Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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 u"text/uri-list"_s; }
16static inline QString textHtmlLiteral() { return u"text/html"_s; }
17static inline QString textPlainLiteral() { return u"text/plain"_s; }
18static inline QString textPlainUtf8Literal() { return u"text/plain;charset=utf-8"_s; }
19static inline QString applicationXColorLiteral() { return u"application/x-color"_s; }
20static inline QString applicationXQtImageLiteral() { return u"application/x-qt-image"_s; }
21
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
79static QList<QVariant> dataToUrls(QByteArrayView text)
80{
81 QList<QVariant> list;
82 qsizetype newLineIndex = -1;
83 qsizetype from = 0;
84 const char *begin = text.data();
85 while ((newLineIndex = text.indexOf('\n', from)) != -1) {
86 const auto bav = QByteArrayView(begin + from, begin + newLineIndex).trimmed();
87 if (!bav.isEmpty())
89 from = newLineIndex + 1;
90 if (from >= text.size())
91 break;
92 }
93 if (from != text.size()) {
94 const auto bav = QByteArrayView(begin + from, text.end()).trimmed();
95 if (!bav.isEmpty())
97 }
98 return list;
99}
100
102{
103 Q_Q(const QMimeData);
104 int typeId = type.id();
105
106 QVariant data = q->retrieveData(format, type);
107
108 // Text data requested: fallback to URL data if available
109 if (format == "text/plain"_L1 && !data.isValid()) {
110 data = retrieveTypedData(textUriListLiteral(), QMetaType(QMetaType::QVariantList));
111 if (data.metaType().id() == QMetaType::QUrl) {
112 data = QVariant(data.toUrl().toDisplayString());
113 } else if (data.metaType().id() == QMetaType::QVariantList) {
115 int numUrls = 0;
116 const QList<QVariant> list = data.toList();
117 for (const auto &element : list) {
118 if (element.metaType().id() == QMetaType::QUrl) {
119 text += element.toUrl().toDisplayString();
120 text += u'\n';
121 ++numUrls;
122 }
123 }
124 if (numUrls == 1)
125 text.chop(1); // no final '\n' if there's only one URL
126 data = QVariant(text);
127 }
128 }
129
130 if (data.metaType() == type || !data.isValid())
131 return data;
132
133 // provide more conversion possibilities than just what QVariant provides
134
135 // URLs can be lists as well...
136 if ((typeId == QMetaType::QUrl && data.metaType().id() == QMetaType::QVariantList)
137 || (typeId == QMetaType::QVariantList && data.metaType().id() == QMetaType::QUrl))
138 return data;
139
140 // images and pixmaps are interchangeable
141 if ((typeId == QMetaType::QPixmap && data.metaType().id() == QMetaType::QImage)
142 || (typeId == QMetaType::QImage && data.metaType().id() == QMetaType::QPixmap))
143 return data;
144
145 if (data.metaType().id() == QMetaType::QByteArray) {
146 // see if we can convert to the requested type
147 switch (typeId) {
148 case QMetaType::QString: {
149 const QByteArray ba = data.toByteArray();
150 if (ba.isNull())
151 return QVariant();
152 if (format == "text/html"_L1) {
154 if (decoder.isValid()) {
155 return QString(decoder(ba));
156 }
157 // fall back to utf8
158 }
159 return QString::fromUtf8(ba);
160 }
161 case QMetaType::QColor: {
162 QVariant newData = data;
163 newData.convert(QMetaType(QMetaType::QColor));
164 return newData;
165 }
166 case QMetaType::QVariantList: {
167 if (format != "text/uri-list"_L1)
168 break;
170 }
171 case QMetaType::QUrl: {
172 auto bav = data.view<QByteArrayView>();
173 // Qt 3.x will send text/uri-list with a trailing
174 // null-terminator (that is *not* sent for any other
175 // text/* mime-type), so chop it off
176 if (bav.endsWith('\0'))
177 bav.chop(1);
178 return dataToUrls(bav);
179 }
180 default:
181 break;
182 }
183
184 } else if (typeId == QMetaType::QByteArray) {
185
186 // try to convert to bytearray
187 switch (data.metaType().id()) {
188 case QMetaType::QByteArray:
189 case QMetaType::QColor:
190 return data.toByteArray();
191 case QMetaType::QString:
192 return data.toString().toUtf8();
193 case QMetaType::QUrl:
194 return data.toUrl().toEncoded();
195 case QMetaType::QVariantList: {
196 // has to be list of URLs
198 const QList<QVariant> list = data.toList();
199 for (const auto &element : list) {
200 if (element.metaType().id() == QMetaType::QUrl) {
201 result += element.toUrl().toEncoded();
202 result += "\r\n";
203 }
204 }
205 if (!result.isEmpty())
206 return result;
207 break;
208 }
209 default:
210 break;
211 }
212 }
213 return data;
214}
215
313
320
328QList<QUrl> QMimeData::urls() const
329{
330 Q_D(const QMimeData);
331 QVariant data = d->retrieveTypedData(textUriListLiteral(), QMetaType(QMetaType::QVariantList));
332 QList<QUrl> urls;
333 if (data.metaType().id() == QMetaType::QUrl)
334 urls.append(data.toUrl());
335 else if (data.metaType().id() == QMetaType::QVariantList) {
336 const QList<QVariant> list = data.toList();
337 for (const auto &element : list) {
338 if (element.metaType().id() == QMetaType::QUrl)
339 urls.append(element.toUrl());
340 }
341 }
342 return urls;
343}
344
356void QMimeData::setUrls(const QList<QUrl> &urls)
357{
358 Q_D(QMimeData);
359 d->setData(textUriListLiteral(), QList<QVariant>(urls.cbegin(), urls.cend()));
360}
361
371{
373}
374
375
383{
384 Q_D(const QMimeData);
385 QVariant utf8Text = d->retrieveTypedData(textPlainUtf8Literal(), QMetaType(QMetaType::QString));
386 if (!utf8Text.isNull())
387 return utf8Text.toString();
388
389 QVariant data = d->retrieveTypedData(textPlainLiteral(), QMetaType(QMetaType::QString));
390 return data.toString();
391}
392
400{
401 Q_D(QMimeData);
402 d->setData(textPlainLiteral(), text);
403}
404
412{
413 return hasFormat(textPlainLiteral()) || hasUrls();
414}
415
423{
424 Q_D(const QMimeData);
425 QVariant data = d->retrieveTypedData(textHtmlLiteral(), QMetaType(QMetaType::QString));
426 return data.toString();
427}
428
436{
437 Q_D(QMimeData);
438 d->setData(textHtmlLiteral(), html);
439}
440
448{
449 return hasFormat(textHtmlLiteral());
450}
451
465{
466 Q_D(const QMimeData);
467 return d->retrieveTypedData(applicationXQtImageLiteral(), QMetaType(QMetaType::QImage));
468}
469
482{
483 Q_D(QMimeData);
485}
486
494{
496}
497
512{
513 Q_D(const QMimeData);
514 return d->retrieveTypedData(applicationXColorLiteral(), QMetaType(QMetaType::QColor));
515}
516
525{
526 Q_D(QMimeData);
527 d->setData(applicationXColorLiteral(), color);
528}
529
530
538{
540}
541
547{
548 Q_D(const QMimeData);
549 QVariant data = d->retrieveTypedData(mimeType, QMetaType(QMetaType::QByteArray));
550 return data.toByteArray();
551}
552
568{
569 Q_D(QMimeData);
570
571 if (mimeType == "text/uri-list"_L1) {
572 auto ba = QByteArrayView(data);
573 if (ba.endsWith('\0'))
574 ba.chop(1);
575 d->setData(mimeType, dataToUrls(ba));
576 } else {
577 d->setData(mimeType, QVariant(data));
578 }
579}
580
592{
593 return formats().contains(mimeType);
594}
595
608{
609 Q_D(const QMimeData);
611 list.reserve(static_cast<int>(d->dataList.size()));
612 for (auto &e : d->dataList)
613 list += e.format;
614 return list;
615}
616
633{
634 Q_UNUSED(type);
635 Q_D(const QMimeData);
636 return d->getData(mimeType);
637}
638
643{
644 Q_D(QMimeData);
645 d->dataList.clear();
646}
647
654{
655 Q_D(QMimeData);
656 d->removeData(mimeType);
657}
658
660
661#include "moc_qmimedata.cpp"
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:227
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.
QList< T > toList() const noexcept
Definition qlist.h:723
void push_back(parameter_type t)
Definition qlist.h:675
void reserve(qsizetype size)
Definition qlist.h:753
const_iterator cend() const noexcept
Definition qlist.h:631
void append(parameter_type t)
Definition qlist.h:458
const_iterator cbegin() const noexcept
Definition qlist.h:630
\inmodule QtCore
Definition qmetatype.h:341
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
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:103
iterator end()
Definition qset.h:140
const_iterator cend() const noexcept
Definition qset.h:142
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:129
qsizetype indexOf(QLatin1StringView s, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4517
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6340
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
iterator end()
Returns an \l{STL-style iterators}{STL-style iterator} pointing just after the last character in the ...
Definition qstring.h:1357
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1240
static QUrl fromEncoded(QByteArrayView input, ParsingMode mode=TolerantMode)
Parses input and returns the corresponding QUrl.
Definition qurl.cpp:2988
\inmodule QtCore
Definition qvariant.h:65
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.
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has userType() \l QMetaType::QByteArray or \l QMet...
QString text
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
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint color
[2]
GLenum type
GLint GLsizei GLsizei GLenum format
GLdouble s
[6]
Definition qopenglext.h:235
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
#define Q_UNUSED(x)
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:158
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:180
ptrdiff_t qsizetype
Definition qtypes.h:165
QList< int > list
[14]
QByteArray ba
[0]
QObject::connect nullptr