diff --git a/wxPython/CHANGES.txt b/wxPython/CHANGES.txt index d6767d3b4e..2b2c3e4d51 100644 --- a/wxPython/CHANGES.txt +++ b/wxPython/CHANGES.txt @@ -12,6 +12,30 @@ Several bug fixes in wxWindows. Added wxHtmlFilter. +wxASSERT and related C++ runtime diagnostics are now converted to +Python exceptions. When an assert happens a wxPyAssertionError +(which derives from AssertionError) exception is created and when +control returns back to the Python code that invoked the C++ API it +will be raised. The same exception restrictions are in place as +before, namely that exceptions can't cross from one Python layer +through C++ to another Python layer. That simply means that if you +want to catch wxPyAssertionError or any other exception that you need +to do it before control returns to C++ at the end of your event +handler or callback code. There is some test code in demo/wxButton.py +you can use to play with this new feature. + +Added some methods to wxApp (SetAssertMode and GetAssertMode) that let +you control how C++ assertions are processed. Valid modes are: +wxPYAPP_ASSERT_SUPPRESS, wxPYAPP_ASSERT_EXCEPTION, and +wxPYAPP_ASSERT_DIALOG. Using _SUPPRESS will give you behavior like +the old "final" builds and the assert will be ignored, _EXCEPTION is +the new default described above, and _DIALOG is like the default in +2.3.3.1 and prior "hybrid" builds. You can also combine _EXCEPTION +and _DIALOG if you wish, although I don't know why you would. + +You can now overload OnInitGui, OnExit and OnAssert in your classes +derived from wxApp. + diff --git a/wxPython/demo/Main.py b/wxPython/demo/Main.py index 51458681d7..6df8b56c65 100644 --- a/wxPython/demo/Main.py +++ b/wxPython/demo/Main.py @@ -360,7 +360,7 @@ class wxPythonDemo(wxFrame): # Set up a TextCtrl on the Demo Code Notebook page self.txt = wxTextCtrl(self.nb, -1, - style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL) + style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL|wxTE_RICH2) self.nb.AddPage(self.txt, "Demo Code") diff --git a/wxPython/demo/run.py b/wxPython/demo/run.py index 82d702bb43..da5eb3732c 100755 --- a/wxPython/demo/run.py +++ b/wxPython/demo/run.py @@ -25,7 +25,9 @@ from wxPython.wx import * class Log: def WriteText(self, text): - sys.stdout.write(text) + if text[-1:] == '\n': + text = text[:-1] + wxLogMessage(text) write = WriteText @@ -38,6 +40,8 @@ class RunDemoApp(wxApp): def OnInit(self): wxInitAllImageHandlers() + wxLog_SetActiveTarget(wxLogStderr()) + frame = wxFrame(None, -1, "RunDemo: " + self.name, size=(0,0), style=wxNO_FULL_REPAINT_ON_RESIZE|wxDEFAULT_FRAME_STYLE) frame.CreateStatusBar() diff --git a/wxPython/demo/wxButton.py b/wxPython/demo/wxButton.py index 2a92effc12..b81618718a 100644 --- a/wxPython/demo/wxButton.py +++ b/wxPython/demo/wxButton.py @@ -19,19 +19,33 @@ class TestPanel(wxPanel): b = wxButton(self, 20, "HELLO AGAIN!", wxPoint(20, 60), wxSize(120, 45)) EVT_BUTTON(self, 20, self.OnClick) - b.SetToolTipString("This is a Hello button...") - bmp = images.getTest2Bitmap() - mask = wxMaskColour(bmp, wxBLUE) - bmp.SetMask(mask) + if 1: # a test case for catching wxPyAssertionError + #wxGetApp().SetAssertMode(wxPYAPP_ASSERT_SUPPRESS) + #wxGetApp().SetAssertMode(wxPYAPP_ASSERT_EXCEPTION) + #wxGetApp().SetAssertMode(wxPYAPP_ASSERT_DIALOG) + #wxGetApp().SetAssertMode(wxPYAPP_ASSERT_EXCEPTION | wxPYAPP_ASSERT_DIALOG) + + try: + bmp = wxBitmap("nosuchfile.bmp", wxBITMAP_TYPE_BMP) + mask = wxMaskColour(bmp, wxBLUE) + except wxPyAssertionError: + self.log.write("Caught wxPyAssertionError! I will fix the problem.\n") + bmp = images.getTest2Bitmap() + mask = wxMaskColour(bmp, wxBLUE) + else: + bmp = images.getTest2Bitmap() + mask = wxMaskColour(bmp, wxBLUE) + + bmp.SetMask(mask) wxBitmapButton(self, 30, bmp, wxPoint(160, 20), wxSize(bmp.GetWidth()+10, bmp.GetHeight()+10)) EVT_BUTTON(self, 30, self.OnClick) def OnClick(self, event): - self.log.WriteText("Click! (%d)\n" % event.GetId()) + self.log.write("Click! (%d)\n" % event.GetId()) #---------------------------------------------------------------------- @@ -43,15 +57,19 @@ def runTest(frame, nb, log): #---------------------------------------------------------------------- +overview = """ +

