Changeset View
Changeset View
Standalone View
Standalone View
libtaskmanager/tasktools.cpp
- This file was added.
1 | /******************************************************************** | ||||
---|---|---|---|---|---|
2 | Copyright 2016 Eike Hein <hein.org> | ||||
3 | | ||||
4 | This library is free software; you can redistribute it and/or | ||||
5 | modify it under the terms of the GNU Lesser General Public | ||||
6 | License as published by the Free Software Foundation; either | ||||
7 | version 2.1 of the License, or (at your option) version 3, or any | ||||
8 | later version accepted by the membership of KDE e.V. (or its | ||||
9 | successor approved by the membership of KDE e.V.), which shall | ||||
10 | act as a proxy defined in Section 6 of version 3 of the license. | ||||
11 | | ||||
12 | This library is distributed in the hope that it will be useful, | ||||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
15 | Lesser General Public License for more details. | ||||
16 | | ||||
17 | You should have received a copy of the GNU Lesser General Public | ||||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
19 | *********************************************************************/ | ||||
20 | | ||||
21 | #include "tasktools.h" | ||||
22 | #include "abstracttasksmodel.h" | ||||
23 | | ||||
24 | #include <KConfigGroup> | ||||
25 | #include <KDesktopFile> | ||||
26 | #include <kemailsettings.h> | ||||
27 | #include <KFileItem> | ||||
28 | #include <KMimeTypeTrader> | ||||
29 | #include <KRun> | ||||
30 | #include <KSharedConfig> | ||||
31 | | ||||
32 | #include <QDir> | ||||
33 | | ||||
34 | namespace TaskManager | ||||
35 | { | ||||
36 | | ||||
37 | AppData appDataFromUrl(const QUrl &url, const QIcon &fallbackIcon) | ||||
38 | { | ||||
39 | AppData data; | ||||
40 | data.url = url; | ||||
41 | | ||||
42 | if (url.hasQuery()) { | ||||
43 | QUrlQuery uQuery(url); | ||||
44 | | ||||
45 | if (uQuery.hasQueryItem(QLatin1String("iconData"))) { | ||||
46 | QString iconData(uQuery.queryItemValue(QLatin1String("iconData"))); | ||||
47 | QPixmap pixmap; | ||||
48 | QByteArray bytes = QByteArray::fromBase64(iconData.toLocal8Bit(), QByteArray::Base64UrlEncoding); | ||||
49 | pixmap.loadFromData(bytes); | ||||
50 | data.icon.addPixmap(pixmap); | ||||
51 | } | ||||
52 | } | ||||
53 | | ||||
54 | if (url.isLocalFile() && KDesktopFile::isDesktopFile(url.toLocalFile())) { | ||||
55 | KDesktopFile f(url.toLocalFile()); | ||||
56 | | ||||
57 | const KService::Ptr service = KService::serviceByStorageId(f.fileName()); | ||||
58 | | ||||
59 | if (service && QUrl::fromLocalFile(service->entryPath()) == url) { | ||||
60 | data.name = service->name(); | ||||
61 | data.genericName = service->genericName(); | ||||
62 | data.id = service->storageId(); | ||||
63 | | ||||
64 | if (data.icon.isNull()) { | ||||
65 | data.icon = QIcon::fromTheme(service->icon()); | ||||
66 | } | ||||
67 | } else if (f.tryExec()) { | ||||
68 | data.name = f.readName(); | ||||
69 | data.genericName = f.readGenericName(); | ||||
70 | data.id = QUrl::fromLocalFile(f.fileName()).fileName(); | ||||
71 | | ||||
72 | if (data.icon.isNull()) { | ||||
73 | data.icon = QIcon::fromTheme(f.readIcon()); | ||||
74 | } | ||||
75 | } | ||||
76 | | ||||
77 | if (data.id.endsWith(".desktop")) { | ||||
78 | data.id = data.id.left(data.id.length() - 8); | ||||
79 | } | ||||
80 | } else if (url.scheme() == QLatin1String("preferred")) { | ||||
81 | data.id = defaultApplication(url); | ||||
82 | | ||||
83 | const KService::Ptr service = KService::serviceByStorageId(data.id); | ||||
84 | | ||||
85 | if (service) { | ||||
86 | QString desktopFile = service->entryPath(); | ||||
87 | | ||||
88 | // Update with resolved URL. | ||||
89 | data.url = QUrl::fromLocalFile(desktopFile); | ||||
90 | | ||||
91 | KDesktopFile f(desktopFile); | ||||
92 | KConfigGroup cg(&f, "Desktop Entry"); | ||||
93 | | ||||
94 | data.icon = QIcon::fromTheme(f.readIcon()); | ||||
95 | const QString exec = cg.readEntry("Exec", QString()); | ||||
96 | data.name = cg.readEntry("Name", QString()); | ||||
97 | | ||||
98 | if (data.name.isEmpty() && !exec.isEmpty()) { | ||||
99 | data.name = exec.split(' ').at(0); | ||||
100 | } | ||||
101 | | ||||
102 | data.genericName = f.readGenericName(); | ||||
103 | } | ||||
104 | } | ||||
105 | | ||||
106 | if (data.name.isEmpty()) { | ||||
107 | data.name = url.fileName(); | ||||
108 | } | ||||
109 | | ||||
110 | if (data.icon.isNull()) { | ||||
111 | data.icon = fallbackIcon; | ||||
112 | } | ||||
113 | | ||||
114 | return data; | ||||
115 | } | ||||
116 | | ||||
117 | QString defaultApplication(const QUrl &url) | ||||
118 | { | ||||
119 | if (url.scheme() != QLatin1String("preferred")) { | ||||
120 | return QString(); | ||||
121 | } | ||||
122 | | ||||
123 | const QString &application = url.host(); | ||||
124 | | ||||
125 | if (application.isEmpty()) { | ||||
126 | return QString(); | ||||
127 | } | ||||
128 | | ||||
129 | if (application.compare(QLatin1String("mailer"), Qt::CaseInsensitive) == 0) { | ||||
130 | KEMailSettings settings; | ||||
131 | | ||||
132 | // In KToolInvocation, the default is kmail; but let's be friendlier. | ||||
133 | QString command = settings.getSetting(KEMailSettings::ClientProgram); | ||||
134 | | ||||
135 | if (command.isEmpty()) { | ||||
136 | if (KService::Ptr kontact = KService::serviceByStorageId(QStringLiteral("kontact"))) { | ||||
137 | return kontact->storageId(); | ||||
138 | } else if (KService::Ptr kmail = KService::serviceByStorageId(QStringLiteral("kmail"))) { | ||||
139 | return kmail->storageId(); | ||||
140 | } | ||||
141 | } | ||||
142 | | ||||
143 | if (!command.isEmpty()) { | ||||
144 | if (settings.getSetting(KEMailSettings::ClientTerminal) == QLatin1String("true")) { | ||||
145 | KConfigGroup confGroup(KSharedConfig::openConfig(), "General"); | ||||
146 | const QString preferredTerminal = confGroup.readPathEntry("TerminalApplication", | ||||
147 | QStringLiteral("konsole")); | ||||
148 | command = preferredTerminal + QLatin1String(" -e ") + command; | ||||
149 | } | ||||
150 | | ||||
151 | return command; | ||||
152 | } | ||||
153 | } else if (application.compare(QLatin1String("browser"), Qt::CaseInsensitive) == 0) { | ||||
154 | KConfigGroup config(KSharedConfig::openConfig(), "General"); | ||||
155 | QString browserApp = config.readPathEntry("BrowserApplication", QString()); | ||||
156 | | ||||
157 | if (browserApp.isEmpty()) { | ||||
158 | const KService::Ptr htmlApp = KMimeTypeTrader::self()->preferredService(QStringLiteral("text/html")); | ||||
159 | | ||||
160 | if (htmlApp) { | ||||
161 | browserApp = htmlApp->storageId(); | ||||
162 | } | ||||
163 | } else if (browserApp.startsWith('!')) { | ||||
164 | browserApp = browserApp.mid(1); | ||||
165 | } | ||||
166 | | ||||
167 | return browserApp; | ||||
168 | } else if (application.compare(QLatin1String("terminal"), Qt::CaseInsensitive) == 0) { | ||||
169 | KConfigGroup confGroup(KSharedConfig::openConfig(), "General"); | ||||
170 | | ||||
171 | return confGroup.readPathEntry("TerminalApplication", QStringLiteral("konsole")); | ||||
172 | } else if (application.compare(QLatin1String("filemanager"), Qt::CaseInsensitive) == 0) { | ||||
173 | KService::Ptr service = KMimeTypeTrader::self()->preferredService(QStringLiteral("inode/directory")); | ||||
174 | | ||||
175 | if (service) { | ||||
176 | return service->storageId(); | ||||
177 | } | ||||
178 | } else if (application.compare(QLatin1String("windowmanager"), Qt::CaseInsensitive) == 0) { | ||||
179 | KConfig cfg(QStringLiteral("ksmserverrc"), KConfig::NoGlobals); | ||||
180 | KConfigGroup confGroup(&cfg, "General"); | ||||
181 | | ||||
182 | return confGroup.readEntry("windowManager", QStringLiteral("kwin")); | ||||
183 | } else if (KService::Ptr service = KMimeTypeTrader::self()->preferredService(application)) { | ||||
184 | return service->storageId(); | ||||
185 | } else { | ||||
186 | // Try the files in share/apps/kcm_componentchooser/*.desktop. | ||||
187 | QStringList directories = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("kcm_componentchooser"), QStandardPaths::LocateDirectory); | ||||
188 | QStringList services; | ||||
189 | | ||||
190 | foreach(const QString& directory, directories) { | ||||
191 | QDir dir(directory); | ||||
192 | foreach(const QString& f, dir.entryList(QStringList("*.desktop"))) | ||||
193 | services += dir.absoluteFilePath(f); | ||||
194 | } | ||||
195 | | ||||
196 | foreach (const QString & service, services) { | ||||
197 | KConfig config(service, KConfig::SimpleConfig); | ||||
198 | KConfigGroup cg = config.group(QByteArray()); | ||||
199 | const QString type = cg.readEntry("valueName", QString()); | ||||
200 | | ||||
201 | if (type.compare(application, Qt::CaseInsensitive) == 0) { | ||||
202 | KConfig store(cg.readPathEntry("storeInFile", QStringLiteral("null"))); | ||||
203 | KConfigGroup storeCg(&store, cg.readEntry("valueSection", QString())); | ||||
204 | const QString exec = storeCg.readPathEntry(cg.readEntry("valueName", "kcm_componenchooser_null"), | ||||
205 | cg.readEntry("defaultImplementation", QString())); | ||||
206 | | ||||
207 | if (!exec.isEmpty()) { | ||||
208 | return exec; | ||||
209 | } | ||||
210 | | ||||
211 | break; | ||||
212 | } | ||||
213 | } | ||||
214 | } | ||||
215 | | ||||
216 | return QString(""); | ||||
217 | } | ||||
218 | | ||||
219 | bool launcherUrlsMatch(const QUrl &_a, const QUrl &_b, UrlComparisonMode mode) | ||||
220 | { | ||||
221 | if (mode == IgnoreQueryItems) { | ||||
222 | QUrl a(_a); | ||||
223 | a.setQuery(QUrlQuery()); | ||||
224 | | ||||
225 | QUrl b(_b); | ||||
226 | b.setQuery(QUrlQuery()); | ||||
227 | | ||||
228 | return (a == b); | ||||
229 | } | ||||
230 | | ||||
231 | return (_a == _b); | ||||
232 | } | ||||
233 | | ||||
234 | bool appsMatch(const QModelIndex &a, const QModelIndex &b) | ||||
235 | { | ||||
236 | const QString &aAppId = a.data(AbstractTasksModel::AppId).toString(); | ||||
237 | const QString &bAppId = b.data(AbstractTasksModel::AppId).toString(); | ||||
238 | | ||||
239 | if (!aAppId.isEmpty() && bAppId.isEmpty() && (aAppId == bAppId)) { | ||||
240 | return true; | ||||
241 | } | ||||
242 | | ||||
243 | const QUrl &aLauncherUrl = a.data(AbstractTasksModel::LauncherUrl).toUrl(); | ||||
244 | const QUrl &bLauncherUrl = b.data(AbstractTasksModel::LauncherUrl).toUrl(); | ||||
245 | | ||||
246 | if (aLauncherUrl.isValid() && bLauncherUrl.isValid() && (aLauncherUrl == bLauncherUrl)) { | ||||
247 | return true; | ||||
248 | } | ||||
249 | | ||||
250 | return false; | ||||
251 | } | ||||
252 | | ||||
253 | } |