1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/*
This is part of TeXworks, an environment for working with TeX documents
Copyright (C) 2010-2024 Jonathan Kew, Stefan Löffler, Charlie Sharpsteen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
For links to further information, or to contact the authors,
see <http://www.tug.org/texworks/>.
*/
#ifndef PythonScript_H
#define PythonScript_H
#include "PythonScriptInterface.h"
#include "scripting/Script.h"
#include "scripting/ScriptAPIInterface.h"
#include <QCoreApplication>
// Forward declaration taken from the Python headers to avoid having to include
// Python in this header file
struct _object;
typedef _object PyObject;
namespace Tw {
namespace Scripting {
/** \brief Class for handling python scripts */
class PythonScript : public Script
{
Q_INTERFACES(Tw::Scripting::Script)
Q_DECLARE_TR_FUNCTIONS(Tw::Scripting::ECMAScript)
public:
/** \brief Constructor
*
* Does nothing
*/
PythonScript(PythonScriptInterface * interface, const QString& fileName)
: Script(interface, fileName) { }
/** \brief Parse the script header
*
* \return \c true if successful, \c false if not (e.g. because the file
* is no valid Tw python script)
*/
bool parseHeader() override { return doParseHeader("", "", "#"); }
protected:
/** \brief Run the python script
*
* \note Every python script is run in its own interpreter.
*
* \param tw the TW interface object, exposed to the script as the TW global
*
* \return \c true on success, \c false if an error occurred
*/
bool execute(ScriptAPIInterface *tw) const override;
/** \brief Handler for attribute requests on QObjects
*
* \param o the pyQObject of which to retrieve the attribute value
* \param attr_name the name of the attribute
* \return the python value on success, \c nullptr if an error occurred
*/
static PyObject* getAttribute(PyObject * o, PyObject * attr_name);
/** \brief Handler for setting attribute values on QObjects
*
* \param o the pyQObject for which to set the attribute value
* \param attr_name the name of the attribute
* \param v the new value
* \return 0 on success, -1 if an error occurred
*/
static int setAttribute(PyObject * o, PyObject * attr_name, PyObject * v);
/** \brief Handler for calling methods of QObjects
*
* \note Calling by keywords is currently not supported
* \param o the pyQObjectMethodObject to call
* \param pyArgs python tuple of arguments
* \param kw dictionary of key-value argument pairs (not supported)
* \return the return value of the method (PyNone for void functions) on
* success, \c nullptr if an error occurred
*/
static PyObject * callMethod(PyObject * o, PyObject * pyArgs, PyObject * kw);
/** \brief Convenience function to convert a QObject to a pyQObject
*
* \param o the QObject to expose to python
* \return the pyQObject that can be used in python
*/
static PyObject * QObjectToPython(QObject * o);
/** \brief Convenience function to convert a QVariant to a python object
*
* \note QObject* instances will be converted by QObjectToPython. Empty
* variants will be converted to PyNone. QList will be converted to
* python lists. If the value can't be converted, an error is
* raised and \c nullptr is returned.
* \param v the QVariant to convert to a python value
* \return the python object on success, \c nullptr if an error occurred
*/
static PyObject * VariantToPython(const QVariant & v);
/** \brief Convenience function to convert a python object to a QVariant
*
* \note Python tuples and lists are converted to QList. pyQObject is not
* supported. If the value can't be converted, an error is raised
* and an empty QVariant is returned.
* \param o the python object to convert
* \return the QVariant
*/
static QVariant PythonToVariant(PyObject * o);
/** \brief Register Tw-specific python types
*
* Registers pyQObject and pyQObjectMethodObject for use in python.
* \param errMsg if an error occurs this variable receives a string
* describing it
* \return \c true on succes, \c false otherwise
*/
bool registerPythonTypes(QVariant & errMsg) const;
/** \brief Convenience function to convert a python object to a QString
*
* This function handles conversion of PyBytes and PyUnicode objects.
* \param obj python object to convert to a QString
* \param str QString to receive the string on success
* \return \c true on succes, \c false otherwise
*/
static bool asQString(PyObject * obj, QString & str);
};
} // namespace Scripting
} // namespace Tw
#endif // !defined(PythonScript_H)
|