wxButton

+A button is a control that contains a text string or a bitmap and cab be +placed on nearly any kind of window. - - - - - - -overview = """\ + """ + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/src/_extras.py b/wxPython/src/_extras.py index b2fb86c8bd..1c53a4863b 100644 --- a/wxPython/src/_extras.py +++ b/wxPython/src/_extras.py @@ -598,6 +598,9 @@ wxSystemSettings_GetSystemColour = wxSystemSettings_GetColour wxSystemSettings_GetSystemFont = wxSystemSettings_GetFont wxSystemSettings_GetSystemMetric = wxSystemSettings_GetMetric + +wxPyAssertionError = wxc.wxPyAssertionError + #---------------------------------------------------------------------- # wxGTK sets the locale when initialized. Doing this at the Python # level should set it up to match what GTK is doing at the C level. @@ -608,8 +611,6 @@ if wxPlatform == "__WXGTK__": except: pass - - #---------------------------------------------------------------------- # wxWindows version numbers. wxPython version is in __version__. @@ -775,6 +776,7 @@ class wxApp(wxPyApp): if redirect: self.RedirectStdio(filename) + # this initializes wxWindows and then calls our OnInit _wxStart(self.OnInit) @@ -801,7 +803,7 @@ class wxApp(wxPyApp): if filename: sys.stdout = sys.stderr = open(filename, 'a') else: - self.stdioWin = self.outputWindowClass() # wxPyOnDemandOutputWindow + self.stdioWin = self.outputWindowClass() sys.stdout = sys.stderr = self.stdioWin diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index 74b75a67bf..3a21537fb3 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -67,6 +67,11 @@ wxMutex* wxPyTMutex = NULL; #endif +static PyObject* wxPython_dict = NULL; +static PyObject* wxPyPtrTypeMap = NULL; +static PyObject* wxPyAssertionError = NULL; + + #ifdef __WXMSW__ // If building for win32... //---------------------------------------------------------------------- // This gets run when the DLL is loaded. We just need to save a handle. @@ -90,15 +95,19 @@ BOOL WINAPI DllMain( // Classes for implementing the wxp main application shell. //---------------------------------------------------------------------- +IMPLEMENT_ABSTRACT_CLASS(wxPyApp, wxApp); + wxPyApp::wxPyApp() { + m_assertMode = wxPYAPP_ASSERT_EXCEPTION; } + wxPyApp::~wxPyApp() { } -// This one isn't acutally called... See __wxStart() +// This one isn't acutally called... We fake it with __wxStart() bool wxPyApp::OnInit() { return FALSE; } @@ -125,6 +134,91 @@ int wxPyApp::MainLoop() { } +bool wxPyApp::OnInitGui() { + bool rval=TRUE; + wxApp::OnInitGui(); // in this case always call the base class version + // wxPyBeginBlockThreads(); *** only called from within __wxStart so we already have the GIL + if (wxPyCBH_findCallback(m_myInst, "OnInitGui")) + rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("()")); + // wxPyEndBlockThreads(); + return rval; +} + + +int wxPyApp::OnExit() { + int rval=0; + wxPyBeginBlockThreads(); + if (wxPyCBH_findCallback(m_myInst, "OnExit")) + rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("()")); + wxPyEndBlockThreads(); + wxApp::OnExit(); // in this case always call the base class version + return rval; +} + + +void wxPyApp::OnAssert(const wxChar *file, + int line, + const wxChar *cond, + const wxChar *msg) { + + // If the OnAssert is overloaded in the Python class then call it... + bool found; + wxPyBeginBlockThreads(); + if ((found = wxPyCBH_findCallback(m_myInst, "OnAssert"))) { + PyObject* fso = wx2PyString(file); + PyObject* cso = wx2PyString(file); + PyObject* mso; + if (msg != NULL) + mso = wx2PyString(file); + else { + mso = Py_None; Py_INCREF(Py_None); + } + wxPyCBH_callCallback(m_myInst, Py_BuildValue("(OiOO)", fso, line, cso, mso)); + Py_DECREF(fso); + Py_DECREF(cso); + Py_DECREF(mso); + } + wxPyEndBlockThreads(); + + // ...otherwise do our own thing with it + if (! found) { + // ignore it? + if (m_assertMode & wxPYAPP_ASSERT_SUPPRESS) + return; + + // turn it into a Python exception? + if (m_assertMode & wxPYAPP_ASSERT_EXCEPTION) { + wxString buf; + buf.Alloc(4096); + buf.Printf(wxT("C++ assertion \"%s\" failed in %s(%d)"), cond, file, line); + if (msg != NULL) { + buf += wxT(": "); + buf += msg; + } + + // Send it to the normal log destination, but only if + // not _DIALOG because it will call this too + if ( !(m_assertMode & wxPYAPP_ASSERT_DIALOG)) + wxLogDebug(buf); + + // set the exception + wxPyBeginBlockThreads(); + PyObject* s = wx2PyString(buf); + PyErr_SetObject(wxPyAssertionError, s); + Py_DECREF(s); + wxPyEndBlockThreads(); + + // Now when control returns to whatever API wrapper was called from + // Python it should detect that an exception is set and will return + // NULL, signalling the exception to Python. + } + + // do the normal wx assert dialog? + if (m_assertMode & wxPYAPP_ASSERT_DIALOG) + wxApp::OnAssert(file, line, cond, msg); + } +} + //--------------------------------------------------------------------- //---------------------------------------------------------------------- @@ -169,7 +263,7 @@ static wxChar* wxPyCopyWString(const wxChar *src) // This is where we pick up the first part of the wxEntry functionality... // The rest is in __wxStart and __wxCleanup. This function is called when // wxcmodule is imported. (Before there is a wxApp object.) -void __wxPreStart() +void __wxPreStart(PyObject* moduleDict) { #ifdef __WXMSW__ @@ -184,6 +278,11 @@ void __wxPreStart() wxApp::CheckBuildOptions(wxBuildOptions()); + wxPyAssertionError = PyErr_NewException("wxPython.wxc.wxPyAssertionError", + PyExc_AssertionError, NULL); + PyDict_SetItemString(moduleDict, "wxPyAssertionError", wxPyAssertionError); + + // Bail out if there is already a wxApp created. This means that the // toolkit has already been initialized, as in embedding wxPython in // a C++ wxWindows app, so we don't need to call wxEntryStart. @@ -292,9 +391,6 @@ void __wxCleanup() { -static PyObject* wxPython_dict = NULL; -static PyObject* wxPyPtrTypeMap = NULL; - PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args) { diff --git a/wxPython/src/helpers.h b/wxPython/src/helpers.h index 1ca7acd7da..46e95f6ca1 100644 --- a/wxPython/src/helpers.h +++ b/wxPython/src/helpers.h @@ -20,21 +20,7 @@ typedef unsigned char byte; - -class wxPyApp: public wxApp -{ -public: - wxPyApp(); - ~wxPyApp(); - bool OnInit(); - int MainLoop(); -}; - -extern wxPyApp *wxPythonApp; - -//---------------------------------------------------------------------- - -void __wxPreStart(); +void __wxPreStart(PyObject*); PyObject* __wxStart(PyObject*, PyObject* args); void __wxCleanup(); @@ -404,19 +390,59 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); //--------------------------------------------------------------------------- + +// This is used in C++ classes that need to be able to make callback to +// "overloaded" python methods + +#define PYPRIVATE \ + void _setCallbackInfo(PyObject* self, PyObject* _class, int incref=1) { \ + wxPyCBH_setCallbackInfo(m_myInst, self, _class, incref); \ + } \ + private: wxPyCallbackHelper m_myInst + + +//--------------------------------------------------------------------------- + +enum { + wxPYAPP_ASSERT_SUPPRESS = 1, + wxPYAPP_ASSERT_EXCEPTION = 2, + wxPYAPP_ASSERT_DIALOG = 4 +}; + +class wxPyApp: public wxApp +{ + DECLARE_ABSTRACT_CLASS(wxPyApp); + +public: + wxPyApp(); + ~wxPyApp(); + bool OnInit(); + int MainLoop(); + + int GetAssertMode() { return m_assertMode; } + void SetAssertMode(int mode) { m_assertMode = mode; } + + virtual bool OnInitGui(); + virtual int OnExit(); + virtual void OnAssert(const wxChar *file, + int line, + const wxChar *cond, + const wxChar *msg); + // virtual int FilterEvent(wxEvent& event); // This one too???? + + PYPRIVATE; + int m_assertMode; +}; + +extern wxPyApp *wxPythonApp; + + +//---------------------------------------------------------------------- // These macros are used to implement the virtual methods that should // redirect to a Python method if one exists. The names designate the // return type, if any, as well as any parameter types. //--------------------------------------------------------------------------- -#define PYPRIVATE \ - void _setCallbackInfo(PyObject* self, PyObject* _class, int incref=1) { \ - wxPyCBH_setCallbackInfo(m_myInst, self, _class, incref); \ - } \ - private: wxPyCallbackHelper m_myInst - -//--------------------------------------------------------------------------- - #define DEC_PYCALLBACK__(CBNAME) \ void CBNAME(); \ void base_##CBNAME(); diff --git a/wxPython/src/msw/wx.cpp b/wxPython/src/msw/wx.cpp index 99bb78a663..47064173eb 100644 --- a/wxPython/src/msw/wx.cpp +++ b/wxPython/src/msw/wx.cpp @@ -1022,6 +1022,44 @@ static PyObject *_wrap_delete_wxPyApp(PyObject *self, PyObject *args, PyObject * return _resultobj; } +#define wxPyApp__setCallbackInfo(_swigobj,_swigarg0,_swigarg1) (_swigobj->_setCallbackInfo(_swigarg0,_swigarg1)) +static PyObject *_wrap_wxPyApp__setCallbackInfo(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + wxPyApp * _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:wxPyApp__setCallbackInfo",_kwnames,&_argo0,&_obj1,&_obj2)) + return NULL; + if (_argo0) { + if (_argo0 == Py_None) { _arg0 = NULL; } + else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxPyApp_p")) { + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxPyApp__setCallbackInfo. Expected _wxPyApp_p."); + return NULL; + } + } +{ + _arg1 = _obj1; +} +{ + _arg2 = _obj2; +} +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + wxPyApp__setCallbackInfo(_arg0,_arg1,_arg2); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} Py_INCREF(Py_None); + _resultobj = Py_None; + return _resultobj; +} + #define wxPyApp_GetAppName(_swigobj) (_swigobj->GetAppName()) static PyObject *_wrap_wxPyApp_GetAppName(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; @@ -1748,7 +1786,66 @@ static PyObject *_wrap_wxPyApp_SetUseBestVisual(PyObject *self, PyObject *args, return _resultobj; } +#define wxPyApp_GetAssertMode(_swigobj) (_swigobj->GetAssertMode()) +static PyObject *_wrap_wxPyApp_GetAssertMode(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + int _result; + wxPyApp * _arg0; + PyObject * _argo0 = 0; + char *_kwnames[] = { "self", NULL }; + + self = self; + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"O:wxPyApp_GetAssertMode",_kwnames,&_argo0)) + return NULL; + if (_argo0) { + if (_argo0 == Py_None) { _arg0 = NULL; } + else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxPyApp_p")) { + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxPyApp_GetAssertMode. Expected _wxPyApp_p."); + return NULL; + } + } +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + _result = (int )wxPyApp_GetAssertMode(_arg0); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} _resultobj = Py_BuildValue("i",_result); + return _resultobj; +} + +#define wxPyApp_SetAssertMode(_swigobj,_swigarg0) (_swigobj->SetAssertMode(_swigarg0)) +static PyObject *_wrap_wxPyApp_SetAssertMode(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + wxPyApp * _arg0; + int _arg1; + PyObject * _argo0 = 0; + char *_kwnames[] = { "self","mode", NULL }; + + self = self; + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"Oi:wxPyApp_SetAssertMode",_kwnames,&_argo0,&_arg1)) + return NULL; + if (_argo0) { + if (_argo0 == Py_None) { _arg0 = NULL; } + else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxPyApp_p")) { + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxPyApp_SetAssertMode. Expected _wxPyApp_p."); + return NULL; + } + } +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + wxPyApp_SetAssertMode(_arg0,_arg1); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} Py_INCREF(Py_None); + _resultobj = Py_None; + return _resultobj; +} + static PyMethodDef wxcMethods[] = { + { "wxPyApp_SetAssertMode", (PyCFunction) _wrap_wxPyApp_SetAssertMode, METH_VARARGS | METH_KEYWORDS }, + { "wxPyApp_GetAssertMode", (PyCFunction) _wrap_wxPyApp_GetAssertMode, METH_VARARGS | METH_KEYWORDS }, { "wxPyApp_SetUseBestVisual", (PyCFunction) _wrap_wxPyApp_SetUseBestVisual, METH_VARARGS | METH_KEYWORDS }, { "wxPyApp_SetVendorName", (PyCFunction) _wrap_wxPyApp_SetVendorName, METH_VARARGS | METH_KEYWORDS }, { "wxPyApp_SetTopWindow", (PyCFunction) _wrap_wxPyApp_SetTopWindow, METH_VARARGS | METH_KEYWORDS }, @@ -1772,6 +1869,7 @@ static PyMethodDef wxcMethods[] = { { "wxPyApp_GetClassName", (PyCFunction) _wrap_wxPyApp_GetClassName, METH_VARARGS | METH_KEYWORDS }, { "wxPyApp_GetAuto3D", (PyCFunction) _wrap_wxPyApp_GetAuto3D, METH_VARARGS | METH_KEYWORDS }, { "wxPyApp_GetAppName", (PyCFunction) _wrap_wxPyApp_GetAppName, METH_VARARGS | METH_KEYWORDS }, + { "wxPyApp__setCallbackInfo", (PyCFunction) _wrap_wxPyApp__setCallbackInfo, METH_VARARGS | METH_KEYWORDS }, { "delete_wxPyApp", (PyCFunction) _wrap_delete_wxPyApp, METH_VARARGS | METH_KEYWORDS }, { "new_wxPyApp", (PyCFunction) _wrap_new_wxPyApp, METH_VARARGS | METH_KEYWORDS }, { "wxApp_CleanUp", (PyCFunction) _wrap_wxApp_CleanUp, METH_VARARGS | METH_KEYWORDS }, @@ -2672,6 +2770,9 @@ SWIGEXPORT(void) initwxc() { PyDict_SetItemString(d,"cvar", SWIG_globals); SWIG_addvarlink(SWIG_globals,"wxDefaultPosition",_wrap_wxDefaultPosition_get, _wrap_wxDefaultPosition_set); SWIG_addvarlink(SWIG_globals,"wxDefaultSize",_wrap_wxDefaultSize_get, _wrap_wxDefaultSize_set); + PyDict_SetItemString(d,"wxPYAPP_ASSERT_SUPPRESS", PyInt_FromLong((long) wxPYAPP_ASSERT_SUPPRESS)); + PyDict_SetItemString(d,"wxPYAPP_ASSERT_EXCEPTION", PyInt_FromLong((long) wxPYAPP_ASSERT_EXCEPTION)); + PyDict_SetItemString(d,"wxPYAPP_ASSERT_DIALOG", PyInt_FromLong((long) wxPYAPP_ASSERT_DIALOG)); // Make our API structure a CObject so other modules can import it // from this module. @@ -2680,7 +2781,7 @@ SWIGEXPORT(void) initwxc() { Py_XDECREF(v); - __wxPreStart(); // initialize the GUI toolkit, if needed. + __wxPreStart(d); // initialize the GUI toolkit, if needed. // Since these modules are all linked together, initialize them now diff --git a/wxPython/src/msw/wx.py b/wxPython/src/msw/wx.py index 61050b8fdd..af5dcc976d 100644 --- a/wxPython/src/msw/wx.py +++ b/wxPython/src/msw/wx.py @@ -49,6 +49,9 @@ class wxPyAppPtr(wxEvtHandlerPtr): def __del__(self,wxc=wxc): if self.thisown == 1 : wxc.delete_wxPyApp(self) + def _setCallbackInfo(self, *_args, **_kwargs): + val = apply(wxc.wxPyApp__setCallbackInfo,(self,) + _args, _kwargs) + return val def GetAppName(self, *_args, **_kwargs): val = apply(wxc.wxPyApp_GetAppName,(self,) + _args, _kwargs) return val @@ -118,12 +121,20 @@ class wxPyAppPtr(wxEvtHandlerPtr): def SetUseBestVisual(self, *_args, **_kwargs): val = apply(wxc.wxPyApp_SetUseBestVisual,(self,) + _args, _kwargs) return val + def GetAssertMode(self, *_args, **_kwargs): + val = apply(wxc.wxPyApp_GetAssertMode,(self,) + _args, _kwargs) + return val + def SetAssertMode(self, *_args, **_kwargs): + val = apply(wxc.wxPyApp_SetAssertMode,(self,) + _args, _kwargs) + return val def __repr__(self): return "" % (self.this,) class wxPyApp(wxPyAppPtr): def __init__(self,*_args,**_kwargs): self.this = apply(wxc.new_wxPyApp,_args,_kwargs) self.thisown = 1 + self._setCallbackInfo(self, wxPyApp) + self._setOORInfo(self) @@ -926,6 +937,9 @@ __version__ = wxc.__version__ cvar = wxc.cvar wxDefaultPosition = wxPointPtr(wxc.cvar.wxDefaultPosition) wxDefaultSize = wxSizePtr(wxc.cvar.wxDefaultSize) +wxPYAPP_ASSERT_SUPPRESS = wxc.wxPYAPP_ASSERT_SUPPRESS +wxPYAPP_ASSERT_EXCEPTION = wxc.wxPYAPP_ASSERT_EXCEPTION +wxPYAPP_ASSERT_DIALOG = wxc.wxPYAPP_ASSERT_DIALOG #-------------- USER INCLUDE ----------------------- @@ -1530,6 +1544,9 @@ wxSystemSettings_GetSystemColour = wxSystemSettings_GetColour wxSystemSettings_GetSystemFont = wxSystemSettings_GetFont wxSystemSettings_GetSystemMetric = wxSystemSettings_GetMetric + +wxPyAssertionError = wxc.wxPyAssertionError + #---------------------------------------------------------------------- # wxGTK sets the locale when initialized. Doing this at the Python # level should set it up to match what GTK is doing at the C level. @@ -1540,8 +1557,6 @@ if wxPlatform == "__WXGTK__": except: pass - - #---------------------------------------------------------------------- # wxWindows version numbers. wxPython version is in __version__. @@ -1707,6 +1722,7 @@ class wxApp(wxPyApp): if redirect: self.RedirectStdio(filename) + # this initializes wxWindows and then calls our OnInit _wxStart(self.OnInit) @@ -1733,7 +1749,7 @@ class wxApp(wxPyApp): if filename: sys.stdout = sys.stderr = open(filename, 'a') else: - self.stdioWin = self.outputWindowClass() # wxPyOnDemandOutputWindow + self.stdioWin = self.outputWindowClass() sys.stdout = sys.stderr = self.stdioWin diff --git a/wxPython/src/wx.i b/wxPython/src/wx.i index 476b7c1dde..a5430b785d 100644 --- a/wxPython/src/wx.i +++ b/wxPython/src/wx.i @@ -65,6 +65,13 @@ wxSize wxDefaultSize; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- +enum { + wxPYAPP_ASSERT_SUPPRESS = 1, + wxPYAPP_ASSERT_EXCEPTION = 2, + wxPYAPP_ASSERT_DIALOG = 4 +}; + + class wxPyApp : public wxEvtHandler { public: %addmethods { @@ -76,6 +83,11 @@ public: ~wxPyApp(); + void _setCallbackInfo(PyObject* self, PyObject* _class); + %pragma(python) addtomethod = "__init__:self._setCallbackInfo(self, wxPyApp)" + %pragma(python) addtomethod = "__init__:self._setOORInfo(self)" + + wxString GetAppName(); #ifdef __WXMSW__ bool GetAuto3D(); @@ -105,6 +117,9 @@ public: void SetTopWindow(wxWindow* window); void SetVendorName(const wxString& name); void SetUseBestVisual(bool flag); + + int GetAssertMode(); + void SetAssertMode(int mode); }; %inline %{ @@ -226,7 +241,7 @@ static wxPyCoreAPI API = { Py_XDECREF(v); - __wxPreStart(); // initialize the GUI toolkit, if needed. + __wxPreStart(d); // initialize the GUI toolkit, if needed. // Since these modules are all linked together, initialize them now