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