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