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