Directory: | ./ |
---|---|
File: | src/client/dataoffer.cpp |
Date: | 2024-01-22 17:25:27 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 84 | 101 | 83.2% |
Branches: | 25 | 48 | 52.1% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /******************************************************************** | ||
2 | Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 2.1 of the License, or (at your option) version 3, or any | ||
8 | later version accepted by the membership of KDE e.V. (or its | ||
9 | successor approved by the membership of KDE e.V.), which shall | ||
10 | act as a proxy defined in Section 6 of version 3 of the license. | ||
11 | |||
12 | This library is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | Lesser General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU Lesser General Public | ||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | ||
20 | #include "dataoffer.h" | ||
21 | #include "datadevice.h" | ||
22 | #include "selection_offer_p.h" | ||
23 | #include "wayland_pointer_p.h" | ||
24 | // Qt | ||
25 | #include <QMimeDatabase> | ||
26 | #include <QMimeType> | ||
27 | // Wayland | ||
28 | #include <wayland-client-protocol.h> | ||
29 | |||
30 | namespace Wrapland | ||
31 | { | ||
32 | |||
33 | namespace Client | ||
34 | { | ||
35 | |||
36 | class Q_DECL_HIDDEN DataOffer::Private | ||
37 | { | ||
38 | public: | ||
39 | Private(wl_data_offer* offer, DataOffer* q); | ||
40 | WaylandPointer<wl_data_offer, wl_data_offer_destroy> dataOffer; | ||
41 | QList<QMimeType> mimeTypes; | ||
42 | 29 | DataDeviceManager::DnDActions sourceActions = DataDeviceManager::DnDAction::None; | |
43 | 29 | DataDeviceManager::DnDAction selectedAction = DataDeviceManager::DnDAction::None; | |
44 | |||
45 | void setAction(DataDeviceManager::DnDAction action); | ||
46 | static void | ||
47 | sourceActionsCallback(void* data, wl_data_offer* wl_data_offer, uint32_t source_actions); | ||
48 | static void actionCallback(void* data, wl_data_offer* wl_data_offer, uint32_t dnd_action); | ||
49 | DataOffer* q; | ||
50 | |||
51 | static const struct wl_data_offer_listener s_listener; | ||
52 | }; | ||
53 | |||
54 | #ifndef DOXYGEN_SHOULD_SKIP_THIS | ||
55 | const struct wl_data_offer_listener DataOffer::Private::s_listener | ||
56 | = {offer_callback<Private>, sourceActionsCallback, actionCallback}; | ||
57 | #endif | ||
58 | |||
59 | 29 | DataOffer::Private::Private(wl_data_offer* offer, DataOffer* q) | |
60 | 29 | : q(q) | |
61 | { | ||
62 |
1/2✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
|
29 | dataOffer.setup(offer); |
63 |
1/2✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
|
29 | wl_data_offer_add_listener(offer, &s_listener, this); |
64 | 29 | } | |
65 | |||
66 | 7 | void DataOffer::Private::sourceActionsCallback(void* data, | |
67 | wl_data_offer* wl_data_offer, | ||
68 | uint32_t source_actions) | ||
69 | { | ||
70 | Q_UNUSED(wl_data_offer) | ||
71 | 7 | DataDeviceManager::DnDActions actions; | |
72 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
|
7 | if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) { |
73 | 5 | actions |= DataDeviceManager::DnDAction::Copy; | |
74 | 5 | } | |
75 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
|
7 | if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) { |
76 | 5 | actions |= DataDeviceManager::DnDAction::Move; | |
77 | 5 | } | |
78 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) { |
79 | ✗ | actions |= DataDeviceManager::DnDAction::Ask; | |
80 | } | ||
81 | 7 | auto d = reinterpret_cast<Private*>(data); | |
82 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
|
7 | if (d->sourceActions != actions) { |
83 | 5 | d->sourceActions = actions; | |
84 | 5 | Q_EMIT d->q->sourceDragAndDropActionsChanged(); | |
85 | 5 | } | |
86 | 7 | } | |
87 | |||
88 | 4 | void DataOffer::Private::actionCallback(void* data, | |
89 | wl_data_offer* wl_data_offer, | ||
90 | uint32_t dnd_action) | ||
91 | { | ||
92 | Q_UNUSED(wl_data_offer) | ||
93 | 4 | auto d = reinterpret_cast<Private*>(data); | |
94 |
1/5✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
4 | switch (dnd_action) { |
95 | case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY: | ||
96 | ✗ | d->setAction(DataDeviceManager::DnDAction::Copy); | |
97 | ✗ | break; | |
98 | case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE: | ||
99 | 4 | d->setAction(DataDeviceManager::DnDAction::Move); | |
100 | 4 | break; | |
101 | case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK: | ||
102 | ✗ | d->setAction(DataDeviceManager::DnDAction::Ask); | |
103 | ✗ | break; | |
104 | case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE: | ||
105 | ✗ | d->setAction(DataDeviceManager::DnDAction::None); | |
106 | ✗ | break; | |
107 | default: | ||
108 | ✗ | Q_UNREACHABLE(); | |
109 | } | ||
110 | 4 | } | |
111 | |||
112 | 4 | void DataOffer::Private::setAction(DataDeviceManager::DnDAction action) | |
113 | { | ||
114 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (action == selectedAction) { |
115 | ✗ | return; | |
116 | } | ||
117 | 4 | selectedAction = action; | |
118 | 4 | Q_EMIT q->selectedDragAndDropActionChanged(); | |
119 | 4 | } | |
120 | |||
121 | 29 | DataOffer::DataOffer(DataDevice* parent, wl_data_offer* dataOffer) | |
122 | 29 | : QObject(parent) | |
123 |
2/4✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 29 times.
|
29 | , d(new Private(dataOffer, this)) |
124 | 29 | { | |
125 | 29 | } | |
126 | |||
127 | 58 | DataOffer::~DataOffer() | |
128 | 58 | { | |
129 |
1/2✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
|
29 | release(); |
130 | 58 | } | |
131 | |||
132 | 29 | void DataOffer::release() | |
133 | { | ||
134 | 29 | d->dataOffer.release(); | |
135 | 29 | } | |
136 | |||
137 | 32 | bool DataOffer::isValid() const | |
138 | { | ||
139 | 32 | return d->dataOffer.isValid(); | |
140 | } | ||
141 | |||
142 | 18 | QList<QMimeType> DataOffer::offeredMimeTypes() const | |
143 | { | ||
144 | 18 | return d->mimeTypes; | |
145 | } | ||
146 | |||
147 | 1 | void DataOffer::receive(QMimeType const& mimeType, qint32 fd) | |
148 | { | ||
149 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | receive(mimeType.name(), fd); |
150 | 1 | } | |
151 | |||
152 | 1 | void DataOffer::receive(QString const& mimeType, qint32 fd) | |
153 | { | ||
154 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | Q_ASSERT(isValid()); |
155 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | wl_data_offer_receive(d->dataOffer, mimeType.toUtf8().constData(), fd); |
156 | 1 | } | |
157 | |||
158 | 29 | DataOffer::operator wl_data_offer*() | |
159 | { | ||
160 | 29 | return d->dataOffer; | |
161 | } | ||
162 | |||
163 | ✗ | DataOffer::operator wl_data_offer*() const | |
164 | { | ||
165 | ✗ | return d->dataOffer; | |
166 | } | ||
167 | |||
168 | 2 | void DataOffer::dragAndDropFinished() | |
169 | { | ||
170 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | Q_ASSERT(isValid()); |
171 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (wl_proxy_get_version(d->dataOffer) < WL_DATA_OFFER_FINISH_SINCE_VERSION) { |
172 | ✗ | return; | |
173 | } | ||
174 | 2 | wl_data_offer_finish(d->dataOffer); | |
175 | 2 | } | |
176 | |||
177 | 16 | DataDeviceManager::DnDActions DataOffer::sourceDragAndDropActions() const | |
178 | { | ||
179 | 16 | return d->sourceActions; | |
180 | } | ||
181 | |||
182 | 4 | void DataOffer::setDragAndDropActions(DataDeviceManager::DnDActions supported, | |
183 | DataDeviceManager::DnDAction preferred) | ||
184 | { | ||
185 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (wl_proxy_get_version(d->dataOffer) < WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) { |
186 | ✗ | return; | |
187 | } | ||
188 | 16 | auto toWayland = [](DataDeviceManager::DnDAction action) { | |
189 |
2/5✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
12 | switch (action) { |
190 | case DataDeviceManager::DnDAction::Copy: | ||
191 | 4 | return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; | |
192 | case DataDeviceManager::DnDAction::Move: | ||
193 | 8 | return WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; | |
194 | case DataDeviceManager::DnDAction::Ask: | ||
195 | ✗ | return WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; | |
196 | case DataDeviceManager::DnDAction::None: | ||
197 | ✗ | return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; | |
198 | default: | ||
199 | ✗ | Q_UNREACHABLE(); | |
200 | } | ||
201 | 12 | }; | |
202 | 4 | uint32_t wlSupported = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; | |
203 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (supported.testFlag(DataDeviceManager::DnDAction::Copy)) { |
204 | 4 | wlSupported |= toWayland(DataDeviceManager::DnDAction::Copy); | |
205 | 4 | } | |
206 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (supported.testFlag(DataDeviceManager::DnDAction::Move)) { |
207 | 4 | wlSupported |= toWayland(DataDeviceManager::DnDAction::Move); | |
208 | 4 | } | |
209 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (supported.testFlag(DataDeviceManager::DnDAction::Ask)) { |
210 | ✗ | wlSupported |= toWayland(DataDeviceManager::DnDAction::Ask); | |
211 | } | ||
212 | 4 | wl_data_offer_set_actions(d->dataOffer, wlSupported, toWayland(preferred)); | |
213 | 4 | } | |
214 | |||
215 | 8 | DataDeviceManager::DnDAction DataOffer::selectedDragAndDropAction() const | |
216 | { | ||
217 | 8 | return d->selectedAction; | |
218 | } | ||
219 | |||
220 | } | ||
221 | } | ||
222 |