libyui-qt  2.53.0
YQRichText.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  Copyright (C) 2019 SUSE LLC
4  This library is free software; you can redistribute it and/or modify
5  it under the terms of the GNU Lesser General Public License as
6  published by the Free Software Foundation; either version 2.1 of the
7  License, or (at your option) version 3.0 of the License. This library
8  is distributed in the hope that it will be useful, but WITHOUT ANY
9  WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
11  License for more details. You should have received a copy of the GNU
12  Lesser General Public License along with this library; if not, write
13  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
14  Floor, Boston, MA 02110-1301 USA
15 */
16 
17 
18 /*-/
19 
20  File: YQRichText.cc
21 
22  Author: Stefan Hundhammer <sh@suse.de>
23 
24 /-*/
25 
26 #define YUILogComponent "qt-ui"
27 #include <yui/YUILog.h>
28 
29 #include <QScrollBar>
30 #include <QRegExp>
31 #include <QDebug>
32 #include <QKeyEvent>
33 #include <QVBoxLayout>
34 
35 #include <yui/YApplication.h>
36 #include <yui/YEvent.h>
37 #include "utf8.h"
38 #include "QY2Styler.h"
39 #include "YQUI.h"
40 #include "YQDialog.h"
41 #include "YQRichText.h"
42 
43 using std::string;
44 
45 
46 static const char *colors[] = { "red", "blue", "green", 0};
47 
48 
49 YQRichText::YQRichText( YWidget * parent,
50  const string & text,
51  bool plainTextMode )
52  : QFrame( (QWidget *) parent->widgetRep() )
53  , YRichText( parent, text, plainTextMode )
54  , _colors_specified( 0 )
55 {
56  QVBoxLayout* layout = new QVBoxLayout( this );
57  layout->setSpacing( 0 );
58  setLayout( layout );
59 
60  setWidgetRep( this );
61 
62  layout->setMargin( YQWidgetMargin );
63 
64  _textBrowser = new YQTextBrowser( this );
65  YUI_CHECK_NEW( _textBrowser );
66  layout->addWidget( _textBrowser );
67 
68  _textBrowser->installEventFilter( this );
69 
70  if ( plainTextMode )
71  {
72  _textBrowser->setWordWrapMode( QTextOption::NoWrap );
73  }
74  else
75  {
76  QString style = "\n" + QY2Styler::styler()->textStyle();
77  size_t ccolors = sizeof( colors ) / sizeof( char* ) - 1;
78  _colors_specified = new bool[ccolors];
79  for ( size_t i = 0; i < ccolors; ++i )
80  {
81  _colors_specified[i] = false;
82  char buffer[20];
83  sprintf( buffer, "\n.%s ", colors[i] );
84  if ( style.contains( buffer ) )
85  _colors_specified[i] = true;
86  }
87  _textBrowser->document()->setDefaultStyleSheet( style );
88  }
89 
90  setValue( text );
91 
92  // Propagate clicks on hyperlinks
93 
94  connect( _textBrowser, &pclass(_textBrowser)::anchorClicked,
95  this, &pclass(this)::linkClicked );
96 }
97 
98 
100 {
101  // NOP
102 }
103 
104 
105 void YQRichText::setValue( const string & newText )
106 {
107  if ( _textBrowser->horizontalScrollBar() )
108  _textBrowser->horizontalScrollBar()->setValue( _textBrowser->horizontalScrollBar()->minimum() );
109 
110  if ( ! autoScrollDown() && _textBrowser->verticalScrollBar() )
111  _textBrowser->verticalScrollBar()->setValue( _textBrowser->verticalScrollBar()->minimum() );
112 
113  QString text = fromUTF8( newText );
114 
115  if ( ! plainTextMode() )
116  {
117  for ( int counter = 0; colors[counter]; counter++ )
118  {
119  if ( !_colors_specified[counter] ) continue;
120  text.replace( QString( "color=%1" ).arg( colors[counter] ), QString( "class=\"%1\"" ).arg( colors[counter] ) );
121  text.replace( QString( "color=\"%1\"" ).arg( colors[counter] ), QString( "class=\"%1\"" ).arg( colors[counter] ));
122  }
123  text.replace( "&product;", fromUTF8( YUI::app()->productName() ) );
124  _textBrowser->setHtml( text );
125  }
126  else
127  {
128  _textBrowser->setPlainText( text );
129  }
130  YRichText::setValue( newText );
131 
132  if ( autoScrollDown() && _textBrowser->verticalScrollBar() )
133  _textBrowser->verticalScrollBar()->setValue( _textBrowser->verticalScrollBar()->maximum() );
134 }
135 
136 
137 void YQRichText::setPlainTextMode( bool newPlainTextMode )
138 {
139  YRichText::setPlainTextMode( newPlainTextMode );
140 
141  if ( plainTextMode() )
142  {
143  _textBrowser->setWordWrapMode( QTextOption::NoWrap );
144  }
145 }
146 
147 
148 void YQRichText::setAutoScrollDown( bool newAutoScrollDown )
149 {
150  YRichText::setAutoScrollDown( newAutoScrollDown );
151 
152  if ( autoScrollDown() && _textBrowser->verticalScrollBar() )
153  _textBrowser->verticalScrollBar()->setValue( _textBrowser->verticalScrollBar()->maximum() );
154 }
155 
156 
157 void YQRichText::activateLink( const string & url )
158 {
159  YQUI::ui()->sendEvent( new YMenuEvent( url ) );
160 }
161 
162 
163 void YQRichText::linkClicked( const QUrl & url )
164 {
165  // yuiDebug() << "Selected hyperlink \"" << url.toString() << "\" << endl;
166  YQUI::ui()->sendEvent( new YMenuEvent( url.toString().toUtf8()) );
167 }
168 
169 
170 bool YQRichText::eventFilter( QObject * obj, QEvent * ev )
171 {
172  if ( ev->type() == QEvent::KeyPress )
173  {
174  QKeyEvent * event = ( QKeyEvent * ) ev;
175 
176  if ( ( event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter ) &&
177  ( event->modifiers() & Qt::NoModifier || event->modifiers() & Qt::KeypadModifier ) &&
178  ! haveHyperLinks() )
179  {
180  YQDialog * dia = (YQDialog *) findDialog();
181 
182  if ( dia )
183  {
184  ( void ) dia->activateDefaultButton();
185  return true;
186  }
187  }
188  }
189 
190  return QWidget::eventFilter( obj, ev );
191 }
192 
193 
195 {
196  if ( plainTextMode() )
197  return false;
198 
199  return ( _textBrowser->document()->toPlainText().contains( QRegExp( "<a\\s+href\\s*=", Qt::CaseInsensitive ) ) > 0 );
200 }
201 
202 
204 {
205  return shrinkable() ? 10 : 100;
206 }
207 
208 
210 {
211  return shrinkable() ? 10 : 100;
212 }
213 
214 
215 void YQRichText::setSize( int newWidth, int newHeight )
216 {
217  resize( newWidth, newHeight );
218 }
219 
220 
221 void YQRichText::setEnabled( bool enabled )
222 {
223  _textBrowser->setEnabled( enabled );
224  YWidget::setEnabled( enabled );
225 }
226 
227 
229 {
230  _textBrowser->setFocus();
231 
232  return true;
233 }
234 
235 
237 {
238  return scrollValue( _textBrowser->verticalScrollBar() );
239 }
240 
241 
242 void YQRichText::setVScrollValue( const string & newValue )
243 {
244  setScrollValue( _textBrowser->verticalScrollBar(), newValue );
245 }
246 
247 
249 {
250  return scrollValue( _textBrowser->horizontalScrollBar() );
251 }
252 
253 
254 void YQRichText::setHScrollValue( const string & newValue )
255 {
256  setScrollValue( _textBrowser->horizontalScrollBar(), newValue );
257 }
258 
259 
260 string YQRichText::scrollValue( QScrollBar* scrollBar ) const
261 {
262  if ( !scrollBar )
263  return "";
264 
265  QString tmp;
266  tmp.setNum( scrollBar->value() );
267  return tmp.toStdString();
268 }
269 
270 
271 void YQRichText::setScrollValue( QScrollBar* scrollBar, const string & newValue )
272 {
273  if ( !scrollBar || newValue.empty() )
274  return;
275 
276  if ( newValue == "minimum" )
277  scrollBar->setValue( scrollBar->minimum() );
278  else if ( newValue == "maximum" )
279  scrollBar->setValue( scrollBar->maximum() );
280  else
281  {
282  QString tmp = QString::fromStdString( newValue );
283  scrollBar->setValue( tmp.toInt() );
284  }
285 }
286 
287 
288 void YQTextBrowser::setSource( const QUrl & name )
289 {
290  // scroll to link if it's available in the current document
291  // but prevent loading empty pages
292 
293  if ( name.toString().startsWith("#") )
294  scrollToAnchor( name.toString().mid(1) );
295 }
YQRichText::setPlainTextMode
virtual void setPlainTextMode(bool on=true)
Set this RichText widget's "plain text" mode on or off.
Definition: YQRichText.cc:137
YQRichText::preferredWidth
virtual int preferredWidth()
Preferred width of the widget.
Definition: YQRichText.cc:203
YQRichText::setAutoScrollDown
virtual void setAutoScrollDown(bool on=true)
Set this RichText widget's "auto scroll down" mode on or off.
Definition: YQRichText.cc:148
YQRichText::hScrollValue
virtual std::string hScrollValue() const override
Get the horizontal scrollbar position.
Definition: YQRichText.cc:248
YQUI::sendEvent
void sendEvent(YEvent *event)
Widget event handlers (slots) call this when an event occured that should be the answer to a UserInpu...
Definition: YQUI.cc:480
YQRichText::setVScrollValue
virtual void setVScrollValue(const std::string &newValue) override
Set the vertical scrollbar position.
Definition: YQRichText.cc:242
YQRichText::preferredHeight
virtual int preferredHeight()
Preferred height of the widget.
Definition: YQRichText.cc:209
YQRichText::setSize
virtual void setSize(int newWidth, int newHeight)
Set the new size of the widget.
Definition: YQRichText.cc:215
YQTextBrowser
Helper class - needed to have the benefits of both QVBox as the base class for YQRichText so uniform ...
Definition: YQRichText.h:202
YQDialog
Definition: YQDialog.h:43
YQRichText::activateLink
virtual void activateLink(const std::string &url)
Derived classes should implement this, method is used to trigger event like user has clicked link in ...
Definition: YQRichText.cc:157
YQRichText::setKeyboardFocus
virtual bool setKeyboardFocus()
Accept the keyboard focus.
Definition: YQRichText.cc:228
YQRichText::YQRichText
YQRichText(YWidget *parent, const std::string &text, bool plainTextMode=false)
Constructor.
Definition: YQRichText.cc:49
YQRichText::setEnabled
virtual void setEnabled(bool enabled)
Set enabled/disabled state.
Definition: YQRichText.cc:221
YQRichText::linkClicked
void linkClicked(const QUrl &url)
Notification that a hyperlink is clicked.
Definition: YQRichText.cc:163
YQRichText::setHScrollValue
virtual void setHScrollValue(const std::string &newValue) override
Set the horizontal scrollbar position.
Definition: YQRichText.cc:254
YQUI::ui
static YQUI * ui()
Access the global Qt-UI.
Definition: YQUI.h:83
YQRichText::vScrollValue
virtual std::string vScrollValue() const override
Get the vertical scrollbar position.
Definition: YQRichText.cc:236
YQRichText::eventFilter
virtual bool eventFilter(QObject *obj, QEvent *ev)
Event filter.
Definition: YQRichText.cc:170
YQRichText::setValue
virtual void setValue(const std::string &newValue) override
Change the text content of the RichText widget.
Definition: YQRichText.cc:105
YQRichText::haveHyperLinks
bool haveHyperLinks()
Returns 'true' if the current text of this RichText widget contains hyperlinks.
Definition: YQRichText.cc:194
YQRichText::~YQRichText
virtual ~YQRichText()
Destructor.
Definition: YQRichText.cc:99
YQDialog::activateDefaultButton
bool activateDefaultButton(bool warn=true)
Activate (i.e.
Definition: YQDialog.cc:534
YQTextBrowser::setSource
virtual void setSource(const QUrl &name)
Get the document pointed to by a hyperlink.
Definition: YQRichText.cc:288