diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2019-06-18 16:08:06 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2019-06-21 11:48:10 +0200 |
commit | 6492541df306e20d16e3a64d9df174c99c847945 (patch) | |
tree | 8166d6fed26db8dd7b4d578eac3b70df1bdb88be /src | |
parent | cefaa2ff4c1d206c6daaba995d5c3572d089ac00 (diff) |
Support copy-pasting foreground images within same document
When using a texture for foreground color in text and copy-pasting
the text inside the same QTextEdit, the formatting would disappear.
Fixing this in a general way would require implementing some
other carrier format in the mime data than HTML, such as e.g ODF,
but it can quite easily be fixed for the case where the data
is pasted in the same document, or even different documents
as long as they have a reference to the image in the formats.
[ChangeLog][QtWidgets][QTextEdit] Added support for copy-pasting
foreground brushes with textures within same document.
Task-number: QTBUG-75931
Change-Id: I8b39dce289c64eea39e25cb8eb207e2534bcd2eb
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/text/qcssparser.cpp | 1 | ||||
-rw-r--r-- | src/gui/text/qcssparser_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 16 | ||||
-rw-r--r-- | src/gui/text/qtextdocument_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser.cpp | 42 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser_p.h | 1 |
6 files changed, 59 insertions, 3 deletions
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index dc7e128bcd..b5489c7ed9 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -67,6 +67,7 @@ struct QCssKnownValue static const QCssKnownValue properties[NumProperties - 1] = { { "-qt-background-role", QtBackgroundRole }, { "-qt-block-indent", QtBlockIndent }, + { "-qt-fg-texture-cachekey", QtForegroundTextureCacheKey }, { "-qt-line-height-type", QtLineHeightType }, { "-qt-list-indent", QtListIndent }, { "-qt-list-number-prefix", QtListNumberPrefix }, diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index 62578f75e5..b0fa4be682 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -196,6 +196,7 @@ enum Property { LineHeight, QtLineHeightType, FontKerning, + QtForegroundTextureCacheKey, NumProperties }; diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 757e2086e5..2ec3f41f42 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2470,9 +2470,19 @@ bool QTextHtmlExporter::emitCharFormatStyle(const QTextCharFormat &format) if (format.foreground() != defaultCharFormat.foreground() && format.foreground().style() != Qt::NoBrush) { - html += QLatin1String(" color:"); - html += colorValue(format.foreground().color()); - html += QLatin1Char(';'); + QBrush brush = format.foreground(); + if (brush.style() == Qt::TexturePattern) { + const bool isPixmap = qHasPixmapTexture(brush); + const qint64 cacheKey = isPixmap ? brush.texture().cacheKey() : brush.textureImage().cacheKey(); + + html += QLatin1String(" -qt-fg-texture-cachekey:"); + html += QString::number(cacheKey); + html += QLatin1String(";"); + } else { + html += QLatin1String(" color:"); + html += colorValue(brush.color()); + html += QLatin1Char(';'); + } attributesEmitted = true; } diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index a8e17bfc08..df00fb7d84 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -357,6 +357,7 @@ public: void mergeCachedResources(const QTextDocumentPrivate *priv); + friend struct QTextHtmlParserNode; friend class QTextHtmlExporter; friend class QTextCursor; }; diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 642f0893b4..0b1a23f399 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1335,6 +1335,17 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration> default: break; } break; + + case QCss::QtForegroundTextureCacheKey: + { + if (resourceProvider != nullptr && resourceProvider->docHandle() != nullptr) { + bool ok; + qint64 searchKey = decl.d->values.first().variant.toLongLong(&ok); + if (ok) + applyForegroundImage(searchKey, resourceProvider); + } + break; + } default: break; } } @@ -1367,6 +1378,37 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration> #endif // QT_NO_CSSPARSER +void QTextHtmlParserNode::applyForegroundImage(qint64 searchKey, const QTextDocument *resourceProvider) +{ + QTextDocumentPrivate *priv = resourceProvider->docHandle(); + for (int i = 0; i < priv->formats.numFormats(); ++i) { + QTextCharFormat format = priv->formats.charFormat(i); + if (format.isValid()) { + QBrush brush = format.foreground(); + if (brush.style() == Qt::TexturePattern) { + const bool isPixmap = qHasPixmapTexture(brush); + + if (isPixmap && QCoreApplication::instance()->thread() != QThread::currentThread()) { + qWarning("Can't apply QPixmap outside of GUI thread"); + return; + } + + const qint64 cacheKey = isPixmap ? brush.texture().cacheKey() : brush.textureImage().cacheKey(); + if (cacheKey == searchKey) { + QBrush b; + if (isPixmap) + b.setTexture(brush.texture()); + else + b.setTextureImage(brush.textureImage()); + b.setStyle(Qt::TexturePattern); + charFormat.setForeground(b); + } + } + } + } + +} + void QTextHtmlParserNode::applyBackgroundImage(const QString &url, const QTextDocument *resourceProvider) { if (!url.isEmpty() && resourceProvider) { diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h index 6ce294d211..c174b54a61 100644 --- a/src/gui/text/qtexthtmlparser_p.h +++ b/src/gui/text/qtexthtmlparser_p.h @@ -251,6 +251,7 @@ struct QTextHtmlParserNode { void setListStyle(const QVector<QCss::Value> &cssValues); #endif + void applyForegroundImage(qint64 cacheKey, const QTextDocument *resourceProvider); void applyBackgroundImage(const QString &url, const QTextDocument *resourceProvider); bool hasOnlyWhitespace() const; |