File indexing completed on 2024-04-14 03:54:31

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 #include "action.h"
0009 
0010 #include <QIcon>
0011 #include <QPointer>
0012 #include <QReadWriteLock>
0013 #include <QSharedData>
0014 #include <QVariant>
0015 
0016 #include "abstractrunner.h"
0017 #include "abstractrunner_p.h"
0018 
0019 namespace KRunner
0020 {
0021 class QueryMatchPrivate : public QSharedData
0022 {
0023 public:
0024     QueryMatchPrivate(AbstractRunner *r)
0025         : QSharedData()
0026         , runner(r)
0027     {
0028     }
0029 
0030     QueryMatchPrivate(const QueryMatchPrivate &other)
0031         : QSharedData(other)
0032     {
0033         QReadLocker l(&other.lock);
0034         runner = other.runner;
0035         categoryRelevance = other.categoryRelevance;
0036         relevance = other.relevance;
0037         selAction = other.selAction;
0038         enabled = other.enabled;
0039         idSetByData = other.idSetByData;
0040         matchCategory = other.matchCategory;
0041         id = other.id;
0042         text = other.text;
0043         subtext = other.subtext;
0044         icon = other.icon;
0045         iconName = other.iconName;
0046         data = other.data;
0047         urls = other.urls;
0048         actions = other.actions;
0049         multiLine = other.multiLine;
0050     }
0051 
0052     void setId(const QString &newId)
0053     {
0054         if (runner && runner->d->hasUniqueResults) {
0055             id = newId;
0056         } else {
0057             if (runner) {
0058                 id = runner.data()->id();
0059             }
0060             if (!id.isEmpty()) {
0061                 id.append(QLatin1Char('_')).append(newId);
0062             }
0063         }
0064         idSetByData = false;
0065     }
0066 
0067     mutable QReadWriteLock lock;
0068     QPointer<AbstractRunner> runner;
0069     QString matchCategory;
0070     QString id;
0071     QString text;
0072     QString subtext;
0073     QString mimeType;
0074     QList<QUrl> urls;
0075     QIcon icon;
0076     QString iconName;
0077     QVariant data;
0078     qreal categoryRelevance = 50;
0079     qreal relevance = .7;
0080     KRunner::Action selAction;
0081     KRunner::Actions actions;
0082     bool enabled = true;
0083     bool idSetByData = false;
0084     bool multiLine = false;
0085 };
0086 
0087 QueryMatch::QueryMatch(AbstractRunner *runner)
0088     : d(new QueryMatchPrivate(runner))
0089 {
0090 }
0091 
0092 QueryMatch::QueryMatch(const QueryMatch &other)
0093     : d(other.d)
0094 {
0095 }
0096 
0097 QueryMatch::~QueryMatch() = default;
0098 
0099 bool QueryMatch::isValid() const
0100 {
0101     return d->runner != nullptr;
0102 }
0103 
0104 QString QueryMatch::id() const
0105 {
0106     if (d->id.isEmpty() && d->runner) {
0107         return d->runner.data()->id();
0108     }
0109 
0110     return d->id;
0111 }
0112 
0113 void QueryMatch::setCategoryRelevance(qreal relevance)
0114 {
0115     d->categoryRelevance = qBound(0.0, relevance, 100.0);
0116 }
0117 
0118 qreal QueryMatch::categoryRelevance() const
0119 {
0120     return d->categoryRelevance;
0121 }
0122 
0123 void QueryMatch::setMatchCategory(const QString &category)
0124 {
0125     d->matchCategory = category;
0126 }
0127 
0128 QString QueryMatch::matchCategory() const
0129 {
0130     if (d->matchCategory.isEmpty() && d->runner) {
0131         return d->runner->name();
0132     }
0133     return d->matchCategory;
0134 }
0135 
0136 void QueryMatch::setRelevance(qreal relevance)
0137 {
0138     d->relevance = qMax(qreal(0.0), relevance);
0139 }
0140 
0141 qreal QueryMatch::relevance() const
0142 {
0143     return d->relevance;
0144 }
0145 
0146 AbstractRunner *QueryMatch::runner() const
0147 {
0148     return d->runner.data();
0149 }
0150 
0151 void QueryMatch::setText(const QString &text)
0152 {
0153     QWriteLocker locker(&d->lock);
0154     d->text = text;
0155 }
0156 
0157 void QueryMatch::setSubtext(const QString &subtext)
0158 {
0159     QWriteLocker locker(&d->lock);
0160     d->subtext = subtext;
0161 }
0162 
0163 void QueryMatch::setData(const QVariant &data)
0164 {
0165     QWriteLocker locker(&d->lock);
0166     d->data = data;
0167 
0168     if (d->id.isEmpty() || d->idSetByData) {
0169         const QString matchId = data.toString();
0170         if (!matchId.isEmpty()) {
0171             d->setId(matchId);
0172             d->idSetByData = true;
0173         }
0174     }
0175 }
0176 
0177 void QueryMatch::setId(const QString &id)
0178 {
0179     QWriteLocker locker(&d->lock);
0180     d->setId(id);
0181 }
0182 
0183 void QueryMatch::setIcon(const QIcon &icon)
0184 {
0185     QWriteLocker locker(&d->lock);
0186     d->icon = icon;
0187 }
0188 
0189 void QueryMatch::setIconName(const QString &iconName)
0190 {
0191     QWriteLocker locker(&d->lock);
0192     d->iconName = iconName;
0193 }
0194 
0195 QVariant QueryMatch::data() const
0196 {
0197     QReadLocker locker(&d->lock);
0198     return d->data;
0199 }
0200 
0201 QString QueryMatch::text() const
0202 {
0203     QReadLocker locker(&d->lock);
0204     return d->text;
0205 }
0206 
0207 QString QueryMatch::subtext() const
0208 {
0209     QReadLocker locker(&d->lock);
0210     return d->subtext;
0211 }
0212 
0213 QIcon QueryMatch::icon() const
0214 {
0215     QReadLocker locker(&d->lock);
0216     return d->icon;
0217 }
0218 
0219 QString QueryMatch::iconName() const
0220 {
0221     QReadLocker locker(&d->lock);
0222     return d->iconName;
0223 }
0224 
0225 void QueryMatch::setUrls(const QList<QUrl> &urls)
0226 {
0227     QWriteLocker locker(&d->lock);
0228     d->urls = urls;
0229 }
0230 
0231 QList<QUrl> QueryMatch::urls() const
0232 {
0233     QReadLocker locker(&d->lock);
0234     return d->urls;
0235 }
0236 
0237 void QueryMatch::setEnabled(bool enabled)
0238 {
0239     d->enabled = enabled;
0240 }
0241 
0242 bool QueryMatch::isEnabled() const
0243 {
0244     return d->enabled && d->runner;
0245 }
0246 
0247 KRunner::Action QueryMatch::selectedAction() const
0248 {
0249     return d->selAction;
0250 }
0251 
0252 void QueryMatch::setSelectedAction(const KRunner::Action &action)
0253 {
0254     d->selAction = action;
0255 }
0256 
0257 void QueryMatch::setMultiLine(bool multiLine)
0258 {
0259     d->multiLine = multiLine;
0260 }
0261 
0262 bool QueryMatch::isMultiLine() const
0263 {
0264     return d->multiLine;
0265 }
0266 
0267 QueryMatch &QueryMatch::operator=(const QueryMatch &other)
0268 {
0269     if (d != other.d) {
0270         d = other.d;
0271     }
0272 
0273     return *this;
0274 }
0275 
0276 bool QueryMatch::operator==(const QueryMatch &other) const
0277 {
0278     return (d == other.d);
0279 }
0280 
0281 bool QueryMatch::operator!=(const QueryMatch &other) const
0282 {
0283     return (d != other.d);
0284 }
0285 
0286 void QueryMatch::setActions(const QList<KRunner::Action> &actions)
0287 {
0288     QWriteLocker locker(&d->lock);
0289     d->actions = actions;
0290 }
0291 
0292 void QueryMatch::addAction(const KRunner::Action &action)
0293 {
0294     QWriteLocker locker(&d->lock);
0295     d->actions << action;
0296 }
0297 
0298 KRunner::Actions QueryMatch::actions() const
0299 {
0300     QReadLocker locker(&d->lock);
0301     return d->actions;
0302 }
0303 
0304 QDebug operator<<(QDebug debug, const KRunner::QueryMatch &match)
0305 {
0306     QDebugStateSaver saver(debug);
0307     debug.nospace() << "QueryMatch(category: " << match.matchCategory() << " text:" << match.text() << ")";
0308     return debug;
0309 }
0310 
0311 } // KRunner namespace