From 562d2461aaeb619e4ce8a52f55732ae54a3c3fb9 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sat, 10 Mar 2012 22:40:41 +0100 Subject: [PATCH] wxString, wxPoint and wxChar wrappers --- pcbnew/CMakeLists.txt | 2 + pcbnew/scripting/helpers.cpp | 119 +++++++++++++++++++++++++++++ pcbnew/scripting/kicad.i | 1 + pcbnew/scripting/pcbnew.i | 1 + pcbnew/scripting/tests/test2.py | 14 ++++ pcbnew/scripting/wx.i | 129 +++++++++++++++++++++++--------- pcbnew/scripting/wx_helpers.h | 15 ++++ 7 files changed, 245 insertions(+), 36 deletions(-) create mode 100644 pcbnew/scripting/helpers.cpp create mode 100644 pcbnew/scripting/tests/test2.py create mode 100644 pcbnew/scripting/wx_helpers.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index fed90c4d57..d0401e99fb 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -18,6 +18,7 @@ include_directories( ${Boost_INCLUDE_DIR} ../polygon ../common/dialogs + ./scripting ${INC_AFTER} ) @@ -224,6 +225,7 @@ set(PCBNEW_COMMON_SRCS set(PCBNEW_SCRIPTING_SRCS kicad_wrap.cxx pcbnew_wrap.cxx + scripting/helpers.cpp ) ## diff --git a/pcbnew/scripting/helpers.cpp b/pcbnew/scripting/helpers.cpp new file mode 100644 index 0000000000..aee5885019 --- /dev/null +++ b/pcbnew/scripting/helpers.cpp @@ -0,0 +1,119 @@ +#include +#include +#include + +#define WX_DEFAULTENCODING_SIZE 64 + +static char wxPythonEncoding[WX_DEFAULTENCODING_SIZE] = "ascii"; + +wxString* newWxStringFromPy(PyObject* src) { + + bool must_unref_str=false; + + wxString* result = NULL; + PyObject *obj=src; + +#if wxUSE_UNICODE + bool must_unref_obj=false; + // Unicode string to python unicode string + PyObject* uni_str = src; + + // if not an str or unicode, try to str(src) + if (!PyString_Check(src) && !PyUnicode_Check(src)) + { + obj = PyObject_Str(src); + must_unref_obj = true; + if (PyErr_Occurred()) return NULL; + } + + if (PyString_Check(obj)) + { + uni_str = PyUnicode_FromEncodedObject(obj, wxPythonEncoding, "strict"); + must_unref_str = true; + if (PyErr_Occurred()) return NULL; + } + + result = new wxString(); + size_t len = PyUnicode_GET_SIZE(uni_str); + if (len) + { + PyUnicode_AsWideChar((PyUnicodeObject*)uni_str, + wxStringBuffer(*result, len),len); + } + + if (must_unref_str) Py_DECREF(uni_str); + if (must_unref_obj) Py_DECREF(obj); +#else + // normal string (or object) to normal python string + PyObject* str = src; + + if (PyUnicode_Check(src)) // if it's unicode convert to normal string + { + str = PyUnicode_AsEncodedString(src, wxPythonEncoding, "strict"); + if (PyErr_Occurred()) return NULL; + } + else if (!PyString_Check(src)) // if it's not a string, str(obj) + { + str = PyObject_Str(src); + must_unref_str = true; + if (PyErr_Occurred()) return NULL; + } + + // get the string pointer and size + char* str_ptr; + Py_ssize_t str_size; + PyString_AsStringAndSize(str, &str_ptr, &str_size); + + // build the wxString from our pointer / size + result = new wxString(str_ptr, str_size); + + if (must_unref_str) Py_DECREF(str); +#endif + + return result; +} + + +wxString Py2wxString(PyObject* src) +{ + wxString result; + wxString* resPtr = newWxStringFromPy(src); + + // In case of exception clear it and return an empty string + if (resPtr==NULL) + { + PyErr_Clear(); + return wxEmptyString; + } + + result = *resPtr; + + delete resPtr; + + return result; +} + + +PyObject* wx2PyString(const wxString& src) +{ + PyObject* str; +#if wxUSE_UNICODE + str = PyUnicode_FromWideChar(src.c_str(), src.Len()); +#else + str = PyString_FromStringAndSize(src.c_str(), src.Len()); +#endif + return str; +} + + + +void wxSetDefaultPyEncoding(const char* encoding) +{ + strncpy(wxPythonEncoding, encoding, WX_DEFAULTENCODING_SIZE); +} + +const char* wxGetDefaultPyEncoding() +{ + return wxPythonEncoding; +} + diff --git a/pcbnew/scripting/kicad.i b/pcbnew/scripting/kicad.i index d5140d0177..3efa03e86d 100644 --- a/pcbnew/scripting/kicad.i +++ b/pcbnew/scripting/kicad.i @@ -17,6 +17,7 @@ #include #include #include + #include %} diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index 342ee37eb4..f9bd1d9b28 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -8,6 +8,7 @@ #include #include #include + #include BOARD *GetBoard(); diff --git a/pcbnew/scripting/tests/test2.py b/pcbnew/scripting/tests/test2.py new file mode 100644 index 0000000000..4cda914932 --- /dev/null +++ b/pcbnew/scripting/tests/test2.py @@ -0,0 +1,14 @@ +pcb = pcbnew.GetBoard() + +m = pcb.m_Modules.item() + +while m: + print m.GetReference(),"(",m.GetValue(),") at ", m.GetPosition() + m.SetValue("pepe") + p = m.m_Pads.item() + while p: + print " pad",p.GetPadName(), "at",p.GetPosition() + p = p.Next() + + m = m.Next() + diff --git a/pcbnew/scripting/wx.i b/pcbnew/scripting/wx.i index 227859e02b..528978e1af 100644 --- a/pcbnew/scripting/wx.i +++ b/pcbnew/scripting/wx.i @@ -1,58 +1,115 @@ +%{ +#include +%} + +// encoding setup, ascii by default /////////////////////////////////////////// + +void wxSetDefaultPyEncoding(const char* encoding); +const char* wxGetDefaultPyEncoding(); + +// wxPoint class wrapper to (xx,yy) tuple ///////////////////////////////////// class wxPoint -{ +{ public: int x, y; - - wxPoint(int xx, int yy); ~wxPoint(); - - %extend { - - wxPoint __add__(const wxPoint& pt) { - return *self + pt; - } + wxPoint __add__(const wxPoint& pt) { return *self + pt; } + wxPoint __sub__(const wxPoint& pt) { return *self - pt; } - - - wxPoint __sub__(const wxPoint& pt) { - return *self - pt; - } - - - - void Set(long x, long y) { - self->x = x; - self->y = y; - } - - - PyObject* Get() { - //wxPyBlock_t blocked = wxPyBeginBlockThreads(); + void Set(long x, long y) { self->x = x; self->y = y; } + PyObject* Get() + { PyObject* tup = PyTuple_New(2); PyTuple_SET_ITEM(tup, 0, PyInt_FromLong(self->x)); PyTuple_SET_ITEM(tup, 1, PyInt_FromLong(self->y)); - //wxPyEndBlockThreads(blocked); return tup; } } %pythoncode { - def __eq__(self,other): return (self.x==other.x and self.y==other.y) - def __ne__(self,other): return not (self==other) - def __str__(self): return str(self.Get()) - def __repr__(self): return 'wx.Point'+str(self.Get()) - def __len__(self): return len(self.Get()) - def __getitem__(self, index): return self.Get()[index] + def __eq__(self,other): return (self.x==other.x and self.y==other.y) + def __ne__(self,other): return not (self==other) + def __str__(self): return str(self.Get()) + def __repr__(self): return 'wxPoint'+str(self.Get()) + def __len__(self): return len(self.Get()) + def __getitem__(self, index): return self.Get()[index] def __setitem__(self, index, val): - if index == 0: self.x = val - elif index == 1: self.y = val - else: raise IndexError + if index == 0: + self.x = val + elif index == 1: + self.y = val + else: + raise IndexError def __nonzero__(self): return self.Get() != (0,0) - __safe_for_unpickling__ = True + } }; + +// wxChar wrappers /////////////////////////////////////////////////////////// + +%typemap(in) wxChar { wxString str = Py2wxString($input); $1 = str[0]; } +%typemap(out) wxChar { wxString str($1); $result = wx2PyString(str); } + +// wxString wrappers ///////////////////////////////////////////////////////// + +%typemap(out) wxString& +{ +%#if wxUSE_UNICODE + $result = PyUnicode_FromWideChar($1->c_str(), $1->Len()); +%#else + $result = PyString_FromStringAndSize($1->c_str(), $1->Len()); +%#endif +} + +%apply wxString& { wxString* } + +%typemap(out) wxString { +%#if wxUSE_UNICODE + $result = PyUnicode_FromWideChar($1.c_str(), $1.Len()); +%#else + $result = PyString_FromStringAndSize($1.c_str(), $1.Len()); +%#endif +} + +%typemap(varout) wxString { +%#if wxUSE_UNICODE + $result = PyUnicode_FromWideChar($1.c_str(), $1.Len()); +%#else + $result = PyString_FromStringAndSize($1.c_str(), $1.Len()); +%#endif +} + +%typemap(in) wxString& (bool temp=false) +{ + $1 = newWxStringFromPy($input); + if ($1 == NULL) SWIG_fail; + temp = true; +} + +%typemap(freearg) wxString& +{ + if (temp$argnum) + delete $1; +} + + +%typemap(in) wxString { + wxString* sptr = newWxStringFromPy($input); + if (sptr == NULL) SWIG_fail; + $1 = *sptr; + delete sptr; +} + +%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) wxString& { + $1 = PyString_Check($input) || PyUnicode_Check($input); +} + + + + + diff --git a/pcbnew/scripting/wx_helpers.h b/pcbnew/scripting/wx_helpers.h new file mode 100644 index 0000000000..4a5976a83e --- /dev/null +++ b/pcbnew/scripting/wx_helpers.h @@ -0,0 +1,15 @@ +#ifndef __wx_helpers_h +#define __wx_helpers_h + +#include +#include +#include + +wxString* newWxStringFromPy(PyObject* source); +wxString Py2wxString(PyObject* source); +PyObject* wx2PyString(const wxString& src); + +void wxSetDefaultPyEncoding(const char* encoding); +const char* wxGetDefaultPyEncoding(); + +#endif