KWayland

dataoffer.cpp
1 /*
2  SPDX-FileCopyrightText: 2014 Martin Gräßlin <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "dataoffer.h"
7 #include "datadevice.h"
8 #include "wayland_pointer_p.h"
9 // Qt
10 #include <QMimeType>
11 #include <QMimeDatabase>
12 // Wayland
13 #include <wayland-client-protocol.h>
14 
15 namespace KWayland
16 {
17 
18 namespace Client
19 {
20 
21 class Q_DECL_HIDDEN DataOffer::Private
22 {
23 public:
24  Private(wl_data_offer *offer, DataOffer *q);
25  WaylandPointer<wl_data_offer, wl_data_offer_destroy> dataOffer;
27  DataDeviceManager::DnDActions sourceActions = DataDeviceManager::DnDAction::None;
28  DataDeviceManager::DnDAction selectedAction = DataDeviceManager::DnDAction::None;
29 
30 private:
31  void offer(const QString &mimeType);
32  void setAction(DataDeviceManager::DnDAction action);
33  static void offerCallback(void *data, wl_data_offer *dataOffer, const char *mimeType);
34  static void sourceActionsCallback(void *data, wl_data_offer *wl_data_offer, uint32_t source_actions);
35  static void actionCallback(void *data, wl_data_offer *wl_data_offer, uint32_t dnd_action);
36  DataOffer *q;
37 
38  static const struct wl_data_offer_listener s_listener;
39 };
40 
41 #ifndef K_DOXYGEN
42 const struct wl_data_offer_listener DataOffer::Private::s_listener = {
43  offerCallback,
44  sourceActionsCallback,
45  actionCallback
46 };
47 #endif
48 
49 DataOffer::Private::Private(wl_data_offer *offer, DataOffer *q)
50  : q(q)
51 {
52  dataOffer.setup(offer);
53  wl_data_offer_add_listener(offer, &s_listener, this);
54 }
55 
56 void DataOffer::Private::offerCallback(void *data, wl_data_offer *dataOffer, const char *mimeType)
57 {
58  auto d = reinterpret_cast<Private*>(data);
59  Q_ASSERT(d->dataOffer == dataOffer);
60  d->offer(QString::fromUtf8(mimeType));
61 }
62 
63 void DataOffer::Private::offer(const QString &mimeType)
64 {
65  QMimeDatabase db;
66  const auto &m = db.mimeTypeForName(mimeType);
67  if (m.isValid()) {
68  mimeTypes << m;
69  emit q->mimeTypeOffered(m.name());
70  }
71 }
72 
73 void DataOffer::Private::sourceActionsCallback(void *data, wl_data_offer *wl_data_offer, uint32_t source_actions)
74 {
75  Q_UNUSED(wl_data_offer)
76  DataDeviceManager::DnDActions actions;
77  if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) {
78  actions |= DataDeviceManager::DnDAction::Copy;
79  }
80  if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) {
81  actions |= DataDeviceManager::DnDAction::Move;
82  }
83  if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) {
84  actions |= DataDeviceManager::DnDAction::Ask;
85  }
86  auto d = reinterpret_cast<Private*>(data);
87  if (d->sourceActions != actions) {
88  d->sourceActions = actions;
89  emit d->q->sourceDragAndDropActionsChanged();
90  }
91 }
92 
93 void DataOffer::Private::actionCallback(void *data, wl_data_offer *wl_data_offer, uint32_t dnd_action)
94 {
95  Q_UNUSED(wl_data_offer)
96  auto d = reinterpret_cast<Private*>(data);
97  switch(dnd_action) {
98  case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY:
99  d->setAction(DataDeviceManager::DnDAction::Copy);
100  break;
101  case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE:
102  d->setAction(DataDeviceManager::DnDAction::Move);
103  break;
104  case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK:
105  d->setAction(DataDeviceManager::DnDAction::Ask);
106  break;
107  case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE:
108  d->setAction(DataDeviceManager::DnDAction::None);
109  break;
110  default:
111  Q_UNREACHABLE();
112  }
113 }
114 
115 void DataOffer::Private::setAction(DataDeviceManager::DnDAction action)
116 {
117  if (action == selectedAction) {
118  return;
119  }
120  selectedAction = action;
121  emit q->selectedDragAndDropActionChanged();
122 }
123 
124 DataOffer::DataOffer(DataDevice *parent, wl_data_offer *dataOffer)
125  : QObject(parent)
126  , d(new Private(dataOffer, this))
127 {
128 }
129 
130 DataOffer::~DataOffer()
131 {
132  release();
133 }
134 
135 void DataOffer::release()
136 {
137  d->dataOffer.release();
138 }
139 
140 void DataOffer::destroy()
141 {
142  d->dataOffer.destroy();
143 }
144 
145 bool DataOffer::isValid() const
146 {
147  return d->dataOffer.isValid();
148 }
149 
150 QList< QMimeType > DataOffer::offeredMimeTypes() const
151 {
152  return d->mimeTypes;
153 }
154 
155 void DataOffer::receive(const QMimeType &mimeType, qint32 fd)
156 {
157  receive(mimeType.name(), fd);
158 }
159 
160 void DataOffer::receive(const QString &mimeType, qint32 fd)
161 {
162  Q_ASSERT(isValid());
163  wl_data_offer_receive(d->dataOffer, mimeType.toUtf8().constData(), fd);
164 }
165 
166 DataOffer::operator wl_data_offer*()
167 {
168  return d->dataOffer;
169 }
170 
171 DataOffer::operator wl_data_offer*() const
172 {
173  return d->dataOffer;
174 }
175 
176 void DataOffer::dragAndDropFinished()
177 {
178  Q_ASSERT(isValid());
179  if (wl_proxy_get_version(d->dataOffer) < WL_DATA_OFFER_FINISH_SINCE_VERSION) {
180  return;
181  }
182  wl_data_offer_finish(d->dataOffer);
183 }
184 
185 DataDeviceManager::DnDActions DataOffer::sourceDragAndDropActions() const
186 {
187  return d->sourceActions;
188 }
189 
190 void DataOffer::setDragAndDropActions(DataDeviceManager::DnDActions supported, DataDeviceManager::DnDAction preferred)
191 {
192  if (wl_proxy_get_version(d->dataOffer) < WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) {
193  return;
194  }
195  auto toWayland = [] (DataDeviceManager::DnDAction action) {
196  switch (action) {
197  case DataDeviceManager::DnDAction::Copy:
198  return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
199  case DataDeviceManager::DnDAction::Move:
200  return WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
201  case DataDeviceManager::DnDAction::Ask:
202  return WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
203  case DataDeviceManager::DnDAction::None:
204  return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
205  default:
206  Q_UNREACHABLE();
207  }
208  };
209  uint32_t wlSupported = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
210  if (supported.testFlag(DataDeviceManager::DnDAction::Copy)) {
211  wlSupported |= toWayland(DataDeviceManager::DnDAction::Copy);
212  }
213  if (supported.testFlag(DataDeviceManager::DnDAction::Move)) {
214  wlSupported |= toWayland(DataDeviceManager::DnDAction::Move);
215  }
216  if (supported.testFlag(DataDeviceManager::DnDAction::Ask)) {
217  wlSupported |= toWayland(DataDeviceManager::DnDAction::Ask);
218  }
219  wl_data_offer_set_actions(d->dataOffer, wlSupported, toWayland(preferred));
220 }
221 
222 DataDeviceManager::DnDAction DataOffer::selectedDragAndDropAction() const
223 {
224  return d->selectedAction;
225 }
226 
227 }
228 }
QString fromUtf8(const char *str, int size)
bool isValid() const
Definition: global.cpp:64
const char * constData() const const
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
QStringList mimeTypes(Types)
DnDAction
Drag and Drop actions supported by DataSource and DataOffer.
QObject * parent() const const
bool testFlag(Enum flag) const const
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Aug 7 2020 22:48:17 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.