QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsrichtexteditor.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Jiří Procházka (Hobrasoft)
4 ** Contact: http://www.hobrasoft.cz/
5 **
6 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
7 ** Contact: http://www.qt-project.org/legal
8 **
9 ** This library is free software; you can redistribute it and/or
10 ** modify it under the terms of the GNU Lesser General Public
11 ** License as published by the Free Software Foundation; either
12 ** version 2.1 of the License, or (at your option) any later version.
13 **
14 ** $QT_BEGIN_LICENSE:LGPL$
15 ** GNU Lesser General Public License Usage
16 ** This file is under the terms of the GNU Lesser General Public License
17 ** version 2.1 as published by the Free Software Foundation and appearing
18 ** in the file LICENSE.LGPL included in the packaging of this file.
19 ** Please review the following information to ensure the
20 ** GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22 **
23 ** In addition, as a special exception, Digia gives you certain additional
24 ** rights. These rights are described in the Digia Qt LGPL Exception
25 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
26 **
27 ** $QT_END_LICENSE$
28 **
29 ****************************************************************************/
30 
31 #include "qgsrichtexteditor.h"
32 #include "qgsguiutils.h"
33 #include "qgscolorbutton.h"
34 #include "qgscodeeditor.h"
35 #include "qgscodeeditorhtml.h"
36 
37 #include <QMimeData>
38 #include <QApplication>
39 #include <QClipboard>
40 #include <QFontDatabase>
41 #include <QInputDialog>
42 #include <QTextList>
43 #include <QtDebug>
44 #include <QFileDialog>
45 #include <QImageReader>
46 #include <QSettings>
47 #include <QUrl>
48 #include <QMenu>
49 #include <QComboBox>
50 #include <QToolButton>
51 
53  : QWidget( parent )
54 {
55  setupUi( this );
56 
57  mMonospaceFontFamily = QgsCodeEditor::getMonospaceFont().family();
58 
59  QVBoxLayout *sourceLayout = new QVBoxLayout();
60  sourceLayout->setContentsMargins( 0, 0, 0, 0 );
61  mSourceEdit = new QgsCodeEditorHTML();
62  sourceLayout->addWidget( mSourceEdit );
63  mPageSourceEdit->setLayout( sourceLayout );
64 
65  mToolBar->setIconSize( QgsGuiUtils::iconSize( false ) );
66 
67  connect( mTextEdit, &QTextEdit::currentCharFormatChanged, this, &QgsRichTextEditor::slotCurrentCharFormatChanged );
68  connect( mTextEdit, &QTextEdit::cursorPositionChanged, this, &QgsRichTextEditor::slotCursorPositionChanged );
69 
70  // paragraph formatting
71  mParagraphStyleCombo = new QComboBox();
72  mParagraphStyleCombo->addItem( tr( "Standard" ), ParagraphStandard );
73  mParagraphStyleCombo->addItem( tr( "Heading 1" ), ParagraphHeading1 );
74  mParagraphStyleCombo->addItem( tr( "Heading 2" ), ParagraphHeading2 );
75  mParagraphStyleCombo->addItem( tr( "Heading 3" ), ParagraphHeading3 );
76  mParagraphStyleCombo->addItem( tr( "Heading 4" ), ParagraphHeading4 );
77  mParagraphStyleCombo->addItem( tr( "Monospace" ), ParagraphMonospace );
78 
79  connect( mParagraphStyleCombo, qOverload< int >( &QComboBox::activated ), this, &QgsRichTextEditor::textStyle );
80  mToolBar->insertWidget( mToolBar->actions().at( 0 ), mParagraphStyleCombo );
81 
82  mFontSizeCombo = new QComboBox();
83  mFontSizeCombo->setEditable( true );
84  mToolBar->insertWidget( mActionBold, mFontSizeCombo );
85 
86  // undo & redo
87  mActionUndo->setShortcut( QKeySequence::Undo );
88  mActionRedo->setShortcut( QKeySequence::Redo );
89 
90  connect( mTextEdit->document(), &QTextDocument::undoAvailable, mActionUndo, &QAction::setEnabled );
91  connect( mTextEdit->document(), &QTextDocument::redoAvailable, mActionRedo, &QAction::setEnabled );
92 
93  mActionUndo->setEnabled( mTextEdit->document()->isUndoAvailable() );
94  mActionRedo->setEnabled( mTextEdit->document()->isRedoAvailable() );
95 
96  connect( mActionUndo, &QAction::triggered, mTextEdit, &QTextEdit::undo );
97  connect( mActionRedo, &QAction::triggered, mTextEdit, &QTextEdit::redo );
98 
99  // cut, copy & paste
100  mActionCut->setShortcut( QKeySequence::Cut );
101  mActionCopy->setShortcut( QKeySequence::Copy );
102  mActionPaste->setShortcut( QKeySequence::Paste );
103 
104  mActionCut->setEnabled( false );
105  mActionCopy->setEnabled( false );
106 
107  connect( mActionCut, &QAction::triggered, mTextEdit, &QTextEdit::cut );
108  connect( mActionCopy, &QAction::triggered, mTextEdit, &QTextEdit::copy );
109  connect( mActionPaste, &QAction::triggered, mTextEdit, &QTextEdit::paste );
110 
111  connect( mTextEdit, &QTextEdit::copyAvailable, mActionCut, &QAction::setEnabled );
112  connect( mTextEdit, &QTextEdit::copyAvailable, mActionCopy, &QAction::setEnabled );
113 
114 #ifndef QT_NO_CLIPBOARD
115  connect( QApplication::clipboard(), &QClipboard::dataChanged, this, &QgsRichTextEditor::slotClipboardDataChanged );
116 #endif
117 
118  // link
119  mActionInsertLink->setShortcut( QKeySequence( QStringLiteral( "CTRL+L" ) ) );
120  connect( mActionInsertLink, &QAction::triggered, this, &QgsRichTextEditor::textLink );
121 
122  // bold, italic & underline
123  mActionBold->setShortcut( QKeySequence( QStringLiteral( "CTRL+B" ) ) );
124  mActionItalic->setShortcut( QKeySequence( QStringLiteral( "CTRL+I" ) ) );
125  mActionUnderline->setShortcut( QKeySequence( QStringLiteral( "CTRL+U" ) ) );
126 
127  connect( mActionBold, &QAction::triggered, this, &QgsRichTextEditor::textBold );
128  connect( mActionItalic, &QAction::triggered, this, &QgsRichTextEditor::textItalic );
129  connect( mActionUnderline, &QAction::triggered, this, &QgsRichTextEditor::textUnderline );
130  connect( mActionStrikeOut, &QAction::triggered, this, &QgsRichTextEditor::textStrikeout );
131 
132  QAction *removeFormat = new QAction( tr( "Remove Character Formatting" ), this );
133  removeFormat->setShortcut( QKeySequence( QStringLiteral( "CTRL+M" ) ) );
134  connect( removeFormat, &QAction::triggered, this, &QgsRichTextEditor::textRemoveFormat );
135  mTextEdit->addAction( removeFormat );
136 
137  QAction *removeAllFormat = new QAction( tr( "Remove all Formatting" ), this );
138  connect( removeAllFormat, &QAction::triggered, this, &QgsRichTextEditor::textRemoveAllFormat );
139  mTextEdit->addAction( removeAllFormat );
140 
141  QAction *clearText = new QAction( tr( "Clear all Content" ), this );
142  connect( clearText, &QAction::triggered, this, &QgsRichTextEditor::clearSource );
143  mTextEdit->addAction( clearText );
144 
145  QMenu *menu = new QMenu( this );
146  menu->addAction( removeAllFormat );
147  menu->addAction( removeFormat );
148  menu->addAction( clearText );
149 
150  QToolButton *menuButton = new QToolButton();
151  menuButton->setMenu( menu );
152  menuButton->setPopupMode( QToolButton::InstantPopup );
153  menuButton->setToolTip( tr( "Advanced Options" ) );
154  menuButton->setText( QStringLiteral( "…" ) );
155  QWidget *spacer = new QWidget();
156  spacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
157  mToolBar->addWidget( spacer );
158  mToolBar->addWidget( menuButton );
159 
160  // lists
161  mActionBulletList->setShortcut( QKeySequence( QStringLiteral( "CTRL+-" ) ) );
162  mActionOrderedList->setShortcut( QKeySequence( QStringLiteral( "CTRL+=" ) ) );
163  connect( mActionBulletList, &QAction::triggered, this, &QgsRichTextEditor::listBullet );
164  connect( mActionOrderedList, &QAction::triggered, this, &QgsRichTextEditor::listOrdered );
165 
166  // indentation
167  mActionDecreaseIndent->setShortcut( QKeySequence( QStringLiteral( "CTRL+," ) ) );
168  mActionIncreaseIndent->setShortcut( QKeySequence( QStringLiteral( "CTRL+." ) ) );
169  connect( mActionIncreaseIndent, &QAction::triggered, this, &QgsRichTextEditor::increaseIndentation );
170  connect( mActionDecreaseIndent, &QAction::triggered, this, &QgsRichTextEditor::decreaseIndentation );
171 
172  // font size
173  const QList< int > sizes = QFontDatabase::standardSizes();
174  for ( const int size : sizes )
175  mFontSizeCombo->addItem( QString::number( size ), size );
176 
177  mFontSizeCombo->setCurrentIndex( mFontSizeCombo->findData( QApplication::font().pointSize() ) );
178 
179  // text foreground color
180  mForeColorButton = new QgsColorButton();
181  mForeColorButton->setAllowOpacity( false );
182  mForeColorButton->setColorDialogTitle( tr( "Foreground Color" ) );
183  mForeColorButton->setColor( palette().windowText().color() );
184  mForeColorButton->setShowNoColor( false );
185  mForeColorButton->setToolTip( tr( "Foreground color" ) );
186  mForeColorButton->setMinimumWidth( QFontMetrics( font() ).horizontalAdvance( QStringLiteral( "x" ) ) * 10 );
187  mForeColorButton->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
188 
189  QAction *listSeparator = mToolBar->insertSeparator( mActionBulletList );
190 
191  connect( mForeColorButton, &QgsColorButton::colorChanged, this, &QgsRichTextEditor::textFgColor );
192  mToolBar->insertWidget( listSeparator, mForeColorButton );
193 
194  // text background color
195  mBackColorButton = new QgsColorButton();
196  mBackColorButton->setAllowOpacity( false );
197  mBackColorButton->setColorDialogTitle( tr( "Background Color" ) );
198  mBackColorButton->setToolTip( tr( "Background color" ) );
199  mBackColorButton->setShowNull( true, tr( "No Background Color" ) );
200  mBackColorButton->setToNull();
201  mBackColorButton->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
202  mBackColorButton->setMinimumWidth( QFontMetrics( font() ).horizontalAdvance( QStringLiteral( "x" ) ) * 10 );
203  connect( mBackColorButton, &QgsColorButton::colorChanged, this, &QgsRichTextEditor::textBgColor );
204  mToolBar->insertWidget( listSeparator, mBackColorButton );
205 
206  connect( mActionEditSource, &QAction::toggled, this, &QgsRichTextEditor::editSource );
207 
208  // images
209  connect( mActionInsertImage, &QAction::triggered, this, &QgsRichTextEditor::insertImage );
210 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
211  connect( mFontSizeCombo, qOverload< const QString &>( &QComboBox::activated ), this, &QgsRichTextEditor::textSize );
212 #else
213  connect( mFontSizeCombo, &QComboBox::textActivated, this, &QgsRichTextEditor::textSize );
214 #endif
215 
216  fontChanged( mTextEdit->font() );
217 
218  connect( mTextEdit, &QTextEdit::textChanged, this, &QgsRichTextEditor::textChanged );
219  connect( mSourceEdit, &QgsCodeEditorHTML::textChanged, this, &QgsRichTextEditor::textChanged );
220 }
221 
223 {
224  switch ( mStackedWidget->currentIndex() )
225  {
226  case 0:
227  return mTextEdit->toPlainText();
228 
229  case 1:
230  // go via text edit to remove html from text...
231  mTextEdit->setText( mSourceEdit->text() );
232  return mTextEdit->toPlainText();
233  }
234  return QString();
235 }
236 
238 {
239  switch ( mStackedWidget->currentIndex() )
240  {
241  case 0:
242  return mTextEdit->toHtml();
243 
244  case 1:
245  return mSourceEdit->text();
246  }
247  return QString();
248 }
249 
250 void QgsRichTextEditor::editSource( bool enabled )
251 {
252  if ( enabled )
253  {
254  mSourceEdit->setText( mTextEdit->toHtml() );
255  mStackedWidget->setCurrentIndex( 1 );
256  }
257  else
258  {
259  mTextEdit->setHtml( mSourceEdit->text() );
260  mStackedWidget->setCurrentIndex( 0 );
261  mSourceEdit->clear();
262  }
263 
264  // disable formatting actions when in html edit mode
265  mFontSizeCombo->setEnabled( !enabled );
266  mParagraphStyleCombo->setEnabled( !enabled );
267  mForeColorButton->setEnabled( !enabled );
268  mBackColorButton->setEnabled( !enabled );
269  mActionUndo->setEnabled( !enabled );
270  mActionRedo->setEnabled( !enabled );
271  mActionCut->setEnabled( !enabled );
272  mActionCopy->setEnabled( !enabled );
273  mActionPaste->setEnabled( !enabled );
274  mActionInsertLink->setEnabled( !enabled );
275  mActionBold->setEnabled( !enabled );
276  mActionItalic->setEnabled( !enabled );
277  mActionUnderline->setEnabled( !enabled );
278  mActionStrikeOut->setEnabled( !enabled );
279  mActionBulletList->setEnabled( !enabled );
280  mActionOrderedList->setEnabled( !enabled );
281  mActionDecreaseIndent->setEnabled( !enabled );
282  mActionIncreaseIndent->setEnabled( !enabled );
283  mActionInsertImage->setEnabled( !enabled );
284 }
285 
287 {
288  mTextEdit->clear();
289 }
290 
291 void QgsRichTextEditor::textRemoveFormat()
292 {
293  QTextCharFormat format;
294  format.setFontWeight( QFont::Normal );
295  format.setFontUnderline( false );
296  format.setFontStrikeOut( false );
297  format.setFontItalic( false );
298  format.setFontPointSize( 9 );
299 
300  mActionBold->setChecked( false );
301  mActionUnderline->setChecked( false );
302  mActionItalic->setChecked( false );
303  mActionStrikeOut->setChecked( false );
304  mFontSizeCombo->setCurrentIndex( mFontSizeCombo->findData( 9 ) );
305 
306  format.clearBackground();
307 
308  mergeFormatOnWordOrSelection( format );
309 }
310 
311 void QgsRichTextEditor::textRemoveAllFormat()
312 {
313  mActionBold->setChecked( false );
314  mActionUnderline->setChecked( false );
315  mActionItalic->setChecked( false );
316  mActionStrikeOut->setChecked( false );
317  mFontSizeCombo->setCurrentIndex( mFontSizeCombo->findData( 9 ) );
318  const QString text = mTextEdit->toPlainText();
319  mTextEdit->setPlainText( text );
320 }
321 
322 void QgsRichTextEditor::textBold()
323 {
324  QTextCharFormat format;
325  format.setFontWeight( mActionBold->isChecked() ? QFont::Bold : QFont::Normal );
326  mergeFormatOnWordOrSelection( format );
327 }
328 
329 void QgsRichTextEditor::focusInEvent( QFocusEvent * )
330 {
331  mTextEdit->setFocus( Qt::TabFocusReason );
332 }
333 
334 void QgsRichTextEditor::textUnderline()
335 {
336  QTextCharFormat format;
337  format.setFontUnderline( mActionUnderline->isChecked() );
338  mergeFormatOnWordOrSelection( format );
339 }
340 
341 void QgsRichTextEditor::textItalic()
342 {
343  QTextCharFormat format;
344  format.setFontItalic( mActionItalic->isChecked() );
345  mergeFormatOnWordOrSelection( format );
346 }
347 
348 void QgsRichTextEditor::textStrikeout()
349 {
350  QTextCharFormat format;
351  format.setFontStrikeOut( mActionStrikeOut->isChecked() );
352  mergeFormatOnWordOrSelection( format );
353 }
354 
355 void QgsRichTextEditor::textSize( const QString &p )
356 {
357  const qreal pointSize = p.toDouble();
358  if ( p.toFloat() > 0 )
359  {
360  QTextCharFormat format;
361  format.setFontPointSize( pointSize );
362  mergeFormatOnWordOrSelection( format );
363  }
364 }
365 
366 void QgsRichTextEditor::textLink( bool checked )
367 {
368  bool unlink = false;
369  QTextCharFormat format;
370  if ( checked )
371  {
372  const QString url = mTextEdit->currentCharFormat().anchorHref();
373  bool ok;
374  const QString newUrl = QInputDialog::getText( this, tr( "Create a Link" ),
375  tr( "Link URL:" ), QLineEdit::Normal,
376  url,
377  &ok );
378  if ( ok )
379  {
380  format.setAnchor( true );
381  format.setAnchorHref( newUrl );
382  format.setForeground( palette().color( QPalette::Link ) );
383  format.setFontUnderline( true );
384  }
385  else
386  {
387  unlink = true;
388  }
389  }
390  else
391  {
392  unlink = true;
393  }
394  if ( unlink )
395  {
396  format.setAnchor( false );
397  format.setForeground( palette().color( QPalette::Text ) );
398  format.setFontUnderline( false );
399  }
400  mergeFormatOnWordOrSelection( format );
401 }
402 
403 void QgsRichTextEditor::textStyle( int )
404 {
405  QTextCursor cursor = mTextEdit->textCursor();
406  cursor.beginEditBlock();
407 
408  // standard
409  if ( !cursor.hasSelection() )
410  {
411  cursor.select( QTextCursor::BlockUnderCursor );
412  }
413  QTextCharFormat format;
414  cursor.setCharFormat( format );
415  mTextEdit->setCurrentCharFormat( format );
416 
417  const ParagraphItems style = static_cast< ParagraphItems >( mParagraphStyleCombo->currentData().toInt() );
418 
419  switch ( style )
420  {
421  case QgsRichTextEditor::ParagraphStandard:
422  break;
423 
424  case QgsRichTextEditor::ParagraphHeading1:
425  format.setFontPointSize( mFontSizeH1 );
426  format.setFontWeight( QFont::Bold );
427  break;
428 
429  case QgsRichTextEditor::ParagraphHeading2:
430  format.setFontPointSize( mFontSizeH2 );
431  format.setFontWeight( QFont::Bold );
432  format.setFontItalic( true );
433  break;
434 
435  case QgsRichTextEditor::ParagraphHeading3:
436  format.setFontPointSize( mFontSizeH3 );
437  format.setFontWeight( QFont::Bold );
438  break;
439 
440  case QgsRichTextEditor::ParagraphHeading4:
441  format.setFontPointSize( mFontSizeH4 );
442  format.setFontWeight( QFont::Bold );
443  format.setFontItalic( true );
444  break;
445 
446  case QgsRichTextEditor::ParagraphMonospace:
447  {
448  format = cursor.charFormat();
449  format.setFontFamily( mMonospaceFontFamily );
450  format.setFontStyleHint( QFont::Monospace );
451  format.setFontFixedPitch( true );
452  break;
453  }
454  }
455 
456  cursor.setCharFormat( format );
457  mTextEdit->setCurrentCharFormat( format );
458 
459  cursor.endEditBlock();
460 }
461 
462 void QgsRichTextEditor::textFgColor()
463 {
464  QTextCharFormat format;
465  format.setForeground( mForeColorButton->color() );
466  mergeFormatOnWordOrSelection( format );
467 }
468 
469 void QgsRichTextEditor::textBgColor()
470 {
471  QTextCharFormat format;
472  const QColor col = mBackColorButton->color();
473  if ( col.isValid() )
474  {
475  format.setBackground( col );
476  }
477  else
478  {
479  format.clearBackground();
480  }
481  mergeFormatOnWordOrSelection( format );
482 }
483 
484 void QgsRichTextEditor::listBullet( bool checked )
485 {
486  if ( checked )
487  {
488  mActionOrderedList->setChecked( false );
489  }
490  list( checked, QTextListFormat::ListDisc );
491 }
492 
493 void QgsRichTextEditor::listOrdered( bool checked )
494 {
495  if ( checked )
496  {
497  mActionBulletList->setChecked( false );
498  }
499  list( checked, QTextListFormat::ListDecimal );
500 }
501 
502 void QgsRichTextEditor::list( bool checked, QTextListFormat::Style style )
503 {
504  QTextCursor cursor = mTextEdit->textCursor();
505  cursor.beginEditBlock();
506  if ( !checked )
507  {
508  const QTextBlockFormat originalFormat = cursor.blockFormat();
509  QTextBlockFormat format;
510  format.setIndent( originalFormat.indent() );
511  cursor.setBlockFormat( format );
512  }
513  else
514  {
515  QTextListFormat listFormat;
516  if ( cursor.currentList() )
517  {
518  listFormat = cursor.currentList()->format();
519  }
520  listFormat.setStyle( style );
521  cursor.createList( listFormat );
522  }
523  cursor.endEditBlock();
524 }
525 
526 void QgsRichTextEditor::mergeFormatOnWordOrSelection( const QTextCharFormat &format )
527 {
528  QTextCursor cursor = mTextEdit->textCursor();
529  if ( !cursor.hasSelection() )
530  {
531  cursor.select( QTextCursor::WordUnderCursor );
532  }
533  cursor.mergeCharFormat( format );
534  mTextEdit->mergeCurrentCharFormat( format );
535  mTextEdit->setFocus( Qt::TabFocusReason );
536 }
537 
538 void QgsRichTextEditor::slotCursorPositionChanged()
539 {
540  QTextList *l = mTextEdit->textCursor().currentList();
541  if ( mLastBlockList && ( l == mLastBlockList || ( l != nullptr && mLastBlockList != nullptr
542  && l->format().style() == mLastBlockList->format().style() ) ) )
543  {
544  return;
545  }
546  mLastBlockList = l;
547  if ( l )
548  {
549  const QTextListFormat listFormat = l->format();
550  if ( listFormat.style() == QTextListFormat::ListDisc )
551  {
552  mActionBulletList->setChecked( true );
553  mActionOrderedList->setChecked( false );
554  }
555  else if ( listFormat.style() == QTextListFormat::ListDecimal )
556  {
557  mActionBulletList->setChecked( false );
558  mActionOrderedList->setChecked( true );
559  }
560  else
561  {
562  mActionBulletList->setChecked( false );
563  mActionOrderedList->setChecked( false );
564  }
565  }
566  else
567  {
568  mActionBulletList->setChecked( false );
569  mActionOrderedList->setChecked( false );
570  }
571 }
572 
573 void QgsRichTextEditor::fontChanged( const QFont &f )
574 {
575  mFontSizeCombo->setCurrentIndex( mFontSizeCombo->findData( f.pointSize() ) );
576  mActionBold->setChecked( f.bold() );
577  mActionItalic->setChecked( f.italic() );
578  mActionUnderline->setChecked( f.underline() );
579  mActionStrikeOut->setChecked( f.strikeOut() );
580  if ( f.pointSize() == mFontSizeH1 )
581  {
582  mParagraphStyleCombo->setCurrentIndex( ParagraphHeading1 );
583  }
584  else if ( f.pointSize() == mFontSizeH2 )
585  {
586  mParagraphStyleCombo->setCurrentIndex( ParagraphHeading2 );
587  }
588  else if ( f.pointSize() == mFontSizeH3 )
589  {
590  mParagraphStyleCombo->setCurrentIndex( ParagraphHeading3 );
591  }
592  else if ( f.pointSize() == mFontSizeH4 )
593  {
594  mParagraphStyleCombo->setCurrentIndex( ParagraphHeading4 );
595  }
596  else
597  {
598  if ( f.fixedPitch() && f.family() == mMonospaceFontFamily )
599  {
600  mParagraphStyleCombo->setCurrentIndex( ParagraphMonospace );
601  }
602  else
603  {
604  mParagraphStyleCombo->setCurrentIndex( ParagraphStandard );
605  }
606  }
607  if ( mTextEdit->textCursor().currentList() )
608  {
609  const QTextListFormat listFormat = mTextEdit->textCursor().currentList()->format();
610  if ( listFormat.style() == QTextListFormat::ListDisc )
611  {
612  mActionBulletList->setChecked( true );
613  mActionOrderedList->setChecked( false );
614  }
615  else if ( listFormat.style() == QTextListFormat::ListDecimal )
616  {
617  mActionBulletList->setChecked( false );
618  mActionOrderedList->setChecked( true );
619  }
620  else
621  {
622  mActionBulletList->setChecked( false );
623  mActionOrderedList->setChecked( false );
624  }
625  }
626  else
627  {
628  mActionBulletList->setChecked( false );
629  mActionOrderedList->setChecked( false );
630  }
631 }
632 
633 void QgsRichTextEditor::fgColorChanged( const QColor &c )
634 {
635  whileBlocking( mForeColorButton )->setColor( c );
636 }
637 
638 void QgsRichTextEditor::bgColorChanged( const QColor &c )
639 {
640  if ( c.isValid() )
641  whileBlocking( mBackColorButton )->setColor( c );
642  else
643  whileBlocking( mBackColorButton )->setToNull();
644 }
645 
646 void QgsRichTextEditor::slotCurrentCharFormatChanged( const QTextCharFormat &format )
647 {
648  fontChanged( format.font() );
649  bgColorChanged( ( format.background().isOpaque() ) ? format.background().color() : QColor() );
650  fgColorChanged( ( format.foreground().isOpaque() ) ? format.foreground().color() : palette().windowText().color() );
651  mActionInsertLink->setChecked( format.isAnchor() );
652 }
653 
654 void QgsRichTextEditor::slotClipboardDataChanged()
655 {
656 #ifndef QT_NO_CLIPBOARD
657  if ( const QMimeData *md = QApplication::clipboard()->mimeData() )
658  mActionPaste->setEnabled( md->hasText() );
659 #endif
660 }
661 
662 void QgsRichTextEditor::increaseIndentation()
663 {
664  indent( +1 );
665 }
666 
667 void QgsRichTextEditor::decreaseIndentation()
668 {
669  indent( -1 );
670 }
671 
672 void QgsRichTextEditor::indent( int delta )
673 {
674  QTextCursor cursor = mTextEdit->textCursor();
675  cursor.beginEditBlock();
676  QTextBlockFormat format = cursor.blockFormat();
677  const int indent = format.indent();
678  if ( indent + delta >= 0 )
679  {
680  format.setIndent( indent + delta );
681  }
682  cursor.setBlockFormat( format );
683  cursor.endEditBlock();
684 }
685 
686 void QgsRichTextEditor::setText( const QString &text )
687 {
688  if ( text.isEmpty() )
689  {
690  setPlainText( text );
691  return;
692  }
693  if ( text[0] == '<' )
694  {
695  setHtml( text );
696  }
697  else
698  {
699  setPlainText( text );
700  }
701 }
702 
703 void QgsRichTextEditor::insertImage()
704 {
705  const QSettings s;
706  const QString attdir = s.value( QStringLiteral( "general/filedialog-path" ) ).toString();
707  const QString file = QFileDialog::getOpenFileName( this,
708  tr( "Select an image" ),
709  attdir,
710  tr( "JPEG (*.jpg);; GIF (*.gif);; PNG (*.png);; BMP (*.bmp);; All (*)" ) );
711  if ( file.isEmpty() )
712  return;
713 
714  const QImage image = QImageReader( file ).read();
715 
716  mTextEdit->dropImage( image, QFileInfo( file ).suffix().toUpper().toLocal8Bit().data() );
717 }
qgscolorbutton.h
QgsColorButton::setShowNoColor
void setShowNoColor(const bool showNoColorOption)
Sets whether the "no color" option should be shown in the button's drop-down menu.
Definition: qgscolorbutton.h:179
QgsColorButton::setColor
void setColor(const QColor &color)
Sets the current color for the button.
Definition: qgscolorbutton.cpp:658
QgsRichTextEditor::clearSource
void clearSource()
Clears the current text from the widget.
Definition: qgsrichtexteditor.cpp:286
QgsRichTextEditor::toPlainText
QString toPlainText() const
Returns the widget's content as a plain text string.
Definition: qgsrichtexteditor.cpp:222
QgsRichTextEditor::QgsRichTextEditor
QgsRichTextEditor(QWidget *parent=nullptr)
Constructor for QgsRichTextEditor, with the specified parent widget.
Definition: qgsrichtexteditor.cpp:52
QgsGuiUtils::iconSize
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
Definition: qgsguiutils.cpp:264
QgsColorButton::colorChanged
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
QgsColorButton::setAllowOpacity
void setAllowOpacity(bool allowOpacity)
Sets whether opacity modification (transparency) is permitted for the color.
Definition: qgscolorbutton.cpp:805
QgsRichTextEditor::setText
void setText(const QString &text)
Sets the text to show in the widget.
Definition: qgsrichtexteditor.cpp:686
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:2191
qgscodeeditorhtml.h
qgsrichtexteditor.h
QgsColorButton::color
QColor color
Definition: qgscolorbutton.h:50
qgscodeeditor.h
QgsColorButton::setShowNull
void setShowNull(bool showNull, const QString &nullString=QString())
Sets whether a set to null (clear) option is shown in the button's drop-down menu.
Definition: qgscolorbutton.cpp:840
QgsRichTextEditor::toHtml
QString toHtml() const
Returns the widget's content as a HTML string.
Definition: qgsrichtexteditor.cpp:237
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
QgsCodeEditorHTML
A HTML editor based on QScintilla2. Adds syntax highlighting and code autocompletion.
Definition: qgscodeeditorhtml.h:32
QgsColorButton
A cross platform button subclass for selecting colors. Will open a color chooser dialog when clicked....
Definition: qgscolorbutton.h:35
QgsRichTextEditor::focusInEvent
void focusInEvent(QFocusEvent *event) override
Definition: qgsrichtexteditor.cpp:329
QgsCodeEditor::getMonospaceFont
static QFont getMonospaceFont()
Returns the monospaced font to use for code editors.
Definition: qgscodeeditor.cpp:445
QgsColorButton::setToNull
void setToNull()
Sets color to null.
Definition: qgscolorbutton.cpp:157
qgsguiutils.h
QgsRichTextEditor::textChanged
void textChanged()
Emitted when the text contents are changed.
QgsColorButton::setColorDialogTitle
void setColorDialogTitle(const QString &title)
Set the title for the color chooser dialog window.
Definition: qgscolorbutton.cpp:810