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