summaryrefslogtreecommitdiff
path: root/src/fqterm/fqterm_python.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/fqterm/fqterm_python.cpp')
-rw-r--r--src/fqterm/fqterm_python.cpp826
1 files changed, 826 insertions, 0 deletions
diff --git a/src/fqterm/fqterm_python.cpp b/src/fqterm/fqterm_python.cpp
new file mode 100644
index 0000000..68b9385
--- /dev/null
+++ b/src/fqterm/fqterm_python.cpp
@@ -0,0 +1,826 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+
+
+#include <QCustomEvent>
+#include <QTextStream>
+#include <QApplication>
+#include <QDir>
+#include <QFile>
+#include <QByteArray>
+#include <QMutex>
+#include <QThread>
+#include "fqterm.h"
+#ifdef HAVE_PYTHON
+#include <Python.h>
+#endif
+class SleeperThread : public QThread
+{
+public:
+ static void msleep(unsigned long msecs)
+ {
+ QThread::msleep(msecs);
+ }
+};
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_PYTHON
+
+#include "fqterm_window.h"
+#include "fqterm_buffer.h"
+#include "fqterm_text_line.h"
+#include "fqterm_param.h"
+#include "fqterm_session.h"
+#include "fqterm_python.h"
+#include "fqterm_path.h"
+#include "common.h"
+namespace FQTerm {
+
+/* **************************************************************************
+ *
+ * Pythons Embedding
+ *
+ * ***************************************************************************/
+
+QString getException() {
+ PyObject *pType = NULL, *pValue = NULL, *pTb = NULL, *pName, *pTraceback;
+
+ PyErr_Fetch(&pType, &pValue, &pTb);
+
+ pName = PyString_FromString("traceback");
+ pTraceback = PyImport_Import(pName);
+ Py_DECREF(pName);
+
+ if (pTraceback == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ pName = PyString_FromString("format_exception");
+ PyObject *pRes = PyObject_CallMethodObjArgs(pTraceback, pName, pType, pValue,
+ pTb, NULL);
+ Py_DECREF(pName);
+
+ Py_DECREF(pTraceback);
+
+ Py_XDECREF(pType);
+ Py_XDECREF(pValue);
+ Py_XDECREF(pTb);
+
+ if (pRes == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ pName = PyString_FromString("string");
+ PyObject *pString = PyImport_Import(pName);
+ Py_DECREF(pName);
+
+ if (pString == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ pName = PyString_FromString("join");
+ PyObject *pErr = PyObject_CallMethodObjArgs(pString, pName, pRes, NULL);
+ Py_DECREF(pName);
+
+ Py_DECREF(pString);
+ Py_DECREF(pRes);
+
+ if (pErr == NULL) {
+ return "General Error in Python Callback";
+ }
+
+ QString str(PyString_AsString(pErr));
+ Py_DECREF(pErr);
+
+ return str;
+}
+
+QString getErrOutputFile(FQTermWindow *lp) {
+ // file name
+ QString str2;
+ str2.setNum(long(lp));
+ str2 += ".err";
+ // path
+ return getPath(USER_CONFIG) + str2;
+}
+
+// copy current artcle for back compatible use only
+// for new coder please use getArticle
+static PyObject *fqterm_copyArticle(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ FQTermWindow *termWindow_ = (FQTermWindow*)lp;
+
+ QStringList strList;
+ QString strArticle;
+ QReadWriteLock& bufferLock = termWindow_->getSession()->getBufferLock();
+ QReadLocker locker(&bufferLock);
+ while (1) {
+ // check it there is duplicated string
+ // it starts from the end in the range of one screen height
+ // so this is a non-greedy match
+ QString strTemp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(0)->getAllPlainText(strTemp);
+ strTemp = strTemp.trimmed();
+ int i = 0;
+ int start = 0;
+ for (QStringList::Iterator it = strList.end();
+ it != strList.begin() && i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; // not exceeeding the last screen
+ --it, i++) {
+ if (*it != strTemp) {
+ continue;
+ }
+ QStringList::Iterator it2 = it;
+ bool dup = true;
+ // match more to see if its duplicated
+ for (int j = 0; j <= i; j++, it2++) {
+ QString str1;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(j)->getAllPlainText(str1);
+ if (*it2 != str1.trimmed()) {
+ dup = false;
+ break;
+ }
+ }
+ if (dup) {
+ // set the start point
+ start = i + 1;
+ break;
+ }
+ }
+ // add new lines
+ for (i = start; i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; i++) {
+ QString tmp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(i)->getAllPlainText(tmp);
+ strList += tmp.trimmed();
+ }
+
+ // the end of article
+ QString testEnd;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(termWindow_->getSession()->getBuffer()->getNumRows() - 1)->getAllPlainText(testEnd);
+ if (testEnd.indexOf("%") == -1) {
+ break;
+ }
+ // continue
+ termWindow_->writeString_ts(" ");
+
+ // TODO: fixme
+ if (!termWindow_->getSession()->getWaitCondition().wait(&bufferLock, 10000)) {
+ // // timeout
+ break;
+ }
+ }
+#if defined(_OS_WIN32_) || defined(Q_OS_WIN32)
+ strArticle = strList.join("\r\n");
+#else
+ strArticle = strList.join("\n");
+#endif
+
+ PyObject *py_text = PyString_FromString(strArticle.toUtf8());
+
+ Py_INCREF(py_text);
+ return py_text;
+}
+
+static PyObject *fqterm_getArticle(PyObject *, PyObject *args) {
+ long lp;
+ int timeout;
+ int succeed = 1;
+
+ if (!PyArg_ParseTuple(args, "li", &lp, &timeout)) {
+ return NULL;
+ }
+ FQTermWindow *termWindow_ = (FQTermWindow*)lp;
+
+ QStringList strList;
+ QString strArticle;
+ QReadWriteLock& bufferLock = termWindow_->getSession()->getBufferLock();
+ while (!bufferLock.tryLockForRead()) {}
+ while (1) {
+ // check it there is duplicated string
+ // it starts from the end in the range of one screen height
+ // so this is a non-greedy match
+ QString strTemp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(0)->getAllPlainText(strTemp);
+ strTemp = strTemp.trimmed();
+
+ int i = 0;
+ int start = 0;
+ for (QStringList::Iterator it = strList.end();
+ it != strList.begin() && i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; // not exceeeding the last screen
+ --it, i++) {
+ if (it == strList.end() || *it != strTemp) {
+ continue;
+ }
+ QStringList::Iterator it2 = it;
+ bool dup = true;
+ // match more to see if its duplicated
+ for (int j = 0; j <= i && it2 != strList.end(); j++, it2++) {
+ QString str1;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(j)->getAllPlainText(str1);
+ if (*it2 != str1.trimmed()) {
+ dup = false;
+ break;
+ }
+ }
+ if (dup) {
+ // set the start point
+ start = i + 1;
+ break;
+ }
+ }
+ // add new lines
+ for (i = start; i < termWindow_->getSession()->getBuffer()->getNumRows() - 1; i++) {
+ QString tmp;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(i)->getAllPlainText(tmp);
+ strList += tmp.trimmed();
+ }
+
+ // the end of article
+ QString testEnd;
+ termWindow_->getSession()->getBuffer()->getTextLineInTerm(termWindow_->getSession()->getBuffer()->getNumRows() - 1)->getAllPlainText(testEnd);
+ if (testEnd.indexOf("%") == -1) {
+ break;
+ }
+ // continue
+ termWindow_->writeString_ts(" ");
+
+ // TODO: fixme
+ if (!termWindow_->getSession()->getWaitCondition().wait(&bufferLock, timeout)) { // timeout
+ succeed = 0;
+ break;
+ }
+ }
+ bufferLock.unlock();
+ if (succeed)
+ strArticle = strList.join(OS_NEW_LINE);
+
+ PyObject *py_res = Py_BuildValue("si", (const char*)strArticle.toUtf8().data(),
+ succeed);
+
+ Py_INCREF(py_res);
+
+ return py_res;
+
+}
+
+static PyObject *fqterm_formatError(PyObject *, PyObject *args) {
+ long lp;
+
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ QString strErr;
+ QString filename = getErrOutputFile((FQTermWindow*)lp);
+
+ QDir d;
+ if (d.exists(filename)) {
+ QFile file(filename);
+ file.open(QIODevice::ReadOnly);
+ QTextStream is(&file);
+ while (!is.atEnd()) {
+ strErr += is.readLine(); // line of text excluding '\n'
+ strErr += '\n';
+ }
+ file.close();
+ d.remove(filename);
+ }
+
+ if (!strErr.isEmpty()) {
+ ((FQTermWindow*)lp)->getPythonErrorMessage() = strErr;
+ // TODO: fixme
+ //qApp->postEvent((FQTermWindow*)lp, new QCustomEvent(PYE_ERROR));
+ } else {
+ // TODO: fixme
+ //qApp->postEvent((FQTermWindow*)lp, new QCustomEvent(PYE_FINISH));
+ }
+
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// caret x
+static PyObject *fqterm_caretX(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+ int x = ((FQTermWindow*)lp)->getSession()->getBuffer()->getCaretColumn();
+ PyObject *py_x = Py_BuildValue("i", x);
+ Py_INCREF(py_x);
+ return py_x;
+}
+
+// caret y
+static PyObject *fqterm_caretY(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+ int y = ((FQTermWindow*)lp)->getSession()->getBuffer()->getCaretRow();
+ PyObject *py_y = Py_BuildValue("i", y);
+ Py_INCREF(py_y);
+ return py_y;
+
+}
+
+// columns
+static PyObject *fqterm_columns(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ int numColumns = ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumColumns();
+ PyObject *py_columns = Py_BuildValue("i", numColumns);
+
+ Py_INCREF(py_columns);
+ return py_columns;
+
+}
+
+// rows
+static PyObject *fqterm_rows(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ int rows = ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumRows();
+ PyObject *py_rows = Py_BuildValue("i", rows);
+
+ Py_INCREF(py_rows);
+ return py_rows;
+}
+
+// sned string to server
+static PyObject *fqterm_sendString(PyObject *, PyObject *args) {
+ char *pstr;
+ long lp;
+
+ if (!PyArg_ParseTuple(args, "ls", &lp, &pstr)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->writeRawString_ts(U82U(pstr));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// input should be utf8.
+// same as above except parsing string first "\n" "^p" etc
+static PyObject *fqterm_sendParsedString(PyObject *, PyObject *args) {
+ char *pstr;
+ long lp;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "ls", &lp, &pstr)) {
+ return NULL;
+ }
+ len = strlen(pstr);
+
+ ((FQTermWindow*)lp)->writeString_ts(U82U(pstr));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// get text at line
+static PyObject *fqterm_getText(PyObject *, PyObject *args) {
+ long lp;
+ int numRows;
+ if (!PyArg_ParseTuple(args, "li", &lp, &numRows)) {
+ return NULL;
+ }
+ QString str;
+ if (numRows < ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumRows())
+ ((FQTermWindow*)lp)->getSession()->getBuffer()->getTextLineInTerm(numRows)->getAllPlainText(str);
+
+ PyObject *py_text = PyString_FromString(U2U8(str));
+
+ Py_INCREF(py_text);
+ return py_text;
+}
+
+// get text with attributes
+static PyObject *fqterm_getAttrText(PyObject *, PyObject *args) {
+ long lp;
+ int numRows;
+ if (!PyArg_ParseTuple(args, "li", &lp, &numRows)) {
+ return NULL;
+ }
+
+ QString str;
+ if (numRows < ((FQTermWindow*)lp)->getSession()->getBuffer()->getNumRows())
+ ((FQTermWindow*)lp)->getSession()->getBuffer()->getTextLineInTerm(numRows)->getAllAnsiText(str);
+
+ PyObject *py_text = PyString_FromString(U2U8(str));
+
+ Py_INCREF(py_text);
+ return py_text;
+}
+
+// is host connected
+static PyObject *fqterm_isConnected(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ bool connected = ((FQTermWindow*)lp)->isConnected();
+ PyObject *py_connected = Py_BuildValue("i", connected ? 1 : 0);
+
+ Py_INCREF(py_connected);
+ return py_connected;
+}
+
+// disconnect from host
+static PyObject *fqterm_disconnect(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->disconnect();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// reconnect to host
+static PyObject *fqterm_reconnect(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->getSession()->reconnect();
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+// bbs encoding 0-GBK 1-BIG5
+//FIXME: UTF8 and HKSCS
+static PyObject *fqterm_getBBSCodec(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_codec = PyString_FromString(((FQTermWindow*)lp)
+ ->getSession()->param().serverEncodingID_ == 0 ? "GBK" : "Big5");
+ Py_INCREF(py_codec);
+
+ return py_codec;
+}
+
+// host address
+static PyObject *fqterm_getAddress(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_addr = PyString_FromString(((FQTermWindow*)lp)
+ ->getSession()->param().hostAddress_.toLocal8Bit());
+ Py_INCREF(py_addr);
+ return py_addr;
+}
+
+// host port number
+static PyObject *fqterm_getPort(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_port = Py_BuildValue("i", ((FQTermWindow*)lp)->getSession()->param().port_);
+ Py_INCREF(py_port);
+ return py_port;
+}
+
+// connection protocol 0-telnet 1-SSH1 2-SSH2
+static PyObject *fqterm_getProtocol(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_port = Py_BuildValue("i", ((FQTermWindow*)lp)
+ ->getSession()->param().protocolType_);
+ Py_INCREF(py_port);
+ return py_port;
+}
+
+// key to reply msg
+static PyObject *fqterm_getReplyKey(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_key = PyString_FromString(((FQTermWindow*)lp)
+ ->getSession()->param().replyKeyCombination_.toLocal8Bit());
+ Py_INCREF(py_key);
+ return py_key;
+}
+
+// url under mouse
+static PyObject *fqterm_getURL(PyObject *, PyObject *args) {
+ long lp;
+ if (!PyArg_ParseTuple(args, "l", &lp)) {
+ return NULL;
+ }
+
+ PyObject *py_url = PyString_FromString(((FQTermWindow*)lp)->getSession()->getUrl().toUtf8().constData());
+ Py_INCREF(py_url);
+ return py_url;
+}
+
+// preview image link
+static PyObject *fqterm_previewImage(PyObject *, PyObject *args) {
+ long lp;
+ char *url;
+ if (!PyArg_ParseTuple(args, "ls", &lp, &url)) {
+ return NULL;
+ }
+
+ ((FQTermWindow*)lp)->getHttpHelper(url, true);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+
+// convert string from UTF8 to specified encoding
+static PyObject *fqterm_fromUTF8(PyObject *, PyObject *args) {
+ char *str, *enc;
+ if (!PyArg_ParseTuple(args, "ss", &str, &enc)) {
+ return NULL;
+ }
+ QTextCodec *encodec = QTextCodec::codecForName(enc);
+ QTextCodec *utf8 = QTextCodec::codecForName("utf8");
+
+ PyObject *py_str = PyString_FromString(encodec->fromUnicode(utf8->toUnicode
+ (str)));
+ Py_INCREF(py_str);
+ return py_str;
+}
+
+// convert string from specified encoding to UTF8
+static PyObject *fqterm_toUTF8(PyObject *, PyObject *args) {
+ char *str, *enc;
+ if (!PyArg_ParseTuple(args, "ss", &str, &enc)) {
+ return NULL;
+ }
+ QTextCodec *encodec = QTextCodec::codecForName(enc);
+ QTextCodec *utf8 = QTextCodec::codecForName("utf8");
+
+ PyObject *py_str = PyString_FromString(utf8->fromUnicode(encodec->toUnicode
+ (str)));
+ Py_INCREF(py_str);
+ return py_str;
+}
+
+static PyObject *fqterm_wait(PyObject *, PyObject *args) {
+ long t;
+ if (!PyArg_ParseTuple(args, "l", &t)) {
+ return NULL;
+ }
+ SleeperThread::msleep(t);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyMethodDef fqterm_methods[] = {
+ {
+ "formatError", (PyCFunction)fqterm_formatError, METH_VARARGS,
+ "get the traceback info"
+ }
+
+ ,
+
+ {
+ "getArticle", (PyCFunction)fqterm_getArticle, METH_VARARGS,
+ "copy current article"
+ }
+
+ ,
+
+ {
+ "copyArticle", (PyCFunction)fqterm_copyArticle, METH_VARARGS,
+ "copy current article (obsolete)"
+ }
+
+ ,
+
+ {
+ "getText", (PyCFunction)fqterm_getText, METH_VARARGS, "get text at line#"
+ }
+
+ ,
+
+ {
+ "getAttrText", (PyCFunction)fqterm_getAttrText, METH_VARARGS,
+ "get attr text at line#"
+ }
+
+ ,
+
+ {
+ "sendString", (PyCFunction)fqterm_sendString, METH_VARARGS,
+ "send string to server"
+ }
+
+ ,
+
+ {
+ "sendParsedString", (PyCFunction)fqterm_sendParsedString, METH_VARARGS,
+ "send string with escape"
+ }
+
+ ,
+
+ {
+ "caretX", (PyCFunction)fqterm_caretX, METH_VARARGS, "caret x"
+ }
+
+ ,
+
+ {
+ "caretY", (PyCFunction)fqterm_caretY, METH_VARARGS, "caret y"
+ }
+
+ ,
+
+ {
+ "columns", (PyCFunction)fqterm_columns, METH_VARARGS, "screen width"
+ }
+
+ ,
+
+ {
+ "rows", (PyCFunction)fqterm_rows, METH_VARARGS, "screen height"
+ }
+
+ ,
+
+ {
+ "isConnected", (PyCFunction)fqterm_isConnected, METH_VARARGS,
+ "connected to server or not"
+ }
+
+ ,
+
+ {
+ "disconnect", (PyCFunction)fqterm_disconnect, METH_VARARGS,
+ "disconnect from server"
+ }
+
+ ,
+
+ {
+ "reconnect", (PyCFunction)fqterm_reconnect, METH_VARARGS, "reconnect"
+ }
+
+ ,
+
+ {
+ "getBBSCodec", (PyCFunction)fqterm_getBBSCodec, METH_VARARGS,
+ "get the bbs encoding, GBK or Big5"
+ }
+
+ ,
+
+ {
+ "getAddress", (PyCFunction)fqterm_getAddress, METH_VARARGS,
+ "get the bbs address"
+ }
+
+ ,
+
+ {
+ "getPort", (PyCFunction)fqterm_getPort, METH_VARARGS, "get the bbs port number"
+ }
+
+ ,
+
+ {
+ "getProtocol", (PyCFunction)fqterm_getProtocol, METH_VARARGS,
+ "get the bbs protocol, 0/1/2 TELNET/SSH1/SSH2"
+ }
+
+ ,
+
+ {
+ "getReplyKey", (PyCFunction)fqterm_getReplyKey, METH_VARARGS,
+ "get the key to reply messages"
+ }
+
+ ,
+
+ {
+ "getURL", (PyCFunction)fqterm_getURL, METH_VARARGS,
+ "get the url string under mouse"
+ }
+
+ ,
+
+ {
+ "previewImage", (PyCFunction)fqterm_previewImage, METH_VARARGS,
+ "preview the image link"
+ }
+
+ ,
+
+ {
+ "fromUTF8", (PyCFunction)fqterm_fromUTF8, METH_VARARGS,
+ "decode from utf8 to string in specified codec"
+ }
+
+ ,
+
+ {
+ "toUTF8", (PyCFunction)fqterm_toUTF8, METH_VARARGS,
+ "decode from string in specified codec to utf8"
+ }
+
+ ,
+
+ {
+ "wait", (PyCFunction)fqterm_wait, METH_VARARGS,
+ "wait for x ms"
+ }
+
+ ,
+
+ {
+ NULL, (PyCFunction)NULL, 0, NULL
+ }
+};
+
+
+
+FQTermPythonHelper::FQTermPythonHelper()
+ : mainThreadState_(NULL) {
+
+ // initialize Python
+ Py_Initialize();
+ // initialize thread support
+ PyEval_InitThreads();
+ // save a pointer to the main PyThreadState object
+ mainThreadState_ = PyThreadState_Get();
+ // add path
+ PyRun_SimpleString("import sys\n");
+ QString pathCmd;
+ pathCmd = "sys.path.insert(0,'";
+ pathCmd += getPath(RESOURCE)+"script')";
+ PyRun_SimpleString(fq_strdup(pathCmd.toUtf8().data()));
+
+ Py_InitModule4("fqterm", fqterm_methods,
+ NULL,(PyObject*)NULL,PYTHON_API_VERSION);
+ // release the lock
+ PyEval_ReleaseLock();
+}
+
+FQTermPythonHelper::~FQTermPythonHelper() {
+ // shut down the interpreter
+ PyInterpreterState * mainInterpreterState = mainThreadState_->interp;
+ // create a thread state object for this thread
+ PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState);
+ PyThreadState_Swap(myThreadState);
+ PyEval_AcquireLock();
+ Py_Finalize();
+}
+
+} // namespace FQTerm
+
+#endif //HAVE_PYTHON \ No newline at end of file