1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#pragma once
#include <cppuhelper/compbase.hxx>
#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <QtCore/QMimeData>
#include <QtCore/QStringList>
#include <QtGui/QClipboard>
/**
* QtTransferable classes are used to read QMimeData via the XTransferable
* interface. All the functionality is already implemented in the QtTransferable.
*
* The specialisations map to the two users, which provide QMimeData: the Clipboard
* and the Drag'n'Drop functionality.
*
* LO itself seem to just accept "text/plain;charset=utf-16", so it relies on the
* backend to convert to this charset, but still offers "text/plain" itself.
*
* It's the "mirror" interface of the QtMimeData, which is defined below.
**/
class QtTransferable : public cppu::WeakImplHelper<css::datatransfer::XTransferable>
{
QtTransferable(const QtTransferable&) = delete;
const QMimeData* m_pMimeData;
osl::Mutex m_aMutex;
bool m_bProvideUTF16FromOtherEncoding;
css::uno::Sequence<css::datatransfer::DataFlavor> m_aMimeTypeSeq;
public:
QtTransferable(const QMimeData* pMimeData);
const QMimeData* mimeData() const { return m_pMimeData; }
css::uno::Sequence<css::datatransfer::DataFlavor> SAL_CALL getTransferDataFlavors() override;
sal_Bool SAL_CALL isDataFlavorSupported(const css::datatransfer::DataFlavor& rFlavor) override;
css::uno::Any SAL_CALL getTransferData(const css::datatransfer::DataFlavor& rFlavor) override;
};
/**
* The QClipboard's QMimeData is volatile. As written in the QClipboard::mimeData
* documentation, "the pointer returned might become invalidated when the contents
* of the clipboard changes". Therefore it can just be accessed reliably inside
* the QClipboard's object thread, which is the QApplication's thread, so all of
* the access has to go through RunInMainThread().
*
* If we detect a QMimeData change, we simply drop reporting any content. In theory
* we can recover in the case where there hadn't been any calls of the XTransferable
* interface, but currently we don't. But we ensure to never report mixed content,
* so we'll just cease operation on QMimeData change.
**/
class QtClipboardTransferable final : public QtTransferable
{
// to detect in-flight QMimeData changes
const QClipboard::Mode m_aMode;
bool hasInFlightChanged() const;
public:
explicit QtClipboardTransferable(const QClipboard::Mode aMode, const QMimeData* pMimeData);
// these are the same then QtTransferable, except they go through RunInMainThread
css::uno::Sequence<css::datatransfer::DataFlavor> SAL_CALL getTransferDataFlavors() override;
sal_Bool SAL_CALL isDataFlavorSupported(const css::datatransfer::DataFlavor& rFlavor) override;
css::uno::Any SAL_CALL getTransferData(const css::datatransfer::DataFlavor& rFlavor) override;
};
/**
* Convenience typedef for better code readability
*
* This just uses the QMimeData provided by the QWidgets D'n'D events.
**/
typedef QtTransferable QtDnDTransferable;
/**
* A lazy loading QMimeData for XTransferable reads
*
* This is an interface class to make a XTransferable read accessible as a
* QMimeData. The mime data is just stored inside the XTransferable, never
* in the QMimeData itself! It's objects are just used for QClipboard to read
* the XTransferable data.
*
* Like XTransferable itself, this class should be considered an immutable
* container for mime data. There is no need to ever set any of its data.
*
* LO will offer at least UTF-16, if there is a viable text representation.
* If LO misses to offer a UTF-8 or a locale encoded string, these objects
* will offer them themselves and convert from UTF-16 on demand.
*
* It's the "mirror" interface of the QtTransferable.
**/
class QtMimeData final : public QMimeData
{
friend class QtClipboardTransferable;
const css::uno::Reference<css::datatransfer::XTransferable> m_aContents;
mutable bool m_bHaveNoCharset; // = uses the locale charset
mutable bool m_bHaveUTF8;
mutable QStringList m_aMimeTypeList;
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QVariant retrieveData(const QString& mimeType, QVariant::Type type) const override;
#else
QVariant retrieveData(const QString& mimeType, QMetaType type) const override;
#endif
public:
explicit QtMimeData(const css::uno::Reference<css::datatransfer::XTransferable>& aContents);
bool hasFormat(const QString& mimeType) const override;
QStringList formats() const override;
bool deepCopy(QMimeData** const) const;
css::datatransfer::XTransferable* xTransferable() const { return m_aContents.get(); }
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|