Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qmimedata.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
4#include "qmimedata.h"
5
6#include "private/qobject_p.h"
7#include "qurl.h"
8#include "qstringlist.h"
9#include "qstringconverter.h"
10
12
13using namespace Qt::StringLiterals;
14
15static inline QString textUriListLiteral() { return QStringLiteral("text/uri-list"); }
16static inline QString textHtmlLiteral() { return QStringLiteral("text/html"); }
17static inline QString textPlainLiteral() { return QStringLiteral("text/plain"); }
18static inline QString textPlainUtf8Literal() { return QStringLiteral("text/plain;charset=utf-8"); }
19static inline QString applicationXColorLiteral() { return QStringLiteral("application/x-color"); }
20static inline QString applicationXQtImageLiteral() { return QStringLiteral("application/x-qt-image"); }
21
23{
26};
28
30{
31 Q_DECLARE_PUBLIC(QMimeData)
32public:
33 void removeData(const QString &format);
34 void setData(const QString &format, const QVariant &data);
35 QVariant getData(const QString &format) const;
36
38
39 std::vector<QMimeDataStruct>::iterator find(const QString &format) noexcept {
40 const auto formatEquals = [](const QString &format) {
41 return [&format](const QMimeDataStruct &s) { return s.format == format; };
42 };
43 return std::find_if(dataList.begin(), dataList.end(), formatEquals(format));
44 }
45
46 std::vector<QMimeDataStruct>::const_iterator find(const QString &format) const noexcept {
47 return const_cast<QMimeDataPrivate*>(this)->find(format);
48 }
49
50 std::vector<QMimeDataStruct> dataList;
51};
52
54{
55 const auto it = find(format);
56 if (it != dataList.end())
57 dataList.erase(it);
58}
59
61{
62 const auto it = find(format);
63 if (it == dataList.end())
64 dataList.push_back({format, data});
65 else
66 it->data = data;
67}
68
69
71{
72 const auto it = find(format);
73 if (it == dataList.cend())
74 return {};
75 else
76 return it->data;
77}
78
80{
82 qsizetype newLineIndex = -1;
83 qsizetype from = 0;
84 const char *begin = text.data();
85 while ((newLineIndex = text.indexOf('\n', from)) != -1) {
86 QByteArrayView bav(begin + from, begin + newLineIndex);
87 bav = bav.trimmed();
88 if (!bav.isEmpty())
90 from = newLineIndex + 1;
91 if (from >= text.size())
92 break;
93 }
94 return list;
95}
96
98{
99 Q_Q(const QMimeData);
100 int typeId = type.id();
101
102 QVariant data = q->retrieveData(format, type);
103
104 // Text data requested: fallback to URL data if available
105 if (format == "text/plain"_L1 && !data.isValid()) {
106 data = retrieveTypedData(textUriListLiteral(), QMetaType(QMetaType::QVariantList));
107 if (data.metaType().id() == QMetaType::QUrl) {
108 data = QVariant(data.toUrl().toDisplayString());
109 } else if (data.metaType().id() == QMetaType::QVariantList) {
111 int numUrls = 0;
113 for (int i = 0; i < list.size(); ++i) {
114 if (list.at(i).metaType().id() == QMetaType::QUrl) {
115 text += list.at(i).toUrl().toDisplayString() + u'\n';
116 ++numUrls;
117 }
118 }
119 if (numUrls == 1)
120 text.chop(1); // no final '\n' if there's only one URL
121 data = QVariant(text);
122 }
123 }
124
125 if (data.metaType() == type || !data.isValid())
126 return data;
127
128 // provide more conversion possibilities than just what QVariant provides
129
130 // URLs can be lists as well...
131 if ((typeId == QMetaType::QUrl && data.metaType().id() == QMetaType::QVariantList)
132 || (typeId == QMetaType::QVariantList && data.metaType().id() == QMetaType::QUrl))
133 return data;
134
135 // images and pixmaps are interchangeable
136 if ((typeId == QMetaType::QPixmap && data.metaType().id() == QMetaType::QImage)
137 || (typeId == QMetaType::QImage && data.metaType().id() == QMetaType::QPixmap))
138 return data;
139
140 if (data.metaType().id() == QMetaType::QByteArray) {
141 // see if we can convert to the requested type
142 switch (typeId) {
143 case QMetaType::QString: {
144 const QByteArray ba = data.toByteArray();
145 if (ba.isNull())
146 return QVariant();
147 if (format == "text/html"_L1) {
149 if (decoder.isValid()) {
150 return QString(decoder(ba));
151 }
152 // fall back to utf8
153 }
154 return QString::fromUtf8(ba);
155 }
156 case QMetaType::QColor: {
157 QVariant newData = data;
158 newData.convert(QMetaType(QMetaType::QColor));
159 return newData;
160 }
161 case QMetaType::QVariantList: {
162 if (format != "text/uri-list"_L1)
163 break;
165 }
166 case QMetaType::QUrl: {
167 auto bav = data.view<QByteArrayView>();
168 // Qt 3.x will send text/uri-list with a trailing
169 // null-terminator (that is *not* sent for any other
170 // text/* mime-type), so chop it off
171 if (bav.endsWith('\0'))
172 bav.chop(1);
173 return dataToUrls(bav);
174 }
175 default:
176 break;
177 }
178
179 } else if (typeId == QMetaType::QByteArray) {
180
181 // try to convert to bytearray
182 switch (data.metaType().id()) {
183 case QMetaType::QByteArray:
184 case QMetaType::QColor:
185 return data.toByteArray();
186 case QMetaType::QString:
187 return data.toString().toUtf8();
188 case QMetaType::QUrl:
189 return data.toUrl().toEncoded();
190 case QMetaType::QVariantList: {
191 // has to be list of URLs
194 for (int i = 0; i < list.size(); ++i) {
195 if (list.at(i).metaType().id() == QMetaType::QUrl) {
196 result += list.at(i).toUrl().toEncoded();
197 result += "\r\n";
198 }
199 }
200 if (!result.isEmpty())
201 return result;
202 break;
203 }
204 default:
205 break;
206 }
207 }
208 return data;
209}
210
306{
307}
308
313{
314}
315
324{
325 Q_D(const QMimeData);
326 QVariant data = d->retrieveTypedData(textUriListLiteral(), QMetaType(QMetaType::QVariantList));
328 if (data.metaType().id() == QMetaType::QUrl)
329 urls.append(data.toUrl());
330 else if (data.metaType().id() == QMetaType::QVariantList) {
332 for (int i = 0; i < list.size(); ++i) {
333 if (list.at(i).metaType().id() == QMetaType::QUrl)
334 urls.append(list.at(i).toUrl());
335 }
336 }
337 return urls;
338}
339
352{
353 Q_D(QMimeData);
355}
356
366{
368}
369
370
378{
379 Q_D(const QMimeData);
380 QVariant utf8Text = d->retrieveTypedData(textPlainUtf8Literal(), QMetaType(QMetaType::QString));
381 if (!utf8Text.isNull())
382 return utf8Text.toString();
383
384 QVariant data = d->retrieveTypedData(textPlainLiteral(), QMetaType(QMetaType::QString));
385 return data.toString();
386}
387
395{
396 Q_D(QMimeData);
397 d->setData(textPlainLiteral(), text);
398}
399
407{
408 return hasFormat(textPlainLiteral()) || hasUrls();
409}
410
418{
419 Q_D(const QMimeData);
420 QVariant data = d->retrieveTypedData(textHtmlLiteral(), QMetaType(QMetaType::QString));
421 return data.toString();
422}
423
431{
432 Q_D(QMimeData);
433 d->setData(textHtmlLiteral(), html);
434}
435
443{
444 return hasFormat(textHtmlLiteral());
445}
446
460{
461 Q_D(const QMimeData);
462 return d->retrieveTypedData(applicationXQtImageLiteral(), QMetaType(QMetaType::QImage));
463}
464
477{
478 Q_D(QMimeData);
480}
481
489{
491}
492
507{
508 Q_D(const QMimeData);
509 return d->retrieveTypedData(applicationXColorLiteral(), QMetaType(QMetaType::QColor));
510}
511
520{
521 Q_D(QMimeData);
522 d->setData(applicationXColorLiteral(), color);
523}
524
525
533{
535}
536
542{
543 Q_D(const QMimeData);
544 QVariant data = d->retrieveTypedData(mimeType, QMetaType(QMetaType::QByteArray));
545 return data.toByteArray();
546}
547
563{
564 Q_D(QMimeData);
565
566 if (mimeType == "text/uri-list"_L1) {
568 if (ba.endsWith('\0'))
569 ba.chop(1);
570 d->setData(mimeType, dataToUrls(ba));
571 } else {
572 d->setData(mimeType, QVariant(data));
573 }
574}
575
587{
588 return formats().contains(mimeType);
589}
590
603{
604 Q_D(const QMimeData);
606 list.reserve(static_cast<int>(d->dataList.size()));
607 for (auto &e : d->dataList)
608 list += e.format;
609 return list;
610}
611
628{
629 Q_UNUSED(type);
630 Q_D(const QMimeData);
631 return d->getData(mimeType);
632}
633
638{
639 Q_D(QMimeData);
640 d->dataList.clear();
641}
642
649{
650 Q_D(QMimeData);
651 d->removeData(mimeType);
652}
653
655
656#include "moc_qmimedata.cpp"
constexpr bool isEmpty() const noexcept
constexpr void chop(qsizetype n)
QByteArrayView trimmed() const noexcept
\inmodule QtCore
Definition qbytearray.h:57
bool endsWith(char c) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qbytearray.h:174
void chop(qsizetype n)
Removes n bytes from the end of the byte array.
bool isNull() const noexcept
Returns true if this byte array is null; otherwise returns false.
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
QList< T > toList() const noexcept
Definition qlist.h:716
void push_back(parameter_type t)
Definition qlist.h:672
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void reserve(qsizetype size)
Definition qlist.h:746
const_iterator cend() const noexcept
Definition qlist.h:614
void append(parameter_type t)
Definition qlist.h:441
const_iterator cbegin() const noexcept
Definition qlist.h:613
\inmodule QtCore
Definition qmetatype.h:320
std::vector< QMimeDataStruct >::const_iterator find(const QString &format) const noexcept
Definition qmimedata.cpp:46
std::vector< QMimeDataStruct > dataList
Definition qmimedata.cpp:50
QVariant getData(const QString &format) const
Definition qmimedata.cpp:70
QVariant retrieveTypedData(const QString &format, QMetaType type) const
Definition qmimedata.cpp:97
std::vector< QMimeDataStruct >::iterator find(const QString &format) noexcept
Definition qmimedata.cpp:39
void setData(const QString &format, const QVariant &data)
Definition qmimedata.cpp:60
void removeData(const QString &format)
Definition qmimedata.cpp:53
\inmodule QtCore
Definition qmimedata.h:16
bool hasUrls() const
Returns true if the object can return a list of urls; otherwise returns false.
void setHtml(const QString &html)
Sets html as the HTML (MIME type text/html) used to represent the data.
QVariant colorData() const
Returns a color if the data stored in the object represents a color (MIME type application/x-color); ...
void setData(const QString &mimetype, const QByteArray &data)
Sets the data associated with the MIME type given by mimeType to the specified data.
~QMimeData()
Destroys the MIME data object.
QMimeData()
Constructs a new MIME data object with no data in it.
QVariant imageData() const
Returns a QVariant storing a QImage if the object can return an image; otherwise returns a null varia...
bool hasHtml() const
Returns true if the object can return HTML (MIME type text/html); otherwise returns false.
bool hasImage() const
Returns true if the object can return an image; otherwise returns false.
bool hasText() const
Returns true if the object can return plain text (MIME type text/plain); otherwise returns false.
void setText(const QString &text)
Sets text as the plain text (MIME type text/plain) used to represent the data.
void setImageData(const QVariant &image)
Sets the data in the object to the given image.
virtual bool hasFormat(const QString &mimetype) const
Returns true if the object can return data for the MIME type specified by mimeType; otherwise returns...
void setColorData(const QVariant &color)
Sets the color data in the object to the given color.
virtual QVariant retrieveData(const QString &mimetype, QMetaType preferredType) const
Returns a variant with the given type containing data for the MIME type specified by mimeType.
QString html() const
Returns a string if the data stored in the object is HTML (MIME type text/html); otherwise returns an...
QList< QUrl > urls() const
Returns a list of URLs contained within the MIME data object.
bool hasColor() const
Returns true if the object can return a color (MIME type application/x-color); otherwise returns fals...
QByteArray data(const QString &mimetype) const
Returns the data stored in the object in the format described by the MIME type specified by mimeType.
void clear()
Removes all the MIME type and data entries in the object.
virtual QStringList formats() const
Returns a list of formats supported by the object.
void setUrls(const QList< QUrl > &urls)
Sets the URLs stored in the MIME data object to those specified by urls.
void removeFormat(const QString &mimetype)
QString text() const
Returns a plain text (MIME type text/plain) representation of the data.
\inmodule QtCore
Definition qobject.h:90
bool isValid() const noexcept
Returns true if this is a valid string converter that can be used for encoding or decoding text.
\inmodule QtCore
static Q_CORE_EXPORT QStringDecoder decoderForHtml(QByteArrayView data)
Tries to determine the encoding of the HTML in data by looking at leading byte order marks or a chars...
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6180
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1095
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4420
static QUrl fromEncoded(QByteArrayView input, ParsingMode mode=TolerantMode)
Parses input and returns the corresponding QUrl.
Definition qurl.cpp:2985
\inmodule QtCore
Definition qvariant.h:64
bool convert(QMetaType type)
Casts the variant to the requested type, targetType.
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
bool isNull() const
Returns true if this is a null variant, false otherwise.
QString text
double e
QSet< QString >::iterator it
Combined button and popup list for selecting options.
Definition image.cpp:4
#define Q_FALLTHROUGH()
const char * mimeType
static QString textPlainLiteral()
Definition qmimedata.cpp:17
static QList< QVariant > dataToUrls(QByteArrayView text)
Definition qmimedata.cpp:79
static QString textPlainUtf8Literal()
Definition qmimedata.cpp:18
static QString applicationXQtImageLiteral()
Definition qmimedata.cpp:20
static QString textUriListLiteral()
Definition qmimedata.cpp:15
static QString textHtmlLiteral()
Definition qmimedata.cpp:16
static QString applicationXColorLiteral()
Definition qmimedata.cpp:19
GLenum type
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei GLsizei GLenum format
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
#define QStringLiteral(str)
#define Q_UNUSED(x)
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:145
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:163
ptrdiff_t qsizetype
Definition qtypes.h:70
QList< int > list
[14]
QByteArray ba
[0]
QObject::connect nullptr