diff --git a/src/Base/Sequencer.cpp b/src/Base/Sequencer.cpp index ad58de7fc..463bb969f 100644 --- a/src/Base/Sequencer.cpp +++ b/src/Base/Sequencer.cpp @@ -319,7 +319,7 @@ void ProgressIndicatorPy::init_type() behaviors().supportRepr(); behaviors().supportGetattr(); behaviors().supportSetattr(); - behaviors().type_object()->tp_new = &PyMake; + behaviors().set_tp_new(PyMake); add_varargs_method("start",&ProgressIndicatorPy::start,"start(string,int)"); add_varargs_method("next",&ProgressIndicatorPy::next,"next()"); diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 6eb8f14b2..23e2d81b1 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -379,6 +379,7 @@ Application::Application(bool GUIenabled) UiLoaderPy::init_type(); Base::Interpreter().addType(UiLoaderPy::type_object(), module,"UiLoader"); + PyResource::init_type(); // PySide additions PySideUicModule* pySide = new PySideUicModule(); diff --git a/src/Gui/SelectionFilter.cpp b/src/Gui/SelectionFilter.cpp index 69a314bf6..45d37fb8a 100644 --- a/src/Gui/SelectionFilter.cpp +++ b/src/Gui/SelectionFilter.cpp @@ -242,7 +242,7 @@ void SelectionFilterPy::init_type() behaviors().supportRepr(); behaviors().supportGetattr(); behaviors().supportSetattr(); - behaviors().type_object()->tp_new = &PyMake; + behaviors().set_tp_new(PyMake); add_varargs_method("match",&SelectionFilterPy::match,"match()"); add_varargs_method("result",&SelectionFilterPy::result,"result()"); add_varargs_method("test",&SelectionFilterPy::test,"test()"); diff --git a/src/Gui/WidgetFactory.cpp b/src/Gui/WidgetFactory.cpp index 4318e169b..da660c4c1 100644 --- a/src/Gui/WidgetFactory.cpp +++ b/src/Gui/WidgetFactory.cpp @@ -568,7 +568,7 @@ void UiLoaderPy::init_type() { behaviors().name("UiLoader"); behaviors().doc("UiLoader to create widgets"); - behaviors().type_object()->tp_new = &PyMake; + behaviors().set_tp_new(PyMake); // you must have overwritten the virtual functions behaviors().supportRepr(); behaviors().supportGetattr(); @@ -879,59 +879,24 @@ ContainerDialog::~ContainerDialog() // ---------------------------------------------------- -//-------------------------------------------------------------------------- -// Type structure -//-------------------------------------------------------------------------- +void PyResource::init_type() +{ + behaviors().name("PyResource"); + behaviors().doc("PyResource"); + // you must have overwritten the virtual functions + behaviors().supportRepr(); + behaviors().supportGetattr(); + behaviors().supportSetattr(); + add_varargs_method("value",&PyResource::value); + add_varargs_method("setValue",&PyResource::setValue); + add_varargs_method("show",&PyResource::show); + add_varargs_method("connect",&PyResource::connect); +} -PyTypeObject PyResource::Type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /*ob_size*/ - "PyResource", /*tp_name*/ - sizeof(PyResource), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - PyDestructor, /*tp_dealloc*/ - 0, /*tp_print*/ - __getattr, /*tp_getattr*/ - __setattr, /*tp_setattr*/ - 0, /*tp_compare*/ - __repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call */ - }; - -//-------------------------------------------------------------------------- -// Methods structure -//-------------------------------------------------------------------------- -PyMethodDef PyResource::Methods[] = { - {"GetValue", (PyCFunction) svalue, Py_NEWARGS}, - {"SetValue", (PyCFunction) ssetValue, Py_NEWARGS}, - {"Show", (PyCFunction) sshow, Py_NEWARGS}, - {"Connect", (PyCFunction) sconnect, Py_NEWARGS}, - - {NULL, NULL} /* Sentinel */ - }; - -//-------------------------------------------------------------------------- -// constructor -//-------------------------------------------------------------------------- -PyResource::PyResource(PyTypeObject *T) - : PyObjectBase(0, T), myDlg(0L) +PyResource::PyResource() : myDlg(0) { } -PyObject *PyResource::PyMake(PyObject *ignored, PyObject *args) // Python wrapper -{ - //return new FCPyResource(); // Make new Python-able object - return 0; -} - -//-------------------------------------------------------------------------- -// FCPyResource destructor -//-------------------------------------------------------------------------- PyResource::~PyResource() { delete myDlg; @@ -941,27 +906,12 @@ PyResource::~PyResource() } } -//-------------------------------------------------------------------------- -// FCPyParametrGrp Attributes -//-------------------------------------------------------------------------- -PyObject *PyResource::_getattr(char *attr) // __getattr__ function: note only need to handle new state -{ - _getattr_up(PyObjectBase); // send to parent - return 0; -} - -int PyResource::_setattr(char *attr, PyObject *value) // __setattr__ function: note only need to handle new state -{ - return PyObjectBase::_setattr(attr, value); // send up to parent - return 0; -} - /** * Loads an .ui file with the name \a name. If the .ui file cannot be found or the QWidgetFactory * cannot create an instance an exception is thrown. If the created resource does not inherit from * QDialog an instance of ContainerDialog is created to embed it. */ -void PyResource::load( const char* name ) +void PyResource::load(const char* name) { QString fn = QString::fromUtf8(name); QFileInfo fi(fn); @@ -1029,8 +979,8 @@ void PyResource::load( const char* name ) /** * Makes a connection between the sender widget \a sender and its signal \a signal * of the created resource and Python callback function \a cb. - * If the sender widget does not exist or no resource has been loaded this method returns false, - * otherwise it returns true. + * If the sender widget does not exist or no resource has been loaded this method returns FALSE, + * otherwise it returns TRUE. */ bool PyResource::connect(const char* sender, const char* signal, PyObject* cb) { @@ -1041,7 +991,7 @@ bool PyResource::connect(const char* sender, const char* signal, PyObject* cb) QList list = myDlg->findChildren(); QList::const_iterator it = list.begin(); QObject *obj; - QString sigStr = QString::fromLatin1("2%1").arg(QString::fromLatin1(signal)); + QString sigStr = QString::fromAscii("2%1").arg(QString::fromAscii(signal)); while ( it != list.end() ) { obj = *it; @@ -1055,7 +1005,7 @@ bool PyResource::connect(const char* sender, const char* signal, PyObject* cb) if (objS) { SignalConnect* sc = new SignalConnect(this, cb); mySingals.push_back(sc); - return QObject::connect(objS, sigStr.toLatin1(), sc, SLOT ( onExecute() ) ); + return QObject::connect(objS, sigStr.toAscii(), sc, SLOT ( onExecute() ) ); } else qWarning( "'%s' does not exist.\n", sender ); @@ -1063,64 +1013,12 @@ bool PyResource::connect(const char* sender, const char* signal, PyObject* cb) return false; } -/** - * Searches for the sender, the signal and the callback function to connect with - * in the argument object \a args. In the case it fails 0 is returned. - */ -PyObject *PyResource::connect(PyObject *args) +Py::Object PyResource::repr() { - char *psSender; - char *psSignal; - - PyObject *result = NULL; - PyObject *temp; - - if (PyArg_ParseTuple(args, "ssOset_callback", &psSender, &psSignal, &temp)) { - if (!PyCallable_Check(temp)) { - PyErr_SetString(PyExc_TypeError, "parameter must be callable"); - return NULL; - } - - Py_XINCREF(temp); /* Add a reference to new callback */ - std::string sSender = psSender; - std::string sSignal = psSignal; - - if (!connect(psSender, psSignal, temp)) { - // no signal object found => dispose the callback object - Py_XDECREF(temp); /* Dispose of callback */ - } - - /* Boilerplate to return "None" */ - Py_INCREF(Py_None); - result = Py_None; - } - - return result; -} - -/** - * If any resouce has been loaded this methods shows it as a modal dialog. - */ -PyObject *PyResource::show(PyObject *args) -{ - if (myDlg) { - // small trick to get focus - myDlg->showMinimized(); - -#ifdef Q_WS_X11 - // On X11 this may not work. For further information see QWidget::showMaximized - // - // workaround for X11 - myDlg->hide(); - myDlg->show(); -#endif - - myDlg->showNormal(); - myDlg->exec(); - } - - Py_INCREF(Py_None); - return Py_None; + std::string s; + std::ostringstream s_out; + s_out << "Resource object"; + return Py::String(s_out.str()); } /** @@ -1128,12 +1026,12 @@ PyObject *PyResource::show(PyObject *args) * to returns its value as Python object. * In the case it fails 0 is returned. */ -PyObject *PyResource::value(PyObject *args) +Py::Object PyResource::value(const Py::Tuple& args) { char *psName; char *psProperty; - if (!PyArg_ParseTuple(args, "ss", &psName, &psProperty)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args.ptr(), "ss", &psName, &psProperty)) + throw Py::Exception(); QVariant v; if (myDlg) { @@ -1156,42 +1054,42 @@ PyObject *PyResource::value(PyObject *args) qWarning( "'%s' not found.\n", psName ); } - PyObject *pItem=0; + Py::Object item = Py::None(); switch (v.type()) { case QVariant::StringList: { QStringList str = v.toStringList(); int nSize = str.count(); - PyObject* slist = PyList_New(nSize); + Py::List slist(nSize); for (int i=0; i(v.toUInt())); break; case QVariant::Int: - pItem = PyInt_FromLong(v.toInt()); + item = Py::Int(v.toInt()); break; default: - pItem = PyString_FromString(""); + item = Py::String(""); break; } - return pItem; + return item; } /** @@ -1199,17 +1097,17 @@ PyObject *PyResource::value(PyObject *args) * to set even this new value. * In the case it fails 0 is returned. */ -PyObject *PyResource::setValue(PyObject *args) +Py::Object PyResource::setValue(const Py::Tuple& args) { char *psName; char *psProperty; PyObject *psValue; - if (!PyArg_ParseTuple(args, "ssO", &psName, &psProperty, &psValue)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args.ptr(), "ssO", &psName, &psProperty, &psValue)) + throw Py::Exception(); QVariant v; if (PyString_Check(psValue)) { - v = QString::fromLatin1(PyString_AsString(psValue)); + v = QString::fromAscii(PyString_AsString(psValue)); } else if (PyInt_Check(psValue)) { int val = PyInt_AsLong(psValue); @@ -1231,14 +1129,13 @@ PyObject *PyResource::setValue(PyObject *args) continue; char* pItem = PyString_AsString(item); - str.append(QString::fromLatin1(pItem)); + str.append(QString::fromAscii(pItem)); } v = str; } else { - PyErr_SetString(PyExc_AssertionError, "Unsupported type"); - return NULL; + throw Py::TypeError("Unsupported type"); } if (myDlg) { @@ -1257,23 +1154,80 @@ PyObject *PyResource::setValue(PyObject *args) } } - if ( !fnd ) + if (!fnd) qWarning( "'%s' not found.\n", psName ); } - Py_INCREF(Py_None); - return Py_None; + return Py::None(); +} + +/** + * If any resouce has been loaded this methods shows it as a modal dialog. + */ +Py::Object PyResource::show(const Py::Tuple& args) +{ + if (myDlg) { + // small trick to get focus + myDlg->showMinimized(); + +#ifdef Q_WS_X11 + // On X11 this may not work. For further information see QWidget::showMaximized + // + // workaround for X11 + myDlg->hide(); + myDlg->show(); +#endif + + myDlg->showNormal(); + myDlg->exec(); + } + + return Py::None(); +} + +/** + * Searches for the sender, the signal and the callback function to connect with + * in the argument object \a args. In the case it fails 0 is returned. + */ +Py::Object PyResource::connect(const Py::Tuple& args) +{ + char *psSender; + char *psSignal; + + PyObject *temp; + + if (PyArg_ParseTuple(args.ptr(), "ssO", &psSender, &psSignal, &temp)) { + if (!PyCallable_Check(temp)) { + PyErr_SetString(PyExc_TypeError, "parameter must be callable"); + throw Py::Exception(); + } + + Py_XINCREF(temp); /* Add a reference to new callback */ + std::string sSender = psSender; + std::string sSignal = psSignal; + + if (!connect(psSender, psSignal, temp)) { + // no signal object found => dispose the callback object + Py_XDECREF(temp); /* Dispose of callback */ + } + + return Py::None(); + } + + // error set by PyArg_ParseTuple + throw Py::Exception(); } // ---------------------------------------------------- -SignalConnect::SignalConnect(Base::PyObjectBase* res, PyObject* cb) +SignalConnect::SignalConnect(PyObject* res, PyObject* cb) : myResource(res), myCallback(cb) { } SignalConnect::~SignalConnect() { + Base::PyGILStateLocker lock; Py_XDECREF(myCallback); /* Dispose of callback */ } @@ -1288,7 +1242,7 @@ void SignalConnect::onExecute() /* Time to call the callback */ arglist = Py_BuildValue("(O)", myResource); result = PyEval_CallObject(myCallback, arglist); - (void)result; + Py_XDECREF(result); Py_DECREF(arglist); } diff --git a/src/Gui/WidgetFactory.h b/src/Gui/WidgetFactory.h index 5d6146ead..74fc4e339 100644 --- a/src/Gui/WidgetFactory.h +++ b/src/Gui/WidgetFactory.h @@ -351,7 +351,7 @@ private: * The PyResource class provides an interface to create widgets or to load .ui files from Python. * With * \code - * d = Gui.CreateDialog("test.ui") + * d = Gui.createDialog("test.ui") * \endcode * * you can create a PyResource object containing the widget. If a relative file name @@ -374,12 +374,12 @@ private: * # define a callback function with one argument * def TestCall(obj): * # sets the value from lineedit if "Button_Name" was pressed - * obj.SetValue("lineedit", "text", "Show this text here!") + * obj.setValue("lineedit", "text", "Show this text here!") * print "Button clicked" * - * d = Gui.CreateDialog("test.ui") - * d.Connect("Button_Name", "clicked()", TestCall) - * d.Show() + * d = Gui.createDialog("test.ui") + * d.connect("Button_Name", "clicked()", TestCall) + * d.show() * \endcode * * If the button with the name "Button_Name" is clicked the message "Button clicked" is @@ -387,47 +387,36 @@ private: * For example if you have a QLineEdit inside your widget you can set the text with * \code * # sets "Show this text here!" to the text property - * d.SetValue("lineedit", "text", "Show this text here!") - * d.Show() + * d.setValue("lineedit", "text", "Show this text here!") + * d.show() * \endcode * * or retrieve the entered text with * \code - * f = d.GetValue("lineedit", "text") + * f = d.getValue("lineedit", "text") * print f * \endcode * * \author Werner Mayer */ -class PyResource : public Base::PyObjectBase + +class PyResource : public Py::PythonExtension { - // always start with Py_Header - Py_Header; - -protected: - ~PyResource(); - public: - PyResource(PyTypeObject *T = &Type); + static void init_type(void); // announce properties and methods + + PyResource(); + ~PyResource(); void load(const char* name); bool connect(const char* sender, const char* signal, PyObject* cb); - /// for construction in Python - static PyObject *PyMake(PyObject *, PyObject *); + Py::Object repr(); - //--------------------------------------------------------------------- - // python exports goes here +++++++++++++++++++++++++++++++++++++++++++ - //--------------------------------------------------------------------- - PyObject *_getattr(char *attr); // __getattr__ function - // getter setter - int _setattr(char *attr, PyObject *value); // __setattr__ function - - // methods - PYFUNCDEF_D(PyResource, value); - PYFUNCDEF_D(PyResource, setValue); - PYFUNCDEF_D(PyResource, show); - PYFUNCDEF_D(PyResource, connect); + Py::Object value(const Py::Tuple&); + Py::Object setValue(const Py::Tuple&); + Py::Object show(const Py::Tuple&); + Py::Object connect(const Py::Tuple&); private: std::vector mySingals; @@ -445,7 +434,7 @@ class SignalConnect : public QObject Q_OBJECT public: - SignalConnect(Base::PyObjectBase* res, PyObject* cb); + SignalConnect(PyObject* res, PyObject* cb); ~SignalConnect(); public Q_SLOTS: diff --git a/src/Mod/Fem/App/HypothesisPy.cpp b/src/Mod/Fem/App/HypothesisPy.cpp index 7dbe2f722..bcfbf78a8 100755 --- a/src/Mod/Fem/App/HypothesisPy.cpp +++ b/src/Mod/Fem/App/HypothesisPy.cpp @@ -83,7 +83,7 @@ void SMESH_HypothesisPy::init_type(PyObject* module) SMESH_HypothesisPy::behaviors().supportRepr(); SMESH_HypothesisPy::behaviors().supportGetattr(); SMESH_HypothesisPy::behaviors().supportSetattr(); - SMESH_HypothesisPy::behaviors().type_object()->tp_new = &PyMake; + SMESH_HypothesisPy::behaviors().set_tp_new(PyMake); SMESH_HypothesisPy::add_varargs_method("setLibName", &SMESH_HypothesisPy::setLibName, "setLibName(String)"); SMESH_HypothesisPy::add_varargs_method("getLibName", &SMESH_HypothesisPy::getLibName, "String getLibName()");