vcl/inc/qt5/QtTransferable.hxx | 2 +- vcl/qt5/QtTransferable.cxx | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-)
New commits: commit 5b3227fac58dcbd588e2389e205679cd77842bac Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed Apr 6 13:51:59 2022 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Apr 7 06:36:35 2022 +0200 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 <glo...@fbihome.de> Tested-by: Jenkins 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 {