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