Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
richtexteditor.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:significant reason:default
4
8#include "ui_addlinkdialog.h"
9
10#include "iconloader_p.h"
11
12#include <QtDesigner/abstractformeditor.h>
13#include <QtDesigner/abstractsettings.h>
14
15#include <QtWidgets/qcolordialog.h>
16#include <QtWidgets/qcombobox.h>
17#include <QtWidgets/qmenu.h>
18#include <QtWidgets/qtabwidget.h>
19#include <QtWidgets/qtoolbar.h>
20#include <QtWidgets/qtoolbutton.h>
21#include <QtWidgets/qboxlayout.h>
22#include <QtWidgets/qpushbutton.h>
23#include <QtWidgets/qdialogbuttonbox.h>
24
25#include <QtGui/qaction.h>
26#include <QtGui/qactiongroup.h>
27#include <QtGui/qevent.h>
28#include <QtGui/qfontdatabase.h>
29#include <QtGui/qicon.h>
30#include <QtGui/qpainter.h>
31#include <QtGui/qtextcursor.h>
32#include <QtGui/qtextdocument.h>
33#include <QtGui/qtextobject.h>
34
35#include <QtCore/qlist.h>
36#include <QtCore/qmap.h>
37#include <QtCore/qpointer.h>
38#include <QtCore/qxmlstream.h>
39
40#include <algorithm>
41
42QT_BEGIN_NAMESPACE
43
44using namespace Qt::StringLiterals;
45
46static constexpr auto RichTextDialogGroupC = "RichTextDialog"_L1;
47static constexpr auto GeometryKeyC = "Geometry"_L1;
48static constexpr auto TabKeyC = "Tab"_L1;
49
50const bool simplifyRichTextDefault = true;
51
52namespace qdesigner_internal {
53
54// Richtext simplification filter helpers: Elements to be discarded
55static inline bool filterElement(QStringView name)
56{
57 return name != "meta"_L1 && name != "style"_L1;
58}
59
60// Richtext simplification filter helpers: Filter attributes of elements
61static inline void filterAttributes(QStringView name,
62 QXmlStreamAttributes *atts,
63 bool *paragraphAlignmentFound)
64{
65 if (atts->isEmpty())
66 return;
67
68 // No style attributes for <body>
69 if (name == "body"_L1) {
70 atts->clear();
71 return;
72 }
73
74 // Clean out everything except 'align' for 'p'
75 if (name == "p"_L1) {
76 for (auto it = atts->begin(); it != atts->end(); ) {
77 if (it->name() == "align"_L1) {
78 ++it;
79 *paragraphAlignmentFound = true;
80 } else {
81 it = atts->erase(it);
82 }
83 }
84 return;
85 }
86}
87
88// Richtext simplification filter helpers: Check for blank QStringView.
89static inline bool isWhiteSpace(QStringView in)
90{
91 return std::all_of(in.cbegin(), in.cend(),
92 [](QChar c) { return c.isSpace(); });
93}
94
95// Richtext simplification filter: Remove hard-coded font settings,
96// <style> elements, <p> attributes other than 'align' and
97// and unnecessary meta-information.
98QString simplifyRichTextFilter(const QString &in, bool *isPlainTextPtr = nullptr)
99{
100 unsigned elementCount = 0;
101 bool paragraphAlignmentFound = false;
102 QString out;
103 QXmlStreamReader reader(in);
104 QXmlStreamWriter writer(&out);
105 writer.setAutoFormatting(false);
106 writer.setAutoFormattingIndent(0);
107
108 while (!reader.atEnd()) {
109 switch (reader.readNext()) {
110 case QXmlStreamReader::StartElement:
111 elementCount++;
112 if (filterElement(reader.name())) {
113 const auto name = reader.name();
114 QXmlStreamAttributes attributes = reader.attributes();
115 filterAttributes(name, &attributes, &paragraphAlignmentFound);
116 writer.writeStartElement(name.toString());
117 if (!attributes.isEmpty())
118 writer.writeAttributes(attributes);
119 } else {
120 reader.readElementText(); // Skip away all nested elements and characters.
121 }
122 break;
123 case QXmlStreamReader::Characters:
124 if (!isWhiteSpace(reader.text()))
125 writer.writeCharacters(reader.text().toString());
126 break;
127 case QXmlStreamReader::EndElement:
128 writer.writeEndElement();
129 break;
130 default:
131 break;
132 }
133 }
134 // Check for plain text (no spans, just <html><head><body><p>)
135 if (isPlainTextPtr)
136 *isPlainTextPtr = !paragraphAlignmentFound && elementCount == 4u; //
137 return out;
138}
139
141{
143public:
144 explicit RichTextEditor(QWidget *parent = nullptr);
145 void setDefaultFont(QFont font);
146
147 QToolBar *createToolBar(QDesignerFormEditorInterface *core, QWidget *parent = nullptr);
148
149 QString text(Qt::TextFormat format) const;
150
151 bool simplifyRichText() const { return m_simplifyRichText; }
152
153public slots:
154 void setFontBold(bool b);
155 void setFontPointSize(double);
156 void setText(const QString &text);
158
159signals:
162
163private:
164 bool m_simplifyRichText;
165};
166
167class AddLinkDialog : public QDialog
168{
170
171public:
174
176
177public slots:
179
180private:
181 RichTextEditor *m_editor;
182 QT_PREPEND_NAMESPACE(Ui)::AddLinkDialog *m_ui;
183};
184
185AddLinkDialog::AddLinkDialog(RichTextEditor *editor, QWidget *parent) :
186 QDialog(parent),
187 m_ui(new QT_PREPEND_NAMESPACE(Ui)::AddLinkDialog)
188{
189 m_ui->setupUi(this);
190
191 m_editor = editor;
192}
193
195{
196 delete m_ui;
197}
198
200{
201 // Set initial focus
202 const QTextCursor cursor = m_editor->textCursor();
203 if (cursor.hasSelection()) {
204 m_ui->titleInput->setText(cursor.selectedText());
205 m_ui->urlInput->setFocus();
206 } else {
207 m_ui->titleInput->setFocus();
208 }
209
210 return exec();
211}
212
213void AddLinkDialog::accept()
214{
215 const QString title = m_ui->titleInput->text();
216 const QString url = m_ui->urlInput->text();
217
218 if (!title.isEmpty()) {
219 const QString html = "<a href=\""_L1 + url + "\">"_L1 + title + "</a>"_L1;
220 m_editor->insertHtml(html);
221 }
222
223 m_ui->titleInput->clear();
224 m_ui->urlInput->clear();
225
226 QDialog::accept();
227}
228
230{
232
233public:
236 {}
237
239
240private slots:
242};
243
244void HtmlTextEdit::contextMenuEvent(QContextMenuEvent *event)
245{
246 QMenu *menu = createStandardContextMenu();
247 QMenu *htmlMenu = new QMenu(tr("Insert HTML entity"), menu);
248
249 typedef struct {
250 const char *text;
251 const char *entity;
252 } Entry;
253
254 const Entry entries[] = {
255 { "&&amp; (&&)", "&amp;" },
256 { "&&nbsp;", "&nbsp;" },
257 { "&&lt; (<)", "&lt;" },
258 { "&&gt; (>)", "&gt;" },
259 { "&&copy; (Copyright)", "&copy;" },
260 { "&&reg; (Trade Mark)", "&reg;" },
261 };
262
263 for (const Entry &e : entries) {
264 QAction *entityAction = new QAction(QLatin1StringView(e.text),
265 htmlMenu);
266 entityAction->setData(QLatin1StringView(e.entity));
267 htmlMenu->addAction(entityAction);
268 }
269
270 menu->addMenu(htmlMenu);
271 connect(htmlMenu, &QMenu::triggered, this, &HtmlTextEdit::actionTriggered);
272 menu->exec(event->globalPos());
273 delete menu;
274}
275
276void HtmlTextEdit::actionTriggered(QAction *action)
277{
278 insertPlainText(action->data().toString());
279}
280
281class ColorAction : public QAction
282{
284
285public:
287
288 const QColor& color() const { return m_color; }
289 void setColor(const QColor &color);
290
291signals:
293
294private slots:
295 void chooseColor();
296
297private:
298 QColor m_color;
299};
300
301ColorAction::ColorAction(QObject *parent):
302 QAction(parent)
303{
304 setText(tr("Text Color"));
305 setColor(Qt::black);
306 connect(this, &QAction::triggered, this, &ColorAction::chooseColor);
307}
308
309void ColorAction::setColor(const QColor &color)
310{
311 if (color == m_color)
312 return;
313 m_color = color;
314 QPixmap pix(24, 24);
315 QPainter painter(&pix);
316 painter.setRenderHint(QPainter::Antialiasing, false);
317 painter.fillRect(pix.rect(), m_color);
318 painter.setPen(m_color.darker());
319 painter.drawRect(pix.rect().adjusted(0, 0, -1, -1));
320 setIcon(pix);
321}
322
323void ColorAction::chooseColor()
324{
325 const QColor col = QColorDialog::getColor(m_color, nullptr);
326 if (col.isValid() && col != m_color) {
327 setColor(col);
328 emit colorChanged(m_color);
329 }
330}
331
333{
335public:
338 QWidget *parent = nullptr);
339
340public slots:
342
343private slots:
345 void sizeInputActivated(const QString &size);
346 void colorChanged(const QColor &color);
347 void setVAlignSuper(bool super);
348 void setVAlignSub(bool sub);
349 void insertLink();
350 void insertImage();
351 void layoutDirectionChanged();
352
353private:
354 QAction *m_bold_action;
355 QAction *m_italic_action;
356 QAction *m_underline_action;
357 QAction *m_valign_sup_action;
358 QAction *m_valign_sub_action;
359 QAction *m_align_left_action;
360 QAction *m_align_center_action;
361 QAction *m_align_right_action;
362 QAction *m_align_justify_action;
363 QAction *m_layoutDirectionAction;
364 QAction *m_link_action;
365 QAction *m_image_action;
366 QAction *m_simplify_richtext_action;
367 ColorAction *m_color_action;
368 QComboBox *m_font_size_input;
369
370 QDesignerFormEditorInterface *m_core;
371 QPointer<RichTextEditor> m_editor;
372};
373
374static QAction *createCheckableAction(const QIcon &icon, const QString &text,
375 QObject *parent = nullptr)
376{
377 QAction *result = new QAction(parent);
378 result->setIcon(icon);
379 result->setText(text);
380 result->setCheckable(true);
381 result->setChecked(false);
382 return result;
383}
384
385RichTextEditorToolBar::RichTextEditorToolBar(QDesignerFormEditorInterface *core,
386 RichTextEditor *editor,
387 QWidget *parent) :
388 QToolBar(parent),
389 m_link_action(new QAction(this)),
390 m_image_action(new QAction(this)),
391 m_color_action(new ColorAction(this)),
392 m_font_size_input(new QComboBox),
393 m_core(core),
394 m_editor(editor)
395{
396 // Font size combo box
397 m_font_size_input->setEditable(false);
398 const auto font_sizes = QFontDatabase::standardSizes();
399 for (int font_size : font_sizes)
400 m_font_size_input->addItem(QString::number(font_size));
401
402 connect(m_font_size_input, &QComboBox::textActivated,
403 this, &RichTextEditorToolBar::sizeInputActivated);
404 addWidget(m_font_size_input);
405
406 addSeparator();
407
408 // Bold, italic and underline buttons
409
410 m_bold_action = createCheckableAction(
411 createIconSet(QIcon::ThemeIcon::FormatTextBold,
412 "textbold.png"_L1), tr("Bold"), this);
413 connect(m_bold_action, &QAction::triggered, editor, &RichTextEditor::setFontBold);
414 m_bold_action->setShortcut(tr("CTRL+B"));
415 addAction(m_bold_action);
416
417 m_italic_action = createCheckableAction(
418 createIconSet(QIcon::ThemeIcon::FormatTextItalic,
419 "textitalic.png"_L1), tr("Italic"), this);
420 connect(m_italic_action, &QAction::triggered, editor, &RichTextEditor::setFontItalic);
421 m_italic_action->setShortcut(tr("CTRL+I"));
422 addAction(m_italic_action);
423
424 m_underline_action = createCheckableAction(
425 createIconSet(QIcon::ThemeIcon::FormatTextUnderline,
426 "textunder.png"_L1), tr("Underline"), this);
427 connect(m_underline_action, &QAction::triggered, editor, &RichTextEditor::setFontUnderline);
428 m_underline_action->setShortcut(tr("CTRL+U"));
429 addAction(m_underline_action);
430
431 addSeparator();
432
433 // Left, center, right and justified alignment buttons
434
435 QActionGroup *alignment_group = new QActionGroup(this);
436 connect(alignment_group, &QActionGroup::triggered,
437 this, &RichTextEditorToolBar::alignmentActionTriggered);
438
439 m_align_left_action = createCheckableAction(
440 createIconSet(QIcon::ThemeIcon::FormatJustifyLeft,
441 "textleft.png"_L1), tr("Left Align"), alignment_group);
442 addAction(m_align_left_action);
443
444 m_align_center_action = createCheckableAction(
445 createIconSet(QIcon::ThemeIcon::FormatJustifyCenter,
446 "textcenter.png"_L1), tr("Center"), alignment_group);
447 addAction(m_align_center_action);
448
449 m_align_right_action = createCheckableAction(
450 createIconSet(QIcon::ThemeIcon::FormatJustifyRight,
451 "textright.png"_L1), tr("Right Align"), alignment_group);
452 addAction(m_align_right_action);
453
454 m_align_justify_action = createCheckableAction(
455 createIconSet(QIcon::ThemeIcon::FormatJustifyFill,
456 "textjustify.png"_L1), tr("Justify"), alignment_group);
457 addAction(m_align_justify_action);
458
459 m_layoutDirectionAction = createCheckableAction(
460 createIconSet(QIcon::ThemeIcon::FormatTextDirectionRtl,
461 "righttoleft.png"_L1), tr("Right to Left"));
462 connect(m_layoutDirectionAction, &QAction::triggered,
463 this, &RichTextEditorToolBar::layoutDirectionChanged);
464 addAction(m_layoutDirectionAction);
465
466 addSeparator();
467
468 // Superscript and subscript buttons
469
470 m_valign_sup_action = createCheckableAction(
471 createIconSet("textsuperscript.png"_L1), tr("Superscript"), this);
472 connect(m_valign_sup_action, &QAction::triggered,
473 this, &RichTextEditorToolBar::setVAlignSuper);
474 addAction(m_valign_sup_action);
475
476 m_valign_sub_action = createCheckableAction(
477 createIconSet("textsubscript.png"_L1), tr("Subscript"), this);
478 connect(m_valign_sub_action, &QAction::triggered,
479 this, &RichTextEditorToolBar::setVAlignSub);
480 addAction(m_valign_sub_action);
481
482 addSeparator();
483
484 // Insert hyperlink and image buttons
485
486 m_link_action->setIcon(createIconSet("textanchor.png"_L1));
487 m_link_action->setText(tr("Insert &Link"));
488 connect(m_link_action, &QAction::triggered, this, &RichTextEditorToolBar::insertLink);
489 addAction(m_link_action);
490
491 m_image_action->setIcon(createIconSet("insertimage.png"_L1));
492 m_image_action->setText(tr("Insert &Image"));
493 connect(m_image_action, &QAction::triggered, this, &RichTextEditorToolBar::insertImage);
494 addAction(m_image_action);
495
496 addSeparator();
497
498 // Text color button
499 connect(m_color_action, &ColorAction::colorChanged,
500 this, &RichTextEditorToolBar::colorChanged);
501 addAction(m_color_action);
502
503 addSeparator();
504
505 // Simplify rich text
506 m_simplify_richtext_action
507 = createCheckableAction(createIconSet("simplifyrichtext.png"_L1), tr("Simplify Rich Text"));
508 connect(m_simplify_richtext_action, &QAction::triggered,
510 m_simplify_richtext_action->setChecked(m_editor->simplifyRichText());
511 connect(m_editor.data(), &RichTextEditor::simplifyRichTextChanged,
512 m_simplify_richtext_action, &QAction::setChecked);
513 addAction(m_simplify_richtext_action);
514
515 connect(editor, &QTextEdit::textChanged, this, &RichTextEditorToolBar::updateActions);
516 connect(editor, &RichTextEditor::stateChanged, this, &RichTextEditorToolBar::updateActions);
517
518 updateActions();
519}
520
521void RichTextEditorToolBar::alignmentActionTriggered(QAction *action)
522{
523 Qt::Alignment new_alignment;
524
525 if (action == m_align_left_action) {
526 new_alignment = Qt::AlignLeft;
527 } else if (action == m_align_center_action) {
528 new_alignment = Qt::AlignCenter;
529 } else if (action == m_align_right_action) {
530 new_alignment = Qt::AlignRight;
531 } else {
532 new_alignment = Qt::AlignJustify;
533 }
534
535 m_editor->setAlignment(new_alignment);
536}
537
538void RichTextEditorToolBar::colorChanged(const QColor &color)
539{
540 m_editor->setTextColor(color);
541 m_editor->setFocus();
542}
543
544void RichTextEditorToolBar::sizeInputActivated(const QString &size)
545{
546 bool ok;
547 int i = size.toInt(&ok);
548 if (!ok)
549 return;
550
551 m_editor->setFontPointSize(i);
552 m_editor->setFocus();
553}
554
555void RichTextEditorToolBar::setVAlignSuper(bool super)
556{
557 const QTextCharFormat::VerticalAlignment align = super ?
558 QTextCharFormat::AlignSuperScript : QTextCharFormat::AlignNormal;
559
560 QTextCharFormat charFormat = m_editor->currentCharFormat();
561 charFormat.setVerticalAlignment(align);
562 m_editor->setCurrentCharFormat(charFormat);
563
564 m_valign_sub_action->setChecked(false);
565}
566
567void RichTextEditorToolBar::setVAlignSub(bool sub)
568{
569 const QTextCharFormat::VerticalAlignment align = sub ?
570 QTextCharFormat::AlignSubScript : QTextCharFormat::AlignNormal;
571
572 QTextCharFormat charFormat = m_editor->currentCharFormat();
573 charFormat.setVerticalAlignment(align);
574 m_editor->setCurrentCharFormat(charFormat);
575
576 m_valign_sup_action->setChecked(false);
577}
578
579void RichTextEditorToolBar::insertLink()
580{
581 AddLinkDialog linkDialog(m_editor, this);
582 linkDialog.showDialog();
583 m_editor->setFocus();
584}
585
586void RichTextEditorToolBar::insertImage()
587{
588 const QString path = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), QString(), this);
589 if (!path.isEmpty())
590 m_editor->insertHtml(QStringLiteral("<img src=\"") + path + QStringLiteral("\"/>"));
591}
592
593void RichTextEditorToolBar::layoutDirectionChanged()
594{
595 QTextCursor cursor = m_editor->textCursor();
596 QTextBlock block = cursor.block();
597 if (block.isValid()) {
598 QTextBlockFormat format = block.blockFormat();
599 const Qt::LayoutDirection newDirection = m_layoutDirectionAction->isChecked() ? Qt::RightToLeft : Qt::LeftToRight;
600 if (format.layoutDirection() != newDirection) {
601 format.setLayoutDirection(newDirection);
602 cursor.setBlockFormat(format);
603 }
604 }
605}
606
607void RichTextEditorToolBar::updateActions()
608{
609 if (m_editor == nullptr) {
610 setEnabled(false);
611 return;
612 }
613
614 const Qt::Alignment alignment = m_editor->alignment();
615 const QTextCursor cursor = m_editor->textCursor();
616 const QTextCharFormat charFormat = cursor.charFormat();
617 const QFont font = charFormat.font();
618 const QTextCharFormat::VerticalAlignment valign =
619 charFormat.verticalAlignment();
620 const bool superScript = valign == QTextCharFormat::AlignSuperScript;
621 const bool subScript = valign == QTextCharFormat::AlignSubScript;
622
623 if (alignment & Qt::AlignLeft) {
624 m_align_left_action->setChecked(true);
625 } else if (alignment & Qt::AlignRight) {
626 m_align_right_action->setChecked(true);
627 } else if (alignment & Qt::AlignHCenter) {
628 m_align_center_action->setChecked(true);
629 } else {
630 m_align_justify_action->setChecked(true);
631 }
632 m_layoutDirectionAction->setChecked(cursor.blockFormat().layoutDirection() == Qt::RightToLeft);
633
634 m_bold_action->setChecked(font.bold());
635 m_italic_action->setChecked(font.italic());
636 m_underline_action->setChecked(font.underline());
637 m_valign_sup_action->setChecked(superScript);
638 m_valign_sub_action->setChecked(subScript);
639
640 const int size = font.pointSize();
641 const int idx = m_font_size_input->findText(QString::number(size));
642 if (idx != -1)
643 m_font_size_input->setCurrentIndex(idx);
644
645 m_color_action->setColor(m_editor->textColor());
646}
647
648RichTextEditor::RichTextEditor(QWidget *parent)
649 : QTextEdit(parent), m_simplifyRichText(simplifyRichTextDefault)
650{
651 connect(this, &RichTextEditor::currentCharFormatChanged,
652 this, &RichTextEditor::stateChanged);
653 connect(this, &RichTextEditor::cursorPositionChanged,
654 this, &RichTextEditor::stateChanged);
655}
656
657QToolBar *RichTextEditor::createToolBar(QDesignerFormEditorInterface *core, QWidget *parent)
658{
659 return new RichTextEditorToolBar(core, this, parent);
660}
661
662void RichTextEditor::setFontBold(bool b)
663{
664 if (b)
665 setFontWeight(QFont::Bold);
666 else
667 setFontWeight(QFont::Normal);
668}
669
671{
672 QTextEdit::setFontPointSize(qreal(d));
673}
674
675void RichTextEditor::setText(const QString &text)
676{
677
678 if (Qt::mightBeRichText(text))
679 setHtml(text);
680 else
681 setPlainText(text);
682}
683
685{
686 if (v != m_simplifyRichText) {
687 m_simplifyRichText = v;
688 emit simplifyRichTextChanged(v);
689 }
690}
691
693{
694 // Some default fonts on Windows have a default size of 7.8,
695 // which results in complicated rich text generated by toHtml().
696 // Use an integer value.
697 const int pointSize = qRound(font.pointSizeF());
698 if (pointSize > 0 && !qFuzzyCompare(qreal(pointSize), font.pointSizeF())) {
699 font.setPointSize(pointSize);
700 }
701
702 document()->setDefaultFont(font);
703 if (font.pointSize() > 0)
704 setFontPointSize(font.pointSize());
705 else
706 setFontPointSize(QFontInfo(font).pointSize());
707 emit textChanged();
708}
709
710QString RichTextEditor::text(Qt::TextFormat format) const
711{
712 switch (format) {
713 case Qt::PlainText:
714 return toPlainText();
715 case Qt::RichText:
716 return m_simplifyRichText ? simplifyRichTextFilter(toHtml()) : toHtml();
717 default:
718 break;
719 }
720 const QString html = toHtml();
721 bool isPlainText;
722 const QString simplifiedHtml = simplifyRichTextFilter(html, &isPlainText);
723 if (isPlainText)
724 return toPlainText();
725 return m_simplifyRichText ? simplifiedHtml : html;
726}
727
733 m_state(Clean),
734 m_core(core),
736{
737 setWindowTitle(tr("Edit text"));
738
739 // Read settings
741 const QString rootKey = RichTextDialogGroupC + u'/';
746
749
754
755 // The toolbar needs to be created after the RichTextEditor
758
763
767
769 m_tab_widget->addTab(rich_edit, tr("Rich Text"));
770 m_tab_widget->addTab(plain_edit, tr("Source"));
773
776 ok_button->setText(tr("&OK"));
777 ok_button->setDefault(true);
781
782 QVBoxLayout *layout = new QVBoxLayout(this);
785
786 if (!lastGeometry.isEmpty())
788}
789
799
801{
803 switch (m_initialTab) {
804 case RichTextIndex:
807 break;
808 case SourceIndex:
811 break;
812 }
813 return exec();
814}
815
820
822{
823 // Generally simplify rich text unless verbose text is found.
824 const bool isSimplifiedRichText = !text.startsWith(QStringLiteral("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">"));
828 m_state = Clean;
829}
830
832{
833 // In autotext mode, if the user has changed the source, use that
834 if (format == Qt::AutoText && (m_state == Clean || m_state == SourceChanged))
835 return m_text_edit->toPlainText();
836 // If the plain text HTML editor is selected, first copy its contents over
837 // to the rich text editor so that it is converted to Qt-HTML or actual
838 // plain text.
841 return m_editor->text(format);
842}
843
845{
846 // Anything changed, is there a need for a conversion?
848 return;
850 return;
851 const State oldState = m_state;
852 // Remember the cursor position, since it is invalidated by setPlainText
854 const int position = new_edit->textCursor().position();
855
856 if (newIndex == SourceIndex)
858 else
860
863 if (cursor.position() > position) {
865 }
867 m_state = oldState; // Changed is triggered by setting the text
868}
869
871{
873}
874
876{
878}
879
880} // namespace qdesigner_internal
881
882QT_END_NAMESPACE
883
884#include "richtexteditor.moc"
void setColor(const QColor &color)
QToolBar * createToolBar(QDesignerFormEditorInterface *core, QWidget *parent=nullptr)
QString text(Qt::TextFormat format) const
void setText(const QString &text)
Auxiliary methods to store/retrieve settings.
static bool isWhiteSpace(QStringView in)
static void filterAttributes(QStringView name, QXmlStreamAttributes *atts, bool *paragraphAlignmentFound)
static bool filterElement(QStringView name)
QString simplifyRichTextFilter(const QString &in, bool *isPlainTextPtr=nullptr)
static QAction * createCheckableAction(const QIcon &icon, const QString &text, QObject *parent=nullptr)
static constexpr auto RichTextDialogGroupC
static constexpr auto TabKeyC
static constexpr auto GeometryKeyC
const bool simplifyRichTextDefault