File indexing completed on 2024-05-12 09:58:24
0001 /* 0002 SPDX-FileCopyrightText: 2004 Jonas Bähr <jonas.baehr@web.de> 0003 SPDX-FileCopyrightText: 2004 Shie Erlich <erlich@users.sourceforge.net> 0004 SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef EXPANDER_H 0010 #define EXPANDER_H 0011 0012 // QtCore 0013 #include <QList> 0014 #include <QString> 0015 #include <QStringList> 0016 0017 #include "tstring.h" 0018 0019 class KrPanel; 0020 class Expander; 0021 class Error; 0022 0023 typedef TagString_t<QStringList> TagString; 0024 typedef QList<TagString> TagStringList; 0025 0026 /** 0027 * This holds the information about each parameter 0028 */ 0029 class exp_parameter 0030 { 0031 public: 0032 exp_parameter() 0033 { 0034 } 0035 inline exp_parameter(QString desc, QString pre, bool ness) 0036 { 0037 _description = desc; 0038 _preset = pre; 0039 _necessary = ness; 0040 } 0041 inline QString description() const 0042 { ///< A description of the parameter 0043 return _description; 0044 } 0045 inline QString preset() const 0046 { ///< the default of the parameter 0047 return _preset; 0048 } 0049 inline bool necessary() const 0050 { ///< false if the parameter is optional 0051 return _necessary; 0052 } 0053 0054 private: 0055 QString _description; 0056 QString _preset; 0057 bool _necessary; 0058 }; 0059 0060 #define EXP_FUNC virtual TagString expFunc(const KrPanel *, const TagStringList &, const bool &, Expander &) const 0061 #define SIMPLE_EXP_FUNC virtual TagString expFunc(const KrPanel *, const QStringList &, const bool &, Expander &) const 0062 /** 0063 * Abstract baseclass for all expander-functions (which replace placeholder). 0064 * A Placeholder is an entry containing the expression, 0065 * its expanding function and Parameter. 0066 * 0067 * Not to be created on the heap 0068 */ 0069 class exp_placeholder 0070 { 0071 public: 0072 inline QString expression() const 0073 { ///< The placeholder (without '%' or panel-prefix) 0074 return _expression; 0075 } 0076 inline QString description() const 0077 { ///< A description of the placeholder 0078 return _description; 0079 } 0080 inline bool needPanel() const 0081 { ///< true if the placeholder needs a panel to operate on 0082 return _needPanel; 0083 } 0084 inline void addParameter(exp_parameter parameter) 0085 { ///< adds parameter to the placeholder 0086 _parameter.append(parameter); 0087 } 0088 inline int parameterCount() const 0089 { ///< returns the number of placeholders 0090 return _parameter.count(); 0091 } 0092 inline const exp_parameter ¶meter(int id) const 0093 { ///< returns a specific parameter 0094 return _parameter[id]; 0095 } 0096 0097 EXP_FUNC = 0; 0098 0099 protected: 0100 static void setError(Expander &exp, const Error &e); 0101 static void panelMissingError(const QString &s, Expander &exp); 0102 static QStringList splitEach(const TagString &s); 0103 static QStringList 0104 fileList(const KrPanel *const panel, const QString &type, const QString &mask, const bool omitPath, const bool useUrl, Expander &, const QString &); 0105 exp_placeholder(); 0106 exp_placeholder(const exp_placeholder &p); 0107 virtual ~exp_placeholder() 0108 { 0109 } 0110 QString _expression; 0111 QString _description; 0112 QList<exp_parameter> _parameter; 0113 bool _needPanel; 0114 }; 0115 0116 class Error 0117 { 0118 public: 0119 enum Cause { exp_C_USER, exp_C_SYNTAX, exp_C_WORLD, exp_C_ARGUMENT }; 0120 enum Severity { exp_S_OK, exp_S_WARNING, exp_S_ERROR, exp_S_FATAL }; 0121 0122 Error() 0123 : m_severity(exp_S_OK) 0124 { 0125 } 0126 Error(Severity severity, Cause cause) 0127 : m_severity(severity) 0128 , m_cause(cause) 0129 , m_description() 0130 { 0131 } 0132 Error(Severity severity, Cause cause, QString description) 0133 : m_severity(severity) 0134 , m_cause(cause) 0135 , m_description(description) 0136 { 0137 } 0138 0139 operator bool() const 0140 { 0141 return m_severity != exp_S_OK; 0142 } 0143 Cause cause() const 0144 { 0145 return m_cause; 0146 } 0147 const QString &description() const 0148 { 0149 return m_description; 0150 } 0151 0152 private: 0153 Severity m_severity; 0154 Cause m_cause; 0155 QString m_description; 0156 }; 0157 0158 /** 0159 * The Expander expands the command of an UserAction by replacing all 0160 * placeholders by their current values.@n 0161 * Each placeholder begins with a '%'-sign, followed by one char indicating 0162 * the panel, followed by a command which may have some parameter enclosed 0163 * in brackets and also ends with a '%'-sign. 0164 * Examples are %aPath% or %rBookmark("/home/jonas/src/krusader_kde3", "yes")%.@n 0165 * The panel-indicator has to be either 0166 * 'a' for the active 0167 * 'o' for the other 0168 * 'r' for the right 0169 * 'l' for the left 0170 * '_' for panel-independence. 0171 * 0172 * Currently supported are these commands can be ordered in three groups 0173 * (children are the parameter in the right order): 0174 * - Placeholders for Krusaders panel-data (panel-indicator has to be 'a', 'o', 'r' or 'l') 0175 * - @em Path is replaced by the panel's path 0176 * - @em Count is replaced by a nomber of 0177 * -# Either "All", "Files", "Dirs", "Selected" 0178 * . 0179 * - @em Filter is preplaced by the panels filter-mask (ex: "*.cpp *.h") 0180 * - @em Current is replaced by the current item or, in case of onmultiple="call_each", by each selected item. 0181 * -# If "yes", only the filename (without path) is returned 0182 * . 0183 * - @em List isreplaced by a list of 0184 * -# Either "All", "Files", "Dirs", "Selected" 0185 * -# A separator between the items (default: " " [one space]) 0186 * -# If "yes", only the filename (without path) is returned 0187 * -# (for all but "Selected") a filter-mask (default: "*") 0188 * . 0189 * . 0190 * - Access to panel-dependent, krusader-internal, parameter-needed functions 0191 * (panel-indicator has to be 'a', 'o', 'r' or 'l') 0192 * - @em Select manipulates the selection of the panel 0193 * -# A filter-mask (necessary) 0194 * -# Either "Add", "Remove", "Set" (default) 0195 * . 0196 * - @em Bookmark manipulates the selection of the panel 0197 * -# A path or URL (necessary) 0198 * -# If "yes", the location is opened in a new tab 0199 * . 0200 * . 0201 * - Access to panel-independent, krusader-internal, parameter-needed functions 0202 * (panel-indicator doesn't matter but should be set to '_') 0203 * - @em Ask displays a lineedit and is replaced by its return 0204 * -# The question (necessary) 0205 * -# A default answer 0206 * -# A cation for the popup 0207 * . 0208 * - @em Clipboard manipulates the system-wide clipboard 0209 * -# The string copied to clip (ex: "%aCurrent%") (necessary) 0210 * -# A separator. If set, parameter1 is append with this to the current clipboard content 0211 * . 0212 * . 0213 * . 0214 * Since all placeholders are expanded in the order they appear in the command, 0215 * little one-line-scripts are possible 0216 */ 0217 class Expander 0218 { 0219 public: 0220 inline static int placeholderCount() 0221 { ///< returns the number of placeholders 0222 return _placeholder().count(); 0223 } 0224 inline static const exp_placeholder *placeholder(int id) 0225 { 0226 return _placeholder()[id]; 0227 } 0228 0229 /** 0230 * This expands a whole commandline 0231 * 0232 * @param stringToExpand the commandline with the placeholder 0233 * @param useUrl true iff the path's should be expanded to an URL instead of an local path 0234 * @return a list of all commands 0235 */ 0236 void expand(const QString &stringToExpand, bool useUrl); 0237 0238 /** 0239 * Returns the list of all commands to be executed, provided that #expand was called 0240 * before, and there was no error (see #error). 0241 * 0242 * @return The list of commands to be executed 0243 */ 0244 const QStringList &result() const 0245 { 0246 assert(!error()); 0247 return resultList; 0248 } 0249 0250 /** 0251 * Returns the error object of this Expander. You can test whether there was 0252 * any error by 0253 * \code 0254 * if(exp.error()) 0255 * error behaviour... 0256 * else 0257 * no error... 0258 * \endcode 0259 * 0260 * @return The error object 0261 */ 0262 const Error &error() const 0263 { 0264 return _err; 0265 } 0266 0267 protected: 0268 /** 0269 * This expands a whole commandline by calling for each Placeholder the corresponding expander 0270 * 0271 * @param stringToExpand the commandline with the placeholder 0272 * @param useUrl true if the path's should be expanded to an URL instead of an local path 0273 * @return the expanded commanline for the current item 0274 */ 0275 TagString expandCurrent(const QString &stringToExpand, bool useUrl); 0276 /** 0277 * This function searches for "\@EACH"-marks to split the string in a list for each %_Each%-item 0278 * 0279 * @param stringToSplit the string which should be split 0280 * @return the split list 0281 */ 0282 static QStringList splitEach(TagString stringToSplit); 0283 /** 0284 * @param panelIndicator either '_' for panel-independent placeholders, 'a', 'o', 'r', or 'l' for the active, other (inactive), right or left panel 0285 * @param pl placeholder 0286 * @param exp expander 0287 * @return a pointer to the right panel or NULL if no panel is needed. 0288 */ 0289 static KrPanel *getPanel(const char panelIndicator, const exp_placeholder *, Expander &); 0290 /** 0291 * This splits the parameter-string into separate parameter and expands each 0292 * @param exp the string holding all parameter 0293 * @param useUrl true if the path's should be expanded to an URL instead of an local path 0294 * @return a list of all parameter 0295 */ 0296 TagStringList separateParameter(QString *const exp, bool useUrl); 0297 /** 0298 * This finds the end of a placeholder, taking care of the parameter 0299 * @return the position where the placeholder ends 0300 */ 0301 int findEnd(const QString &str, int start); 0302 0303 void setError(const Error &e) 0304 { 0305 _err = e; 0306 } 0307 friend class exp_placeholder; 0308 0309 private: 0310 static QList<const exp_placeholder *> &_placeholder(); 0311 Error _err; 0312 QStringList resultList; 0313 }; 0314 0315 #endif // ifndef EXPANDER_H