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

source code of qtbase/src/gui/kernel/qclipboard.cpp