KRunner

abstractrunner.h
1/*
2 SPDX-FileCopyrightText: 2006-2007 Aaron Seigo <aseigo@kde.org>
3 SPDX-FileCopyrightText: 2020-2023 Alexander Lohnau<alexander.lohnau@gmx.de>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#ifndef KRUNNER_ABSTRACTRUNNER_H
9#define KRUNNER_ABSTRACTRUNNER_H
10
11#include "krunner_export.h"
12
13#include <QObject>
14#include <QStringList>
15
16#include <KPluginFactory>
17#include <KPluginMetaData>
18
19#include <memory>
20
21#include "querymatch.h"
22#include "runnercontext.h"
23#include "runnersyntax.h"
24
25class KConfigGroup;
26class QMimeData;
28class QIcon;
29
30namespace KRunner
31{
32class AbstractRunnerPrivate;
33
34/**
35 * @class AbstractRunner abstractrunner.h <KRunner/AbstractRunner>
36 *
37 * @short An abstract base class for Plasma Runner plugins.
38 *
39 * Be aware that runners will be moved to their own thread after being instantiated.
40 * This means that except for AbstractRunner::run and the constructor, all methods will be non-blocking
41 * for the UI.
42 * Consider doing heavy resource initialization in the init method instead of the constructor.
43 */
44class KRUNNER_EXPORT AbstractRunner : public QObject
45{
47
48public:
49 ~AbstractRunner() override;
50
51 /**
52 * This is the main query method. It should trigger creation of
53 * QueryMatch instances through RunnerContext::addMatch and
54 * RunnerContext::addMatches.
55 *
56 * If the runner can run precisely the requested term (RunnerContext::query()),
57 * it should create an exact match by setting the type to RunnerContext::ExactMatch.
58 * The first runner that creates a QueryMatch will be the
59 * default runner. Other runner's matches will be suggested in the
60 * interface. Non-exact matches should be offered via RunnerContext::PossibleMatch.
61 *
62 * The match will be activated via run() if the user selects it.
63 *
64 * All matches need to be reported once this method returns. Asynchronous runners therefore need
65 * to make use of a local event loop to wait for all matches.
66 *
67 * It is recommended to use local status data in async runners. The simplest way is
68 * to have a separate class doing all the work like so:
69 *
70 * \code
71 * void MyFancyAsyncRunner::match(RunnerContext &context)
72 * {
73 * QEventLoop loop;
74 * MyAsyncWorker worker(context);
75 * connect(&worker, &MyAsyncWorker::finished, &loop, &MyAsyncWorker::quit);
76 * worker.work();
77 * loop.exec();
78 * }
79 * \endcode
80 *
81 * Here MyAsyncWorker creates all the matches and calls RunnerContext::addMatch
82 * in some internal slot. It emits the finished() signal once done which will
83 * quit the loop and make the match() method return.
84 *
85 * Execution of the correct action should be handled in the run method.
86 *
87 * @warning Returning from this method means to end execution of the runner.
88 *
89 * @sa run(), RunnerContext::addMatch, RunnerContext::addMatches, QueryMatch
90 */
91 virtual void match(KRunner::RunnerContext &context) = 0;
92
93 /**
94 * Called whenever an exact or possible match associated with this
95 * runner is triggered.
96 *
97 * @param context The context in which the match is triggered, i.e. for which
98 * the match was created.
99 * @param match The actual match to run/execute.
100 */
101 virtual void run(const KRunner::RunnerContext &context, const KRunner::QueryMatch &match);
102
103 /**
104 * @return the plugin metadata for this runner that was passed in the constructor
105 */
107
108 /**
109 * Returns the translated name from the runner's metadata
110 */
111 QString name() const;
112
113 /**
114 * @return an id from the runner's metadata'
115 */
116 QString id() const;
117
118 /**
119 * Reloads the runner's configuration. This is called when it's KCM in the PluginSelector is applied.
120 * This function may be used to set for example using setMatchRegex, setMinLetterCount or setTriggerWords.
121 * Also, syntaxes should be updated when this method is called.
122 * While reloading the config, matching is suspended.
123 */
124 virtual void reloadConfiguration();
125
126 /**
127 * @return the syntaxes the runner has registered that it accepts and understands
128 */
130
131 /**
132 * @return true if the runner is currently busy with non-interuptable work, signaling that
133 * the RunnerManager may not query it or read it's config properties
134 */
135 bool isMatchingSuspended() const;
136
137 /**
138 * This is the minimum letter count for the query. If the query is shorter than this value
139 * and KRunner is not in the singleRunnerMode, match method is not called.
140 * This can be set using the X-Plasma-Runner-Min-Letter-Count property or the setMinLetterCount method.
141 * The default value is 0.
142 *
143 * @see setMinLetterCount
144 * @see match
145 * @since 5.75
146 */
147 int minLetterCount() const;
148
149 /**
150 * Set the minLetterCount property
151 * @param count
152 * @since 5.75
153 */
154 void setMinLetterCount(int count);
155
156 /**
157 * If this regex is set with a non empty pattern it must match the query in order for match being called.
158 * Just like the minLetterCount property this check is ignored when the runner is in the singleRunnerMode.
159 * In case both the regex and the letter count is set the letter count is checked first.
160 * @return matchRegex property
161 * @see hasMatchRegex
162 * @since 5.75
163 */
165
166 /**
167 * Set the matchRegex property
168 * @param regex
169 * @since 5.75
170 */
171 void setMatchRegex(const QRegularExpression &regex);
172
173 /**
174 * Constructs internally a regex which requires the query to start with the trigger words.
175 * Multiple words are concatenated with or, for instance: "^word1|word2|word3".
176 * The trigger words are internally escaped.
177 * Also the minLetterCount is set to the shortest word in the list.
178 * @since 5.75
179 * @see matchRegex
180 */
181 void setTriggerWords(const QStringList &triggerWords);
182
183 /**
184 * If the runner has a valid regex and non empty regex
185 * @internal
186 * @since 5.75
187 */
188 bool hasMatchRegex() const;
189
191 /**
192 * This signal is emitted when matching is about to commence, giving runners
193 * an opportunity to prepare themselves, e.g. loading data sets or preparing
194 * IPC or network connections. Things that should be loaded once and remain
195 * extant for the lifespan of the AbstractRunner should be done in init().
196 * @see init()
197 */
198 void prepare();
199
200 /**
201 * This signal is emitted when a session of matches is complete, giving runners
202 * the opportunity to tear down anything set up as a result of the prepare()
203 * method.
204 */
205 void teardown();
206
207protected:
208 friend class RunnerManager;
209 friend class RunnerManagerPrivate;
210
211 /**
212 * Constructor for a KRunner plugin
213 *
214 * @note You should connect here to the prepare/teardown signals. However, avoid doing heavy initialization here
215 * in favor of doing it in AbstractRunner::init
216 *
217 * @param parent parent object for this runner
218 * @param pluginMetaData metadata that was embedded in the runner
219 * @param args for compatibility with KPluginFactory, since 6.0 this can be omitted
220 * @since 5.72
221 */
222 explicit AbstractRunner(QObject *parent, const KPluginMetaData &pluginMetaData);
223
224 /**
225 * Sets whether or not the runner is available for match requests. Useful to
226 * prevent queries when the runner is in a busy state.
227 * @note Do not permanently suspend the runner. This is only intended as a temporary measure to
228 * avoid useless queries being launched or async fetching of config/data being interfered with.
229 */
230 void suspendMatching(bool suspend);
231
232 /**
233 * Provides access to the runner's configuration object.
234 * This config is saved in the "krunnerrc" file in the [Runners][<pluginId>] config group
235 * Settings should be written in a KDE config module. See https://develop.kde.org/docs/plasma/krunner/#runner-configuration
236 */
237 KConfigGroup config() const;
238
239 /**
240 * Adds a registered syntax that this runner understands. This is used to
241 * display to the user what this runner can understand and how it can be
242 * used.
243 *
244 * @param syntax the syntax to register
245 */
246 void addSyntax(const RunnerSyntax &syntax);
247
248 /**
249 * Utility overload for creating a syntax based on the given parameters
250 * @see RunnerSyntax
251 * @since 5.106
252 */
253 inline void addSyntax(const QString &exampleQuery, const QString &description)
254 {
255 addSyntax(QStringList(exampleQuery), description);
256 }
257
258 /// @copydoc addSyntax(const QString &exampleQuery, const QString &description)
259 inline void addSyntax(const QStringList &exampleQueries, const QString &description)
260 {
261 addSyntax(KRunner::RunnerSyntax(exampleQueries, description));
262 }
263
264 /**
265 * Sets the list of syntaxes; passing in an empty list effectively clears
266 * the syntaxes.
267 *
268 * @param the syntaxes to register for this runner
269 */
270 void setSyntaxes(const QList<RunnerSyntax> &syntaxes);
271
272 /**
273 * Reimplement this to run any initialization routines on first load.
274 * Because it is executed in the runner's thread, it will not block the UI and is thus preferred.
275 * By default, it calls reloadConfiguration();
276 *
277 * Until the runner is initialized, it will not be queried by the RunnerManager.
278 */
279 virtual void init();
280
281 /**
282 * Reimplement this if you want your runner to support serialization and drag and drop.
283 * By default, this sets the QMimeData urls to the ones specified in @ref QueryMatch::urls
284 */
285 virtual QMimeData *mimeDataForMatch(const KRunner::QueryMatch &match);
286
287private:
288 std::unique_ptr<AbstractRunnerPrivate> const d;
289 KRUNNER_NO_EXPORT Q_INVOKABLE void matchInternal(KRunner::RunnerContext context);
290 KRUNNER_NO_EXPORT Q_INVOKABLE void reloadConfigurationInternal();
291 KRUNNER_NO_EXPORT Q_SIGNAL void matchInternalFinished(const QString &jobId);
292 KRUNNER_NO_EXPORT Q_SIGNAL void matchingResumed();
293 friend class RunnerManager;
294 friend class RunnerContext;
295 friend class RunnerContextPrivate;
296 friend class QueryMatchPrivate;
297 friend class DBusRunner; // Because it "overrides" matchInternal
298};
299
300} // KRunner namespace
301#endif
QString name() const
Returns the translated name from the runner's metadata.
void teardown()
This signal is emitted when a session of matches is complete, giving runners the opportunity to tear ...
KConfigGroup config() const
Provides access to the runner's configuration object.
int minLetterCount() const
This is the minimum letter count for the query.
virtual void reloadConfiguration()
Reloads the runner's configuration.
void suspendMatching(bool suspend)
Sets whether or not the runner is available for match requests.
virtual void run(const KRunner::RunnerContext &context, const KRunner::QueryMatch &match)
Called whenever an exact or possible match associated with this runner is triggered.
KPluginMetaData metadata() const
void setTriggerWords(const QStringList &triggerWords)
Constructs internally a regex which requires the query to start with the trigger words.
void addSyntax(const QString &exampleQuery, const QString &description)
Utility overload for creating a syntax based on the given parameters.
void addSyntax(const RunnerSyntax &syntax)
Adds a registered syntax that this runner understands.
void prepare()
This signal is emitted when matching is about to commence, giving runners an opportunity to prepare t...
bool hasMatchRegex() const
If the runner has a valid regex and non empty regex.
void addSyntax(const QStringList &exampleQueries, const QString &description)
Utility overload for creating a syntax based on the given parameters.
QList< RunnerSyntax > syntaxes() const
QRegularExpression matchRegex() const
If this regex is set with a non empty pattern it must match the query in order for match being called...
void setMinLetterCount(int count)
Set the minLetterCount property.
void setMatchRegex(const QRegularExpression &regex)
Set the matchRegex property.
AbstractRunner(QObject *parent, const KPluginMetaData &pluginMetaData)
Constructor for a KRunner plugin.
virtual void match(KRunner::RunnerContext &context)=0
This is the main query method.
A match returned by an AbstractRunner in response to a given RunnerContext.
Definition querymatch.h:32
The RunnerContext class provides information related to a search, including the search term and colle...
The RunnerManager class decides what installed runners are runnable, and their ratings.
Represents a query prototype that the runner accepts.
void suspend()
QObject(QObject *parent)
Q_OBJECTQ_OBJECT
Q_SIGNALSQ_SIGNALS
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 31 2025 12:10:47 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.