From a353e9fde19ae0862ed95aeb71654da57f24fcac Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 19 Apr 2023 11:03:58 +0200 Subject: [PATCH] Markdown: Reuse Markdown highlighter from change log viewer Change-Id: Ief1b0c135a34bfd5e9b5220e9fbf93f281d8e95a Reviewed-by: David Schulz Reviewed-by: Qt CI Bot --- .../templates/wizards/files/markdown/file.md | 6 +- src/libs/utils/stringutils.cpp | 63 +++++++++++++++++- src/libs/utils/stringutils.h | 12 ++++ src/plugins/coreplugin/mainwindow.cpp | 64 +------------------ src/plugins/texteditor/markdowneditor.cpp | 4 +- 5 files changed, 80 insertions(+), 69 deletions(-) diff --git a/share/qtcreator/templates/wizards/files/markdown/file.md b/share/qtcreator/templates/wizards/files/markdown/file.md index 2062554585a..1c00de1fca7 100644 --- a/share/qtcreator/templates/wizards/files/markdown/file.md +++ b/share/qtcreator/templates/wizards/files/markdown/file.md @@ -11,8 +11,6 @@ Paragraph. * another bullet * child bullet ---- - 1. ordered 2. next ordered @@ -25,6 +23,10 @@ An empty line starts a new paragraph. Use two spaces at the end to force a line break. +A horizontal ruler follows: + +--- + Add links inline like [this link to the Qt homepage](https://www.qt.io), or with a reference like [this other link to the Qt homepage][1]. diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp index 37f9336d376..c296881cb8b 100644 --- a/src/libs/utils/stringutils.cpp +++ b/src/libs/utils/stringutils.cpp @@ -3,10 +3,9 @@ #include "stringutils.h" -#include "algorithm.h" -#include "hostosinfo.h" -#include "qtcassert.h" #include "filepath.h" +#include "qtcassert.h" +#include "theme/theme.h" #include "utilstr.h" #ifdef QT_WIDGETS_LIB @@ -15,11 +14,13 @@ #endif #include +#include #include #include #include #include #include +#include #include #include @@ -568,4 +569,60 @@ QTCREATOR_UTILS_EXPORT int endOfNextWord(const QString &string, int position) return std::distance(string.begin(), it); } +MarkdownHighlighter::MarkdownHighlighter(QTextDocument *parent) + : QSyntaxHighlighter(parent) + , h2Brush(Qt::NoBrush) +{ + parent->setIndentWidth(30); // default value is 40 +} + +void MarkdownHighlighter::highlightBlock(const QString &text) +{ + if (text.isEmpty()) + return; + + QTextBlockFormat fmt = currentBlock().blockFormat(); + QTextCursor cur(currentBlock()); + if (fmt.hasProperty(QTextFormat::HeadingLevel)) { + fmt.setTopMargin(10); + fmt.setBottomMargin(10); + + // Draw an underline for Heading 2, by creating a texture brush + // with the last pixel visible + if (fmt.property(QTextFormat::HeadingLevel) == 2) { + QTextCharFormat charFmt = currentBlock().charFormat(); + charFmt.setBaselineOffset(15); + setFormat(0, text.length(), charFmt); + + if (h2Brush.style() == Qt::NoBrush) { + const int height = QFontMetrics(charFmt.font()).height(); + QImage image(1, height, QImage::Format_ARGB32); + + image.fill(QColor(0, 0, 0, 0).rgba()); + image.setPixel(0, + height - 1, + Utils::creatorTheme()->color(Theme::TextColorDisabled).rgba()); + + h2Brush = QBrush(image); + } + fmt.setBackground(h2Brush); + } + cur.setBlockFormat(fmt); + } else if (fmt.hasProperty(QTextFormat::BlockCodeLanguage) && fmt.indent() == 0) { + // set identation for code blocks + fmt.setIndent(1); + cur.setBlockFormat(fmt); + } + + // Show the bulet points as filled circles + QTextList *list = cur.currentList(); + if (list) { + QTextListFormat listFmt = list->format(); + if (listFmt.indent() == 1 && listFmt.style() == QTextListFormat::ListCircle) { + listFmt.setStyle(QTextListFormat::ListDisc); + list->setFormat(listFmt); + } + } +} + } // namespace Utils diff --git a/src/libs/utils/stringutils.h b/src/libs/utils/stringutils.h index d1a94330b7b..3bab6110cf3 100644 --- a/src/libs/utils/stringutils.h +++ b/src/libs/utils/stringutils.h @@ -5,8 +5,10 @@ #include "utils_global.h" +#include #include #include +#include #include @@ -121,4 +123,14 @@ QTCREATOR_UTILS_EXPORT QPair splitAtFirst(const QStrin QTCREATOR_UTILS_EXPORT int endOfNextWord(const QString &string, int position = 0); +class QTCREATOR_UTILS_EXPORT MarkdownHighlighter : public QSyntaxHighlighter +{ +public: + MarkdownHighlighter(QTextDocument *parent); + void highlightBlock(const QString &text); + +private: + QBrush h2Brush; +}; + } // namespace Utils diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 168fff92208..2d7ec70c8eb 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -1384,67 +1384,6 @@ public: } }; -class MarkdownHighlighter : public QSyntaxHighlighter -{ - QBrush h2Brush; -public: - MarkdownHighlighter(QTextDocument *parent) - : QSyntaxHighlighter(parent) - , h2Brush(Qt::NoBrush) - { - parent->setIndentWidth(30); // default value is 40 - } - - void highlightBlock(const QString &text) - { - if (text.isEmpty()) - return; - - QTextBlockFormat fmt = currentBlock().blockFormat(); - QTextCursor cur(currentBlock()); - if (fmt.hasProperty(QTextFormat::HeadingLevel)) { - fmt.setTopMargin(10); - fmt.setBottomMargin(10); - - // Draw an underline for Heading 2, by creating a texture brush - // with the last pixel visible - if (fmt.property(QTextFormat::HeadingLevel) == 2) { - QTextCharFormat charFmt = currentBlock().charFormat(); - charFmt.setBaselineOffset(15); - setFormat(0, text.length(), charFmt); - - if (h2Brush.style() == Qt::NoBrush) { - const int height = QFontMetrics(charFmt.font()).height(); - QImage image(1, height, QImage::Format_ARGB32); - - image.fill(QColor(0, 0, 0, 0).rgba()); - image.setPixel(0, - height - 1, - Utils::creatorTheme()->color(Theme::TextColorDisabled).rgba()); - - h2Brush = QBrush(image); - } - fmt.setBackground(h2Brush); - } - cur.setBlockFormat(fmt); - } else if (fmt.hasProperty(QTextFormat::BlockCodeLanguage) && fmt.indent() == 0) { - // set identation for code blocks - fmt.setIndent(1); - cur.setBlockFormat(fmt); - } - - // Show the bulet points as filled circles - QTextList *list = cur.currentList(); - if (list) { - QTextListFormat listFmt = list->format(); - if (listFmt.indent() == 1 && listFmt.style() == QTextListFormat::ListCircle) { - listFmt.setStyle(QTextListFormat::ListDisc); - list->setFormat(listFmt); - } - } - } -}; - void MainWindow::changeLog() { static QPointer dialog; @@ -1484,8 +1423,7 @@ void MainWindow::changeLog() aggregate->add(textEdit); aggregate->add(new Core::BaseTextFind(textEdit)); - auto highlighter = new MarkdownHighlighter(textEdit->document()); - (void)highlighter; + new MarkdownHighlighter(textEdit->document()); auto textEditWidget = new QFrame; textEditWidget->setFrameStyle(QFrame::NoFrame); diff --git a/src/plugins/texteditor/markdowneditor.cpp b/src/plugins/texteditor/markdowneditor.cpp index 4041a0069e9..c04dcf0942d 100644 --- a/src/plugins/texteditor/markdowneditor.cpp +++ b/src/plugins/texteditor/markdowneditor.cpp @@ -7,10 +7,11 @@ #include "texteditor.h" #include "texteditortr.h" -#include #include #include +#include #include +#include #include #include @@ -34,6 +35,7 @@ public: auto browser = new QTextBrowser(&m_widget); browser->setOpenExternalLinks(true); browser->setFrameShape(QFrame::NoFrame); + new Utils::MarkdownHighlighter(browser->document()); // Right side (hidable) auto editor = new TextEditorWidget(&m_widget);