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
         {

Reply via email to