diff --git a/wxPython/contrib/xrc/_xrcextras.py b/wxPython/contrib/xrc/_xrcextras.py index e4cd16f562..c4f42b0cba 100644 --- a/wxPython/contrib/xrc/_xrcextras.py +++ b/wxPython/contrib/xrc/_xrcextras.py @@ -4,3 +4,35 @@ wxTheXmlResource = wxXmlResource_Get() wx.wxXmlNodePtr = wxXmlNodePtr + + + + +#---------------------------------------------------------------------- +# Create a factory for handling the subclass property of the object tag. + + +def _my_import(name): + mod = __import__(name) + components = string.split(name, '.') + for comp in components[1:]: + mod = getattr(mod, comp) + return mod + + +class wxXmlSubclassFactory_Python(wxXmlSubclassFactory): + def __init__(self): + wxXmlSubclassFactory.__init__(self) + + def Create(self, className): + assert className.find('.') != -1, "Module name must be specified!" + mname = className[:className.rfind('.')] + cname = className[className.rfind('.')+1:] + module = _my_import(mname) + klass = getattr(module, cname) + inst = klass() + return inst + + +wxXmlResource_AddSubclassFactory(wxXmlSubclassFactory_Python()) + diff --git a/wxPython/contrib/xrc/xrc.cpp b/wxPython/contrib/xrc/xrc.cpp index e42e2572b8..42a4a3f063 100644 --- a/wxPython/contrib/xrc/xrc.cpp +++ b/wxPython/contrib/xrc/xrc.cpp @@ -98,6 +98,16 @@ static PyObject* t_output_helper(PyObject* target, PyObject* o) { static const wxString wxPyBitmapString(wxT("bitmap")); static const wxString wxPyIconString(wxT("icon")); static const wxString wxPyFontString(wxT("font")); + +class wxPyXmlSubclassFactory : public wxXmlSubclassFactory +{ +public: + wxPyXmlSubclassFactory() {} + DEC_PYCALLBACK_OBJECT_STRING_pure(Create); + PYPRIVATE; +}; + +IMP_PYCALLBACK_OBJECT_STRING_pure(wxPyXmlSubclassFactory, wxXmlSubclassFactory, Create); // C++ version of Python aware wxXmlResourceHandler, for the pure virtual // callbacks, as well as to make some protected things public so they can // be wrapped. @@ -111,34 +121,6 @@ public: DEC_PYCALLBACK_OBJECT__pure(DoCreateResource); DEC_PYCALLBACK_BOOL_NODE_pure(CanHandle); -// wxObject* DoCreateResource() { -// wxObject* rv = NULL; -// wxPyBeginBlockThreads(); -// if (wxPyCBH_findCallback(m_myInst, "DoCreateResource")) { -// PyObject* ro; -// ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); -// if (ro) { -// SWIG_GetPtrObj(ro, (void **)&rv, "_wxObject_p"); -// Py_DECREF(ro); -// } -// } -// wxPyEndBlockThreads(); -// return rv; -// } - -// bool CanHandle(wxXmlNode* a) { -// bool rv=FALSE; -// wxPyBeginBlockThreads(); -// if (wxPyCBH_findCallback(m_myInst, "CanHandle")) { -// PyObject* obj = wxPyConstructObject((void*)a, "wxXmlNode", 0); -// rv = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); -// Py_DECREF(obj); -// } -// wxPyEndBlockThreads(); -// return rv; -// } - - // accessors for protected members @@ -576,6 +558,33 @@ static PyObject *_wrap_wxXmlResource_ClearHandlers(PyObject *self, PyObject *arg return _resultobj; } +static PyObject *_wrap_wxXmlResource_AddSubclassFactory(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + wxPyXmlSubclassFactory * _arg0; + PyObject * _argo0 = 0; + char *_kwnames[] = { "factory", NULL }; + + self = self; + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"O:wxXmlResource_AddSubclassFactory",_kwnames,&_argo0)) + return NULL; + if (_argo0) { + if (_argo0 == Py_None) { _arg0 = NULL; } + else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxPyXmlSubclassFactory_p")) { + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxXmlResource_AddSubclassFactory. Expected _wxPyXmlSubclassFactory_p."); + return NULL; + } + } +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + wxXmlResource::AddSubclassFactory(_arg0); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} Py_INCREF(Py_None); + _resultobj = Py_None; + return _resultobj; +} + #define wxXmlResource_LoadMenu(_swigobj,_swigarg0) (_swigobj->LoadMenu(_swigarg0)) static PyObject *_wrap_wxXmlResource_LoadMenu(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; @@ -1521,6 +1530,70 @@ static PyObject *_wrap_wxXmlResource_GetFlags(PyObject *self, PyObject *args, Py return _resultobj; } +#define new_wxXmlSubclassFactory() (new wxPyXmlSubclassFactory()) +static PyObject *_wrap_new_wxXmlSubclassFactory(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + wxPyXmlSubclassFactory * _result; + char *_kwnames[] = { NULL }; + char _ptemp[128]; + + self = self; + if(!PyArg_ParseTupleAndKeywords(args,kwargs,":new_wxXmlSubclassFactory",_kwnames)) + return NULL; +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + _result = (wxPyXmlSubclassFactory *)new_wxXmlSubclassFactory(); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} if (_result) { + SWIG_MakePtr(_ptemp, (char *) _result,"_wxPyXmlSubclassFactory_p"); + _resultobj = Py_BuildValue("s",_ptemp); + } else { + Py_INCREF(Py_None); + _resultobj = Py_None; + } + return _resultobj; +} + +#define wxXmlSubclassFactory__setCallbackInfo(_swigobj,_swigarg0,_swigarg1) (_swigobj->_setCallbackInfo(_swigarg0,_swigarg1)) +static PyObject *_wrap_wxXmlSubclassFactory__setCallbackInfo(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + wxPyXmlSubclassFactory * _arg0; + PyObject * _arg1; + PyObject * _arg2; + PyObject * _argo0 = 0; + PyObject * _obj1 = 0; + PyObject * _obj2 = 0; + char *_kwnames[] = { "self","self","_class", NULL }; + + self = self; + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OOO:wxXmlSubclassFactory__setCallbackInfo",_kwnames,&_argo0,&_obj1,&_obj2)) + return NULL; + if (_argo0) { + if (_argo0 == Py_None) { _arg0 = NULL; } + else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxPyXmlSubclassFactory_p")) { + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxXmlSubclassFactory__setCallbackInfo. Expected _wxPyXmlSubclassFactory_p."); + return NULL; + } + } +{ + _arg1 = _obj1; +} +{ + _arg2 = _obj2; +} +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + wxXmlSubclassFactory__setCallbackInfo(_arg0,_arg1,_arg2); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} Py_INCREF(Py_None); + _resultobj = Py_None; + return _resultobj; +} + #define new_wxXmlProperty(_swigarg0,_swigarg1,_swigarg2) (new wxXmlProperty(_swigarg0,_swigarg1,_swigarg2)) static PyObject *_wrap_new_wxXmlProperty(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; @@ -4990,6 +5063,8 @@ static PyMethodDef xrccMethods[] = { { "wxXmlProperty_GetValue", (PyCFunction) _wrap_wxXmlProperty_GetValue, METH_VARARGS | METH_KEYWORDS }, { "wxXmlProperty_GetName", (PyCFunction) _wrap_wxXmlProperty_GetName, METH_VARARGS | METH_KEYWORDS }, { "new_wxXmlProperty", (PyCFunction) _wrap_new_wxXmlProperty, METH_VARARGS | METH_KEYWORDS }, + { "wxXmlSubclassFactory__setCallbackInfo", (PyCFunction) _wrap_wxXmlSubclassFactory__setCallbackInfo, METH_VARARGS | METH_KEYWORDS }, + { "new_wxXmlSubclassFactory", (PyCFunction) _wrap_new_wxXmlSubclassFactory, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_GetFlags", (PyCFunction) _wrap_wxXmlResource_GetFlags, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_Set", (PyCFunction) _wrap_wxXmlResource_Set, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_Get", (PyCFunction) _wrap_wxXmlResource_Get, METH_VARARGS | METH_KEYWORDS }, @@ -5011,6 +5086,7 @@ static PyMethodDef xrccMethods[] = { { "wxXmlResource_LoadMenuBarOnFrame", (PyCFunction) _wrap_wxXmlResource_LoadMenuBarOnFrame, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_LoadMenuBar", (PyCFunction) _wrap_wxXmlResource_LoadMenuBar, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_LoadMenu", (PyCFunction) _wrap_wxXmlResource_LoadMenu, METH_VARARGS | METH_KEYWORDS }, + { "wxXmlResource_AddSubclassFactory", (PyCFunction) _wrap_wxXmlResource_AddSubclassFactory, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_ClearHandlers", (PyCFunction) _wrap_wxXmlResource_ClearHandlers, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_InsertHandler", (PyCFunction) _wrap_wxXmlResource_InsertHandler, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_AddHandler", (PyCFunction) _wrap_wxXmlResource_AddHandler, METH_VARARGS | METH_KEYWORDS }, diff --git a/wxPython/contrib/xrc/xrc.i b/wxPython/contrib/xrc/xrc.i index 037e1eb214..f6f2f33cd5 100644 --- a/wxPython/contrib/xrc/xrc.i +++ b/wxPython/contrib/xrc/xrc.i @@ -48,6 +48,9 @@ static const wxString wxPyIconString(wxT("icon")); static const wxString wxPyFontString(wxT("font")); %} + +class wxPyXmlSubclassFactory; + //--------------------------------------------------------------------------- enum wxXmlResourceFlags @@ -128,6 +131,12 @@ public: // Removes all handlers void ClearHandlers(); + // Registers subclasses factory for use in XRC. This function is not meant + // for public use, please see the comment above wxXmlSubclassFactory + // definition. + static void AddSubclassFactory(wxPyXmlSubclassFactory *factory); + + // Loads menu from resource. Returns NULL on failure. wxMenu *LoadMenu(const wxString& name); @@ -215,6 +224,31 @@ XMLCTRL = XRCCTRL " //---------------------------------------------------------------------- +// wxXmlSubclassFactory + + +%{ +class wxPyXmlSubclassFactory : public wxXmlSubclassFactory +{ +public: + wxPyXmlSubclassFactory() {} + DEC_PYCALLBACK_OBJECT_STRING_pure(Create); + PYPRIVATE; +}; + +IMP_PYCALLBACK_OBJECT_STRING_pure(wxPyXmlSubclassFactory, wxXmlSubclassFactory, Create); +%} + + +%name(wxXmlSubclassFactory)class wxPyXmlSubclassFactory { +public: + wxPyXmlSubclassFactory(); + + void _setCallbackInfo(PyObject* self, PyObject* _class); + %pragma(python) addtomethod = "__init__:self._setCallbackInfo(self, wxXmlSubclassFactory)" +}; + + //---------------------------------------------------------------------- // In order to provide wrappers for wxXmlResourceHandler we need to also // provide the classes for representing and parsing XML. @@ -396,34 +430,6 @@ public: DEC_PYCALLBACK_OBJECT__pure(DoCreateResource); DEC_PYCALLBACK_BOOL_NODE_pure(CanHandle); -// wxObject* DoCreateResource() { -// wxObject* rv = NULL; -// wxPyBeginBlockThreads(); -// if (wxPyCBH_findCallback(m_myInst, "DoCreateResource")) { -// PyObject* ro; -// ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); -// if (ro) { -// SWIG_GetPtrObj(ro, (void **)&rv, "_wxObject_p"); -// Py_DECREF(ro); -// } -// } -// wxPyEndBlockThreads(); -// return rv; -// } - -// bool CanHandle(wxXmlNode* a) { -// bool rv=FALSE; -// wxPyBeginBlockThreads(); -// if (wxPyCBH_findCallback(m_myInst, "CanHandle")) { -// PyObject* obj = wxPyConstructObject((void*)a, "wxXmlNode", 0); -// rv = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); -// Py_DECREF(obj); -// } -// wxPyEndBlockThreads(); -// return rv; -// } - - // accessors for protected members diff --git a/wxPython/contrib/xrc/xrc.py b/wxPython/contrib/xrc/xrc.py index 9a10422a35..deaa024f34 100644 --- a/wxPython/contrib/xrc/xrc.py +++ b/wxPython/contrib/xrc/xrc.py @@ -152,6 +152,24 @@ def wxEmptyXmlResource(*_args,**_kwargs): return val +class wxXmlSubclassFactoryPtr : + def __init__(self,this): + self.this = this + self.thisown = 0 + def _setCallbackInfo(self, *_args, **_kwargs): + val = apply(xrcc.wxXmlSubclassFactory__setCallbackInfo,(self,) + _args, _kwargs) + return val + def __repr__(self): + return "" % (self.this,) +class wxXmlSubclassFactory(wxXmlSubclassFactoryPtr): + def __init__(self,*_args,**_kwargs): + self.this = apply(xrcc.new_wxXmlSubclassFactory,_args,_kwargs) + self.thisown = 1 + self._setCallbackInfo(self, wxXmlSubclassFactory) + + + + class wxXmlPropertyPtr : def __init__(self,this): self.this = this @@ -474,6 +492,8 @@ class wxXmlResourceHandler(wxXmlResourceHandlerPtr): #-------------- FUNCTION WRAPPERS ------------------ +wxXmlResource_AddSubclassFactory = xrcc.wxXmlResource_AddSubclassFactory + wxXmlResource_GetXRCID = xrcc.wxXmlResource_GetXRCID def wxXmlResource_Get(*_args, **_kwargs): @@ -515,3 +535,35 @@ wxXML_HTML_DOCUMENT_NODE = xrcc.wxXML_HTML_DOCUMENT_NODE wxTheXmlResource = wxXmlResource_Get() wx.wxXmlNodePtr = wxXmlNodePtr + + + + +#---------------------------------------------------------------------- +# Create a factory for handling the subclass property of the object tag. + + +def _my_import(name): + mod = __import__(name) + components = string.split(name, '.') + for comp in components[1:]: + mod = getattr(mod, comp) + return mod + + +class wxXmlSubclassFactory_Python(wxXmlSubclassFactory): + def __init__(self): + wxXmlSubclassFactory.__init__(self) + + def Create(self, className): + assert className.find('.') != -1, "Module name must be specified!" + mname = className[:className.rfind('.')] + cname = className[className.rfind('.')+1:] + module = _my_import(mname) + klass = getattr(module, cname) + inst = klass() + return inst + + +wxXmlResource_AddSubclassFactory(wxXmlSubclassFactory_Python()) + diff --git a/wxPython/demo/wxXmlResourceHandler.py b/wxPython/demo/wxXmlResourceHandler.py index dda5005d4e..69bcd621e1 100644 --- a/wxPython/demo/wxXmlResourceHandler.py +++ b/wxPython/demo/wxXmlResourceHandler.py @@ -11,7 +11,7 @@ resourceText = r''' 200,100 - + 10,10 diff --git a/wxPython/src/helpers.h b/wxPython/src/helpers.h index 46e95f6ca1..49a6545026 100644 --- a/wxPython/src/helpers.h +++ b/wxPython/src/helpers.h @@ -451,10 +451,10 @@ extern wxPyApp *wxPythonApp; #define IMP_PYCALLBACK__(CLASS, PCLASS, CBNAME) \ void CLASS::CBNAME() { \ bool found; \ - wxPyBeginBlockThreads(); \ + wxPyBeginBlockThreads(); \ if ((found = wxPyCBH_findCallback(m_myInst, #CBNAME))) \ wxPyCBH_callCallback(m_myInst, Py_BuildValue("()")); \ - wxPyEndBlockThreads(); \ + wxPyEndBlockThreads(); \ if (! found) \ PCLASS::CBNAME(); \ } \ @@ -1877,6 +1877,29 @@ extern wxPyApp *wxPythonApp; //--------------------------------------------------------------------------- +#define DEC_PYCALLBACK_OBJECT_STRING_pure(CBNAME) \ + wxObject* CBNAME(const wxString& a); + +#define IMP_PYCALLBACK_OBJECT_STRING_pure(CLASS, PCLASS, CBNAME) \ + wxObject* CLASS::CBNAME(const wxString& a) { \ + wxObject* rv = NULL; \ + wxPyBeginBlockThreads(); \ + if (wxPyCBH_findCallback(m_myInst, #CBNAME)) { \ + PyObject* so = wx2PyString(a); \ + PyObject* ro; \ + ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("(O)", so)); \ + if (ro) { \ + SWIG_GetPtrObj(ro, (void **)&rv, "_wxObject_p"); \ + Py_DECREF(ro); \ + } \ + Py_DECREF(so); \ + } \ + wxPyEndBlockThreads(); \ + return rv; \ + } + +//--------------------------------------------------------------------------- + #define DEC_PYCALLBACK_BOOL_NODE_pure(CBNAME) \ bool CBNAME(wxXmlNode* a);