summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmimedata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qmimedata.cpp')
-rw-r--r--src/corelib/kernel/qmimedata.cpp220
1 files changed, 94 insertions, 126 deletions
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index 21a1350fc5..2c0a89dbd7 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qmimedata.h"
@@ -46,19 +10,21 @@
QT_BEGIN_NAMESPACE
-static inline QString textUriListLiteral() { return QStringLiteral("text/uri-list"); }
-static inline QString textHtmlLiteral() { return QStringLiteral("text/html"); }
-static inline QString textPlainLiteral() { return QStringLiteral("text/plain"); }
-static inline QString textPlainUtf8Literal() { return QStringLiteral("text/plain;charset=utf-8"); }
-static inline QString applicationXColorLiteral() { return QStringLiteral("application/x-color"); }
-static inline QString applicationXQtImageLiteral() { return QStringLiteral("application/x-qt-image"); }
+using namespace Qt::StringLiterals;
+
+static inline QString textUriListLiteral() { return u"text/uri-list"_s; }
+static inline QString textHtmlLiteral() { return u"text/html"_s; }
+static inline QString textPlainLiteral() { return u"text/plain"_s; }
+static inline QString textPlainUtf8Literal() { return u"text/plain;charset=utf-8"_s; }
+static inline QString applicationXColorLiteral() { return u"application/x-color"_s; }
+static inline QString applicationXQtImageLiteral() { return u"application/x-qt-image"_s; }
struct QMimeDataStruct
{
QString format;
QVariant data;
};
-Q_DECLARE_TYPEINFO(QMimeDataStruct, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QMimeDataStruct, Q_RELOCATABLE_TYPE);
class QMimeDataPrivate : public QObjectPrivate
{
@@ -68,7 +34,7 @@ public:
void setData(const QString &format, const QVariant &data);
QVariant getData(const QString &format) const;
- QVariant retrieveTypedData(const QString &format, QMetaType::Type type) const;
+ QVariant retrieveTypedData(const QString &format, QMetaType type) const;
std::vector<QMimeDataStruct>::iterator find(const QString &format) noexcept {
const auto formatEquals = [](const QString &format) {
@@ -110,24 +76,48 @@ QVariant QMimeDataPrivate::getData(const QString &format) const
return it->data;
}
-QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QMetaType::Type type) const
+static QList<QVariant> dataToUrls(QByteArrayView text)
+{
+ QList<QVariant> list;
+ qsizetype newLineIndex = -1;
+ qsizetype from = 0;
+ const char *begin = text.data();
+ while ((newLineIndex = text.indexOf('\n', from)) != -1) {
+ const auto bav = QByteArrayView(begin + from, begin + newLineIndex).trimmed();
+ if (!bav.isEmpty())
+ list.push_back(QUrl::fromEncoded(bav));
+ from = newLineIndex + 1;
+ if (from >= text.size())
+ break;
+ }
+ if (from != text.size()) {
+ const auto bav = QByteArrayView(begin + from, text.end()).trimmed();
+ if (!bav.isEmpty())
+ list.push_back(QUrl::fromEncoded(bav));
+ }
+ return list;
+}
+
+QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QMetaType type) const
{
Q_Q(const QMimeData);
+ int typeId = type.id();
- QVariant data = q->retrieveData(format, QVariant::Type(type));
+ QVariant data = q->retrieveData(format, type);
// Text data requested: fallback to URL data if available
- if (format == QLatin1String("text/plain") && !data.isValid()) {
- data = retrieveTypedData(textUriListLiteral(), QMetaType::QVariantList);
- if (data.userType() == QMetaType::QUrl) {
+ if (format == "text/plain"_L1 && !data.isValid()) {
+ data = retrieveTypedData(textUriListLiteral(), QMetaType(QMetaType::QVariantList));
+ if (data.metaType().id() == QMetaType::QUrl) {
data = QVariant(data.toUrl().toDisplayString());
- } else if (data.userType() == QMetaType::QVariantList) {
+ } else if (data.metaType().id() == QMetaType::QVariantList) {
QString text;
int numUrls = 0;
const QList<QVariant> list = data.toList();
- for (int i = 0; i < list.size(); ++i) {
- if (list.at(i).userType() == QMetaType::QUrl) {
- text += list.at(i).toUrl().toDisplayString() + QLatin1Char('\n');
+ for (const auto &element : list) {
+ if (element.metaType().id() == QMetaType::QUrl) {
+ text += element.toUrl().toDisplayString();
+ text += u'\n';
++numUrls;
}
}
@@ -137,31 +127,32 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QMetaType::T
}
}
- if (data.userType() == type || !data.isValid())
+ if (data.metaType() == type || !data.isValid())
return data;
- // provide more conversion possiblities than just what QVariant provides
+ // provide more conversion possibilities than just what QVariant provides
// URLs can be lists as well...
- if ((type == QMetaType::QUrl && data.userType() == QMetaType::QVariantList)
- || (type == QMetaType::QVariantList && data.userType() == QMetaType::QUrl))
+ if ((typeId == QMetaType::QUrl && data.metaType().id() == QMetaType::QVariantList)
+ || (typeId == QMetaType::QVariantList && data.metaType().id() == QMetaType::QUrl))
return data;
// images and pixmaps are interchangeable
- if ((type == QMetaType::QPixmap && data.userType() == QMetaType::QImage)
- || (type == QMetaType::QImage && data.userType() == QMetaType::QPixmap))
+ if ((typeId == QMetaType::QPixmap && data.metaType().id() == QMetaType::QImage)
+ || (typeId == QMetaType::QImage && data.metaType().id() == QMetaType::QPixmap))
return data;
- if (data.userType() == QMetaType::QByteArray) {
+ if (data.metaType().id() == QMetaType::QByteArray) {
// see if we can convert to the requested type
- switch(type) {
+ switch (typeId) {
case QMetaType::QString: {
const QByteArray ba = data.toByteArray();
- if (format == QLatin1String("text/html")) {
- auto encoding = QStringConverter::encodingForHtml(ba.constData(), ba.size());
- if (encoding) {
- QStringDecoder toUtf16(*encoding);
- return QString(toUtf16(ba));
+ if (ba.isNull())
+ return QVariant();
+ if (format == "text/html"_L1) {
+ QStringDecoder decoder = QStringDecoder::decoderForHtml(ba);
+ if (decoder.isValid()) {
+ return QString(decoder(ba));
}
// fall back to utf8
}
@@ -169,39 +160,31 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QMetaType::T
}
case QMetaType::QColor: {
QVariant newData = data;
- newData.convert(QMetaType::QColor);
+ newData.convert(QMetaType(QMetaType::QColor));
return newData;
}
case QMetaType::QVariantList: {
- if (format != QLatin1String("text/uri-list"))
+ if (format != "text/uri-list"_L1)
break;
Q_FALLTHROUGH();
}
case QMetaType::QUrl: {
- QByteArray ba = data.toByteArray();
+ auto bav = data.view<QByteArrayView>();
// Qt 3.x will send text/uri-list with a trailing
// null-terminator (that is *not* sent for any other
// text/* mime-type), so chop it off
- if (ba.endsWith('\0'))
- ba.chop(1);
-
- QList<QByteArray> urls = ba.split('\n');
- QList<QVariant> list;
- for (int i = 0; i < urls.size(); ++i) {
- QByteArray ba = urls.at(i).trimmed();
- if (!ba.isEmpty())
- list.append(QUrl::fromEncoded(ba));
- }
- return list;
+ if (bav.endsWith('\0'))
+ bav.chop(1);
+ return dataToUrls(bav);
}
default:
break;
}
- } else if (type == QMetaType::QByteArray) {
+ } else if (typeId == QMetaType::QByteArray) {
// try to convert to bytearray
- switch (data.userType()) {
+ switch (data.metaType().id()) {
case QMetaType::QByteArray:
case QMetaType::QColor:
return data.toByteArray();
@@ -212,10 +195,10 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QMetaType::T
case QMetaType::QVariantList: {
// has to be list of URLs
QByteArray result;
- QList<QVariant> list = data.toList();
- for (int i = 0; i < list.size(); ++i) {
- if (list.at(i).userType() == QMetaType::QUrl) {
- result += list.at(i).toUrl().toEncoded();
+ const QList<QVariant> list = data.toList();
+ for (const auto &element : list) {
+ if (element.metaType().id() == QMetaType::QUrl) {
+ result += element.toUrl().toEncoded();
result += "\r\n";
}
}
@@ -312,12 +295,12 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QMetaType::T
\snippet code/src_corelib_kernel_qmimedata.cpp 8
On Windows, the MIME format does not always map directly to the
- clipboard formats. Qt provides QWinMime to map clipboard
+ clipboard formats. Qt provides QWindowsMimeConverter to map clipboard
formats to open-standard MIME formats. Similarly, the
- QMacPasteboardMime maps MIME to Mac flavors.
+ QUtiMimeConverter maps MIME to Uniform Type Identifiers on macOS and iOS.
\sa QClipboard, QDragEnterEvent, QDragMoveEvent, QDropEvent, QDrag,
- QMacPasteboardMime, {Drag and Drop}
+ {Drag and Drop}
*/
/*!
@@ -345,15 +328,15 @@ QMimeData::~QMimeData()
QList<QUrl> QMimeData::urls() const
{
Q_D(const QMimeData);
- QVariant data = d->retrieveTypedData(textUriListLiteral(), QMetaType::QVariantList);
+ QVariant data = d->retrieveTypedData(textUriListLiteral(), QMetaType(QMetaType::QVariantList));
QList<QUrl> urls;
- if (data.userType() == QMetaType::QUrl)
+ if (data.metaType().id() == QMetaType::QUrl)
urls.append(data.toUrl());
- else if (data.userType() == QMetaType::QVariantList) {
- QList<QVariant> list = data.toList();
- for (int i = 0; i < list.size(); ++i) {
- if (list.at(i).userType() == QMetaType::QUrl)
- urls.append(list.at(i).toUrl());
+ else if (data.metaType().id() == QMetaType::QVariantList) {
+ const QList<QVariant> list = data.toList();
+ for (const auto &element : list) {
+ if (element.metaType().id() == QMetaType::QUrl)
+ urls.append(element.toUrl());
}
}
return urls;
@@ -373,13 +356,7 @@ QList<QUrl> QMimeData::urls() const
void QMimeData::setUrls(const QList<QUrl> &urls)
{
Q_D(QMimeData);
- QList<QVariant> list;
- const int numUrls = urls.size();
- list.reserve(numUrls);
- for (int i = 0; i < numUrls; ++i)
- list.append(urls.at(i));
-
- d->setData(textUriListLiteral(), list);
+ d->setData(textUriListLiteral(), QList<QVariant>(urls.cbegin(), urls.cend()));
}
/*!
@@ -405,11 +382,11 @@ bool QMimeData::hasUrls() const
QString QMimeData::text() const
{
Q_D(const QMimeData);
- QVariant utf8Text = d->retrieveTypedData(textPlainUtf8Literal(), QMetaType::QString);
+ QVariant utf8Text = d->retrieveTypedData(textPlainUtf8Literal(), QMetaType(QMetaType::QString));
if (!utf8Text.isNull())
return utf8Text.toString();
- QVariant data = d->retrieveTypedData(textPlainLiteral(), QMetaType::QString);
+ QVariant data = d->retrieveTypedData(textPlainLiteral(), QMetaType(QMetaType::QString));
return data.toString();
}
@@ -445,7 +422,7 @@ bool QMimeData::hasText() const
QString QMimeData::html() const
{
Q_D(const QMimeData);
- QVariant data = d->retrieveTypedData(textHtmlLiteral(), QMetaType::QString);
+ QVariant data = d->retrieveTypedData(textHtmlLiteral(), QMetaType(QMetaType::QString));
return data.toString();
}
@@ -487,7 +464,7 @@ bool QMimeData::hasHtml() const
QVariant QMimeData::imageData() const
{
Q_D(const QMimeData);
- return d->retrieveTypedData(applicationXQtImageLiteral(), QMetaType::QImage);
+ return d->retrieveTypedData(applicationXQtImageLiteral(), QMetaType(QMetaType::QImage));
}
/*!
@@ -534,7 +511,7 @@ bool QMimeData::hasImage() const
QVariant QMimeData::colorData() const
{
Q_D(const QMimeData);
- return d->retrieveTypedData(applicationXColorLiteral(), QMetaType::QColor);
+ return d->retrieveTypedData(applicationXColorLiteral(), QMetaType(QMetaType::QColor));
}
/*!
@@ -569,7 +546,7 @@ bool QMimeData::hasColor() const
QByteArray QMimeData::data(const QString &mimeType) const
{
Q_D(const QMimeData);
- QVariant data = d->retrieveTypedData(mimeType, QMetaType::QByteArray);
+ QVariant data = d->retrieveTypedData(mimeType, QMetaType(QMetaType::QByteArray));
return data.toByteArray();
}
@@ -583,28 +560,19 @@ QByteArray QMimeData::data(const QString &mimeType) const
Note that if you want to use a custom data type in an item view drag and drop
operation, you must register it as a Qt \l{QMetaType}{meta type}, using the
- Q_DECLARE_METATYPE() macro, and implement stream operators for it. The stream
- operators must then be registered with the qRegisterMetaTypeStreamOperators()
- function.
+ Q_DECLARE_METATYPE() macro, and implement stream operators for it.
- \sa hasFormat(), QMetaType, {QMetaType::}{qRegisterMetaTypeStreamOperators()}
+ \sa hasFormat(), QMetaType, {QMetaType::}{Q_DECLARE_METATYPE()}
*/
void QMimeData::setData(const QString &mimeType, const QByteArray &data)
{
Q_D(QMimeData);
- if (mimeType == QLatin1String("text/uri-list")) {
- QByteArray ba = data;
+ if (mimeType == "text/uri-list"_L1) {
+ auto ba = QByteArrayView(data);
if (ba.endsWith('\0'))
ba.chop(1);
- QList<QByteArray> urls = ba.split('\n');
- QList<QVariant> list;
- for (int i = 0; i < urls.size(); ++i) {
- QByteArray ba = urls.at(i).trimmed();
- if (!ba.isEmpty())
- list.append(QUrl::fromEncoded(ba));
- }
- d->setData(mimeType, list);
+ d->setData(mimeType, dataToUrls(ba));
} else {
d->setData(mimeType, QVariant(data));
}
@@ -661,7 +629,7 @@ QStringList QMimeData::formats() const
\sa data()
*/
-QVariant QMimeData::retrieveData(const QString &mimeType, QVariant::Type type) const
+QVariant QMimeData::retrieveData(const QString &mimeType, QMetaType type) const
{
Q_UNUSED(type);
Q_D(const QMimeData);