Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qinternalmimedata.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 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
6
7#include <QtCore/qbuffer.h>
8#include <QtGui/qimage.h>
9#include <QtGui/qimagereader.h>
10#include <QtGui/qimagewriter.h>
11
13
14using namespace Qt::StringLiterals;
15
16static QStringList imageMimeFormats(const QList<QByteArray> &imageFormats)
17{
18 QStringList formats;
19 formats.reserve(imageFormats.size());
20 for (const auto &format : imageFormats)
21 formats.append("image/"_L1 + QLatin1StringView(format.toLower()));
22
23 //put png at the front because it is best
24 const qsizetype pngIndex = formats.indexOf("image/png"_L1);
25 if (pngIndex != -1 && pngIndex != 0)
26 formats.move(pngIndex, 0);
27
28 return formats;
29}
30
32{
33 return imageMimeFormats(QImageReader::supportedImageFormats());
34}
35
37{
38 return imageMimeFormats(QImageWriter::supportedImageFormats());
39}
40
41QInternalMimeData::QInternalMimeData()
42 : QMimeData()
43{
44}
45
46QInternalMimeData::~QInternalMimeData()
47{
48}
49
50bool QInternalMimeData::hasFormat(const QString &mimeType) const
51{
52 bool foundFormat = hasFormat_sys(mimeType);
53 if (!foundFormat && mimeType == "application/x-qt-image"_L1) {
54 QStringList imageFormats = imageReadMimeFormats();
55 for (int i = 0; i < imageFormats.size(); ++i) {
56 if ((foundFormat = hasFormat_sys(imageFormats.at(i))))
57 break;
58 }
59 }
60 return foundFormat;
61}
62
63QStringList QInternalMimeData::formats() const
64{
65 QStringList realFormats = formats_sys();
66 if (!realFormats.contains("application/x-qt-image"_L1)) {
67 QStringList imageFormats = imageReadMimeFormats();
68 for (int i = 0; i < imageFormats.size(); ++i) {
69 if (realFormats.contains(imageFormats.at(i))) {
70 realFormats += "application/x-qt-image"_L1;
71 break;
72 }
73 }
74 }
75 return realFormats;
76}
77
78QVariant QInternalMimeData::retrieveData(const QString &mimeType, QMetaType type) const
79{
80 QVariant data = retrieveData_sys(mimeType, type);
81 const QByteArray *ba = get_if<QByteArray>(&std::as_const(data));
82 if (mimeType == "application/x-qt-image"_L1) {
83 if (data.isNull() || (ba && ba->isEmpty())) {
84 // try to find an image
85 QStringList imageFormats = imageReadMimeFormats();
86 for (int i = 0; i < imageFormats.size(); ++i) {
87 data = retrieveData_sys(imageFormats.at(i), type);
88 ba = get_if<QByteArray>(&std::as_const(data));
89 if (data.isNull() || (ba && ba->isEmpty()))
90 continue;
91 break;
92 }
93 }
94 int typeId = type.id();
95 // we wanted some image type, but all we got was a byte array. Convert it to an image.
96 if (ba
97 && (typeId == QMetaType::QImage || typeId == QMetaType::QPixmap || typeId == QMetaType::QBitmap))
98 data = QImage::fromData(*ba);
99
100 } else if (ba && mimeType == "application/x-color"_L1) {
101 QColor c;
102 if (ba->size() == 8) {
103 auto colBuf = reinterpret_cast<const ushort *>(ba->data());
104 c.setRgbF(qreal(colBuf[0]) / qreal(0xFFFF),
105 qreal(colBuf[1]) / qreal(0xFFFF),
106 qreal(colBuf[2]) / qreal(0xFFFF),
107 qreal(colBuf[3]) / qreal(0xFFFF));
108 data = c;
109 } else {
110 qWarning("Qt: Invalid color format");
111 }
112 } else if (ba && data.metaType() != type) {
113 // try to use mime data's internal conversion stuf.
114 QInternalMimeData *that = const_cast<QInternalMimeData *>(this);
115 that->setData(mimeType, *ba);
116 data = QMimeData::retrieveData(mimeType, type);
117 that->clear();
118 }
119 return data;
120}
121
122bool QInternalMimeData::canReadData(const QString &mimeType)
123{
124 return imageReadMimeFormats().contains(mimeType);
125}
126
127// helper functions for rendering mimedata to the system, this is needed because QMimeData is in core.
128QStringList QInternalMimeData::formatsHelper(const QMimeData *data)
129{
130 QStringList realFormats = data->formats();
131 if (realFormats.contains("application/x-qt-image"_L1)) {
132 // add all supported image formats
133 QStringList imageFormats = imageWriteMimeFormats();
134 for (int i = 0; i < imageFormats.size(); ++i) {
135 if (!realFormats.contains(imageFormats.at(i)))
136 realFormats.append(imageFormats.at(i));
137 }
138 }
139 return realFormats;
140}
141
142bool QInternalMimeData::hasFormatHelper(const QString &mimeType, const QMimeData *data)
143{
144
145 bool foundFormat = data->hasFormat(mimeType);
146 if (!foundFormat) {
147 if (mimeType == "application/x-qt-image"_L1) {
148 // check all supported image formats
149 QStringList imageFormats = imageWriteMimeFormats();
150 for (int i = 0; i < imageFormats.size(); ++i) {
151 if ((foundFormat = data->hasFormat(imageFormats.at(i))))
152 break;
153 }
154 } else if (mimeType.startsWith("image/"_L1)) {
155 return data->hasImage() && imageWriteMimeFormats().contains(mimeType);
156 }
157 }
158 return foundFormat;
159}
160
161QByteArray QInternalMimeData::renderDataHelper(const QString &mimeType, const QMimeData *data)
162{
163 QByteArray ba;
164 if (mimeType == "application/x-color"_L1) {
165 /* QMimeData can only provide colors as QColor or the name
166 of a color as a QByteArray or a QString. So we need to do
167 the conversion to application/x-color here.
168 The application/x-color format is :
169 type: application/x-color
170 format: 16
171 data[0]: red
172 data[1]: green
173 data[2]: blue
174 data[3]: opacity
175 */
176 ba.resize(8);
177 ushort * colBuf = (ushort *)ba.data();
178 QColor c = qvariant_cast<QColor>(data->colorData());
179 colBuf[0] = ushort(c.redF() * 0xFFFF);
180 colBuf[1] = ushort(c.greenF() * 0xFFFF);
181 colBuf[2] = ushort(c.blueF() * 0xFFFF);
182 colBuf[3] = ushort(c.alphaF() * 0xFFFF);
183 } else {
184 ba = data->data(mimeType);
185 if (ba.isEmpty()) {
186 if (mimeType == "application/x-qt-image"_L1 && data->hasImage()) {
187 QImage image = qvariant_cast<QImage>(data->imageData());
188 QBuffer buf(&ba);
189 buf.open(QBuffer::WriteOnly);
190 // would there not be PNG ??
191 image.save(&buf, "PNG");
192 } else if (auto prefix = "image/"_L1; mimeType.startsWith(prefix) && data->hasImage()) {
193 QImage image = qvariant_cast<QImage>(data->imageData());
194 QBuffer buf(&ba);
195 buf.open(QBuffer::WriteOnly);
196 auto type = QStringView{mimeType}.sliced(prefix.size());
197 image.save(&buf, type.toLatin1().toUpper().constData());
198 }
199 }
200 }
201 return ba;
202}
203
204QT_END_NAMESPACE
205
206#include "moc_qinternalmimedata_p.cpp"
Combined button and popup list for selecting options.
static QStringList imageReadMimeFormats()
static QStringList imageMimeFormats(const QList< QByteArray > &imageFormats)
static QStringList imageWriteMimeFormats()