KIO

kprotocolinfo.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 1999 Torben Weis <weis@kde.org>
4 SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
5 SPDX-FileCopyrightText: 2012 David Faure <faure@kde.org>
6 SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
7
8 SPDX-License-Identifier: LGPL-2.0-only
9*/
10
11#include "kprotocolinfo.h"
12#include "kprotocolinfo_p.h"
13#include "kprotocolinfofactory_p.h"
14
15#include "kiocoredebug.h"
16
17#include <KApplicationTrader>
18#include <KConfig>
19#include <KConfigGroup>
20#include <KJsonUtils>
21#include <KPluginMetaData>
22#include <KSharedConfig>
23#include <QUrl>
24
25KProtocolInfoPrivate::KProtocolInfoPrivate(const QString &name, const QString &exec, const QJsonObject &json)
26 : m_name(name)
27 , m_exec(exec)
28{
29 // source has fallback true if not set
30 m_isSourceProtocol = json.value(QStringLiteral("source")).toBool(true);
31 // true if not set for backwards compatibility
32 m_supportsPermissions = json.value(QStringLiteral("permissions")).toBool(true);
33
34 // other bools are fine with default false by toBool
35 m_isHelperProtocol = json.value(QStringLiteral("helper")).toBool();
36 m_supportsReading = json.value(QStringLiteral("reading")).toBool();
37 m_supportsWriting = json.value(QStringLiteral("writing")).toBool();
38 m_supportsMakeDir = json.value(QStringLiteral("makedir")).toBool();
39 m_supportsDeleting = json.value(QStringLiteral("deleting")).toBool();
40 m_supportsLinking = json.value(QStringLiteral("linking")).toBool();
41 m_supportsMoving = json.value(QStringLiteral("moving")).toBool();
42 m_supportsOpening = json.value(QStringLiteral("opening")).toBool();
43 m_supportsTruncating = json.value(QStringLiteral("truncating")).toBool();
44 m_canCopyFromFile = json.value(QStringLiteral("copyFromFile")).toBool();
45 m_canCopyToFile = json.value(QStringLiteral("copyToFile")).toBool();
46 m_canRenameFromFile = json.value(QStringLiteral("renameFromFile")).toBool();
47 m_canRenameToFile = json.value(QStringLiteral("renameToFile")).toBool();
48 m_canDeleteRecursive = json.value(QStringLiteral("deleteRecursive")).toBool();
49
50 // default is "FromURL"
51 const QString fnu = json.value(QStringLiteral("fileNameUsedForCopying")).toString();
52 m_fileNameUsedForCopying = KProtocolInfo::FromUrl;
53 if (fnu == QLatin1String("Name")) {
54 m_fileNameUsedForCopying = KProtocolInfo::Name;
55 } else if (fnu == QLatin1String("DisplayName")) {
56 m_fileNameUsedForCopying = KProtocolInfo::DisplayName;
57 }
58
59 m_listing = json.value(QStringLiteral("listing")).toVariant().toStringList();
60 // Many .protocol files say "Listing=false" when they really mean "Listing=" (i.e. unsupported)
61 if (m_listing.count() == 1 && m_listing.first() == QLatin1String("false")) {
62 m_listing.clear();
63 }
64 m_supportsListing = (m_listing.count() > 0);
65
66 m_defaultMimetype = json.value(QStringLiteral("defaultMimetype")).toString();
67
68 // determineMimetypeFromExtension has fallback true if not set
69 m_determineMimetypeFromExtension = json.value(QStringLiteral("determineMimetypeFromExtension")).toBool(true);
70
71 m_archiveMimeTypes = json.value(QStringLiteral("archiveMimetype")).toVariant().toStringList();
72
73 m_icon = json.value(QStringLiteral("Icon")).toString();
74
75 // config has fallback to name if not set
76 m_config = json.value(QStringLiteral("config")).toString(m_name);
77
78 // max workers has fallback to 1 if not set
79 m_maxWorkers = json.value(QStringLiteral("maxInstances")).toInt(1);
80
81 m_maxWorkersPerHost = json.value(QStringLiteral("maxInstancesPerHost")).toInt();
82
83 QString tmp = json.value(QStringLiteral("input")).toString();
84 if (tmp == QLatin1String("filesystem")) {
85 m_inputType = KProtocolInfo::T_FILESYSTEM;
86 } else if (tmp == QLatin1String("stream")) {
87 m_inputType = KProtocolInfo::T_STREAM;
88 } else {
89 m_inputType = KProtocolInfo::T_NONE;
90 }
91
92 tmp = json.value(QStringLiteral("output")).toString();
93 if (tmp == QLatin1String("filesystem")) {
94 m_outputType = KProtocolInfo::T_FILESYSTEM;
95 } else if (tmp == QLatin1String("stream")) {
96 m_outputType = KProtocolInfo::T_STREAM;
97 } else {
98 m_outputType = KProtocolInfo::T_NONE;
99 }
100
101 m_docPath = json.value(QStringLiteral("X-DocPath")).toString();
102 if (m_docPath.isEmpty()) {
103 m_docPath = json.value(QStringLiteral("DocPath")).toString();
104 }
105
106 m_protClass = json.value(QStringLiteral("Class")).toString().toLower();
107 if (!m_protClass.startsWith(QLatin1Char(':'))) {
108 m_protClass.prepend(QLatin1Char(':'));
109 }
110
111 // ExtraNames is a translated value, use the KCoreAddons helper to read it
112 const QStringList extraNames = KJsonUtils::readTranslatedValue(json, QStringLiteral("ExtraNames")).toVariant().toStringList();
113 const QStringList extraTypes = json.value(QStringLiteral("ExtraTypes")).toVariant().toStringList();
114 if (extraNames.size() == extraTypes.size()) {
115 auto func = [](const QString &name, const QString &type) {
116 const int metaType = QMetaType::fromName(type.toLatin1().constData()).id();
117 // currently QMetaType::Type and ExtraField::Type use the same subset of values, so we can just cast.
118 return KProtocolInfo::ExtraField(name, static_cast<KProtocolInfo::ExtraField::Type>(metaType));
119 };
120
121 std::transform(extraNames.cbegin(), extraNames.cend(), extraTypes.cbegin(), std::back_inserter(m_extraFields), func);
122 } else {
123 qCWarning(KIO_CORE) << "Malformed JSON protocol file for protocol:" << name
124 << ", number of the ExtraNames fields should match the number of ExtraTypes fields";
125 }
126
127 // fallback based on class
128 m_showPreviews = json.value(QStringLiteral("ShowPreviews")).toBool(m_protClass == QLatin1String(":local"));
129
130 m_capabilities = json.value(QStringLiteral("Capabilities")).toVariant().toStringList();
131
132 m_proxyProtocol = json.value(QStringLiteral("ProxiedBy")).toString();
133}
134
135//
136// Static functions:
137//
138
140{
141 return KProtocolInfoFactory::self()->protocols();
142}
143
145{
146 // We call the findProtocol directly (not via KProtocolManager) to bypass any proxy settings.
147 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
148 if (!prot) {
149 return false;
150 }
151
152 return !prot->m_isSourceProtocol;
153}
154
156{
157 // We call the findProtocol directly (not via KProtocolManager) to bypass any proxy settings.
158 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
159 if (!prot) {
160 if (auto service = KApplicationTrader::preferredService(QLatin1String("x-scheme-handler/") + _protocol)) {
161 return service->icon();
162 } else {
163 return QString();
164 }
165 }
166
167 return prot->m_icon;
168}
169
171{
172 // We call the findProtocol directly (not via KProtocolManager) to bypass any proxy settings.
173 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
174 if (!prot) {
175 return QString();
176 }
177
178 return QStringLiteral("kio_%1rc").arg(prot->m_config);
179}
180
182{
183 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
184 if (!prot) {
185 return 1;
186 }
187
188 return prot->m_maxWorkers;
189}
190
192{
193 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
194 if (!prot) {
195 return 0;
196 }
197
198 return prot->m_maxWorkersPerHost;
199}
200
202{
203 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
204 if (!prot) {
205 return true;
206 }
207
208 return prot->m_determineMimetypeFromExtension;
209}
210
212{
213 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(protocol);
214 if (!prot) {
215 return QString();
216 }
217 return prot->m_exec;
218}
219
221{
222 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(url.scheme());
223 if (!prot) {
224 return ExtraFieldList();
225 }
226
227 return prot->m_extraFields;
228}
229
231{
232 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
233 if (!prot) {
234 return QString();
235 }
236
237 return prot->m_defaultMimetype;
238}
239
241{
242 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
243 if (!prot) {
244 return QString();
245 }
246
247 return prot->m_docPath;
248}
249
251{
252 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
253 if (!prot) {
254 return QString();
255 }
256
257 return prot->m_protClass;
258}
259
261{
262 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
263 const bool defaultSetting = prot ? prot->m_showPreviews : false;
264
265 KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("PreviewSettings"));
266 return group.readEntry(_protocol, defaultSetting);
267}
268
270{
271 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
272 if (!prot) {
273 return QStringList();
274 }
275
276 return prot->m_capabilities;
277}
278
280{
281 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(protocol);
282 if (!prot) {
283 return QStringList();
284 }
285
286 return prot->m_archiveMimeTypes;
287}
288
289#if KIOCORE_BUILD_DEPRECATED_SINCE(6, 4)
291{
292 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol);
293 if (!prot) {
294 return QString();
295 }
296
297 return prot->m_proxyProtocol;
298}
299#endif
300
302{
303 return isFilterProtocol(url.scheme());
304}
305
307{
308 return isHelperProtocol(url.scheme());
309}
310
312{
313 // We call the findProtocol directly (not via KProtocolManager) to bypass any proxy settings.
314 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(protocol);
315 if (prot) {
316 return prot->m_isHelperProtocol;
317 }
318 return false;
319}
320
322{
323 return isKnownProtocol(url.scheme());
324}
325
326bool KProtocolInfo::isKnownProtocol(const QString &protocol, bool updateCacheIfNotfound)
327{
328 // We call the findProtocol (const QString&) to bypass any proxy settings.
329 KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(protocol, updateCacheIfNotfound);
330 return prot;
331}
QString readEntry(const char *key, const char *aDefault=nullptr) const
static QString config(const QString &protocol)
Returns the name of the config file associated with the specified protocol.
static QString protocolClass(const QString &protocol)
Returns the protocol class for the specified protocol.
static bool determineMimetypeFromExtension(const QString &protocol)
Returns whether MIME types can be determined based on extension for this protocol.
static bool showFilePreview(const QString &protocol)
Returns whether file previews should be shown for the specified protocol.
static QString proxiedBy(const QString &protocol)
Returns the name of the protocol through which the request will be routed if proxy support is enabled...
static QStringList archiveMimetypes(const QString &protocol)
Returns the list of archive MIME types handled by the KIO worker implementing this protocol.
static QStringList capabilities(const QString &protocol)
Returns the list of capabilities provided by the KIO worker implementing this protocol.
static int maxWorkersPerHost(const QString &protocol)
Returns the limit on the number of KIO workers for this protocol per host.
@ T_STREAM
stream of data (e.g. single file)
@ T_NONE
no information about the type available
@ T_FILESYSTEM
structured directory
static QStringList protocols()
Returns list of all known protocols.
static QString docPath(const QString &protocol)
Returns the documentation path for the specified protocol.
static bool isKnownProtocol(const QUrl &url)
Returns whether a protocol is installed that is able to handle url.
static QString icon(const QString &protocol)
Returns the name of the icon, associated with the specified protocol.
static QString exec(const QString &protocol)
Returns the library / executable to open for the protocol protocol Example : "kio_ftp",...
static int maxWorkers(const QString &protocol)
Returns the soft limit on the number of KIO workers for this protocol.
static ExtraFieldList extraFields(const QUrl &url)
Definition of extra fields in the UDS entries, returned by a listDir operation.
static bool isHelperProtocol(const QUrl &url)
Returns whether the protocol can act as a helper protocol.
static bool isFilterProtocol(const QUrl &url)
Returns whether the protocol can act as a filter protocol.
static QString defaultMimetype(const QString &protocol)
Returns the default MIME type for the specified protocol, if one exists.
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
char * toString(const EngineQuery &query)
KSERVICE_EXPORT KService::Ptr preferredService(const QString &mimeType)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QString name(StandardAction id)
QJsonValue value(QLatin1StringView key) const const
bool toBool(bool defaultValue) const const
QString toString() const const
QVariant toVariant() const const
const_iterator cbegin() const const
const_iterator cend() const const
qsizetype size() const const
QMetaType fromName(QByteArrayView typeName)
int id() const const
QString arg(Args &&... args) const const
QString scheme() const const
QStringList toStringList() const const
Definition of an extra field in the UDS entries, returned by a listDir operation.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:11:14 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.