File indexing completed on 2024-03-24 15:37:23
0001 /*************************************************************************** 0002 * action.h 0003 * This file is part of the KDE project 0004 * copyright (C)2004-2007 by Sebastian Sauer (mail@dipe.org) 0005 * 0006 * This program is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * You should have received a copy of the GNU Library General Public License 0015 * along with this program; see the file COPYING. If not, write to 0016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 ***************************************************************************/ 0019 0020 #ifndef KROSS_ACTION_H 0021 #define KROSS_ACTION_H 0022 0023 #include <QVariant> 0024 #include <QObject> 0025 #include <QDir> 0026 #include <QUrl> 0027 #include <QAction> 0028 #include <QDomAttr> 0029 #include <QScriptable> 0030 0031 #include "errorinterface.h" 0032 #include "childreninterface.h" 0033 0034 namespace Kross 0035 { 0036 0037 class Script; 0038 0039 /** 0040 * The Action class is an abstract container to deal with scripts 0041 * like a single standalone script file. Each action holds a reference 0042 * to the matching @a Kross::Interpreter created @a Kross::Script 0043 * instance. 0044 * 0045 * The \a Manager takes care of handling the \a Action instances 0046 * application by providing access to \a ActionCollection containers 0047 * for those \a Action instances. 0048 * 0049 * Once you've such a Action instance you're able to perform actions 0050 * with it like executing scripting code. 0051 * 0052 * Following sample shows "Hello World." executed with the python 0053 * interpreter: 0054 * \code 0055 * # Create a new Kross::Action instance. 0056 * Kross::Action* action = new Kross::Action(0,"MyFirstScript"); 0057 * # Set the interpreter we like to use. This could be e.g. "python" or "ruby". 0058 * action->setInterpreter("python"); 0059 * # Set the scripting code. 0060 * action->setCode("print \"Hello World.\""); 0061 * # Execute the scripting code. 0062 * action->trigger(); 0063 * \endcode 0064 * 0065 * Following sample demonstrates how to execute an external python script 0066 * file. The script file itself is named "mytest.py" and contains: 0067 * \code 0068 * # this function got called from within C++ 0069 * def myfunction(args): 0070 * print "Arguments are: %s" % args 0071 * # Import the published QObject's 0072 * import MyFirstQObject, MySecondQObject 0073 * # Call a slot MyFirstQObject provides. 0074 * MyFirstQObject.someSlot("Some string") 0075 * # Set a property MySecondQObject provides. 0076 * MySecondQObject.someProperty = "Other string" 0077 * \endcode 0078 * Then you are able to load the script file, publish QObject instances 0079 * and let the script do whatever it likes to do: 0080 * \code 0081 * # Publish a QObject instance for all Kross::Action instances. 0082 * Kross::Manager::self().addObject(myqobject1, "MyFirstQObject") 0083 * # Create a new Kross::Action instance. 0084 * Kross::Action* action = new Kross::Action(0,"MySecondScript"); 0085 * # Publish a QObject instance only for the Kross::Action instance. 0086 * action->addObject(myqobject2, "MySecondQObject"); 0087 * # Set the script file we like to execute. 0088 * action->setFile("/home/myuser/mytest.py"); 0089 * # Execute the script file. 0090 * action->trigger(); 0091 * # Call the "myfunction" defined in the "mytest.py" python script. 0092 * QVariant result = action->callFunction("myfunction", QVariantList()<<"Arg"); 0093 * \endcode 0094 */ 0095 class KROSSCORE_EXPORT Action 0096 : public QAction 0097 , public QScriptable 0098 , public ChildrenInterface 0099 , public ErrorInterface 0100 { 0101 Q_OBJECT 0102 0103 public: 0104 0105 /** 0106 * Constructor. 0107 * 0108 * \param parent The parent QObject this \a Action is a child of. 0109 * \param name The unique name this Action has. It's used 0110 * e.g. at the \a Manager to identify the Action. The 0111 * name is accessible via \a QObject::objectName . 0112 * \deprecated since 4.3: pass search path to fromDomElement() and toDomElement() 0113 */ 0114 Action(QObject *parent, const QString &name, const QDir &packagepath = QDir()); //BIC may be removed in favour of the next c'tor 0115 0116 /** 0117 * Constructor. 0118 * 0119 * \param parent The parent QObject this \a Action is a child of. 0120 * \param url The URL should point to a valid scripting file. 0121 * This \a Action will be filled with the content of the 0122 * file (e.g. the file is read and \a code should return 0123 * its content and it's also tried to determine the 0124 * \a interpreter ). Remember to use QUrl c'tor explicitly. 0125 * The name will be set to url.path() 0126 */ 0127 Action(QObject *parent, const QUrl &url); 0128 0129 /** 0130 * Destructor. 0131 */ 0132 ~Action() override; 0133 0134 /** 0135 * Method to read settings from the QDomElement \p element that 0136 * contains details about e.g. the displayed text, the file to 0137 * execute or the used interpreter. 0138 * \todo BIC merge 0139 */ 0140 void fromDomElement(const QDomElement &element); 0141 0142 /** 0143 * Method to read settings from the QDomElement \p element that 0144 * contains details about e.g. the displayed text, the file to 0145 * execute or the used interpreter. 0146 * 0147 * \param searchPath List of directories where to search the script if its path is relative 0148 * First item is given the highest priority. 0149 */ 0150 void fromDomElement(const QDomElement &element, const QStringList &searchPath/* = QStringList()*/); 0151 0152 /** 0153 * \return a QDomElement that contains the settings like e.g. the 0154 * displayed text, the file to execute or the used interpreter 0155 * of this \a Action instance. 0156 */ 0157 QDomElement toDomElement() const; 0158 0159 /** 0160 * \return a QDomElement that contains the settings like e.g. the 0161 * displayed text, the file to execute or the used interpreter 0162 * of this \a Action instance. 0163 * \param searchPath if given, find the closest directory containing the scriptfile 0164 * and write relative filepath 0165 */ 0166 QDomElement toDomElement(const QStringList &searchPath/* = QStringList()*/) const; 0167 0168 /** 0169 * Initialize the \a Script instance. 0170 * 0171 * Normally there is no need to call this function directly because 0172 * if will be called internally if needed (e.g. on \a execute ). 0173 * 0174 * \return true if the initialization was successful else 0175 * false is returned. 0176 */ 0177 bool initialize(); 0178 0179 /** 0180 * Finalize the \a Script instance and frees any cached or still 0181 * running executions. Normally there is no need to call this 0182 * function directly because the \a Action will take care 0183 * of calling it if needed. 0184 */ 0185 void finalize(); 0186 0187 /** 0188 * \return true if the action is finalized, which means the 0189 * action is currently not running. 0190 */ 0191 bool isFinalized() const; 0192 0193 /** 0194 * \return the \a Kross::Script implementation used by the scripting 0195 * backend. This returns NULL until the action got triggered or if 0196 * there was an error before that. 0197 * 0198 * Normally it shouldn't be necessary to deal with the scripting backend 0199 * depending instance of a \a Kross::Script implementation since this 0200 * \a Action class already decorates all the things needed. It 0201 * may however be useful to provide additional interpreter dependent 0202 * functionality. 0203 */ 0204 Script *script() const; 0205 0206 public Q_SLOTS: 0207 0208 /** 0209 * \return the objectName for this Action. 0210 */ 0211 QString name() const; 0212 0213 /** 0214 * \return the version number this Action has. 0215 * Per default 0 is returned. 0216 */ 0217 int version() const; 0218 0219 /** 0220 * \return the optional description for this Action. 0221 */ 0222 QString description() const; 0223 0224 /** 0225 * Set the optional description for this Action. 0226 */ 0227 void setDescription(const QString &description); 0228 0229 /** 0230 * Return the name of the icon. 0231 */ 0232 QString iconName() const; 0233 0234 /** 0235 * Set the name of the icon to \p iconname . 0236 */ 0237 void setIconName(const QString &iconname); 0238 0239 /** 0240 * Return true if this Action is enabled else false is returned. 0241 */ 0242 bool isEnabled() const; 0243 0244 /** 0245 * Set the enable state of this Action to \p enabled . 0246 */ 0247 void setEnabled(bool enabled); 0248 0249 /** 0250 * \return the script file that should be executed. 0251 */ 0252 QString file() const; 0253 0254 /** 0255 * Set the script file that should be executed. 0256 */ 0257 bool setFile(const QString &scriptfile); 0258 0259 /** 0260 * \return the scriptcode this Action holds. 0261 */ 0262 QByteArray code() const; 0263 0264 /** 0265 * Set the scriptcode \p code this Action should execute. 0266 */ 0267 void setCode(const QByteArray &code); 0268 0269 /** 0270 * \return the name of the interpreter. Could be for 0271 * example "python" or "ruby". 0272 */ 0273 QString interpreter() const; 0274 0275 /** 0276 * Set the name of the interpreter (javascript, python or ruby). 0277 */ 0278 void setInterpreter(const QString &interpretername); 0279 0280 /** 0281 * \return the current path the script is running in or 0282 * an empty string if there is no current path defined. 0283 */ 0284 QString currentPath() const; 0285 0286 /** 0287 * Add a QObject instance to the action. This instance will 0288 * be published to scripts. 0289 */ 0290 void addQObject(QObject *obj, const QString &name = QString()); 0291 0292 /** 0293 * \return the QObject with the object name \p name . 0294 */ 0295 QObject *qobject(const QString &name) const; 0296 0297 /** 0298 * \return a list of QObject object names. 0299 */ 0300 QStringList qobjectNames() const; 0301 0302 /** 0303 * \return a map of options this \a Action defines. 0304 * The options are returned call-by-ref, so you are able to 0305 * manipulate them. 0306 */ 0307 QVariantMap options() const; 0308 0309 /** 0310 * \return the value of the option defined with \p name . 0311 * If there doesn't exist an option with such a name, 0312 * the \p defaultvalue is returned. 0313 */ 0314 QVariant option(const QString &name, const QVariant &defaultvalue = QVariant()); 0315 0316 /** 0317 * Set the \a Interpreter::Option value. 0318 */ 0319 bool setOption(const QString &name, const QVariant &value); 0320 0321 /** 0322 * \return the list of functionnames. 0323 */ 0324 QStringList functionNames(); 0325 0326 /** 0327 * Call a function in the script. 0328 * 0329 * \param name The name of the function which should be called. 0330 * \param args The optional list of arguments. 0331 */ 0332 QVariant callFunction(const QString &name, const QVariantList &args = QVariantList()); 0333 0334 /** 0335 * Evaluate some scripting code. 0336 * 0337 * Example how this can be used: 0338 * \code 0339 * Kross::Action* a = new Kross::Action(0, "MyScript"); 0340 * a->setInterpreter("python"); 0341 * a->setCode("def myFunc(x): return x"); 0342 * a->trigger(); 0343 * int three = a->evaluate("1+2").toInt(); // returns 3 0344 * int nine = a->evaluate("myFunc(9)").toInt(); // returns 9 0345 * \endcode 0346 * 0347 * \param code The scripting code to evaluate. 0348 * \return The return value of the evaluation. 0349 */ 0350 QVariant evaluate(const QByteArray &code); 0351 0352 Q_SIGNALS: 0353 0354 /** 0355 * This signal is emitted if the content of the Action 0356 * was changed. The \a ActionCollection instances this Action 0357 * is a child of are connected with this signal to fire up 0358 * their own updated signal if an Action of them was updated. 0359 */ 0360 void updated(); 0361 0362 /// This signal is emitted when the data of the Action is changed 0363 void dataChanged(Action *); 0364 0365 /** 0366 * This signal is emitted before the script got executed. 0367 */ 0368 void started(Kross::Action *); 0369 0370 /** 0371 * This signal is emitted after the script got executed. 0372 */ 0373 void finished(Kross::Action *); 0374 0375 /** 0376 * This signal is emitted once a script finalized. 0377 */ 0378 void finalized(Kross::Action *); 0379 0380 private Q_SLOTS: 0381 0382 /** 0383 * This private slot is connected with the \a QAction::triggered 0384 * signal. To execute the script just emit that signal and this 0385 * slot tries to execute the script. 0386 */ 0387 void slotTriggered(); 0388 0389 private: 0390 /// \internal d-pointer class. 0391 class Private; 0392 /// \internal d-pointer instance. 0393 Private *const d; 0394 }; 0395 0396 } 0397 0398 #endif 0399