1/*
2 * Copyright 2006-2007 Aaron Seigo <aseigo@kde.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#include "querymatch.h"
21
22#include <QAction>
23#include <QIcon>
24#include <QReadWriteLock>
25#include <QSharedData>
26#include <QStringList>
27#include <QVariant>
28#include <QWeakPointer>
29
30#include <kdebug.h>
31
32#include "abstractrunner.h"
33
34namespace Plasma
35{
36
37class QueryMatchPrivate : public QSharedData
38{
39 public:
40 QueryMatchPrivate(AbstractRunner *r)
41 : QSharedData(),
42 lock(new QReadWriteLock(QReadWriteLock::Recursive)),
43 runner(r),
44 type(QueryMatch::ExactMatch),
45 relevance(.7),
46 selAction(0),
47 enabled(true),
48 idSetByData(false)
49 {
50 }
51
52 QueryMatchPrivate(const QueryMatchPrivate &other)
53 : QSharedData(other),
54 lock(new QReadWriteLock(QReadWriteLock::Recursive))
55 {
56 QReadLocker lock(other.lock);
57 runner = other.runner;
58 type = other.type;
59 relevance = other.relevance;
60 selAction = other.selAction;
61 enabled = other.enabled;
62 idSetByData = other.idSetByData;
63 id = other.id;
64 text = other.text;
65 subtext = other.subtext;
66 icon = other.icon;
67 data = other.data;
68 }
69
70 ~QueryMatchPrivate()
71 {
72 delete lock;
73 }
74
75 QReadWriteLock *lock;
76 QWeakPointer<AbstractRunner> runner;
77 QueryMatch::Type type;
78 QString id;
79 QString text;
80 QString subtext;
81 QIcon icon;
82 QVariant data;
83 qreal relevance;
84 QAction *selAction;
85 bool enabled : 1;
86 bool idSetByData : 1;
87};
88
89QueryMatch::QueryMatch(AbstractRunner *runner)
90 : d(new QueryMatchPrivate(runner))
91{
92// kDebug() << "new match created";
93}
94
95QueryMatch::QueryMatch(const QueryMatch &other)
96 : d(other.d)
97{
98}
99
100QueryMatch::~QueryMatch()
101{
102}
103
104bool QueryMatch::isValid() const
105{
106 return d->runner != 0;
107}
108
109QString QueryMatch::id() const
110{
111 if (d->id.isEmpty() && d->runner) {
112 return d->runner.data()->id();
113 }
114
115 return d->id;
116}
117
118void QueryMatch::setType(Type type)
119{
120 d->type = type;
121}
122
123QueryMatch::Type QueryMatch::type() const
124{
125 return d->type;
126}
127
128void QueryMatch::setRelevance(qreal relevance)
129{
130 d->relevance = qMax(qreal(0.0), relevance);
131}
132
133qreal QueryMatch::relevance() const
134{
135 return d->relevance;
136}
137
138AbstractRunner* QueryMatch::runner() const
139{
140 return d->runner.data();
141}
142
143void QueryMatch::setText(const QString &text)
144{
145 QWriteLocker locker(d->lock);
146 d->text = text;
147}
148
149void QueryMatch::setSubtext(const QString &subtext)
150{
151 QWriteLocker locker(d->lock);
152 d->subtext = subtext;
153}
154
155void QueryMatch::setData(const QVariant & data)
156{
157 QWriteLocker locker(d->lock);
158 d->data = data;
159
160 if (d->id.isEmpty() || d->idSetByData) {
161 const QString id = data.toString();
162 if (!id.isEmpty()) {
163 setId(data.toString());
164 d->idSetByData = true;
165 }
166 }
167}
168
169void QueryMatch::setId(const QString &id)
170{
171 QWriteLocker locker(d->lock);
172 if (d->runner) {
173 d->id = d->runner.data()->id();
174 }
175
176 if (!id.isEmpty()) {
177 d->id.append('_').append(id);
178 }
179
180 d->idSetByData = false;
181}
182
183void QueryMatch::setIcon(const QIcon &icon)
184{
185 QWriteLocker locker(d->lock);
186 d->icon = icon;
187}
188
189QVariant QueryMatch::data() const
190{
191 QReadLocker locker(d->lock);
192 return d->data;
193}
194
195QString QueryMatch::text() const
196{
197 QReadLocker locker(d->lock);
198 return d->text;
199}
200
201QString QueryMatch::subtext() const
202{
203 QReadLocker locker(d->lock);
204 return d->subtext;
205}
206
207QIcon QueryMatch::icon() const
208{
209 QReadLocker locker(d->lock);
210 return d->icon;
211}
212
213void QueryMatch::setEnabled(bool enabled)
214{
215 d->enabled = enabled;
216}
217
218bool QueryMatch::isEnabled() const
219{
220 return d->enabled && d->runner;
221}
222
223QAction* QueryMatch::selectedAction() const
224{
225 return d->selAction;
226}
227
228void QueryMatch::setSelectedAction(QAction *action)
229{
230 d->selAction = action;
231}
232
233bool QueryMatch::operator<(const QueryMatch &other) const
234{
235 if (d->type == other.d->type) {
236 if (isEnabled() != other.isEnabled()) {
237 return other.isEnabled();
238 }
239
240 if (d->relevance != other.d->relevance) {
241 return d->relevance < other.d->relevance;
242 }
243
244 QReadLocker locker(d->lock);
245 QReadLocker otherLocker(other.d->lock);
246 // when resorting to sort by alpha, we want the
247 // reverse sort order!
248 return d->text > other.d->text;
249 }
250
251 return d->type < other.d->type;
252}
253
254QueryMatch &QueryMatch::operator=(const QueryMatch &other)
255{
256 if (d != other.d) {
257 d = other.d;
258 }
259
260 return *this;
261}
262
263bool QueryMatch::operator==(const QueryMatch &other) const
264{
265 return (d == other.d);
266}
267
268bool QueryMatch::operator!=(const QueryMatch &other) const
269{
270 return (d != other.d);
271}
272
273void QueryMatch::run(const RunnerContext &context) const
274{
275 //kDebug() << "we run the term" << context->query() << "whose type is" << context->mimetype();
276 if (d->runner) {
277 d->runner.data()->run(context, *this);
278 }
279}
280
281bool QueryMatch::hasConfigurationInterface() const
282{
283 return d->runner && d->runner.data()->hasRunOptions();
284}
285
286void QueryMatch::createConfigurationInterface(QWidget *parent)
287{
288 if (hasConfigurationInterface()) {
289 d->runner.data()->createRunOptions(parent);
290 }
291}
292
293} // Plasma namespace
294
295