File indexing completed on 2024-12-01 09:55:31
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef __ktrader_parse_tree_h__ 0009 #define __ktrader_parse_tree_h__ 0010 0011 #include <QMap> 0012 #include <QString> 0013 #include <QStringList> 0014 0015 #include <kplugininfo.h> 0016 #include <kservice.h> 0017 0018 namespace KTraderParse 0019 { 0020 class ParseTreeBase; 0021 0022 /** 0023 * @internal 0024 * @return 0 => Does not match 0025 * 1 => Does match 0026 * <0 => Error 0027 */ 0028 int matchConstraint(const ParseTreeBase *_tree, const KService::Ptr &, const KService::List &); 0029 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90) 0030 int matchConstraintPlugin(const ParseTreeBase *_tree, const KPluginInfo &_info, const KPluginInfo::List &_list); 0031 #endif 0032 0033 /** 0034 * @internal 0035 */ 0036 struct KSERVICE_EXPORT PreferencesMaxima { 0037 PreferencesMaxima() 0038 : iMax(0) 0039 , iMin(0) 0040 , fMax(0) 0041 , fMin(0) 0042 { 0043 } 0044 0045 enum Type { PM_ERROR, PM_INVALID_INT, PM_INVALID_DOUBLE, PM_DOUBLE, PM_INT }; 0046 0047 Type type; 0048 int iMax; 0049 int iMin; 0050 double fMax; 0051 double fMin; 0052 }; 0053 0054 /** 0055 * @internal 0056 */ 0057 class ParseContext 0058 { 0059 public: 0060 /** 0061 * This is NOT a copy constructor. 0062 */ 0063 explicit ParseContext(const ParseContext *_ctx) 0064 : service(_ctx->service) 0065 , maxima(_ctx->maxima) 0066 , offers(_ctx->offers) 0067 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90) 0068 , info(_ctx->info) 0069 , pluginOffers(_ctx->pluginOffers) 0070 #endif 0071 { 0072 } 0073 ParseContext(const KService::Ptr &_service, const KService::List &_offers, QMap<QString, PreferencesMaxima> &_m) 0074 : service(_service) 0075 , maxima(_m) 0076 , offers(_offers) 0077 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90) 0078 , info(KPluginInfo()) 0079 , pluginOffers(KPluginInfo::List()) 0080 #endif 0081 { 0082 } 0083 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90) 0084 ParseContext(const KPluginInfo &_info, const KPluginInfo::List &_offers, QMap<QString, PreferencesMaxima> &_m) 0085 : service(nullptr) 0086 , maxima(_m) 0087 , offers(KService::List()) 0088 , info(_info) 0089 , pluginOffers(_offers) 0090 { 0091 } 0092 #endif 0093 0094 bool initMaxima(const QString &_prop); 0095 0096 QVariant property(const QString &_key) const; 0097 0098 enum Type { 0099 T_STRING = 1, 0100 T_DOUBLE = 2, 0101 T_NUM = 3, 0102 T_BOOL = 4, 0103 T_STR_SEQ = 5, 0104 T_SEQ = 6, 0105 }; 0106 0107 QString str; 0108 int i; 0109 double f; 0110 bool b; 0111 QList<QVariant> seq; 0112 QStringList strSeq; 0113 Type type; 0114 0115 KService::Ptr service; 0116 0117 QMap<QString, PreferencesMaxima> &maxima; 0118 KService::List offers; 0119 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90) 0120 KPluginInfo info; 0121 KPluginInfo::List pluginOffers; 0122 #endif 0123 }; 0124 0125 /** 0126 * @internal 0127 */ 0128 class ParseTreeBase : public QSharedData 0129 { 0130 public: 0131 typedef QExplicitlySharedDataPointer<ParseTreeBase> Ptr; 0132 ParseTreeBase() 0133 { 0134 } 0135 virtual ~ParseTreeBase(); 0136 0137 virtual bool eval(ParseContext *_context) const = 0; 0138 }; 0139 0140 ParseTreeBase::Ptr parseConstraints(const QString &_constr); 0141 0142 /** 0143 * @internal 0144 */ 0145 class ParseTreeOR : public ParseTreeBase 0146 { 0147 public: 0148 ParseTreeOR(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2) 0149 : m_pLeft(_ptr1) 0150 , m_pRight(_ptr2) 0151 { 0152 } 0153 0154 bool eval(ParseContext *_context) const override; 0155 0156 protected: 0157 ParseTreeBase::Ptr m_pLeft; 0158 ParseTreeBase::Ptr m_pRight; 0159 }; 0160 0161 /** 0162 * @internal 0163 */ 0164 class ParseTreeAND : public ParseTreeBase 0165 { 0166 public: 0167 ParseTreeAND(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2) 0168 : m_pLeft(_ptr1) 0169 , m_pRight(_ptr2) 0170 { 0171 } 0172 0173 bool eval(ParseContext *_context) const override; 0174 0175 protected: 0176 ParseTreeBase::Ptr m_pLeft; 0177 ParseTreeBase::Ptr m_pRight; 0178 }; 0179 0180 /** 0181 * @internal 0182 */ 0183 class ParseTreeCMP : public ParseTreeBase 0184 { 0185 public: 0186 ParseTreeCMP(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2, int _i) 0187 : m_pLeft(_ptr1) 0188 , m_pRight(_ptr2) 0189 , m_cmd(_i) 0190 { 0191 } 0192 0193 bool eval(ParseContext *_context) const override; 0194 0195 protected: 0196 ParseTreeBase::Ptr m_pLeft; 0197 ParseTreeBase::Ptr m_pRight; 0198 int m_cmd; 0199 }; 0200 0201 /** 0202 * @internal 0203 */ 0204 class ParseTreeIN : public ParseTreeBase 0205 { 0206 public: 0207 ParseTreeIN(ParseTreeBase *ptr1, ParseTreeBase *ptr2, Qt::CaseSensitivity cs, bool substring = false) 0208 : m_pLeft(ptr1) 0209 , m_pRight(ptr2) 0210 , m_cs(cs) 0211 , m_substring(substring) 0212 { 0213 } 0214 0215 bool eval(ParseContext *_context) const override; 0216 0217 protected: 0218 ParseTreeBase::Ptr m_pLeft; 0219 ParseTreeBase::Ptr m_pRight; 0220 Qt::CaseSensitivity m_cs; 0221 bool m_substring; 0222 }; 0223 0224 /** 0225 * @internal 0226 */ 0227 class ParseTreeMATCH : public ParseTreeBase 0228 { 0229 public: 0230 ParseTreeMATCH(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2, Qt::CaseSensitivity cs) 0231 : m_pLeft(_ptr1) 0232 , m_pRight(_ptr2) 0233 , m_cs(cs) 0234 { 0235 } 0236 0237 bool eval(ParseContext *_context) const override; 0238 0239 protected: 0240 ParseTreeBase::Ptr m_pLeft; 0241 ParseTreeBase::Ptr m_pRight; 0242 Qt::CaseSensitivity m_cs; 0243 }; 0244 0245 /** 0246 * @internal 0247 * 0248 * A sub-sequence match is like a sub-string match except the characters 0249 * do not have to be contiguous. For example 'ct' is a sub-sequence of 'cat' 0250 * but not a sub-string. 'at' is both a sub-string and sub-sequence of 'cat'. 0251 * All sub-strings are sub-sequences. 0252 * 0253 * This is useful if you want to support a fuzzier search, say for instance 0254 * you are searching for `LibreOffice 6.0 Writer`, after typing `libre` you 0255 * see a list of all the LibreOffice apps, to narrow down that list you only 0256 * need to add `write` (so the search term is `librewrite`) instead of typing 0257 * out the entire app name until a distinguishing letter is reached. 0258 * It's also useful to allow the user to forget to type some characters. 0259 */ 0260 class ParseTreeSubsequenceMATCH : public ParseTreeBase 0261 { 0262 public: 0263 ParseTreeSubsequenceMATCH(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2, Qt::CaseSensitivity cs) 0264 : m_pLeft(_ptr1) 0265 , m_pRight(_ptr2) 0266 , m_cs(cs) 0267 { 0268 } 0269 0270 bool eval(ParseContext *_context) const override; 0271 0272 protected: 0273 ParseTreeBase::Ptr m_pLeft; 0274 ParseTreeBase::Ptr m_pRight; 0275 Qt::CaseSensitivity m_cs; 0276 }; 0277 0278 /** 0279 * @internal 0280 */ 0281 class ParseTreeCALC : public ParseTreeBase 0282 { 0283 public: 0284 ParseTreeCALC(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2, int _i) 0285 : m_pLeft(_ptr1) 0286 , m_pRight(_ptr2) 0287 , m_cmd(_i) 0288 { 0289 } 0290 0291 bool eval(ParseContext *_context) const override; 0292 0293 protected: 0294 ParseTreeBase::Ptr m_pLeft; 0295 ParseTreeBase::Ptr m_pRight; 0296 int m_cmd; 0297 }; 0298 0299 /** 0300 * @internal 0301 */ 0302 class ParseTreeBRACKETS : public ParseTreeBase 0303 { 0304 public: 0305 explicit ParseTreeBRACKETS(ParseTreeBase *_ptr) 0306 : m_pLeft(_ptr) 0307 { 0308 } 0309 0310 bool eval(ParseContext *_context) const override; 0311 0312 protected: 0313 ParseTreeBase::Ptr m_pLeft; 0314 }; 0315 0316 /** 0317 * @internal 0318 */ 0319 class ParseTreeNOT : public ParseTreeBase 0320 { 0321 public: 0322 explicit ParseTreeNOT(ParseTreeBase *_ptr) 0323 : m_pLeft(_ptr) 0324 { 0325 } 0326 0327 bool eval(ParseContext *_context) const override; 0328 0329 protected: 0330 ParseTreeBase::Ptr m_pLeft; 0331 }; 0332 0333 /** 0334 * @internal 0335 */ 0336 class ParseTreeEXIST : public ParseTreeBase 0337 { 0338 public: 0339 explicit ParseTreeEXIST(const char *_id) 0340 : m_id(QString::fromUtf8(_id)) 0341 { 0342 } 0343 0344 bool eval(ParseContext *_context) const override; 0345 0346 protected: 0347 QString m_id; 0348 }; 0349 0350 /** 0351 * @internal 0352 */ 0353 class ParseTreeID : public ParseTreeBase 0354 { 0355 public: 0356 explicit ParseTreeID(const char *arg) 0357 : m_str(QString::fromUtf8(arg)) 0358 { 0359 } 0360 0361 bool eval(ParseContext *_context) const override; 0362 0363 protected: 0364 QString m_str; 0365 }; 0366 0367 /** 0368 * @internal 0369 */ 0370 class ParseTreeSTRING : public ParseTreeBase 0371 { 0372 public: 0373 explicit ParseTreeSTRING(const char *arg) 0374 : m_str(QString::fromUtf8(arg)) 0375 { 0376 } 0377 0378 bool eval(ParseContext *_context) const override; 0379 0380 protected: 0381 QString m_str; 0382 }; 0383 0384 /** 0385 * @internal 0386 */ 0387 class ParseTreeNUM : public ParseTreeBase 0388 { 0389 public: 0390 explicit ParseTreeNUM(int arg) 0391 { 0392 m_int = arg; 0393 } 0394 0395 bool eval(ParseContext *_context) const override; 0396 0397 protected: 0398 int m_int; 0399 }; 0400 0401 /** 0402 * @internal 0403 */ 0404 class ParseTreeDOUBLE : public ParseTreeBase 0405 { 0406 public: 0407 explicit ParseTreeDOUBLE(double arg) 0408 { 0409 m_double = arg; 0410 } 0411 0412 bool eval(ParseContext *_context) const override; 0413 0414 protected: 0415 double m_double; 0416 }; 0417 0418 /** 0419 * @internal 0420 */ 0421 class ParseTreeBOOL : public ParseTreeBase 0422 { 0423 public: 0424 explicit ParseTreeBOOL(bool arg) 0425 { 0426 m_bool = arg; 0427 } 0428 0429 bool eval(ParseContext *_context) const override; 0430 0431 protected: 0432 bool m_bool; 0433 }; 0434 0435 /** 0436 * @internal 0437 */ 0438 class ParseTreeMAX2 : public ParseTreeBase 0439 { 0440 public: 0441 explicit ParseTreeMAX2(const char *_id) 0442 : m_strId(QString::fromUtf8(_id)) 0443 { 0444 } 0445 0446 bool eval(ParseContext *_context) const override; 0447 0448 protected: 0449 QString m_strId; 0450 }; 0451 0452 /** 0453 * @internal 0454 */ 0455 class ParseTreeMIN2 : public ParseTreeBase 0456 { 0457 public: 0458 explicit ParseTreeMIN2(const char *_id) 0459 : m_strId(QString::fromUtf8(_id)) 0460 { 0461 } 0462 0463 bool eval(ParseContext *_context) const override; 0464 0465 protected: 0466 QString m_strId; 0467 }; 0468 0469 } 0470 0471 #endif