File indexing completed on 2024-04-28 15:29:43

0001 /*
0002     SPDX-FileCopyrightText: 2006-2007 Aaron Seigo <aseigo@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "querymatch.h"
0008 
0009 #include <QAction>
0010 #include <QIcon>
0011 #include <QPointer>
0012 #include <QReadWriteLock>
0013 #include <QSharedData>
0014 #include <QVariant>
0015 
0016 #include "krunner_debug.h"
0017 
0018 #include "abstractrunner.h"
0019 
0020 namespace Plasma
0021 {
0022 class QueryMatchPrivate : public QSharedData
0023 {
0024 public:
0025     QueryMatchPrivate(AbstractRunner *r)
0026         : QSharedData()
0027         , runner(r)
0028     {
0029     }
0030 
0031     QueryMatchPrivate(const QueryMatchPrivate &other)
0032         : QSharedData(other)
0033     {
0034         QReadLocker l(other.lock);
0035         runner = other.runner;
0036         type = other.type;
0037         relevance = other.relevance;
0038         selAction = other.selAction;
0039         enabled = other.enabled;
0040         idSetByData = other.idSetByData;
0041         matchCategory = other.matchCategory;
0042         id = other.id;
0043         text = other.text;
0044         subtext = other.subtext;
0045         icon = other.icon;
0046         iconName = other.iconName;
0047         data = other.data;
0048 #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 82)
0049         mimeType = other.mimeType;
0050 #endif
0051         urls = other.urls;
0052         actions = other.actions;
0053         multiLine = other.multiLine;
0054     }
0055 
0056     ~QueryMatchPrivate()
0057     {
0058         delete lock;
0059     }
0060 
0061     QReadWriteLock *lock = new QReadWriteLock(QReadWriteLock::Recursive);
0062     QPointer<AbstractRunner> runner;
0063     QueryMatch::Type type = QueryMatch::ExactMatch;
0064     QString matchCategory;
0065     QString id;
0066     QString text;
0067     QString subtext;
0068     QString mimeType;
0069     QList<QUrl> urls;
0070     QIcon icon;
0071     QString iconName;
0072     QVariant data;
0073     qreal relevance = .7;
0074     QAction *selAction = nullptr;
0075     bool enabled = true;
0076     bool idSetByData = false;
0077     QList<QAction *> actions;
0078     bool multiLine = false;
0079 };
0080 
0081 QueryMatch::QueryMatch(AbstractRunner *runner)
0082     : d(new QueryMatchPrivate(runner))
0083 {
0084 }
0085 
0086 QueryMatch::QueryMatch(const QueryMatch &other)
0087     : d(other.d)
0088 {
0089 }
0090 
0091 QueryMatch::~QueryMatch()
0092 {
0093 }
0094 
0095 bool QueryMatch::isValid() const
0096 {
0097     return d->runner != nullptr;
0098 }
0099 
0100 QString QueryMatch::id() const
0101 {
0102     if (d->id.isEmpty() && d->runner) {
0103         return d->runner.data()->id();
0104     }
0105 
0106     return d->id;
0107 }
0108 
0109 #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 113)
0110 void QueryMatch::setType(Type type)
0111 {
0112     d->type = type;
0113 }
0114 #endif
0115 
0116 QueryMatch::Type QueryMatch::type() const
0117 {
0118     return d->type;
0119 }
0120 
0121 void QueryMatch::setMatchCategory(const QString &category)
0122 {
0123     d->matchCategory = category;
0124 }
0125 
0126 QString QueryMatch::matchCategory() const
0127 {
0128     if (d->matchCategory.isEmpty() && d->runner) {
0129         return d->runner->name();
0130     }
0131     return d->matchCategory;
0132 }
0133 
0134 void QueryMatch::setCategoryRelevance(CategoryRelevance relevance)
0135 {
0136     setType((Type) static_cast<int>(relevance));
0137 }
0138 
0139 void QueryMatch::setRelevance(qreal relevance)
0140 {
0141     d->relevance = qMax(qreal(0.0), relevance);
0142 }
0143 
0144 qreal QueryMatch::relevance() const
0145 {
0146     return d->relevance;
0147 }
0148 
0149 AbstractRunner *QueryMatch::runner() const
0150 {
0151     return d->runner.data();
0152 }
0153 
0154 void QueryMatch::setText(const QString &text)
0155 {
0156     QWriteLocker locker(d->lock);
0157     d->text = text;
0158 }
0159 
0160 void QueryMatch::setSubtext(const QString &subtext)
0161 {
0162     QWriteLocker locker(d->lock);
0163     d->subtext = subtext;
0164 }
0165 
0166 void QueryMatch::setData(const QVariant &data)
0167 {
0168     QWriteLocker locker(d->lock);
0169     d->data = data;
0170 
0171     if (d->id.isEmpty() || d->idSetByData) {
0172         const QString matchId = data.toString();
0173         if (!matchId.isEmpty()) {
0174             setId(matchId);
0175             d->idSetByData = true;
0176         }
0177     }
0178 }
0179 
0180 void QueryMatch::setId(const QString &id)
0181 {
0182     QWriteLocker locker(d->lock);
0183     if (d->runner && d->runner->hasUniqueResults()) {
0184         d->id = id;
0185     } else {
0186         if (d->runner) {
0187             d->id = d->runner.data()->id();
0188         }
0189         if (!id.isEmpty()) {
0190             d->id.append(QLatin1Char('_')).append(id);
0191         }
0192     }
0193     d->idSetByData = false;
0194 }
0195 
0196 void QueryMatch::setIcon(const QIcon &icon)
0197 {
0198     QWriteLocker locker(d->lock);
0199     d->icon = icon;
0200 }
0201 
0202 void QueryMatch::setIconName(const QString &iconName)
0203 {
0204     QWriteLocker locker(d->lock);
0205     d->iconName = iconName;
0206 }
0207 
0208 QVariant QueryMatch::data() const
0209 {
0210     QReadLocker locker(d->lock);
0211     return d->data;
0212 }
0213 
0214 QString QueryMatch::text() const
0215 {
0216     QReadLocker locker(d->lock);
0217     return d->text;
0218 }
0219 
0220 QString QueryMatch::subtext() const
0221 {
0222     QReadLocker locker(d->lock);
0223     return d->subtext;
0224 }
0225 
0226 QIcon QueryMatch::icon() const
0227 {
0228     QReadLocker locker(d->lock);
0229     return d->icon;
0230 }
0231 
0232 QString QueryMatch::iconName() const
0233 {
0234     QReadLocker locker(d->lock);
0235     return d->iconName;
0236 }
0237 
0238 #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 82)
0239 void QueryMatch::setMimeType(const QString &mimeType)
0240 {
0241     QWriteLocker locker(d->lock);
0242     d->mimeType = mimeType;
0243 }
0244 
0245 QString QueryMatch::mimeType() const
0246 {
0247     QReadLocker locker(d->lock);
0248     return d->mimeType;
0249 }
0250 #endif
0251 
0252 void QueryMatch::setUrls(const QList<QUrl> &urls)
0253 {
0254     QWriteLocker locker(d->lock);
0255     d->urls = urls;
0256 }
0257 
0258 QList<QUrl> QueryMatch::urls() const
0259 {
0260     QReadLocker locker(d->lock);
0261     return d->urls;
0262 }
0263 
0264 void QueryMatch::setEnabled(bool enabled)
0265 {
0266     d->enabled = enabled;
0267 }
0268 
0269 bool QueryMatch::isEnabled() const
0270 {
0271     return d->enabled && d->runner;
0272 }
0273 
0274 QAction *QueryMatch::selectedAction() const
0275 {
0276     return d->selAction;
0277 }
0278 
0279 void QueryMatch::setSelectedAction(QAction *action)
0280 {
0281     d->selAction = action;
0282 }
0283 
0284 bool QueryMatch::operator<(const QueryMatch &other) const
0285 {
0286     if (d->type == other.d->type) {
0287         if (isEnabled() != other.isEnabled()) {
0288             return other.isEnabled();
0289         }
0290 
0291         if (!qFuzzyCompare(d->relevance, other.d->relevance)) {
0292             return d->relevance < other.d->relevance;
0293         }
0294 
0295         QReadLocker locker(d->lock);
0296         QReadLocker otherLocker(other.d->lock);
0297         // when resorting to sort by alpha, we want the
0298         // reverse sort order!
0299         return d->text > other.d->text;
0300     }
0301 
0302     return d->type < other.d->type;
0303 }
0304 
0305 void QueryMatch::setMultiLine(bool multiLine)
0306 {
0307     d->multiLine = multiLine;
0308 }
0309 
0310 bool QueryMatch::isMultiLine() const
0311 {
0312     return d->multiLine;
0313 }
0314 
0315 QueryMatch &QueryMatch::operator=(const QueryMatch &other)
0316 {
0317     if (d != other.d) {
0318         d = other.d;
0319     }
0320 
0321     return *this;
0322 }
0323 
0324 bool QueryMatch::operator==(const QueryMatch &other) const
0325 {
0326     return (d == other.d);
0327 }
0328 
0329 bool QueryMatch::operator!=(const QueryMatch &other) const
0330 {
0331     return (d != other.d);
0332 }
0333 
0334 void QueryMatch::run(const RunnerContext &context) const
0335 {
0336     if (d->runner) {
0337         d->runner.data()->run(context, *this);
0338     }
0339 }
0340 
0341 #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 71)
0342 bool QueryMatch::hasConfigurationInterface() const
0343 {
0344     return false;
0345 }
0346 #endif
0347 
0348 #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 71)
0349 void QueryMatch::createConfigurationInterface(QWidget *parent)
0350 {
0351     Q_UNUSED(parent)
0352 }
0353 #endif
0354 
0355 void QueryMatch::setActions(const QList<QAction *> &actions)
0356 {
0357     QWriteLocker locker(d->lock);
0358     d->actions = actions;
0359 }
0360 
0361 void QueryMatch::addAction(QAction *action)
0362 {
0363     QWriteLocker locker(d->lock);
0364     d->actions << action;
0365 }
0366 
0367 QList<QAction *> QueryMatch::actions() const
0368 {
0369     QReadLocker locker(d->lock);
0370     return d->actions;
0371 }
0372 
0373 } // Plasma namespace