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"