1 /*
2     SPDX-FileCopyrightText: 2006 Aaron Seigo <aseigo@kde.org>
3     SPDX-FileCopyrightText: 2007 Ryan P. Bitanga <ryan.bitanga@gmail.com>
4     SPDX-FileCopyrightText: 2008 Jordi Polo <mumismo@gmail.com>
5 
6     SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #ifndef PLASMA_RUNNERMANAGER_H
10 #define PLASMA_RUNNERMANAGER_H
11 
12 #include <QList>
13 #include <QObject>
14 
15 #include <KPluginInfo>
16 #include <KPluginMetaData>
17 
18 #include <memory>
19 
20 #include "abstractrunner.h"
21 #include "krunner_export.h"
22 
23 class QAction;
24 class KConfigGroup;
25 
26 namespace Plasma
27 {
28 class QueryMatch;
29 class AbstractRunner;
30 class RunnerContext;
31 class RunnerManagerPrivate;
32 
33 /**
34  * @class RunnerManager runnermanager.h <KRunner/RunnerManager>
35  *
36  * @short The RunnerManager class decides what installed runners are runnable,
37  *        and their ratings. It is the main proxy to the runners.
38  */
39 class KRUNNER_EXPORT RunnerManager : public QObject
40 {
41     Q_OBJECT
42     Q_PROPERTY(bool retainPriorSearch READ retainPriorSearch)
43     Q_PROPERTY(QString priorSearch READ priorSearch WRITE setPriorSearch)
44     Q_PROPERTY(QStringList history READ history)
45     Q_PROPERTY(bool historyEnabled READ historyEnabled NOTIFY historyEnabledChanged)
46 
47 public:
48     explicit RunnerManager(QObject *parent = nullptr);
49     explicit RunnerManager(const QString &configFile, QObject *parent = nullptr);
50 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 76)
51     /**
52      * @deprecated Since 5.76, use "RunnerManager(const QString &configFile, QObject *parent)" instead.
53      */
54     KRUNNER_DEPRECATED_VERSION(5, 76, "use RunnerManager(const QString &configFile, QObject *parent) instead")
55     explicit RunnerManager(KConfigGroup &config, QObject *parent = nullptr);
56 #endif
57     ~RunnerManager() override;
58 
59     /**
60      * Finds and returns a loaded runner or NULL
61      * @param pluginName the name of the runner plugin
62      * @return Pointer to the runner
63      */
64     AbstractRunner *runner(const QString &pluginName) const;
65 
66 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 82)
67     /**
68      * @return the currently active "single mode" runner, or null if none
69      * @since 4.4
70      * @deprecated Since 5.81, the dedicated singleRunnerMode methods are deprecated, use runner(const QString &pluginName) with the singleRunnerId instead"
71      */
72     KRUNNER_DEPRECATED_VERSION(5,
73                                82,
74                                "The dedicated singleRunnerMode methods are deprecated, use runner(const QString &pluginName) with the singleRunnerId instead")
75     AbstractRunner *singleModeRunner() const;
76 
77     /**
78      * Puts the manager into "single runner" mode using the given
79      * runner; if the runner does not exist or can not be loaded then
80      * the single runner mode will not be started and singleModeRunner()
81      * will return NULL
82      * @param id the id of the runner to use
83      * @since 4.4
84      * @deprecated Since 5.82, the dedicated singleRunnerMode methods are deprecated, pass in the singleModeRunnerId into the launchQuery overload instead
85      */
86     KRUNNER_DEPRECATED_VERSION(5,
87                                82,
88                                "The dedicated singleRunnerMode methods are deprecated, pass in the singleModeRunnerId into the launchQuery overload instead")
89     void setSingleModeRunnerId(const QString &id);
90 
91     /**
92      * @return the id of the runner to use in single mode
93      * @since 4.4
94      * @deprecated Since 5.82, the dedicated singleRunnerMode methods are deprecated, use runner(const QString &pluginName) with the singleRunnerId instead
95      */
96     KRUNNER_DEPRECATED_VERSION(5, 82, "The dedicated singleRunnerMode methods are deprecated, save the variable before using it in launchQuery() instead")
97     QString singleModeRunnerId() const;
98 
99     /**
100      * @return true if the manager is set to run in single runner mode
101      * @since 4.4
102      * @deprecated Since 5.82, the dedicated singleRunnerMode methods are deprecated, call the RunnerContext::singleRunnerQueryMode on the searchContext instead
103      */
104     KRUNNER_DEPRECATED_VERSION(
105         5,
106         82,
107         "The dedicated singleRunnerMode methods are deprecated, call the RunnerContext::singleRunnerQueryMode on the searchContext instead")
108     bool singleMode() const;
109 
110     /**
111      * Sets whether or not the manager is in single mode.
112      *
113      * @param singleMode true if the manager should be in single mode, false otherwise
114      * @since 4.4
115      * @deprecated Since 5.82, the dedicated singleRunnerMode methods are deprecated, the single mode is set to true when launchQuery is called with a non
116      * empty and existing runnerId
117      */
118     KRUNNER_DEPRECATED_VERSION(5,
119                                82,
120                                "The dedicated singleRunnerMode methods are deprecated, the single mode is set to true when launchQuery is called with a non "
121                                "empty and existing runnerId")
122     void setSingleMode(bool singleMode);
123 
124     /**
125      * @return the names of all runners that advertise single query mode
126      * @since 4.4
127      * @deprecated Since 5.81, filter the runners manually using the X-Plasma-AdvertiseSingleRunnerQueryMode of the metadata
128      */
129     KRUNNER_DEPRECATED_VERSION(5, 81, "filter the runners manually using the X-Plasma-AdvertiseSingleRunnerQueryMode of the metadata")
130     QStringList singleModeAdvertisedRunnerIds() const;
131 
132     /**
133      * Returns the translated name of a runner
134      * @param id the id of the runner
135      *
136      * @since 4.4
137      * @deprecated Since 5.81, call runner(const QString &id) and fetch the name from the returned object instead
138      */
139     KRUNNER_DEPRECATED_VERSION(5, 81, "call runner(const QString &id) and fetch the name from the returned object instead")
140     QString runnerName(const QString &id) const;
141 #endif
142 
143     /**
144      * @return the list of all currently loaded runners
145      */
146     QList<AbstractRunner *> runners() const;
147 
148     /**
149      * Retrieves the current context
150      * @return pointer to the current context
151      */
152     RunnerContext *searchContext() const;
153 
154     /**
155      * Retrieves all available matches found so far for the previously launched query
156      * @return List of matches
157      */
158     QList<QueryMatch> matches() const;
159 
160     /**
161      * Runs a given match
162      * @param match the match to be executed
163      */
164     void run(const QueryMatch &match);
165 
166 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 79)
167     /**
168      * Runs a given match
169      * @param id the id of the match to run
170      * @deprecated Since 5.79, use run(const QueryMatch &match) instead
171      */
172     KRUNNER_DEPRECATED_VERSION(5, 79, "Use run(const QueryMatch &match) instead")
173     void run(const QString &id);
174 #endif
175 
176     /**
177      * Runs a given match. This also respects the extra handling for the InformationalMatch.
178      * This also handles the history automatically
179      * @param match the match to be executed
180      * @return if the RunnerWindow should close
181      * @since 5.78
182      */
183     bool runMatch(const QueryMatch &match);
184 
185     /**
186      * Retrieves the list of actions, if any, for a match
187      */
188     QList<QAction *> actionsForMatch(const QueryMatch &match);
189 
190     /**
191      * @return the current query term
192      */
193     QString query() const;
194 
195     /**
196      * @return History of this runner for the current activity. If the RunnerManager is not history
197      * aware the global entries will be returned.
198      * @since 5.78
199      */
200     QStringList history() const;
201 
202     /**
203      * Delete the given index from the history.
204      * @param historyEntry
205      * @since 5.78
206      */
207     Q_INVOKABLE void removeFromHistory(int index);
208 
209     /**
210      * Get the suggested history entry for the typed query. If no entry is found an empty string is returned.
211      * @param typedQuery
212      * @return completion for typedQuery
213      * @since 5.78
214      */
215     Q_INVOKABLE QString getHistorySuggestion(const QString &typedQuery) const;
216 
217     /**
218      * Get the suggested prior search for this runner.
219      * Just like the history this value can be activity specific, depending on the build/config.
220      * @return priorSearch
221      * @since 5.78
222      */
223     QString priorSearch() const;
224 
225     /**
226      * Set the prior search for this runner. Setting an empty string will clear this value.
227      * @since 5.78
228      */
229     void setPriorSearch(const QString &search);
230 
231     /**
232      * If the prior search should be restored when KRunner is reopened
233      * @since 5.78
234      */
235     bool retainPriorSearch();
236 
237     /**
238      * If history completion is enabled, the default value is true.
239      * @since 5.78
240      */
241     bool historyEnabled();
242 
243     /**
244      * Causes a reload of the current configuration
245      */
246     void reloadConfiguration();
247 
248     /**
249      * Sets a whitelist for the plugins that can be loaded by this manager.
250      *
251      * @param plugins the plugin names of allowed runners
252      * @since 4.4
253      */
254     void setAllowedRunners(const QStringList &runners);
255 
256 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 76)
257     /**
258      * Sets the list of categories which matches should be
259      * returned for. It also internally tries not to execute the
260      * runners which do not fall in this category.
261      * @deprecated Since 5.76, feature is unused and not supported by most runners
262      */
263     KRUNNER_DEPRECATED_VERSION(5, 76, "feature is unused and not supported by most runners")
264     void setEnabledCategories(const QStringList &categories);
265 #endif
266 
267 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 72)
268 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 0)
269     /**
270      * Attempts to add the AbstractRunner plugin represented
271      * by the KService passed in. Usually one can simply let
272      * the configuration of plugins handle loading Runner plugins,
273      * but in cases where specific runners should be loaded this
274      * allows for that to take place
275      *
276      * @param service the service to use to load the plugin
277      * @since 4.5
278      * @deprecated Since 5.72, use loadRunner(const KPluginMetaData &)
279      */
280     KRUNNER_DEPRECATED_VERSION(5, 72, "use loadRunner(const KPluginMetaData &)")
281     void loadRunner(const KService::Ptr service);
282 #endif
283 #endif
284 
285     /**
286      * Attempts to add the AbstractRunner plugin represented
287      * by the plugin info passed in. Usually one can simply let
288      * the configuration of plugins handle loading Runner plugins,
289      * but in cases where specific runners should be loaded this
290      * allows for that to take place
291      *
292      * @param pluginMetaData the metaData to use to load the plugin
293      * @since 5.72
294      */
295     void loadRunner(const KPluginMetaData &pluginMetaData);
296 
297 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 77)
298     /**
299      * Attempts to add the AbstractRunner from a Plasma::Package on disk.
300      * Usually one can simply let the configuration of plugins
301      * handle loading Runner plugins, but in cases where specific
302      * runners should be loaded this allows for that to take place
303      *
304      * @param path the path to a Runner package to load
305      * @since 4.5
306      * @deprecated Since 5.0, the KPackage support was removed in Plasma 5.0
307      */
308     KRUNNER_DEPRECATED_VERSION_BELATED(5, 77, 5, 0, "the KPackage support was removed in Plasma 5.0")
309     void loadRunner(const QString &path);
310 #endif
311 
312 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 77)
313     /**
314      * @return the list of allowed plugins
315      * @since 4.4
316      * @deprecated Since 5.88, reading allowed runners from the config is deprecated, use @p runners() and get their @p AbstractRunner::id instead
317      */
318     KRUNNER_DEPRECATED_VERSION(5, 88, "reading allowed runners from the config is deprecated, use runners() and get their ids instead")
319     QStringList allowedRunners() const;
320 #endif
321 
322 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 76)
323     /**
324      * @return the list of enabled categories
325      * @deprecated Since 5.76, feature is unused and not supported by most runners
326      */
327     KRUNNER_DEPRECATED_VERSION(5, 76, "feature is unused and not supported by most runners")
328     QStringList enabledCategories() const;
329 #endif
330 
331     /**
332      * @return mime data of the specified match
333      * @since 4.5
334      */
335     QMimeData *mimeDataForMatch(const QueryMatch &match) const;
336 
337 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 79)
338     /**
339      * @return mime data of the specified match
340      * @since 4.5
341      * @deprecated Since 5.79, use mimeDataForMatch(const QueryMatch &match) instead
342      */
343     KRUNNER_DEPRECATED_VERSION(5, 79, "Use mimeDataForMatch(const QueryMatch &match) instead")
344     QMimeData *mimeDataForMatch(const QString &matchId) const;
345 #endif
346 
347 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 85)
348     /**
349      * Returns a list of all known Runner implementations
350      *
351      * @param parentApp the application to filter runners on. Uses the
352      *                  X-KDE-ParentApp entry (if any) in the plugin metadata.
353      *                  The default value of QString() will result in a
354      *                  list containing only runners not specifically
355      *                  registered to an application.
356      * @return list of metadata of known runners
357      * @since 5.72
358      * @deprecated Since 5.85, the concept of parent apps for runners is deprecated, use no-arg overload instead
359      **/
360     KRUNNER_DEPRECATED_VERSION(5, 85, "The concept of parent apps for runners is deprecated, use no-arg overload instead")
361     static QVector<KPluginMetaData> runnerMetaDataList(const QString &parentApp);
362 #endif
363 
364     /**
365      * @return metadata list of all known Runner implementations
366      * @since 5.72
367      */
368     static QVector<KPluginMetaData> runnerMetaDataList();
369 
370 #if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 72)
371     /**
372      * Returns a list of all known Runner implementations
373      *
374      * @param parentApp the application to filter applets on. Uses the
375      *                  X-KDE-ParentApp entry (if any) in the plugin info.
376      *                  The default value of QString() will result in a
377      *                  list containing only applets not specifically
378      *                  registered to an application.
379      * @return list of AbstractRunners
380      * @since 4.6
381      * @deprecated since 5.72, use runnerMetaDataList() instead
382      **/
383     KRUNNER_DEPRECATED_VERSION(5, 72, "Use runnerMetaDataList() instead")
384     static KPluginInfo::List listRunnerInfo(const QString &parentApp = QString());
385 #endif
386 
387     /**
388      * If you call this method the manager will create a KConfigWatcher
389      * which reload its runners or the runner configuration when the settings in the KCM are edited.
390      * @since 5.73
391      * @see reloadConfiguration
392      */
393     void enableKNotifyPluginWatcher(); // TODO KF6 make enabling the watcher default behavior and remove the method
394 
395 public Q_SLOTS:
396     /**
397      * Call this method when the runners should be prepared for a query session.
398      * Call matchSessionComplete when the query session is finished for the time
399      * being.
400      * @since 4.4
401      * @see matchSessionComplete
402      */
403     void setupMatchSession();
404 
405     /**
406      * Call this method when the query session is finished for the time
407      * being.
408      * @since 4.4
409      * @see prepareForMatchSession
410      */
411     void matchSessionComplete();
412 
413     /**
414      * Launch a query, this will create threads and return immediately.
415      * When the information will be available can be known using the
416      * matchesChanged signal.
417      *
418      * @param term the term we want to find matches for
419      * @param runnerId optional, if only one specific runner is to be used;
420      *               providing an id will put the manager into single runner mode
421      */
422     void launchQuery(const QString &term, const QString &runnerId);
423 
424     /**
425      * Convenience version of above
426      */
427     void launchQuery(const QString &term); // TODO KF6 Merge with other overload and use default argument
428 
429     /**
430      * Reset the current data and stops the query
431      */
432     void reset();
433 
434 Q_SIGNALS:
435     /**
436      * Emitted each time a new match is added to the list
437      */
438     void matchesChanged(const QList<Plasma::QueryMatch> &matches);
439 
440     /**
441      * Emitted when the launchQuery finish
442      * @since 4.5
443      */
444     void queryFinished();
445 
446     /**
447      * Put the given search term in the KRunner search field
448      * @param term The term that should be displayed
449      * @param cursorPosition Where the cursor should be positioned
450      * @since 5.78
451      */
452     void setSearchTerm(const QString &term, int cursorPosition);
453 
454     /**
455      * @see @p historyEnabled
456      * @since 5.78
457      */
458     void historyEnabledChanged();
459 
460 private:
461     Q_PRIVATE_SLOT(d, void jobDone(ThreadWeaver::JobPointer))
462 
463     std::unique_ptr<RunnerManagerPrivate> const d;
464 
465     friend class RunnerManagerPrivate;
466 };
467 
468 }
469 
470 #endif
471