QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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 connect( mFontSizeCombo, &QComboBox::textActivated, this, &QgsRichTextEditor::textSize );
211
212 fontChanged( mTextEdit->font() );
213
214 connect( mTextEdit, &QTextEdit::textChanged, this, &QgsRichTextEditor::textChanged );
215 connect( mSourceEdit, &QgsCodeEditorHTML::textChanged, this, &QgsRichTextEditor::textChanged );
216}
217
219{
220 switch ( mStackedWidget->currentIndex() )
221 {
222 case 0:
223 return mTextEdit->toPlainText();
224
225 case 1:
226 // go via text edit to remove html from text...
227 mTextEdit->setText( mSourceEdit->text() );
228 return mTextEdit->toPlainText();
229 }
230 return QString();
231}
232
234{
235 switch ( mStackedWidget->currentIndex() )
236 {
237 case 0:
238 return mTextEdit->toHtml();
239
240 case 1:
241 return mSourceEdit->text();
242 }
243 return QString();
244}
245
246void QgsRichTextEditor::editSource( bool enabled )
247{
248 if ( enabled )
249 {
250 mSourceEdit->setText( mTextEdit->toHtml() );
251 mStackedWidget->setCurrentIndex( 1 );
252 }
253 else
254 {
255 mTextEdit->setHtml( mSourceEdit->text() );
256 mStackedWidget->setCurrentIndex( 0 );
257 mSourceEdit->clear();
258 }
259
260 // disable formatting actions when in html edit mode
261 mFontSizeCombo->setEnabled( !enabled );
262 mParagraphStyleCombo->setEnabled( !enabled );
263 mForeColorButton->setEnabled( !enabled );
264 mBackColorButton->setEnabled( !enabled );
265 mActionUndo->setEnabled( !enabled );
266 mActionRedo->setEnabled( !enabled );
267 mActionCut->setEnabled( !enabled );
268 mActionCopy->setEnabled( !enabled );
269 mActionPaste->setEnabled( !enabled );
270 mActionInsertLink->setEnabled( !enabled );
271 mActionBold->setEnabled( !enabled );
272 mActionItalic->setEnabled( !enabled );
273 mActionUnderline->setEnabled( !enabled );
274 mActionStrikeOut->setEnabled( !enabled );
275 mActionBulletList->setEnabled( !enabled );
276 mActionOrderedList->setEnabled( !enabled );
277 mActionDecreaseIndent->setEnabled( !enabled );
278 mActionIncreaseIndent->setEnabled( !enabled );
279 mActionInsertImage->setEnabled( !enabled );
280}
281
283{
284 mTextEdit->clear();
285}
286
287void QgsRichTextEditor::textRemoveFormat()
288{
289 QTextCharFormat format;
290 format.setFontWeight( QFont::Normal );
291 format.setFontUnderline( false );
292 format.setFontStrikeOut( false );
293 format.setFontItalic( false );
294 format.setFontPointSize( 9 );
295
296 mActionBold->setChecked( false );
297 mActionUnderline->setChecked( false );
298 mActionItalic->setChecked( false );
299 mActionStrikeOut->setChecked( false );
300 mFontSizeCombo->setCurrentIndex( mFontSizeCombo->findData( 9 ) );
301
302 format.clearBackground();
303
304 mergeFormatOnWordOrSelection( format );
305}
306
307void QgsRichTextEditor::textRemoveAllFormat()
308{
309 mActionBold->setChecked( false );
310 mActionUnderline->setChecked( false );
311 mActionItalic->setChecked( false );
312 mActionStrikeOut->setChecked( false );
313 mFontSizeCombo->setCurrentIndex( mFontSizeCombo->findData( 9 ) );
314 const QString text = mTextEdit->toPlainText();
315 mTextEdit->setPlainText( text );
316}
317
318void QgsRichTextEditor::textBold()
319{
320 QTextCharFormat format;
321 format.setFontWeight( mActionBold->isChecked() ? QFont::Bold : QFont::Normal );
322 mergeFormatOnWordOrSelection( format );
323}
324
326{
327 mTextEdit->setFocus( Qt::TabFocusReason );
328}
329
330void QgsRichTextEditor::textUnderline()
331{
332 QTextCharFormat format;
333 format.setFontUnderline( mActionUnderline->isChecked() );
334 mergeFormatOnWordOrSelection( format );
335}
336
337void QgsRichTextEditor::textItalic()
338{
339 QTextCharFormat format;
340 format.setFontItalic( mActionItalic->isChecked() );
341 mergeFormatOnWordOrSelection( format );
342}
343
344void QgsRichTextEditor::textStrikeout()
345{
346 QTextCharFormat format;
347 format.setFontStrikeOut( mActionStrikeOut->isChecked() );
348 mergeFormatOnWordOrSelection( format );
349}
350
351void QgsRichTextEditor::textSize( const QString &p )
352{
353 const qreal pointSize = p.toDouble();
354 if ( p.toFloat() > 0 )
355 {
356 QTextCharFormat format;
357 format.setFontPointSize( pointSize );
358 mergeFormatOnWordOrSelection( format );
359 }
360}
361
362void QgsRichTextEditor::textLink( bool checked )
363{
364 bool unlink = false;
365 QTextCharFormat format;
366 if ( checked )
367 {
368 const QString url = mTextEdit->currentCharFormat().anchorHref();
369 bool ok;
370 const QString newUrl = QInputDialog::getText( this, tr( "Create a Link" ),
371 tr( "Link URL:" ), QLineEdit::Normal,
372 url,
373 &ok );
374 if ( ok )
375 {
376 format.setAnchor( true );
377 format.setAnchorHref( newUrl );
378 format.setForeground( palette().color( QPalette::Link ) );
379 format.setFontUnderline( true );
380 }
381 else
382 {
383 unlink = true;
384 }
385 }
386 else
387 {
388 unlink = true;
389 }
390 if ( unlink )
391 {
392 format.setAnchor( false );
393 format.setForeground( palette().color( QPalette::Text ) );
394 format.setFontUnderline( false );
395 }
396 mergeFormatOnWordOrSelection( format );
397}
398
399void QgsRichTextEditor::textStyle( int )
400{
401 QTextCursor cursor = mTextEdit->textCursor();
402 cursor.beginEditBlock();
403
404 // standard
405 if ( !cursor.hasSelection() )
406 {
407 cursor.select( QTextCursor::BlockUnderCursor );
408 }
409 QTextCharFormat format;
410 cursor.setCharFormat( format );
411 mTextEdit->setCurrentCharFormat( format );
412
413 const ParagraphItems style = static_cast< ParagraphItems >( mParagraphStyleCombo->currentData().toInt() );
414
415 switch ( style )
416 {
417 case QgsRichTextEditor::ParagraphStandard:
418 break;
419
420 case QgsRichTextEditor::ParagraphHeading1:
421 format.setFontPointSize( mFontSizeH1 );
422 format.setFontWeight( QFont::Bold );
423 break;
424
425 case QgsRichTextEditor::ParagraphHeading2:
426 format.setFontPointSize( mFontSizeH2 );
427 format.setFontWeight( QFont::Bold );
428 format.setFontItalic( true );
429 break;
430
431 case QgsRichTextEditor::ParagraphHeading3:
432 format.setFontPointSize( mFontSizeH3 );
433 format.setFontWeight( QFont::Bold );
434 break;
435
436 case QgsRichTextEditor::ParagraphHeading4:
437 format.setFontPointSize( mFontSizeH4 );
438 format.setFontWeight( QFont::Bold );
439 format.setFontItalic( true );
440 break;
441
442 case QgsRichTextEditor::ParagraphMonospace:
443 {
444 format = cursor.charFormat();
445 format.setFontFamily( mMonospaceFontFamily );
446 format.setFontStyleHint( QFont::Monospace );
447 format.setFontFixedPitch( true );
448 break;
449 }
450 }
451
452 cursor.setCharFormat( format );
453 mTextEdit->setCurrentCharFormat( format );
454
455 cursor.endEditBlock();
456}
457
458void QgsRichTextEditor::textFgColor()
459{
460 QTextCharFormat format;
461 format.setForeground( mForeColorButton->color() );
462 mergeFormatOnWordOrSelection( format );
463}
464
465void QgsRichTextEditor::textBgColor()
466{
467 QTextCharFormat format;
468 const QColor col = mBackColorButton->color();
469 if ( col.isValid() )
470 {
471 format.setBackground( col );
472 }
473 else
474 {
475 format.clearBackground();
476 }
477 mergeFormatOnWordOrSelection( format );
478}
479
480void QgsRichTextEditor::listBullet( bool checked )
481{
482 if ( checked )
483 {
484 mActionOrderedList->setChecked( false );
485 }
486 list( checked, QTextListFormat::ListDisc );
487}
488
489void QgsRichTextEditor::listOrdered( bool checked )
490{
491 if ( checked )
492 {
493 mActionBulletList->setChecked( false );
494 }
495 list( checked, QTextListFormat::ListDecimal );
496}
497
498void QgsRichTextEditor::list( bool checked, QTextListFormat::Style style )
499{
500 QTextCursor cursor = mTextEdit->textCursor();
501 cursor.beginEditBlock();
502 if ( !checked )
503 {
504 const QTextBlockFormat originalFormat = cursor.blockFormat();
505 QTextBlockFormat format;
506 format.setIndent( originalFormat.indent() );
507 cursor.setBlockFormat( format );
508 }
509 else
510 {
511 QTextListFormat listFormat;
512 if ( cursor.currentList() )
513 {
514 listFormat = cursor.currentList()->format();
515 }
516 listFormat.setStyle( style );
517 cursor.createList( listFormat );
518 }
519 cursor.endEditBlock();
520}
521
522void QgsRichTextEditor::mergeFormatOnWordOrSelection( const QTextCharFormat &format )
523{
524 QTextCursor cursor = mTextEdit->textCursor();
525 if ( !cursor.hasSelection() )
526 {
527 cursor.select( QTextCursor::WordUnderCursor );
528 }
529 cursor.mergeCharFormat( format );
530 mTextEdit->mergeCurrentCharFormat( format );
531 mTextEdit->setFocus( Qt::TabFocusReason );
532}
533
534void QgsRichTextEditor::slotCursorPositionChanged()
535{
536 QTextList *l = mTextEdit->textCursor().currentList();
537 if ( mLastBlockList && ( l == mLastBlockList || ( l != nullptr && mLastBlockList != nullptr
538 && l->format().style() == mLastBlockList->format().style() ) ) )
539 {
540 return;
541 }
542 mLastBlockList = l;
543 if ( l )
544 {
545 const QTextListFormat listFormat = l->format();
546 if ( listFormat.style() == QTextListFormat::ListDisc )
547 {
548 mActionBulletList->setChecked( true );
549 mActionOrderedList->setChecked( false );
550 }
551 else if ( listFormat.style() == QTextListFormat::ListDecimal )
552 {
553 mActionBulletList->setChecked( false );
554 mActionOrderedList->setChecked( true );
555 }
556 else
557 {
558 mActionBulletList->setChecked( false );
559 mActionOrderedList->setChecked( false );
560 }
561 }
562 else
563 {
564 mActionBulletList->setChecked( false );
565 mActionOrderedList->setChecked( false );
566 }
567}
568
569void QgsRichTextEditor::fontChanged( const QFont &f )
570{
571 mFontSizeCombo->setCurrentIndex( mFontSizeCombo->findData( f.pointSize() ) );
572 mActionBold->setChecked( f.bold() );
573 mActionItalic->setChecked( f.italic() );
574 mActionUnderline->setChecked( f.underline() );
575 mActionStrikeOut->setChecked( f.strikeOut() );
576 if ( f.pointSize() == mFontSizeH1 )
577 {
578 mParagraphStyleCombo->setCurrentIndex( ParagraphHeading1 );
579 }
580 else if ( f.pointSize() == mFontSizeH2 )
581 {
582 mParagraphStyleCombo->setCurrentIndex( ParagraphHeading2 );
583 }
584 else if ( f.pointSize() == mFontSizeH3 )
585 {
586 mParagraphStyleCombo->setCurrentIndex( ParagraphHeading3 );
587 }
588 else if ( f.pointSize() == mFontSizeH4 )
589 {
590 mParagraphStyleCombo->setCurrentIndex( ParagraphHeading4 );
591 }
592 else
593 {
594 if ( f.fixedPitch() && f.family() == mMonospaceFontFamily )
595 {
596 mParagraphStyleCombo->setCurrentIndex( ParagraphMonospace );
597 }
598 else
599 {
600 mParagraphStyleCombo->setCurrentIndex( ParagraphStandard );
601 }
602 }
603 if ( mTextEdit->textCursor().currentList() )
604 {
605 const QTextListFormat listFormat = mTextEdit->textCursor().currentList()->format();
606 if ( listFormat.style() == QTextListFormat::ListDisc )
607 {
608 mActionBulletList->setChecked( true );
609 mActionOrderedList->setChecked( false );
610 }
611 else if ( listFormat.style() == QTextListFormat::ListDecimal )
612 {
613 mActionBulletList->setChecked( false );
614 mActionOrderedList->setChecked( true );
615 }
616 else
617 {
618 mActionBulletList->setChecked( false );
619 mActionOrderedList->setChecked( false );
620 }
621 }
622 else
623 {
624 mActionBulletList->setChecked( false );
625 mActionOrderedList->setChecked( false );
626 }
627}
628
629void QgsRichTextEditor::fgColorChanged( const QColor &c )
630{
631 whileBlocking( mForeColorButton )->setColor( c );
632}
633
634void QgsRichTextEditor::bgColorChanged( const QColor &c )
635{
636 if ( c.isValid() )
637 whileBlocking( mBackColorButton )->setColor( c );
638 else
639 whileBlocking( mBackColorButton )->setToNull();
640}
641
642void QgsRichTextEditor::slotCurrentCharFormatChanged( const QTextCharFormat &format )
643{
644 fontChanged( format.font() );
645 bgColorChanged( ( format.background().isOpaque() ) ? format.background().color() : QColor() );
646 fgColorChanged( ( format.foreground().isOpaque() ) ? format.foreground().color() : palette().windowText().color() );
647 mActionInsertLink->setChecked( format.isAnchor() );
648}
649
650void QgsRichTextEditor::slotClipboardDataChanged()
651{
652#ifndef QT_NO_CLIPBOARD
653 if ( const QMimeData *md = QApplication::clipboard()->mimeData() )
654 mActionPaste->setEnabled( md->hasText() );
655#endif
656}
657
658void QgsRichTextEditor::increaseIndentation()
659{
660 indent( +1 );
661}
662
663void QgsRichTextEditor::decreaseIndentation()
664{
665 indent( -1 );
666}
667
668void QgsRichTextEditor::indent( int delta )
669{
670 QTextCursor cursor = mTextEdit->textCursor();
671 cursor.beginEditBlock();
672 QTextBlockFormat format = cursor.blockFormat();
673 const int indent = format.indent();
674 if ( indent + delta >= 0 )
675 {
676 format.setIndent( indent + delta );
677 }
678 cursor.setBlockFormat( format );
679 cursor.endEditBlock();
680}
681
682void QgsRichTextEditor::setText( const QString &text )
683{
684 if ( text.isEmpty() )
685 {
686 setPlainText( text );
687 return;
688 }
689 if ( text[0] == '<' )
690 {
691 setHtml( text );
692 }
693 else
694 {
695 setPlainText( text );
696 }
697}
698
699void QgsRichTextEditor::insertImage()
700{
701 const QSettings s;
702 const QString attdir = s.value( QStringLiteral( "general/filedialog-path" ) ).toString();
703 const QString file = QFileDialog::getOpenFileName( this,
704 tr( "Select an image" ),
705 attdir,
706 tr( "JPEG (*.jpg);; GIF (*.gif);; PNG (*.png);; BMP (*.bmp);; All (*)" ) );
707 if ( file.isEmpty() )
708 return;
709
710 const QImage image = QImageReader( file ).read();
711
712 mTextEdit->dropImage( image, QFileInfo( file ).suffix().toUpper().toLocal8Bit().data() );
713}
A HTML editor based on QScintilla2.
static QFont getMonospaceFont()
Returns the monospaced font to use for code editors.
A cross platform button subclass for selecting colors.
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
void setColorDialogTitle(const QString &title)
Set the title for the color chooser dialog window.
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.
void setAllowOpacity(bool allowOpacity)
Sets whether opacity modification (transparency) is permitted for the color.
void setShowNoColor(const bool showNoColorOption)
Sets whether the "no color" option should be shown in the button's drop-down menu.
void setToNull()
Sets color to null.
void setColor(const QColor &color)
Sets the current color for the button.
QgsRichTextEditor(QWidget *parent=nullptr)
Constructor for QgsRichTextEditor, with the specified parent widget.
QString toPlainText() const
Returns the widget's content as a plain text string.
QString toHtml() const
Returns the widget's content as a HTML string.
void textChanged()
Emitted when the text contents are changed.
void clearSource()
Clears the current text from the widget.
void focusInEvent(QFocusEvent *event) override
void setText(const QString &text)
Sets the text to show in the widget.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
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
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:5111