Coverage Report

Created: 2026-06-30 07:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/kernel/qclipboard.cpp
Line
Count
Source
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
20
QT_BEGIN_NAMESPACE
21
22
using 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
128
QClipboard::QClipboard(QObject *parent)
129
0
    : QObject(parent)
130
0
{
131
    // nothing
132
0
}
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
*/
142
QClipboard::~QClipboard()
143
0
{
144
0
}
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
*/
236
QString QClipboard::text(QString &subtype, Mode mode) const
237
0
{
238
0
    const QMimeData *const data = mimeData(mode);
239
0
    if (!data)
240
0
        return QString();
241
242
0
    const QStringList formats = data->formats();
243
0
    if (subtype.isEmpty()) {
244
0
        if (formats.contains("text/plain"_L1))
245
0
            subtype = "plain"_L1;
246
0
        else {
247
0
            for (const auto &format : formats) {
248
0
                if (format.startsWith("text/"_L1)) {
249
0
                    subtype = format.sliced(5);
250
0
                    break;
251
0
                }
252
0
            }
253
0
            if (subtype.isEmpty())
254
0
                return QString();
255
0
        }
256
0
    } else if (!formats.contains("text/"_L1 + subtype)) {
257
0
        return QString();
258
0
    }
259
260
0
    const QByteArray rawData = data->data("text/"_L1 + subtype);
261
0
    auto encoding = QStringConverter::encodingForData(rawData);
262
0
    if (!encoding)
263
0
        encoding = QStringConverter::Utf8;
264
0
    return QStringDecoder(*encoding).decode(rawData);
265
0
}
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
*/
280
QString QClipboard::text(Mode mode) const
281
0
{
282
0
    const QMimeData *data = mimeData(mode);
283
0
    return data ? data->text() : QString();
284
0
}
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
*/
298
void QClipboard::setText(const QString &text, Mode mode)
299
0
{
300
0
    QMimeData *data = new QMimeData;
301
0
    data->setText(text);
302
0
    setMimeData(data, mode);
303
0
}
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
*/
318
QImage QClipboard::image(Mode mode) const
319
0
{
320
0
    const QMimeData *data = mimeData(mode);
321
0
    if (!data)
322
0
        return QImage();
323
0
    return qvariant_cast<QImage>(data->imageData());
324
0
}
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
*/
341
void QClipboard::setImage(const QImage &image, Mode mode)
342
0
{
343
0
    QMimeData *data = new QMimeData;
344
0
    data->setImageData(image);
345
0
    setMimeData(data, mode);
346
0
}
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
*/
363
QPixmap QClipboard::pixmap(Mode mode) const
364
0
{
365
0
    const QMimeData *data = mimeData(mode);
366
0
    return data ? qvariant_cast<QPixmap>(data->imageData()) : QPixmap();
367
0
}
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
*/
382
void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode)
383
0
{
384
0
    QMimeData *data = new QMimeData;
385
0
    data->setImageData(pixmap);
386
0
    setMimeData(data, mode);
387
0
}
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
*/
413
const QMimeData* QClipboard::mimeData(Mode mode) const
414
0
{
415
0
    QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
416
0
    if (!clipboard->supportsMode(mode)) return nullptr;
417
0
    return clipboard->mimeData(mode);
418
0
}
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
*/
439
void QClipboard::setMimeData(QMimeData* src, Mode mode)
440
0
{
441
0
    QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
442
0
    if (!clipboard->supportsMode(mode)) {
443
0
        if (src != nullptr) {
444
0
            qDebug("Data set on unsupported clipboard mode. QMimeData object will be deleted.");
445
0
            src->deleteLater();
446
0
        }
447
0
    } else {
448
0
        clipboard->setMimeData(src,mode);
449
0
    }
450
0
}
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
*/
465
void QClipboard::clear(Mode mode)
466
0
{
467
0
    setMimeData(nullptr, mode);
468
0
}
469
470
/*!
471
    Returns \c true if the clipboard supports mouse selection; otherwise
472
    returns \c false.
473
*/
474
bool QClipboard::supportsSelection() const
475
0
{
476
0
    return supportsMode(Selection);
477
0
}
478
479
/*!
480
    Returns \c true if the clipboard supports a separate search buffer; otherwise
481
    returns \c false.
482
*/
483
bool QClipboard::supportsFindBuffer() const
484
0
{
485
0
    return supportsMode(FindBuffer);
486
0
}
487
488
/*!
489
    Returns \c true if this clipboard object owns the clipboard data;
490
    otherwise returns \c false.
491
*/
492
bool QClipboard::ownsClipboard() const
493
0
{
494
0
    return ownsMode(Clipboard);
495
0
}
496
497
/*!
498
    Returns \c true if this clipboard object owns the mouse selection
499
    data; otherwise returns \c false.
500
*/
501
bool QClipboard::ownsSelection() const
502
0
{
503
0
    return ownsMode(Selection);
504
0
}
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
*/
512
bool QClipboard::ownsFindBuffer() const
513
0
{
514
0
    return ownsMode(FindBuffer);
515
0
}
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
*/
523
bool QClipboard::supportsMode(Mode mode) const
524
0
{
525
0
    QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
526
0
    return clipboard && clipboard->supportsMode(mode);
527
0
}
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
*/
535
bool QClipboard::ownsMode(Mode mode) const
536
0
{
537
0
    QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
538
0
    return clipboard && clipboard->ownsMode(mode);
539
0
}
540
541
/*!
542
    \internal
543
    Emits the appropriate changed signal for \a mode.
544
*/
545
void QClipboard::emitChanged(Mode mode)
546
0
{
547
0
    switch (mode) {
548
0
        case Clipboard:
549
0
            emit dataChanged();
550
0
        break;
551
0
        case Selection:
552
0
            emit selectionChanged();
553
0
        break;
554
0
        case FindBuffer:
555
0
            emit findBufferChanged();
556
0
        break;
557
0
    }
558
559
0
    emit changed(mode);
560
0
}
561
562
QT_END_NAMESPACE
563
564
#include "moc_qclipboard.cpp"
565
566
#endif // QT_NO_CLIPBOARD