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>
This commit is contained in:
parent
cefaa2ff4c
commit
6492541df3
@ -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 },
|
||||
|
@ -196,6 +196,7 @@ enum Property {
|
||||
LineHeight,
|
||||
QtLineHeightType,
|
||||
FontKerning,
|
||||
QtForegroundTextureCacheKey,
|
||||
NumProperties
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -357,6 +357,7 @@ public:
|
||||
|
||||
void mergeCachedResources(const QTextDocumentPrivate *priv);
|
||||
|
||||
friend struct QTextHtmlParserNode;
|
||||
friend class QTextHtmlExporter;
|
||||
friend class QTextCursor;
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -160,6 +160,7 @@ private slots:
|
||||
void selectionChanged();
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
void copyPasteBackgroundImage();
|
||||
void copyPasteForegroundImage();
|
||||
#endif
|
||||
void setText();
|
||||
void cursorRect();
|
||||
@ -1904,6 +1905,36 @@ void tst_QTextEdit::copyPasteBackgroundImage()
|
||||
ba.texture().cacheKey() == bb.texture().cacheKey());
|
||||
QFile::remove(QLatin1String("foo.png"));
|
||||
}
|
||||
|
||||
void tst_QTextEdit::copyPasteForegroundImage()
|
||||
{
|
||||
ed->clear();
|
||||
|
||||
QPixmap pix(20, 20);
|
||||
pix.fill(Qt::blue);
|
||||
|
||||
QTextCharFormat fmt;
|
||||
{
|
||||
QBrush textureBrush;
|
||||
{
|
||||
textureBrush.setTexture(pix);
|
||||
}
|
||||
textureBrush.setStyle(Qt::TexturePattern);
|
||||
fmt.setForeground(textureBrush);
|
||||
}
|
||||
ed->textCursor().insertText("Foobar", fmt);
|
||||
|
||||
ed->moveCursor(QTextCursor::Start);
|
||||
ed->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
|
||||
ed->copy();
|
||||
ed->clear();
|
||||
ed->paste();
|
||||
|
||||
QBrush brush = ed->textCursor().charFormat().foreground();
|
||||
QCOMPARE(brush.style(), Qt::TexturePattern);
|
||||
QCOMPARE(brush.texture().cacheKey(), pix.cacheKey());
|
||||
}
|
||||
#endif
|
||||
|
||||
void tst_QTextEdit::setText()
|
||||
|
Loading…
x
Reference in New Issue
Block a user