diff options
author | Michael Weghorn <m.weghorn@posteo.de> | 2022-04-06 13:51:59 +0200 |
---|---|---|
committer | Michael Weghorn <m.weghorn@posteo.de> | 2022-04-07 06:36:35 +0200 |
commit | 5b3227fac58dcbd588e2389e205679cd77842bac (patch) | |
tree | 9c1f62e3c13f977e85cec114db7b3ce19b2a767b | |
parent | 55b20c8781d7718fa992769df90282563694f7fe (diff) |
tdf#147285 qt: Prefer "text/plain;charset=utf-8" over "text/plain"
If there were no data for MIME type "text/plain;charset=utf-16"
in the clipboard, but "text/plain" was provided, it was previously
assumed that this would be encoded in the locale's encoding, and
corresponding conversion using that encoding happened to provide
"text/plain;charset=utf-16" ourselves.
"text/plain;charset=utf-8" data was simply ignored, but using
it (if present) and preferring it over "text/plain"
is more reliable (and e.g. avoids incorrect paste of Chinese
characters from Firefox into Impress when using the qt5/qt6/kf5
VCL plugins on Wayland), so use it if present.
Rename the "m_bConvertFromLocale" member to better fit
the new meaning.
(An alternative solution to adding our own handling for
"text/plain;charset=utf-8" and making assumptions for the
encoding of "text/plain" data would be to let Qt handle
this and just call `QMimeData::text()` for the
`m_bProvideUTF16FromOtherEncoding=true` case
in `QtTransferable::getTransferData`.
Since qtbase commit 589a01ff6b1eacf81e74a5fc4801572135214f43
("QMimeData: Prefer UTF-8 when multiple charsets are available",
contained in Qt >= 5.13), that one handles MIME type
"text/plain;charset=utf-8" in addition to "text/plain".)
[1] https://code.qt.io/cgit/qt/qtbase.git/commit/?id=589a01ff6b1eacf81e74a5fc4801572135214f43
Change-Id: I89f33216bf6be02a347d245b2359273af2eb530a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132631
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Tested-by: Jenkins
-rw-r--r-- | vcl/inc/qt5/QtTransferable.hxx | 2 | ||||
-rw-r--r-- | vcl/qt5/QtTransferable.cxx | 25 |
2 files changed, 18 insertions, 9 deletions
diff --git a/vcl/inc/qt5/QtTransferable.hxx b/vcl/inc/qt5/QtTransferable.hxx index f2997089c037..5f1533dd5968 100644 --- a/vcl/inc/qt5/QtTransferable.hxx +++ b/vcl/inc/qt5/QtTransferable.hxx @@ -35,7 +35,7 @@ class QtTransferable : public cppu::WeakImplHelper<css::datatransfer::XTransfera const QMimeData* m_pMimeData; osl::Mutex m_aMutex; - bool m_bConvertFromLocale; + bool m_bProvideUTF16FromOtherEncoding; css::uno::Sequence<css::datatransfer::DataFlavor> m_aMimeTypeSeq; public: diff --git a/vcl/qt5/QtTransferable.cxx b/vcl/qt5/QtTransferable.cxx index 4f42f93a238b..ed31a54d769e 100644 --- a/vcl/qt5/QtTransferable.cxx +++ b/vcl/qt5/QtTransferable.cxx @@ -42,7 +42,7 @@ static bool lcl_textMimeInfo(const OUString& rMimeString, bool& bHaveNoCharset, QtTransferable::QtTransferable(const QMimeData* pMimeData) : m_pMimeData(pMimeData) - , m_bConvertFromLocale(false) + , m_bProvideUTF16FromOtherEncoding(false) { assert(pMimeData); } @@ -62,7 +62,7 @@ css::uno::Sequence<css::datatransfer::DataFlavor> SAL_CALL QtTransferable::getTr QStringList aFormatList(m_pMimeData->formats()); // we might add the UTF-16 mime text variant later const int nMimeTypeSeqSize = aFormatList.size() + 1; - bool bHaveNoCharset = false, bHaveUTF16 = false; + bool bHaveNoCharset = false, bHaveUTF16 = false, bHaveUTF8 = false; css::uno::Sequence<css::datatransfer::DataFlavor> aMimeTypeSeq(nMimeTypeSeqSize); auto pMimeTypeSeq = aMimeTypeSeq.getArray(); @@ -85,6 +85,7 @@ css::uno::Sequence<css::datatransfer::DataFlavor> SAL_CALL QtTransferable::getTr { bHaveNoCharset |= bIsNoCharset; bHaveUTF16 |= bIsUTF16; + bHaveUTF8 |= bIsUTF8; if (bIsUTF16) aFlavor.DataType = cppu::UnoType<OUString>::get(); else @@ -99,8 +100,8 @@ css::uno::Sequence<css::datatransfer::DataFlavor> SAL_CALL QtTransferable::getTr nMimeTypeCount++; } - m_bConvertFromLocale = bHaveNoCharset && !bHaveUTF16; - if (m_bConvertFromLocale) + m_bProvideUTF16FromOtherEncoding = (bHaveNoCharset || bHaveUTF8) && !bHaveUTF16; + if (m_bProvideUTF16FromOtherEncoding) { aFlavor.MimeType = "text/plain;charset=utf-16"; aFlavor.DataType = cppu::UnoType<OUString>::get(); @@ -133,11 +134,19 @@ css::uno::Any SAL_CALL QtTransferable::getTransferData(const css::datatransfer:: if (rFlavor.MimeType == "text/plain;charset=utf-16") { OUString aString; - if (m_bConvertFromLocale) + if (m_bProvideUTF16FromOtherEncoding) { - QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain"))); - aString = OUString(reinterpret_cast<const char*>(aByteData.data()), aByteData.size(), - osl_getThreadTextEncoding()); + if (m_pMimeData->hasFormat("text/plain;charset=utf-8")) + { + QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain;charset=utf-8"))); + aString = OUString::fromUtf8(reinterpret_cast<const char*>(aByteData.data())); + } + else + { + QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain"))); + aString = OUString(reinterpret_cast<const char*>(aByteData.data()), + aByteData.size(), osl_getThreadTextEncoding()); + } } else { |