File indexing completed on 2024-05-12 05:38:19

0001 /*
0002     SPDX-FileCopyrightText: 2007 Teemu Rytilahti <tpr@iki.fi>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "locationrunner.h"
0008 
0009 #include <QDir>
0010 #include <QIcon>
0011 #include <QMimeData>
0012 #include <QUrl>
0013 
0014 #include <KApplicationTrader>
0015 #include <KIO/DesktopExecParser>
0016 #include <KIO/Global>
0017 #include <KIO/OpenUrlJob>
0018 #include <KLocalizedString>
0019 #include <KNotificationJobUiDelegate>
0020 #include <KProtocolInfo>
0021 #include <KShell>
0022 #include <KUriFilter>
0023 #include <QDebug>
0024 
0025 K_PLUGIN_CLASS_WITH_JSON(LocationsRunner, "plasma-runner-locations.json")
0026 
0027 LocationsRunner::LocationsRunner(QObject *parent, const KPluginMetaData &metaData)
0028     : KRunner::AbstractRunner(parent, metaData)
0029 {
0030     addSyntax(QStringLiteral(":q:"), i18n("Finds local directories and files, network locations and Internet sites with paths matching :q:."));
0031 }
0032 
0033 void LocationsRunner::match(KRunner::RunnerContext &context)
0034 {
0035     QString term = context.query();
0036     // If we have a query with an executable and optionally arguments, BUG: 433053
0037     const QStringList split = KShell::splitArgs(term);
0038     if (!split.isEmpty()) {
0039         QFileInfo tmpInfo(KShell::tildeExpand(split.constFirst()));
0040         if (tmpInfo.isFile() && tmpInfo.isExecutable()) {
0041             return;
0042         }
0043     }
0044     // We want to expand ENV variables like $HOME to get the actual path, BUG: 358221
0045     KUriFilter::self()->filterUri(term, {QStringLiteral("kshorturifilter")});
0046     const QUrl url(term);
0047     // The uri filter takes care of the shell expansion
0048     const QFileInfo fileInfo = QFileInfo(url.toLocalFile());
0049 
0050     if (fileInfo.exists()) {
0051         KRunner::QueryMatch match(this);
0052         match.setText(i18n("Open %1", context.query()));
0053         match.setIconName(fileInfo.isFile() ? KIO::iconNameForUrl(url) : QStringLiteral("system-file-manager"));
0054 
0055         match.setRelevance(1);
0056         match.setData(url);
0057         match.setUrls({url});
0058         match.setCategoryRelevance(KRunner::QueryMatch::CategoryRelevance::Highest);
0059         context.addMatch(match);
0060     } else if (!url.isLocalFile() && !url.isEmpty() && !url.scheme().isEmpty()) {
0061         const QString protocol = url.scheme();
0062         KRunner::QueryMatch match(this);
0063         match.setCategoryRelevance(KRunner::QueryMatch::CategoryRelevance::Low);
0064         match.setData(url);
0065         match.setUrls({url});
0066 
0067         const bool isKnownProtocol = KProtocolInfo::isKnownProtocol(protocol, false);
0068         if (!isKnownProtocol || KProtocolInfo::isHelperProtocol(protocol)) {
0069             const KService::Ptr service = KApplicationTrader::preferredService(QLatin1String("x-scheme-handler/") + protocol);
0070             if (service) {
0071                 match.setIconName(service->icon());
0072                 match.setText(i18n("Launch with %1", service->name()));
0073             } else if (isKnownProtocol) {
0074                 Q_ASSERT(KProtocolInfo::isHelperProtocol(protocol));
0075                 match.setIconName(KProtocolInfo::icon(protocol));
0076                 match.setText(i18n("Launch with %1", KIO::DesktopExecParser::executableName(KProtocolInfo::exec(protocol))));
0077             } else {
0078                 return;
0079             }
0080         } else {
0081             match.setIconName(KProtocolInfo::icon(protocol));
0082             match.setText(i18n("Go to %1", url.toDisplayString(QUrl::PreferLocalFile)));
0083             // in case of https://phabricator.kde.org we add a slash at the end to make it comparable to results of other runners
0084             if (url.scheme() == QLatin1String("https") && url.toString().endsWith(url.host())) {
0085                 match.setId(url.toString() + QLatin1Char('/'));
0086             }
0087         }
0088 
0089         if (url.scheme() == QLatin1String("mailto")) {
0090             match.setText(i18n("Send email to %1", url.path()));
0091         }
0092         context.addMatch(match);
0093     }
0094 }
0095 
0096 void LocationsRunner::run(const KRunner::RunnerContext & /*context*/, const KRunner::QueryMatch &match)
0097 {
0098     auto *job = new KIO::OpenUrlJob(match.data().toUrl());
0099     job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoErrorHandlingEnabled));
0100     job->setRunExecutables(false);
0101     job->start();
0102 }
0103 
0104 #include "locationrunner.moc"