mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
ParaView-5.0.1: Added the source-tree to ThirdParty-dev and patched as described in the README file
Resolves bug-report http://bugs.openfoam.org/view.php?id=2098
This commit is contained in:
607
ParaView-5.0.1/ThirdParty/QtTesting/vtkqttesting/pqPythonEventSource.cxx
vendored
Normal file
607
ParaView-5.0.1/ThirdParty/QtTesting/vtkqttesting/pqPythonEventSource.cxx
vendored
Normal file
@ -0,0 +1,607 @@
|
||||
/*=========================================================================
|
||||
|
||||
Program: ParaView
|
||||
Module: pqPythonEventSource.cxx
|
||||
|
||||
Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
|
||||
All rights reserved.
|
||||
|
||||
ParaView is a free software; you can redistribute it and/or modify it
|
||||
under the terms of the ParaView license version 1.2.
|
||||
|
||||
See License_v1.2.txt for the full ParaView license.
|
||||
A copy of this license can be obtained by contacting
|
||||
Kitware Inc.
|
||||
28 Corporate Drive
|
||||
Clifton Park, NY 12065
|
||||
USA
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=========================================================================*/
|
||||
|
||||
/*
|
||||
Use the "documented" trick involving checking for _DEBUG
|
||||
and undefined that symbol while we include Python headers.
|
||||
Update: this method does not fool Microsoft Visual C++ 8 anymore; two
|
||||
of its header files (crtdefs.h and use_ansi.h) check if _DEBUG was set
|
||||
or not, and set flags accordingly (_CRT_MANIFEST_RETAIL,
|
||||
_CRT_MANIFEST_DEBUG, _CRT_MANIFEST_INCONSISTENT). The next time the
|
||||
check is performed in the same compilation unit, and the flags are found,
|
||||
and error is triggered. Let's prevent that by setting _CRT_NOFORCE_MANIFEST.
|
||||
*/
|
||||
|
||||
#ifdef _DEBUG
|
||||
# undef _DEBUG
|
||||
# if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
# define _CRT_NOFORCE_MANIFEST 1
|
||||
# endif
|
||||
# include <Python.h>
|
||||
# define _DEBUG
|
||||
#else
|
||||
# include <Python.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef PyMODINIT_FUNC
|
||||
#define PyMODINIT_FUNC extern "C" void
|
||||
#endif // PyMODINIT_FUNC
|
||||
|
||||
// self include
|
||||
#include "pqPythonEventSource.h"
|
||||
|
||||
// system includes
|
||||
#include <signal.h>
|
||||
|
||||
// Qt include
|
||||
#include <QVariant>
|
||||
#include <QFile>
|
||||
#include <QtDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QEvent>
|
||||
#include <QStringList>
|
||||
#include <QThread>
|
||||
#include <QApplication>
|
||||
#include <QMetaObject>
|
||||
#include <QMetaProperty>
|
||||
|
||||
// Qt testing includes
|
||||
#include "pqObjectNaming.h"
|
||||
#include "pqWidgetEventPlayer.h"
|
||||
#include "pqEventDispatcher.h"
|
||||
|
||||
|
||||
// TODO not have a global instance pointer?
|
||||
static pqPythonEventSource* Instance = NULL;
|
||||
static QString PropertyObject;
|
||||
static QString PropertyResult;
|
||||
static QString PropertyValue;
|
||||
static QStringList ObjectList;
|
||||
|
||||
|
||||
static PyObject*
|
||||
QtTesting_playCommand(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
// this gives the main thread some time to refresh before we start sending
|
||||
// commands. Avoids crazy hangs in QDialog::exec() calls.
|
||||
pqThreadedEventSource::msleep(500);
|
||||
|
||||
// void QtTesting.playCommand('object', 'command', 'arguments')
|
||||
// an exception is thrown in this fails
|
||||
|
||||
const char* object = 0;
|
||||
const char* command = 0;
|
||||
const char* arguments = 0;
|
||||
|
||||
if(!PyArg_ParseTuple(args, const_cast<char*>("sss"), &object, &command, &arguments))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "bad arguments to playCommand()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(Instance)
|
||||
{
|
||||
if(!Instance->postNextEvent(object, command, arguments))
|
||||
{
|
||||
PyErr_SetString(PyExc_AssertionError, "error processing event");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_AssertionError, "pqPythonEventSource not defined");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Py_BuildValue(const_cast<char*>(""));
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
QtTesting_getProperty(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
// string QtTesting.getProperty('object', 'property')
|
||||
// returns the string value of the property
|
||||
|
||||
const char* object = 0;
|
||||
const char* property = 0;
|
||||
|
||||
if(!PyArg_ParseTuple(args, const_cast<char*>("ss"), &object, &property))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PropertyObject = object;
|
||||
PropertyResult = property;
|
||||
PropertyValue = QString::null;
|
||||
|
||||
if(Instance && QThread::currentThread() != QApplication::instance()->thread())
|
||||
{
|
||||
QMetaObject::invokeMethod(Instance, "threadGetProperty", Qt::QueuedConnection);
|
||||
if(!Instance->waitForGUI())
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "error getting property");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if(QThread::currentThread() == QApplication::instance()->thread())
|
||||
{
|
||||
PropertyValue = pqPythonEventSource::getProperty(PropertyObject, PropertyResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_AssertionError, "pqPythonEventSource not defined");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(PropertyObject == QString::null)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "object not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(PropertyResult == QString::null)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "property not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Py_BuildValue(const_cast<char*>("s"),
|
||||
PropertyValue.toLatin1().data());
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
QtTesting_setProperty(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
// string QtTesting.setProperty('object', 'property', 'value')
|
||||
// returns the string value of the property
|
||||
|
||||
const char* object = 0;
|
||||
const char* property = 0;
|
||||
const char* value = 0;
|
||||
|
||||
if(!PyArg_ParseTuple(args, const_cast<char*>("sss"), &object,
|
||||
&property, &value))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PropertyObject = object;
|
||||
PropertyResult = property;
|
||||
PropertyValue = value;
|
||||
|
||||
if(Instance && QThread::currentThread() != QApplication::instance()->thread())
|
||||
{
|
||||
QMetaObject::invokeMethod(Instance, "threadSetProperty", Qt::QueuedConnection);
|
||||
if(!Instance->waitForGUI())
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "error setting property");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if(QThread::currentThread() == QApplication::instance()->thread())
|
||||
{
|
||||
pqPythonEventSource::setProperty(PropertyObject,
|
||||
PropertyResult,
|
||||
PropertyValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_AssertionError, "pqPythonEventSource not defined");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(PropertyObject == QString::null)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "object not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(PropertyResult == QString::null)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "property not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Py_BuildValue(const_cast<char*>("s"), "");
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
QtTesting_getQtVersion(PyObject* /*self*/, PyObject* /*args*/)
|
||||
{
|
||||
// string QtTesting.getQtVersion()
|
||||
// returns the Qt version as a string
|
||||
|
||||
return Py_BuildValue(const_cast<char*>("s"), qVersion());
|
||||
}
|
||||
|
||||
|
||||
static PyObject*
|
||||
QtTesting_getChildren(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
// string QtTesting.getChildren('object')
|
||||
// returns the a list of strings with object names
|
||||
|
||||
const char* object = 0;
|
||||
|
||||
if(!PyArg_ParseTuple(args, const_cast<char*>("s"), &object))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PropertyObject = object;
|
||||
ObjectList.clear();
|
||||
|
||||
if(Instance && QThread::currentThread() != QApplication::instance()->thread())
|
||||
{
|
||||
QMetaObject::invokeMethod(Instance, "threadGetChildren", Qt::QueuedConnection);
|
||||
if(!Instance->waitForGUI())
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "error getting children");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if(QThread::currentThread() == QApplication::instance()->thread())
|
||||
{
|
||||
ObjectList = pqPythonEventSource::getChildren(PropertyObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_AssertionError, "pqPythonEventSource not defined");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(PropertyObject == QString::null)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "object not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QString objs = ObjectList.join(", ");
|
||||
QString ret = QString("[%1]").arg(objs);
|
||||
|
||||
return Py_BuildValue(const_cast<char*>("s"),
|
||||
ret.toLatin1().data());
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
QtTesting_invokeMethod(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
// string QtTesting.invokeMethod('object', 'method')
|
||||
// calls a method and returns its value
|
||||
|
||||
const char* object = 0;
|
||||
const char* method = 0;
|
||||
|
||||
if(!PyArg_ParseTuple(args, const_cast<char*>("ss"), &object, &method))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PropertyObject = object;
|
||||
PropertyValue = method;
|
||||
PropertyResult = QString();
|
||||
|
||||
if(Instance && QThread::currentThread() != QApplication::instance()->thread())
|
||||
{
|
||||
QMetaObject::invokeMethod(Instance, "threadInvokeMethod", Qt::QueuedConnection);
|
||||
if(!Instance->waitForGUI())
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "error invoking method");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if(QThread::currentThread() == QApplication::instance()->thread())
|
||||
{
|
||||
PropertyResult = pqPythonEventSource::invokeMethod(PropertyObject,
|
||||
PropertyValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_AssertionError, "pqPythonEventSource not defined");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(PropertyObject == QString::null)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "object not found");
|
||||
return NULL;
|
||||
}
|
||||
else if(PropertyValue == QString::null)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "method not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Py_BuildValue(const_cast<char*>("s"),
|
||||
PropertyResult.toLatin1().data());
|
||||
}
|
||||
|
||||
static PyMethodDef QtTestingMethods[] = {
|
||||
{
|
||||
const_cast<char*>("playCommand"),
|
||||
QtTesting_playCommand,
|
||||
METH_VARARGS,
|
||||
const_cast<char*>("Play a test command.")
|
||||
},
|
||||
{
|
||||
const_cast<char*>("getProperty"),
|
||||
QtTesting_getProperty,
|
||||
METH_VARARGS,
|
||||
const_cast<char*>("Get a property of an object.")
|
||||
},
|
||||
{
|
||||
const_cast<char*>("setProperty"),
|
||||
QtTesting_setProperty,
|
||||
METH_VARARGS,
|
||||
const_cast<char*>("Set a property of an object.")
|
||||
},
|
||||
|
||||
{
|
||||
const_cast<char*>("getQtVersion"),
|
||||
QtTesting_getQtVersion,
|
||||
METH_VARARGS,
|
||||
const_cast<char*>("Get the version of Qt being used.")
|
||||
},
|
||||
{
|
||||
const_cast<char*>("getChildren"),
|
||||
QtTesting_getChildren,
|
||||
METH_VARARGS,
|
||||
const_cast<char*>("Return a list of child objects.")
|
||||
},
|
||||
{
|
||||
const_cast<char*>("invokeMethod"),
|
||||
QtTesting_invokeMethod,
|
||||
METH_VARARGS,
|
||||
const_cast<char*>("Invoke a Qt slot with the signature \"QVariant foo()\".")
|
||||
},
|
||||
|
||||
{NULL, NULL, 0, NULL} // Sentinal
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
initQtTesting(void)
|
||||
{
|
||||
Py_InitModule(const_cast<char*>("QtTesting"), QtTestingMethods);
|
||||
}
|
||||
|
||||
|
||||
class pqPythonEventSource::pqInternal
|
||||
{
|
||||
public:
|
||||
QString FileName;
|
||||
};
|
||||
|
||||
pqPythonEventSource::pqPythonEventSource(QObject* p)
|
||||
: pqThreadedEventSource(p)
|
||||
{
|
||||
this->Internal = new pqInternal;
|
||||
}
|
||||
|
||||
pqPythonEventSource::~pqPythonEventSource()
|
||||
{
|
||||
delete this->Internal;
|
||||
}
|
||||
|
||||
void pqPythonEventSource::initPythonIfNeeded()
|
||||
{
|
||||
int initPy = Py_IsInitialized();
|
||||
if(!initPy)
|
||||
{
|
||||
// initialize python
|
||||
Py_Initialize();
|
||||
#ifdef SIGINT
|
||||
signal(SIGINT, SIG_DFL);
|
||||
#endif
|
||||
}
|
||||
// add QtTesting to python's inittab, so it is
|
||||
// available to all interpreters
|
||||
PyImport_AppendInittab(const_cast<char*>("QtTesting"), initQtTesting);
|
||||
}
|
||||
|
||||
void pqPythonEventSource::setContent(const QString& path)
|
||||
{
|
||||
// start the python thread
|
||||
this->Internal->FileName = path;
|
||||
this->start();
|
||||
}
|
||||
|
||||
QString pqPythonEventSource::getProperty(QString& object, QString& prop)
|
||||
{
|
||||
// ensure other tasks have been completed
|
||||
pqEventDispatcher::processEventsAndWait(1);
|
||||
QVariant ret;
|
||||
|
||||
QObject* qobject = pqObjectNaming::GetObject(object);
|
||||
if(!qobject)
|
||||
{
|
||||
object = QString::null;
|
||||
return QString();
|
||||
}
|
||||
int idx = qobject->metaObject()->indexOfProperty(prop.toLatin1().data());
|
||||
if(idx == -1)
|
||||
{
|
||||
prop = QString::null;
|
||||
return QString();
|
||||
}
|
||||
else
|
||||
{
|
||||
QMetaProperty metaProp = qobject->metaObject()->property(idx);
|
||||
ret = metaProp.read(qobject);
|
||||
|
||||
if(metaProp.type() == QVariant::List || metaProp.type() ==
|
||||
QVariant::StringList)
|
||||
{
|
||||
return ret.toStringList().join(";");
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pqPythonEventSource::threadGetProperty()
|
||||
{
|
||||
PropertyValue = this->getProperty(PropertyObject, PropertyResult);
|
||||
this->guiAcknowledge();
|
||||
}
|
||||
|
||||
|
||||
void pqPythonEventSource::setProperty(QString& object, QString& prop,
|
||||
const QString& value)
|
||||
{
|
||||
// ensure other tasks have been completed
|
||||
pqEventDispatcher::processEventsAndWait(1);
|
||||
QVariant ret;
|
||||
|
||||
QObject* qobject = pqObjectNaming::GetObject(object);
|
||||
if(!qobject)
|
||||
{
|
||||
object = QString::null;
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = qobject->metaObject()->indexOfProperty(prop.toLatin1().data());
|
||||
if(idx == -1)
|
||||
{
|
||||
prop = QString::null;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
QVariant val = value;
|
||||
QMetaProperty metaProp = qobject->metaObject()->property(idx);
|
||||
if(metaProp.type() == QVariant::List || metaProp.type() ==
|
||||
QVariant::StringList)
|
||||
{
|
||||
val = value.split(";");
|
||||
}
|
||||
qobject->setProperty(prop.toLatin1().data(), val);
|
||||
}
|
||||
}
|
||||
|
||||
void pqPythonEventSource::threadSetProperty()
|
||||
{
|
||||
this->setProperty(PropertyObject, PropertyResult, PropertyValue);
|
||||
this->guiAcknowledge();
|
||||
}
|
||||
|
||||
|
||||
QStringList pqPythonEventSource::getChildren(QString& object)
|
||||
{
|
||||
// ensure other tasks have been completed
|
||||
pqEventDispatcher::processEventsAndWait(1);
|
||||
QStringList ret;
|
||||
|
||||
QObject* qobject = pqObjectNaming::GetObject(object);
|
||||
if(!qobject)
|
||||
{
|
||||
object = QString::null;
|
||||
}
|
||||
else
|
||||
{
|
||||
const QObjectList& children = qobject->children();
|
||||
foreach(QObject* child, children)
|
||||
{
|
||||
ret.append(pqObjectNaming::GetName(*child));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void pqPythonEventSource::threadGetChildren()
|
||||
{
|
||||
ObjectList = this->getChildren(PropertyObject);
|
||||
this->guiAcknowledge();
|
||||
}
|
||||
|
||||
void pqPythonEventSource::start()
|
||||
{
|
||||
this->initPythonIfNeeded();
|
||||
|
||||
PyEval_InitThreads();
|
||||
PyEval_ReleaseLock();
|
||||
pqThreadedEventSource::start();
|
||||
}
|
||||
|
||||
void pqPythonEventSource::run()
|
||||
{
|
||||
QFile file(this->Internal->FileName);
|
||||
if(!file.open(QFile::ReadOnly | QFile::Text))
|
||||
{
|
||||
printf("Unable to open python script\n");
|
||||
return;
|
||||
}
|
||||
this->initPythonIfNeeded();
|
||||
Instance = this;
|
||||
|
||||
PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
|
||||
// finally run the script
|
||||
QByteArray wholeFile = file.readAll();
|
||||
int result = PyRun_SimpleString(wholeFile.data()) == 0 ? 0 : 1;
|
||||
|
||||
PyGILState_Release(gstate);
|
||||
PyEval_ReleaseLock();
|
||||
|
||||
this->done(result);
|
||||
}
|
||||
|
||||
void pqPythonEventSource::threadInvokeMethod()
|
||||
{
|
||||
PropertyResult = this->invokeMethod(PropertyObject, PropertyValue);
|
||||
this->guiAcknowledge();
|
||||
}
|
||||
|
||||
QString pqPythonEventSource::invokeMethod(QString& object, QString& method)
|
||||
{
|
||||
// ensure other tasks have been completed
|
||||
pqEventDispatcher::processEventsAndWait(1);
|
||||
QVariant ret;
|
||||
|
||||
QObject* qobject = pqObjectNaming::GetObject(object);
|
||||
if(!qobject)
|
||||
{
|
||||
object = QString::null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!QMetaObject::invokeMethod(qobject, method.toLatin1().data(),
|
||||
Q_RETURN_ARG(QVariant, ret)))
|
||||
{
|
||||
method = QString::null;
|
||||
}
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user