QGIS API Documentation 3.41.0-Master (cea29feecf2)
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" ), tr( "Link URL:" ), QLineEdit::Normal, url, &ok );
444 if ( ok )
445 {
446 format.setAnchor( true );
447 format.setAnchorHref( newUrl );
448 format.setForeground( palette().color( QPalette::Link ) );
449 format.setFontUnderline( true );
450 }
451 else
452 {
453 unlink = true;
454 }
455 }
456 else
457 {
458 unlink = true;
459 }
460 if ( unlink )
461 {
462 format.setAnchor( false );
463 format.setForeground( palette().color( QPalette::Text ) );
464 format.setFontUnderline( false );
465 }
466 mergeFormatOnWordOrSelection( format );
467}
468
469void QgsRichTextEditor::textStyle( int )
470{
471 QTextCursor cursor = mTextEdit->textCursor();
472 cursor.beginEditBlock();
473
474 // standard
475 if ( !cursor.hasSelection() )
476 {
477 cursor.select( QTextCursor::BlockUnderCursor );
478 }
479 QTextCharFormat format;
480 cursor.setCharFormat( format );
481 mTextEdit->setCurrentCharFormat( format );
482
483 const ParagraphItems style = static_cast<ParagraphItems>( mParagraphStyleCombo->currentData().toInt() );
484
485 switch ( style )
486 {
487 case QgsRichTextEditor::ParagraphStandard:
488 break;
489
490 case QgsRichTextEditor::ParagraphHeading1:
491 format.setFontPointSize( mFontSizeH1 );
492 format.setFontWeight( QFont::Bold );
493 break;
494
495 case QgsRichTextEditor::ParagraphHeading2:
496 format.setFontPointSize( mFontSizeH2 );
497 format.setFontWeight( QFont::Bold );
498 format.setFontItalic( true );
499 break;
500
501 case QgsRichTextEditor::ParagraphHeading3:
502 format.setFontPointSize( mFontSizeH3 );
503 format.setFontWeight( QFont::Bold );
504 break;
505
506 case QgsRichTextEditor::ParagraphHeading4:
507 format.setFontPointSize( mFontSizeH4 );
508 format.setFontWeight( QFont::Bold );
509 format.setFontItalic( true );
510 break;
511
512 case QgsRichTextEditor::ParagraphMonospace:
513 {
514 format = cursor.charFormat();
515 format.setFontFamily( mMonospaceFontFamily );
516 format.setFontStyleHint( QFont::Monospace );
517 format.setFontFixedPitch( true );
518 break;
519 }
520 }
521
522 cursor.setCharFormat( format );
523 mTextEdit->setCurrentCharFormat( format );
524
525 cursor.endEditBlock();
526}
527
528void QgsRichTextEditor::textFgColor()
529{
530 QTextCharFormat format;
531 format.setForeground( mForeColorButton->color() );
532 mergeFormatOnWordOrSelection( format );
533}
534
535void QgsRichTextEditor::textBgColor()
536{
537 QTextCharFormat format;
538 const QColor col = mBackColorButton->color();
539 if ( col.isValid() )
540 {
541 format.setBackground( col );
542 }
543 else
544 {
545 format.clearBackground();
546 }
547 mergeFormatOnWordOrSelection( format );
548}
549
550void QgsRichTextEditor::listBullet( bool checked )
551{
552 if ( checked )
553 {
554 mActionOrderedList->setChecked( false );
555 }
556 list( checked, QTextListFormat::ListDisc );
557}
558
559void QgsRichTextEditor::listOrdered( bool checked )
560{
561 if ( checked )
562 {
563 mActionBulletList->setChecked( false );
564 }
565 list( checked, QTextListFormat::ListDecimal );
566}
567
568void QgsRichTextEditor::list( bool checked, QTextListFormat::Style style )
569{
570 QTextCursor cursor = mTextEdit->textCursor();
571 cursor.beginEditBlock();
572 if ( !checked )
573 {
574 const QTextBlockFormat originalFormat = cursor.blockFormat();
575 QTextBlockFormat format;
576 format.setIndent( originalFormat.indent() );
577 cursor.setBlockFormat( format );
578 }
579 else
580 {
581 QTextListFormat listFormat;
582 if ( cursor.currentList() )
583 {
584 listFormat = cursor.currentList()->format();
585 }
586 listFormat.setStyle( style );
587 cursor.createList( listFormat );
588 }
589 cursor.endEditBlock();
590}
591
592void QgsRichTextEditor::mergeFormatOnWordOrSelection( const QTextCharFormat &format )
593{
594 QTextCursor cursor = mTextEdit->textCursor();
595 if ( !cursor.hasSelection() )
596 {
597 cursor.select( QTextCursor::WordUnderCursor );
598 }
599 cursor.mergeCharFormat( format );
600 mTextEdit->mergeCurrentCharFormat( format );
601 mTextEdit->setFocus( Qt::TabFocusReason );
602}
603
604void QgsRichTextEditor::slotCursorPositionChanged()
605{
606 QTextList *l = mTextEdit->textCursor().currentList();
607 if ( mLastBlockList && ( l == mLastBlockList || ( l && mLastBlockList && l->format().style() == mLastBlockList->format().style() ) ) )
608 {
609 return;
610 }
611 mLastBlockList = l;
612 if ( l )
613 {
614 const QTextListFormat listFormat = l->format();
615 if ( listFormat.style() == QTextListFormat::ListDisc )
616 {
617 mActionBulletList->setChecked( true );
618 mActionOrderedList->setChecked( false );
619 }
620 else if ( listFormat.style() == QTextListFormat::ListDecimal )
621 {
622 mActionBulletList->setChecked( false );
623 mActionOrderedList->setChecked( true );
624 }
625 else
626 {
627 mActionBulletList->setChecked( false );
628 mActionOrderedList->setChecked( false );
629 }
630 }
631 else
632 {
633 mActionBulletList->setChecked( false );
634 mActionOrderedList->setChecked( false );
635 }
636}
637
638void QgsRichTextEditor::fontChanged( const QFont &f )
639{
640 mFontSizeCombo->setCurrentIndex( mFontSizeCombo->findData( f.pointSize() ) );
641 mActionBold->setChecked( f.bold() );
642 mActionItalic->setChecked( f.italic() );
643 mActionUnderline->setChecked( f.underline() );
644 mActionStrikeOut->setChecked( f.strikeOut() );
645 if ( f.pointSize() == mFontSizeH1 )
646 {
647 mParagraphStyleCombo->setCurrentIndex( ParagraphHeading1 );
648 }
649 else if ( f.pointSize() == mFontSizeH2 )
650 {
651 mParagraphStyleCombo->setCurrentIndex( ParagraphHeading2 );
652 }
653 else if ( f.pointSize() == mFontSizeH3 )
654 {
655 mParagraphStyleCombo->setCurrentIndex( ParagraphHeading3 );
656 }
657 else if ( f.pointSize() == mFontSizeH4 )
658 {
659 mParagraphStyleCombo->setCurrentIndex( ParagraphHeading4 );
660 }
661 else
662 {
663 if ( f.fixedPitch() && f.family() == mMonospaceFontFamily )
664 {
665 mParagraphStyleCombo->setCurrentIndex( ParagraphMonospace );
666 }
667 else
668 {
669 mParagraphStyleCombo->setCurrentIndex( ParagraphStandard );
670 }
671 }
672 if ( mTextEdit->textCursor().currentList() )
673 {
674 const QTextListFormat listFormat = mTextEdit->textCursor().currentList()->format();
675 if ( listFormat.style() == QTextListFormat::ListDisc )
676 {
677 mActionBulletList->setChecked( true );
678 mActionOrderedList->setChecked( false );
679 }
680 else if ( listFormat.style() == QTextListFormat::ListDecimal )
681 {
682 mActionBulletList->setChecked( false );
683 mActionOrderedList->setChecked( true );
684 }
685 else
686 {
687 mActionBulletList->setChecked( false );
688 mActionOrderedList->setChecked( false );
689 }
690 }
691 else
692 {
693 mActionBulletList->setChecked( false );
694 mActionOrderedList->setChecked( false );
695 }
696}
697
698void QgsRichTextEditor::fgColorChanged( const QColor &c )
699{
700 whileBlocking( mForeColorButton )->setColor( c );
701}
702
703void QgsRichTextEditor::bgColorChanged( const QColor &c )
704{
705 if ( c.isValid() )
706 whileBlocking( mBackColorButton )->setColor( c );
707 else
708 whileBlocking( mBackColorButton )->setToNull();
709}
710
711void QgsRichTextEditor::slotCurrentCharFormatChanged( const QTextCharFormat &format )
712{
713 fontChanged( format.font() );
714 bgColorChanged( ( format.background().isOpaque() ) ? format.background().color() : QColor() );
715 fgColorChanged( ( format.foreground().isOpaque() ) ? format.foreground().color() : palette().windowText().color() );
716 mActionInsertLink->setChecked( format.isAnchor() );
717}
718
719void QgsRichTextEditor::slotClipboardDataChanged()
720{
721#ifndef QT_NO_CLIPBOARD
722 if ( const QMimeData *md = QApplication::clipboard()->mimeData() )
723 mActionPaste->setEnabled( md->hasText() );
724#endif
725}
726
727void QgsRichTextEditor::increaseIndentation()
728{
729 indent( +1 );
730}
731
732void QgsRichTextEditor::decreaseIndentation()
733{
734 indent( -1 );
735}
736
737void QgsRichTextEditor::indent( int delta )
738{
739 QTextCursor cursor = mTextEdit->textCursor();
740 cursor.beginEditBlock();
741 QTextBlockFormat format = cursor.blockFormat();
742 const int indent = format.indent();
743 if ( indent + delta >= 0 )
744 {
745 format.setIndent( indent + delta );
746 }
747 cursor.setBlockFormat( format );
748 cursor.endEditBlock();
749}
750
751void QgsRichTextEditor::setText( const QString &text )
752{
753 if ( text.isEmpty() )
754 {
755 setPlainText( text );
756 return;
757 }
758 if ( text[0] == '<' )
759 {
760 setHtml( text );
761 }
762 else
763 {
764 setPlainText( text );
765 }
766}
767
768void QgsRichTextEditor::insertImage()
769{
770 const QSettings s;
771 const QString attdir = s.value( QStringLiteral( "general/filedialog-path" ) ).toString();
772 const QString file = QFileDialog::getOpenFileName( this, tr( "Select an image" ), attdir, tr( "JPEG (*.jpg);; GIF (*.gif);; PNG (*.png);; BMP (*.bmp);; All (*)" ) );
773 if ( file.isEmpty() )
774 return;
775
776 const QImage image = QImageReader( file ).read();
777
778 mTextEdit->dropImage( image, QFileInfo( file ).suffix().toUpper().toLocal8Bit().data() );
779}
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:5928