KIO

clipboardupdater.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2013 Dawit Alemayehu <adawit@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "../utils_p.h"
9#include "clipboardupdater_p.h"
10#include "copyjob.h"
11#include "deletejob.h"
12#include "filecopyjob.h"
13#include "simplejob.h"
14#include <KUrlMimeData>
15
16#include <QClipboard>
17#include <QGuiApplication>
18#include <QMimeData>
19
20using namespace KIO;
21
22static void overwriteUrlsInClipboard(KJob *job)
23{
24 CopyJob *copyJob = qobject_cast<CopyJob *>(job);
25 FileCopyJob *fileCopyJob = qobject_cast<FileCopyJob *>(job);
26
27 if (!copyJob && !fileCopyJob) {
28 return;
29 }
30
31 QList<QUrl> newUrls;
32
33 if (copyJob) {
34 const auto srcUrls = copyJob->srcUrls();
35 newUrls.reserve(srcUrls.size());
36 for (const QUrl &url : srcUrls) {
38 dUrl.setPath(Utils::concatPaths(dUrl.path(), url.fileName()));
39 newUrls.append(dUrl);
40 }
41 } else if (fileCopyJob) {
42 newUrls << fileCopyJob->destUrl();
43 }
44
45 QMimeData *mime = new QMimeData();
46 mime->setUrls(newUrls);
48}
49
50static void updateUrlsInClipboard(KJob *job)
51{
52 CopyJob *copyJob = qobject_cast<CopyJob *>(job);
53 FileCopyJob *fileCopyJob = qobject_cast<FileCopyJob *>(job);
54
55 if (!copyJob && !fileCopyJob) {
56 return;
57 }
58
60 auto mimeData = clipboard->mimeData();
61 if (!mimeData) {
62 return;
63 }
64
65 QList<QUrl> clipboardUrls = KUrlMimeData::urlsFromMimeData(mimeData);
66 bool update = false;
67
68 if (copyJob) {
69 const QList<QUrl> urls = copyJob->srcUrls();
70 for (const QUrl &url : urls) {
71 const int index = clipboardUrls.indexOf(url);
72 if (index > -1) {
74 dUrl.setPath(Utils::concatPaths(dUrl.path(), url.fileName()));
75 clipboardUrls.replace(index, dUrl);
76 update = true;
77 }
78 }
79 } else if (fileCopyJob) {
80 const int index = clipboardUrls.indexOf(fileCopyJob->srcUrl());
81 if (index > -1) {
82 clipboardUrls.replace(index, fileCopyJob->destUrl());
83 update = true;
84 }
85 }
86
87 if (update) {
88 QMimeData *mime = new QMimeData();
89 mime->setUrls(clipboardUrls);
90 clipboard->setMimeData(mime);
91 }
92}
93
94static void removeUrlsFromClipboard(KJob *job)
95{
96 SimpleJob *simpleJob = qobject_cast<SimpleJob *>(job);
97 DeleteJob *deleteJob = qobject_cast<DeleteJob *>(job);
98
99 if (!simpleJob && !deleteJob) {
100 return;
101 }
102
103 QList<QUrl> deletedUrls;
104 if (simpleJob) {
105 deletedUrls << simpleJob->url();
106 } else if (deleteJob) {
107 deletedUrls << deleteJob->urls();
108 }
109
110 if (deletedUrls.isEmpty()) {
111 return;
112 }
113
115 auto mimeData = clipboard->mimeData();
116 if (!mimeData) {
117 return;
118 }
119
120 QList<QUrl> clipboardUrls = KUrlMimeData::urlsFromMimeData(mimeData);
121 quint32 removedCount = 0;
122
123 for (const QUrl &url : std::as_const(deletedUrls)) {
124 removedCount += clipboardUrls.removeAll(url);
125 }
126
127 if (removedCount > 0) {
128 QMimeData *mime = new QMimeData();
129 if (!clipboardUrls.isEmpty()) {
130 mime->setUrls(clipboardUrls);
131 }
132 clipboard->setMimeData(mime);
133 }
134}
135
136void ClipboardUpdater::slotResult(KJob *job)
137{
138 if (job->error()) {
139 return;
140 }
141
142 switch (m_mode) {
143 case JobUiDelegateExtension::UpdateContent:
144 updateUrlsInClipboard(job);
145 break;
146 case JobUiDelegateExtension::OverwriteContent:
147 overwriteUrlsInClipboard(job);
148 break;
149 case JobUiDelegateExtension::RemoveContent:
150 removeUrlsFromClipboard(job);
151 break;
152 }
153}
154
155void ClipboardUpdater::setMode(JobUiDelegateExtension::ClipboardUpdaterMode mode)
156{
157 m_mode = mode;
158}
159
160void ClipboardUpdater::update(const QUrl &srcUrl, const QUrl &destUrl)
161{
163 auto mimeData = clipboard->mimeData();
164 if (mimeData && mimeData->hasUrls()) {
165 QList<QUrl> clipboardUrls = KUrlMimeData::urlsFromMimeData(clipboard->mimeData());
166 const int index = clipboardUrls.indexOf(srcUrl);
167 if (index > -1) {
168 clipboardUrls.replace(index, destUrl);
169 QMimeData *mime = new QMimeData();
170 mime->setUrls(clipboardUrls);
171 clipboard->setMimeData(mime);
172 }
173 }
174}
175
176ClipboardUpdater::ClipboardUpdater(Job *job, JobUiDelegateExtension::ClipboardUpdaterMode mode)
177 : QObject(job)
178 , m_mode(mode)
179{
180 Q_ASSERT(job);
181 connect(job, &KJob::result, this, &ClipboardUpdater::slotResult);
182}
183
184#include "moc_clipboardupdater_p.cpp"
CopyJob is used to move, copy or symlink files and directories.
QList< QUrl > srcUrls() const
Returns the list of source URLs.
Definition copyjob.cpp:452
QUrl destUrl() const
Returns the destination URL.
Definition copyjob.cpp:457
A more complex Job to delete files and directories.
QList< QUrl > urls() const
Returns the list of URLs.
The FileCopyJob copies data from one place to another.
QUrl destUrl() const
Returns the destination URL.
QUrl srcUrl() const
Returns the source URL.
The base class for all jobs.
A simple job (one url and one command).
const QUrl & url() const
Returns the SimpleJob's URL.
Definition simplejob.cpp:70
int error() const
void result(KJob *job)
void update(Part *part, const QByteArray &data, qint64 dataSize)
A namespace for KIO globals.
KCOREADDONS_EXPORT QList< QUrl > urlsFromMimeData(const QMimeData *mimeData, DecodeOptions decodeOptions=PreferKdeUrls, MetaDataMap *metaData=nullptr)
const QMimeData * mimeData(Mode mode) const const
void setMimeData(QMimeData *src, Mode mode)
QClipboard * clipboard()
void append(QList< T > &&value)
qsizetype indexOf(const AT &value, qsizetype from) const const
bool isEmpty() const const
qsizetype removeAll(const AT &t)
void replace(qsizetype i, parameter_type value)
void reserve(qsizetype size)
void setUrls(const QList< QUrl > &urls)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
StripTrailingSlash
QUrl adjusted(FormattingOptions options) const const
QString path(ComponentFormattingOptions options) const const
void setPath(const QString &path, ParsingMode mode)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:58:45 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.