diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-05-06 17:43:32 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-05-07 19:58:09 +0200 |
commit | 1d44ddf57671399a9fa3a7dadab8d448ce7b52e7 (patch) | |
tree | ebbf405791fe02eb72695920883ef4a120b46501 /tests | |
parent | a0f0f4fa54fe8e9fa6526ef6ccde5eb5cbc73450 (diff) |
Add support for QTextCharFormat::underlineColor in highlighers and CSS
When a QSyntaxHighlighter calls setUnderlineColor(), TextEdit will use
that color for underline, overline and strikeout rendering. Likewise
when Text has textFormat: Text.RichText and the HTML contains CSS styling
specifying text-decoration-color, it will be applied (depending on the
css support in QTextHtmlParser to call setUnderlineColor()).
Added a manual test.
[ChangeLog][QtQuick][TextEdit] When a QSyntaxHighlighter calls
QTextFormat::setUnderlineColor(), or CSS style contains
text-decoration-color, Text and TextEdit will now use that color for
underline, overline and strikeout rendering.
Task-number: QTBUG-87260
Task-number: QTBUG-74572
Task-number: QTBUG-39617
Change-Id: Ia2b564d5366ff67bb5df4f6c9e68ff5773ca5d6a
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/manual/syntaxhighlighter/app.qml | 96 | ||||
-rw-r--r-- | tests/manual/syntaxhighlighter/documenthighlighter.cpp | 124 | ||||
-rw-r--r-- | tests/manual/syntaxhighlighter/documenthighlighter.h | 96 | ||||
-rw-r--r-- | tests/manual/syntaxhighlighter/main.cpp | 63 | ||||
-rw-r--r-- | tests/manual/syntaxhighlighter/syntaxhighlighter.pro | 10 | ||||
-rw-r--r-- | tests/manual/syntaxhighlighter/syntaxhighlighter.qrc | 5 |
6 files changed, 394 insertions, 0 deletions
diff --git a/tests/manual/syntaxhighlighter/app.qml b/tests/manual/syntaxhighlighter/app.qml new file mode 100644 index 0000000000..5ad775785f --- /dev/null +++ b/tests/manual/syntaxhighlighter/app.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import Highlighter + +TextEdit { + id: textEdit + width: 420; height: 200 + text: '<p>Try the different <span style="text-decoration: underline overline; text-decoration-color: green;">highlight</span> styles.' + + "The keyword is 'char'.</p><code>char * test;</code>" + textFormat: TextEdit.RichText + leftPadding: 6; topPadding: 6 + + DocumentHighlighter { + id: highlighter + document: textEdit.textDocument + style: sb.value + } + + SpinBox { + id: sb + anchors.bottom: parent.bottom + anchors.margins: 6 + x: 6 + to: items.length - 1 + value: 0 + width: 200 + + property var items: ["Bold", "Cyanderlined", "Misspelled", "Gaudy", "Orangeout"] + + validator: RegularExpressionValidator { + regularExpression: new RegExp("(Bold|Cyanderlined|Misspelled|Gaudy|Orangeout)", "i") + } + + textFromValue: function(value) { + return items[value]; + } + + valueFromText: function(text) { + for (var i = 0; i < items.length; ++i) { + if (items[i].toLowerCase().indexOf(text.toLowerCase()) === 0) + return i + } + return sb.value + } + } +} diff --git a/tests/manual/syntaxhighlighter/documenthighlighter.cpp b/tests/manual/syntaxhighlighter/documenthighlighter.cpp new file mode 100644 index 0000000000..f5f3471074 --- /dev/null +++ b/tests/manual/syntaxhighlighter/documenthighlighter.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "documenthighlighter.h" +#include <QtQuick/QQuickTextDocument> + +Highlighter::Highlighter(QTextDocument *parent, int underlineTest) + : QSyntaxHighlighter(parent) +{ + m_testRegex.setPattern("char"); +} + +void Highlighter::highlightBlock(const QString &text) +{ + QTextCharFormat fmt; + if (m_style > 0) + fmt.setForeground(Qt::darkBlue); + fmt.setFontWeight(QFont::Bold); + switch (m_style) { + case 1: + fmt.setFontUnderline(true); + fmt.setUnderlineColor(QColor("cyan")); + break; + case 2: + fmt.setFontUnderline(true); + fmt.setUnderlineColor(QColor("red")); + // fmt.setUnderlineStyle(QTextCharFormat::WaveUnderline); // not supported yet: QTBUG-39617 + break; + case 3: + fmt.setFontOverline(true); + fmt.setFontUnderline(true); + fmt.setUnderlineColor(QColor("green")); + fmt.setBackground(QColor("lightgreen")); + fmt.setForeground(Qt::magenta); + fmt.setFontItalic(true); + fmt.setFontStretch(200); + fmt.setFontPointSize(14); + fmt.setFontStyleHint(QFont::Decorative); // seems ignored in practice + break; + case 4: + fmt.setFontStrikeOut(true); + fmt.setUnderlineColor(QColor("orange")); + fmt.setFontCapitalization(QFont::Capitalization::SmallCaps); + break; + } + + QRegularExpressionMatchIterator matchIterator = m_testRegex.globalMatch(text); + while (matchIterator.hasNext()) { + QRegularExpressionMatch match = matchIterator.next(); + setFormat(match.capturedStart(), match.capturedLength(), fmt); + } +} + +DocumentHighlighter::DocumentHighlighter(QObject *parent) + : QObject(parent) {} + +void DocumentHighlighter::setDocument(QQuickTextDocument *document) +{ + if (m_document == document) + return; + + m_document = document; + m_highlighter.setDocument(m_document->textDocument()); + m_highlighter.rehighlight(); + + emit documentChanged(); +} + +void DocumentHighlighter::setStyle(int style) +{ + if (m_highlighter.m_style == style) + return; + + m_highlighter.m_style = style; + m_highlighter.rehighlight(); + emit styleChanged(); +} diff --git a/tests/manual/syntaxhighlighter/documenthighlighter.h b/tests/manual/syntaxhighlighter/documenthighlighter.h new file mode 100644 index 0000000000..354fb3be4d --- /dev/null +++ b/tests/manual/syntaxhighlighter/documenthighlighter.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DOCUMENTHIGHLIGHTER_H +#define DOCUMENTHIGHLIGHTER_H + +#include <QSyntaxHighlighter> +#include <QTextCharFormat> +#include <QRegularExpression> +#include <QQuickTextDocument> +#include <QtQml> + +class Highlighter : public QSyntaxHighlighter +{ +public: + Highlighter(QTextDocument *parent = nullptr, int underlineTest = 0); + + void highlightBlock(const QString &text) override; + + QRegularExpression m_testRegex; + int m_style = 0; +}; + +class DocumentHighlighter : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickTextDocument *document READ document WRITE setDocument NOTIFY documentChanged) + Q_PROPERTY(int style READ style WRITE setStyle NOTIFY styleChanged) + QML_ELEMENT + +public: + DocumentHighlighter(QObject *parent = nullptr); + + QQuickTextDocument *document() const { return m_document; } + void setDocument(QQuickTextDocument * document); + + int style() const { return m_highlighter.m_style; } + void setStyle(int style); + +signals: + void documentChanged(); + void styleChanged(); + +private: + QQuickTextDocument *m_document = nullptr; + Highlighter m_highlighter; +}; + +#endif // DOCUMENTHIGHLIGHTER_H diff --git a/tests/manual/syntaxhighlighter/main.cpp b/tests/manual/syntaxhighlighter/main.cpp new file mode 100644 index 0000000000..be18034923 --- /dev/null +++ b/tests/manual/syntaxhighlighter/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuick/QQuickView> +#include <QGuiApplication> +#include "documenthighlighter.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + QQuickView view; + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:///app.qml")); + view.show(); + return app.exec(); +} diff --git a/tests/manual/syntaxhighlighter/syntaxhighlighter.pro b/tests/manual/syntaxhighlighter/syntaxhighlighter.pro new file mode 100644 index 0000000000..e364936dbe --- /dev/null +++ b/tests/manual/syntaxhighlighter/syntaxhighlighter.pro @@ -0,0 +1,10 @@ +QT += qml quick + +HEADERS += documenthighlighter.h +SOURCES += main.cpp \ + documenthighlighter.cpp + +RESOURCES += syntaxhighlighter.qrc +CONFIG += qmltypes +QML_IMPORT_NAME = Highlighter +QML_IMPORT_MAJOR_VERSION = 1 diff --git a/tests/manual/syntaxhighlighter/syntaxhighlighter.qrc b/tests/manual/syntaxhighlighter/syntaxhighlighter.qrc new file mode 100644 index 0000000000..f1168aef3b --- /dev/null +++ b/tests/manual/syntaxhighlighter/syntaxhighlighter.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>app.qml</file> + </qresource> +</RCC> |