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