1 | /* |
2 | SPDX-FileCopyrightText: 2006-2007 Aaron Seigo <aseigo@kde.org> |
3 | |
4 | SPDX-License-Identifier: LGPL-2.0-or-later |
5 | */ |
6 | |
7 | #include "querymatch.h" |
8 | #include "action.h" |
9 | |
10 | #include <QIcon> |
11 | #include <QPointer> |
12 | #include <QReadWriteLock> |
13 | #include <QSharedData> |
14 | #include <QVariant> |
15 | |
16 | #include "krunner_debug.h" |
17 | |
18 | #include "abstractrunner.h" |
19 | #include "abstractrunner_p.h" |
20 | |
21 | namespace KRunner |
22 | { |
23 | class QueryMatchPrivate : public QSharedData |
24 | { |
25 | public: |
26 | QueryMatchPrivate(AbstractRunner *r) |
27 | : QSharedData() |
28 | , runner(r) |
29 | { |
30 | } |
31 | |
32 | QueryMatchPrivate(const QueryMatchPrivate &other) |
33 | : QSharedData(other) |
34 | { |
35 | QReadLocker l(&other.lock); |
36 | runner = other.runner; |
37 | categoryRelevance = other.categoryRelevance; |
38 | relevance = other.relevance; |
39 | selAction = other.selAction; |
40 | enabled = other.enabled; |
41 | idSetByData = other.idSetByData; |
42 | matchCategory = other.matchCategory; |
43 | id = other.id; |
44 | text = other.text; |
45 | subtext = other.subtext; |
46 | icon = other.icon; |
47 | iconName = other.iconName; |
48 | data = other.data; |
49 | urls = other.urls; |
50 | actions = other.actions; |
51 | multiLine = other.multiLine; |
52 | } |
53 | |
54 | void setId(const QString &newId) |
55 | { |
56 | if (runner && runner->d->hasUniqueResults) { |
57 | id = newId; |
58 | } else { |
59 | if (runner) { |
60 | id = runner.data()->id(); |
61 | } |
62 | if (!id.isEmpty()) { |
63 | id.append(QLatin1Char('_')).append(newId); |
64 | } |
65 | } |
66 | idSetByData = false; |
67 | } |
68 | |
69 | mutable QReadWriteLock lock; |
70 | QPointer<AbstractRunner> runner; |
71 | QString matchCategory; |
72 | QString id; |
73 | QString text; |
74 | QString subtext; |
75 | QString mimeType; |
76 | QList<QUrl> urls; |
77 | QIcon icon; |
78 | QString iconName; |
79 | QVariant data; |
80 | qreal categoryRelevance = 50; |
81 | qreal relevance = .7; |
82 | KRunner::Action selAction; |
83 | KRunner::Actions actions; |
84 | bool enabled = true; |
85 | bool idSetByData = false; |
86 | bool multiLine = false; |
87 | }; |
88 | |
89 | QueryMatch::QueryMatch(AbstractRunner *runner) |
90 | : d(new QueryMatchPrivate(runner)) |
91 | { |
92 | } |
93 | |
94 | QueryMatch::QueryMatch(const QueryMatch &other) |
95 | : d(other.d) |
96 | { |
97 | } |
98 | |
99 | QueryMatch::~QueryMatch() = default; |
100 | |
101 | bool QueryMatch::isValid() const |
102 | { |
103 | return d->runner != nullptr; |
104 | } |
105 | |
106 | QString QueryMatch::id() const |
107 | { |
108 | if (d->id.isEmpty() && d->runner) { |
109 | return d->runner.data()->id(); |
110 | } |
111 | |
112 | return d->id; |
113 | } |
114 | |
115 | void QueryMatch::setType(Type type) |
116 | { |
117 | d->categoryRelevance = type; |
118 | } |
119 | |
120 | QueryMatch::Type QueryMatch::type() const |
121 | { |
122 | return (QueryMatch::Type)d->categoryRelevance; |
123 | } |
124 | |
125 | void QueryMatch::setCategoryRelevance(qreal relevance) |
126 | { |
127 | d->categoryRelevance = qBound(0.0, relevance, 100.0); |
128 | } |
129 | |
130 | qreal QueryMatch::categoryRelevance() const |
131 | { |
132 | return d->categoryRelevance; |
133 | } |
134 | |
135 | void QueryMatch::setMatchCategory(const QString &category) |
136 | { |
137 | d->matchCategory = category; |
138 | } |
139 | |
140 | QString QueryMatch::matchCategory() const |
141 | { |
142 | if (d->matchCategory.isEmpty() && d->runner) { |
143 | return d->runner->name(); |
144 | } |
145 | return d->matchCategory; |
146 | } |
147 | |
148 | void QueryMatch::setRelevance(qreal relevance) |
149 | { |
150 | d->relevance = qMax(qreal(0.0), relevance); |
151 | } |
152 | |
153 | qreal QueryMatch::relevance() const |
154 | { |
155 | return d->relevance; |
156 | } |
157 | |
158 | AbstractRunner *QueryMatch::runner() const |
159 | { |
160 | return d->runner.data(); |
161 | } |
162 | |
163 | void QueryMatch::setText(const QString &text) |
164 | { |
165 | QWriteLocker locker(&d->lock); |
166 | d->text = text; |
167 | } |
168 | |
169 | void QueryMatch::setSubtext(const QString &subtext) |
170 | { |
171 | QWriteLocker locker(&d->lock); |
172 | d->subtext = subtext; |
173 | } |
174 | |
175 | void QueryMatch::setData(const QVariant &data) |
176 | { |
177 | QWriteLocker locker(&d->lock); |
178 | d->data = data; |
179 | |
180 | if (d->id.isEmpty() || d->idSetByData) { |
181 | const QString matchId = data.toString(); |
182 | if (!matchId.isEmpty()) { |
183 | d->setId(matchId); |
184 | d->idSetByData = true; |
185 | } |
186 | } |
187 | } |
188 | |
189 | void QueryMatch::setId(const QString &id) |
190 | { |
191 | QWriteLocker locker(&d->lock); |
192 | d->setId(id); |
193 | } |
194 | |
195 | void QueryMatch::setIcon(const QIcon &icon) |
196 | { |
197 | QWriteLocker locker(&d->lock); |
198 | d->icon = icon; |
199 | } |
200 | |
201 | void QueryMatch::setIconName(const QString &iconName) |
202 | { |
203 | QWriteLocker locker(&d->lock); |
204 | d->iconName = iconName; |
205 | } |
206 | |
207 | QVariant QueryMatch::data() const |
208 | { |
209 | QReadLocker locker(&d->lock); |
210 | return d->data; |
211 | } |
212 | |
213 | QString QueryMatch::text() const |
214 | { |
215 | QReadLocker locker(&d->lock); |
216 | return d->text; |
217 | } |
218 | |
219 | QString QueryMatch::subtext() const |
220 | { |
221 | QReadLocker locker(&d->lock); |
222 | return d->subtext; |
223 | } |
224 | |
225 | QIcon QueryMatch::icon() const |
226 | { |
227 | QReadLocker locker(&d->lock); |
228 | return d->icon; |
229 | } |
230 | |
231 | QString QueryMatch::iconName() const |
232 | { |
233 | QReadLocker locker(&d->lock); |
234 | return d->iconName; |
235 | } |
236 | |
237 | void QueryMatch::setUrls(const QList<QUrl> &urls) |
238 | { |
239 | QWriteLocker locker(&d->lock); |
240 | d->urls = urls; |
241 | } |
242 | |
243 | QList<QUrl> QueryMatch::urls() const |
244 | { |
245 | QReadLocker locker(&d->lock); |
246 | return d->urls; |
247 | } |
248 | |
249 | void QueryMatch::setEnabled(bool enabled) |
250 | { |
251 | d->enabled = enabled; |
252 | } |
253 | |
254 | bool QueryMatch::isEnabled() const |
255 | { |
256 | return d->enabled && d->runner; |
257 | } |
258 | |
259 | KRunner::Action QueryMatch::selectedAction() const |
260 | { |
261 | return d->selAction; |
262 | } |
263 | |
264 | void QueryMatch::setSelectedAction(const KRunner::Action &action) |
265 | { |
266 | d->selAction = action; |
267 | } |
268 | |
269 | void QueryMatch::setMultiLine(bool multiLine) |
270 | { |
271 | d->multiLine = multiLine; |
272 | } |
273 | |
274 | bool QueryMatch::isMultiLine() const |
275 | { |
276 | return d->multiLine; |
277 | } |
278 | |
279 | QueryMatch &QueryMatch::operator=(const QueryMatch &other) |
280 | { |
281 | if (d != other.d) { |
282 | d = other.d; |
283 | } |
284 | |
285 | return *this; |
286 | } |
287 | |
288 | bool QueryMatch::operator==(const QueryMatch &other) const |
289 | { |
290 | return (d == other.d); |
291 | } |
292 | |
293 | bool QueryMatch::operator!=(const QueryMatch &other) const |
294 | { |
295 | return (d != other.d); |
296 | } |
297 | |
298 | void QueryMatch::setActions(const QList<KRunner::Action> &actions) |
299 | { |
300 | QWriteLocker locker(&d->lock); |
301 | d->actions = actions; |
302 | } |
303 | |
304 | void QueryMatch::addAction(const KRunner::Action &action) |
305 | { |
306 | QWriteLocker locker(&d->lock); |
307 | d->actions << action; |
308 | } |
309 | |
310 | KRunner::Actions QueryMatch::actions() const |
311 | { |
312 | QReadLocker locker(&d->lock); |
313 | return d->actions; |
314 | } |
315 | |
316 | QDebug operator<<(QDebug debug, const KRunner::QueryMatch &match) |
317 | { |
318 | QDebugStateSaver saver(debug); |
319 | debug.nospace() << "QueryMatch(category: " << match.matchCategory() << " text:" << match.text() << ")" ; |
320 | return debug; |
321 | } |
322 | |
323 | } // KRunner namespace |
324 | |