X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4152e8b9fd8679a53ecbb58312f5db3fd346b7ba..4e1c35f810f574af79e649fa37171dfa7fc775ee:/wxPython/src/helpers.cpp diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index bf1d3402f3..a1be4c1611 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -30,6 +30,12 @@ #endif +//---------------------------------------------------------------------- + +#if PYTHON_API_VERSION <= 1007 && wxUSE_UNICODE +#error Python must support Unicode to use wxWindows Unicode +#endif + //---------------------------------------------------------------------- #ifdef __WXGTK__ @@ -41,6 +47,7 @@ int WXDLLEXPORT wxEntryInitGui(); void WXDLLEXPORT wxEntryCleanup(); wxPyApp* wxPythonApp = NULL; // Global instance of application object +bool wxPyDoCleanup = FALSE; #ifdef WXP_WITH_THREAD @@ -120,6 +127,42 @@ int wxPyApp::MainLoop() { //---------------------------------------------------------------------- +static char* wxPyCopyCString(const wxChar* src) +{ + wxWX2MBbuf buff = (wxWX2MBbuf)wxConvCurrent->cWX2MB(src); + size_t len = strlen(buff); + char* dest = new char[len+1]; + strcpy(dest, buff); + return dest; +} + +#if wxUSE_UNICODE +static char* wxPyCopyCString(const char* src) // we need a char version too +{ + size_t len = strlen(src); + char* dest = new char[len+1]; + strcpy(dest, src); + return dest; +} +#endif + +static wxChar* wxPyCopyWString(const char *src) +{ + //wxMB2WXbuf buff = wxConvCurrent->cMB2WX(src); + wxString str(src, *wxConvCurrent); + return copystring(str); +} + +#if wxUSE_UNICODE +static wxChar* wxPyCopyWString(const wxChar *src) +{ + return copystring(src); +} +#endif + + +//---------------------------------------------------------------------- + // 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.) @@ -142,6 +185,7 @@ void __wxPreStart() if (wxTopLevelWindows.Number() > 0) return; + wxPyDoCleanup = TRUE; int argc = 0; char** argv = NULL; @@ -150,8 +194,15 @@ void __wxPreStart() argc = PyList_Size(sysargv); argv = new char*[argc+1]; int x; - for(x=0; xargc = argc; wxPythonApp->argv = argv; @@ -223,7 +282,8 @@ PyObject* __wxStart(PyObject* /* self */, PyObject* args) void __wxCleanup() { - wxEntryCleanup(); + if (wxPyDoCleanup) + wxEntryCleanup(); #ifdef WXP_WITH_THREAD delete wxPyTMutex; wxPyTMutex = NULL; @@ -238,6 +298,7 @@ void __wxCleanup() { static PyObject* wxPython_dict = NULL; static PyObject* wxPyPtrTypeMap = NULL; + PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args) { @@ -271,11 +332,58 @@ PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args) #endif PyDict_SetItemString(wxPython_dict, "wxPlatform", PyString_FromString(wxPlatform)); + PyDict_SetItemString(wxPython_dict, "wxUSE_UNICODE", PyInt_FromLong(wxUSE_UNICODE)); Py_INCREF(Py_None); return Py_None; } +//--------------------------------------------------------------------------- + +void wxPyClientData_dtor(wxPyClientData* self) { + wxPyBeginBlockThreads(); + Py_DECREF(self->m_obj); + wxPyEndBlockThreads(); +} + +void wxPyUserData_dtor(wxPyUserData* self) { + wxPyBeginBlockThreads(); + Py_DECREF(self->m_obj); + wxPyEndBlockThreads(); +} + + +// This is called when an OOR controled object is being destroyed. Although +// the C++ object is going away there is no way to force the Python object +// (and all references to it) to die too. This causes problems (crashes) in +// wxPython when a python shadow object attempts to call a C++ method using +// the now bogus pointer... So to try and prevent this we'll do a little black +// magic and change the class of the python instance to a class that will +// raise an exception for any attempt to call methods with it. See +// _wxPyDeadObject in _extras.py for the implementation of this class. +void wxPyOORClientData_dtor(wxPyOORClientData* self) { + + static PyObject* deadObjectClass = NULL; + + wxPyBeginBlockThreads(); + if (deadObjectClass == NULL) { + deadObjectClass = PyDict_GetItemString(wxPython_dict, "_wxPyDeadObject"); + wxASSERT_MSG(deadObjectClass != NULL, wxT("Can't get _wxPyDeadObject class!")); + Py_INCREF(deadObjectClass); + } + + // Clear the instance's dictionary, put the name of the old class into the + // instance, and then reset the class to be the dead class. + if (self->m_obj->ob_refcnt > 1) { // but only if there is more than one reference + wxASSERT_MSG(PyInstance_Check(self->m_obj), wxT("m_obj not an instance!?!?!")); + PyInstanceObject* inst = (PyInstanceObject*)self->m_obj; + PyDict_Clear(inst->in_dict); + PyDict_SetItemString(inst->in_dict, "_name", inst->in_class->cl_name); + inst->in_class = (PyClassObject*)deadObjectClass; + Py_INCREF(deadObjectClass); + } + wxPyEndBlockThreads(); +} //--------------------------------------------------------------------------- // Stuff used by OOR to find the right wxPython class type to return and to @@ -286,6 +394,7 @@ PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args) // is not the same as the shadow class name, for example wxPyTreeCtrl // vs. wxTreeCtrl. It needs to be referenced in Python as well as from C++, // so we'll just make it a Python dictionary in the wx module's namespace. +// (See __wxSetDictionary) void wxPyPtrTypeMap_Add(const char* commonName, const char* ptrName) { if (! wxPyPtrTypeMap) wxPyPtrTypeMap = PyDict_New(); @@ -296,14 +405,14 @@ void wxPyPtrTypeMap_Add(const char* commonName, const char* ptrName) { -PyObject* wxPyClassExists(const char* className) { +PyObject* wxPyClassExists(const wxString& className) { if (!className) return NULL; char buff[64]; // should always be big enough... - sprintf(buff, "%sPtr", className); + sprintf(buff, "%sPtr", className.mbc_str()); PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff); return classobj; // returns NULL if not found @@ -321,7 +430,7 @@ PyObject* wxPyMake_wxObject(wxObject* source, bool checkEvtHandler) { if (checkEvtHandler && wxIsKindOf(source, wxEvtHandler)) { isEvtHandler = TRUE; wxEvtHandler* eh = (wxEvtHandler*)source; - wxPyClientData* data = (wxPyClientData*)eh->GetClientObject(); + wxPyOORClientData* data = (wxPyOORClientData*)eh->GetClientObject(); if (data) { target = data->m_obj; Py_INCREF(target); @@ -342,11 +451,11 @@ PyObject* wxPyMake_wxObject(wxObject* source, bool checkEvtHandler) { if (info) { target = wxPyConstructObject(source, name, klass, FALSE); if (target && isEvtHandler) - ((wxEvtHandler*)source)->SetClientObject(new wxPyClientData(target)); + ((wxEvtHandler*)source)->SetClientObject(new wxPyOORClientData(target)); } else { - wxString msg("wxPython class not found for "); + wxString msg(wxT("wxPython class not found for ")); msg += source->GetClassInfo()->GetClassName(); - PyErr_SetString(PyExc_NameError, msg.c_str()); + PyErr_SetString(PyExc_NameError, msg.mbc_str()); target = NULL; } } @@ -365,7 +474,7 @@ PyObject* wxPyMake_wxSizer(wxSizer* source) { // already be a pointer to a Python object that we can use // in the OOR data. wxSizer* sz = (wxSizer*)source; - wxPyClientData* data = (wxPyClientData*)sz->GetClientObject(); + wxPyOORClientData* data = (wxPyOORClientData*)sz->GetClientObject(); if (data) { target = data->m_obj; Py_INCREF(target); @@ -374,7 +483,7 @@ PyObject* wxPyMake_wxSizer(wxSizer* source) { if (! target) { target = wxPyMake_wxObject(source, FALSE); if (target != Py_None) - ((wxSizer*)source)->SetClientObject(new wxPyClientData(target)); + ((wxSizer*)source)->SetClientObject(new wxPyOORClientData(target)); } return target; } @@ -384,20 +493,21 @@ PyObject* wxPyMake_wxSizer(wxSizer* source) { //--------------------------------------------------------------------------- PyObject* wxPyConstructObject(void* ptr, - const char* className, + const wxString& className, PyObject* klass, int setThisOwn) { PyObject* obj; PyObject* arg; PyObject* item; + wxString name(className); char swigptr[64]; // should always be big enough... char buff[64]; - if ((item = PyDict_GetItemString(wxPyPtrTypeMap, (char*)className)) != NULL) { - className = PyString_AsString(item); + if ((item = PyDict_GetItemString(wxPyPtrTypeMap, (char*)(const char*)name.mbc_str())) != NULL) { + name = wxString(PyString_AsString(item), *wxConvCurrent); } - sprintf(buff, "_%s_p", className); + sprintf(buff, "_%s_p", (const char*)name.mbc_str()); SWIG_MakePtr(swigptr, ptr, buff); arg = Py_BuildValue("(s)", swigptr); @@ -415,7 +525,7 @@ PyObject* wxPyConstructObject(void* ptr, PyObject* wxPyConstructObject(void* ptr, - const char* className, + const wxString& className, int setThisOwn) { PyObject* obj; @@ -425,23 +535,22 @@ PyObject* wxPyConstructObject(void* ptr, } char buff[64]; // should always be big enough... - sprintf(buff, "%sPtr", className); + sprintf(buff, "%sPtr", (const char*)className.mbc_str()); - wxASSERT_MSG(wxPython_dict, "wxPython_dict is not set yet!!"); + wxASSERT_MSG(wxPython_dict, wxT("wxPython_dict is not set yet!!")); PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff); if (! classobj) { - char temp[128]; - sprintf(temp, - "*** Unknown class name %s, tell Robin about it please ***", - buff); - obj = PyString_FromString(temp); - return obj; + wxString msg(wxT("wxPython class not found for ")); + msg += className; + PyErr_SetString(PyExc_NameError, msg.mbc_str()); + return NULL; } return wxPyConstructObject(ptr, className, classobj, setThisOwn); } + //--------------------------------------------------------------------------- @@ -469,7 +578,7 @@ PyThreadState* wxPyGetThreadState() { } } wxPyTMutex->Unlock(); - wxASSERT_MSG(tstate, "PyThreadState should not be NULL!"); + wxASSERT_MSG(tstate, wxT("PyThreadState should not be NULL!")); return tstate; } @@ -540,16 +649,13 @@ void wxPyEndBlockThreads() { //--------------------------------------------------------------------------- // wxPyInputStream and wxPyCBInputStream methods -#include -WX_DEFINE_LIST(wxStringPtrList); - void wxPyInputStream::close() { - /* do nothing */ + /* do nothing for now */ } void wxPyInputStream::flush() { - /* do nothing */ + /* do nothing for now */ } bool wxPyInputStream::eof() { @@ -563,8 +669,12 @@ wxPyInputStream::~wxPyInputStream() { /* do nothing */ } -wxString* wxPyInputStream::read(int size) { - wxString* s = NULL; + + + +PyObject* wxPyInputStream::read(int size) { + PyObject* obj = NULL; + wxMemoryBuffer buf; const int BUFSIZE = 1024; // check if we have a real wxInputStream to work with @@ -574,88 +684,62 @@ wxString* wxPyInputStream::read(int size) { } if (size < 0) { - // init buffers - char * buf = new char[BUFSIZE]; - if (!buf) { - PyErr_NoMemory(); - return NULL; - } - - s = new wxString(); - if (!s) { - delete buf; - PyErr_NoMemory(); - return NULL; - } - // read until EOF while (! m_wxis->Eof()) { - m_wxis->Read(buf, BUFSIZE); - s->Append(buf, m_wxis->LastRead()); - } - delete buf; - - // error check - if (m_wxis->LastError() == wxSTREAM_READ_ERROR) { - delete s; - PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); - return NULL; + m_wxis->Read(buf.GetAppendBuf(BUFSIZE), BUFSIZE); + buf.UngetAppendBuf(m_wxis->LastRead()); } } else { // Read only size number of characters - s = new wxString; - if (!s) { - PyErr_NoMemory(); - return NULL; - } - - // read size bytes - m_wxis->Read(s->GetWriteBuf(size+1), size); - s->UngetWriteBuf(m_wxis->LastRead()); + m_wxis->Read(buf.GetWriteBuf(size), size); + buf.UngetWriteBuf(m_wxis->LastRead()); + } - // error check - if (m_wxis->LastError() == wxSTREAM_READ_ERROR) { - delete s; - PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); - return NULL; - } + // error check + if (m_wxis->LastError() == wxSTREAM_READ_ERROR) { + PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); + } + else { + // We use only strings for the streams, not unicode + obj = PyString_FromStringAndSize(buf, buf.GetDataLen()); } - return s; + return obj; } -wxString* wxPyInputStream::readline (int size) { +PyObject* wxPyInputStream::readline(int size) { + PyObject* obj = NULL; + wxMemoryBuffer buf; + int i; + char ch; + // check if we have a real wxInputStream to work with if (!m_wxis) { PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream"); return NULL; } - // init buffer - int i; - char ch; - wxString* s = new wxString; - if (!s) { - PyErr_NoMemory(); - return NULL; - } - // read until \n or byte limit reached for (i=ch=0; (ch != '\n') && (!m_wxis->Eof()) && ((size < 0) || (i < size)); i++) { - *s += ch = m_wxis->GetC(); + ch = m_wxis->GetC(); + buf.AppendByte(ch); } // errorcheck if (m_wxis->LastError() == wxSTREAM_READ_ERROR) { - delete s; PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); - return NULL; } - return s; + else { + // We use only strings for the streams, not unicode + obj = PyString_FromStringAndSize((char*)buf.GetData(), buf.GetDataLen()); + } + return obj; } -wxStringPtrList* wxPyInputStream::readlines (int sizehint) { +PyObject* wxPyInputStream::readlines(int sizehint) { + PyObject* pylist; + // check if we have a real wxInputStream to work with if (!m_wxis) { PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream below"); @@ -663,8 +747,8 @@ wxStringPtrList* wxPyInputStream::readlines (int sizehint) { } // init list - wxStringPtrList* l = new wxStringPtrList(); - if (!l) { + pylist = PyList_New(0); + if (!pylist) { PyErr_NoMemory(); return NULL; } @@ -672,24 +756,23 @@ wxStringPtrList* wxPyInputStream::readlines (int sizehint) { // read sizehint bytes or until EOF int i; for (i=0; (!m_wxis->Eof()) && ((sizehint < 0) || (i < sizehint));) { - wxString* s = readline(); + PyObject* s = this->readline(); if (s == NULL) { - l->DeleteContents(TRUE); - l->Clear(); + Py_DECREF(pylist); return NULL; } - l->Append(s); - i = i + s->Length(); + PyList_Append(pylist, s); + i += PyString_Size(s); } // error check if (m_wxis->LastError() == wxSTREAM_READ_ERROR) { - l->DeleteContents(TRUE); - l->Clear(); + Py_DECREF(pylist); PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); return NULL; } - return l; + + return pylist; } @@ -776,13 +859,13 @@ size_t wxPyCBInputStream::OnSysRead(void *buffer, size_t bufsize) { Py_DECREF(arglist); size_t o = 0; - if ((result != NULL) && PyString_Check(result)) { // TODO: unicode? + if ((result != NULL) && PyString_Check(result)) { o = PyString_Size(result); if (o == 0) m_lasterror = wxSTREAM_EOF; if (o > bufsize) o = bufsize; - memcpy((char*)buffer, PyString_AsString(result), o); + memcpy((char*)buffer, PyString_AsString(result), o); // strings only, not unicode... Py_DECREF(result); } @@ -860,8 +943,9 @@ void wxPyCallback::EventThunker(wxEvent& event) { arg = ((wxPyEvent*)&event)->GetSelf(); else if (className == "wxPyCommandEvent") arg = ((wxPyCommandEvent*)&event)->GetSelf(); - else + else { arg = wxPyConstructObject((void*)&event, className); + } tuple = PyTuple_New(1); PyTuple_SET_ITEM(tuple, 0, arg); @@ -1225,7 +1309,108 @@ long wxPyGetWinHandle(wxWindow* win) { //---------------------------------------------------------------------- // Some helper functions for typemaps in my_typemaps.i, so they won't be -// included in every file... +// included in every file over and over again... + +#if PYTHON_API_VERSION >= 1009 + static char* wxStringErrorMsg = "String or Unicode type required"; +#else + static char* wxStringErrorMsg = "String type required"; +#endif + + +wxString* wxString_in_helper(PyObject* source) { + wxString* target; +#if PYTHON_API_VERSION >= 1009 // Have Python unicode API + if (!PyString_Check(source) && !PyUnicode_Check(source)) { + PyErr_SetString(PyExc_TypeError, wxStringErrorMsg); + return NULL; + } +#if wxUSE_UNICODE + if (PyUnicode_Check(source)) { + target = new wxString(PyUnicode_AS_UNICODE(source)); + } else { + // It is a string, get pointers to it and transform to unicode + char* tmpPtr; int tmpSize; + PyString_AsStringAndSize(source, &tmpPtr, &tmpSize); + target = new wxString(tmpPtr, *wxConvCurrent, tmpSize); + } +#else + char* tmpPtr; int tmpSize; + if (PyString_AsStringAndSize(source, &tmpPtr, &tmpSize) == -1) { + PyErr_SetString(PyExc_TypeError, "Unable to convert string"); + return NULL; + } + target = new wxString(tmpPtr, tmpSize); +#endif // wxUSE_UNICODE + +#else // No Python unicode API (1.5.2) + if (!PyString_Check(source)) { + PyErr_SetString(PyExc_TypeError, wxStringErrorMsg); + return NULL; + } + target = new wxString(PyString_AS_STRING(source), PyString_GET_SIZE(source)); +#endif + return target; +} + + +// Similar to above except doesn't use "new" and doesn't set an exception +wxString Py2wxString(PyObject* source) +{ + wxString target; + bool doDecRef = FALSE; + +#if PYTHON_API_VERSION >= 1009 // Have Python unicode API + if (!PyString_Check(source) && !PyUnicode_Check(source)) { + // Convert to String if not one already... (TODO: Unicode too?) + source = PyObject_Str(source); + doDecRef = TRUE; + } + +#if wxUSE_UNICODE + if (PyUnicode_Check(source)) { + target = PyUnicode_AS_UNICODE(source); + } else { + // It is a string, get pointers to it and transform to unicode + char* tmpPtr; int tmpSize; + PyString_AsStringAndSize(source, &tmpPtr, &tmpSize); + target = wxString(tmpPtr, *wxConvCurrent, tmpSize); + } +#else + char* tmpPtr; int tmpSize; + PyString_AsStringAndSize(source, &tmpPtr, &tmpSize); + target = wxString(tmpPtr, tmpSize); +#endif // wxUSE_UNICODE + +#else // No Python unicode API (1.5.2) + if (!PyString_Check(source)) { + // Convert to String if not one already... + source = PyObject_Str(source); + doDecRef = TRUE; + } + target = wxString(PyString_AS_STRING(source), PyString_GET_SIZE(source)); +#endif + + if (doDecRef) + Py_DECREF(source); + return target; +} + + +// Make either a Python String or Unicode object, depending on build mode +PyObject* wx2PyString(const wxString& src) +{ + PyObject* str; +#if wxUSE_UNICODE + str = PyUnicode_FromUnicode(src.c_str(), src.Len()); +#else + str = PyString_FromStringAndSize(src.c_str(), src.Len()); +#endif + return str; +} + + +//---------------------------------------------------------------------- byte* byte_LIST_helper(PyObject* source) { @@ -1480,19 +1665,16 @@ wxString* wxString_LIST_helper(PyObject* source) { PyErr_SetString(PyExc_TypeError, "Expected a list of string or unicode objects."); return NULL; } - - char* buff; - int length; - if (PyString_AsStringAndSize(o, &buff, &length) == -1) - return NULL; - temp[x] = wxString(buff, length); #else if (! PyString_Check(o)) { PyErr_SetString(PyExc_TypeError, "Expected a list of strings."); return NULL; } - temp[x] = PyString_AsString(o); #endif + + wxString* pStr = wxString_in_helper(o); + temp[x] = *pStr; + delete pStr; } return temp; } @@ -1644,7 +1826,14 @@ bool wxSize_helper(PyObject* source, wxSize** obj) { else if (PySequence_Check(source) && PyObject_Length(source) == 2) { PyObject* o1 = PySequence_GetItem(source, 0); PyObject* o2 = PySequence_GetItem(source, 1); + if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) { + Py_DECREF(o1); + Py_DECREF(o2); + goto error; + } **obj = wxSize(PyInt_AsLong(o1), PyInt_AsLong(o2)); + Py_DECREF(o1); + Py_DECREF(o2); return TRUE; } @@ -1667,15 +1856,15 @@ bool wxPoint_helper(PyObject* source, wxPoint** obj) { if (PySequence_Check(source) && PySequence_Length(source) == 2) { PyObject* o1 = PySequence_GetItem(source, 0); PyObject* o2 = PySequence_GetItem(source, 1); - // This should really check for integers, not numbers -- but that would break code. - if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) { - Py_DECREF(o1); - Py_DECREF(o2); - goto error; - } - **obj = wxPoint(PyInt_AsLong(o1), PyInt_AsLong(o2)); - Py_DECREF(o1); - Py_DECREF(o2); + // This should really check for integers, not numbers -- but that would break code. + if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) { + Py_DECREF(o1); + Py_DECREF(o2); + goto error; + } + **obj = wxPoint(PyInt_AsLong(o1), PyInt_AsLong(o2)); + Py_DECREF(o1); + Py_DECREF(o2); return TRUE; } error: @@ -1699,7 +1888,14 @@ bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj) { else if (PySequence_Check(source) && PyObject_Length(source) == 2) { PyObject* o1 = PySequence_GetItem(source, 0); PyObject* o2 = PySequence_GetItem(source, 1); + if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) { + Py_DECREF(o1); + Py_DECREF(o2); + goto error; + } **obj = wxRealPoint(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2)); + Py_DECREF(o1); + Py_DECREF(o2); return TRUE; } @@ -1727,8 +1923,20 @@ bool wxRect_helper(PyObject* source, wxRect** obj) { PyObject* o2 = PySequence_GetItem(source, 1); PyObject* o3 = PySequence_GetItem(source, 2); PyObject* o4 = PySequence_GetItem(source, 3); + if (!PyNumber_Check(o1) || !PyNumber_Check(o2) || + !PyNumber_Check(o3) || !PyNumber_Check(o4)) { + Py_DECREF(o1); + Py_DECREF(o2); + Py_DECREF(o3); + Py_DECREF(o4); + goto error; + } **obj = wxRect(PyInt_AsLong(o1), PyInt_AsLong(o2), - PyInt_AsLong(o3), PyInt_AsLong(o4)); + PyInt_AsLong(o3), PyInt_AsLong(o4)); + Py_DECREF(o1); + Py_DECREF(o2); + Py_DECREF(o3); + Py_DECREF(o4); return TRUE; } @@ -1751,12 +1959,14 @@ bool wxColour_helper(PyObject* source, wxColour** obj) { } // otherwise a string is expected else if (PyString_Check(source)) { - wxString spec = PyString_AS_STRING(source); - if (spec[0U] == '#' && spec.Length() == 7) { // It's #RRGGBB - char* junk; - int red = strtol(spec.Mid(1,2), &junk, 16); - int green = strtol(spec.Mid(3,2), &junk, 16); - int blue = strtol(spec.Mid(5,2), &junk, 16); + wxString spec(PyString_AS_STRING(source), *wxConvCurrent); + if (spec.GetChar(0) == '#' && spec.Length() == 7) { // It's #RRGGBB + long red, green, blue; + red = green = blue = 0; + spec.Mid(1,2).ToLong(&red, 16); + spec.Mid(3,2).ToLong(&green, 16); + spec.Mid(5,2).ToLong(&blue, 16); + **obj = wxColour(red, green, blue); return TRUE; } @@ -1767,7 +1977,9 @@ 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; } @@ -1778,7 +1990,11 @@ PyObject* wxArrayString2PyList_helper(const wxArrayString& arr) { PyObject* list = PyList_New(0); for (size_t i=0; i < arr.GetCount(); i++) { - PyObject* str = PyString_FromString(arr[i].c_str()); +#if wxUSE_UNICODE + PyObject* str = PyUnicode_FromUnicode(arr[i].c_str(), arr[i].Len()); +#else + PyObject* str = PyString_FromStringAndSize(arr[i].c_str(), arr[i].Len()); +#endif PyList_Append(list, str); Py_DECREF(str); }