File indexing completed on 2024-05-05 05:48:20

0001 /*
0002  * SPDX-FileCopyrightText: 2007-2011 Peter Penz <peter.penz19@gmail.com>
0003  * SPDX-FileCopyrightText: 2007 David Faure <faure@kde.org>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "draganddrophelper.h"
0009 
0010 #include <KIO/DropJob>
0011 #include <KJobWidgets>
0012 
0013 #include <QDBusConnection>
0014 #include <QDBusMessage>
0015 #include <QDropEvent>
0016 #include <QMimeData>
0017 
0018 QHash<QUrl, bool> DragAndDropHelper::m_urlListMatchesUrlCache;
0019 
0020 bool DragAndDropHelper::urlListMatchesUrl(const QList<QUrl> &urls, const QUrl &destUrl)
0021 {
0022     auto iteratorResult = m_urlListMatchesUrlCache.constFind(destUrl);
0023     if (iteratorResult != m_urlListMatchesUrlCache.constEnd()) {
0024         return *iteratorResult;
0025     }
0026 
0027     const bool destUrlMatches = std::find_if(urls.constBegin(),
0028                                              urls.constEnd(),
0029                                              [destUrl](const QUrl &url) {
0030                                                  return url.matches(destUrl, QUrl::StripTrailingSlash);
0031                                              })
0032         != urls.constEnd();
0033 
0034     return *m_urlListMatchesUrlCache.insert(destUrl, destUrlMatches);
0035 }
0036 
0037 KIO::DropJob *DragAndDropHelper::dropUrls(const QUrl &destUrl, QDropEvent *event, QWidget *window)
0038 {
0039     const QMimeData *mimeData = event->mimeData();
0040     if (isArkDndMimeType(mimeData)) {
0041         const QString remoteDBusClient = QString::fromUtf8(mimeData->data(arkDndServiceMimeType()));
0042         const QString remoteDBusPath = QString::fromUtf8(mimeData->data(arkDndPathMimeType()));
0043 
0044         QDBusMessage message = QDBusMessage::createMethodCall(remoteDBusClient,
0045                                                               remoteDBusPath,
0046                                                               QStringLiteral("org.kde.ark.DndExtract"),
0047                                                               QStringLiteral("extractSelectedFilesTo"));
0048         message.setArguments({destUrl.toDisplayString(QUrl::PreferLocalFile)});
0049         QDBusConnection::sessionBus().call(message);
0050     } else {
0051         if (urlListMatchesUrl(event->mimeData()->urls(), destUrl)) {
0052             return nullptr;
0053         }
0054 
0055         // Drop into a directory or a desktop-file
0056         KIO::DropJob *job = KIO::drop(event, destUrl);
0057         KJobWidgets::setWindow(job, window);
0058         return job;
0059     }
0060 
0061     return nullptr;
0062 }
0063 
0064 void DragAndDropHelper::clearUrlListMatchesUrlCache()
0065 {
0066     DragAndDropHelper::m_urlListMatchesUrlCache.clear();
0067 }
0068 
0069 bool DragAndDropHelper::isArkDndMimeType(const QMimeData *mimeData)
0070 {
0071     return mimeData->hasFormat(arkDndServiceMimeType()) && mimeData->hasFormat(arkDndPathMimeType());
0072 }