File indexing completed on 2024-05-12 17:10:17

0001 /*
0002     SPDX-FileCopyrightText: 2008 Sebastian Kügler <sebas@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "recentdocuments.h"
0008 
0009 #include <QApplication>
0010 #include <QDir>
0011 #include <QMimeData>
0012 
0013 #include <KIO/Job>
0014 #include <KIO/JobUiDelegate>
0015 #include <KIO/JobUiDelegateFactory>
0016 #include <KIO/OpenFileManagerWindowJob>
0017 #include <KIO/OpenUrlJob>
0018 #include <KLocalizedString>
0019 #include <KNotificationJobUiDelegate>
0020 #include <KShell>
0021 
0022 #include <KActivities/Stats/Query>
0023 #include <KActivities/Stats/ResultModel>
0024 #include <KActivities/Stats/Terms>
0025 
0026 using namespace KActivities::Stats;
0027 using namespace KActivities::Stats::Terms;
0028 
0029 K_PLUGIN_CLASS_WITH_JSON(RecentDocuments, "plasma-runner-recentdocuments.json")
0030 
0031 RecentDocuments::RecentDocuments(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
0032     : Plasma::AbstractRunner(parent, metaData, args)
0033 {
0034     setObjectName(QStringLiteral("Recent Documents"));
0035 
0036     addSyntax(Plasma::RunnerSyntax(QStringLiteral(":q:"), i18n("Looks for documents recently used with names matching :q:.")));
0037 
0038     m_actions = {new QAction(QIcon::fromTheme(QStringLiteral("document-open-folder")), i18n("Open Containing Folder"), this)};
0039     setMinLetterCount(3);
0040 }
0041 
0042 RecentDocuments::~RecentDocuments()
0043 {
0044 }
0045 
0046 void RecentDocuments::match(Plasma::RunnerContext &context)
0047 {
0048     if (!context.isValid()) {
0049         return;
0050     }
0051 
0052     // clang-format off
0053     const QString term = context.query();
0054     auto query = UsedResources
0055             | Activity::current()
0056             | Order::RecentlyUsedFirst
0057             | Agent::any()
0058             // we search only on file name, as KActivity does not support better options
0059             | Url("/*/*" + term + "*")
0060             | Limit(20);
0061     // clang-format on
0062 
0063     const auto result = new ResultModel(query);
0064 
0065     float relevance = 0.75;
0066     Plasma::QueryMatch::Type type = Plasma::QueryMatch::CompletionMatch;
0067     for (int i = 0; i < result->rowCount(); ++i) {
0068         const auto index = result->index(i, 0);
0069 
0070         const auto url = QUrl::fromUserInput(result->data(index, ResultModel::ResourceRole).toString(),
0071                                              QString(),
0072                                              // We can assume local file thanks to the request Url
0073                                              QUrl::AssumeLocalFile);
0074         const auto name = result->data(index, ResultModel::TitleRole).toString();
0075 
0076         Plasma::QueryMatch match(this);
0077 
0078         match.setRelevance(relevance);
0079         match.setType(type);
0080         if (term.size() >= 5
0081             && (url.fileName().compare(term, Qt::CaseInsensitive) == 0 || QFileInfo(url.fileName()).baseName().compare(term, Qt::CaseInsensitive) == 0)) {
0082             match.setRelevance(relevance + 0.1);
0083             match.setType(Plasma::QueryMatch::ExactMatch);
0084         } else if (url.fileName().startsWith(term, Qt::CaseInsensitive)) {
0085             match.setRelevance(relevance + 0.1);
0086             match.setType(Plasma::QueryMatch::PossibleMatch);
0087         } else if (!url.fileName().contains(term, Qt::CaseInsensitive)) {
0088             continue;
0089         }
0090 
0091         match.setIconName(KIO::iconNameForUrl(url));
0092         match.setData(QVariant(url));
0093         match.setUrls({url});
0094         match.setId(url.toString());
0095         if (url.isLocalFile()) {
0096             match.setActions(m_actions);
0097         }
0098         match.setText(name);
0099         QString destUrlString = KShell::tildeCollapse(url.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).path());
0100         match.setSubtext(destUrlString);
0101 
0102         relevance -= 0.05;
0103 
0104         context.addMatch(match);
0105     }
0106 }
0107 
0108 void RecentDocuments::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match)
0109 {
0110     Q_UNUSED(context)
0111 
0112     const QUrl url = match.data().toUrl();
0113 
0114     if (match.selectedAction()) {
0115         KIO::highlightInFileManager({url});
0116         return;
0117     }
0118 
0119     auto *job = new KIO::OpenUrlJob(url);
0120     job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, QApplication::activeWindow()));
0121     job->setShowOpenOrExecuteDialog(true);
0122     job->start();
0123 }
0124 
0125 #include "recentdocuments.moc"