Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qclipboard.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qclipboard.h"
6
7#ifndef QT_NO_CLIPBOARD
8
9#include "qmimedata.h"
10#include "qpixmap.h"
11#include "qvariant.h"
12#include "qbuffer.h"
13#include "qimage.h"
14#include "private/qstringconverter_p.h"
15
16#include "private/qguiapplication_p.h"
17#include <qpa/qplatformintegration.h>
18#include <qpa/qplatformclipboard.h>
19
21
22using namespace Qt::StringLiterals;
23
24/*!
25 \class QClipboard
26 \brief The QClipboard class provides access to the window system clipboard.
27 \inmodule QtGui
28
29 The clipboard offers a simple mechanism to copy and paste data
30 between applications.
31
32 QClipboard supports the same data types that QDrag does, and uses
33 similar mechanisms. For advanced clipboard usage read \l{Drag and
34 Drop}.
35
36 There is a single QClipboard object in an application, accessible
37 as QGuiApplication::clipboard().
38
39 Example:
40 \snippet code/src_gui_kernel_qclipboard.cpp 0
41
42 QClipboard features some convenience functions to access common
43 data types: setText() allows the exchange of Unicode text and
44 setPixmap() and setImage() allows the exchange of QPixmaps and
45 QImages between applications. The setMimeData() function is the
46 ultimate in flexibility: it allows you to add any QMimeData into
47 the clipboard. There are corresponding getters for each of these,
48 e.g. text(), image() and pixmap(). You can clear the clipboard by
49 calling clear().
50
51 A typical example of the use of these functions follows:
52
53 \snippet droparea/droparea.cpp 0
54
55 \section1 Notes for X11 Users
56
57 \list
58
59 \li The X11 Window System has the concept of a separate selection
60 and clipboard. When text is selected, it is immediately available
61 as the global mouse selection. The global mouse selection may
62 later be copied to the clipboard. By convention, the middle mouse
63 button is used to paste the global mouse selection.
64
65 \li X11 also has the concept of ownership; if you change the
66 selection within a window, X11 will only notify the owner and the
67 previous owner of the change, i.e. it will not notify all
68 applications that the selection or clipboard data changed.
69
70 \li Lastly, the X11 clipboard is event driven, i.e. the clipboard
71 will not function properly if the event loop is not running.
72 Similarly, it is recommended that the contents of the clipboard
73 are stored or retrieved in direct response to user-input events,
74 e.g. mouse button or key presses and releases. You should not
75 store or retrieve the clipboard contents in response to timer or
76 non-user-input events.
77
78 \li Since there is no standard way to copy and paste files between
79 applications on X11, various MIME types and conventions are currently
80 in use. For instance, Nautilus expects files to be supplied with a
81 \c{x-special/gnome-copied-files} MIME type with data beginning with
82 the cut/copy action, a newline character, and the URL of the file.
83
84 \endlist
85
86 \section1 Notes for \macos Users
87
88 \macos supports a separate find buffer that holds the current
89 search string in Find operations. This find clipboard can be accessed
90 by specifying the FindBuffer mode.
91
92 \section1 Notes for Windows and \macos Users
93
94 \list
95
96 \li Windows and \macos do not support the global mouse
97 selection; they only supports the global clipboard, i.e. they
98 only add text to the clipboard when an explicit copy or cut is
99 made.
100
101 \li Windows and \macos does not have the concept of ownership;
102 the clipboard is a fully global resource so all applications are
103 notified of changes.
104
105 \endlist
106
107 \section1 Notes for Android Users
108
109 On Android only these mime types are supported: text/plain, text/html, and text/uri-list.
110
111 \sa QGuiApplication
112*/
113
114/*!
115 \internal
116
117 Constructs a clipboard object.
118
119 Do not call this function.
120
121 Call QGuiApplication::clipboard() instead to get a pointer to the
122 application's global clipboard object.
123
124 There is only one clipboard in the window system, and creating
125 more than one object to represent it is almost certainly an error.
126*/
127
128QClipboard::QClipboard(QObject *parent)
129 : QObject(parent)
130{
131 // nothing
132}
133
134/*!
135 \internal
136
137 Destroys the clipboard.
138
139 You should never delete the clipboard. QGuiApplication will do this
140 when the application terminates.
141*/
142QClipboard::~QClipboard()
143{
144}
145
146/*!
147 \fn void QClipboard::changed(QClipboard::Mode mode)
148 \since 4.2
149
150 This signal is emitted when the data for the given clipboard \a
151 mode is changed.
152
153 \sa dataChanged(), selectionChanged(), findBufferChanged()
154*/
155
156/*!
157 \fn void QClipboard::dataChanged()
158
159 This signal is emitted when the clipboard data is changed.
160
161 On \macos and with Qt version 4.3 or higher, clipboard
162 changes made by other applications will only be detected
163 when the application is activated.
164
165 \sa findBufferChanged(), selectionChanged(), changed()
166*/
167
168/*!
169 \fn void QClipboard::selectionChanged()
170
171 This signal is emitted when the selection is changed. This only
172 applies to windowing systems that support selections, e.g. X11.
173 Windows and \macos don't support selections.
174
175 \sa dataChanged(), findBufferChanged(), changed()
176*/
177
178/*!
179 \fn void QClipboard::findBufferChanged()
180 \since 4.2
181
182 This signal is emitted when the find buffer is changed. This only
183 applies to \macos.
184
185 With Qt version 4.3 or higher, clipboard changes made by other
186 applications will only be detected when the application is activated.
187
188 \sa dataChanged(), selectionChanged(), changed()
189*/
190
191
192/*! \enum QClipboard::Mode
193 \keyword clipboard mode
194
195 This enum type is used to control which part of the system clipboard is
196 used by QClipboard::mimeData(), QClipboard::setMimeData() and related functions.
197
198 \value Clipboard indicates that data should be stored and retrieved from
199 the global clipboard.
200
201 \value Selection indicates that data should be stored and retrieved from
202 the global mouse selection. Support for \c Selection is provided only on
203 systems with a global mouse selection (e.g. X11).
204
205 \value FindBuffer indicates that data should be stored and retrieved from
206 the Find buffer. This mode is used for holding search strings on \macos.
207
208 \omitvalue LastMode
209
210 \sa QClipboard::supportsSelection()
211*/
212
213
214/*!
215 \overload
216
217 Returns the clipboard text in subtype \a subtype, or an empty string
218 if the clipboard does not contain any text. If \a subtype is null,
219 any subtype is acceptable, and \a subtype is set to the chosen
220 subtype.
221
222 The \a mode argument is used to control which part of the system
223 clipboard is used. If \a mode is QClipboard::Clipboard, the
224 text is retrieved from the global clipboard. If \a mode is
225 QClipboard::Selection, the text is retrieved from the global
226 mouse selection.
227
228 Common values for \a subtype are "plain" and "html".
229
230 Note that calling this function repeatedly, for instance from a
231 key event handler, may be slow. In such cases, you should use the
232 \c dataChanged() signal instead.
233
234 \sa setText(), mimeData()
235*/
236QString QClipboard::text(QString &subtype, Mode mode) const
237{
238 const QMimeData *const data = mimeData(mode);
239 if (!data)
240 return QString();
241
242 const QStringList formats = data->formats();
243 if (subtype.isEmpty()) {
244 if (formats.contains("text/plain"_L1))
245 subtype = "plain"_L1;
246 else {
247 for (const auto &format : formats) {
248 if (format.startsWith("text/"_L1)) {
249 subtype = format.sliced(5);
250 break;
251 }
252 }
253 if (subtype.isEmpty())
254 return QString();
255 }
256 } else if (!formats.contains("text/"_L1 + subtype)) {
257 return QString();
258 }
259
260 const QByteArray rawData = data->data("text/"_L1 + subtype);
261 auto encoding = QStringConverter::encodingForData(rawData);
262 if (!encoding)
263 encoding = QStringConverter::Utf8;
264 return QStringDecoder(*encoding).decode(rawData);
265}
266
267/*!
268 Returns the clipboard text as plain text, or an empty string if the
269 clipboard does not contain any text.
270
271 The \a mode argument is used to control which part of the system
272 clipboard is used. If \a mode is QClipboard::Clipboard, the
273 text is retrieved from the global clipboard. If \a mode is
274 QClipboard::Selection, the text is retrieved from the global
275 mouse selection. If \a mode is QClipboard::FindBuffer, the
276 text is retrieved from the search string buffer.
277
278 \sa setText(), mimeData()
279*/
280QString QClipboard::text(Mode mode) const
281{
282 const QMimeData *data = mimeData(mode);
283 return data ? data->text() : QString();
284}
285
286/*!
287 Copies \a text into the clipboard as plain text.
288
289 The \a mode argument is used to control which part of the system
290 clipboard is used. If \a mode is QClipboard::Clipboard, the
291 text is stored in the global clipboard. If \a mode is
292 QClipboard::Selection, the text is stored in the global
293 mouse selection. If \a mode is QClipboard::FindBuffer, the
294 text is stored in the search string buffer.
295
296 \sa text(), setMimeData()
297*/
298void QClipboard::setText(const QString &text, Mode mode)
299{
300 QMimeData *data = new QMimeData;
301 data->setText(text);
302 setMimeData(data, mode);
303}
304
305/*!
306 Returns the clipboard image, or returns a null image if the
307 clipboard does not contain an image or if it contains an image in
308 an unsupported image format.
309
310 The \a mode argument is used to control which part of the system
311 clipboard is used. If \a mode is QClipboard::Clipboard, the
312 image is retrieved from the global clipboard. If \a mode is
313 QClipboard::Selection, the image is retrieved from the global
314 mouse selection.
315
316 \sa setImage(), pixmap(), mimeData(), QImage::isNull()
317*/
318QImage QClipboard::image(Mode mode) const
319{
320 const QMimeData *data = mimeData(mode);
321 if (!data)
322 return QImage();
323 return qvariant_cast<QImage>(data->imageData());
324}
325
326/*!
327 Copies the \a image into the clipboard.
328
329 The \a mode argument is used to control which part of the system
330 clipboard is used. If \a mode is QClipboard::Clipboard, the
331 image is stored in the global clipboard. If \a mode is
332 QClipboard::Selection, the data is stored in the global
333 mouse selection.
334
335 This is shorthand for:
336
337 \snippet code/src_gui_kernel_qclipboard.cpp 1
338
339 \sa image(), setPixmap(), setMimeData()
340*/
341void QClipboard::setImage(const QImage &image, Mode mode)
342{
343 QMimeData *data = new QMimeData;
344 data->setImageData(image);
345 setMimeData(data, mode);
346}
347
348/*!
349 Returns the clipboard pixmap, or null if the clipboard does not
350 contain a pixmap. Note that this can lose information. For
351 example, if the image is 24-bit and the display is 8-bit, the
352 result is converted to 8 bits, and if the image has an alpha
353 channel, the result just has a mask.
354
355 The \a mode argument is used to control which part of the system
356 clipboard is used. If \a mode is QClipboard::Clipboard, the
357 pixmap is retrieved from the global clipboard. If \a mode is
358 QClipboard::Selection, the pixmap is retrieved from the global
359 mouse selection.
360
361 \sa setPixmap(), image(), mimeData(), QPixmap::convertFromImage()
362*/
363QPixmap QClipboard::pixmap(Mode mode) const
364{
365 const QMimeData *data = mimeData(mode);
366 return data ? qvariant_cast<QPixmap>(data->imageData()) : QPixmap();
367}
368
369/*!
370 Copies \a pixmap into the clipboard. Note that this is slower
371 than setImage() because it needs to convert the QPixmap to a
372 QImage first.
373
374 The \a mode argument is used to control which part of the system
375 clipboard is used. If \a mode is QClipboard::Clipboard, the
376 pixmap is stored in the global clipboard. If \a mode is
377 QClipboard::Selection, the pixmap is stored in the global
378 mouse selection.
379
380 \sa pixmap(), setImage(), setMimeData()
381*/
382void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode)
383{
384 QMimeData *data = new QMimeData;
385 data->setImageData(pixmap);
386 setMimeData(data, mode);
387}
388
389
390/*!
391 \fn QMimeData *QClipboard::mimeData(Mode mode) const
392
393 Returns a pointer to a QMimeData representation of the current
394 clipboard data (can be \nullptr if the given \a mode is not
395 supported by the platform).
396
397 The \a mode argument is used to control which part of the system
398 clipboard is used. If \a mode is QClipboard::Clipboard, the
399 data is retrieved from the global clipboard. If \a mode is
400 QClipboard::Selection, the data is retrieved from the global
401 mouse selection. If \a mode is QClipboard::FindBuffer, the
402 data is retrieved from the search string buffer.
403
404 The text(), image(), and pixmap() functions are simpler
405 wrappers for retrieving text, image, and pixmap data.
406
407 \note The pointer returned might become invalidated when the contents
408 of the clipboard changes; either by calling one of the setter functions
409 or externally by the system clipboard changing.
410
411 \sa setMimeData()
412*/
413const QMimeData* QClipboard::mimeData(Mode mode) const
414{
415 QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
416 if (!clipboard->supportsMode(mode)) return nullptr;
417 return clipboard->mimeData(mode);
418}
419
420/*!
421 \fn void QClipboard::setMimeData(QMimeData *src, Mode mode)
422
423 Sets the clipboard data to \a src. Ownership of the data is
424 transferred to the clipboard. If you want to remove the data
425 either call clear() or call setMimeData() again with new data.
426
427 The \a mode argument is used to control which part of the system
428 clipboard is used. If \a mode is QClipboard::Clipboard, the
429 data is stored in the global clipboard. If \a mode is
430 QClipboard::Selection, the data is stored in the global
431 mouse selection. If \a mode is QClipboard::FindBuffer, the
432 data is stored in the search string buffer.
433
434 The setText(), setImage() and setPixmap() functions are simpler
435 wrappers for setting text, image and pixmap data respectively.
436
437 \sa mimeData()
438*/
439void QClipboard::setMimeData(QMimeData* src, Mode mode)
440{
441 QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
442 if (!clipboard->supportsMode(mode)) {
443 if (src != nullptr) {
444 qDebug("Data set on unsupported clipboard mode. QMimeData object will be deleted.");
445 src->deleteLater();
446 }
447 } else {
448 clipboard->setMimeData(src,mode);
449 }
450}
451
452/*!
453 \fn void QClipboard::clear(Mode mode)
454 Clear the clipboard contents.
455
456 The \a mode argument is used to control which part of the system
457 clipboard is used. If \a mode is QClipboard::Clipboard, this
458 function clears the global clipboard contents. If \a mode is
459 QClipboard::Selection, this function clears the global mouse
460 selection contents. If \a mode is QClipboard::FindBuffer, this
461 function clears the search string buffer.
462
463 \sa QClipboard::Mode, supportsSelection()
464*/
465void QClipboard::clear(Mode mode)
466{
467 setMimeData(nullptr, mode);
468}
469
470/*!
471 Returns \c true if the clipboard supports mouse selection; otherwise
472 returns \c false.
473*/
474bool QClipboard::supportsSelection() const
475{
476 return supportsMode(Selection);
477}
478
479/*!
480 Returns \c true if the clipboard supports a separate search buffer; otherwise
481 returns \c false.
482*/
483bool QClipboard::supportsFindBuffer() const
484{
485 return supportsMode(FindBuffer);
486}
487
488/*!
489 Returns \c true if this clipboard object owns the clipboard data;
490 otherwise returns \c false.
491*/
492bool QClipboard::ownsClipboard() const
493{
494 return ownsMode(Clipboard);
495}
496
497/*!
498 Returns \c true if this clipboard object owns the mouse selection
499 data; otherwise returns \c false.
500*/
501bool QClipboard::ownsSelection() const
502{
503 return ownsMode(Selection);
504}
505
506/*!
507 \since 4.2
508
509 Returns \c true if this clipboard object owns the find buffer data;
510 otherwise returns \c false.
511*/
512bool QClipboard::ownsFindBuffer() const
513{
514 return ownsMode(FindBuffer);
515}
516
517/*!
518 \internal
519 \fn bool QClipboard::supportsMode(Mode mode) const;
520 Returns \c true if the clipboard supports the clipboard mode speacified by \a mode;
521 otherwise returns \c false.
522*/
523bool QClipboard::supportsMode(Mode mode) const
524{
525 QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
526 return clipboard && clipboard->supportsMode(mode);
527}
528
529/*!
530 \internal
531 \fn bool QClipboard::ownsMode(Mode mode) const;
532 Returns \c true if the clipboard supports the clipboard data speacified by \a mode;
533 otherwise returns \c false.
534*/
535bool QClipboard::ownsMode(Mode mode) const
536{
537 QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
538 return clipboard && clipboard->ownsMode(mode);
539}
540
541/*!
542 \internal
543 Emits the appropriate changed signal for \a mode.
544*/
545void QClipboard::emitChanged(Mode mode)
546{
547 switch (mode) {
548 case Clipboard:
549 emit dataChanged();
550 break;
551 case Selection:
552 emit selectionChanged();
553 break;
554 case FindBuffer:
555 emit findBufferChanged();
556 break;
557 }
558
559 emit changed(mode);
560}
561
562QT_END_NAMESPACE
563
564#include "moc_qclipboard.cpp"
565
566#endif // QT_NO_CLIPBOARD
Combined button and popup list for selecting options.