Changeset View
Changeset View
Standalone View
Standalone View
kioslave/desktop/kio_desktop.cpp
- This file was added.
1 | /* This file is part of the KDE project | ||||
---|---|---|---|---|---|
2 | Copyright (C) 2008, 2009 Fredrik Höglund <fredrik@kde.org> | ||||
3 | | ||||
4 | This library is free software; you can redistribute it and/or | ||||
5 | modify it under the terms of the GNU Library General Public | ||||
6 | License as published by the Free Software Foundation; either | ||||
7 | version 2 of the License, or (at your option) any later version. | ||||
8 | | ||||
9 | This library is distributed in the hope that it will be useful, | ||||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
12 | Library General Public License for more details. | ||||
13 | | ||||
14 | You should have received a copy of the GNU Library General Public License | ||||
15 | along with this library; see the file COPYING.LIB. If not, write to | ||||
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||
17 | Boston, MA 02110-1301, USA. | ||||
18 | */ | ||||
19 | | ||||
20 | #include "kio_desktop.h" | ||||
21 | | ||||
22 | #include <KConfigGroup> | ||||
23 | #include <KDesktopFile> | ||||
24 | #include <KDirNotify> | ||||
25 | | ||||
26 | #include <kio/udsentry.h> | ||||
27 | #include <kio_version.h> | ||||
28 | | ||||
29 | #include <QCoreApplication> | ||||
30 | #include <QFile> | ||||
31 | #include <QDBusInterface> | ||||
32 | #include <QDesktopServices> | ||||
33 | #include <QDir> | ||||
34 | #include <QStandardPaths> | ||||
35 | | ||||
36 | extern "C" | ||||
37 | { | ||||
38 | int Q_DECL_EXPORT kdemain(int argc, char **argv) | ||||
39 | { | ||||
40 | // necessary to use other kio slaves | ||||
41 | QCoreApplication app(argc, argv); | ||||
42 | app.setApplicationName("kio_desktop"); | ||||
43 | | ||||
44 | // start the slave | ||||
45 | DesktopProtocol slave(argv[1], argv[2], argv[3]); | ||||
46 | slave.dispatchLoop(); | ||||
47 | return 0; | ||||
48 | } | ||||
49 | } | ||||
50 | | ||||
51 | DesktopProtocol::DesktopProtocol(const QByteArray& protocol, const QByteArray &pool, const QByteArray &app) | ||||
52 | : KIO::ForwardingSlaveBase(protocol, pool, app) | ||||
53 | { | ||||
54 | checkLocalInstall(); | ||||
55 | | ||||
56 | QDBusInterface kded(QStringLiteral("org.kde.kded5"), QStringLiteral("/kded"), QStringLiteral("org.kde.kded5")); | ||||
57 | kded.call(QStringLiteral("loadModule"), "desktopnotifier"); | ||||
58 | } | ||||
59 | | ||||
60 | DesktopProtocol::~DesktopProtocol() | ||||
61 | { | ||||
62 | } | ||||
63 | | ||||
64 | void DesktopProtocol::checkLocalInstall() | ||||
65 | { | ||||
66 | #ifndef Q_WS_WIN | ||||
67 | // We can't use QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) here, since it returns the home dir | ||||
68 | // if the desktop folder doesn't exist. | ||||
69 | QString desktopPath = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); | ||||
70 | if (desktopPath.isEmpty()) | ||||
71 | desktopPath = QDir::homePath() + "/Desktop"; | ||||
72 | | ||||
73 | const QDir desktopDir(desktopPath); | ||||
74 | bool desktopIsEmpty; | ||||
75 | | ||||
76 | // Create the desktop folder if it doesn't exist | ||||
77 | if (!desktopDir.exists()) { | ||||
78 | ::mkdir(QFile::encodeName(desktopPath), S_IRWXU); | ||||
79 | desktopIsEmpty = true; | ||||
80 | } else | ||||
81 | desktopIsEmpty = desktopDir.entryList(QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot).isEmpty(); | ||||
82 | | ||||
83 | if (desktopIsEmpty) { | ||||
84 | // Copy the .directory file | ||||
85 | QFile::copy(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kio_desktop/directory.desktop")), | ||||
86 | desktopPath + "/.directory"); | ||||
87 | | ||||
88 | // Copy the trash link | ||||
89 | QFile::copy(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kio_desktop/directory.trash")), | ||||
90 | desktopPath + "/trash.desktop"); | ||||
91 | | ||||
92 | // Copy the desktop links | ||||
93 | QSet<QString> links; | ||||
94 | const auto dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("kio_desktop/DesktopLinks"), QStandardPaths::LocateDirectory); | ||||
95 | for (const auto &dir : dirs) { | ||||
96 | const auto fileNames = QDir(dir).entryList({QStringLiteral("*.desktop")}); | ||||
97 | for (const auto &file : fileNames) { | ||||
98 | links += file; | ||||
99 | } | ||||
100 | } | ||||
101 | | ||||
102 | foreach (const QString &link, links) { | ||||
103 | const auto fullPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kio_desktop/DesktopLinks/%1").arg(link)); | ||||
104 | KDesktopFile file(fullPath); | ||||
105 | if (!file.desktopGroup().readEntry("Hidden", false)) | ||||
106 | QFile::copy(fullPath, QStringLiteral("%1/%2").arg(desktopPath, link)); | ||||
107 | } | ||||
108 | } | ||||
109 | #endif | ||||
110 | } | ||||
111 | | ||||
112 | bool DesktopProtocol::rewriteUrl(const QUrl &url, QUrl &newUrl) | ||||
113 | { | ||||
114 | newUrl.setScheme(QStringLiteral("file")); | ||||
115 | newUrl.setPath(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + url.path()); | ||||
116 | return true; | ||||
117 | } | ||||
118 | | ||||
119 | void DesktopProtocol::listDir(const QUrl &url) | ||||
120 | { | ||||
121 | KIO::ForwardingSlaveBase::listDir(url); | ||||
122 | | ||||
123 | QUrl actual; | ||||
124 | rewriteUrl(url, actual); | ||||
125 | | ||||
126 | QDBusInterface kded(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/desktopnotifier"), QStringLiteral("org.kde.DesktopNotifier")); | ||||
127 | kded.call(QStringLiteral("watchDir"), actual.path()); | ||||
128 | } | ||||
129 | | ||||
130 | QString DesktopProtocol::desktopFile(KIO::UDSEntry &entry) const | ||||
131 | { | ||||
132 | const QString name = entry.stringValue(KIO::UDSEntry::UDS_NAME); | ||||
133 | if (name == QLatin1String(".") || name == QLatin1String("..")) | ||||
134 | return QString(); | ||||
135 | | ||||
136 | QUrl url = processedUrl(); | ||||
137 | url.setPath(QStringLiteral("%1/%2").arg(url.path(), name)); | ||||
138 | | ||||
139 | if (entry.isDir()) { | ||||
140 | url.setPath(QStringLiteral("%1/.directory").arg(url.path())); | ||||
141 | if (!QFileInfo::exists(url.path())) | ||||
142 | return QString(); | ||||
143 | | ||||
144 | return url.path(); | ||||
145 | } | ||||
146 | | ||||
147 | if (KDesktopFile::isDesktopFile(url.path())) | ||||
148 | return url.path(); | ||||
149 | | ||||
150 | return QString(); | ||||
151 | } | ||||
152 | | ||||
153 | void DesktopProtocol::prepareUDSEntry(KIO::UDSEntry &entry, bool listing) const | ||||
154 | { | ||||
155 | ForwardingSlaveBase::prepareUDSEntry(entry, listing); | ||||
156 | const QString path = desktopFile(entry); | ||||
157 | | ||||
158 | if (!path.isEmpty()) { | ||||
159 | KDesktopFile file(path); | ||||
160 | | ||||
161 | const QString name = file.readName(); | ||||
162 | if (!name.isEmpty()) | ||||
163 | entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, name); | ||||
164 | | ||||
165 | if (file.noDisplay() || !file.tryExec()) | ||||
166 | entry.insert(KIO::UDSEntry::UDS_HIDDEN, 1); | ||||
167 | } | ||||
168 | | ||||
169 | // Set the target URL to the local path | ||||
170 | QUrl localUrl(QUrl::fromLocalFile(entry.stringValue(KIO::UDSEntry::UDS_LOCAL_PATH))); | ||||
171 | entry.insert(KIO::UDSEntry::UDS_TARGET_URL, localUrl.toString()); | ||||
172 | } | ||||
173 | | ||||
174 | void DesktopProtocol::rename(const QUrl &_src, const QUrl &_dest, KIO::JobFlags flags) | ||||
175 | { | ||||
176 | Q_UNUSED(flags) | ||||
177 | | ||||
178 | if (_src == _dest) { | ||||
179 | finished(); | ||||
180 | return; | ||||
181 | } | ||||
182 | | ||||
183 | QUrl src; | ||||
184 | rewriteUrl(_src, src); | ||||
185 | const QString srcPath = src.toLocalFile(); | ||||
186 | | ||||
187 | QUrl dest; | ||||
188 | rewriteUrl(_dest, dest); | ||||
189 | const QString destPath = dest.toLocalFile(); | ||||
190 | | ||||
191 | if (KDesktopFile::isDesktopFile(srcPath)) { | ||||
192 | QString friendlyName; | ||||
193 | | ||||
194 | if (destPath.endsWith(QLatin1String(".desktop"))) { | ||||
195 | const QString fileName = dest.fileName(); | ||||
196 | friendlyName = KIO::decodeFileName(fileName.left(fileName.length() - 8)); | ||||
197 | } else { | ||||
198 | friendlyName = KIO::decodeFileName(dest.fileName()); | ||||
199 | } | ||||
200 | | ||||
201 | // Update the value of the Name field in the file. | ||||
202 | KDesktopFile file(src.toLocalFile()); | ||||
203 | KConfigGroup cg(file.desktopGroup()); | ||||
204 | cg.writeEntry("Name", friendlyName); | ||||
205 | cg.writeEntry("Name", friendlyName, KConfigGroup::Persistent | KConfigGroup::Localized); | ||||
206 | cg.sync(); | ||||
207 | } | ||||
208 | | ||||
209 | if (QFile(srcPath).rename(destPath)) { | ||||
210 | #if KIO_VERSION >= QT_VERSION_CHECK(5, 20, 0) | ||||
211 | org::kde::KDirNotify::emitFileRenamedWithLocalPath(_src, _dest, destPath); | ||||
212 | #else | ||||
213 | org::kde::KDirNotify::emitFileRenamed(_src, _dest); | ||||
214 | #endif | ||||
215 | finished(); | ||||
216 | } else { | ||||
217 | error(KIO::ERR_CANNOT_RENAME, srcPath); | ||||
218 | } | ||||
219 | } | ||||
220 | |