tdf#122689 KDE5: Fix selection clipboard

Selection clipboard now should properly get
and set data from/to selection buffer
and not from/to copy buffer.

Related: tdf#122239

Change-Id: Ia5298932ee277385c6f8a587d4fcb8204647c491
Reviewed-on: https://gerrit.libreoffice.org/66577
Tested-by: Jenkins
Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de>
(cherry picked from commit 3d4fe8b13545ee4d2992d33638f90855080d09d3)
Reviewed-on: https://gerrit.libreoffice.org/67364
Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
diff --git a/vcl/inc/qt5/Qt5Clipboard.hxx b/vcl/inc/qt5/Qt5Clipboard.hxx
index e3d791e..beff6b7 100644
--- a/vcl/inc/qt5/Qt5Clipboard.hxx
+++ b/vcl/inc/qt5/Qt5Clipboard.hxx
@@ -19,6 +19,8 @@
#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>

#include <QtGui/QClipboard>

using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
@@ -26,6 +28,8 @@ using namespace com::sun::star::lang;
class Qt5Transferable : public cppu::WeakImplHelper<css::datatransfer::XTransferable>
{
public:
    explicit Qt5Transferable(QClipboard::Mode aMode);

    virtual css::uno::Any SAL_CALL
    getTransferData(const css::datatransfer::DataFlavor& rFlavor) override;

@@ -35,6 +39,9 @@ public:
        SAL_CALL getTransferDataFlavors() override;
    virtual sal_Bool SAL_CALL
    isDataFlavorSupported(const css::datatransfer::DataFlavor& rFlavor) override;

private:
    QClipboard::Mode m_aClipboardMode;
};

class VclQt5Clipboard
@@ -46,9 +53,11 @@ class VclQt5Clipboard
    Reference<css::datatransfer::XTransferable> m_aContents;
    Reference<css::datatransfer::clipboard::XClipboardOwner> m_aOwner;
    std::vector<Reference<css::datatransfer::clipboard::XClipboardListener>> m_aListeners;
    OUString m_aClipboardName;
    QClipboard::Mode m_aClipboardMode;

