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