1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
13 #include <cppuhelper/compbase.hxx>
14 #include <com/sun/star/datatransfer/XTransferable.hpp>
16 #include <QtCore/QMimeData>
17 #include <QtCore/QStringList>
18 #include <QtGui/QClipboard>
21 * QtTransferable classes are used to read QMimeData via the XTransferable
22 * interface. All the functionality is already implemented in the QtTransferable.
24 * The specialisations map to the two users, which provide QMimeData: the Clipboard
25 * and the Drag'n'Drop functionality.
27 * LO itself seem to just accept "text/plain;charset=utf-16", so it relies on the
28 * backend to convert to this charset, but still offers "text/plain" itself.
30 * It's the "mirror" interface of the QtMimeData, which is defined below.
32 class QtTransferable
: public cppu::WeakImplHelper
<css::datatransfer::XTransferable
>
34 QtTransferable(const QtTransferable
&) = delete;
36 const QMimeData
* m_pMimeData
;
39 /** Sets new mime data.
40 * Since data flavors supported by this class depend on the mime data,
41 * results from previous calls to the public methods of this
42 * class are no longer valid after setting new mime data using this method.
44 * Subclasses that set new mime data must ensure that no data race exists
46 * (For the current only subclass doing so, QtClipboardTransferable, all access
47 * to m_pMimeData happens with the SolarMutex held.)
49 void setMimeData(const QMimeData
* pMimeData
) { m_pMimeData
= pMimeData
; }
50 const QMimeData
* mimeData() const { return m_pMimeData
; }
53 QtTransferable(const QMimeData
* pMimeData
);
55 css::uno::Sequence
<css::datatransfer::DataFlavor
> SAL_CALL
getTransferDataFlavors() override
;
56 sal_Bool SAL_CALL
isDataFlavorSupported(const css::datatransfer::DataFlavor
& rFlavor
) override
;
57 css::uno::Any SAL_CALL
getTransferData(const css::datatransfer::DataFlavor
& rFlavor
) override
;
61 * The QClipboard's QMimeData is volatile. As written in the QClipboard::mimeData
62 * documentation, "the pointer returned might become invalidated when the contents
63 * of the clipboard changes". Therefore it can just be accessed reliably inside
64 * the QClipboard's object thread, which is the QApplication's thread, so all of
65 * the access has to go through RunInMainThread().
67 * If we detect a QMimeData change, the mime data is updated with the new one from
68 * the system clipboard. Note however that this means that results of any previous
69 * calls of the XTransferable interface will be out of sync with the newly set mime
70 * data, so this scenario should generally be avoided.
72 class QtClipboardTransferable final
: public QtTransferable
74 // to detect in-flight QMimeData changes
75 const QClipboard::Mode m_aMode
;
77 void ensureConsistencyWithSystemClipboard();
80 explicit QtClipboardTransferable(const QClipboard::Mode aMode
, const QMimeData
* pMimeData
);
82 // whether pMimeData are the current mime data
83 bool hasMimeData(const QMimeData
* pMimeData
) const;
85 // these are the same then QtTransferable, except they go through RunInMainThread
86 css::uno::Sequence
<css::datatransfer::DataFlavor
> SAL_CALL
getTransferDataFlavors() override
;
87 sal_Bool SAL_CALL
isDataFlavorSupported(const css::datatransfer::DataFlavor
& rFlavor
) override
;
88 css::uno::Any SAL_CALL
getTransferData(const css::datatransfer::DataFlavor
& rFlavor
) override
;
92 * Convenience typedef for better code readability
94 * This just uses the QMimeData provided by the QWidgets D'n'D events.
96 typedef QtTransferable QtDnDTransferable
;
99 * A lazy loading QMimeData for XTransferable reads
101 * This is an interface class to make a XTransferable read accessible as a
102 * QMimeData. The mime data is just stored inside the XTransferable, never
103 * in the QMimeData itself! It's objects are just used for QClipboard to read
104 * the XTransferable data.
106 * Like XTransferable itself, this class should be considered an immutable
107 * container for mime data. There is no need to ever set any of its data.
109 * LO will offer at least UTF-16, if there is a viable text representation.
110 * If LO misses to offer a UTF-8 or a locale encoded string, these objects
111 * will offer them themselves and convert from UTF-16 on demand.
113 * It's the "mirror" interface of the QtTransferable.
115 class QtMimeData final
: public QMimeData
119 friend class QtClipboardTransferable
;
121 const css::uno::Reference
<css::datatransfer::XTransferable
> m_aContents
;
122 mutable bool m_bHaveNoCharset
; // = uses the locale charset
123 mutable bool m_bHaveUTF8
;
124 mutable QStringList m_aMimeTypeList
;
126 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
127 QVariant
retrieveData(const QString
& mimeType
, QVariant::Type type
) const override
;
129 QVariant
retrieveData(const QString
& mimeType
, QMetaType type
) const override
;
133 explicit QtMimeData(const css::uno::Reference
<css::datatransfer::XTransferable
>& aContents
);
135 bool hasFormat(const QString
& mimeType
) const override
;
136 QStringList
formats() const override
;
138 bool deepCopy(QMimeData
** const) const;
140 css::datatransfer::XTransferable
* xTransferable() const { return m_aContents
.get(); }
143 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */