wxASSERT and others are converted to Python Exceptions.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@17446 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user