diff --git a/autotests/kurlmimedatatest.cpp b/autotests/kurlmimedatatest.cpp index 96ac329..3a53c55 100644 --- a/autotests/kurlmimedatatest.cpp +++ b/autotests/kurlmimedatatest.cpp @@ -1,139 +1,172 @@ /* This file is part of the KDE libraries Copyright (c) 2005 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kurlmimedatatest.h" #include #include #include QTEST_MAIN(KUrlMimeDataTest) void KUrlMimeDataTest::testURLList() { QMimeData *mimeData = new QMimeData(); QVERIFY(!mimeData->hasUrls()); QList urls; urls.append(QUrl(QLatin1String("https://www.kde.org"))); urls.append(QUrl(QLatin1String("http://wstephenson:secret@example.com/path"))); urls.append(QUrl(QLatin1String("file:///home/dfaure/konqtests/Mat%C3%A9riel"))); QMap metaData; metaData[QLatin1String("key")] = QLatin1String("value"); metaData[QLatin1String("key2")] = QLatin1String("value2"); KUrlMimeData::setUrls(QList(), urls, mimeData); KUrlMimeData::setMetaData(metaData, mimeData); QVERIFY(mimeData->hasUrls()); QVERIFY(mimeData->hasText()); QMap decodedMetaData; QList decodedURLs = KUrlMimeData::urlsFromMimeData(mimeData, KUrlMimeData::PreferKdeUrls, &decodedMetaData); QVERIFY(!decodedURLs.isEmpty()); QList expectedUrls = urls; expectedUrls[1] = QUrl(QLatin1String("http://wstephenson:secret@example.com/path")); // password kept, unlike in KDE4, but that's okay, it's not displayed QCOMPARE(expectedUrls, decodedURLs); const QList qurls = mimeData->urls(); QCOMPARE(qurls.count(), urls.count()); for (int i = 0; i < qurls.count(); ++i) { QCOMPARE(qurls[i], decodedURLs[i]); } QVERIFY(!decodedMetaData.isEmpty()); QCOMPARE(decodedMetaData[QLatin1String("key")], QString::fromLatin1("value")); QCOMPARE(decodedMetaData[QLatin1String("key2")], QString::fromLatin1("value2")); delete mimeData; } void KUrlMimeDataTest::testOneURL() { QUrl oneURL(QLatin1String("file:///tmp")); QList oneEltList; oneEltList.append(oneURL); QMimeData *mimeData = new QMimeData(); KUrlMimeData::setUrls(QList(), oneEltList, mimeData); QVERIFY(mimeData->hasUrls()); QMap decodedMetaData; QList decodedURLs = KUrlMimeData::urlsFromMimeData(mimeData, KUrlMimeData::PreferKdeUrls, &decodedMetaData); QVERIFY(!decodedURLs.isEmpty()); QCOMPARE(decodedURLs.count(), 1); QCOMPARE(decodedURLs[0], oneURL); QVERIFY(decodedMetaData.isEmpty()); delete mimeData; } void KUrlMimeDataTest::testFromQUrl() { QList qurls; qurls.append(QUrl(QLatin1String("https://www.kde.org"))); qurls.append(QUrl(QLatin1String("file:///home/dfaure/konqtests/Mat%C3%A9riel"))); QMimeData *mimeData = new QMimeData(); KUrlMimeData::setUrls(QList(), qurls, mimeData); QVERIFY(mimeData->hasUrls()); QMap decodedMetaData; QList decodedURLs = KUrlMimeData::urlsFromMimeData(mimeData, KUrlMimeData::PreferKdeUrls, &decodedMetaData); QVERIFY(!decodedURLs.isEmpty()); QCOMPARE(decodedURLs.count(), 2); QCOMPARE(decodedURLs[0], qurls[0]); QCOMPARE(decodedURLs[1], qurls[1]); QVERIFY(decodedMetaData.isEmpty()); delete mimeData; } +void KUrlMimeDataTest::testMostLocalUrlList_data() +{ + QTest::addColumn("withKdeUrls"); + QTest::addColumn("withLocalUrls"); + QTest::addColumn("expectedLocalUrls"); + + QTest::newRow("both") << true << true << false; + QTest::newRow("local_only") << false << true << true; + QTest::newRow("kde_only") << true << false << false; +} + void KUrlMimeDataTest::testMostLocalUrlList() { + QFETCH(bool, withKdeUrls); + QFETCH(bool, withLocalUrls); + QFETCH(bool, expectedLocalUrls); + QMimeData *mimeData = new QMimeData(); QList urls; urls.append(QUrl(QLatin1String("desktop:/foo"))); urls.append(QUrl(QLatin1String("desktop:/bar"))); QList localUrls; localUrls.append(QUrl(QLatin1String("file:/home/dfaure/Desktop/foo"))); localUrls.append(QUrl(QLatin1String("file:/home/dfaure/Desktop/bar"))); - KUrlMimeData::setUrls(urls, localUrls, mimeData); + if (withKdeUrls && withLocalUrls) { + KUrlMimeData::setUrls(urls, localUrls, mimeData); + } else if (withKdeUrls) { + KUrlMimeData::setUrls(urls, {}, mimeData); + } else if (withLocalUrls) { + KUrlMimeData::setUrls({}, localUrls, mimeData); + } QVERIFY(mimeData->hasUrls()); QVERIFY(mimeData->hasText()); // The support for urls is done in hasText, a direct call to hasFormat will say false. //QVERIFY(mimeData->hasFormat(QLatin1String("text/plain"))); - // urlsFromMimeData decodes the real "kde" urls by default + // urlsFromMimeData decodes the real "kde" urls by default, if any QList decodedURLs = KUrlMimeData::urlsFromMimeData(mimeData); QVERIFY(!decodedURLs.isEmpty()); - QCOMPARE(decodedURLs, urls); + if (expectedLocalUrls) { + QCOMPARE(decodedURLs, localUrls); + } else { + QCOMPARE(decodedURLs, urls); + } // urlsFromMimeData can also be told to decode the "most local" urls decodedURLs = KUrlMimeData::urlsFromMimeData(mimeData, KUrlMimeData::PreferLocalUrls); QVERIFY(!decodedURLs.isEmpty()); - QCOMPARE(decodedURLs, localUrls); + if (withLocalUrls) { + QCOMPARE(decodedURLs, localUrls); + } else { + QCOMPARE(decodedURLs, urls); + } // QMimeData decodes the "most local" urls const QList qurls = mimeData->urls(); - QCOMPARE(qurls.count(), localUrls.count()); - for (int i = 0; i < qurls.count(); ++i) { - QCOMPARE(qurls[i], static_cast(localUrls[i])); + if (withLocalUrls) { + QCOMPARE(qurls.count(), localUrls.count()); + for (int i = 0; i < qurls.count(); ++i) { + QCOMPARE(qurls[i], static_cast(localUrls[i])); + } + } else { + QCOMPARE(qurls.count(), 0); } delete mimeData; } diff --git a/autotests/kurlmimedatatest.h b/autotests/kurlmimedatatest.h index 36cd77a..db34551 100644 --- a/autotests/kurlmimedatatest.h +++ b/autotests/kurlmimedatatest.h @@ -1,35 +1,36 @@ /* This file is part of the KDE libraries Copyright (c) 2005 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KURLMIMEDATATEST_H #define KURLMIMEDATATEST_H #include class KUrlMimeDataTest : public QObject { Q_OBJECT private Q_SLOTS: void testURLList(); void testOneURL(); void testFromQUrl(); + void testMostLocalUrlList_data(); void testMostLocalUrlList(); }; #endif diff --git a/src/lib/io/kurlmimedata.cpp b/src/lib/io/kurlmimedata.cpp index 498a8a4..511aab1 100644 --- a/src/lib/io/kurlmimedata.cpp +++ b/src/lib/io/kurlmimedata.cpp @@ -1,113 +1,120 @@ /* This file is part of the KDE libraries * Copyright (C) 2005-2012 David Faure * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kurlmimedata.h" #include #include static const char s_kdeUriListMime[] = "application/x-kde4-urilist"; // keep this name "kde4" for compat. static QByteArray uriListData(const QList &urls) { // compatible with qmimedata.cpp encoding of QUrls QByteArray result; for (int i = 0; i < urls.size(); ++i) { result += urls.at(i).toEncoded(); result += "\r\n"; } return result; } void KUrlMimeData::setUrls(const QList &urls, const QList &mostLocalUrls, QMimeData *mimeData) { // Export the most local urls as text/uri-list and plain text, for non KDE apps. mimeData->setUrls(mostLocalUrls); // set text/uri-list and text/plain // Export the real KIO urls as a kde-specific mimetype mimeData->setData(QString::fromLatin1(s_kdeUriListMime), uriListData(urls)); } void KUrlMimeData::setMetaData(const MetaDataMap &metaData, QMimeData *mimeData) { QByteArray metaDataData; // :) for (MetaDataMap::const_iterator it = metaData.begin(); it != metaData.end(); ++it) { metaDataData += it.key().toUtf8(); metaDataData += "$@@$"; metaDataData += it.value().toUtf8(); metaDataData += "$@@$"; } mimeData->setData(QStringLiteral("application/x-kio-metadata"), metaDataData); } QStringList KUrlMimeData::mimeDataTypes() { return QStringList() << QString::fromLatin1(s_kdeUriListMime) << QStringLiteral("text/uri-list"); } +static QList extractKdeUriList(const QMimeData *mimeData) +{ + QList uris; + const QByteArray ba = mimeData->data(QString::fromLatin1(s_kdeUriListMime)); + // Code from qmimedata.cpp + QList urls = ba.split('\n'); + for (int i = 0; i < urls.size(); ++i) { + QByteArray data = urls.at(i).trimmed(); + if (!data.isEmpty()) { + uris.append(QUrl::fromEncoded(data)); + } + } + return uris; +} + + QList KUrlMimeData::urlsFromMimeData(const QMimeData *mimeData, DecodeOptions decodeOptions, MetaDataMap *metaData) { QList uris; - const char *firstMimeType = s_kdeUriListMime; - const char *secondMimeType = "text/uri-list"; if (decodeOptions == PreferLocalUrls) { - qSwap(firstMimeType, secondMimeType); - } - QByteArray ba = mimeData->data(QString::fromLatin1(firstMimeType)); - if (ba.isEmpty()) { // Extracting uris from text/uri-list, use the much faster QMimeData method urls() - if (mimeData->hasUrls()) { - uris = mimeData->urls(); + uris = mimeData->urls(); + if (uris.isEmpty()) { + uris = extractKdeUriList(mimeData); } } else { - // Code from qmimedata.cpp - QList urls = ba.split('\n'); - for (int i = 0; i < urls.size(); ++i) { - QByteArray data = urls.at(i).trimmed(); - if (!data.isEmpty()) { - uris.append(QUrl::fromEncoded(data)); - } + uris = extractKdeUriList(mimeData); + if (uris.isEmpty()) { + uris = mimeData->urls(); } } if (metaData) { const QByteArray metaDataPayload = mimeData->data(QStringLiteral("application/x-kio-metadata")); if (!metaDataPayload.isEmpty()) { QString str = QString::fromUtf8(metaDataPayload.constData()); Q_ASSERT(str.endsWith(QLatin1String("$@@$"))); str.truncate(str.length() - 4); const QStringList lst = str.split(QStringLiteral("$@@$")); bool readingKey = true; // true, then false, then true, etc. QString key; for (QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it) { if (readingKey) { key = *it; } else { metaData->insert(key, *it); } readingKey = !readingKey; } Q_ASSERT(readingKey); // an odd number of items would be, well, odd ;-) } } return uris; }