KRunner

abstractrunner.cpp
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#include "abstractrunner.h"
9#include "abstractrunner_p.h"
10
11#include <QHash>
12#include <QIcon>
13#include <QMimeData>
14#include <QRegularExpression>
15#include <QTimer>
16
17#include <KConfigGroup>
18#include <KLocalizedString>
19#include <KSharedConfig>
20
21namespace KRunner
22{
24 : QObject(nullptr)
25 , d(new AbstractRunnerPrivate(this, pluginMetaData))
26{
27 // By now, runners who do "qobject_cast<Krunner::RunnerManager*>(parent)" should have saved the value
28 // By setting the parent to a nullptr, we are allowed to move the object to another thread
29 Q_ASSERT(parent);
30 setObjectName(pluginMetaData.pluginId()); // Only for debugging purposes
31
32 // Suspend matching while we initialize the runner. Once it is ready, the last query will be run
33 QTimer::singleShot(0, this, [this]() {
34 init();
35 // In case the runner didn't specify anything explicitly, we resume matching after the initialization
36 bool doesNotHaveExplicitSuspend = true;
37 {
38 QReadLocker l(&d->lock);
39 doesNotHaveExplicitSuspend = !d->suspendMatching.has_value();
40 }
41 if (doesNotHaveExplicitSuspend) {
42 suspendMatching(false);
43 }
44 });
45}
46
47AbstractRunner::~AbstractRunner() = default;
48
50{
51 KConfigGroup runners(KSharedConfig::openConfig(QStringLiteral("krunnerrc")), QStringLiteral("Runners"));
52 return runners.group(id());
53}
54
58
60{
61 d->syntaxes.append(syntax);
62}
63
65{
66 d->syntaxes = syntaxes;
67}
68
70{
71 return d->syntaxes;
72}
73
75{
76 if (match.urls().isEmpty()) {
77 return nullptr;
78 }
79 QMimeData *result = new QMimeData();
80 result->setUrls(match.urls());
81 return result;
82}
83
84void AbstractRunner::run(const KRunner::RunnerContext & /*search*/, const KRunner::QueryMatch & /*action*/)
85{
86}
87
89{
90 return d->translatedName;
91}
92
94{
95 return d->runnerDescription.pluginId();
96}
97
99{
100 return d->runnerDescription;
101}
102
107
109{
110 QReadLocker lock(&d->lock);
111 return d->suspendMatching.value_or(true);
112}
113
115{
116 QWriteLocker lock(&d->lock);
117 if (d->suspendMatching.has_value() && d->suspendMatching.value() == suspend) {
118 return;
119 }
120
121 d->suspendMatching = suspend;
122 if (!suspend) {
123 Q_EMIT matchingResumed();
124 }
125}
126
128{
129 return d->minLetterCount;
130}
131
133{
134 d->minLetterCount = count;
135}
136
138{
139 return d->matchRegex;
140}
141
143{
144 d->matchRegex = regex;
145 d->hasMatchRegex = regex.isValid() && !regex.pattern().isEmpty();
146}
147
149{
150 int minTriggerWordLetters = 0;
151 QString constructedRegex = QStringLiteral("^");
152 for (const QString &triggerWord : triggerWords) {
153 // We want to link them with an or
154 if (constructedRegex.length() > 1) {
155 constructedRegex += QLatin1Char('|');
156 }
157 constructedRegex += QRegularExpression::escape(triggerWord);
158 if (minTriggerWordLetters == 0 || triggerWord.length() < minTriggerWordLetters) {
159 minTriggerWordLetters = triggerWord.length();
160 }
161 }
162 // If we can reject the query because of the length we don't need the regex
163 setMinLetterCount(minTriggerWordLetters);
164 setMatchRegex(QRegularExpression(constructedRegex));
165}
166
168{
169 return d->hasMatchRegex;
170}
171
172void AbstractRunner::matchInternal(KRunner::RunnerContext context)
173{
174 if (context.isValid()) { // Otherwise, we would just waste resources
175 match(context);
176 }
177 Q_EMIT matchInternalFinished(context.runnerJobId(this));
178}
179// Suspend the runner while reloading the config
180void AbstractRunner::reloadConfigurationInternal()
181{
182 bool isSuspended = isMatchingSuspended();
183 suspendMatching(true);
185 suspendMatching(isSuspended);
186}
187
188} // KRunner namespace
189
190#include "moc_abstractrunner.cpp"
KConfigGroup group(const QString &group)
QString pluginId() const
QString name() const
Returns the translated name from the runner's metadata.
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.
void setSyntaxes(const QList< RunnerSyntax > &syntaxes)
Sets the list of syntaxes; passing in an empty list effectively clears the syntaxes.
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 RunnerSyntax &syntax)
Adds a registered syntax that this runner understands.
bool hasMatchRegex() const
If the runner has a valid regex and non empty regex.
virtual void init()
Reimplement this to run any initialization routines on first load.
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.
virtual QMimeData * mimeDataForMatch(const KRunner::QueryMatch &match)
Reimplement this if you want your runner to support serialization and drag and drop.
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...
Represents a query prototype that the runner accepts.
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
void suspend()
void setUrls(const QList< QUrl > &urls)
Q_EMITQ_EMIT
QObject * parent() const const
void setObjectName(QAnyStringView name)
QString escape(QStringView str)
bool isValid() const const
QString pattern() const const
bool isEmpty() const const
qsizetype length() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 10 2024 11:49:02 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.