diff options
Diffstat (limited to 'examples/widgets/richtext')
13 files changed, 261 insertions, 19 deletions
diff --git a/examples/widgets/richtext/textedit/CMakeLists.txt b/examples/widgets/richtext/textedit/CMakeLists.txt index 9166f6748a..487f708b34 100644 --- a/examples/widgets/richtext/textedit/CMakeLists.txt +++ b/examples/widgets/richtext/textedit/CMakeLists.txt @@ -11,7 +11,7 @@ add_qt_executable(textedit SOURCES main.cpp textedit.cpp textedit.h - LIBRARIES + PUBLIC_LIBRARIES Qt::Widgets ) @@ -19,6 +19,8 @@ add_qt_executable(textedit add_qt_resource(textedit "textedit" PREFIX "/" FILES example.html images/logo32.png + images/mac/checkbox-checked.png + images/mac/checkbox.png images/mac/editcopy.png images/mac/editcut.png images/mac/editpaste.png @@ -29,6 +31,8 @@ add_qt_resource(textedit "textedit" PREFIX "/" FILES images/mac/fileopen.png images/mac/fileprint.png images/mac/filesave.png + images/mac/format-indent-less.png + images/mac/format-indent-more.png images/mac/textbold.png images/mac/textcenter.png images/mac/textitalic.png @@ -38,6 +42,8 @@ add_qt_resource(textedit "textedit" PREFIX "/" FILES images/mac/textunder.png images/mac/zoomin.png images/mac/zoomout.png + images/win/checkbox-checked.png + images/win/checkbox.png images/win/editcopy.png images/win/editcut.png images/win/editpaste.png @@ -48,6 +54,8 @@ add_qt_resource(textedit "textedit" PREFIX "/" FILES images/win/fileopen.png images/win/fileprint.png images/win/filesave.png + images/win/format-indent-less.png + images/win/format-indent-more.png images/win/textbold.png images/win/textcenter.png images/win/textitalic.png @@ -59,7 +67,7 @@ add_qt_resource(textedit "textedit" PREFIX "/" FILES images/win/zoomout.png) -#### Keys ignored in scope 1:.:textedit.pro:<NONE>: +#### Keys ignored in scope 1:.:.:textedit.pro:<TRUE>: # EXAMPLE_FILES = "textedit.qdoc" # TEMPLATE = "app" @@ -67,9 +75,9 @@ add_qt_resource(textedit "textedit" PREFIX "/" FILES ##################################################################### extend_target(textedit CONDITION TARGET Qt::PrintSupport - LIBRARIES + PUBLIC_LIBRARIES Qt::PrintSupport ) -#### Keys ignored in scope 3:.:textedit.pro:build_all AND NOT build_pass: +#### Keys ignored in scope 3:.:.:textedit.pro:build_all AND NOT build_pass: # CONFIG = "-build_all" "release" diff --git a/examples/widgets/richtext/textedit/example.md b/examples/widgets/richtext/textedit/example.md new file mode 100644 index 0000000000..a16a9197b4 --- /dev/null +++ b/examples/widgets/richtext/textedit/example.md @@ -0,0 +1,102 @@ +# QTextEdit + +The QTextEdit widget is an advanced editor that supports formatted rich text. +It can be used to display HTML and other rich document formats. Internally, +QTextEdit uses the QTextDocument class to describe both the high-level +structure of each document and the low-level formatting of paragraphs. + +If you are viewing this document in the textedit example, you can edit this +document to explore Qt's rich text editing features. We have included some +comments in each of the following sections to encourage you to experiment. + +## Font and Paragraph Styles + +QTextEdit supports **bold**, *italic*, & ~~strikethrough~~ font styles, and +can display <span style="font-size:10pt; font-weight:600; +color:#00007f;">multicolored</span> text. Font families such as <span +style="font-family:Times New Roman">Times New Roman</span> and `Courier` +can also be used directly. *If you place the cursor in a region of styled text, +the controls in the tool bars will change to reflect the current style.* + +Paragraphs can be formatted so that the text is left-aligned, right-aligned, +centered, or fully justified. + +*Try changing the alignment of some text and resize the editor to see how the +text layout changes.* + +## Lists + +Different kinds of lists can be included in rich text documents. Standard +bullet lists can be nested, using different symbols for each level of the list: + +- Disc symbols are typically used for top-level list items. + * Circle symbols can be used to distinguish between items in lower-level + lists. + + Square symbols provide a reasonable alternative to discs and circles. + +Ordered lists can be created that can be used for tables of contents. Different +characters can be used to enumerate items, and we can use both Roman and Arabic +numerals in the same list structure: + +1. Introduction +2. Qt Tools + 1) Qt Assistant + 2) Qt Designer + 1. Form Editor + 2. Component Architecture + 3) Qt Linguist + +The list will automatically be renumbered if you add or remove items. *Try +adding new sections to the above list or removing existing item to see the +numbers change.* + +Task lists can be used to track progress on projects: + +- [ ] This is not yet done +- This is just a bullet point +- [x] This is done + +## Images + +Inline images are treated like ordinary ranges of characters in the text +editor, so they flow with the surrounding text. Images can also be selected in +the same way as text, making it easy to cut, copy, and paste them. + +![logo](images/logo32.png "logo") *Try to select this image by clicking and +dragging over it with the mouse, or use the text cursor to select it by holding +down Shift and using the arrow keys. You can then cut or copy it, and paste it +into different parts of this document.* + +## Tables + +QTextEdit can arrange and format tables, supporting features such as row and +column spans, text formatting within cells, and size constraints for columns. + +| | Development Tools | Programming Techniques | Graphical User Interfaces | +| ------------: | ----------------- | ---------------------- | ------------------------- | +| 9:00 - 11:00 | Introduction to Qt ||| +| 11:00 - 13:00 | Using qmake | Object-oriented Programming | Layouts in Qt | +| 13:00 - 15:00 | Qt Designer Tutorial | Extreme Programming | Writing Custom Styles | +| 15:00 - 17:00 | Qt Linguist and Internationalization | | | + +*Try adding text to the cells in the table and experiment with the alignment of +the paragraphs.* + +## Hyperlinks + +QTextEdit is designed to support hyperlinks between documents, and this feature +is used extensively in +[Qt Assistant](http://doc.qt.io/qt-5/qtassistant-index.html). Hyperlinks are +automatically created when an HTML file is imported into an editor. Since the +rich text framework supports hyperlinks natively, they can also be created +programatically. + +## Undo and Redo + +Full support for undo and redo operations is built into QTextEdit and the +underlying rich text framework. Operations on a document can be packaged +together to make editing a more comfortable experience for the user. + +*Try making changes to this document and press `Ctrl+Z` to undo them. You can +always recover the original contents of the document.* + diff --git a/examples/widgets/richtext/textedit/images/mac/checkbox-checked.png b/examples/widgets/richtext/textedit/images/mac/checkbox-checked.png Binary files differnew file mode 100644 index 0000000000..a072d7fb5c --- /dev/null +++ b/examples/widgets/richtext/textedit/images/mac/checkbox-checked.png diff --git a/examples/widgets/richtext/textedit/images/mac/checkbox.png b/examples/widgets/richtext/textedit/images/mac/checkbox.png Binary files differnew file mode 100644 index 0000000000..4064909712 --- /dev/null +++ b/examples/widgets/richtext/textedit/images/mac/checkbox.png diff --git a/examples/widgets/richtext/textedit/images/mac/format-indent-less.png b/examples/widgets/richtext/textedit/images/mac/format-indent-less.png Binary files differnew file mode 100644 index 0000000000..e38074e78b --- /dev/null +++ b/examples/widgets/richtext/textedit/images/mac/format-indent-less.png diff --git a/examples/widgets/richtext/textedit/images/mac/format-indent-more.png b/examples/widgets/richtext/textedit/images/mac/format-indent-more.png Binary files differnew file mode 100644 index 0000000000..1bdeabd354 --- /dev/null +++ b/examples/widgets/richtext/textedit/images/mac/format-indent-more.png diff --git a/examples/widgets/richtext/textedit/images/win/checkbox-checked.png b/examples/widgets/richtext/textedit/images/win/checkbox-checked.png Binary files differnew file mode 100644 index 0000000000..a072d7fb5c --- /dev/null +++ b/examples/widgets/richtext/textedit/images/win/checkbox-checked.png diff --git a/examples/widgets/richtext/textedit/images/win/checkbox.png b/examples/widgets/richtext/textedit/images/win/checkbox.png Binary files differnew file mode 100644 index 0000000000..4064909712 --- /dev/null +++ b/examples/widgets/richtext/textedit/images/win/checkbox.png diff --git a/examples/widgets/richtext/textedit/images/win/format-indent-less.png b/examples/widgets/richtext/textedit/images/win/format-indent-less.png Binary files differnew file mode 100644 index 0000000000..e38074e78b --- /dev/null +++ b/examples/widgets/richtext/textedit/images/win/format-indent-less.png diff --git a/examples/widgets/richtext/textedit/images/win/format-indent-more.png b/examples/widgets/richtext/textedit/images/win/format-indent-more.png Binary files differnew file mode 100644 index 0000000000..1bdeabd354 --- /dev/null +++ b/examples/widgets/richtext/textedit/images/win/format-indent-more.png diff --git a/examples/widgets/richtext/textedit/textedit.cpp b/examples/widgets/richtext/textedit/textedit.cpp index 3ad9f48b67..996bb8e0a4 100644 --- a/examples/widgets/richtext/textedit/textedit.cpp +++ b/examples/widgets/richtext/textedit/textedit.cpp @@ -71,6 +71,7 @@ #include <QCloseEvent> #include <QMessageBox> #include <QMimeData> +#include <QMimeDatabase> #if defined(QT_PRINTSUPPORT_LIB) #include <QtPrintSupport/qtprintsupportglobal.h> #if QT_CONFIG(printer) @@ -316,6 +317,14 @@ void TextEdit::setupTextActions() actionAlignJustify->setShortcut(Qt::CTRL + Qt::Key_J); actionAlignJustify->setCheckable(true); actionAlignJustify->setPriority(QAction::LowPriority); + const QIcon indentMoreIcon = QIcon::fromTheme("format-indent-more", QIcon(rsrcPath + "/format-indent-more.png")); + actionIndentMore = menu->addAction(indentMoreIcon, tr("&Indent"), this, &TextEdit::indent); + actionIndentMore->setShortcut(Qt::CTRL + Qt::Key_BracketRight); + actionIndentMore->setPriority(QAction::LowPriority); + const QIcon indentLessIcon = QIcon::fromTheme("format-indent-less", QIcon(rsrcPath + "/format-indent-less.png")); + actionIndentLess = menu->addAction(indentLessIcon, tr("&Unindent"), this, &TextEdit::unindent); + actionIndentLess->setShortcut(Qt::CTRL + Qt::Key_BracketLeft); + actionIndentLess->setPriority(QAction::LowPriority); // Make sure the alignLeft is always left of the alignRight QActionGroup *alignGroup = new QActionGroup(this); @@ -334,6 +343,10 @@ void TextEdit::setupTextActions() tb->addActions(alignGroup->actions()); menu->addActions(alignGroup->actions()); + tb->addAction(actionIndentMore); + tb->addAction(actionIndentLess); + menu->addAction(actionIndentMore); + menu->addAction(actionIndentLess); menu->addSeparator(); @@ -342,6 +355,15 @@ void TextEdit::setupTextActions() actionTextColor = menu->addAction(pix, tr("&Color..."), this, &TextEdit::textColor); tb->addAction(actionTextColor); + menu->addSeparator(); + + const QIcon checkboxIcon = QIcon::fromTheme("status-checkbox-checked", QIcon(rsrcPath + "/checkbox-checked.png")); + actionToggleCheckState = menu->addAction(checkboxIcon, tr("Chec&ked"), this, &TextEdit::setChecked); + actionToggleCheckState->setShortcut(Qt::CTRL + Qt::Key_K); + actionToggleCheckState->setCheckable(true); + actionToggleCheckState->setPriority(QAction::LowPriority); + tb->addAction(actionToggleCheckState); + tb = addToolBar(tr("Format Actions")); tb->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); addToolBarBreak(Qt::TopToolBarArea); @@ -353,6 +375,8 @@ void TextEdit::setupTextActions() comboStyle->addItem("Bullet List (Disc)"); comboStyle->addItem("Bullet List (Circle)"); comboStyle->addItem("Bullet List (Square)"); + comboStyle->addItem("Task List (Unchecked)"); + comboStyle->addItem("Task List (Checked)"); comboStyle->addItem("Ordered List (Decimal)"); comboStyle->addItem("Ordered List (Alpha lower)"); comboStyle->addItem("Ordered List (Alpha upper)"); @@ -395,11 +419,18 @@ bool TextEdit::load(const QString &f) QByteArray data = file.readAll(); QTextCodec *codec = Qt::codecForHtml(data); QString str = codec->toUnicode(data); + QUrl baseUrl = (f.front() == QLatin1Char(':') ? QUrl(f) : QUrl::fromLocalFile(f)).adjusted(QUrl::RemoveFilename); + textEdit->document()->setBaseUrl(baseUrl); if (Qt::mightBeRichText(str)) { textEdit->setHtml(str); } else { - str = QString::fromLocal8Bit(data); - textEdit->setPlainText(str); +#if QT_CONFIG(textmarkdownreader) + QMimeDatabase db; + if (db.mimeTypeForFileNameAndData(f, data).name() == QLatin1String("text/markdown")) + textEdit->setMarkdown(str); + else +#endif + textEdit->setPlainText(QString::fromLocal8Bit(data)); } setCurrentFileName(f); @@ -451,7 +482,15 @@ void TextEdit::fileOpen() QFileDialog fileDialog(this, tr("Open File...")); fileDialog.setAcceptMode(QFileDialog::AcceptOpen); fileDialog.setFileMode(QFileDialog::ExistingFile); - fileDialog.setMimeTypeFilters(QStringList() << "text/html" << "text/plain"); + fileDialog.setMimeTypeFilters(QStringList() +#if QT_CONFIG(texthtmlparser) + << "text/html" +#endif +#if QT_CONFIG(textmarkdownreader) + + << "text/markdown" +#endif + << "text/plain"); if (fileDialog.exec() != QDialog::Accepted) return; const QString fn = fileDialog.selectedFiles().first(); @@ -485,9 +524,18 @@ bool TextEdit::fileSaveAs() QFileDialog fileDialog(this, tr("Save as...")); fileDialog.setAcceptMode(QFileDialog::AcceptSave); QStringList mimeTypes; - mimeTypes << "application/vnd.oasis.opendocument.text" << "text/html" << "text/plain"; + mimeTypes << "text/plain" +#if QT_CONFIG(textodfwriter) + << "application/vnd.oasis.opendocument.text" +#endif +#if QT_CONFIG(textmarkdownwriter) + << "text/markdown" +#endif + << "text/html"; fileDialog.setMimeTypeFilters(mimeTypes); +#if QT_CONFIG(textodfwriter) fileDialog.setDefaultSuffix("odt"); +#endif if (fileDialog.exec() != QDialog::Accepted) return false; const QString fn = fileDialog.selectedFiles().first(); @@ -592,6 +640,7 @@ void TextEdit::textStyle(int styleIndex) { QTextCursor cursor = textEdit->textCursor(); QTextListFormat::Style style = QTextListFormat::ListStyleUndefined; + QTextBlockFormat::MarkerType marker = QTextBlockFormat::NoMarker; switch (styleIndex) { case 1: @@ -604,18 +653,32 @@ void TextEdit::textStyle(int styleIndex) style = QTextListFormat::ListSquare; break; case 4: - style = QTextListFormat::ListDecimal; + if (cursor.currentList()) + style = cursor.currentList()->format().style(); + else + style = QTextListFormat::ListDisc; + marker = QTextBlockFormat::Unchecked; break; case 5: - style = QTextListFormat::ListLowerAlpha; + if (cursor.currentList()) + style = cursor.currentList()->format().style(); + else + style = QTextListFormat::ListDisc; + marker = QTextBlockFormat::Checked; break; case 6: - style = QTextListFormat::ListUpperAlpha; + style = QTextListFormat::ListDecimal; break; case 7: - style = QTextListFormat::ListLowerRoman; + style = QTextListFormat::ListLowerAlpha; break; case 8: + style = QTextListFormat::ListUpperAlpha; + break; + case 9: + style = QTextListFormat::ListLowerRoman; + break; + case 10: style = QTextListFormat::ListUpperRoman; break; default: @@ -628,7 +691,7 @@ void TextEdit::textStyle(int styleIndex) if (style == QTextListFormat::ListStyleUndefined) { blockFmt.setObjectIndex(-1); - int headingLevel = styleIndex >= 9 ? styleIndex - 9 + 1 : 0; // H1 to H6, or Standard + int headingLevel = styleIndex >= 11 ? styleIndex - 11 + 1 : 0; // H1 to H6, or Standard blockFmt.setHeadingLevel(headingLevel); cursor.setBlockFormat(blockFmt); @@ -640,6 +703,8 @@ void TextEdit::textStyle(int styleIndex) cursor.mergeCharFormat(fmt); textEdit->mergeCurrentCharFormat(fmt); } else { + blockFmt.setMarker(marker); + cursor.setBlockFormat(blockFmt); QTextListFormat listFmt; if (cursor.currentList()) { listFmt = cursor.currentList()->format(); @@ -678,6 +743,45 @@ void TextEdit::textAlign(QAction *a) textEdit->setAlignment(Qt::AlignJustify); } +void TextEdit::setChecked(bool checked) +{ + textStyle(checked ? 5 : 4); +} + +void TextEdit::indent() +{ + modifyIndentation(1); +} + +void TextEdit::unindent() +{ + modifyIndentation(-1); +} + +void TextEdit::modifyIndentation(int amount) +{ + QTextCursor cursor = textEdit->textCursor(); + cursor.beginEditBlock(); + if (cursor.currentList()) { + QTextListFormat listFmt = cursor.currentList()->format(); + // See whether the line above is the list we want to move this item into, + // or whether we need a new list. + QTextCursor above(cursor); + above.movePosition(QTextCursor::Up); + if (above.currentList() && listFmt.indent() + amount == above.currentList()->format().indent()) { + above.currentList()->add(cursor.block()); + } else { + listFmt.setIndent(listFmt.indent() + amount); + cursor.createList(listFmt); + } + } else { + QTextBlockFormat blockFmt = cursor.blockFormat(); + blockFmt.setIndent(blockFmt.indent() + amount); + cursor.setBlockFormat(blockFmt); + } + cursor.endEditBlock(); +} + void TextEdit::currentCharFormatChanged(const QTextCharFormat &format) { fontChanged(format.font()); @@ -700,27 +804,40 @@ void TextEdit::cursorPositionChanged() comboStyle->setCurrentIndex(3); break; case QTextListFormat::ListDecimal: - comboStyle->setCurrentIndex(4); + comboStyle->setCurrentIndex(6); break; case QTextListFormat::ListLowerAlpha: - comboStyle->setCurrentIndex(5); + comboStyle->setCurrentIndex(7); break; case QTextListFormat::ListUpperAlpha: - comboStyle->setCurrentIndex(6); + comboStyle->setCurrentIndex(8); break; case QTextListFormat::ListLowerRoman: - comboStyle->setCurrentIndex(7); + comboStyle->setCurrentIndex(9); break; case QTextListFormat::ListUpperRoman: - comboStyle->setCurrentIndex(8); + comboStyle->setCurrentIndex(10); break; default: comboStyle->setCurrentIndex(-1); break; } + switch (textEdit->textCursor().block().blockFormat().marker()) { + case QTextBlockFormat::NoMarker: + actionToggleCheckState->setChecked(false); + break; + case QTextBlockFormat::Unchecked: + comboStyle->setCurrentIndex(4); + actionToggleCheckState->setChecked(false); + break; + case QTextBlockFormat::Checked: + comboStyle->setCurrentIndex(5); + actionToggleCheckState->setChecked(true); + break; + } } else { int headingLevel = textEdit->textCursor().blockFormat().headingLevel(); - comboStyle->setCurrentIndex(headingLevel ? headingLevel + 8 : 0); + comboStyle->setCurrentIndex(headingLevel ? headingLevel + 10 : 0); } } diff --git a/examples/widgets/richtext/textedit/textedit.h b/examples/widgets/richtext/textedit/textedit.h index ae0b13a4cc..9e50166c6f 100644 --- a/examples/widgets/richtext/textedit/textedit.h +++ b/examples/widgets/richtext/textedit/textedit.h @@ -96,6 +96,9 @@ private slots: void textStyle(int styleIndex); void textColor(); void textAlign(QAction *a); + void setChecked(bool checked); + void indent(); + void unindent(); void currentCharFormatChanged(const QTextCharFormat &format); void cursorPositionChanged(); @@ -110,6 +113,7 @@ private: void setupTextActions(); bool maybeSave(); void setCurrentFileName(const QString &fileName); + void modifyIndentation(int amount); void mergeFormatOnWordOrSelection(const QTextCharFormat &format); void fontChanged(const QFont &f); @@ -125,6 +129,9 @@ private: QAction *actionAlignCenter; QAction *actionAlignRight; QAction *actionAlignJustify; + QAction *actionIndentLess; + QAction *actionIndentMore; + QAction *actionToggleCheckState; QAction *actionUndo; QAction *actionRedo; #ifndef QT_NO_CLIPBOARD diff --git a/examples/widgets/richtext/textedit/textedit.qrc b/examples/widgets/richtext/textedit/textedit.qrc index 7d6efd7d67..1641acc207 100644 --- a/examples/widgets/richtext/textedit/textedit.qrc +++ b/examples/widgets/richtext/textedit/textedit.qrc @@ -1,6 +1,8 @@ <!DOCTYPE RCC><RCC version="1.0"> <qresource prefix="/"> <file>images/logo32.png</file> + <file>images/mac/checkbox.png</file> + <file>images/mac/checkbox-checked.png</file> <file>images/mac/editcopy.png</file> <file>images/mac/editcut.png</file> <file>images/mac/editpaste.png</file> @@ -11,6 +13,8 @@ <file>images/mac/fileopen.png</file> <file>images/mac/fileprint.png</file> <file>images/mac/filesave.png</file> + <file>images/mac/format-indent-less.png</file> + <file>images/mac/format-indent-more.png</file> <file>images/mac/textbold.png</file> <file>images/mac/textcenter.png</file> <file>images/mac/textitalic.png</file> @@ -20,6 +24,8 @@ <file>images/mac/textunder.png</file> <file>images/mac/zoomin.png</file> <file>images/mac/zoomout.png</file> + <file>images/win/checkbox.png</file> + <file>images/win/checkbox-checked.png</file> <file>images/win/editcopy.png</file> <file>images/win/editcut.png</file> <file>images/win/editpaste.png</file> @@ -30,6 +36,8 @@ <file>images/win/fileopen.png</file> <file>images/win/fileprint.png</file> <file>images/win/filesave.png</file> + <file>images/win/format-indent-less.png</file> + <file>images/win/format-indent-more.png</file> <file>images/win/textbold.png</file> <file>images/win/textcenter.png</file> <file>images/win/textitalic.png</file> |