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 
57 QT_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 
QClipboard(QObject * parent)170 QClipboard::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 */
~QClipboard()184 QClipboard::~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 */
text(QString & subtype,Mode mode) const278 QString 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(QLatin1String("text/plain")))
287             subtype = QLatin1String("plain");
288         else {
289             for (int i = 0; i < formats.size(); ++i)
290                 if (formats.at(i).startsWith(QLatin1String("text/"))) {
291                     subtype = formats.at(i).mid(5);
292                     break;
293                 }
294             if (subtype.isEmpty())
295                 return QString();
296         }
297     } else if (!formats.contains(QLatin1String("text/") + subtype)) {
298         return QString();
299     }
300 
301     const QByteArray rawData = data->data(QLatin1String("text/") + subtype);
302 
303 #if QT_CONFIG(textcodec)
304     QTextCodec* codec = QTextCodec::codecForMib(106); // utf-8 is default
305     if (subtype == QLatin1String("html"))
306         codec = QTextCodec::codecForHtml(rawData, codec);
307     else
308         codec = QTextCodec::codecForUtfText(rawData, 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 */
text(Mode mode) const328 QString 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 */
setText(const QString & text,Mode mode)346 void 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 */
image(Mode mode) const366 QImage QClipboard::image(Mode mode) const
367 {
368     const QMimeData *data = mimeData(mode);
369     if (!data)
370         return QImage();
371     return qvariant_cast<QImage>(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 */
setImage(const QImage & image,Mode mode)389 void 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 */
pixmap(Mode mode) const411 QPixmap QClipboard::pixmap(Mode mode) const
412 {
413     const QMimeData *data = mimeData(mode);
414     return data ? qvariant_cast<QPixmap>(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 */
setPixmap(const QPixmap & pixmap,Mode mode)430 void 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 */
mimeData(Mode mode) const461 const 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 */
setMimeData(QMimeData * src,Mode mode)487 void QClipboard::setMimeData(QMimeData* src, Mode mode)
488 {
489     QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
490     if (!clipboard->supportsMode(mode)) {
491         if (src != nullptr) {
492             qDebug("Data set on unsupported clipboard mode. QMimeData object will be deleted.");
493             src->deleteLater();
494         }
495     } else {
496         clipboard->setMimeData(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 */
clear(Mode mode)513 void QClipboard::clear(Mode mode)
514 {
515     setMimeData(nullptr, mode);
516 }
517 
518 /*!
519     Returns \c true if the clipboard supports mouse selection; otherwise
520     returns \c false.
521 */
supportsSelection() const522 bool QClipboard::supportsSelection() const
523 {
524     return supportsMode(Selection);
525 }
526 
527 /*!
528     Returns \c true if the clipboard supports a separate search buffer; otherwise
529     returns \c false.
530 */
supportsFindBuffer() const531 bool QClipboard::supportsFindBuffer() const
532 {
533     return supportsMode(FindBuffer);
534 }
535 
536 /*!
537     Returns \c true if this clipboard object owns the clipboard data;
538     otherwise returns \c false.
539 */
ownsClipboard() const540 bool QClipboard::ownsClipboard() const
541 {
542     return ownsMode(Clipboard);
543 }
544 
545 /*!
546     Returns \c true if this clipboard object owns the mouse selection
547     data; otherwise returns \c false.
548 */
ownsSelection() const549 bool QClipboard::ownsSelection() const
550 {
551     return ownsMode(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 */
ownsFindBuffer() const560 bool QClipboard::ownsFindBuffer() const
561 {
562     return ownsMode(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 */
supportsMode(Mode mode) const571 bool 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 */
ownsMode(Mode mode) const583 bool 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 */
emitChanged(Mode mode)593 void 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 
611 QT_END_NAMESPACE
612 
613 #endif // QT_NO_CLIPBOARD
614