File indexing completed on 2024-12-01 03:41:11
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2013 Dawit Alemayehu <adawit@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "../utils_p.h" 0009 #include "clipboardupdater_p.h" 0010 #include "copyjob.h" 0011 #include "deletejob.h" 0012 #include "filecopyjob.h" 0013 #include "simplejob.h" 0014 #include <KUrlMimeData> 0015 0016 #include <QClipboard> 0017 #include <QGuiApplication> 0018 #include <QMimeData> 0019 0020 using namespace KIO; 0021 0022 static void overwriteUrlsInClipboard(KJob *job) 0023 { 0024 CopyJob *copyJob = qobject_cast<CopyJob *>(job); 0025 FileCopyJob *fileCopyJob = qobject_cast<FileCopyJob *>(job); 0026 0027 if (!copyJob && !fileCopyJob) { 0028 return; 0029 } 0030 0031 QList<QUrl> newUrls; 0032 0033 if (copyJob) { 0034 const auto srcUrls = copyJob->srcUrls(); 0035 newUrls.reserve(srcUrls.size()); 0036 for (const QUrl &url : srcUrls) { 0037 QUrl dUrl = copyJob->destUrl().adjusted(QUrl::StripTrailingSlash); 0038 dUrl.setPath(Utils::concatPaths(dUrl.path(), url.fileName())); 0039 newUrls.append(dUrl); 0040 } 0041 } else if (fileCopyJob) { 0042 newUrls << fileCopyJob->destUrl(); 0043 } 0044 0045 QMimeData *mime = new QMimeData(); 0046 mime->setUrls(newUrls); 0047 QGuiApplication::clipboard()->setMimeData(mime); 0048 } 0049 0050 static void updateUrlsInClipboard(KJob *job) 0051 { 0052 CopyJob *copyJob = qobject_cast<CopyJob *>(job); 0053 FileCopyJob *fileCopyJob = qobject_cast<FileCopyJob *>(job); 0054 0055 if (!copyJob && !fileCopyJob) { 0056 return; 0057 } 0058 0059 QClipboard *clipboard = QGuiApplication::clipboard(); 0060 auto mimeData = clipboard->mimeData(); 0061 if (!mimeData) { 0062 return; 0063 } 0064 0065 QList<QUrl> clipboardUrls = KUrlMimeData::urlsFromMimeData(mimeData); 0066 bool update = false; 0067 0068 if (copyJob) { 0069 const QList<QUrl> urls = copyJob->srcUrls(); 0070 for (const QUrl &url : urls) { 0071 const int index = clipboardUrls.indexOf(url); 0072 if (index > -1) { 0073 QUrl dUrl = copyJob->destUrl().adjusted(QUrl::StripTrailingSlash); 0074 dUrl.setPath(Utils::concatPaths(dUrl.path(), url.fileName())); 0075 clipboardUrls.replace(index, dUrl); 0076 update = true; 0077 } 0078 } 0079 } else if (fileCopyJob) { 0080 const int index = clipboardUrls.indexOf(fileCopyJob->srcUrl()); 0081 if (index > -1) { 0082 clipboardUrls.replace(index, fileCopyJob->destUrl()); 0083 update = true; 0084 } 0085 } 0086 0087 if (update) { 0088 QMimeData *mime = new QMimeData(); 0089 mime->setUrls(clipboardUrls); 0090 clipboard->setMimeData(mime); 0091 } 0092 } 0093 0094 static void removeUrlsFromClipboard(KJob *job) 0095 { 0096 SimpleJob *simpleJob = qobject_cast<SimpleJob *>(job); 0097 DeleteJob *deleteJob = qobject_cast<DeleteJob *>(job); 0098 0099 if (!simpleJob && !deleteJob) { 0100 return; 0101 } 0102 0103 QList<QUrl> deletedUrls; 0104 if (simpleJob) { 0105 deletedUrls << simpleJob->url(); 0106 } else if (deleteJob) { 0107 deletedUrls << deleteJob->urls(); 0108 } 0109 0110 if (deletedUrls.isEmpty()) { 0111 return; 0112 } 0113 0114 QClipboard *clipboard = QGuiApplication::clipboard(); 0115 auto mimeData = clipboard->mimeData(); 0116 if (!mimeData) { 0117 return; 0118 } 0119 0120 QList<QUrl> clipboardUrls = KUrlMimeData::urlsFromMimeData(mimeData); 0121 quint32 removedCount = 0; 0122 0123 for (const QUrl &url : std::as_const(deletedUrls)) { 0124 removedCount += clipboardUrls.removeAll(url); 0125 } 0126 0127 if (removedCount > 0) { 0128 QMimeData *mime = new QMimeData(); 0129 if (!clipboardUrls.isEmpty()) { 0130 mime->setUrls(clipboardUrls); 0131 } 0132 clipboard->setMimeData(mime); 0133 } 0134 } 0135 0136 void ClipboardUpdater::slotResult(KJob *job) 0137 { 0138 if (job->error()) { 0139 return; 0140 } 0141 0142 switch (m_mode) { 0143 case JobUiDelegateExtension::UpdateContent: 0144 updateUrlsInClipboard(job); 0145 break; 0146 case JobUiDelegateExtension::OverwriteContent: 0147 overwriteUrlsInClipboard(job); 0148 break; 0149 case JobUiDelegateExtension::RemoveContent: 0150 removeUrlsFromClipboard(job); 0151 break; 0152 } 0153 } 0154 0155 void ClipboardUpdater::setMode(JobUiDelegateExtension::ClipboardUpdaterMode mode) 0156 { 0157 m_mode = mode; 0158 } 0159 0160 void ClipboardUpdater::update(const QUrl &srcUrl, const QUrl &destUrl) 0161 { 0162 QClipboard *clipboard = QGuiApplication::clipboard(); 0163 auto mimeData = clipboard->mimeData(); 0164 if (mimeData && mimeData->hasUrls()) { 0165 QList<QUrl> clipboardUrls = KUrlMimeData::urlsFromMimeData(clipboard->mimeData()); 0166 const int index = clipboardUrls.indexOf(srcUrl); 0167 if (index > -1) { 0168 clipboardUrls.replace(index, destUrl); 0169 QMimeData *mime = new QMimeData(); 0170 mime->setUrls(clipboardUrls); 0171 clipboard->setMimeData(mime); 0172 } 0173 } 0174 } 0175 0176 ClipboardUpdater::ClipboardUpdater(Job *job, JobUiDelegateExtension::ClipboardUpdaterMode mode) 0177 : QObject(job) 0178 , m_mode(mode) 0179 { 0180 Q_ASSERT(job); 0181 connect(job, &KJob::result, this, &ClipboardUpdater::slotResult); 0182 } 0183 0184 #include "moc_clipboardupdater_p.cpp"