public:
    explicit VclQt5Clipboard();
    explicit VclQt5Clipboard(const OUString& aModeString);
    virtual ~VclQt5Clipboard() override;

    /*
diff --git a/vcl/qt5/Qt5Clipboard.cxx b/vcl/qt5/Qt5Clipboard.cxx
index a913450..7a794cf 100644
--- a/vcl/qt5/Qt5Clipboard.cxx
+++ b/vcl/qt5/Qt5Clipboard.cxx
@@ -12,16 +12,42 @@
#include <comphelper/sequence.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <vcl/svapp.hxx>
#include <sal/log.hxx>

#include <QtWidgets/QApplication>
#include <QtGui/QClipboard>
#include <QtCore/QBuffer>
#include <QtCore/QMimeData>

#include <Qt5Clipboard.hxx>
#include <Qt5Tools.hxx>

#include <map>

namespace
{
std::map<OUString, QClipboard::Mode> g_nameToClipboardMap
    = { { "CLIPBOARD", QClipboard::Clipboard }, { "PRIMARY", QClipboard::Selection } };

QClipboard::Mode getClipboardTypeFromName(const OUString& aString)
{
    // use QClipboard::Clipboard as fallback if requested type isn't found
    QClipboard::Mode aMode = QClipboard::Clipboard;

    auto iter = g_nameToClipboardMap.find(aString);
    if (iter != g_nameToClipboardMap.end())
    {
        aMode = iter->second;
    }
    else
    {
        SAL_WARN("vcl.qt5", "Unrecognized clipboard type \""
                                << aString
                                << "\" is requested, falling back to QClipboard::Clipboard");
    }

    return aMode;
}

void lcl_peekFormats(const css::uno::Sequence<css::datatransfer::DataFlavor>& rFormats,
                     bool& bHasHtml, bool& bHasImage)
{
@@ -37,12 +63,17 @@ void lcl_peekFormats(const css::uno::Sequence<css::datatransfer::DataFlavor>& rF
}
}

Qt5Transferable::Qt5Transferable(QClipboard::Mode aMode)
    : m_aClipboardMode(aMode)
{
}

std::vector<css::datatransfer::DataFlavor> Qt5Transferable::getTransferDataFlavorsAsVector()
{
    std::vector<css::datatransfer::DataFlavor> aVector;

    const QClipboard* clipboard = QApplication::clipboard();
    const QMimeData* mimeData = clipboard->mimeData();
    const QMimeData* mimeData = clipboard->mimeData(m_aClipboardMode);
    css::datatransfer::DataFlavor aFlavor;

    if (mimeData->hasHtml())
@@ -91,44 +122,49 @@ Qt5Transferable::getTransferData(const css::datatransfer::DataFlavor& rFlavor)
{
    css::uno::Any aRet;
    const QClipboard* clipboard = QApplication::clipboard();
    const QMimeData* mimeData = clipboard->mimeData();
    const QMimeData* mimeData = clipboard->mimeData(m_aClipboardMode);

    if (rFlavor.MimeType == "text/plain;charset=utf-16")
    if (mimeData)
    {
        QString clipboardContent = mimeData->text();
        OUString sContent = toOUString(clipboardContent);
        if (rFlavor.MimeType == "text/plain;charset=utf-16")
        {
            QString clipboardContent = mimeData->text();
            OUString sContent = toOUString(clipboardContent);

        aRet <<= sContent.replaceAll("\r\n", "\n");
    }
    else if (rFlavor.MimeType == "text/html")
    {
        QString clipboardContent = mimeData->html();
        std::string aStr = clipboardContent.toStdString();
        Sequence<sal_Int8> aSeq(reinterpret_cast<const sal_Int8*>(aStr.c_str()), aStr.length());
        aRet <<= aSeq;
    }
    else if (rFlavor.MimeType.startsWith("image") && mimeData->hasImage())
    {
        QImage image = qvariant_cast<QImage>(mimeData->imageData());
        QByteArray ba;
        QBuffer buffer(&ba);
        sal_Int32 nIndex = rFlavor.MimeType.indexOf('/');
        OUString sFormat(nIndex != -1 ? rFlavor.MimeType.copy(nIndex + 1) : "png");
            aRet <<= sContent.replaceAll("\r\n", "\n");
        }
        else if (rFlavor.MimeType == "text/html")
        {
            QString clipboardContent = mimeData->html();
            std::string aStr = clipboardContent.toStdString();
            Sequence<sal_Int8> aSeq(reinterpret_cast<const sal_Int8*>(aStr.c_str()), aStr.length());
            aRet <<= aSeq;
        }
        else if (rFlavor.MimeType.startsWith("image") && mimeData->hasImage())
        {
            QImage image = qvariant_cast<QImage>(mimeData->imageData());
            QByteArray ba;
            QBuffer buffer(&ba);
            sal_Int32 nIndex = rFlavor.MimeType.indexOf('/');
            OUString sFormat(nIndex != -1 ? rFlavor.MimeType.copy(nIndex + 1) : "png");

        buffer.open(QIODevice::WriteOnly);
        image.save(&buffer, sFormat.toUtf8().getStr());
            buffer.open(QIODevice::WriteOnly);
            image.save(&buffer, sFormat.toUtf8().getStr());

        Sequence<sal_Int8> aSeq(reinterpret_cast<const sal_Int8*>(ba.data()), ba.size());
        aRet <<= aSeq;
            Sequence<sal_Int8> aSeq(reinterpret_cast<const sal_Int8*>(ba.data()), ba.size());
            aRet <<= aSeq;
        }
    }

    return aRet;
}

VclQt5Clipboard::VclQt5Clipboard()
VclQt5Clipboard::VclQt5Clipboard(const OUString& aModeString)
    : cppu::WeakComponentImplHelper<datatransfer::clipboard::XSystemClipboard,
                                    datatransfer::clipboard::XFlushableClipboard, XServiceInfo>(
          m_aMutex)
    , m_aClipboardName(aModeString)
    , m_aClipboardMode(getClipboardTypeFromName(aModeString))
{
}

@@ -159,7 +195,7 @@ sal_Bool VclQt5Clipboard::supportsService(const OUString& ServiceName)
Reference<css::datatransfer::XTransferable> VclQt5Clipboard::getContents()
{
    if (!m_aContents.is())
        m_aContents = new Qt5Transferable;
        m_aContents = new Qt5Transferable(m_aClipboardMode);

    return m_aContents;
}
@@ -177,6 +213,29 @@ void VclQt5Clipboard::setContents(
    std::vector<Reference<datatransfer::clipboard::XClipboardListener>> aListeners(m_aListeners);
    datatransfer::clipboard::ClipboardEvent aEv;

    QClipboard* clipboard = QApplication::clipboard();

    switch (m_aClipboardMode)
    {
        case QClipboard::Selection:
            if (!clipboard->supportsSelection())
            {
                return;
            }
            break;

        case QClipboard::FindBuffer:
            if (!clipboard->supportsFindBuffer())
            {
                return;
            }
            break;

        case QClipboard::Clipboard:
        default:
            break;
    }

    if (m_aContents.is())
    {
        css::uno::Sequence<css::datatransfer::DataFlavor> aFormats
@@ -268,8 +327,7 @@ void VclQt5Clipboard::setContents(
            }
        }

        QClipboard* clipboard = QApplication::clipboard();
        clipboard->setMimeData(pMimeData.release());
        clipboard->setMimeData(pMimeData.release(), m_aClipboardMode);
    }

    aEv.Contents = getContents();
@@ -284,7 +342,7 @@ void VclQt5Clipboard::setContents(
    }
}

OUString VclQt5Clipboard::getName() { return OUString("CLIPBOARD"); }
OUString VclQt5Clipboard::getName() { return m_aClipboardName; }

sal_Int8 VclQt5Clipboard::getRenderingCapabilities() { return 0; }

diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx
index 6564edd..3d9f78b 100644
--- a/vcl/qt5/Qt5Instance.cxx
+++ b/vcl/qt5/Qt5Instance.cxx
@@ -252,7 +252,7 @@ Qt5Instance::CreateClipboard(const css::uno::Sequence<css::uno::Any>& arguments)
    }

    css::uno::Reference<css::uno::XInterface> xClipboard(
        static_cast<cppu::OWeakObject*>(new VclQt5Clipboard()));
        static_cast<cppu::OWeakObject*>(new VclQt5Clipboard(sel)));
    m_aClipboards[sel] = xClipboard;

    return xClipboard;