diff --git a/autotests/kprotocolinfotest.cpp b/autotests/kprotocolinfotest.cpp index 12106d1f..237b6528 100644 --- a/autotests/kprotocolinfotest.cpp +++ b/autotests/kprotocolinfotest.cpp @@ -1,181 +1,185 @@ /* * Copyright (C) 2002 David Faure * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation; * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include // Tests both KProtocolInfo and KProtocolManager class KProtocolInfoTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void testBasic(); void testExtraFields(); void testShowFilePreview(); void testSlaveProtocol(); void testProxySettings_data(); void testProxySettings(); void testCapabilities(); void testProtocolForArchiveMimetype(); void testHelperProtocols(); }; void KProtocolInfoTest::initTestCase() { QString configFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kioslaverc"; QFile::remove(configFile); } void KProtocolInfoTest::testBasic() { QVERIFY(KProtocolInfo::isKnownProtocol(QUrl(QStringLiteral("http:/")))); QVERIFY(KProtocolInfo::isKnownProtocol(QUrl(QStringLiteral("file:/")))); QVERIFY(KProtocolInfo::exec(QStringLiteral("file")).contains(QStringLiteral("kf5/kio/file"))); QCOMPARE(KProtocolInfo::protocolClass(QStringLiteral("file")), QStringLiteral(":local")); QCOMPARE(KProtocolInfo::protocolClass(QStringLiteral("http")), QStringLiteral(":internet")); + QCOMPARE(KProtocolInfo::defaultMimetype(QStringLiteral("ftp")), QString()); + QCOMPARE(KProtocolInfo::defaultMimetype(QStringLiteral("rtsp")), QString("audio/x-pn-realaudio")); + QCOMPARE(KProtocolInfo::defaultMimetype(QStringLiteral("data")), QString("application/octet-stream")); + QVERIFY(KProtocolManager::supportsListing(QUrl(QStringLiteral("ftp://10.1.1.10")))); const QUrl url = QUrl::fromLocalFile(QStringLiteral("/tmp")); QCOMPARE(KProtocolManager::inputType(url), KProtocolInfo::T_NONE); QCOMPARE(KProtocolManager::outputType(url), KProtocolInfo::T_FILESYSTEM); QVERIFY(KProtocolManager::supportsReading(url)); } void KProtocolInfoTest::testExtraFields() { KProtocolInfo::ExtraFieldList extraFields = KProtocolInfo::extraFields(QUrl(QStringLiteral("trash:/"))); KProtocolInfo::ExtraFieldList::Iterator extraFieldsIt = extraFields.begin(); for (; extraFieldsIt != extraFields.end(); ++extraFieldsIt) { qDebug() << (*extraFieldsIt).name << " " << (*extraFieldsIt).type; } // TODO } void KProtocolInfoTest::testShowFilePreview() { QVERIFY(KProtocolInfo::showFilePreview(QStringLiteral("file"))); QVERIFY(!KProtocolInfo::showFilePreview(QStringLiteral("audiocd"))); } void KProtocolInfoTest::testSlaveProtocol() { QString proxy; QString protocol = KProtocolManager::slaveProtocol(QUrl(QStringLiteral("http://bugs.kde.org")), proxy); QCOMPARE(protocol, QStringLiteral("http")); QVERIFY(!KProtocolManager::useProxy()); // Just to test it doesn't deadlock KProtocolManager::reparseConfiguration(); protocol = KProtocolManager::slaveProtocol(QUrl(QStringLiteral("http://bugs.kde.org")), proxy); QCOMPARE(protocol, QStringLiteral("http")); } void KProtocolInfoTest::testProxySettings_data() { QTest::addColumn("proxyType"); // Just to test it doesn't deadlock (bug 346214) QTest::newRow("manual") << static_cast(KProtocolManager::ManualProxy); QTest::newRow("wpad") << static_cast(KProtocolManager::WPADProxy); // Same for bug 350890 QTest::newRow("envvar") << static_cast(KProtocolManager::EnvVarProxy); } void KProtocolInfoTest::testProxySettings() { QFETCH(int, proxyType); KConfig config(QStringLiteral("kioslaverc"), KConfig::NoGlobals); KConfigGroup cfg(&config, "Proxy Settings"); cfg.writeEntry("ProxyType", proxyType); cfg.sync(); KProtocolManager::reparseConfiguration(); QString proxy; QString protocol = KProtocolManager::slaveProtocol(QUrl(QStringLiteral("http://bugs.kde.org")), proxy); QCOMPARE(protocol, QStringLiteral("http")); QVERIFY(KProtocolManager::useProxy()); // restore cfg.writeEntry("ProxyType", static_cast(KProtocolManager::NoProxy)); cfg.sync(); KProtocolManager::reparseConfiguration(); } void KProtocolInfoTest::testCapabilities() { QStringList capabilities = KProtocolInfo::capabilities(QStringLiteral("imap")); qDebug() << "kio_imap capabilities: " << capabilities; //QVERIFY(capabilities.contains("ACL")); } void KProtocolInfoTest::testProtocolForArchiveMimetype() { if (!QFile::exists(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("kservices5/") + "zip.protocol"))) { QSKIP("kdebase not installed"); } else { const QString zip = KProtocolManager::protocolForArchiveMimetype(QStringLiteral("application/zip")); QVERIFY(zip == QLatin1String("zip") || zip == QLatin1String("krarc")); } } void KProtocolInfoTest::testHelperProtocols() { QVERIFY(!KProtocolInfo::isHelperProtocol(QStringLiteral("http"))); QVERIFY(!KProtocolInfo::isHelperProtocol(QStringLiteral("ftp"))); QVERIFY(!KProtocolInfo::isHelperProtocol(QStringLiteral("file"))); QVERIFY(!KProtocolInfo::isHelperProtocol(QStringLiteral("unknown"))); // Comes from ktelnetservice.desktop:MimeType=x-scheme-handler/telnet;x-scheme-handler/rlogin;x-scheme-handler/ssh; // TODO: this logic has moved to KRun. Should it be public API, so we can unittest it? //QVERIFY(KProtocolInfo::isHelperProtocol("telnet")); // To test that compat still works if (KProtocolInfo::isKnownProtocol(QStringLiteral("tel"))) { QVERIFY(KProtocolInfo::isHelperProtocol(QStringLiteral("tel"))); } // TODO: this logic has moved to KRun. Should it be public API, so we can unittest it? #if 0 QVERIFY(KProtocolInfo::isKnownProtocol("mailto")); QVERIFY(KProtocolInfo::isHelperProtocol("mailto")); QVERIFY(KProtocolInfo::isHelperProtocol(QUrl("mailto:faure@kde.org"))); // "mailto" is associated with kmail2 when present, and with kmailservice otherwise. KService::Ptr kmail2 = KService::serviceByStorageId("KMail2.desktop"); if (kmail2) { //qDebug() << kmail2->entryPath(); QVERIFY2(KProtocolInfo::exec("mailto").contains(QLatin1String("kmail -caption \"%c\"")), // comes from KMail2.desktop qPrintable(KProtocolInfo::exec("mailto"))); } else { QCOMPARE(KProtocolInfo::exec("mailto"), QLatin1String("kmailservice %u")); } #endif } QTEST_MAIN(KProtocolInfoTest) #include "kprotocolinfotest.moc" diff --git a/src/core/kprotocolinfo.cpp b/src/core/kprotocolinfo.cpp index e2ae03e5..229d7f40 100644 --- a/src/core/kprotocolinfo.cpp +++ b/src/core/kprotocolinfo.cpp @@ -1,418 +1,428 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Torben Weis Copyright (C) 2003 Waldo Bastian Copyright 2012 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kprotocolinfo.h" #include "kprotocolinfo_p.h" #include "kprotocolinfofactory_p.h" #include #include #include #include #include // // Internal functions: // KProtocolInfoPrivate::KProtocolInfoPrivate(const QString &path) { KConfig sconfig(path, KConfig::SimpleConfig); KConfigGroup config(&sconfig, "Protocol"); m_name = config.readEntry("protocol"); m_exec = config.readPathEntry("exec", QString()); m_isSourceProtocol = config.readEntry("source", true); m_isHelperProtocol = config.readEntry("helper", false); m_supportsReading = config.readEntry("reading", false); m_supportsWriting = config.readEntry("writing", false); m_supportsMakeDir = config.readEntry("makedir", false); m_supportsDeleting = config.readEntry("deleting", false); m_supportsLinking = config.readEntry("linking", false); m_supportsMoving = config.readEntry("moving", false); m_supportsOpening = config.readEntry("opening", false); m_canCopyFromFile = config.readEntry("copyFromFile", false); m_canCopyToFile = config.readEntry("copyToFile", false); m_canRenameFromFile = config.readEntry("renameFromFile", false); m_canRenameToFile = config.readEntry("renameToFile", false); m_canDeleteRecursive = config.readEntry("deleteRecursive", false); const QString fnu = config.readEntry("fileNameUsedForCopying", "FromURL"); m_fileNameUsedForCopying = KProtocolInfo::FromUrl; if (fnu == QLatin1String("Name")) { m_fileNameUsedForCopying = KProtocolInfo::Name; } else if (fnu == QLatin1String("DisplayName")) { m_fileNameUsedForCopying = KProtocolInfo::DisplayName; } m_listing = config.readEntry("listing", QStringList()); // Many .protocol files say "Listing=false" when they really mean "Listing=" (i.e. unsupported) if (m_listing.count() == 1 && m_listing.first() == QLatin1String("false")) { m_listing.clear(); } m_supportsListing = (m_listing.count() > 0); m_defaultMimetype = config.readEntry("defaultMimetype"); m_determineMimetypeFromExtension = config.readEntry("determineMimetypeFromExtension", true); m_archiveMimeTypes = config.readEntry("archiveMimetype", QStringList()); m_icon = config.readEntry("Icon"); m_config = config.readEntry("config", m_name); m_maxSlaves = config.readEntry("maxInstances", 1); m_maxSlavesPerHost = config.readEntry("maxInstancesPerHost", 0); QString tmp = config.readEntry("input"); if (tmp == QLatin1String("filesystem")) { m_inputType = KProtocolInfo::T_FILESYSTEM; } else if (tmp == QLatin1String("stream")) { m_inputType = KProtocolInfo::T_STREAM; } else { m_inputType = KProtocolInfo::T_NONE; } tmp = config.readEntry("output"); if (tmp == QLatin1String("filesystem")) { m_outputType = KProtocolInfo::T_FILESYSTEM; } else if (tmp == QLatin1String("stream")) { m_outputType = KProtocolInfo::T_STREAM; } else { m_outputType = KProtocolInfo::T_NONE; } m_docPath = config.readPathEntry("X-DocPath", QString()); if (m_docPath.isEmpty()) { m_docPath = config.readPathEntry("DocPath", QString()); } m_protClass = config.readEntry("Class").toLower(); if (m_protClass[0] != QLatin1Char(':')) { m_protClass.prepend(QLatin1Char(':')); } const QStringList extraNames = config.readEntry("ExtraNames", QStringList()); const QStringList extraTypes = config.readEntry("ExtraTypes", QStringList()); QStringList::const_iterator it = extraNames.begin(); QStringList::const_iterator typeit = extraTypes.begin(); for (; it != extraNames.end() && typeit != extraTypes.end(); ++it, ++typeit) { QVariant::Type type = QVariant::nameToType((*typeit).toLatin1().constData()); // currently QVariant::Type and ExtraField::Type use the same subset of values, so we can just cast. m_extraFields.append(KProtocolInfo::ExtraField(*it, static_cast(type))); } m_showPreviews = config.readEntry("ShowPreviews", m_protClass == QLatin1String(":local")); m_capabilities = config.readEntry("Capabilities", QStringList()); m_slaveHandlesNotify = config.readEntry("slaveHandlesNotify", QStringList()); m_proxyProtocol = config.readEntry("ProxiedBy"); } KProtocolInfoPrivate::KProtocolInfoPrivate(const QString &name, const QString &exec, const QJsonObject &json) : m_name(name) , m_exec(exec) { // source has fallback true if not set m_isSourceProtocol = json.value(QStringLiteral("source")).toBool(true); // other bools are fine with default false by toBool m_isHelperProtocol = json.value(QStringLiteral("helper")).toBool(); m_supportsReading = json.value(QStringLiteral("reading")).toBool(); m_supportsWriting = json.value(QStringLiteral("writing")).toBool(); m_supportsMakeDir = json.value(QStringLiteral("makedir")).toBool(); m_supportsDeleting = json.value(QStringLiteral("deleting")).toBool(); m_supportsLinking = json.value(QStringLiteral("linking")).toBool(); m_supportsMoving = json.value(QStringLiteral("moving")).toBool(); m_supportsOpening = json.value(QStringLiteral("opening")).toBool(); m_canCopyFromFile = json.value(QStringLiteral("copyFromFile")).toBool(); m_canCopyToFile = json.value(QStringLiteral("copyToFile")).toBool(); m_canRenameFromFile = json.value(QStringLiteral("renameFromFile")).toBool(); m_canRenameToFile = json.value(QStringLiteral("renameToFile")).toBool(); m_canDeleteRecursive = json.value(QStringLiteral("deleteRecursive")).toBool(); // default is "FromURL" const QString fnu = json.value(QStringLiteral("fileNameUsedForCopying")).toString(); m_fileNameUsedForCopying = KProtocolInfo::FromUrl; if (fnu == QLatin1String("Name")) { m_fileNameUsedForCopying = KProtocolInfo::Name; } else if (fnu == QLatin1String("DisplayName")) { m_fileNameUsedForCopying = KProtocolInfo::DisplayName; } m_listing = json.value(QStringLiteral("listing")).toVariant().toStringList(); // Many .protocol files say "Listing=false" when they really mean "Listing=" (i.e. unsupported) if (m_listing.count() == 1 && m_listing.first() == QLatin1String("false")) { m_listing.clear(); } m_supportsListing = (m_listing.count() > 0); m_defaultMimetype = json.value(QStringLiteral("defaultMimetype")).toString(); // determineMimetypeFromExtension has fallback true if not set m_determineMimetypeFromExtension = json.value(QStringLiteral("determineMimetypeFromExtension")).toBool(true); m_archiveMimeTypes = json.value(QStringLiteral("archiveMimetype")).toVariant().toStringList(); m_icon = json.value(QStringLiteral("Icon")).toString(); // config has fallback to name if not set m_config = json.value(QStringLiteral("config")).toString(m_name); // max slaves has fallback to 1 if not set m_maxSlaves = json.value(QStringLiteral("maxInstances")).toInt(1); m_maxSlavesPerHost = json.value(QStringLiteral("maxInstancesPerHost")).toInt(); QString tmp = json.value(QStringLiteral("input")).toString(); if (tmp == QLatin1String("filesystem")) { m_inputType = KProtocolInfo::T_FILESYSTEM; } else if (tmp == QLatin1String("stream")) { m_inputType = KProtocolInfo::T_STREAM; } else { m_inputType = KProtocolInfo::T_NONE; } tmp = json.value(QStringLiteral("output")).toString(); if (tmp == QLatin1String("filesystem")) { m_outputType = KProtocolInfo::T_FILESYSTEM; } else if (tmp == QLatin1String("stream")) { m_outputType = KProtocolInfo::T_STREAM; } else { m_outputType = KProtocolInfo::T_NONE; } m_docPath = json.value(QStringLiteral("X-DocPath")).toString(); if (m_docPath.isEmpty()) { m_docPath = json.value(QStringLiteral("DocPath")).toString(); } m_protClass = json.value(QStringLiteral("Class")).toString().toLower(); if (m_protClass[0] != QLatin1Char(':')) { m_protClass.prepend(QLatin1Char(':')); } // ExtraNames is a translated value, use the KCoreAddons helper to read it const QStringList extraNames = KPluginMetaData::readTranslatedValue(json, QStringLiteral("ExtraNames")).toVariant().toStringList(); const QStringList extraTypes = json.value(QStringLiteral("ExtraTypes")).toVariant().toStringList(); QStringList::const_iterator it = extraNames.begin(); QStringList::const_iterator typeit = extraTypes.begin(); for (; it != extraNames.end() && typeit != extraTypes.end(); ++it, ++typeit) { QVariant::Type type = QVariant::nameToType((*typeit).toLatin1().constData()); // currently QVariant::Type and ExtraField::Type use the same subset of values, so we can just cast. m_extraFields.append(KProtocolInfo::ExtraField(*it, static_cast(type))); } // fallback based on class m_showPreviews = json.value(QStringLiteral("ShowPreviews")).toBool(m_protClass == QLatin1String(":local")); m_capabilities = json.value(QStringLiteral("Capabilities")).toVariant().toStringList(); m_slaveHandlesNotify = json.value(QStringLiteral("slaveHandlesNotify")).toVariant().toStringList(); m_proxyProtocol = json.value(QStringLiteral("ProxiedBy")).toString(); } // // Static functions: // QStringList KProtocolInfo::protocols() { return KProtocolInfoFactory::self()->protocols(); } bool KProtocolInfo::isFilterProtocol(const QString &_protocol) { // We call the findProtocol directly (not via KProtocolManager) to bypass any proxy settings. KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return false; } return !prot->m_isSourceProtocol; } QString KProtocolInfo::icon(const QString &_protocol) { // We call the findProtocol directly (not via KProtocolManager) to bypass any proxy settings. KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return QString(); } return prot->m_icon; } QString KProtocolInfo::config(const QString &_protocol) { // We call the findProtocol directly (not via KProtocolManager) to bypass any proxy settings. KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return QString(); } return QStringLiteral("kio_%1rc").arg(prot->m_config); } int KProtocolInfo::maxSlaves(const QString &_protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return 1; } return prot->m_maxSlaves; } int KProtocolInfo::maxSlavesPerHost(const QString &_protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return 0; } return prot->m_maxSlavesPerHost; } bool KProtocolInfo::determineMimetypeFromExtension(const QString &_protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return true; } return prot->m_determineMimetypeFromExtension; } QString KProtocolInfo::exec(const QString &protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(protocol); if (!prot) { return QString(); } return prot->m_exec; } KProtocolInfo::ExtraFieldList KProtocolInfo::extraFields(const QUrl &url) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(url.scheme()); if (!prot) { return ExtraFieldList(); } return prot->m_extraFields; } +QString KProtocolInfo::defaultMimetype(const QString &_protocol) +{ + KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); + if (!prot) { + return QString(); + } + + return prot->m_defaultMimetype; +} + QString KProtocolInfo::docPath(const QString &_protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return QString(); } return prot->m_docPath; } QString KProtocolInfo::protocolClass(const QString &_protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return QString(); } return prot->m_protClass; } bool KProtocolInfo::showFilePreview(const QString &_protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); const bool defaultSetting = prot ? prot->m_showPreviews : false; KConfigGroup group(KSharedConfig::openConfig(), "PreviewSettings"); return group.readEntry(_protocol, defaultSetting); } QStringList KProtocolInfo::capabilities(const QString &_protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return QStringList(); } return prot->m_capabilities; } QStringList KProtocolInfo::archiveMimetypes(const QString &protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(protocol); if (!prot) { return QStringList(); } return prot->m_archiveMimeTypes; } QStringList KProtocolInfo::slaveHandlesNotify(const QString &_protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return QStringList(); } return prot->m_slaveHandlesNotify; } QString KProtocolInfo::proxiedBy(const QString &_protocol) { KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(_protocol); if (!prot) { return QString(); } return prot->m_proxyProtocol; } bool KProtocolInfo::isFilterProtocol(const QUrl &url) { return isFilterProtocol(url.scheme()); } bool KProtocolInfo::isHelperProtocol(const QUrl &url) { return isHelperProtocol(url.scheme()); } bool KProtocolInfo::isHelperProtocol(const QString &protocol) { // We call the findProtocol directly (not via KProtocolManager) to bypass any proxy settings. KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(protocol); if (prot) { return prot->m_isHelperProtocol; } return false; } bool KProtocolInfo::isKnownProtocol(const QUrl &url) { return isKnownProtocol(url.scheme()); } bool KProtocolInfo::isKnownProtocol(const QString &protocol) { // We call the findProtocol (const QString&) to bypass any proxy settings. KProtocolInfoPrivate *prot = KProtocolInfoFactory::self()->findProtocol(protocol); return prot; } diff --git a/src/core/kprotocolinfo.h b/src/core/kprotocolinfo.h index 52cfe5cb..fc51a6f7 100644 --- a/src/core/kprotocolinfo.h +++ b/src/core/kprotocolinfo.h @@ -1,333 +1,344 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Torben Weis Copyright (C) 2000-2001 Waldo Bastian Copyright 2012 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KPROTOCOLINFO_H #define KPROTOCOLINFO_H #include "kiocore_export.h" #include #include /** * \class KProtocolInfo kprotocolinfo.h * * Information about I/O (Internet, etc.) protocols supported by KDE. * KProtocolInfo is useful if you want to know which protocols * KDE supports. In addition you can find out lots of information * about a certain protocol. All of the functionality is provided by the static * methods. * The implementation scans the *.protocol files of all installed kioslaves to get * this information and stores the result into an internal cache. * * *.protocol files are installed in the "services" resource. * * The KProtocolInfo methods are reentrant (i.e. can be called from multiple threads simultaneously). */ class KIOCORE_EXPORT KProtocolInfo { public: // // Static functions: // /** * Returns list of all known protocols. * @return a list of all known protocols */ static QStringList protocols(); /** * Returns whether a protocol is installed that is able to handle @p url. * * @param url the url to check * @return true if the protocol is known * @see name() */ static bool isKnownProtocol(const QUrl &url); /** * Same as above except you can supply just the protocol instead of * the whole URL. */ static bool isKnownProtocol(const QString &protocol); /** * Returns the library / executable to open for the protocol @p protocol * Example : "kio_ftp", meaning either the executable "kio_ftp" or * the library "kio_ftp.la" (recommended), whichever is available. * * This corresponds to the "exec=" field in the protocol description file. * @param protocol the protocol to check * @return the executable of library to open, or QString() for * unsupported protocols * @see KUrl::protocol() */ static QString exec(const QString &protocol); /** * Describes the type of a protocol. * For instance ftp:// appears as a filesystem with folders and files, * while bzip2:// appears as a single file (a stream of data), * and telnet:// doesn't output anything. * @see outputType */ enum Type { T_STREAM, ///< stream of data (e.g. single file) T_FILESYSTEM, ///< structured directory T_NONE, ///< no information about the type available T_ERROR ///< used to signal an error }; /** * Definition of an extra field in the UDS entries, returned by a listDir operation. * * The name is the name of the column, translated. * * The type name comes from QVariant::typeName() * Currently supported types: "QString", "QDateTime" (ISO-8601 format) */ struct ExtraField { enum Type { String = QVariant::String, DateTime = QVariant::DateTime, Invalid = QVariant::Invalid }; ExtraField() : type(Invalid) {} ExtraField(const QString &_name, Type _type) : name(_name), type(_type) { } QString name; Type type; }; typedef QList ExtraFieldList; /** * Definition of extra fields in the UDS entries, returned by a listDir operation. * * This corresponds to the "ExtraNames=" and "ExtraTypes=" fields in the protocol description file. * Those two lists should be separated with ',' in the protocol description file. * See ExtraField for details about names and types */ static ExtraFieldList extraFields(const QUrl &url); /** * Returns whether the protocol can act as a helper protocol. * A helper protocol invokes an external application and does not return * a file or stream. * * This corresponds to the "helper=" field in the protocol description file. * Valid values for this field are "true" or "false" (default). * * @param url the url to check * @return true if the protocol is a helper protocol (e.g. vnc), false * if not (e.g. http) */ static bool isHelperProtocol(const QUrl &url); /** * Same as above except you can supply just the protocol instead of * the whole URL. */ static bool isHelperProtocol(const QString &protocol); /** * Returns whether the protocol can act as a filter protocol. * * A filter protocol can operate on data that is passed to it * but does not retrieve/store data itself, like gzip. * A filter protocol is the opposite of a source protocol. * * The "source=" field in the protocol description file determines * whether a protocol is a source protocol or a filter protocol. * Valid values for this field are "true" (default) for source protocol or * "false" for filter protocol. * * @param url the url to check * @return true if the protocol is a filter (e.g. gzip), false if the * protocol is a helper or source */ static bool isFilterProtocol(const QUrl &url); /** * Same as above except you can supply just the protocol instead of * the whole URL. */ static bool isFilterProtocol(const QString &protocol); /** * Returns the name of the icon, associated with the specified protocol. * * This corresponds to the "Icon=" field in the protocol description file. * * @param protocol the protocol to check * @return the icon of the protocol, or an empty string if unknown */ static QString icon(const QString &protocol); /** * Returns the name of the config file associated with the * specified protocol. This is useful if two similar protocols * need to share a single config file, e.g. http and https. * * This corresponds to the "config=" field in the protocol description file. * The default is the protocol name, see name() * * @param protocol the protocol to check * @return the config file, or an empty string if unknown */ static QString config(const QString &protocol); /** * Returns the soft limit on the number of slaves for this protocol. * This limits the number of slaves used for a single operation, note * that multiple operations may result in a number of instances that * exceeds this soft limit. * * This corresponds to the "maxInstances=" field in the protocol description file. * The default is 1. * * @param protocol the protocol to check * @return the maximum number of slaves, or 1 if unknown */ static int maxSlaves(const QString &protocol); /** * Returns the limit on the number of slaves for this protocol per host. * * This corresponds to the "maxInstancesPerHost=" field in the protocol description file. * The default is 0 which means there is no per host limit. * * @param protocol the protocol to check * @return the maximum number of slaves, or 1 if unknown * * @since 4.4 */ static int maxSlavesPerHost(const QString &protocol); /** * Returns whether mimetypes can be determined based on extension for this * protocol. For some protocols, e.g. http, the filename extension in the URL * can not be trusted to truly reflect the file type. * * This corresponds to the "determineMimetypeFromExtension=" field in the protocol description file. * Valid values for this field are "true" (default) or "false". * * @param protocol the protocol to check * @return true if the mime types can be determined by extension */ static bool determineMimetypeFromExtension(const QString &protocol); + /** + * Returns the default mimetype for the specified protocol, if one exists. + * + * This corresponds to the "defaultMimetype=" field in the protocol description file. + * + * @param protocol the protocol to check + * @return the default mimetype of the protocol, or an empty string if none set or protocol unknown + * @since 5.60 + */ + static QString defaultMimetype(const QString &protocol); + /** * Returns the documentation path for the specified protocol. * * This corresponds to the "X-DocPath=" or "DocPath=" field in the protocol description file. * * @param protocol the protocol to check * @return the docpath of the protocol, or an empty string if unknown */ static QString docPath(const QString &protocol); /** * Returns the protocol class for the specified protocol. * * This corresponds to the "Class=" field in the protocol description file. * * The following classes are defined: * @li ":internet" for common internet protocols * @li ":local" for protocols that access local resources * * Protocol classes always start with a ':' so that they can not be confused with * the protocols themselves. * * @param protocol the protocol to check * @return the class of the protocol, or an empty string if unknown */ static QString protocolClass(const QString &protocol); /** * Returns whether file previews should be shown for the specified protocol. * * This corresponds to the "ShowPreviews=" field in the protocol description file. * * By default previews are shown if protocolClass is :local. * * @param protocol the protocol to check * @return true if previews should be shown by default, false otherwise */ static bool showFilePreview(const QString &protocol); /** * Returns the list of capabilities provided by the kioslave implementing * this protocol. * * This corresponds to the "Capabilities=" field in the protocol description file. * * The capability names are not defined globally, they are up to each * slave implementation. For example when adding support for a new * special command for mounting, one would add the string "Mount" to the * capabilities list, and applications could check for that string * before sending a special() command that would otherwise do nothing * on older kioslave implementations. * * @param protocol the protocol to check * @return the list of capabilities. */ static QStringList capabilities(const QString &protocol); /** * Returns the list of archive mimetypes handled by the kioslave implementing * this protocol. * * This corresponds to the "archiveMimetype=" field in the protocol description file. * * @param protocol the protocol to check * @return the list of archive mimetypes (e.g. application/x-zip) handled. * @since 5.23 */ static QStringList archiveMimetypes(const QString &protocol); /** * Returns the list of notification types the kioslave implementing this * protocol will produce on its own, making it unnecessary for job * implementations to do so. An example would be returning "Rename" * if the kioslave's rename() method takes care of calling * KDirNotify::emitFileRenameWithLocalPath on its own. * * This corresponds to "slaveHandlesNotify=" in the protocol description file. * * @since 5.20 */ static QStringList slaveHandlesNotify(const QString &protocol); /** * Returns the name of the protocol through which the request * will be routed if proxy support is enabled. * * A good example of this is the ftp protocol for which proxy * support is commonly handled by the http protocol. * * This corresponds to the "ProxiedBy=" in the protocol description file. */ static QString proxiedBy(const QString &protocol); typedef enum { Name, FromUrl, DisplayName } FileNameUsedForCopying; private: Q_DISABLE_COPY(KProtocolInfo) }; #endif