]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/src/helpers.cpp
*** empty log message ***
[wxWidgets.git] / wxPython / src / helpers.cpp
index 32578bf5f6832591e77e785c8162a8b9cf01a2d9..4495879274c95ffd9e6a9a5036046aead26d5875 100644 (file)
@@ -105,6 +105,11 @@ int  wxPyApp::MainLoop(void) {
 //---------------------------------------------------------------------
 //----------------------------------------------------------------------
 
+#ifdef __WXMSW__
+#include "wx/msw/msvcrt.h"
+#endif
+
+
 int  WXDLLEXPORT wxEntryStart( int argc, char** argv );
 int  WXDLLEXPORT wxEntryInitGui();
 void WXDLLEXPORT wxEntryCleanup();
@@ -121,6 +126,11 @@ static char* __nullArgv[1] = { 0 };
 // wxcmodule is imported.  (Before there is a wxApp object.)
 void __wxPreStart()
 {
+
+#ifdef __WXMSW__
+//    wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
+#endif
+
 #ifdef WXP_WITH_THREAD
     PyEval_InitThreads();
     wxPyEventThreadState = PyThreadState_Get();
@@ -158,11 +168,12 @@ PyObject* __wxStart(PyObject* /* self */, PyObject* args)
     if (!PyArg_ParseTuple(args, "O", &onInitFunc))
         return NULL;
 
+#if 0  // Try it out without this check, soo how it does...
     if (wxTopLevelWindows.Number() > 0) {
         PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!");
         return NULL;
     }
-
+#endif
 
     // This is the next part of the wxEntry functionality...
     PyObject* sysargv = PySys_GetObject("argv");
@@ -170,7 +181,7 @@ PyObject* __wxStart(PyObject* /* self */, PyObject* args)
     char** argv = new char*[argc+1];
     int x;
     for(x=0; x<argc; x++)
-        argv[x] = PyString_AsString(PyList_GetItem(sysargv, x));
+        argv[x] = copystring(PyString_AsString(PyList_GetItem(sysargv, x)));
     argv[argc] = NULL;
 
     wxPythonApp->argc = argc;
@@ -245,7 +256,17 @@ PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
 
 //---------------------------------------------------------------------------
 
-PyObject* wxPyConstructObject(void* ptr, const char* className) {
+PyObject* wxPyConstructObject(void* ptr,
+                                 const char* className,
+                                 int setThisOwn) {
+    PyObject* obj;
+    PyObject* arg;
+
+    if (!ptr) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+
     char    buff[64];               // should always be big enough...
     char    swigptr[64];
 
@@ -255,14 +276,26 @@ PyObject* wxPyConstructObject(void* ptr, const char* className) {
     sprintf(buff, "%sPtr", className);
     PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
     if (! classobj) {
-        Py_INCREF(Py_None);
-        return Py_None;
+        //Py_INCREF(Py_None);
+        //return Py_None;
+        char temp[128];
+        sprintf(temp,
+                "*** Unknown class name %s, tell Robin about it please ***",
+                buff);
+        obj = PyString_FromString(temp);
+        return obj;
     }
 
-    PyObject* arg = Py_BuildValue("(s)", swigptr);
-    PyObject* obj = PyInstance_New(classobj, arg, NULL);
+    arg = Py_BuildValue("(s)", swigptr);
+    obj = PyInstance_New(classobj, arg, NULL);
     Py_DECREF(arg);
 
+    if (setThisOwn) {
+        PyObject* one = PyInt_FromLong(1);
+        PyObject_SetAttrString(obj, "thisown", one);
+        Py_DECREF(one);
+    }
+
     return obj;
 }
 
@@ -393,9 +426,9 @@ wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper& other) {
 }
 
 
-void wxPyCallbackHelper::setSelf(PyObject* self, PyObject* _class, int incref) {
+void wxPyCallbackHelper::setSelf(PyObject* self, PyObject* klass, int incref) {
     m_self = self;
-    m_class = _class;
+    m_class = klass;
     m_incRef = incref;
     if (incref) {
         Py_INCREF(m_self);
@@ -407,12 +440,12 @@ void wxPyCallbackHelper::setSelf(PyObject* self, PyObject* _class, int incref) {
 // If the object (m_self) has an attibute of the given name, and if that
 // attribute is a method, and if that method's class is not from a base class,
 // then we'll save a pointer to the method so callCallback can call it.
-bool wxPyCallbackHelper::findCallback(const wxString& name) const {
+bool wxPyCallbackHelper::findCallback(const char* name) const {
     wxPyCallbackHelper* self = (wxPyCallbackHelper*)this; // cast away const
     self->m_lastFound = NULL;
-    if (m_self && PyObject_HasAttrString(m_self, (char*)name.c_str())) {
+    if (m_self && PyObject_HasAttrString(m_self, (char*)name)) {
         PyObject* method;
-        method = PyObject_GetAttrString(m_self, (char*)name.c_str());
+        method = PyObject_GetAttrString(m_self, (char*)name);
 
         if (PyMethod_Check(method) &&
             ((PyMethod_GET_CLASS(method) == m_class) ||
@@ -420,6 +453,9 @@ bool wxPyCallbackHelper::findCallback(const wxString& name) const {
 
             self->m_lastFound = method;
         }
+        else {
+            Py_DECREF(method);
+        }
     }
     return m_lastFound != NULL;
 }
@@ -441,10 +477,17 @@ int wxPyCallbackHelper::callCallback(PyObject* argTuple) const {
 // Invoke the Python callable object, returning the raw PyObject return
 // value.  Caller should DECREF the return value and also call PyEval_SaveThread.
 PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) const {
-    PyObject*   result;
+    wxPyCallbackHelper* self = (wxPyCallbackHelper*)this; // cast away const
+    PyObject* result;
 
-    result = PyEval_CallObject(m_lastFound, argTuple);
+    // Save a copy of the pointer in case the callback generates another
+    // callback.  In that case m_lastFound will have a different value when
+    // it gets back here...
+    PyObject* method = m_lastFound;
+
+    result = PyEval_CallObject(method, argTuple);
     Py_DECREF(argTuple);
+    Py_DECREF(method);
     if (!result) {
         PyErr_Print();
     }
@@ -456,7 +499,7 @@ PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) const {
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 // These classes can be derived from in Python and passed through the event
-// system without loosing anything.  They do this by keeping a reference to
+// system without losing anything.  They do this by keeping a reference to
 // themselves and some special case handling in wxPyCallback::EventThunker.
 
 
@@ -541,20 +584,26 @@ wxPyTimer::~wxPyTimer() {
 }
 
 void wxPyTimer::Notify() {
-    bool doSave = wxPyRestoreThread();
-
-    PyObject*   result;
-    PyObject*   args = Py_BuildValue("()");
+    if (!func || func == Py_None) {
+        wxTimer::Notify();
+    }
+    else {
+        bool doSave = wxPyRestoreThread();
+
+        PyObject*   result;
+        PyObject*   args = Py_BuildValue("()");
+
+        result = PyEval_CallObject(func, args);
+        Py_DECREF(args);
+        if (result) {
+            Py_DECREF(result);
+            PyErr_Clear();
+        } else {
+            PyErr_Print();
+        }
 
-    result = PyEval_CallObject(func, args);
-    Py_DECREF(args);
-    if (result) {
-        Py_DECREF(result);
-        PyErr_Clear();
-    } else {
-        PyErr_Print();
+        wxPySaveThread(doSave);
     }
-    wxPySaveThread(doSave);
 }
 
 
@@ -961,7 +1010,7 @@ bool wxColour_helper(PyObject* source, wxColour** obj) {
     }
 
  error:
-    PyErr_SetString(PyExc_TypeError, "Expected a wxColour object or a string containing a colour name or #RRGGBB.");
+    PyErr_SetString(PyExc_TypeError, "Expected a wxColour object or a string containing a colour name or '#RRGGBB'.");
     return FALSE;
 }
 
@@ -972,3 +1021,4 @@ bool wxColour_helper(PyObject* source, wxColour** obj) {
 
 
 
+