diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,11 @@ TYPE OPTIONAL PURPOSE "Needed by activity related plasmoids." ) +find_package(KF5ActivitiesStats ${KF5_MIN_VERSION}) +set_package_properties(KF5ActivitiesStats PROPERTIES DESCRIPTION " querying of activity history" + TYPE OPTIONAL + PURPOSE "Needed by runner recentlyused." + ) find_package(ZLIB) set_package_properties(ZLIB PROPERTIES DESCRIPTION "Support for gzip compressed files and data streams" diff --git a/runners/CMakeLists.txt b/runners/CMakeLists.txt --- a/runners/CMakeLists.txt +++ b/runners/CMakeLists.txt @@ -8,6 +8,7 @@ add_subdirectory(places) add_subdirectory(services) add_subdirectory(recentdocuments) +add_subdirectory(recentlyused) add_subdirectory(shell) add_subdirectory(webshortcuts) add_subdirectory(windowedwidgets) diff --git a/runners/recentlyused/CMakeLists.txt b/runners/recentlyused/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/runners/recentlyused/CMakeLists.txt @@ -0,0 +1,20 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"plasma_runner_recentlyused\") + +set(krunner_recentlyused_SRCS + recentlyused.cpp +) + +add_library(krunner_recentlyused MODULE ${krunner_recentlyused_SRCS}) + +target_link_libraries(krunner_recentlyused + KF5::KIOCore + KF5::KIOWidgets + KF5::I18n + KF5::Activities + KF5::ActivitiesStats + KF5::Runner +) + +install(TARGETS krunner_recentlyused DESTINATION ${KDE_INSTALL_PLUGINDIR} ) + +install(FILES plasma-runner-recentlyused.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) diff --git a/runners/recentlyused/Messages.sh b/runners/recentlyused/Messages.sh new file mode 100755 --- /dev/null +++ b/runners/recentlyused/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_recentlyused.pot diff --git a/runners/recentlyused/plasma-runner-recentlyused.desktop b/runners/recentlyused/plasma-runner-recentlyused.desktop new file mode 100644 --- /dev/null +++ b/runners/recentlyused/plasma-runner-recentlyused.desktop @@ -0,0 +1,14 @@ +[Desktop Entry] +Name=Recently used documents +Icon=document-open-recent + +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +X-KDE-Library=krunner_recentlyused +X-KDE-PluginInfo-Author=Méven Car +X-KDE-PluginInfo-Email=meven.car@kdemail.net +X-KDE-PluginInfo-Name=recentlyused +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-Plasma-AdvertiseSingleRunnerQueryMode=true +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/runners/recentlyused/recentlyused.h b/runners/recentlyused/recentlyused.h new file mode 100644 --- /dev/null +++ b/runners/recentlyused/recentlyused.h @@ -0,0 +1,41 @@ +/* + * Copyright 2019 Méven Car + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program 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 General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef RECENTLYUSED_H +#define RECENTLYUSED_H + +#include + +class RecentlyUsed : public Plasma::AbstractRunner { + Q_OBJECT + + public: + RecentlyUsed( QObject *parent, const QVariantList& args ); + ~RecentlyUsed() override; + + void match(Plasma::RunnerContext &context) override; + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) override; + + private Q_SLOTS: + QList actionsForMatch(const Plasma::QueryMatch &match) override; + QMimeData * mimeDataForMatch(const Plasma::QueryMatch &match) override; +}; + + +#endif diff --git a/runners/recentlyused/recentlyused.cpp b/runners/recentlyused/recentlyused.cpp new file mode 100644 --- /dev/null +++ b/runners/recentlyused/recentlyused.cpp @@ -0,0 +1,147 @@ +/* + * Copyright 2019 Méven Car + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program 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 General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "recentlyused.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace KAStats = KActivities::Stats; + +using namespace KAStats; +using namespace KAStats::Terms; + +K_EXPORT_PLASMA_RUNNER(recentlyused, RecentlyUsed) + +static const QString s_openParentDirId = QStringLiteral("openParentDir"); + +RecentlyUsed::RecentlyUsed(QObject *parent, const QVariantList& args) + : Plasma::AbstractRunner(parent, args) +{ + Q_UNUSED(args); + setObjectName( QStringLiteral("Recently Used Documents" )); + + addSyntax(Plasma::RunnerSyntax(QStringLiteral(":q:"), i18n("Looks for documents recently used with names matching :q:."))); + + addAction(s_openParentDirId, QIcon::fromTheme(QStringLiteral("document-open-folder")), i18n("Open Containing Folder")); +} + +RecentlyUsed::~RecentlyUsed() +{ +} + +void RecentlyUsed::match(Plasma::RunnerContext &context) +{ + if (!context.isValid()) { + return; + } + + const QString term = context.query(); + + auto query = UsedResources + | Activity::current() + | Order::RecentlyUsedFirst + | Agent::any() + | Url("/*/" + term + "*") + | Limit(30); + + const auto result = new ResultModel(query); + + for (int i = 0; i < result->rowCount(); i++) { + const auto index = result->index(i, 0); + + const auto url = QUrl::fromUserInput(result->data(index, ResultModel::ResourceRole).toString()); + const auto name = result->data(index, ResultModel::TitleRole).toString(); + + Plasma::QueryMatch match(this); + + auto relevance = 0.5; + match.setType(Plasma::QueryMatch::PossibleMatch); + if (url.fileName() == term) { + relevance = 1.0; + match.setType(Plasma::QueryMatch::ExactMatch); + } else if(url.fileName().startsWith(term)) { + relevance = 0.9; + match.setType(Plasma::QueryMatch::PossibleMatch); + } + match.setIconName(KIO::iconNameForUrl(url)); + match.setRelevance(relevance); + match.setData(QVariant(url)); + match.setText(name); + + const QString homePath = QDir::homePath(); + QString destUrlString = url.adjusted(QUrl::RemoveFilename).path(); + if (destUrlString.startsWith(homePath)) { + destUrlString = QLatin1String("~") + destUrlString.mid(homePath.length()); + } + match.setSubtext(destUrlString); + + context.addMatch(match); + } +} + +void RecentlyUsed::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + Q_UNUSED(context) + + const QUrl url = match.data().toUrl(); + + if (match.selectedAction() == action(s_openParentDirId)) { + KIO::highlightInFileManager({url}); + return; + } + + new KRun(url, nullptr); +} + +QList RecentlyUsed::actionsForMatch(const Plasma::QueryMatch &match) +{ + Q_UNUSED(match) + + QList actions; + + const QUrl url = match.data().toUrl(); + + if (url.isLocalFile() && !QFileInfo(url.toLocalFile()).isDir()) { + actions << action(s_openParentDirId); + } + + return actions; +} + +QMimeData * RecentlyUsed::mimeDataForMatch(const Plasma::QueryMatch& match) +{ + QMimeData *result = new QMimeData(); + result->setUrls({match.data().toUrl()}); + return result; +} + +#include "recentlyused.moc"