From d7692cd115ec075704b6d13b92149e3cd2302785 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Tue, 28 Feb 2012 22:30:46 +0100 Subject: [PATCH 01/41] SWIG+Python initial scripting support added. It does nothing but loading and initializing right now. --- include/base_struct.h | 2 +- pcbnew/CMakeLists.txt | 34 +++++++++++++++++++++++++++ pcbnew/pcbnew.cpp | 49 +++++++++++++++++++++++++++++++++++++++ pcbnew/scripting/kicad.i | 19 +++++++++++++++ pcbnew/scripting/pcbnew.i | 25 ++++++++++++++++++++ 5 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 pcbnew/scripting/kicad.i create mode 100644 pcbnew/scripting/pcbnew.i diff --git a/include/base_struct.h b/include/base_struct.h index 368da50827..c4cb4b1f8f 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -173,7 +173,7 @@ public: * @return A #SEARCH_RESULT type #SEARCH_QUIT if the iterator function is to * stop the scan, else #SEARCH_CONTINUE; */ - SEARCH_RESULT virtual Inspect( EDA_ITEM* aItem, const void* aTestData ) = 0; + virtual SEARCH_RESULT Inspect( EDA_ITEM* aItem, const void* aTestData ) = 0; }; diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 92140becdc..1d7404752e 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -1,5 +1,12 @@ add_definitions(-DPCBNEW) +FIND_PACKAGE(SWIG REQUIRED) +INCLUDE(${SWIG_USE_FILE}) + +FIND_PACKAGE(PythonLibs) +INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) + + ### # Includes ### @@ -209,6 +216,31 @@ set(PCBNEW_COMMON_SRCS ../common/dialogs/dialog_page_settings.cpp ) +## +# Scripting sources +## +set(PCBNEW_SCRIPTING_SRCS + kicad_wrap.cxx + pcbnew_wrap.cxx + ) + +## +# Scripting build +## + +SET(SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -DKICAD_TESTING_VERSION -D_FILE_OFFSET_BITS=64 -DPCBNEW -D_LARGE_FILES -D__WXGTK__ -DHAVE_SVN_VERSION -DDEBUG) + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/kicad_wrap.cxx + COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/kicad_wrap.cxx scripting/kicad.i + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx + COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx scripting/pcbnew.i + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + ### # Windows resource file @@ -269,6 +301,7 @@ make_lexer( add_executable(pcbnew WIN32 MACOSX_BUNDLE ${PCBNEW_SRCS} ${PCBNEW_COMMON_SRCS} + ${PCBNEW_SCRIPTING_SRCS} ${PCBNEW_RESOURCES} ) @@ -292,6 +325,7 @@ target_link_libraries(pcbnew ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${GDI_PLUS_LIBRARIES} + ${PYTHON_LIBRARIES} ) ### diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index 84a18f2d03..be4b4871c5 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -45,6 +45,7 @@ #include #include #include +#include // Colors for layers and items @@ -104,11 +105,59 @@ void EDA_APP::MacOpenFile( const wxString& fileName ) } +struct _inittab SWIG_Import_Inittab[1000]; +static int swig_num_modules = 0; + +static void swig_add_module(char *name, void (*initfunc)()) { + SWIG_Import_Inittab[swig_num_modules].name = name; + SWIG_Import_Inittab[swig_num_modules].initfunc = initfunc; + swig_num_modules++; + SWIG_Import_Inittab[swig_num_modules].name = (char *) 0; + SWIG_Import_Inittab[swig_num_modules].initfunc = 0; +} + +extern "C" void init_kicad(void); +extern "C" void init_pcbnew(void); + +static void swig_add_builtin() { + int i = 0; + while (PyImport_Inittab[i].name) { + swig_add_module(PyImport_Inittab[i].name, PyImport_Inittab[i].initfunc); + i++; + } + swig_add_module("_kicad",init_kicad); + swig_add_module("_pcbnew",init_pcbnew); + PyImport_Inittab = SWIG_Import_Inittab; + +} + + bool EDA_APP::OnInit() { wxFileName fn; PCB_EDIT_FRAME* frame = NULL; + int i=0; + + swig_add_builtin(); + + +#if 0 + while(PyImport_Inittab[i].name) + { + printf("name[%d]=>%s\n",i,PyImport_Inittab[i].name); + i++; + } +#endif + Py_Initialize(); + + PyRun_SimpleString("import sys\n" + "sys.path.append(\".\")\n" + "import kicad,pcbnew\n" + "from time import time,ctime\n" + "print 'Today is',ctime(time())\n"); + + InitEDA_Appl( wxT( "Pcbnew" ), APP_PCBNEW_T ); if( m_Checker && m_Checker->IsAnotherRunning() ) diff --git a/pcbnew/scripting/kicad.i b/pcbnew/scripting/kicad.i new file mode 100644 index 0000000000..38b8f0fc34 --- /dev/null +++ b/pcbnew/scripting/kicad.i @@ -0,0 +1,19 @@ +%module kicad + +%nodefaultctor EDA_ITEM; +%ignore InitKiCadAbout; +%ignore GetCommandOptions; + +%{ + #include + #include + #include + +%} + +%include +%include +%include + + + diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i new file mode 100644 index 0000000000..5754c54be3 --- /dev/null +++ b/pcbnew/scripting/pcbnew.i @@ -0,0 +1,25 @@ +%module pcbnew +%import "kicad.i" + + +%{ + #include + #include + #include + #include + #include +%} + +%include +%include +%include +%include + + + + +/*%template(BOARD_ITEM_List) DLIST; +%template(MODULE_List) DLIST; +%template(TRACK_List) DLIST; +%template(PAD_List) DLIST; +*/ From b21dbd95616bed71f9f9a8efa989b91497f6caae Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Thu, 1 Mar 2012 08:21:53 +0100 Subject: [PATCH 02/41] Added a starting scripting dialog for tests --- pcbnew/CMakeLists.txt | 2 + pcbnew/dialogs/dialog_scripting.cpp | 29 ++++ pcbnew/dialogs/dialog_scripting.h | 22 +++ pcbnew/dialogs/dialog_scripting_base.cpp | 41 +++++ pcbnew/dialogs/dialog_scripting_base.fbp | 207 +++++++++++++++++++++++ pcbnew/dialogs/dialog_scripting_base.h | 46 +++++ pcbnew/pcbnew.cpp | 13 +- pcbnew/scripting/pcbnew.i | 5 +- 8 files changed, 363 insertions(+), 2 deletions(-) create mode 100644 pcbnew/dialogs/dialog_scripting.cpp create mode 100644 pcbnew/dialogs/dialog_scripting.h create mode 100644 pcbnew/dialogs/dialog_scripting_base.cpp create mode 100644 pcbnew/dialogs/dialog_scripting_base.fbp create mode 100644 pcbnew/dialogs/dialog_scripting_base.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 1d7404752e..fed90c4d57 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -86,6 +86,8 @@ set(PCBNEW_DIALOGS dialogs/dialog_SVG_print.cpp dialogs/dialog_SVG_print_base.cpp dialogs/dialog_set_grid_base.cpp + dialogs/dialog_scripting_base.cpp + dialogs/dialog_scripting.cpp ) set(PCBNEW_SRCS diff --git a/pcbnew/dialogs/dialog_scripting.cpp b/pcbnew/dialogs/dialog_scripting.cpp new file mode 100644 index 0000000000..6bc9822cab --- /dev/null +++ b/pcbnew/dialogs/dialog_scripting.cpp @@ -0,0 +1,29 @@ +/** + * @file dialog_scripting.cpp + */ + + +#include +#include +#include +#include +#include +#include + + +DIALOG_SCRIPTING::DIALOG_SCRIPTING( wxWindow* parent ) + : DIALOG_SCRIPTING_BASE( parent ) +{ + SetFocus(); + +} + + + +void DIALOG_SCRIPTING::OnRunButtonClick( wxCommandEvent& event ) +{ + wxCharBuffer buffer = m_txScript->GetValue().ToUTF8(); + PyRun_SimpleString(buffer.data()); +} + + diff --git a/pcbnew/dialogs/dialog_scripting.h b/pcbnew/dialogs/dialog_scripting.h new file mode 100644 index 0000000000..9f3a4638ca --- /dev/null +++ b/pcbnew/dialogs/dialog_scripting.h @@ -0,0 +1,22 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: dialog_scripting.h +///////////////////////////////////////////////////////////////////////////// + +#ifndef _DIALOG_SCRIPTING_H_ +#define _DIALOG_SCRIPTING_H_ + +#include + +class DIALOG_SCRIPTING: public DIALOG_SCRIPTING_BASE +{ +private: + wxDialog * m_Parent; + +public: + DIALOG_SCRIPTING(wxWindow * parent ); + +private: + void OnRunButtonClick( wxCommandEvent& event ); +}; + +#endif // _DIALOG_SCRIPTING_H_ diff --git a/pcbnew/dialogs/dialog_scripting_base.cpp b/pcbnew/dialogs/dialog_scripting_base.cpp new file mode 100644 index 0000000000..4064b79b95 --- /dev/null +++ b/pcbnew/dialogs/dialog_scripting_base.cpp @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Sep 8 2010) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialog_scripting_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_SCRIPTING_BASE::DIALOG_SCRIPTING_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer4; + bSizer4 = new wxBoxSizer( wxVERTICAL ); + + m_txScript = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTE_MULTILINE ); + m_txScript->SetMinSize( wxSize( 480,500 ) ); + + bSizer4->Add( m_txScript, 0, wxALL, 5 ); + + m_btRun = new wxButton( this, wxID_ANY, wxT("&Run"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer4->Add( m_btRun, 0, wxALL, 5 ); + + this->SetSizer( bSizer4 ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + m_btRun->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCRIPTING_BASE::OnRunButtonClick ), NULL, this ); +} + +DIALOG_SCRIPTING_BASE::~DIALOG_SCRIPTING_BASE() +{ + // Disconnect Events + m_btRun->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCRIPTING_BASE::OnRunButtonClick ), NULL, this ); + +} diff --git a/pcbnew/dialogs/dialog_scripting_base.fbp b/pcbnew/dialogs/dialog_scripting_base.fbp new file mode 100644 index 0000000000..0852d2f913 --- /dev/null +++ b/pcbnew/dialogs/dialog_scripting_base.fbp @@ -0,0 +1,207 @@ + + + + + + C++ + 1 + source_name + 0 + UTF-8 + connect + dialog_scripting_base + 1000 + none + 0 + DIALOG_SCRIPTING_BASE + + . + + 1 + 1 + 0 + 0 + + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_SCRIPTING_BASE + + 500,600 + wxDEFAULT_FRAME_STYLE + + Scripting Test Window + + + wxFILTER_NONE + wxDefaultValidator + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer4 + wxVERTICAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + + 0 + wxID_ANY + + 0 + 480,500 + m_txScript + protected + + + wxHSCROLL|wxTE_MULTILINE + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + 0 + 1 + + + 0 + wxID_ANY + &Run + + + m_btRun + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRunButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcbnew/dialogs/dialog_scripting_base.h b/pcbnew/dialogs/dialog_scripting_base.h new file mode 100644 index 0000000000..87dc68b746 --- /dev/null +++ b/pcbnew/dialogs/dialog_scripting_base.h @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Sep 8 2010) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __dialog_scripting_base__ +#define __dialog_scripting_base__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_SCRIPTING_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_SCRIPTING_BASE : public wxFrame +{ + private: + + protected: + wxTextCtrl* m_txScript; + wxButton* m_btRun; + + // Virtual event handlers, overide them in your derived class + virtual void OnRunButtonClick( wxCommandEvent& event ) { event.Skip(); } + + + public: + + DIALOG_SCRIPTING_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Scripting Test Window"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,600 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ); + ~DIALOG_SCRIPTING_BASE(); + +}; + +#endif //__dialog_scripting_base__ diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index be4b4871c5..ed9af5708e 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -46,8 +46,11 @@ #include #include #include +#include +#include + // Colors for layers and items COLORS_DESIGN_SETTINGS g_ColorsSettings; int g_DrawDefaultLineThickness = 60; /* Default line thickness in PCnew units used to draw @@ -131,6 +134,12 @@ static void swig_add_builtin() { } +static BOARD *st_board; + +BOARD *GetBoard() +{ + return st_board; +} bool EDA_APP::OnInit() { @@ -244,6 +253,8 @@ Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); */ frame->SetFocus(); frame->GetCanvas()->SetFocus(); - + st_board = frame->GetBoard(); + DIALOG_SCRIPTING* sw = new DIALOG_SCRIPTING(frame); + sw->Show(true); return true; } diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index 5754c54be3..8301253399 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -8,6 +8,9 @@ #include #include #include + + + BOARD *GetBoard(); %} %include @@ -16,7 +19,7 @@ %include - +BOARD *GetBoard(); /*%template(BOARD_ITEM_List) DLIST; %template(MODULE_List) DLIST; From 3dacab9691a381e138fcbf6c907b969cd689776d Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Mon, 5 Mar 2012 23:49:49 +0100 Subject: [PATCH 03/41] wxPoint + more lists --- pcbnew/scripting/kicad.i | 12 +++++++ pcbnew/scripting/pcbnew.i | 17 ++++++++-- pcbnew/scripting/tests/test1.py | 14 ++++++++ pcbnew/scripting/wx.i | 58 +++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 pcbnew/scripting/tests/test1.py create mode 100644 pcbnew/scripting/wx.i diff --git a/pcbnew/scripting/kicad.i b/pcbnew/scripting/kicad.i index 38b8f0fc34..d5140d0177 100644 --- a/pcbnew/scripting/kicad.i +++ b/pcbnew/scripting/kicad.i @@ -1,6 +1,15 @@ %module kicad %nodefaultctor EDA_ITEM; + + +/* swig tries to wrap SetBack/SetNext on derived classes, but this method is + private for most childs, so if we don't ignore it it won't compile */ + +%ignore EDA_ITEM::SetBack; +%ignore EDA_ITEM::SetNext; + + %ignore InitKiCadAbout; %ignore GetCommandOptions; @@ -16,4 +25,7 @@ %include +%include + + diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index 8301253399..342ee37eb4 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -1,13 +1,13 @@ %module pcbnew %import "kicad.i" - %{ #include #include #include #include #include + #include BOARD *GetBoard(); @@ -17,12 +17,23 @@ %include %include %include +%include +%include + +%rename(item) operator BOARD_ITEM*; +%rename(item) operator TRACK*; +%rename(item) operator D_PAD*; +%rename(item) operator MODULE*; BOARD *GetBoard(); -/*%template(BOARD_ITEM_List) DLIST; + + +%template(BOARD_ITEM_List) DLIST; %template(MODULE_List) DLIST; %template(TRACK_List) DLIST; %template(PAD_List) DLIST; -*/ + + + diff --git a/pcbnew/scripting/tests/test1.py b/pcbnew/scripting/tests/test1.py new file mode 100644 index 0000000000..6b50b24914 --- /dev/null +++ b/pcbnew/scripting/tests/test1.py @@ -0,0 +1,14 @@ +pcb = pcbnew.GetBoard() + +m = pcb.m_Modules.item() + +while m: + print m.GetPosition() + p = m.m_Pads.item() + while p: + print "p=>",p.GetPosition(),p.GetPadName() + print p.GetPosition() + p = p.Next() + m = m.Next() + + diff --git a/pcbnew/scripting/wx.i b/pcbnew/scripting/wx.i new file mode 100644 index 0000000000..227859e02b --- /dev/null +++ b/pcbnew/scripting/wx.i @@ -0,0 +1,58 @@ + + +class wxPoint +{ +public: + int x, y; + + + wxPoint(int xx, int yy); + ~wxPoint(); + + + %extend { + + wxPoint __add__(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(); + 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 __setitem__(self, index, val): + 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 + } +}; + From 562d2461aaeb619e4ce8a52f55732ae54a3c3fb9 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sat, 10 Mar 2012 22:40:41 +0100 Subject: [PATCH 04/41] 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 From ec5757a4fa4c07ad27f38291e16722e6e3d5f0ba Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sun, 11 Mar 2012 20:07:10 +0100 Subject: [PATCH 05/41] code cleanup, io_mgr and kicad_plugin included when enabled in cmake... --- pcbnew/CMakeLists.txt | 43 +++++++-- pcbnew/pcbnew.cpp | 57 +----------- pcbnew/scripting/kicad.i | 23 +++-- pcbnew/scripting/pcbnew.i | 37 ++++++-- pcbnew/scripting/python_scripting.cpp | 90 +++++++++++++++++++ pcbnew/scripting/python_scripting.h | 11 +++ pcbnew/scripting/wx.i | 2 +- .../{helpers.cpp => wx_python_helpers.cpp} | 0 .../{wx_helpers.h => wx_python_helpers.h} | 0 9 files changed, 187 insertions(+), 76 deletions(-) create mode 100644 pcbnew/scripting/python_scripting.cpp create mode 100644 pcbnew/scripting/python_scripting.h rename pcbnew/scripting/{helpers.cpp => wx_python_helpers.cpp} (100%) rename pcbnew/scripting/{wx_helpers.h => wx_python_helpers.h} (100%) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index d0401e99fb..70f1164fa2 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -223,22 +223,49 @@ set(PCBNEW_COMMON_SRCS # Scripting sources ## set(PCBNEW_SCRIPTING_SRCS - kicad_wrap.cxx +# kicad_wrap.cxx pcbnew_wrap.cxx - scripting/helpers.cpp + scripting/wx_python_helpers.cpp + scripting/python_scripting.cpp ) ## # Scripting build ## -SET(SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -DKICAD_TESTING_VERSION -D_FILE_OFFSET_BITS=64 -DPCBNEW -D_LARGE_FILES -D__WXGTK__ -DHAVE_SVN_VERSION -DDEBUG) -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/kicad_wrap.cxx - COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/kicad_wrap.cxx scripting/kicad.i - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -) + +SET(SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -DDEBUG ) + +# collect CFLAGS , and pass them to swig later + +get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS ) +foreach( d ${DirDefs} ) + SET(SWIG_OPTS ${SWIG_OPTS} -D${d} ) +endforeach() + +# check if we have IO_MGR and KICAD_PLUGIN available +if ( USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE ) + SET(SWIG_OPTS ${SWIG_OPTS} -DBUILD_WITH_PLUGIN) +endif() + + +foreach( d ${SWIG_OPTS} ) + message(STATUS "Swig options:" ${d}) +endforeach() + + +if ( USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE ) +endif() + + + +#add_custom_command( +# OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/kicad_wrap.cxx +# COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/kicad_wrap.cxx scripting/kicad.i +# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +#) + add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx scripting/pcbnew.i diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index ed9af5708e..14ef6c7420 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -45,11 +45,10 @@ #include #include #include -#include #include - #include +#include // Colors for layers and items COLORS_DESIGN_SETTINGS g_ColorsSettings; @@ -108,64 +107,14 @@ void EDA_APP::MacOpenFile( const wxString& fileName ) } -struct _inittab SWIG_Import_Inittab[1000]; -static int swig_num_modules = 0; - -static void swig_add_module(char *name, void (*initfunc)()) { - SWIG_Import_Inittab[swig_num_modules].name = name; - SWIG_Import_Inittab[swig_num_modules].initfunc = initfunc; - swig_num_modules++; - SWIG_Import_Inittab[swig_num_modules].name = (char *) 0; - SWIG_Import_Inittab[swig_num_modules].initfunc = 0; -} - -extern "C" void init_kicad(void); -extern "C" void init_pcbnew(void); - -static void swig_add_builtin() { - int i = 0; - while (PyImport_Inittab[i].name) { - swig_add_module(PyImport_Inittab[i].name, PyImport_Inittab[i].initfunc); - i++; - } - swig_add_module("_kicad",init_kicad); - swig_add_module("_pcbnew",init_pcbnew); - PyImport_Inittab = SWIG_Import_Inittab; - -} - -static BOARD *st_board; - -BOARD *GetBoard() -{ - return st_board; -} - bool EDA_APP::OnInit() { wxFileName fn; PCB_EDIT_FRAME* frame = NULL; int i=0; - - swig_add_builtin(); - -#if 0 - while(PyImport_Inittab[i].name) - { - printf("name[%d]=>%s\n",i,PyImport_Inittab[i].name); - i++; - } -#endif - Py_Initialize(); - - PyRun_SimpleString("import sys\n" - "sys.path.append(\".\")\n" - "import kicad,pcbnew\n" - "from time import time,ctime\n" - "print 'Today is',ctime(time())\n"); - + pcbnewInitPythonScripting(); InitEDA_Appl( wxT( "Pcbnew" ), APP_PCBNEW_T ); @@ -253,7 +202,7 @@ Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); */ frame->SetFocus(); frame->GetCanvas()->SetFocus(); - st_board = frame->GetBoard(); + pythonSetPcbEditFrame(frame); DIALOG_SCRIPTING* sw = new DIALOG_SCRIPTING(frame); sw->Show(true); return true; diff --git a/pcbnew/scripting/kicad.i b/pcbnew/scripting/kicad.i index 3efa03e86d..e2f6805f60 100644 --- a/pcbnew/scripting/kicad.i +++ b/pcbnew/scripting/kicad.i @@ -1,5 +1,11 @@ -%module kicad +//%module kicad +/* OFF NOW, it triggers an error with GCC 4.6 and swig-2.0.4 or trunk.. + http://sourceforge.net/tracker/index.php?func=detail&aid=3391906&group_id=1645&atid=101645 + + %include + %include +*/ %nodefaultctor EDA_ITEM; @@ -17,7 +23,10 @@ #include #include #include - #include + #include + #include + #include + using namespace std; %} @@ -25,8 +34,12 @@ %include %include - +/* all the wx wrappers for wxString, wxPoint, wxRect, wxChar .. */ %include - - +/* +namespace std +{ + %template(intVector) vector; +} +*/ diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index f9bd1d9b28..27428fce27 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -1,35 +1,57 @@ %module pcbnew -%import "kicad.i" + +%include "kicad.i" %{ + #include #include #include #include #include #include + #include + #include + #include #include - #include + + BOARD *GetBoard(); %} +#ifdef BUILD_WITH_PLUGIN +%{ + #include + #include +%} +#endif + + %include %include %include %include %include +%include +%include +%include %include -%rename(item) operator BOARD_ITEM*; -%rename(item) operator TRACK*; -%rename(item) operator D_PAD*; -%rename(item) operator MODULE*; +#ifdef BUILD_WITH_PLUGIN +%include +%include +#endif + +%rename(Get) operator BOARD_ITEM*; +%rename(Get) operator TRACK*; +%rename(Get) operator D_PAD*; +%rename(Get) operator MODULE*; BOARD *GetBoard(); - +// se must translate C++ templates to scripting languages %template(BOARD_ITEM_List) DLIST; %template(MODULE_List) DLIST; @@ -37,4 +59,3 @@ BOARD *GetBoard(); %template(PAD_List) DLIST; - diff --git a/pcbnew/scripting/python_scripting.cpp b/pcbnew/scripting/python_scripting.cpp new file mode 100644 index 0000000000..46135151cb --- /dev/null +++ b/pcbnew/scripting/python_scripting.cpp @@ -0,0 +1,90 @@ + +#include + +/* init functions defined by swig */ + +extern "C" void init_kicad(void); +extern "C" void init_pcbnew(void); + + +/* python inittab that links module names to module init functions + * we will rebuild it to include the original python modules plus + * our own ones + */ + +struct _inittab SwigImportInittab[1000]; +static int SwigNumModules = 0; + + +/* Add a name + initfuction to our SwigImportInittab */ + +static void swigAddModule(const char *name, void (*initfunc)()) { + SwigImportInittab[SwigNumModules].name = (char *)name; + SwigImportInittab[SwigNumModules].initfunc = initfunc; + SwigNumModules++; + SwigImportInittab[SwigNumModules].name = (char *) 0; + SwigImportInittab[SwigNumModules].initfunc = 0; +} + +/* Add the builting python modules */ + +static void swigAddBuiltin() { + int i = 0; + while (PyImport_Inittab[i].name) { + swigAddModule(PyImport_Inittab[i].name, PyImport_Inittab[i].initfunc); + i++; + } + +} +static void swigAddModules() +{ + //swigAddModule("_kicad",init_kicad); + swigAddModule("_pcbnew",init_pcbnew); +} + +static void swigSwitchPythonBuiltin() +{ + PyImport_Inittab = SwigImportInittab; +} + +static PCB_EDIT_FRAME *PcbEditFrame=NULL; + +BOARD *GetBoard() +{ + if (PcbEditFrame) return PcbEditFrame->GetBoard(); + else return NULL; +} + +void pythonSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame) +{ + PcbEditFrame = aPCBEdaFrame; +} + + + +void pcbnewInitPythonScripting() +{ + swigAddBuiltin(); + swigAddModules(); + swigSwitchPythonBuiltin(); + +#if 0 + /* print the list of modules available from python */ + while(PyImport_Inittab[i].name) + { + printf("name[%d]=>%s\n",i,PyImport_Inittab[i].name); + i++; + } +#endif + + Py_Initialize(); + + /* setup the scripting path, we may need to add the installation path + of kicad here */ + + PyRun_SimpleString("import sys\n" + "sys.path.append(\".\")\n" + "import pcbnew\n"); + + +} diff --git a/pcbnew/scripting/python_scripting.h b/pcbnew/scripting/python_scripting.h new file mode 100644 index 0000000000..03b0de8b63 --- /dev/null +++ b/pcbnew/scripting/python_scripting.h @@ -0,0 +1,11 @@ +#ifndef __PYTHON_SCRIPTING_H +#define __PYTHON_SCRIPTING_H + +#include +#include + +void pythonSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame); +void pcbnewInitPythonScripting(void); + + +#endif diff --git a/pcbnew/scripting/wx.i b/pcbnew/scripting/wx.i index 528978e1af..61f6c8ce38 100644 --- a/pcbnew/scripting/wx.i +++ b/pcbnew/scripting/wx.i @@ -1,6 +1,6 @@ %{ -#include +#include %} // encoding setup, ascii by default /////////////////////////////////////////// diff --git a/pcbnew/scripting/helpers.cpp b/pcbnew/scripting/wx_python_helpers.cpp similarity index 100% rename from pcbnew/scripting/helpers.cpp rename to pcbnew/scripting/wx_python_helpers.cpp diff --git a/pcbnew/scripting/wx_helpers.h b/pcbnew/scripting/wx_python_helpers.h similarity index 100% rename from pcbnew/scripting/wx_helpers.h rename to pcbnew/scripting/wx_python_helpers.h From 970e033399cff7374318bb9f92f900b88f5c598c Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sun, 11 Mar 2012 20:48:43 +0100 Subject: [PATCH 06/41] build _pcbnew DSO/DLL --- pcbnew/CMakeLists.txt | 50 ++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 70f1164fa2..e203b2e1b0 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -91,7 +91,7 @@ set(PCBNEW_DIALOGS dialogs/dialog_scripting.cpp ) -set(PCBNEW_SRCS +set(PCBNEW_CLASS_SRCS tool_modview.cpp modview.cpp modview_frame.cpp @@ -114,7 +114,6 @@ set(PCBNEW_SRCS dimension.cpp cross-probing.cpp deltrack.cpp - ${PCBNEW_DIALOGS} dist.cpp dragsegm.cpp drc.cpp @@ -212,6 +211,8 @@ set(PCBNEW_SRCS zones_test_and_combine_areas.cpp ) +set(PCBNEW_SRCS ${PCBNEW_CLASS_SRCS} ${PCBNEW_DIALOGS}) + ### # We need some extra sources from common ### @@ -222,11 +223,15 @@ set(PCBNEW_COMMON_SRCS ## # Scripting sources ## +set(PCBNEW_SCRIPTING_PYTHON_HELPERS + scripting/wx_python_helpers.cpp + scripting/python_scripting.cpp + ) + set(PCBNEW_SCRIPTING_SRCS # kicad_wrap.cxx pcbnew_wrap.cxx - scripting/wx_python_helpers.cpp - scripting/python_scripting.cpp + ${PCBNEW_SCRIPTING_PYTHON_HELPERS} ) ## @@ -234,32 +239,31 @@ set(PCBNEW_SCRIPTING_SRCS ## - -SET(SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -DDEBUG ) +set(SWIG_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -DDEBUG) # collect CFLAGS , and pass them to swig later get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS ) foreach( d ${DirDefs} ) - SET(SWIG_OPTS ${SWIG_OPTS} -D${d} ) + SET(SWIG_FLAGS ${SWIG_FLAGS} -D${d} ) endforeach() # check if we have IO_MGR and KICAD_PLUGIN available if ( USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE ) - SET(SWIG_OPTS ${SWIG_OPTS} -DBUILD_WITH_PLUGIN) + SET(SWIG_FLAGS ${SWIG_FLAGS} -DBUILD_WITH_PLUGIN) endif() -foreach( d ${SWIG_OPTS} ) +foreach( d ${SWIG_FLAGS} ) message(STATUS "Swig options:" ${d}) endforeach() - -if ( USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE ) -endif() - +SET(SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} ${SWIG_FLAGS} ) +# we checked the posibility to build kicad thinks in a separate module, but it +# will be easier in just one "pcbnew" for now +# #add_custom_command( # OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/kicad_wrap.cxx # COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/kicad_wrap.cxx scripting/kicad.i @@ -273,6 +277,26 @@ add_custom_command( ) +### +# _pcbnew DLL/DSO file creation +### + +SET(CMAKE_SWIG_FLAGS ${SWIG_FLAGS}) +SET_SOURCE_FILES_PROPERTIES(scripting/pcbnew.i PROPERTIES CPLUSPLUS ON) +SWIG_ADD_MODULE(pcbnew python scripting/pcbnew.i ${PCBNEW_SCRIPTING_PYTHON_HELPERS} ${PCBNEW_SRCS}) +SWIG_LINK_LIBRARIES(pcbnew + 3d-viewer + pcbcommon + common + bitmaps + polygon + kbool + ${wxWidgets_LIBRARIES} + ${OPENGL_LIBRARIES} + ${GDI_PLUS_LIBRARIES} + ${PYTHON_LIBRARIES}) + + ### # Windows resource file ### From f42235060547323ab04b9270e9ac7fbbbc2c7f30 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sat, 17 Mar 2012 16:17:13 +0100 Subject: [PATCH 07/41] pcbnew_scripting_helpers.cpp/h to handle generic scripting tools CMakeLists.txt options to build scripting or scripting modules --- CMakeLists.txt | 10 ++ pcbnew/CMakeLists.txt | 134 ++++++++++-------- pcbnew/pcbnew.cpp | 13 +- pcbnew/scripting/kicad.i | 12 +- pcbnew/scripting/pcbnew.i | 57 ++++++-- pcbnew/scripting/pcbnew_scripting_helpers.cpp | 72 ++++++++++ pcbnew/scripting/pcbnew_scripting_helpers.h | 16 +++ pcbnew/scripting/python_scripting.cpp | 31 ++-- pcbnew/scripting/python_scripting.h | 3 - 9 files changed, 245 insertions(+), 103 deletions(-) create mode 100644 pcbnew/scripting/pcbnew_scripting_helpers.cpp create mode 100644 pcbnew/scripting/pcbnew_scripting_helpers.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 23071ba725..a1eea87d7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,16 @@ option(KICAD_TESTING_VERSION "set this option to ON to build the stable version of KICAD. mainly used to set version ID (default OFF)" ) +option(KICAD_SCRIPTING + "set this option ON to build the scripting support inside kicad binaries" + ) + +option(KICAD_SCRIPTING_MODULES + "set this option ON to build kicad modules that can be used from scripting languages" + ) + + + #Set version option (stable or testing) if (KICAD_STABLE_VERSION ) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index e203b2e1b0..bda556d348 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -1,11 +1,14 @@ add_definitions(-DPCBNEW) -FIND_PACKAGE(SWIG REQUIRED) -INCLUDE(${SWIG_USE_FILE}) - -FIND_PACKAGE(PythonLibs) -INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) +if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) + FIND_PACKAGE(SWIG REQUIRED) + INCLUDE(${SWIG_USE_FILE}) + + FIND_PACKAGE(PythonLibs) + INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) + add_definitions(-DPCBNEW -DKICAD_SCRIPTING) +endif() ### # Includes @@ -223,79 +226,78 @@ set(PCBNEW_COMMON_SRCS ## # Scripting sources ## -set(PCBNEW_SCRIPTING_PYTHON_HELPERS - scripting/wx_python_helpers.cpp - scripting/python_scripting.cpp - ) -set(PCBNEW_SCRIPTING_SRCS -# kicad_wrap.cxx - pcbnew_wrap.cxx - ${PCBNEW_SCRIPTING_PYTHON_HELPERS} - ) +if (KICAD_SCRIPTING) + + set(PCBNEW_SCRIPTING_PYTHON_HELPERS + scripting/wx_python_helpers.cpp + scripting/pcbnew_scripting_helpers.cpp + scripting/python_scripting.cpp + ) + + set(PCBNEW_SCRIPTING_SRCS + pcbnew_wrap.cxx + ${PCBNEW_SCRIPTING_PYTHON_HELPERS} + ) +endif() ## # Scripting build ## +if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) -set(SWIG_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -DDEBUG) + set(SWIG_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -DDEBUG) + + # collect CFLAGS , and pass them to swig later + + get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS ) + foreach( d ${DirDefs} ) + SET(SWIG_FLAGS ${SWIG_FLAGS} -D${d} ) + endforeach() + + # check if we have IO_MGR and KICAD_PLUGIN available + if ( USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE ) + SET(SWIG_FLAGS ${SWIG_FLAGS} -DBUILD_WITH_PLUGIN) + endif() -# collect CFLAGS , and pass them to swig later - -get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS ) -foreach( d ${DirDefs} ) - SET(SWIG_FLAGS ${SWIG_FLAGS} -D${d} ) -endforeach() - -# check if we have IO_MGR and KICAD_PLUGIN available -if ( USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE ) - SET(SWIG_FLAGS ${SWIG_FLAGS} -DBUILD_WITH_PLUGIN) endif() - - -foreach( d ${SWIG_FLAGS} ) - message(STATUS "Swig options:" ${d}) -endforeach() - -SET(SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} ${SWIG_FLAGS} ) - - -# we checked the posibility to build kicad thinks in a separate module, but it -# will be easier in just one "pcbnew" for now -# -#add_custom_command( -# OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/kicad_wrap.cxx -# COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/kicad_wrap.cxx scripting/kicad.i -# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -#) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx - COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx scripting/pcbnew.i - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -) + +if (KICAD_SCRIPTING) + + SET(SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} ${SWIG_FLAGS} ) + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx + COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx scripting/pcbnew.i + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) + +endif(KICAD_SCRIPTING) ### # _pcbnew DLL/DSO file creation ### -SET(CMAKE_SWIG_FLAGS ${SWIG_FLAGS}) -SET_SOURCE_FILES_PROPERTIES(scripting/pcbnew.i PROPERTIES CPLUSPLUS ON) -SWIG_ADD_MODULE(pcbnew python scripting/pcbnew.i ${PCBNEW_SCRIPTING_PYTHON_HELPERS} ${PCBNEW_SRCS}) -SWIG_LINK_LIBRARIES(pcbnew - 3d-viewer - pcbcommon - common - bitmaps - polygon - kbool - ${wxWidgets_LIBRARIES} - ${OPENGL_LIBRARIES} - ${GDI_PLUS_LIBRARIES} - ${PYTHON_LIBRARIES}) +if (KICAD_SCRIPTING_MODULES) + SET(CMAKE_SWIG_FLAGS ${SWIG_FLAGS}) + SET_SOURCE_FILES_PROPERTIES(scripting/pcbnew.i PROPERTIES CPLUSPLUS ON) + SWIG_ADD_MODULE(pcbnew python scripting/pcbnew.i ${PCBNEW_SCRIPTING_PYTHON_HELPERS} ${PCBNEW_SRCS}) + SWIG_LINK_LIBRARIES(pcbnew + 3d-viewer + pcbcommon + common + bitmaps + polygon + kbool + ${wxWidgets_LIBRARIES} + ${OPENGL_LIBRARIES} + ${GDI_PLUS_LIBRARIES} + ${PYTHON_LIBRARIES}) + +endif (KICAD_SCRIPTING_MODULES) ### # Windows resource file @@ -390,6 +392,14 @@ install(TARGETS pcbnew DESTINATION ${KICAD_BIN} COMPONENT binary) +if (KICAD_SCRIPTING_MODULES) + install(FILES ${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py + DESTINATION share/python) + + install(FILES ${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.so + DESTINATION share/python) +endif(KICAD_SCRIPTING_MODULES) + # The specctra test fails to build properly using MS Visual Studio. if(NOT MSVC) diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index 14ef6c7420..db36f29b9c 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -49,6 +49,7 @@ #include #include +#include // Colors for layers and items COLORS_DESIGN_SETTINGS g_ColorsSettings; @@ -113,8 +114,11 @@ bool EDA_APP::OnInit() PCB_EDIT_FRAME* frame = NULL; int i=0; - + +#ifdef KICAD_SCRIPTING pcbnewInitPythonScripting(); +#endif + InitEDA_Appl( wxT( "Pcbnew" ), APP_PCBNEW_T ); @@ -150,6 +154,11 @@ Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); ReadHotkeyConfig( wxT( "PcbFrame" ), g_Board_Editor_Hokeys_Descr ); frame = new PCB_EDIT_FRAME( NULL, wxT( "Pcbnew" ), wxPoint( 0, 0 ), wxSize( 600, 400 ) ); + + #ifdef KICAD_SCRIPTING + ScriptingSetPcbEditFrame(frame); /* give the scripting helpers access to our frame */ + #endif + frame->UpdateTitle(); SetTopWindow( frame ); @@ -202,7 +211,7 @@ Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); */ frame->SetFocus(); frame->GetCanvas()->SetFocus(); - pythonSetPcbEditFrame(frame); + DIALOG_SCRIPTING* sw = new DIALOG_SCRIPTING(frame); sw->Show(true); return true; diff --git a/pcbnew/scripting/kicad.i b/pcbnew/scripting/kicad.i index e2f6805f60..77d9ab4731 100644 --- a/pcbnew/scripting/kicad.i +++ b/pcbnew/scripting/kicad.i @@ -25,17 +25,23 @@ #include #include #include - #include + #include using namespace std; + #include + #include %} +/* all the wx wrappers for wxString, wxPoint, wxRect, wxChar .. */ +%include + + %include %include %include +%include +%include -/* all the wx wrappers for wxString, wxPoint, wxRect, wxChar .. */ -%include /* namespace std diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index 27428fce27..7ba2e627b4 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -1,23 +1,26 @@ %module pcbnew - %include "kicad.i" -%{ - #include +// this is what it must be included in the wrapper .cxx code to compile + +%{ + #include #include #include #include #include #include #include - #include + #include #include #include + #include + #include + #include + #include + #include - - - - BOARD *GetBoard(); + BOARD *GetBoard(); /* get current editor board */ %} #ifdef BUILD_WITH_PLUGIN @@ -27,7 +30,6 @@ %} #endif - %include %include %include @@ -37,12 +39,32 @@ %include %include %include +%include +%include +%include +%include + +/* the IO_ERROR exception handler, not working yet... */ +%exception +{ + try { + $function + } + catch (IO_ERROR e) { + PyErr_SetString(PyExc_IOError,"IO error"); + return NULL; + } +} + +%include #ifdef BUILD_WITH_PLUGIN -%include -%include + %include + %include #endif +/* this is to help python with the * accessor of DLIST templates */ + %rename(Get) operator BOARD_ITEM*; %rename(Get) operator TRACK*; %rename(Get) operator D_PAD*; @@ -51,11 +73,16 @@ BOARD *GetBoard(); -// se must translate C++ templates to scripting languages +// we must translate C++ templates to scripting languages %template(BOARD_ITEM_List) DLIST; -%template(MODULE_List) DLIST; -%template(TRACK_List) DLIST; -%template(PAD_List) DLIST; +%template(MODULE_List) DLIST; +%template(TRACK_List) DLIST; +%template(PAD_List) DLIST; +/* TODO: -the std::* compilatio is broken with some swig + gcc combinations + * see kicad.i for more information. + * %template(MARKER_Vector) std::vector; + * %template(ZONE_CONTAINER_Vector) std::vector; + */ diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/scripting/pcbnew_scripting_helpers.cpp new file mode 100644 index 0000000000..ee2400903a --- /dev/null +++ b/pcbnew/scripting/pcbnew_scripting_helpers.cpp @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +#include + +static PCB_EDIT_FRAME *PcbEditFrame=NULL; + +BOARD *GetBoard() +{ + if (PcbEditFrame) return PcbEditFrame->GetBoard(); + else return NULL; +} + +void ScriptingSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame) +{ + PcbEditFrame = aPCBEdaFrame; +} + + +BOARD* LoadBoard(wxString aFileName) +{ +#ifdef USE_NEW_PCBNEW_LOAD + try{ + return IO_MGR::Load(IO_MGR::KICAD,aFileName); + } catch (IO_ERROR) + { + return NULL; + } +#else + fprintf(stderr,"Warning, LoadBoard not implemented without USE_NEW_PCBNEW_LOAD\n"); + return NULL; +#endif +} + +bool SaveBoard(wxString aFileName, BOARD* aBoard) +{ + +#ifdef USE_NEW_PCBNEW_LOAD + aBoard->m_Status_Pcb &= ~CONNEXION_OK; + aBoard->SynchronizeNetsAndNetClasses(); + aBoard->SetCurrentNetClass( aBoard->m_NetClasses.GetDefault()->GetName() ); + + wxString header = wxString::Format( + wxT( "PCBNEW-BOARD Version %d date %s\n\n# Created by Pcbnew%s\n\n" ), + BOARD_FILE_VERSION, DateAndTime().GetData(), + GetBuildVersion().GetData() ); + + PROPERTIES props; + + props["header"] = header; + + try + { + IO_MGR::Save( IO_MGR::KICAD, aFileName, aBoard, &props ); + return true; + } + catch (IO_ERROR) + { + return false; + } + +#else + fprintf(stderr,"Warning, SaveBoard not implemented without USE_NEW_PCBNEW_LOAD\n"); + return false; +#endif + +} + + diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.h b/pcbnew/scripting/pcbnew_scripting_helpers.h new file mode 100644 index 0000000000..4750f56f46 --- /dev/null +++ b/pcbnew/scripting/pcbnew_scripting_helpers.h @@ -0,0 +1,16 @@ +#ifndef __PCBNEW_SCRIPTING_HELPERS_H +#define __PCBNEW_SCRIPTING_HELPERS_H + +#include + +/* we could be including all these methods as static in a class, but + * we want plain pcbnew. access from python */ + +#ifndef SWIG +void ScriptingSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame); +#endif + +BOARD* LoadBoard(wxString aFileName); +bool SaveBoard(wxString aFileName, BOARD* aBoard); + +#endif \ No newline at end of file diff --git a/pcbnew/scripting/python_scripting.cpp b/pcbnew/scripting/python_scripting.cpp index 46135151cb..1a5bf7bc21 100644 --- a/pcbnew/scripting/python_scripting.cpp +++ b/pcbnew/scripting/python_scripting.cpp @@ -18,7 +18,8 @@ static int SwigNumModules = 0; /* Add a name + initfuction to our SwigImportInittab */ -static void swigAddModule(const char *name, void (*initfunc)()) { +static void swigAddModule(const char *name, void (*initfunc)()) +{ SwigImportInittab[SwigNumModules].name = (char *)name; SwigImportInittab[SwigNumModules].initfunc = initfunc; SwigNumModules++; @@ -28,7 +29,8 @@ static void swigAddModule(const char *name, void (*initfunc)()) { /* Add the builting python modules */ -static void swigAddBuiltin() { +static void swigAddBuiltin() +{ int i = 0; while (PyImport_Inittab[i].name) { swigAddModule(PyImport_Inittab[i].name, PyImport_Inittab[i].initfunc); @@ -38,26 +40,18 @@ static void swigAddBuiltin() { } static void swigAddModules() { - //swigAddModule("_kicad",init_kicad); swigAddModule("_pcbnew",init_pcbnew); + + // finally it seems better to include all in just one module + // but in case we needed to include any other modules, + // it must be done like this: + // swigAddModule("_kicad",init_kicad); + } static void swigSwitchPythonBuiltin() { - PyImport_Inittab = SwigImportInittab; -} - -static PCB_EDIT_FRAME *PcbEditFrame=NULL; - -BOARD *GetBoard() -{ - if (PcbEditFrame) return PcbEditFrame->GetBoard(); - else return NULL; -} - -void pythonSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame) -{ - PcbEditFrame = aPCBEdaFrame; + PyImport_Inittab = SwigImportInittab; } @@ -83,8 +77,9 @@ void pcbnewInitPythonScripting() of kicad here */ PyRun_SimpleString("import sys\n" - "sys.path.append(\".\")\n" + "sys.path.append(\".\")\n" "import pcbnew\n"); } + \ No newline at end of file diff --git a/pcbnew/scripting/python_scripting.h b/pcbnew/scripting/python_scripting.h index 03b0de8b63..32dfd2278d 100644 --- a/pcbnew/scripting/python_scripting.h +++ b/pcbnew/scripting/python_scripting.h @@ -1,11 +1,8 @@ #ifndef __PYTHON_SCRIPTING_H #define __PYTHON_SCRIPTING_H -#include #include -void pythonSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame); void pcbnewInitPythonScripting(void); - #endif From 06c570bab3b8415441bfe3baed24e402519a6320 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sat, 17 Mar 2012 18:30:03 +0100 Subject: [PATCH 08/41] * More cleanup (common wrappers moved to scripting, instead of pcbnew/scripting) * Added a first test 'testLoadSave.py' --- pcbnew/CMakeLists.txt | 9 ++- pcbnew/pcbnew.cpp | 4 +- pcbnew/scripting/kicad.i | 51 ------------ pcbnew/scripting/pcbnew.i | 30 +++++++ pcbnew/scripting/pcbnew_scripting_helpers.cpp | 30 +++++++ pcbnew/scripting/tests/test1.py | 4 +- pcbnew/scripting/tests/testLoadSave.py | 29 +++++++ scripting/kicad.i | 79 +++++++++++++++++++ .../python_scripting.cpp | 28 +++++++ .../python_scripting.h | 0 {pcbnew/scripting => scripting}/wx.i | 28 +++++++ .../wx_python_helpers.cpp | 29 +++++++ .../wx_python_helpers.h | 0 13 files changed, 263 insertions(+), 58 deletions(-) delete mode 100644 pcbnew/scripting/kicad.i create mode 100644 pcbnew/scripting/tests/testLoadSave.py create mode 100644 scripting/kicad.i rename {pcbnew/scripting => scripting}/python_scripting.cpp (60%) rename {pcbnew/scripting => scripting}/python_scripting.h (100%) rename {pcbnew/scripting => scripting}/wx.i (70%) rename {pcbnew/scripting => scripting}/wx_python_helpers.cpp (68%) rename {pcbnew/scripting => scripting}/wx_python_helpers.h (100%) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index bda556d348..e2d7f80496 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -1,6 +1,8 @@ add_definitions(-DPCBNEW) if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) + + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/scripting) FIND_PACKAGE(SWIG REQUIRED) INCLUDE(${SWIG_USE_FILE}) @@ -22,6 +24,7 @@ include_directories( ../polygon ../common/dialogs ./scripting + ../scripting ${INC_AFTER} ) @@ -230,9 +233,9 @@ set(PCBNEW_COMMON_SRCS if (KICAD_SCRIPTING) set(PCBNEW_SCRIPTING_PYTHON_HELPERS - scripting/wx_python_helpers.cpp + ../scripting/wx_python_helpers.cpp + ../scripting/python_scripting.cpp scripting/pcbnew_scripting_helpers.cpp - scripting/python_scripting.cpp ) set(PCBNEW_SCRIPTING_SRCS @@ -247,7 +250,7 @@ endif() if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) - set(SWIG_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -DDEBUG) + set(SWIG_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -I${CMAKE_CURRENT_SOURCE_DIR}/../scripting -DDEBUG) # collect CFLAGS , and pass them to swig later diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index db36f29b9c..85e74642dc 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -48,8 +48,8 @@ #include #include -#include -#include +#include +#include // Colors for layers and items COLORS_DESIGN_SETTINGS g_ColorsSettings; diff --git a/pcbnew/scripting/kicad.i b/pcbnew/scripting/kicad.i deleted file mode 100644 index 77d9ab4731..0000000000 --- a/pcbnew/scripting/kicad.i +++ /dev/null @@ -1,51 +0,0 @@ -//%module kicad - -/* OFF NOW, it triggers an error with GCC 4.6 and swig-2.0.4 or trunk.. - http://sourceforge.net/tracker/index.php?func=detail&aid=3391906&group_id=1645&atid=101645 - - %include - %include -*/ -%nodefaultctor EDA_ITEM; - - -/* swig tries to wrap SetBack/SetNext on derived classes, but this method is - private for most childs, so if we don't ignore it it won't compile */ - -%ignore EDA_ITEM::SetBack; -%ignore EDA_ITEM::SetNext; - - -%ignore InitKiCadAbout; -%ignore GetCommandOptions; - -%{ - #include - #include - #include - #include - #include - #include - using namespace std; - #include - #include - -%} - -/* all the wx wrappers for wxString, wxPoint, wxRect, wxChar .. */ -%include - - -%include -%include -%include -%include -%include - - -/* -namespace std -{ - %template(intVector) vector; -} -*/ diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index 7ba2e627b4..bda640a789 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -1,3 +1,33 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file pcbnew.i + * @brief Specific pcbnew wrappers + */ + + %module pcbnew %include "kicad.i" diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/scripting/pcbnew_scripting_helpers.cpp index ee2400903a..8315ff216d 100644 --- a/pcbnew/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/scripting/pcbnew_scripting_helpers.cpp @@ -1,3 +1,33 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file pcbnew_scripting_helpers.cpp + * @brief Scripting helper functions for pcbnew functionality + */ + + #include #include #include diff --git a/pcbnew/scripting/tests/test1.py b/pcbnew/scripting/tests/test1.py index 6b50b24914..82d73dcd23 100644 --- a/pcbnew/scripting/tests/test1.py +++ b/pcbnew/scripting/tests/test1.py @@ -1,10 +1,10 @@ pcb = pcbnew.GetBoard() -m = pcb.m_Modules.item() +m = pcb.m_Modules while m: print m.GetPosition() - p = m.m_Pads.item() + p = m.m_Pads while p: print "p=>",p.GetPosition(),p.GetPadName() print p.GetPosition() diff --git a/pcbnew/scripting/tests/testLoadSave.py b/pcbnew/scripting/tests/testLoadSave.py new file mode 100644 index 0000000000..cabdacdef3 --- /dev/null +++ b/pcbnew/scripting/tests/testLoadSave.py @@ -0,0 +1,29 @@ +from pcbnew import * +import unittest + +class TestLoadSave(unittest.TestCase): + + def setUp(self): + self.TITLE="Test Board" + self.COMMENT1="For load/save test" + self.FILENAME="/tmp/test.brd" + + def test_00_save(self): + pcb = BOARD() + pcb.GetTitleBlock().SetTitle(self.TITLE) + pcb.GetTitleBlock().SetComment1(self.COMMENT1) + result = SaveBoard(self.FILENAME,pcb) + self.assertTrue(result) + + def test_01_load(self): + pcb2 = LoadBoard(self.FILENAME) + self.assertIsNotNone(pcb2) + + def test_02_titleblock_ok(self): + pcb2 = LoadBoard(self.FILENAME) + tb = pcb2.GetTitleBlock() + self.assertEqual(tb.GetTitle(),self.TITLE) + self.assertEqual(tb.GetComment1(),self.COMMENT1) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/scripting/kicad.i b/scripting/kicad.i new file mode 100644 index 0000000000..5bd5dd11f7 --- /dev/null +++ b/scripting/kicad.i @@ -0,0 +1,79 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file kicad.i + * @brief General wrappers for kicad / wx structures and classes + */ + + +/* OFF NOW, it triggers an error with GCC 4.6 and swig-2.0.4 or trunk.. + http://sourceforge.net/tracker/index.php?func=detail&aid=3391906&group_id=1645&atid=101645 + + %include + %include +*/ +%nodefaultctor EDA_ITEM; + + +/* swig tries to wrap SetBack/SetNext on derived classes, but this method is + private for most childs, so if we don't ignore it it won't compile */ + +%ignore EDA_ITEM::SetBack; +%ignore EDA_ITEM::SetNext; + + +%ignore InitKiCadAbout; +%ignore GetCommandOptions; + +%{ + #include + #include + #include + #include + #include + #include + using namespace std; + #include + #include + +%} + +/* all the wx wrappers for wxString, wxPoint, wxRect, wxChar .. */ +%include + + +%include +%include +%include +%include +%include + + +/* +namespace std +{ + %template(intVector) vector; +} +*/ diff --git a/pcbnew/scripting/python_scripting.cpp b/scripting/python_scripting.cpp similarity index 60% rename from pcbnew/scripting/python_scripting.cpp rename to scripting/python_scripting.cpp index 1a5bf7bc21..d8f07e67b3 100644 --- a/pcbnew/scripting/python_scripting.cpp +++ b/scripting/python_scripting.cpp @@ -1,3 +1,31 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file python_scripting.cpp + * @brief methods to add scripting capabilities inside pcbnew + */ #include diff --git a/pcbnew/scripting/python_scripting.h b/scripting/python_scripting.h similarity index 100% rename from pcbnew/scripting/python_scripting.h rename to scripting/python_scripting.h diff --git a/pcbnew/scripting/wx.i b/scripting/wx.i similarity index 70% rename from pcbnew/scripting/wx.i rename to scripting/wx.i index 61f6c8ce38..2c5cfae95c 100644 --- a/pcbnew/scripting/wx.i +++ b/scripting/wx.i @@ -1,3 +1,31 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file wx.i + * @brief wx wrappers for basic things, wxString, wxPoint, wxRect, etc.. + */ %{ #include diff --git a/pcbnew/scripting/wx_python_helpers.cpp b/scripting/wx_python_helpers.cpp similarity index 68% rename from pcbnew/scripting/wx_python_helpers.cpp rename to scripting/wx_python_helpers.cpp index aee5885019..a3c4848f93 100644 --- a/pcbnew/scripting/wx_python_helpers.cpp +++ b/scripting/wx_python_helpers.cpp @@ -1,3 +1,32 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file wx_python_helpers.cpp + * @brief Python wrapping helpers for wx structures/objects + */ + #include #include #include diff --git a/pcbnew/scripting/wx_python_helpers.h b/scripting/wx_python_helpers.h similarity index 100% rename from pcbnew/scripting/wx_python_helpers.h rename to scripting/wx_python_helpers.h From c0be31aedacbbb3b242713a7d054a288c4295341 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sun, 18 Mar 2012 10:09:51 +0100 Subject: [PATCH 09/41] Fixed some indent, and added some conditional compiles on pcbnew.cpp --- pcbnew/pcbnew.cpp | 4 +--- pcbnew/scripting/tests/testLoadSave.py | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index 85e74642dc..e2495f19c9 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -113,8 +113,6 @@ bool EDA_APP::OnInit() wxFileName fn; PCB_EDIT_FRAME* frame = NULL; - int i=0; - #ifdef KICAD_SCRIPTING pcbnewInitPythonScripting(); #endif @@ -156,7 +154,7 @@ Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); frame = new PCB_EDIT_FRAME( NULL, wxT( "Pcbnew" ), wxPoint( 0, 0 ), wxSize( 600, 400 ) ); #ifdef KICAD_SCRIPTING - ScriptingSetPcbEditFrame(frame); /* give the scripting helpers access to our frame */ + ScriptingSetPcbEditFrame(frame); /* give the scripting helpers access to our frame */ #endif frame->UpdateTitle(); diff --git a/pcbnew/scripting/tests/testLoadSave.py b/pcbnew/scripting/tests/testLoadSave.py index cabdacdef3..d8d9649a38 100644 --- a/pcbnew/scripting/tests/testLoadSave.py +++ b/pcbnew/scripting/tests/testLoadSave.py @@ -4,26 +4,26 @@ import unittest class TestLoadSave(unittest.TestCase): def setUp(self): - self.TITLE="Test Board" - self.COMMENT1="For load/save test" - self.FILENAME="/tmp/test.brd" - + self.TITLE="Test Board" + self.COMMENT1="For load/save test" + self.FILENAME="/tmp/test.brd" + def test_00_save(self): - pcb = BOARD() - pcb.GetTitleBlock().SetTitle(self.TITLE) - pcb.GetTitleBlock().SetComment1(self.COMMENT1) - result = SaveBoard(self.FILENAME,pcb) - self.assertTrue(result) + pcb = BOARD() + pcb.GetTitleBlock().SetTitle(self.TITLE) + pcb.GetTitleBlock().SetComment1(self.COMMENT1) + result = SaveBoard(self.FILENAME,pcb) + self.assertTrue(result) def test_01_load(self): pcb2 = LoadBoard(self.FILENAME) self.assertIsNotNone(pcb2) def test_02_titleblock_ok(self): - pcb2 = LoadBoard(self.FILENAME) - tb = pcb2.GetTitleBlock() - self.assertEqual(tb.GetTitle(),self.TITLE) - self.assertEqual(tb.GetComment1(),self.COMMENT1) + pcb2 = LoadBoard(self.FILENAME) + tb = pcb2.GetTitleBlock() + self.assertEqual(tb.GetTitle(),self.TITLE) + self.assertEqual(tb.GetComment1(),self.COMMENT1) if __name__ == '__main__': unittest.main() \ No newline at end of file From b28dbd31c3a0949e84457ec49f0b9facd546819e Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sun, 18 Mar 2012 22:35:51 +0100 Subject: [PATCH 10/41] Cast() method to cast down classes from BOARD_ITEM to all childs --- pcbnew/scripting/pcbnew.i | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index bda640a789..32baad7083 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -36,6 +36,7 @@ %{ #include #include + #include #include #include #include @@ -43,12 +44,17 @@ #include #include #include + #include + #include + #include + #include #include #include #include #include #include #include + BOARD *GetBoard(); /* get current editor board */ %} @@ -61,6 +67,7 @@ #endif %include +%include %include %include %include @@ -68,12 +75,17 @@ %include %include %include +%include +%include +%include +%include %include %include %include %include %include + /* the IO_ERROR exception handler, not working yet... */ %exception { @@ -86,6 +98,64 @@ } } +/* Cast downs from EDA_ITEM/BOARD_ITEM to childs */ + + +%inline +{ + BOARD_ITEM* Cast_to_BOARD_ITEM(EDA_ITEM* base) { return dynamic_cast(base); } +} + +%extend BOARD_ITEM +{ + TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast(self); } + DIMENSION* Cast_to_DIMENSION() { return dynamic_cast(self); } + MODULE* Cast_to_MODULE() { return dynamic_cast(self); } + TEXTE_MODULE* Cast_to_TEXTE_MODULE(){ return dynamic_cast(self); } + DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast(self); } + MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast(self); } + BOARD* Cast_to_BOARD() { return dynamic_cast(self); } + EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast(self); } + D_PAD* Cast_to_D_PAD() { return dynamic_cast(self); } + TRACK* Cast_to_TRACK() { return dynamic_cast(self); } + SEGZONE* Cast_to_SEGZONE() { return dynamic_cast(self); } + SEGVIA* Cast_to_SEGVIA() { return dynamic_cast(self); } + + + + %pythoncode + { + def Cast(self): + ct = self.GetClass() + if ct=="PTEXT": + return self.Cast_to_TEXTE_PCB() + elif ct=="BOARD": + return self.Cast_to_BOARD() + elif ct=="DIMENSION": + return self.Cast_to_DIMENSION() + elif ct=="DRAWSEGMENT": + return self.Cast_to_DRAWSEGMENT() + elif ct=="MGRAPHIC": + return self.Cast_to_EDGE_MODULE() + elif ct=="MODULE": + return self.Cast_to_MODULE() + elif ct=="PAD": + return self.Cast_to_D_PAD() + elif ct=="MTEXT": + return self.Cast_to_TEXTE_MODULE() + elif ct=="ZONE": + return self.Cast_to_SEGZONE() + elif ct=="VIA": + return self.Cast_to_SEGVIA() + elif ct=="TRACK": + return self.Cast_to_TRACK() + else: + return None + } +} + + + %include #ifdef BUILD_WITH_PLUGIN From 7a256041619dcdfd382013dd5e381dd3a9dc951e Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Mon, 19 Mar 2012 08:40:43 +0100 Subject: [PATCH 11/41] fixed ident tabs --- pcbnew/scripting/pcbnew.i | 144 +++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index 32baad7083..d778bf7e3d 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -35,34 +35,34 @@ %{ #include - #include - #include - #include - #include - #include - #include - #include + #include + #include + #include + #include + #include + #include + #include #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + - BOARD *GetBoard(); /* get current editor board */ + BOARD *GetBoard(); /* get current editor board */ %} #ifdef BUILD_WITH_PLUGIN %{ - #include - #include + #include + #include %} #endif @@ -89,13 +89,13 @@ /* the IO_ERROR exception handler, not working yet... */ %exception { - try { - $function - } - catch (IO_ERROR e) { - PyErr_SetString(PyExc_IOError,"IO error"); - return NULL; - } + try { + $function + } + catch (IO_ERROR e) { + PyErr_SetString(PyExc_IOError,"IO error"); + return NULL; + } } /* Cast downs from EDA_ITEM/BOARD_ITEM to childs */ @@ -103,55 +103,55 @@ %inline { - BOARD_ITEM* Cast_to_BOARD_ITEM(EDA_ITEM* base) { return dynamic_cast(base); } + BOARD_ITEM* Cast_to_BOARD_ITEM(EDA_ITEM* base) { return dynamic_cast(base); } } %extend BOARD_ITEM { - TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast(self); } - DIMENSION* Cast_to_DIMENSION() { return dynamic_cast(self); } - MODULE* Cast_to_MODULE() { return dynamic_cast(self); } - TEXTE_MODULE* Cast_to_TEXTE_MODULE(){ return dynamic_cast(self); } - DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast(self); } - MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast(self); } - BOARD* Cast_to_BOARD() { return dynamic_cast(self); } - EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast(self); } - D_PAD* Cast_to_D_PAD() { return dynamic_cast(self); } - TRACK* Cast_to_TRACK() { return dynamic_cast(self); } - SEGZONE* Cast_to_SEGZONE() { return dynamic_cast(self); } - SEGVIA* Cast_to_SEGVIA() { return dynamic_cast(self); } - + TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast(self); } + DIMENSION* Cast_to_DIMENSION() { return dynamic_cast(self); } + MODULE* Cast_to_MODULE() { return dynamic_cast(self); } + TEXTE_MODULE* Cast_to_TEXTE_MODULE(){ return dynamic_cast(self); } + DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast(self); } + MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast(self); } + BOARD* Cast_to_BOARD() { return dynamic_cast(self); } + EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast(self); } + D_PAD* Cast_to_D_PAD() { return dynamic_cast(self); } + TRACK* Cast_to_TRACK() { return dynamic_cast(self); } + SEGZONE* Cast_to_SEGZONE() { return dynamic_cast(self); } + SEGVIA* Cast_to_SEGVIA() { return dynamic_cast(self); } + - %pythoncode - { - def Cast(self): - ct = self.GetClass() - if ct=="PTEXT": - return self.Cast_to_TEXTE_PCB() - elif ct=="BOARD": - return self.Cast_to_BOARD() - elif ct=="DIMENSION": - return self.Cast_to_DIMENSION() - elif ct=="DRAWSEGMENT": - return self.Cast_to_DRAWSEGMENT() - elif ct=="MGRAPHIC": - return self.Cast_to_EDGE_MODULE() - elif ct=="MODULE": - return self.Cast_to_MODULE() - elif ct=="PAD": - return self.Cast_to_D_PAD() - elif ct=="MTEXT": - return self.Cast_to_TEXTE_MODULE() - elif ct=="ZONE": - return self.Cast_to_SEGZONE() - elif ct=="VIA": - return self.Cast_to_SEGVIA() - elif ct=="TRACK": - return self.Cast_to_TRACK() - else: - return None - } + %pythoncode + { + def Cast(self): + ct = self.GetClass() + if ct=="PTEXT": + return self.Cast_to_TEXTE_PCB() + elif ct=="BOARD": + return self.Cast_to_BOARD() + elif ct=="DIMENSION": + return self.Cast_to_DIMENSION() + elif ct=="DRAWSEGMENT": + return self.Cast_to_DRAWSEGMENT() + elif ct=="MGRAPHIC": + return self.Cast_to_EDGE_MODULE() + elif ct=="MODULE": + return self.Cast_to_MODULE() + elif ct=="PAD": + return self.Cast_to_D_PAD() + elif ct=="MTEXT": + return self.Cast_to_TEXTE_MODULE() + elif ct=="ZONE": + return self.Cast_to_SEGZONE() + elif ct=="VIA": + return self.Cast_to_SEGVIA() + elif ct=="TRACK": + return self.Cast_to_TRACK() + else: + return None + } } From 9398eb9767736d6891c71acc10616b77a5a2c9f2 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Mon, 19 Mar 2012 09:36:38 +0100 Subject: [PATCH 12/41] std::vector and std::string items DLIST iterator code, now we can do: for module in pcb.m_Modules: print module.GetReference() instead of: module = pcb.m_Modules while module: print module.GetReference() module = module.Next() or even: module_list = list(pcb.m_Modules) --- pcbnew/scripting/pcbnew.i | 11 ++++++----- scripting/kicad.i | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index d778bf7e3d..c74d00fdc6 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -180,9 +180,10 @@ BOARD *GetBoard(); %template(TRACK_List) DLIST; %template(PAD_List) DLIST; -/* TODO: -the std::* compilatio is broken with some swig + gcc combinations - * see kicad.i for more information. - * %template(MARKER_Vector) std::vector; - * %template(ZONE_CONTAINER_Vector) std::vector; - */ + + +%template(MARKER_Vector) std::vector; +%template(ZONE_CONTAINER_Vector) std::vector; +%template(VIA_DIMENSION_Vector) std::vector; + diff --git a/scripting/kicad.i b/scripting/kicad.i index 5bd5dd11f7..b2c9809c69 100644 --- a/scripting/kicad.i +++ b/scripting/kicad.i @@ -30,10 +30,12 @@ /* OFF NOW, it triggers an error with GCC 4.6 and swig-2.0.4 or trunk.. http://sourceforge.net/tracker/index.php?func=detail&aid=3391906&group_id=1645&atid=101645 +*/ + %include %include -*/ + %nodefaultctor EDA_ITEM; @@ -48,6 +50,7 @@ %ignore GetCommandOptions; %{ + #include #include #include #include @@ -63,7 +66,6 @@ /* all the wx wrappers for wxString, wxPoint, wxRect, wxChar .. */ %include - %include %include %include @@ -71,9 +73,34 @@ %include -/* -namespace std +%extend DLIST { - %template(intVector) vector; + %pythoncode + { + class DLISTIter: + def __init__(self,aList): + self.last = aList + + def next(self): + if self.last is None: + raise StopIteration + else: + ret = None + + # first item in list has "Get" as a DLIST + try: + ret = self.last.Get() + except: + ret = self.last #next items just not.. + + self.last = self.last.Next() + return ret + + def __iter__(self): + return self.DLISTIter(self) + + } } -*/ +%template(intVector) std::vector; + + From 9ebe983eaa3767bd3fe3e2f3c81a9178e352681f Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Mon, 19 Mar 2012 12:21:29 +0100 Subject: [PATCH 13/41] * cleanups: board.i board_item.i separated from pcbnew.i * dlist.i empty list fixed (Segfault) * units.i: FromMM FromMils ToMM ToMils * added a little example (listPcb.py) that shows most items in a board --- pcbnew/scripting/TODO.txt | 4 + pcbnew/scripting/board.i | 80 +++++++++++++++++ pcbnew/scripting/board_item.i | 86 +++++++++++++++++++ pcbnew/scripting/examples/listPcb.py | 62 ++++++++++++++ pcbnew/scripting/pcbnew.i | 95 +-------------------- pcbnew/scripting/pcbnew_scripting_helpers.h | 1 + pcbnew/scripting/units.i | 58 +++++++++++++ scripting/dlist.i | 42 +++++++++ scripting/kicad.i | 50 +++++------ 9 files changed, 357 insertions(+), 121 deletions(-) create mode 100644 pcbnew/scripting/TODO.txt create mode 100644 pcbnew/scripting/board.i create mode 100644 pcbnew/scripting/board_item.i create mode 100644 pcbnew/scripting/examples/listPcb.py create mode 100644 pcbnew/scripting/units.i create mode 100644 scripting/dlist.i diff --git a/pcbnew/scripting/TODO.txt b/pcbnew/scripting/TODO.txt new file mode 100644 index 0000000000..525d130cd6 --- /dev/null +++ b/pcbnew/scripting/TODO.txt @@ -0,0 +1,4 @@ + +iterator for NETCLASSES (NETCLASS) see class_netclass.h + + diff --git a/pcbnew/scripting/board.i b/pcbnew/scripting/board.i new file mode 100644 index 0000000000..3d20f10d2f --- /dev/null +++ b/pcbnew/scripting/board.i @@ -0,0 +1,80 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file board.i + * @brief Specific BOARD extensions and templates + */ + + +%extend BOARD +{ + %pythoncode + { + def GetModules(self): return self.m_Modules + def GetDrawings(self): return self.m_Drawings + def GetTracks(self): return self.m_Track + def GetSegZones(self): return self.m_Zone + def GetFullRatsnest(self): return self.m_FullRatsnest + def GetLocalRatsnest(self): return self.m_LocalRatsnest + def GetNetClasses(self): return self.m_NetClasses + def GetCurrentNetClassName(self): return self.m_CurrentNetClassName + def GetViasDimensionsList(self): return self.m_ViasDimensionsList + def GetTrackWidthList(self): return self.m_TrackWidthList + + def Save(self,filename): + return pcbnew.SaveBoard(filename,self) + } + +} + +// this is to help python with the * accessor of DLIST templates + +%rename(Get) operator BOARD_ITEM*; +%rename(Get) operator TRACK*; +%rename(Get) operator D_PAD*; +%rename(Get) operator MODULE*; +%rename(Get) operator SEGZONE*; + +// we must translate C++ templates to scripting languages + +%template(BOARD_ITEM_List) DLIST; +%template(MODULE_List) DLIST; +%template(SEGZONE_List) DLIST; +%template(TRACK_List) DLIST; +%template(PAD_List) DLIST; + +// std::vector templates + +%template(VIA_DIMENSION_Vector) std::vector; +%template (RASTNET_Vector) std::vector; + +%extend DRAWSEGMENT +{ + %pythoncode + { + def GetShapeStr(self): + return self.ShowShape(self.GetShape()) + } +} \ No newline at end of file diff --git a/pcbnew/scripting/board_item.i b/pcbnew/scripting/board_item.i new file mode 100644 index 0000000000..37e3ed1f83 --- /dev/null +++ b/pcbnew/scripting/board_item.i @@ -0,0 +1,86 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file board_item.i + * @brief board_item helpers, mainly for casting down to all child classes + */ + + +/* Cast downs from EDA_ITEM/BOARD_ITEM to childs */ + +%inline +{ + BOARD_ITEM* Cast_to_BOARD_ITEM(EDA_ITEM* base) { return dynamic_cast(base); } +} + +%extend BOARD_ITEM +{ + TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast(self); } + DIMENSION* Cast_to_DIMENSION() { return dynamic_cast(self); } + MODULE* Cast_to_MODULE() { return dynamic_cast(self); } + TEXTE_MODULE* Cast_to_TEXTE_MODULE(){ return dynamic_cast(self); } + DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast(self); } + MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast(self); } + BOARD* Cast_to_BOARD() { return dynamic_cast(self); } + EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast(self); } + D_PAD* Cast_to_D_PAD() { return dynamic_cast(self); } + TRACK* Cast_to_TRACK() { return dynamic_cast(self); } + SEGZONE* Cast_to_SEGZONE() { return dynamic_cast(self); } + SEGVIA* Cast_to_SEGVIA() { return dynamic_cast(self); } + + + + %pythoncode + { + def Cast(self): + + ct = self.GetClass() + + if ct=="PTEXT": + return self.Cast_to_TEXTE_PCB() + elif ct=="BOARD": + return self.Cast_to_BOARD() + elif ct=="DIMENSION": + return self.Cast_to_DIMENSION() + elif ct=="DRAWSEGMENT": + return self.Cast_to_DRAWSEGMENT() + elif ct=="MGRAPHIC": + return self.Cast_to_EDGE_MODULE() + elif ct=="MODULE": + return self.Cast_to_MODULE() + elif ct=="PAD": + return self.Cast_to_D_PAD() + elif ct=="MTEXT": + return self.Cast_to_TEXTE_MODULE() + elif ct=="ZONE": + return self.Cast_to_SEGZONE() + elif ct=="VIA": + return self.Cast_to_SEGVIA() + elif ct=="TRACK": + return self.Cast_to_TRACK() + else: + return None + } +} diff --git a/pcbnew/scripting/examples/listPcb.py b/pcbnew/scripting/examples/listPcb.py new file mode 100644 index 0000000000..879622dba4 --- /dev/null +++ b/pcbnew/scripting/examples/listPcb.py @@ -0,0 +1,62 @@ +import sys +from pcbnew import * + +filename=sys.argv[1] + +pcb = LoadBoard(filename) + +#ToUnits = ToMM +#FromUnits = FromMM +ToUnits=ToMils +FromUnits=FromMils + +print "LISTING VIAS:" + +for item in pcb.GetTracks(): + if type(item) is SEGVIA: + + pos = item.GetPosition() + drill = item.GetDrillValue() + width = item.GetWidth() + print " * Via: %s - %f/%f "%(ToUnits(pos),ToUnits(drill),ToUnits(width)) + + elif type(item) is TRACK: + + start = item.GetStart() + end = item.GetEnd() + width = item.GetWidth() + + print " * Track: %s to %s, width %f" % (ToUnits(start),ToUnits(end),ToUnits(width)) + + else: + print "Unknown type %s" % type(item) + +print "" +print "LISTING DRAWINGS:" + +for item in pcb.GetDrawings(): + if type(item) is TEXTE_PCB: + print "* Text: '%s' at %s"%(item.GetText(),item.GetPosition()) + elif type(item) is DRAWSEGMENT: + print "* Drawing: %s"%item.GetShapeStr() # dir(item) + else: + print type(item) + +print "" +print "LIST MODULES:" + +for module in pcb.GetModules(): + print "* Module: %s at %s"%(module.GetReference(),ToUnits(module.GetPosition())) + +print "" +print "LIST ZONES:" + +for zone in pcb.GetSegZones(): + print zone + + +print "" +print "RATSNEST:",len(pcb.GetFullRatsnest()) + +print dir(pcb.GetNetClasses()) + \ No newline at end of file diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index c74d00fdc6..4d858f7581 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -85,76 +85,7 @@ %include %include - -/* the IO_ERROR exception handler, not working yet... */ -%exception -{ - try { - $function - } - catch (IO_ERROR e) { - PyErr_SetString(PyExc_IOError,"IO error"); - return NULL; - } -} - -/* Cast downs from EDA_ITEM/BOARD_ITEM to childs */ - - -%inline -{ - BOARD_ITEM* Cast_to_BOARD_ITEM(EDA_ITEM* base) { return dynamic_cast(base); } -} - -%extend BOARD_ITEM -{ - TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast(self); } - DIMENSION* Cast_to_DIMENSION() { return dynamic_cast(self); } - MODULE* Cast_to_MODULE() { return dynamic_cast(self); } - TEXTE_MODULE* Cast_to_TEXTE_MODULE(){ return dynamic_cast(self); } - DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast(self); } - MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast(self); } - BOARD* Cast_to_BOARD() { return dynamic_cast(self); } - EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast(self); } - D_PAD* Cast_to_D_PAD() { return dynamic_cast(self); } - TRACK* Cast_to_TRACK() { return dynamic_cast(self); } - SEGZONE* Cast_to_SEGZONE() { return dynamic_cast(self); } - SEGVIA* Cast_to_SEGVIA() { return dynamic_cast(self); } - - - - %pythoncode - { - def Cast(self): - ct = self.GetClass() - if ct=="PTEXT": - return self.Cast_to_TEXTE_PCB() - elif ct=="BOARD": - return self.Cast_to_BOARD() - elif ct=="DIMENSION": - return self.Cast_to_DIMENSION() - elif ct=="DRAWSEGMENT": - return self.Cast_to_DRAWSEGMENT() - elif ct=="MGRAPHIC": - return self.Cast_to_EDGE_MODULE() - elif ct=="MODULE": - return self.Cast_to_MODULE() - elif ct=="PAD": - return self.Cast_to_D_PAD() - elif ct=="MTEXT": - return self.Cast_to_TEXTE_MODULE() - elif ct=="ZONE": - return self.Cast_to_SEGZONE() - elif ct=="VIA": - return self.Cast_to_SEGVIA() - elif ct=="TRACK": - return self.Cast_to_TRACK() - else: - return None - } -} - - +%include "board_item.i" %include @@ -163,27 +94,7 @@ %include #endif -/* this is to help python with the * accessor of DLIST templates */ - -%rename(Get) operator BOARD_ITEM*; -%rename(Get) operator TRACK*; -%rename(Get) operator D_PAD*; -%rename(Get) operator MODULE*; - - -BOARD *GetBoard(); - -// we must translate C++ templates to scripting languages - -%template(BOARD_ITEM_List) DLIST; -%template(MODULE_List) DLIST; -%template(TRACK_List) DLIST; -%template(PAD_List) DLIST; - - - -%template(MARKER_Vector) std::vector; -%template(ZONE_CONTAINER_Vector) std::vector; -%template(VIA_DIMENSION_Vector) std::vector; +%include "board.i" +%include "units.i" diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.h b/pcbnew/scripting/pcbnew_scripting_helpers.h index 4750f56f46..eca5f62aba 100644 --- a/pcbnew/scripting/pcbnew_scripting_helpers.h +++ b/pcbnew/scripting/pcbnew_scripting_helpers.h @@ -8,6 +8,7 @@ #ifndef SWIG void ScriptingSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame); +BOARD *GetBoard(); #endif BOARD* LoadBoard(wxString aFileName); diff --git a/pcbnew/scripting/units.i b/pcbnew/scripting/units.i new file mode 100644 index 0000000000..87b784f5d9 --- /dev/null +++ b/pcbnew/scripting/units.i @@ -0,0 +1,58 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file units.i + * @brief unit conversion code + */ + +// Unit conversion, must be conditionally adapter to the new +// nanometer mode that will be soon included in pcbnew + +%pythoncode +{ + def ToMM(iu): + if type(iu) is int: + return iu * 0.00254 + elif type(iu) is wxPoint: + return tuple(map(ToMM,iu)) + + def FromMM(mm): + if type(iu) is int: + return iu / 0.00254 + elif type(iu) is wxPoint: + return tuple(map(FromMM,iu)) + + def ToMils(iu): + if type(iu) is int: + return iu / 10.0 + elif type(iu) is wxPoint: + return tuple(map(ToMils,iu)) + + def FromMils(mils): + if type(iu) is int: + return mils*10.0 + elif type(iu) is wxPoint: + return tuple(map(FromMils,iu)) +} \ No newline at end of file diff --git a/scripting/dlist.i b/scripting/dlist.i new file mode 100644 index 0000000000..c05c6a237f --- /dev/null +++ b/scripting/dlist.i @@ -0,0 +1,42 @@ +/* DLIST python iteration code, to allow standard iteration over DLIST */ + +%extend DLIST +{ + %pythoncode + { + class DLISTIter: + def __init__(self,aList): + self.last = aList + + def next(self): + + item = self.last + try: + item = item.Get() + except: + pass + + if item is None: + raise StopIteration + else: + ret = None + + # first item in list has "Get" as a DLIST + try: + ret = self.last.Get() + except: + ret = self.last #next items just not.. + + self.last = self.last.Next() + + # when the iterated object can be casted down in inheritance, just do it.. + if 'Cast' in dir(ret): + ret = ret.Cast() + + return ret + + def __iter__(self): + return self.DLISTIter(self) + + } +} diff --git a/scripting/kicad.i b/scripting/kicad.i index b2c9809c69..becaa24027 100644 --- a/scripting/kicad.i +++ b/scripting/kicad.i @@ -60,47 +60,39 @@ using namespace std; #include #include + #include %} /* all the wx wrappers for wxString, wxPoint, wxRect, wxChar .. */ %include +/* exception handling */ + +/* the IO_ERROR exception handler, not working yet... */ +%exception +{ + try { + $function + } + catch (IO_ERROR e) { + PyErr_SetString(PyExc_IOError,"IO error"); + return NULL; + } +} + + + %include %include %include %include %include +%include -%extend DLIST -{ - %pythoncode - { - class DLISTIter: - def __init__(self,aList): - self.last = aList - - def next(self): - if self.last is None: - raise StopIteration - else: - ret = None - - # first item in list has "Get" as a DLIST - try: - ret = self.last.Get() - except: - ret = self.last #next items just not.. - - self.last = self.last.Next() - return ret - - def __iter__(self): - return self.DLISTIter(self) - - } -} +%include "dlist.i" + +/* std template mappings */ %template(intVector) std::vector; - From cd93e14d7d48bfb09fa37e79a8624331cb8fc0f6 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Mon, 19 Mar 2012 16:39:50 +0100 Subject: [PATCH 14/41] fixed DEBUG build dependency... --- pcbnew/CMakeLists.txt | 6 ++++-- scripting/kicad.i | 6 +++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index e2d7f80496..ac500c2b22 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -250,8 +250,10 @@ endif() if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) - set(SWIG_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -I${CMAKE_CURRENT_SOURCE_DIR}/../scripting -DDEBUG) - + set(SWIG_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/../include -I${CMAKE_CURRENT_SOURCE_DIR}/../scripting ) + if (DEBUG) + set(SWIG_FLAGS ${SWIG_FLAGS} -DDEBUG) + endif() # collect CFLAGS , and pass them to swig later get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS ) diff --git a/scripting/kicad.i b/scripting/kicad.i index becaa24027..4719c8b559 100644 --- a/scripting/kicad.i +++ b/scripting/kicad.i @@ -36,8 +36,12 @@ %include %include -%nodefaultctor EDA_ITEM; +/* ignore some constructors of EDA_ITEM that will make the build fail */ +%nodefaultctor EDA_ITEM; +%ignore EDA_ITEM::EDA_ITEM( EDA_ITEM* parent, KICAD_T idType ); +%ignore EDA_ITEM::EDA_ITEM( KICAD_T idType ); +%ignore EDA_ITEM::EDA_ITEM( const EDA_ITEM& base ); /* swig tries to wrap SetBack/SetNext on derived classes, but this method is private for most childs, so if we don't ignore it it won't compile */ From 6d643f70b523b479c4266c00dc7f47fd7839c8d8 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Tue, 20 Mar 2012 07:34:23 +0100 Subject: [PATCH 15/41] Fixed Board.Save, listPcb.py +x and updated TODO.txt --- pcbnew/scripting/TODO.txt | 12 +++++++++++- pcbnew/scripting/board.i | 2 +- pcbnew/scripting/examples/listPcb.py | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) mode change 100644 => 100755 pcbnew/scripting/examples/listPcb.py diff --git a/pcbnew/scripting/TODO.txt b/pcbnew/scripting/TODO.txt index 525d130cd6..357ba8960d 100644 --- a/pcbnew/scripting/TODO.txt +++ b/pcbnew/scripting/TODO.txt @@ -1,4 +1,14 @@ -iterator for NETCLASSES (NETCLASS) see class_netclass.h +* Tell swig(somehow) to forget automatic object deletion after adding + a BOARD_ITEM to BOARD object (it will be automatically deleted by BOARD, + leading to Segmentation Fault when unloading our python module (double free). + +* implement iterator for NETCLASSES (NETCLASS) see class_netclass.h + +* add MODULE::Add (see BOARD:Add), to make it more clean + +* add wxSize implementation to wx.i and wx helpers (D_PAD uses it) + + diff --git a/pcbnew/scripting/board.i b/pcbnew/scripting/board.i index 3d20f10d2f..b482c4ce84 100644 --- a/pcbnew/scripting/board.i +++ b/pcbnew/scripting/board.i @@ -44,7 +44,7 @@ def GetTrackWidthList(self): return self.m_TrackWidthList def Save(self,filename): - return pcbnew.SaveBoard(filename,self) + return SaveBoard(filename,self) } } diff --git a/pcbnew/scripting/examples/listPcb.py b/pcbnew/scripting/examples/listPcb.py old mode 100644 new mode 100755 index 879622dba4..2e76f20629 --- a/pcbnew/scripting/examples/listPcb.py +++ b/pcbnew/scripting/examples/listPcb.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python import sys from pcbnew import * From 3f761c890c150625207d6fce10c05fedbe01eb3f Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Thu, 5 Apr 2012 23:41:45 +0200 Subject: [PATCH 16/41] Added wxRect and wxSize wrappers to wx.i --- pcbnew/scripting/TODO.txt | 2 - scripting/wx.i | 112 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/pcbnew/scripting/TODO.txt b/pcbnew/scripting/TODO.txt index 357ba8960d..83df1ffb4b 100644 --- a/pcbnew/scripting/TODO.txt +++ b/pcbnew/scripting/TODO.txt @@ -7,8 +7,6 @@ * add MODULE::Add (see BOARD:Add), to make it more clean -* add wxSize implementation to wx.i and wx helpers (D_PAD uses it) - diff --git a/scripting/wx.i b/scripting/wx.i index 2c5cfae95c..21b13a8b1a 100644 --- a/scripting/wx.i +++ b/scripting/wx.i @@ -36,6 +36,118 @@ void wxSetDefaultPyEncoding(const char* encoding); const char* wxGetDefaultPyEncoding(); + +// wxRect class wrapper /////////////////////////////////////////////////////// + +class wxRect +{ +public: + wxRect() : x(0), y(0), width(0), height(0) { } + wxRect(int xx, int yy, int ww, int hh): x(xx), y(yy), width(ww), height(hh) { } + wxRect(const wxPoint& topLeft, const wxPoint& bottomRight); + wxRect(const wxPoint& pt, const wxSize& size) + : x(pt.x), y(pt.y), width(size.x), height(size.y) { } + wxRect(const wxSize& size): x(0), y(0), width(size.x), height(size.y) { } + + int GetX() const { return x; } + void SetX(int xx) { x = xx; } + + int GetY() const { return y; } + void SetY(int yy) { y = yy; } + + int GetWidth() const { return width; } + void SetWidth(int w) { width = w; } + + int GetHeight() const { return height; } + void SetHeight(int h) { height = h; } + + wxPoint GetPosition() const { return wxPoint(x, y); } + void SetPosition( const wxPoint &p ) { x = p.x; y = p.y; } + + int x, y, width, height; + + %extend + { + PyObject* Get() + { + PyObject* res = PyTuple_New(4); + PyTuple_SET_ITEM(res, 0, PyInt_FromLong(self->x)); + PyTuple_SET_ITEM(res, 1, PyInt_FromLong(self->y)); + PyTuple_SET_ITEM(res, 2, PyInt_FromLong(self->width)); + PyTuple_SET_ITEM(res, 3, PyInt_FromLong(self->height)); + return res; + } + } + + + %pythoncode + { + + def __eq__(self,other): + return self.x==other.x and self.y==other.y and self.width==other.width and self.height==other.height + def __str__(self): return str(self.Get()) + def __repr__(self): return 'wxRect'+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.SetX(val) + elif index == 1: self.SetY(val) + elif index == 2: self.SetWidth(val) + elif index == 3: self.SetHeight(val) + else: raise IndexError + def __nonzero__(self): return self.Get() != (0,0,0,0) + __safe_for_unpickling__ = True + } + +}; + +// wxSize class wrapper /////////////////////////////////////////////////////// + +class wxSize +{ +public: + int x,y; + wxSize(int xx, int yy) : x(xx), y(yy) { } + + %extend + { + PyObject* Get() + { + PyObject* res = PyTuple_New(2); + PyTuple_SET_ITEM(res, 0, PyInt_FromLong(self->x)); + PyTuple_SET_ITEM(res, 1, PyInt_FromLong(self->y)); + return res; + } + } + + ~wxSize(); + + void SetWidth(int w); + void SetHeight(int h); + int GetWidth() const; + int GetHeight() const; + + + %pythoncode + { + def Scale(self,xscale,yscale): + return wxSize(self.x*xscale,self.y*yscale) + def __eq__(self,other): + return self.GetWidth()==other.GetWidth() and self.GetHeight()==other.GetHeight() + def __str__(self): return str(self.Get()) + def __repr__(self): return 'wxSize'+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.SetWidth(val) + elif index == 1: self.SetHeight(val) + else: raise IndexError + def __nonzero__(self): return self.Get() != (0,0) + __safe_for_unpickling__ = True + + } +}; + // wxPoint class wrapper to (xx,yy) tuple ///////////////////////////////////// class wxPoint From 173b869dcbd03d81de394623cdddac8551122ae8 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Fri, 6 Apr 2012 20:13:03 +0200 Subject: [PATCH 17/41] Compilation cleanup, TODO.txt update about library creation --- pcbnew/scripting/TODO.txt | 14 ++++++++++++++ pcbnew/scripting/pcbnew.i | 5 +++++ scripting/kicad.i | 9 ++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/pcbnew/scripting/TODO.txt b/pcbnew/scripting/TODO.txt index 83df1ffb4b..73a348546d 100644 --- a/pcbnew/scripting/TODO.txt +++ b/pcbnew/scripting/TODO.txt @@ -7,6 +7,20 @@ * add MODULE::Add (see BOARD:Add), to make it more clean +* Saving modules to library (in librairi.cpp) + + see: + - void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewModulesOnly ) + - bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName, + MODULE* aModule, + bool aOverwrite, + bool aDisplayDialog ) + + What do we do about this?, ask Dick, these functions should be transplanted + to kicad plugin? + + + diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index 4d858f7581..b62e56cd7b 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -31,6 +31,11 @@ %module pcbnew %include "kicad.i" +// ignore a couple of items that generate warnings from swig built code + +%ignore BOARD_ITEM::ZeroOffset; +%ignore D_PAD::m_PadSketchModePenSize; + // this is what it must be included in the wrapper .cxx code to compile %{ diff --git a/scripting/kicad.i b/scripting/kicad.i index 4719c8b559..01b75278f3 100644 --- a/scripting/kicad.i +++ b/scripting/kicad.i @@ -53,6 +53,11 @@ %ignore InitKiCadAbout; %ignore GetCommandOptions; +%rename(getWxRect) operator wxRect; +%ignore operator <<; +%ignore operator =; + + %{ #include #include @@ -60,8 +65,10 @@ #include #include #include - #include + #include + using namespace std; + #include #include #include From 96c1a50e00b083a571e48ebb93f0282eb162ce97 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Fri, 6 Apr 2012 21:46:45 +0200 Subject: [PATCH 18/41] BOARD::Add now it's wrapped in python and clears the .thisown flag on python to avoid GC from deleting the object later (BOARD will do) --- pcbnew/scripting/TODO.txt | 16 ++++++++++------ pcbnew/scripting/board.i | 10 ++++++++++ pcbnew/scripting/pcbnew.i | 2 ++ scripting/kicad.i | 2 +- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/pcbnew/scripting/TODO.txt b/pcbnew/scripting/TODO.txt index 73a348546d..ff1cfe20e5 100644 --- a/pcbnew/scripting/TODO.txt +++ b/pcbnew/scripting/TODO.txt @@ -1,11 +1,14 @@ +* add MODULE::Add (see BOARD:Add), to make it more clean -* Tell swig(somehow) to forget automatic object deletion after adding - a BOARD_ITEM to BOARD object (it will be automatically deleted by BOARD, +* Tell swig to forget automatic object deletion after adding + a BOARD_ITEM to MODULE object (it will be automatically deleted by MODULE, leading to Segmentation Fault when unloading our python module (double free). -* implement iterator for NETCLASSES (NETCLASS) see class_netclass.h - -* add MODULE::Add (see BOARD:Add), to make it more clean + It seems that we must do object.thisown=0 when added, may be adding a wrapper + Add function. + + +* Implement iterator for NETCLASSES (NETCLASS) see class_netclass.h * Saving modules to library (in librairi.cpp) @@ -22,5 +25,6 @@ to kicad plugin? - + void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewModulesOnly ) + diff --git a/pcbnew/scripting/board.i b/pcbnew/scripting/board.i index b482c4ce84..18449934bd 100644 --- a/pcbnew/scripting/board.i +++ b/pcbnew/scripting/board.i @@ -45,6 +45,15 @@ def Save(self,filename): return SaveBoard(filename,self) + + # + # add function, clears the thisown to avoid python from deleting + # the object in the garbage collector + # + + def Add(self,item): + item.thisown=0 + self.AddNative(item) } } @@ -57,6 +66,7 @@ %rename(Get) operator MODULE*; %rename(Get) operator SEGZONE*; + // we must translate C++ templates to scripting languages %template(BOARD_ITEM_List) DLIST; diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index b62e56cd7b..f45011650e 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -36,6 +36,8 @@ %ignore BOARD_ITEM::ZeroOffset; %ignore D_PAD::m_PadSketchModePenSize; +%rename(AddNative) *::Add; + // this is what it must be included in the wrapper .cxx code to compile %{ diff --git a/scripting/kicad.i b/scripting/kicad.i index 01b75278f3..08d65c20ee 100644 --- a/scripting/kicad.i +++ b/scripting/kicad.i @@ -55,7 +55,7 @@ %rename(getWxRect) operator wxRect; %ignore operator <<; -%ignore operator =; +%ignore operator=; %{ From b54acf607a8d33512872f3acf4e3477f66294b4b Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Fri, 6 Apr 2012 21:48:00 +0200 Subject: [PATCH 19/41] example for pcb creation in scripting --- pcbnew/scripting/examples/createPcb.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100755 pcbnew/scripting/examples/createPcb.py diff --git a/pcbnew/scripting/examples/createPcb.py b/pcbnew/scripting/examples/createPcb.py new file mode 100755 index 0000000000..f92ef21107 --- /dev/null +++ b/pcbnew/scripting/examples/createPcb.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +from pcbnew import * +import pcbnew + +pcb = BOARD() +module = MODULE(pcb) +module.SetReference("M1") + +pad = D_PAD(module) +module.m_Pads.PushBack(pad) +pad.thisown=0 + +pcb.Add(module) + +pcb.Save("/tmp/my2.brd") + + +print map( lambda x: x.GetReference() , list(pcb.GetModules())) + +print "Saved?" From 485ec24f613a40dcefa11bb9570438bbe7d23188 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Fri, 6 Apr 2012 22:38:32 +0200 Subject: [PATCH 20/41] Add method for MODULE in python that takes care of memory handling --- pcbnew/scripting/examples/createPcb.py | 6 +-- pcbnew/scripting/module.i | 60 ++++++++++++++++++++++++++ pcbnew/scripting/pcbnew.i | 1 + 3 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 pcbnew/scripting/module.i diff --git a/pcbnew/scripting/examples/createPcb.py b/pcbnew/scripting/examples/createPcb.py index f92ef21107..2af4a58bbd 100755 --- a/pcbnew/scripting/examples/createPcb.py +++ b/pcbnew/scripting/examples/createPcb.py @@ -1,21 +1,17 @@ #!/usr/bin/env python from pcbnew import * -import pcbnew pcb = BOARD() module = MODULE(pcb) module.SetReference("M1") pad = D_PAD(module) -module.m_Pads.PushBack(pad) -pad.thisown=0 +module.Add(pad) pcb.Add(module) - pcb.Save("/tmp/my2.brd") - print map( lambda x: x.GetReference() , list(pcb.GetModules())) print "Saved?" diff --git a/pcbnew/scripting/module.i b/pcbnew/scripting/module.i new file mode 100644 index 0000000000..942ef7a9aa --- /dev/null +++ b/pcbnew/scripting/module.i @@ -0,0 +1,60 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file module.i + * @brief Specific BOARD extensions and templates + */ + + +%extend MODULE +{ + %pythoncode + { + + def GetPads(self): return self.m_Pads + def GetDrawings(self): return self.m_Drawings + + #def SaveToLibrary(self,filename): + # return SaveModuleToLibrary(filename,self) + + # + # add function, clears the thisown to avoid python from deleting + # the object in the garbage collector + # + + def Add(self,item): + + itemC = item.Cast() + + if type(itemC) is D_PAD: + item.thisown=0 + self.m_Pads.PushBack(itemC) + elif type(itemC) in [ TEXTE_PCB, DIMENSION, TEXTE_MODULE, DRAWSEGMENT]: + item.thisown = 0 + self.m_Drawings.PushBack(item) + } + +} + diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index f45011650e..0f3659bd30 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -104,4 +104,5 @@ %include "board.i" +%include "module.i" %include "units.i" From 7c8bfab5cac40f6ae7b8a51a49a8ef3de08823b5 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Fri, 6 Apr 2012 22:42:39 +0200 Subject: [PATCH 21/41] TODO.txt updated --- pcbnew/scripting/TODO.txt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pcbnew/scripting/TODO.txt b/pcbnew/scripting/TODO.txt index ff1cfe20e5..f92f806674 100644 --- a/pcbnew/scripting/TODO.txt +++ b/pcbnew/scripting/TODO.txt @@ -1,13 +1,3 @@ -* add MODULE::Add (see BOARD:Add), to make it more clean - -* Tell swig to forget automatic object deletion after adding - a BOARD_ITEM to MODULE object (it will be automatically deleted by MODULE, - leading to Segmentation Fault when unloading our python module (double free). - - It seems that we must do object.thisown=0 when added, may be adding a wrapper - Add function. - - * Implement iterator for NETCLASSES (NETCLASS) see class_netclass.h * Saving modules to library (in librairi.cpp) From be15057977559b0b7698469eb4d3dce9cea7232e Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sun, 8 Apr 2012 16:25:49 +0200 Subject: [PATCH 22/41] Fixed wxSize bug, wxPoint(double,double) support, units. Fixed GetBoard wasn't accessible at every build. Extended example for board creation (now adds pads). Also fixed the _pcbnew loading from pcbnew which should only go to the internal _pcbnew and not the _pcbnew.so/dso. Right installation path for _pcbnew.so (in linux only) --- pcbnew/CMakeLists.txt | 32 ++++++++++++++-- pcbnew/scripting/examples/createPcb.py | 41 +++++++++++++++++---- pcbnew/scripting/pcbnew.i | 3 ++ pcbnew/scripting/pcbnew_scripting_helpers.h | 2 +- pcbnew/scripting/units.i | 18 ++++----- scripting/wx.i | 31 ++++++++-------- 6 files changed, 91 insertions(+), 36 deletions(-) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index ac500c2b22..cf36bf6a83 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -1,7 +1,9 @@ add_definitions(-DPCBNEW) if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) - + EXECUTE_PROCESS(COMMAND python -c "import sys;print\"%s.%s\"%sys.version_info[0:2]" OUTPUT_VARIABLE PYTHON_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) + + SET(PYTHON_DEST "lib/python${PYTHON_VERSION}/dist-packages" ) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/scripting) FIND_PACKAGE(SWIG REQUIRED) @@ -275,8 +277,10 @@ if (KICAD_SCRIPTING) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx scripting/pcbnew.i + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../scripting/fixswigimports.py ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) + endif(KICAD_SCRIPTING) @@ -397,12 +401,31 @@ install(TARGETS pcbnew DESTINATION ${KICAD_BIN} COMPONENT binary) -if (KICAD_SCRIPTING_MODULES) +if(KICAD_SCRIPTING) + add_custom_target(FixSwigImportsScripting ALL + ${CMAKE_CURRENT_SOURCE_DIR}/../scripting/fixswigimports.py ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/pcbnew + COMMENT "Fixing swig_import_helper" + ) + + install(FILES ${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py - DESTINATION share/python) + DESTINATION ${PYTHON_DEST}) +endif(KICAD_SCRIPTING) + +if (KICAD_SCRIPTING_MODULES) + add_custom_target(FixSwigImportsModuleScripting ALL + ${CMAKE_CURRENT_SOURCE_DIR}/../scripting/fixswigimports.py ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew + COMMENT "Fixing swig_import_helper" + ) + + + install(FILES ${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py + DESTINATION ${PYTHON_DEST}) install(FILES ${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.so - DESTINATION share/python) + DESTINATION ${PYTHON_DEST}) endif(KICAD_SCRIPTING_MODULES) @@ -418,3 +441,4 @@ add_executable(layer_widget_test WIN32 EXCLUDE_FROM_ALL layer_widget.cpp ) target_link_libraries(layer_widget_test common ${wxWidgets_LIBRARIES}) + diff --git a/pcbnew/scripting/examples/createPcb.py b/pcbnew/scripting/examples/createPcb.py index 2af4a58bbd..5b8bee9882 100755 --- a/pcbnew/scripting/examples/createPcb.py +++ b/pcbnew/scripting/examples/createPcb.py @@ -1,17 +1,44 @@ -#!/usr/bin/env python - +#!/usr/bin/env python2.7 from pcbnew import * +size_0_6mm = wxSize(FromMM(0.6),FromMM(0.6)) + + +# create a blank board pcb = BOARD() + +# create a new module, it's parent is our previously created pcb module = MODULE(pcb) -module.SetReference("M1") +module.SetReference("M1") # give it a reference name +pcb.Add(module) # add it to our pcb +m_pos = wxPoint(FromMM(50),FromMM(50)) +module.SetPosition(m_pos) +print "module position:",m_pos -pad = D_PAD(module) -module.Add(pad) +# create a pad and add it to the module +n = 1 +for y in range (0,10): + for x in range (0,10): + pad = D_PAD(module) + pad.SetDrillSize(size_0_6mm) + pt = wxPoint(FromMM(x*2),FromMM(y*2)) + pad.SetPos0(pt); + pad.SetPosition(pt) + pad.SetPadName(str(n)) + module.Add(pad) + n+=1 + -pcb.Add(module) +# save the PCB to disk pcb.Save("/tmp/my2.brd") +pcb = LoadBoard("/tmp/my2.brd") +#pcb = LoadBoard("/home/ajo/work/xpress-hardware/boards/hexa-xpress/esp.brd"); + + print map( lambda x: x.GetReference() , list(pcb.GetModules())) -print "Saved?" +for m in pcb.GetModules(): + for p in m.GetPads(): + print p.GetPadName(),p.GetPosition(), p.GetOffset() + diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index 0f3659bd30..cbabab029d 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -29,6 +29,9 @@ %module pcbnew + +%feature("autodoc", "1"); + %include "kicad.i" // ignore a couple of items that generate warnings from swig built code diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.h b/pcbnew/scripting/pcbnew_scripting_helpers.h index eca5f62aba..d015d929fa 100644 --- a/pcbnew/scripting/pcbnew_scripting_helpers.h +++ b/pcbnew/scripting/pcbnew_scripting_helpers.h @@ -8,9 +8,9 @@ #ifndef SWIG void ScriptingSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame); -BOARD *GetBoard(); #endif +BOARD *GetBoard(); BOARD* LoadBoard(wxString aFileName); bool SaveBoard(wxString aFileName, BOARD* aBoard); diff --git a/pcbnew/scripting/units.i b/pcbnew/scripting/units.i index 87b784f5d9..adbd3a7ae8 100644 --- a/pcbnew/scripting/units.i +++ b/pcbnew/scripting/units.i @@ -33,26 +33,26 @@ %pythoncode { def ToMM(iu): - if type(iu) is int: + if type(iu) in [int,float]: return iu * 0.00254 - elif type(iu) is wxPoint: + elif type(iu) in [wxPoint,wxSize]: return tuple(map(ToMM,iu)) - def FromMM(mm): - if type(iu) is int: + def FromMM(iu): + if type(iu) in [int,float]: return iu / 0.00254 - elif type(iu) is wxPoint: + elif type(iu) in [wxPoint,wxSize]: return tuple(map(FromMM,iu)) def ToMils(iu): - if type(iu) is int: + if type(iu) in [int,float]: return iu / 10.0 - elif type(iu) is wxPoint: + elif type(iu) in [wxPoint,wxSize]: return tuple(map(ToMils,iu)) def FromMils(mils): - if type(iu) is int: + if type(iu) in [int,float]: return mils*10.0 - elif type(iu) is wxPoint: + elif type(iu) in [wxPoint,wxSize]: return tuple(map(FromMils,iu)) } \ No newline at end of file diff --git a/scripting/wx.i b/scripting/wx.i index 21b13a8b1a..002a01142d 100644 --- a/scripting/wx.i +++ b/scripting/wx.i @@ -108,7 +108,7 @@ class wxSize public: int x,y; wxSize(int xx, int yy) : x(xx), y(yy) { } - + wxSize(double xx, double yy) : x(xx), y(yy) {} %extend { PyObject* Get() @@ -130,20 +130,20 @@ public: %pythoncode { - def Scale(self,xscale,yscale): - return wxSize(self.x*xscale,self.y*yscale) - def __eq__(self,other): - return self.GetWidth()==other.GetWidth() and self.GetHeight()==other.GetHeight() - def __str__(self): return str(self.Get()) - def __repr__(self): return 'wxSize'+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.SetWidth(val) - elif index == 1: self.SetHeight(val) - else: raise IndexError - def __nonzero__(self): return self.Get() != (0,0) - __safe_for_unpickling__ = True + def Scale(self,xscale,yscale): + return wxSize(self.x*xscale,self.y*yscale) + def __eq__(self,other): + return self.GetWidth()==other.GetWidth() and self.GetHeight()==other.GetHeight() + def __str__(self): return str(self.Get()) + def __repr__(self): return 'wxSize'+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.SetWidth(val) + elif index == 1: self.SetHeight(val) + else: raise IndexError + def __nonzero__(self): return self.Get() != (0,0) + __safe_for_unpickling__ = True } }; @@ -155,6 +155,7 @@ class wxPoint public: int x, y; wxPoint(int xx, int yy); + wxPoint(double xx, double yy) : x(xx), y(yy) {} ~wxPoint(); %extend { wxPoint __add__(const wxPoint& pt) { return *self + pt; } From 946ddbaa08b6bb1fa99365fa37621bdbaedb5e85 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sun, 8 Apr 2012 16:59:12 +0200 Subject: [PATCH 23/41] Fix units.i and add some extra wrappers wxSizeMM, wxSizeMils wxRectMM wxRectMils --- pcbnew/scripting/examples/createPcb.py | 3 ++- pcbnew/scripting/units.i | 23 ++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/pcbnew/scripting/examples/createPcb.py b/pcbnew/scripting/examples/createPcb.py index 5b8bee9882..f46b1f5a40 100755 --- a/pcbnew/scripting/examples/createPcb.py +++ b/pcbnew/scripting/examples/createPcb.py @@ -1,7 +1,8 @@ #!/usr/bin/env python2.7 +import pcbnew from pcbnew import * -size_0_6mm = wxSize(FromMM(0.6),FromMM(0.6)) +size_0_6mm = wxSizeMM(0.6,0.6) # create a blank board diff --git a/pcbnew/scripting/units.i b/pcbnew/scripting/units.i index adbd3a7ae8..09cb6fb320 100644 --- a/pcbnew/scripting/units.i +++ b/pcbnew/scripting/units.i @@ -50,9 +50,30 @@ elif type(iu) in [wxPoint,wxSize]: return tuple(map(ToMils,iu)) - def FromMils(mils): + def FromMils(iu): if type(iu) in [int,float]: return mils*10.0 elif type(iu) in [wxPoint,wxSize]: return tuple(map(FromMils,iu)) + + def wxSizeMM(mmx,mmy): return wxSize(FromMM(mmx),FromMM(mmy)) + def wxSizeMils(mmx,mmy): return wxSize(FromMils(mmx),FromMils(mmy)) + + def wxPointMM(mmx,mmy): return wxPoint(FromMM(mmx),FromMM(mmy)) + def wxPointMils(mmx,mmy): return wxPoint(FromMils(mmx),FromMils(mmy)) + + def wxRectMM(x,y,wx,wy): + x = int(FromMM(x)) + y = int(FromMM(y)) + wx = int(FromMM(wx)) + wy = int (FromMM(wy)) + return wxRect(x,y,wx,wy) + + def wxRectMils(x,y,wx,wy): + x = int(FromMils(x)) + y = int(FromMils(y)) + wx = int(FromMils(wx)) + wy = int (FromMils(wy)) + return wxRect(x,y,wx,wy) + } \ No newline at end of file From 1f108b0b6cd7f1610f2b2ed0dbe96c9be44e72e9 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sun, 8 Apr 2012 17:00:15 +0200 Subject: [PATCH 24/41] missing script --- scripting/fixswigimports.py | 55 +++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100755 scripting/fixswigimports.py diff --git a/scripting/fixswigimports.py b/scripting/fixswigimports.py new file mode 100755 index 0000000000..484552970d --- /dev/null +++ b/scripting/fixswigimports.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +# the purpose of this script is rewriting the swig_import_helper +# call so it will not load _xxxxx.so/dso from inside a kicad executable +# because the kicad executable itself sill provide an _xxxxx module +# that's linked inside itself. +# +# for the normal module import it should work the same way with this +# fix in the swig_import_helper +# + +from sys import argv,exit + +if len(argv)<2: + print "usage:" + print " fixswigimports.py file.py" + print "" + print " will fix the swig import code for working inside KiCad" + print " where it happended that the external _pcbnew.so/dll was" + print " loaded too -and the internal _pcbnew module was to be used" + exit(1) + + +filename = argv[1] + +f = open(filename,"rb") +lines = f.readlines() +f.close() + +f = open(filename,"wb") + +doneOk = False + +for l in lines: + if l.startswith("if version_info >= (2,6,0):"): + l = l.replace("version_info >= (2,6,0)","False") + doneOk = True + elif l.startswith("if False:"): # it was already patched? + doneOk = True + f.write(l) + +f.close() + +if doneOk: + print "swig_import_helper fixed for",filename +else: + print "Error: the swig import helper was not fixed, check",filename + print " and fix this script: fixswigimports.py" + exit(2) + + +exit(0) + + + From 0cdc5c59ab6a5a2c958efce9f95e5e1dda74e0d5 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Mon, 9 Apr 2012 08:19:57 +0200 Subject: [PATCH 25/41] detect building status of the swig .py file (on parallel make builds). Fix unit conversion returns (From_xxx) to integer, what's all the wxPoint/wxRect/wx.. expect. Extended createPcb.py example --- pcbnew/scripting/examples/createPcb.py | 18 +++++++++++------- pcbnew/scripting/module.i | 1 + pcbnew/scripting/pcbnew.i | 2 ++ pcbnew/scripting/units.i | 6 +++--- scripting/fixswigimports.py | 4 ++++ 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/pcbnew/scripting/examples/createPcb.py b/pcbnew/scripting/examples/createPcb.py index f46b1f5a40..2c50ee5301 100755 --- a/pcbnew/scripting/examples/createPcb.py +++ b/pcbnew/scripting/examples/createPcb.py @@ -1,30 +1,32 @@ #!/usr/bin/env python2.7 -import pcbnew from pcbnew import * size_0_6mm = wxSizeMM(0.6,0.6) - +size_1_0mm = wxSizeMM(1.0,1.0) # create a blank board pcb = BOARD() +pcb.m_NetClasses.GetDefault().SetClearance(FromMM(0.1)) + # create a new module, it's parent is our previously created pcb module = MODULE(pcb) module.SetReference("M1") # give it a reference name +module.m_Reference.SetPos0(wxPointMM(-10,-10)) pcb.Add(module) # add it to our pcb -m_pos = wxPoint(FromMM(50),FromMM(50)) +m_pos = wxPointMM(50,50) module.SetPosition(m_pos) -print "module position:",m_pos -# create a pad and add it to the module +# create a pad array and add it to the module n = 1 for y in range (0,10): for x in range (0,10): pad = D_PAD(module) pad.SetDrillSize(size_0_6mm) - pt = wxPoint(FromMM(x*2),FromMM(y*2)) + pad.SetSize(size_1_0mm) + pt = wxPointMM(1.27*x,1.27*y) pad.SetPos0(pt); - pad.SetPosition(pt) + #pad.SetPosition(pt) pad.SetPadName(str(n)) module.Add(pad) n+=1 @@ -43,3 +45,5 @@ for m in pcb.GetModules(): for p in m.GetPads(): print p.GetPadName(),p.GetPosition(), p.GetOffset() + +# pcb.GetDesignSettings() \ No newline at end of file diff --git a/pcbnew/scripting/module.i b/pcbnew/scripting/module.i index 942ef7a9aa..cf7cedb757 100644 --- a/pcbnew/scripting/module.i +++ b/pcbnew/scripting/module.i @@ -35,6 +35,7 @@ def GetPads(self): return self.m_Pads def GetDrawings(self): return self.m_Drawings + def GetReferenceObj(self): return self.m_Reference #def SaveToLibrary(self,filename): # return SaveModuleToLibrary(filename,self) diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index cbabab029d..ece9340af0 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -47,6 +47,7 @@ #include #include #include + #include #include #include #include @@ -78,6 +79,7 @@ %include %include +%include %include %include %include diff --git a/pcbnew/scripting/units.i b/pcbnew/scripting/units.i index 09cb6fb320..f496b42e7b 100644 --- a/pcbnew/scripting/units.i +++ b/pcbnew/scripting/units.i @@ -40,19 +40,19 @@ def FromMM(iu): if type(iu) in [int,float]: - return iu / 0.00254 + return int(iu / 0.00254) elif type(iu) in [wxPoint,wxSize]: return tuple(map(FromMM,iu)) def ToMils(iu): if type(iu) in [int,float]: - return iu / 10.0 + return int(iu / 10.0) elif type(iu) in [wxPoint,wxSize]: return tuple(map(ToMils,iu)) def FromMils(iu): if type(iu) in [int,float]: - return mils*10.0 + return int(iu*10.0) elif type(iu) in [wxPoint,wxSize]: return tuple(map(FromMils,iu)) diff --git a/scripting/fixswigimports.py b/scripting/fixswigimports.py index 484552970d..bb338c1e4c 100755 --- a/scripting/fixswigimports.py +++ b/scripting/fixswigimports.py @@ -31,6 +31,10 @@ f = open(filename,"wb") doneOk = False +if (len(lines)<4000): + print "still building" + exit(0) + for l in lines: if l.startswith("if version_info >= (2,6,0):"): l = l.replace("version_info >= (2,6,0)","False") From a201522f6bcbed62d1d305b427b2088848852137 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Mon, 9 Apr 2012 08:53:24 +0200 Subject: [PATCH 26/41] lajos kamocsay compilation patches --- CMakeLists.txt | 8 ++++---- common/CMakeLists.txt | 2 +- include/boost/polygon/polygon.hpp | 2 ++ pcbnew/CMakeLists.txt | 7 ++++--- pcbnew/dialogs/dialog_scripting.cpp | 2 +- scripting/fixswigimports.py | 2 +- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a1eea87d7d..e4f5ebc683 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,13 +86,13 @@ endif(KICAD_STABLE_VERSION ) if(CMAKE_COMPILER_IS_GNUCXX) # Set default flags for Release build. - set(CMAKE_C_FLAGS_RELEASE "-Wall -O2 -DNDEBUG ") - set(CMAKE_CXX_FLAGS_RELEASE "-Wall -O2 -DNDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-Wall -O2 -DNDEBUG -fPIC") + set(CMAKE_CXX_FLAGS_RELEASE "-Wall -O2 -DNDEBUG -fPIC") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s") # Set default flags for Debug build. - set(CMAKE_C_FLAGS_DEBUG "-Wall -g3 -ggdb3 -DDEBUG") - set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g3 -ggdb3 -DDEBUG") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g3 -ggdb3 -DDEBUG -fPIC") + set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g3 -ggdb3 -DDEBUG -fPIC") if( USE_PNG_BITMAPS ) #Add -DUSE_PNG_BITMAPS to windres.exe command line diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 3749bc051d..9acdfecb82 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -150,6 +150,6 @@ if(NOT MSVC) # This one gets made only when testing. # to build it, first enable #define STAND_ALONE at top of dsnlexer.cpp add_executable( dsntest EXCLUDE_FROM_ALL dsnlexer.cpp ) - target_link_libraries( dsntest common ${wxWidgets_LIBRARIES} ) + target_link_libraries( dsntest common ${wxWidgets_LIBRARIES} rt ) endif( NOT MSVC ) diff --git a/include/boost/polygon/polygon.hpp b/include/boost/polygon/polygon.hpp index 10104565da..9dc936844c 100644 --- a/include/boost/polygon/polygon.hpp +++ b/include/boost/polygon/polygon.hpp @@ -24,6 +24,8 @@ #include "transform.hpp" #include "detail/transform_detail.hpp" +#include "detail/polygon_sort_adaptor.hpp" + //interval #include "interval_data.hpp" #include "interval_traits.hpp" diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index cf36bf6a83..0c7d12d64e 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -1,7 +1,7 @@ add_definitions(-DPCBNEW) if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) - EXECUTE_PROCESS(COMMAND python -c "import sys;print\"%s.%s\"%sys.version_info[0:2]" OUTPUT_VARIABLE PYTHON_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) + EXECUTE_PROCESS(COMMAND python2 -c "import sys;print\"%s.%s\"%sys.version_info[0:2]" OUTPUT_VARIABLE PYTHON_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) SET(PYTHON_DEST "lib/python${PYTHON_VERSION}/dist-packages" ) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/scripting) @@ -392,6 +392,7 @@ target_link_libraries(pcbnew ${OPENGL_LIBRARIES} ${GDI_PLUS_LIBRARIES} ${PYTHON_LIBRARIES} + rt ) ### @@ -433,12 +434,12 @@ endif(KICAD_SCRIPTING_MODULES) if(NOT MSVC) # This one gets made only when testing. add_executable(specctra_test EXCLUDE_FROM_ALL specctra_test.cpp specctra.cpp) - target_link_libraries(specctra_test common ${wxWidgets_LIBRARIES}) + target_link_libraries(specctra_test common ${wxWidgets_LIBRARIES} rt) endif(NOT MSVC) # This one gets made only when testing. add_executable(layer_widget_test WIN32 EXCLUDE_FROM_ALL layer_widget.cpp ) -target_link_libraries(layer_widget_test common ${wxWidgets_LIBRARIES}) +target_link_libraries(layer_widget_test common ${wxWidgets_LIBRARIES} rt) diff --git a/pcbnew/dialogs/dialog_scripting.cpp b/pcbnew/dialogs/dialog_scripting.cpp index 6bc9822cab..7b20997a58 100644 --- a/pcbnew/dialogs/dialog_scripting.cpp +++ b/pcbnew/dialogs/dialog_scripting.cpp @@ -3,12 +3,12 @@ */ +#include #include #include #include #include #include -#include DIALOG_SCRIPTING::DIALOG_SCRIPTING( wxWindow* parent ) diff --git a/scripting/fixswigimports.py b/scripting/fixswigimports.py index bb338c1e4c..add960fa81 100755 --- a/scripting/fixswigimports.py +++ b/scripting/fixswigimports.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # the purpose of this script is rewriting the swig_import_helper # call so it will not load _xxxxx.so/dso from inside a kicad executable From 42fad8a754613305df0fbbd267807fe3a4b9131f Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Fri, 20 Apr 2012 23:20:56 +0200 Subject: [PATCH 27/41] Exceptions handled on board Load/Save --- pcbnew/scripting/pcbnew.i | 5 +++++ pcbnew/scripting/pcbnew_scripting_helpers.cpp | 19 ++++++++++++++----- scripting/kicad.i | 3 ++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index ece9340af0..9851e518cd 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -39,6 +39,9 @@ %ignore BOARD_ITEM::ZeroOffset; %ignore D_PAD::m_PadSketchModePenSize; +// rename the Add method of classes to Add native, so we will handle +// the Add method in python + %rename(AddNative) *::Add; // this is what it must be included in the wrapper .cxx code to compile @@ -102,6 +105,8 @@ %include #ifdef BUILD_WITH_PLUGIN + // ignore RELEASER as nested classes are still unsupported by swig + %ignore IO_MGR::RELEASER; %include %include #endif diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/scripting/pcbnew_scripting_helpers.cpp index 89b678e35a..086238c2b8 100644 --- a/pcbnew/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/scripting/pcbnew_scripting_helpers.cpp @@ -27,6 +27,7 @@ * @brief Scripting helper functions for pcbnew functionality */ +#include #include #include @@ -35,6 +36,8 @@ #include #include #include +#include +#include static PCB_EDIT_FRAME *PcbEditFrame=NULL; @@ -56,16 +59,19 @@ BOARD* LoadBoard(wxString& aFileName) BOARD* LoadBoard(wxString& aFileName,IO_MGR::PCB_FILE_T aFormat) { + static char ExceptionError[256]; #ifdef USE_NEW_PCBNEW_LOAD try{ return IO_MGR::Load(aFormat,aFileName); - } catch (IO_ERROR) + } catch (IO_ERROR e) { + sprintf(ExceptionError, "%s\n", TO_UTF8(e.errorText) ); + PyErr_SetString(PyExc_IOError,ExceptionError); return NULL; } #else fprintf(stderr,"Warning, LoadBoard not implemented without USE_NEW_PCBNEW_LOAD\n"); - return NULL; + return NULL; #endif } @@ -77,7 +83,7 @@ bool SaveBoard(wxString& aFilename, BOARD* aBoard) bool SaveBoard(wxString& aFileName, BOARD* aBoard, IO_MGR::PCB_FILE_T aFormat) { - + static char ExceptionError[256]; #ifdef USE_NEW_PCBNEW_LOAD aBoard->m_Status_Pcb &= ~CONNEXION_OK; aBoard->SynchronizeNetsAndNetClasses(); @@ -101,9 +107,12 @@ bool SaveBoard(wxString& aFileName, BOARD* aBoard, IO_MGR::Save( aFormat, aFileName, aBoard, &props ); return true; } - catch (IO_ERROR) + catch (IO_ERROR e) { - return false; + sprintf(ExceptionError, "%s\n", TO_UTF8(e.errorText) ); + PyErr_SetString(PyExc_IOError,ExceptionError); + + return false; } #else diff --git a/scripting/kicad.i b/scripting/kicad.i index 02003c53a8..9784ede559 100644 --- a/scripting/kicad.i +++ b/scripting/kicad.i @@ -82,6 +82,7 @@ /* exception handling */ /* the IO_ERROR exception handler, not working yet... */ +/* %exception { try { @@ -92,7 +93,7 @@ return NULL; } } - +*/ %include From 5157657eba354919a773bfe71a457807aafab5ca Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sun, 22 Apr 2012 13:14:58 +0200 Subject: [PATCH 28/41] merged to last testing, also added automatic file extension detection on save/load --- pcbnew/class_module.h | 2 -- pcbnew/class_netclass.h | 7 ------ pcbnew/scripting/board.i | 11 ++++++---- pcbnew/scripting/examples/createPcb.py | 4 ++-- pcbnew/scripting/pcbnew.i | 14 +++++------- pcbnew/scripting/pcbnew_scripting_helpers.cpp | 22 +++++++++---------- 6 files changed, 25 insertions(+), 35 deletions(-) diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 135b0f8f1b..ae63b75799 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -235,8 +235,6 @@ public: */ bool Read_GPCB_Descr( const wxString& CmpFullFileName ); - int Read_3D_Descr( LINE_READER* aReader ); - /* drawing functions */ void Draw( EDA_DRAW_PANEL* aPanel, diff --git a/pcbnew/class_netclass.h b/pcbnew/class_netclass.h index 73fab5c8a1..be7d51f461 100644 --- a/pcbnew/class_netclass.h +++ b/pcbnew/class_netclass.h @@ -294,13 +294,6 @@ public: */ NETCLASS* Find( const wxString& aName ) const; - /** - * Function Save - * writes the data structures for this object out to a FILE in "*.brd" format. - * @param aFile The FILE to write to. - * @return bool - true if success writing else false. - */ - bool Save( FILE* aFile ) const; }; #endif // CLASS_NETCLASS_H diff --git a/pcbnew/scripting/board.i b/pcbnew/scripting/board.i index 0df6736fed..55426db705 100644 --- a/pcbnew/scripting/board.i +++ b/pcbnew/scripting/board.i @@ -45,9 +45,12 @@ def Save(self,filename,format = None): if format is None: - return SaveBoard(filename,self) - else: - return SaveBoard(filename,self,format) + str_filename = str(filename) + if str_filename.endswith(".brd"): + format = IO_MGR.LEGACY + if str_filename.endswith(".kicad_brd"): + format = IO_MGR.KICAD + return SaveBoard(filename,self,format) # # add function, clears the thisown to avoid python from deleting @@ -90,4 +93,4 @@ def GetShapeStr(self): return self.ShowShape(self.GetShape()) } -} \ No newline at end of file +} diff --git a/pcbnew/scripting/examples/createPcb.py b/pcbnew/scripting/examples/createPcb.py index 1c30d178c8..70cdef9da6 100755 --- a/pcbnew/scripting/examples/createPcb.py +++ b/pcbnew/scripting/examples/createPcb.py @@ -34,9 +34,9 @@ for y in range (0,10): # save the PCB to disk pcb.Save("/tmp/my2.kicad_brd") -pcb.Save("/tmp/my2.brd",IO_MGR.LEGACY) +pcb.Save("/tmp/my2.brd") -pcb = LoadBoard("/tmp/my2.brd",IO_MGR.LEGACY) +pcb = LoadBoard("/tmp/my2.brd") print map( lambda x: x.GetReference() , list(pcb.GetModules())) diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index 9851e518cd..4b0fb5d325 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -73,12 +73,11 @@ BOARD *GetBoard(); /* get current editor board */ %} -#ifdef BUILD_WITH_PLUGIN + %{ #include #include %} -#endif %include %include @@ -104,15 +103,14 @@ %include -#ifdef BUILD_WITH_PLUGIN - // ignore RELEASER as nested classes are still unsupported by swig - %ignore IO_MGR::RELEASER; - %include - %include -#endif +// ignore RELEASER as nested classes are still unsupported by swig +%ignore IO_MGR::RELEASER; +%include +%include %include "board.i" %include "module.i" %include "units.i" + diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/scripting/pcbnew_scripting_helpers.cpp index 086238c2b8..1918a9d57b 100644 --- a/pcbnew/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/scripting/pcbnew_scripting_helpers.cpp @@ -54,13 +54,20 @@ void ScriptingSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame) BOARD* LoadBoard(wxString& aFileName) { - return LoadBoard(aFileName,IO_MGR::KICAD); + + if (aFileName.EndsWith(wxT(".kicad_brd"))) + return LoadBoard(aFileName,IO_MGR::KICAD); + else if (aFileName.EndsWith(wxT(".brd"))) + return LoadBoard(aFileName,IO_MGR::LEGACY); + + // as fall back for any other kind use the legacy format + return LoadBoard(aFileName,IO_MGR::LEGACY); + } BOARD* LoadBoard(wxString& aFileName,IO_MGR::PCB_FILE_T aFormat) { static char ExceptionError[256]; -#ifdef USE_NEW_PCBNEW_LOAD try{ return IO_MGR::Load(aFormat,aFileName); } catch (IO_ERROR e) @@ -69,10 +76,7 @@ BOARD* LoadBoard(wxString& aFileName,IO_MGR::PCB_FILE_T aFormat) PyErr_SetString(PyExc_IOError,ExceptionError); return NULL; } -#else - fprintf(stderr,"Warning, LoadBoard not implemented without USE_NEW_PCBNEW_LOAD\n"); - return NULL; -#endif + } bool SaveBoard(wxString& aFilename, BOARD* aBoard) @@ -84,7 +88,6 @@ bool SaveBoard(wxString& aFileName, BOARD* aBoard, IO_MGR::PCB_FILE_T aFormat) { static char ExceptionError[256]; -#ifdef USE_NEW_PCBNEW_LOAD aBoard->m_Status_Pcb &= ~CONNEXION_OK; aBoard->SynchronizeNetsAndNetClasses(); aBoard->SetCurrentNetClass( aBoard->m_NetClasses.GetDefault()->GetName() ); @@ -115,11 +118,6 @@ bool SaveBoard(wxString& aFileName, BOARD* aBoard, return false; } -#else - fprintf(stderr,"Warning, SaveBoard not implemented without USE_NEW_PCBNEW_LOAD\n"); - return false; -#endif - } From b939f3bc2f6c993462d62477a444a6d83d0c5069 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Tue, 24 Apr 2012 22:28:23 +0200 Subject: [PATCH 29/41] C++ plugin exceptions correctly handled now --- pcbnew/scripting/pcbnew.i | 19 ++++++++++++ pcbnew/scripting/pcbnew_scripting_helpers.cpp | 30 ++++--------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index 4b0fb5d325..8f89a31e31 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -44,6 +44,25 @@ %rename(AddNative) *::Add; +%exception { + try{ + $action + } + catch( IO_ERROR e ) + { + char ExceptionError[256]; + sprintf(ExceptionError, "%s\n", TO_UTF8(e.errorText) ); + PyErr_SetString(PyExc_IOError,ExceptionError); + return NULL; + } + catch( ... ) + { + SWIG_fail; + } +} +%include exception.i + + // this is what it must be included in the wrapper .cxx code to compile %{ diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/scripting/pcbnew_scripting_helpers.cpp index 1918a9d57b..7e483514f6 100644 --- a/pcbnew/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/scripting/pcbnew_scripting_helpers.cpp @@ -67,16 +67,8 @@ BOARD* LoadBoard(wxString& aFileName) BOARD* LoadBoard(wxString& aFileName,IO_MGR::PCB_FILE_T aFormat) { - static char ExceptionError[256]; - try{ - return IO_MGR::Load(aFormat,aFileName); - } catch (IO_ERROR e) - { - sprintf(ExceptionError, "%s\n", TO_UTF8(e.errorText) ); - PyErr_SetString(PyExc_IOError,ExceptionError); - return NULL; - } - + return IO_MGR::Load(aFormat,aFileName); + } bool SaveBoard(wxString& aFilename, BOARD* aBoard) @@ -87,7 +79,6 @@ bool SaveBoard(wxString& aFilename, BOARD* aBoard) bool SaveBoard(wxString& aFileName, BOARD* aBoard, IO_MGR::PCB_FILE_T aFormat) { - static char ExceptionError[256]; aBoard->m_Status_Pcb &= ~CONNEXION_OK; aBoard->SynchronizeNetsAndNetClasses(); aBoard->SetCurrentNetClass( aBoard->m_NetClasses.GetDefault()->GetName() ); @@ -105,19 +96,10 @@ bool SaveBoard(wxString& aFileName, BOARD* aBoard, } - try - { - IO_MGR::Save( aFormat, aFileName, aBoard, &props ); - return true; - } - catch (IO_ERROR e) - { - sprintf(ExceptionError, "%s\n", TO_UTF8(e.errorText) ); - PyErr_SetString(PyExc_IOError,ExceptionError); - - return false; - } - + + IO_MGR::Save( aFormat, aFileName, aBoard, &props ); + return true; + } From f114e800a4443b148b29c4d069c6d693c8749c77 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Tue, 1 May 2012 17:13:36 +0200 Subject: [PATCH 30/41] support for footprint library operations --- pcbnew/scripting/examples/createFPC40.py | 59 +++++++++++++++++++++ pcbnew/scripting/examples/listPcbLibrary.py | 9 ++++ pcbnew/scripting/module.i | 36 +++++++++++++ 3 files changed, 104 insertions(+) create mode 100755 pcbnew/scripting/examples/createFPC40.py create mode 100644 pcbnew/scripting/examples/listPcbLibrary.py diff --git a/pcbnew/scripting/examples/createFPC40.py b/pcbnew/scripting/examples/createFPC40.py new file mode 100755 index 0000000000..8afeec117f --- /dev/null +++ b/pcbnew/scripting/examples/createFPC40.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python2.7 +from pcbnew import * + +size_025_160mm = wxSizeMM(0.25,1.6) +size_150_200mm = wxSizeMM(1.50,2.0) +pads = 40 + +# create a blank board +pcb = BOARD() + +pcb.m_NetClasses.GetDefault().SetClearance(FromMM(0.1)) + +# create a new module, it's parent is our previously created pcb +module = MODULE(pcb) +module.SetReference("FPC"+str(pads)) # give it a reference name +module.m_Reference.SetPos0(wxPointMM(-1,-1)) +pcb.Add(module) # add it to our pcb +m_pos = wxPointMM(50,50) +module.SetPosition(m_pos) + +# create a pad array and add it to the module + + +def smdRectPad(module,size,pos,name): + pad = D_PAD(module) + pad.SetSize(size) + pad.SetShape(PAD_RECT) + pad.SetAttribute(PAD_SMD) + pad.SetLayerMask(PAD_SMD_DEFAULT_LAYERS) + pad.SetPos0(pos) + pad.SetPadName(name) + return pad + +for n in range (0,pads): + pad = smdRectPad(module,size_025_160mm,wxPointMM(0.5*n,0),str(n+1)) + module.Add(pad) + + +pad_s0 = smdRectPad(module,size_150_200mm,wxPointMM(-1.6,1.3),"0") +pad_s1 = smdRectPad(module,size_150_200mm,wxPointMM((pads-1)*0.5+1.6,1.3),"0") +module.Add(pad_s0) +module.Add(pad_s1) + +e = EDGE_MODULE(module) +e.SetStart0(wxPointMM(-1,0)) +e.SetEnd0(wxPointMM(0,0)) +e.SetWidth(FromMM(0.2)) +e.SetLayer(EDGE_LAYER) +e.SetShape(S_SEGMENT) +module.Add(e) + +# save the PCB to disk +module.SetLibRef("FPC"+str(pads)) +try: + FootprintLibCreate("fpc.mod") +except: + pass # we try to create, but may be it exists already +FootprintSave("fpc40.mod",module) + diff --git a/pcbnew/scripting/examples/listPcbLibrary.py b/pcbnew/scripting/examples/listPcbLibrary.py new file mode 100644 index 0000000000..10b82bf981 --- /dev/null +++ b/pcbnew/scripting/examples/listPcbLibrary.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python +from pcbnew import * +lst = FootprintEnumerate("/usr/share/kicad/modules/sockets.mod") +for name in lst: + m = FootprintLoad("/usr/share/kicad/modules/sockets.mod",name) + print name,"->",m.GetLibRef(), m.GetReference() + for p in m.GetPads(): + print "\t",p.GetPadName(),p.GetPosition(), p.GetOffset() + \ No newline at end of file diff --git a/pcbnew/scripting/module.i b/pcbnew/scripting/module.i index 30b3bcd151..6443a630cd 100644 --- a/pcbnew/scripting/module.i +++ b/pcbnew/scripting/module.i @@ -59,3 +59,39 @@ } +%pythoncode +{ + +def GetPluginForPath(lpath): + return IO_MGR.PluginFind(IO_MGR.LEGACY) + +def FootprintEnumerate(lpath): + plug = GetPluginForPath(lpath) + return plug.FootprintEnumerate(lpath) + +def FootprintLoad(lpath,name): + plug = GetPluginForPath(lpath) + return plug.FootprintLoad(lpath,name) + +def FootprintSave(lpath,module): + plug = GetPluginForPath(lpath) + return plug.FootprintSave(lpath,module) + +def FootprintDelete(lpath,name): + plug = GetPluginForPath(lpath) + plug.FootprintDelete(lpath,name) + +def FootprintLibCreate(lpath): + plug = GetPluginForPath(lpath) + plug.FootprintLibCreate(lpath) + +def FootprintLibDelete(lpath): + plug = GetPluginForPath(lpath) + plug.FootprintLibDelete(lpath) + +def FootprintIsWritable(lpath): + plug = GetPluginForPath(lpath) + plug.FootprintLibIsWritable(lpath) + + +} From edee5dc1ced77b0ad558b8312b70ea00807cfcd4 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sat, 5 May 2012 22:18:47 +0200 Subject: [PATCH 31/41] KiCad scripting plugin architecture, footprint wizards first --- pcbnew/CMakeLists.txt | 8 +- pcbnew/scripting/pcbnew.i | 2 + pcbnew/scripting/pcbnew_footprint_wizards.cpp | 179 ++++++++++++++++++ pcbnew/scripting/pcbnew_footprint_wizards.h | 45 +++++ pcbnew/scripting/plugins.i | 11 ++ .../scripting/plugins/fpc_footprint_wizard.py | 83 ++++++++ scripting/kicad.i | 1 + scripting/kicadplugins.i | 147 ++++++++++++++ scripting/python_scripting.cpp | 13 +- 9 files changed, 476 insertions(+), 13 deletions(-) create mode 100644 pcbnew/scripting/pcbnew_footprint_wizards.cpp create mode 100644 pcbnew/scripting/pcbnew_footprint_wizards.h create mode 100644 pcbnew/scripting/plugins.i create mode 100644 pcbnew/scripting/plugins/fpc_footprint_wizard.py create mode 100644 scripting/kicadplugins.i diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index c33a73184c..d20fa8afb0 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -231,14 +231,15 @@ set(PCBNEW_COMMON_SRCS # Scripting sources ## -if (KICAD_SCRIPTING) - - set(PCBNEW_SCRIPTING_PYTHON_HELPERS +set(PCBNEW_SCRIPTING_PYTHON_HELPERS ../scripting/wx_python_helpers.cpp ../scripting/python_scripting.cpp scripting/pcbnew_scripting_helpers.cpp + scripting/pcbnew_footprint_wizards.cpp ) +if (KICAD_SCRIPTING) + set(PCBNEW_SCRIPTING_SRCS pcbnew_wrap.cxx ${PCBNEW_SCRIPTING_PYTHON_HELPERS} @@ -279,6 +280,7 @@ if (KICAD_SCRIPTING) DEPENDS scripting/board.i DEPENDS scripting/board_item.i DEPENDS scripting/module.i + DEPENDS scripting/plugins.i DEPENDS scripting/units.i DEPENDS ../scripting/dlist.i DEPENDS ../scripting/kicad.i diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index f7280cff4c..393df32a8f 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -133,5 +133,7 @@ %include "board.i" %include "module.i" +%include "plugins.i" %include "units.i" + \ No newline at end of file diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.cpp b/pcbnew/scripting/pcbnew_footprint_wizards.cpp new file mode 100644 index 0000000000..8bd60af79e --- /dev/null +++ b/pcbnew/scripting/pcbnew_footprint_wizards.cpp @@ -0,0 +1,179 @@ +/** + * @file pcbnew_footprint_wizards.cpp + * @brief Class PCBNEW_FOOTPRINT_WIZARDS + */ + +#include "pcbnew_footprint_wizards.h" +#include + +FOOTPRINT_WIZARD::FOOTPRINT_WIZARD(PyObject *aWizard) +{ + this->py_wizard = aWizard; + Py_XINCREF(aWizard); +} + +FOOTPRINT_WIZARD::~FOOTPRINT_WIZARD() +{ + Py_XDECREF(this->py_wizard); +} + +PyObject* FOOTPRINT_WIZARD::CallMethod(const char* aMethod, PyObject *aArglist) +{ + PyObject *pFunc; + + /* pFunc is a new reference to the desired method */ + pFunc = PyObject_GetAttrString(this->py_wizard, aMethod); + + if (pFunc && PyCallable_Check(pFunc)) + { + PyObject *result; + + result = PyObject_CallObject(pFunc, aArglist); + + if (PyErr_Occurred()) + { + PyObject *t, *v, *b; + PyErr_Fetch(&t, &v, &b); + printf ("calling %s()\n",aMethod); + printf ("Exception: %s\n",PyString_AsString(PyObject_Str(v))); + printf (" : %s\n",PyString_AsString(PyObject_Str(b))); + } + + + if (result) + { + Py_XDECREF(pFunc); + return result; + } + + } + else + { + printf("method not found, or not callable: %s\n",aMethod); + } + + if (pFunc) Py_XDECREF(pFunc); + + return NULL; +} + +wxString FOOTPRINT_WIZARD::CallRetStrMethod(const char* aMethod, PyObject *aArglist) +{ + wxString ret; + PyObject *result = CallMethod(aMethod,aArglist); + if (result) + { + const char *str_res = PyString_AsString(result); + ret = wxString::FromUTF8(str_res); + Py_DECREF(result); + } + else + { + printf("method not found, or not callable: %s\n",aMethod); + } + + return ret; +} +wxString FOOTPRINT_WIZARD::GetName() +{ + return CallRetStrMethod("GetName"); +} + +wxString FOOTPRINT_WIZARD::GetImage() +{ + return CallRetStrMethod("GetImage"); +} + +wxString FOOTPRINT_WIZARD::GetDescription() +{ + return CallRetStrMethod("GetDescription"); +} + +int FOOTPRINT_WIZARD::GetNumParameterPages() +{ + int ret; + PyObject *result; + + /* Time to call the callback */ + result = CallMethod("GetNumParameterPages",NULL); + + if (result) + { + if (!PyInt_Check(result)) return -1; + ret = PyInt_AsLong(result); + Py_DECREF(result); + } + return ret; +} + +wxString FOOTPRINT_WIZARD::GetParameterPageName(int aPage) +{ + wxString ret; + PyObject *arglist; + PyObject *result; + + /* Time to call the callback */ + arglist = Py_BuildValue("(i)", aPage); + result = CallMethod("GetParameterPageName",arglist); + Py_DECREF(arglist); + + if (result) + { + const char *str_res = PyString_AsString(result); + ret = wxString::FromUTF8(str_res); + Py_DECREF(result); + } + return ret; +} + +wxArrayString FOOTPRINT_WIZARD::GetParameterNames(int aPage) +{ + wxArrayString a; + return a; +} + +wxArrayString FOOTPRINT_WIZARD::GetParameterValues(int aPage) +{ + wxArrayString a; + return a; +} + +wxString FOOTPRINT_WIZARD::SetParameterValues(int aPage,wxArrayString& aValues) +{ + wxString ret; + return ret; +} + +MODULE FOOTPRINT_WIZARD::*GetModule() +{ + return NULL; +} + +std::vector FOOTPRINT_WIZARDS::m_FootprintWizards; + +void FOOTPRINT_WIZARDS::register_wizard(PyObject* wizard) +{ + FOOTPRINT_WIZARD *fw; + + fw = new FOOTPRINT_WIZARD(wizard); + m_FootprintWizards.push_back(fw); + + printf("Registered python footprint wizard '%s'\n", + (const char*)fw->GetName().mb_str()); + + int pages = fw->GetNumParameterPages(); + printf(" %d pages\n",pages); + + for (int n=0; n'%s'\n",n, + (const char*)fw->GetParameterPageName(n).mb_str()); + } + + + +} + + + + diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.h b/pcbnew/scripting/pcbnew_footprint_wizards.h new file mode 100644 index 0000000000..37349cd2d3 --- /dev/null +++ b/pcbnew/scripting/pcbnew_footprint_wizards.h @@ -0,0 +1,45 @@ +/** + * @file pcbnew_footprint_wizards.h + * @brief Class PCBNEW_FOOTPRINT_WIZARDS + */ + +#ifndef PCBNEW_FOOTPRINT_WIZARDS_H +#define PCBNEW_FOOTPRINT_WIZARDS_H +#include +#include +#include + +class FOOTPRINT_WIZARD +{ + + PyObject *py_wizard; + PyObject *CallMethod(const char *aMethod, PyObject *aArglist=NULL); + wxString CallRetStrMethod(const char *aMethod, PyObject *aArglist=NULL); +public: + FOOTPRINT_WIZARD(PyObject *wizard); + ~FOOTPRINT_WIZARD(); + wxString GetName(); + wxString GetImage(); + wxString GetDescription(); + int GetNumParameterPages(); + wxString GetParameterPageName(int aPage); + wxArrayString GetParameterNames(int aPage); + wxArrayString GetParameterValues(int aPage); + wxString SetParameterValues(int aPage,wxArrayString& aValues); + MODULE *GetModule(); + +}; + + +class FOOTPRINT_WIZARDS +{ +private: + static std::vector m_FootprintWizards; + +public: + static void register_wizard(PyObject *wizard); + +}; + +#endif /* PCBNEW_FOOTPRINT_WIZARDS_H */ + diff --git a/pcbnew/scripting/plugins.i b/pcbnew/scripting/plugins.i new file mode 100644 index 0000000000..591ba79884 --- /dev/null +++ b/pcbnew/scripting/plugins.i @@ -0,0 +1,11 @@ + +%{ +#include +%} + +class FOOTPRINT_WIZARDS +{ +public: + static void register_wizard(PyObject *wizard); + +}; diff --git a/pcbnew/scripting/plugins/fpc_footprint_wizard.py b/pcbnew/scripting/plugins/fpc_footprint_wizard.py new file mode 100644 index 0000000000..725da1a026 --- /dev/null +++ b/pcbnew/scripting/plugins/fpc_footprint_wizard.py @@ -0,0 +1,83 @@ +#!/usr/bin/python + +from pcbnew import * + +class FPCFootprintWizard(FootprintWizardPlugin): + def __init__(self): + FootprintWizardPlugin.__init__(self) + self.name = "FPC" + self.description = "FPC Footprint Wizard" + self.parameters = { + "Pads": + {"n":40,"pitch":0.5,"width":0.25,"height":1.6}, + "Shield": + {"shield_to_pad":1.6,"from_top":1.3,"width":1.5,"height":2} + } + + def smdRectPad(self,module,size,pos,name): + pad = D_PAD(module) + pad.SetSize(size) + pad.SetShape(PAD_RECT) + pad.SetAttribute(PAD_SMD) + pad.SetLayerMask(PAD_SMD_DEFAULT_LAYERS) + pad.SetPos0(pos) + pad.SetPadName(name) + return pad + + def BuildFootprint(self): + + pads = self.parameters["Pads"]["n"] + pad_width = self.parameters["Pads"]["width"] + pad_height = self.parameters["Pads"]["height"] + pad_pitch = self.parameters["Pads"]["pitch"] + shl_width = self.parameters["Shield"]["width"] + shl_height = self.parameters["Shield"]["height"] + shl_to_pad = self.parameters["Shield"]["shield_to_pad"] + shl_from_top = self.parameters["Shield"]["from_top"] + + size_pad = wxSizeMM(pad_width,pad_height) + size_shld = wxSizeMM(shl_width,shl_height) + + + # create a new module, it's parent is our previously created pcb + module = MODULE(None) + module.SetReference("FPC"+str(pads)) # give it a reference name + module.m_Reference.SetPos0(wxPointMM(-1,-1)) + + # create a pad array and add it to the module + + for n in range (0,pads): + pad = self.smdRectPad(module,size_pad,wxPointMM(pad_pitch*n,0),str(n+1)) + module.Add(pad) + + + pad_s0 = self.smdRectPad(module, + size_shld, + wxPointMM(-shl_to_pad,shl_from_top), + "0") + pad_s1 = self.smdRectPad(module, + size_shld, + wxPointMM((pads-1)*pad_pitch+shl_to_pad,shl_from_top), + "0") + + module.Add(pad_s0) + module.Add(pad_s1) + + e = EDGE_MODULE(module) + e.SetStart0(wxPointMM(-1,0)) + e.SetEnd0(wxPointMM(0,0)) + e.SetWidth(FromMM(0.2)) + e.SetLayer(EDGE_LAYER) + e.SetShape(S_SEGMENT) + module.Add(e) + + # save the PCB to disk + module.SetLibRef("FPC"+str(pads)) + + self.module = module + +# create our footprint wizard +fpc_wizard = FPCFootprintWizard() + +# register it into pcbnew +fpc_wizard.register() diff --git a/scripting/kicad.i b/scripting/kicad.i index 9784ede559..7029044e1d 100644 --- a/scripting/kicad.i +++ b/scripting/kicad.i @@ -110,3 +110,4 @@ /* std template mappings */ %template(intVector) std::vector; +%include "kicadplugins.i" diff --git a/scripting/kicadplugins.i b/scripting/kicadplugins.i new file mode 100644 index 0000000000..084561c711 --- /dev/null +++ b/scripting/kicadplugins.i @@ -0,0 +1,147 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +%pythoncode +{ + + +# KiCadPlugin base class will register any plugin into the right place +class KiCadPlugin: + def __init__(self): + pass + + def register(self): + if isinstance(self,FilePlugin): + pass # register to file plugins in C++ + if isinstance(self,FootprintWizardPlugin): + FOOTPRINT_WIZARDS.register_wizard(self) + return + + if isinstance(self,ActionPlugin): + pass # register to action plugins in C++ + + return + + + + +# This will be the file io scripting based plugins class +class FilePlugin(KiCadPlugin): + def __init__(self): + KiCadPlugin.__init__(self) + + +# Scriping footprint wizards +class FootprintWizardPlugin(KiCadPlugin): + def __init__(self): + KiCadPlugin.__init__(self) + self.defaults() + + def defaults(self): + self.module = None + self.parameters = {} + self.name = "Undefined Footprint Wizard plugin" + self.description = "" + self.image = "" + + def GetName(self): + return self.name + + def GetImage(self): + return self.image + + def GetDescription(self): + return self.description + + + def GetNumParameterPages(self): + return len(self.parameters) + + def GetParameterPageName(self,page_n): + return self.parameters.keys()[page_n] + + def GetParameterNames(self,page_n): + name = self.GetParameterPageName(page_n) + return self.parameters[name].keys() + + def GetParameterValues(self,page_n): + name = self.GetParameterPageName(page_n) + return self.parameters[name].keys() + + def GetParameterValues(self,page_n): + name = self.GetParameterPageName(page_n) + return self.parameters[name].values() + + + def SetParameterValues(self,page_n,values): + name = self.GetParameterPageName(pagen_n) + keys = self.parameters[name].values() + n=0 + for key in keys: + self.parameters[name][key] = values[n] + n+=1 + + def GetModule(self): + self.BuildFootprint() + return self.module + + def BuildFootprint(self): + return + + def Show(self): + print "Footprint Wizard Name: ",self.GetName() + print "Footprint Wizard Description: ",self.GetDescription() + n_pages = self.GetNumParameterPages() + print " setup pages: ",n_pages + for page in range(0,n_pages): + name = self.GetParameterPageName(page) + values = self.GetParameterValues(page) + names = self.GetParameterNames(page) + print "page %d) %s"%(page,name) + for n in range (0,len(values)): + print "\t%s\t:\t%s"%(names[n],values[n]) + +class ActionPlugin(KiCadPlugin): + def __init__(self): + KiCadPlugin.__init__(self) + + +def LoadPlugins(): + import os + import sys + + plugins_dir = os.environ['HOME']+'/.kicad_plugins/' + + sys.path.append(plugins_dir) + + for module in os.listdir(plugins_dir): + if os.path.isdir(plugins_dir+module): + __import__(module, locals(), globals()) + + if module == '__init__.py' or module[-3:] != '.py': + continue + __import__(module[:-3], locals(), globals()) + + +} diff --git a/scripting/python_scripting.cpp b/scripting/python_scripting.cpp index d8f07e67b3..8abd092e24 100644 --- a/scripting/python_scripting.cpp +++ b/scripting/python_scripting.cpp @@ -90,15 +90,6 @@ void pcbnewInitPythonScripting() swigAddModules(); swigSwitchPythonBuiltin(); -#if 0 - /* print the list of modules available from python */ - while(PyImport_Inittab[i].name) - { - printf("name[%d]=>%s\n",i,PyImport_Inittab[i].name); - i++; - } -#endif - Py_Initialize(); /* setup the scripting path, we may need to add the installation path @@ -106,7 +97,9 @@ void pcbnewInitPythonScripting() PyRun_SimpleString("import sys\n" "sys.path.append(\".\")\n" - "import pcbnew\n"); + "import pcbnew\n" + "pcbnew.LoadPlugins()" + ); } From 23bec4b80b9fe7d5ba508f515de52fe05a331a52 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Wed, 9 May 2012 19:37:25 +0200 Subject: [PATCH 32/41] * Footprint wizard UI: Added to module editor. * Footprint wizard C++ generic classes * Footprint wizard C++ to python wrappers * Automatic plugin loader from ~/.kicad/plugins * Python plugin architecture: Footprint wizards --- bitmaps_png/CMakeLists.txt | 1 + bitmaps_png/cpp_26/module_wizard.cpp | 97 +++ bitmaps_png/sources/module_wizard.svg | 401 ++++++++++ include/bitmaps.h | 1 + pcbnew/CMakeLists.txt | 5 +- pcbnew/class_footprint_wizard.cpp | 41 ++ pcbnew/class_footprint_wizard.h | 44 ++ pcbnew/footprint_wizard.cpp | 160 ++++ pcbnew/footprint_wizard_frame.cpp | 685 ++++++++++++++++++ pcbnew/footprint_wizard_frame.h | 167 +++++ pcbnew/modedit.cpp | 32 + pcbnew/moduleframe.cpp | 1 + pcbnew/pcbnew_id.h | 18 +- pcbnew/scripting/pcbnew_footprint_wizards.cpp | 56 +- pcbnew/scripting/pcbnew_footprint_wizards.h | 17 +- pcbnew/scripting/plugins.i | 2 +- pcbnew/tool_modedit.cpp | 6 + scripting/kicadplugins.i | 2 +- 18 files changed, 1696 insertions(+), 40 deletions(-) create mode 100644 bitmaps_png/cpp_26/module_wizard.cpp create mode 100644 bitmaps_png/sources/module_wizard.svg create mode 100644 pcbnew/class_footprint_wizard.cpp create mode 100644 pcbnew/class_footprint_wizard.h create mode 100644 pcbnew/footprint_wizard.cpp create mode 100644 pcbnew/footprint_wizard_frame.cpp create mode 100644 pcbnew/footprint_wizard_frame.h diff --git a/bitmaps_png/CMakeLists.txt b/bitmaps_png/CMakeLists.txt index 6f58b942d4..60f92128a4 100644 --- a/bitmaps_png/CMakeLists.txt +++ b/bitmaps_png/CMakeLists.txt @@ -327,6 +327,7 @@ set( BMAPS_MID modratsnest module_check module_edit + module_wizard module_filtered_list module_full_list module_options diff --git a/bitmaps_png/cpp_26/module_wizard.cpp b/bitmaps_png/cpp_26/module_wizard.cpp new file mode 100644 index 0000000000..316c6931fb --- /dev/null +++ b/bitmaps_png/cpp_26/module_wizard.cpp @@ -0,0 +1,97 @@ + +/* Do not modify this file, it was automatically generated by the + * PNG2cpp CMake script, using a *.png file as input. + */ + +#include + +static const unsigned char png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c, + 0xce, 0x00, 0x00, 0x05, 0x07, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xad, 0x96, 0x0d, 0x50, 0x14, + 0x65, 0x18, 0xc7, 0x6f, 0x77, 0x39, 0xe4, 0x38, 0x20, 0x2f, 0x73, 0xc0, 0x92, 0x13, 0x2c, 0xd4, + 0x81, 0xf1, 0x03, 0xc5, 0xa0, 0x3b, 0x0e, 0x41, 0x4f, 0x85, 0x88, 0x81, 0x40, 0x0e, 0x90, 0x4f, + 0x0f, 0x30, 0x08, 0xc3, 0x03, 0x3d, 0xc4, 0x14, 0xc2, 0x86, 0x98, 0x38, 0x04, 0x86, 0x14, 0x44, + 0xc1, 0x0f, 0x3a, 0x3f, 0xf8, 0x70, 0x40, 0x4b, 0x1a, 0x14, 0x6c, 0x4c, 0x4c, 0xb4, 0xc2, 0xf2, + 0x2b, 0x6d, 0x9c, 0xd1, 0x12, 0x6a, 0xc8, 0xd0, 0x50, 0x01, 0x01, 0xcf, 0xfb, 0xb7, 0xef, 0xe5, + 0x22, 0x2a, 0x37, 0x9e, 0xe5, 0xcd, 0xfc, 0x66, 0x6e, 0xfe, 0xef, 0x3e, 0xcf, 0xef, 0xf6, 0xdd, + 0x67, 0x77, 0x8f, 0x07, 0x80, 0x37, 0x12, 0x99, 0x98, 0x3e, 0xb7, 0xda, 0x9d, 0xfa, 0x85, 0x43, + 0x62, 0xcf, 0xec, 0x23, 0xb9, 0xdb, 0x04, 0x3a, 0xed, 0x03, 0x37, 0xea, 0x0a, 0x97, 0x07, 0x4f, + 0xa5, 0xaf, 0xf2, 0x78, 0xbc, 0x29, 0x64, 0xcd, 0x4b, 0xcc, 0x7c, 0x37, 0xb2, 0x46, 0x66, 0xcf, + 0x34, 0x3c, 0xd9, 0x97, 0xf7, 0x64, 0x40, 0x0e, 0x44, 0x26, 0xfb, 0xf5, 0x21, 0xfe, 0x4e, 0xcc, + 0x21, 0x92, 0x4b, 0xec, 0xe9, 0xdc, 0xbf, 0xd3, 0x1e, 0xe5, 0x8d, 0x0a, 0xaa, 0x97, 0xcf, 0xe7, + 0xcf, 0x22, 0x6b, 0xa9, 0x6e, 0xd4, 0xd9, 0x91, 0x35, 0x4b, 0x5d, 0xa8, 0x26, 0x93, 0x44, 0x1d, + 0x29, 0x3c, 0xec, 0x0f, 0x13, 0xe2, 0xde, 0xea, 0xa7, 0x45, 0x2d, 0xd1, 0x02, 0xb4, 0x2b, 0xcd, + 0xb0, 0x69, 0x31, 0xd5, 0x3f, 0x52, 0xd4, 0xbd, 0x92, 0x87, 0x5a, 0x85, 0x10, 0x3d, 0x69, 0x46, + 0x44, 0xec, 0xe7, 0xd5, 0x31, 0x63, 0xc6, 0x6c, 0xb3, 0xb0, 0xb0, 0xd8, 0x41, 0x48, 0x9e, 0x43, + 0xdf, 0x7e, 0xd7, 0x67, 0x32, 0x12, 0xe3, 0xbc, 0x90, 0xe1, 0x3b, 0x09, 0xec, 0xb6, 0x74, 0x90, + 0x7c, 0xea, 0x78, 0xfe, 0x4f, 0x35, 0x61, 0xd6, 0x28, 0xda, 0xa0, 0x86, 0xaf, 0x7c, 0x02, 0x3c, + 0x67, 0xd1, 0x60, 0xeb, 0x0e, 0x90, 0x35, 0xe5, 0x4c, 0xfa, 0x56, 0x56, 0xe8, 0x1c, 0x9c, 0x6b, + 0x6d, 0xc2, 0xfa, 0xe0, 0x19, 0xe4, 0xc7, 0x75, 0x72, 0xfd, 0x08, 0x66, 0x66, 0x66, 0x0b, 0x88, + 0x28, 0xc9, 0xd6, 0xd6, 0x76, 0x28, 0x21, 0x21, 0x01, 0x84, 0x74, 0xaf, 0xb1, 0x88, 0x90, 0x4d, + 0x44, 0x6d, 0x8d, 0x00, 0xb9, 0x59, 0x02, 0x78, 0x7b, 0x08, 0x11, 0x1c, 0x1c, 0x08, 0x3f, 0xe9, + 0x0c, 0x24, 0x78, 0x33, 0xc8, 0x5a, 0x67, 0x8d, 0xc1, 0x41, 0x2b, 0xc4, 0xf8, 0x32, 0x6c, 0x1e, + 0x6c, 0xa8, 0x59, 0x21, 0x1b, 0x87, 0x82, 0x50, 0x27, 0x14, 0xaf, 0x5d, 0x8e, 0xe2, 0xd0, 0xc9, + 0x88, 0x96, 0xda, 0x83, 0xeb, 0x27, 0x95, 0x4a, 0x21, 0x14, 0x0a, 0x8f, 0x18, 0x44, 0xae, 0xae, + 0xae, 0xbd, 0xa7, 0x4e, 0x9d, 0x02, 0x21, 0x27, 0x60, 0x12, 0x6e, 0xaa, 0x78, 0xc8, 0x59, 0xc5, + 0x67, 0xcf, 0xd8, 0x0a, 0x03, 0x03, 0x56, 0x28, 0x2b, 0x1b, 0x8f, 0x65, 0xb1, 0x22, 0x74, 0x76, + 0x0a, 0x0d, 0x19, 0x21, 0xda, 0x87, 0x0f, 0xad, 0x56, 0x6b, 0xa8, 0xc9, 0x0e, 0x74, 0x32, 0x5c, + 0x9b, 0x9e, 0x87, 0xd7, 0x70, 0x6d, 0x98, 0x04, 0x5c, 0xbf, 0x8c, 0x8c, 0x0c, 0xe3, 0x22, 0x72, + 0xb0, 0x4a, 0xc1, 0x0c, 0x37, 0x7d, 0x92, 0xdb, 0xb7, 0x85, 0x88, 0xf7, 0x7a, 0x5a, 0xc4, 0x61, + 0x92, 0x28, 0x25, 0x4c, 0x8e, 0xcc, 0x08, 0x19, 0xde, 0xf6, 0x79, 0x05, 0x7a, 0xfd, 0xe8, 0xa2, + 0x0b, 0x17, 0x2c, 0xb1, 0xc8, 0xc3, 0x01, 0x8d, 0x8d, 0x8d, 0x86, 0x1a, 0x55, 0x94, 0xbf, 0xa1, + 0x86, 0x23, 0x3b, 0x35, 0x76, 0x74, 0x91, 0xa3, 0xa3, 0xe3, 0x40, 0x5d, 0x5d, 0xdd, 0xf0, 0x62, + 0x6b, 0x6b, 0x2b, 0x82, 0x82, 0xa6, 0xe3, 0xde, 0xbd, 0xd1, 0x45, 0x43, 0x43, 0x56, 0x48, 0x4a, + 0x72, 0x40, 0x45, 0x45, 0xe9, 0x70, 0x8d, 0x31, 0x1e, 0x13, 0xc9, 0x64, 0x32, 0x3d, 0x3b, 0x41, + 0xc8, 0xcb, 0xcb, 0xc3, 0xc9, 0x93, 0x27, 0x11, 0x1e, 0x2e, 0xc1, 0xc5, 0x8b, 0x56, 0x46, 0xb7, + 0x8e, 0x23, 0x27, 0xc7, 0x1e, 0x1a, 0x4d, 0xb6, 0xe9, 0xa2, 0xda, 0xda, 0xda, 0x07, 0x6a, 0xb5, + 0x1a, 0xce, 0xce, 0xce, 0x88, 0x8b, 0x93, 0xa3, 0xad, 0xcd, 0xe6, 0x99, 0x12, 0x8e, 0x8a, 0x0a, + 0x3b, 0x64, 0x66, 0x26, 0x9a, 0x2e, 0x22, 0x81, 0x8b, 0xcb, 0xcb, 0xc8, 0xcf, 0x17, 0xa2, 0xab, + 0x4b, 0x08, 0x9d, 0x6e, 0xf4, 0xc6, 0x24, 0x6f, 0x6f, 0xb7, 0xc4, 0xe6, 0x22, 0x4b, 0xa4, 0xa4, + 0x38, 0x22, 0x3e, 0xde, 0x15, 0xc9, 0xc9, 0x81, 0xa6, 0x89, 0xd8, 0x59, 0xd7, 0xb3, 0x77, 0x39, + 0x54, 0x2a, 0x15, 0x72, 0x73, 0xd7, 0x62, 0xd5, 0xaa, 0x68, 0x28, 0x95, 0x0b, 0x11, 0x13, 0x23, + 0x61, 0xef, 0x05, 0x87, 0xc7, 0x44, 0xeb, 0xd3, 0x2d, 0xa1, 0xfd, 0x70, 0x36, 0x4e, 0x6b, 0x16, + 0xa0, 0x7d, 0xa3, 0xe2, 0xf9, 0xae, 0x11, 0x19, 0x06, 0xf6, 0xac, 0x46, 0x3d, 0xb0, 0xa4, 0x24, + 0x1f, 0xd5, 0xd5, 0xe3, 0x0c, 0x92, 0xbe, 0x3e, 0x2b, 0xa4, 0x2a, 0xec, 0xd0, 0xa7, 0x9d, 0x0b, + 0x5d, 0x73, 0x14, 0x7e, 0xdd, 0x28, 0xc1, 0xf7, 0xbb, 0x73, 0x4d, 0x17, 0x8d, 0x1c, 0x6f, 0x32, + 0xb2, 0x0d, 0x0d, 0x0d, 0xc3, 0xb4, 0xb4, 0xb4, 0x20, 0x32, 0x72, 0x8e, 0xe1, 0xc6, 0x2d, 0xfd, + 0xcc, 0x06, 0x0d, 0x49, 0xd3, 0x70, 0xb3, 0x72, 0x1e, 0x06, 0x6b, 0x24, 0xd0, 0x7d, 0x9d, 0x80, + 0x4b, 0xeb, 0x9c, 0xd1, 0x5c, 0xbd, 0xed, 0xb1, 0x9a, 0xe6, 0xe6, 0xe6, 0x67, 0x8b, 0x96, 0x4a, + 0xc4, 0xd0, 0x2a, 0x44, 0xc3, 0x2c, 0x0f, 0xf4, 0xc4, 0x9e, 0x3d, 0x5a, 0x7c, 0x94, 0x6d, 0x83, + 0x25, 0x72, 0x73, 0x1c, 0x5b, 0xca, 0xc7, 0x35, 0x8d, 0x14, 0xb7, 0x2a, 0xde, 0x82, 0xee, 0xc0, + 0x7c, 0x0c, 0x1e, 0x8e, 0xc7, 0xb7, 0x89, 0x22, 0xec, 0x51, 0x8c, 0x7d, 0x54, 0x13, 0xe0, 0x6e, + 0xfa, 0x93, 0x81, 0x43, 0x15, 0xea, 0x69, 0xc8, 0x17, 0x7a, 0x3b, 0x60, 0x57, 0x08, 0x05, 0xfd, + 0x1a, 0x1e, 0x2e, 0xc7, 0x9b, 0xe1, 0xf7, 0xd2, 0xc5, 0xe8, 0xa9, 0x64, 0xb7, 0xf0, 0x90, 0x1f, + 0xee, 0xd4, 0x87, 0xe3, 0x6a, 0xb2, 0xf9, 0xf3, 0x3d, 0x19, 0x88, 0xe8, 0x74, 0xbc, 0x00, 0xf9, + 0x41, 0x62, 0x74, 0xa5, 0xd2, 0xc3, 0xa2, 0xec, 0x95, 0xcb, 0x70, 0x83, 0x7d, 0x15, 0x94, 0x87, + 0x4e, 0xc0, 0xfe, 0x08, 0x11, 0xce, 0x24, 0x5a, 0xe3, 0xcf, 0x4a, 0x7f, 0xdc, 0xdd, 0xe5, 0x06, + 0x5d, 0x53, 0x08, 0x6e, 0x6c, 0x9d, 0x8f, 0x83, 0x91, 0x22, 0x5c, 0x79, 0x9f, 0x6f, 0x54, 0x14, + 0xce, 0x30, 0xcc, 0x7d, 0x91, 0x48, 0xd4, 0x4b, 0x58, 0x3e, 0xdb, 0xec, 0xc1, 0x9a, 0x28, 0x39, + 0xfa, 0x3a, 0x2f, 0xe1, 0xe3, 0xe0, 0x69, 0x90, 0x8a, 0xcd, 0x75, 0x24, 0x9f, 0x62, 0x2b, 0x18, + 0xda, 0x15, 0xf2, 0x12, 0x7e, 0x68, 0x39, 0x88, 0xaa, 0xe2, 0x1c, 0xec, 0x7e, 0x87, 0xd2, 0xb7, + 0x25, 0xbf, 0xa6, 0xff, 0x6b, 0x87, 0x1f, 0xfa, 0x77, 0xbf, 0x89, 0x07, 0x47, 0x63, 0xf1, 0x9b, + 0xc6, 0x1d, 0x65, 0xe1, 0x4e, 0x58, 0xf4, 0xc6, 0xbf, 0x35, 0x04, 0x81, 0x40, 0x30, 0xc8, 0x52, + 0xcd, 0xbd, 0x94, 0xdc, 0x58, 0x3c, 0x08, 0xaa, 0xb9, 0xd4, 0xf5, 0xa2, 0xd0, 0xd7, 0xb1, 0x41, + 0xe9, 0x8b, 0xa6, 0xb8, 0x71, 0x58, 0x38, 0x99, 0x39, 0x41, 0xf2, 0x59, 0x76, 0xf4, 0xce, 0xf3, + 0x09, 0x14, 0x32, 0x14, 0x12, 0x64, 0x04, 0xcd, 0x44, 0x7d, 0x08, 0xd5, 0x5f, 0x2e, 0xa7, 0xea, + 0x2f, 0x67, 0x4d, 0xef, 0xbf, 0x59, 0xe9, 0x8d, 0xc1, 0x3a, 0x29, 0xee, 0x1f, 0x4d, 0xc4, 0x79, + 0x95, 0x1d, 0x92, 0x5c, 0xa9, 0x1f, 0xb9, 0x7e, 0x0f, 0xb1, 0xfe, 0xdf, 0xaf, 0xf2, 0x33, 0x51, + 0xbc, 0xa6, 0x6b, 0x1b, 0xbd, 0xf4, 0xb7, 0x2a, 0xd9, 0xe1, 0x38, 0x28, 0xc7, 0x40, 0xd3, 0x32, + 0xb4, 0x29, 0x2d, 0x7b, 0xd9, 0xdc, 0xf2, 0x85, 0xfe, 0x67, 0x60, 0x1b, 0x0a, 0x4f, 0x44, 0x9a, + 0x0f, 0xfc, 0xb1, 0xc5, 0x0f, 0x3d, 0xdb, 0xd9, 0xeb, 0xd5, 0xe8, 0x8f, 0x9e, 0xda, 0x25, 0xfa, + 0x2f, 0xd5, 0x9e, 0x67, 0x3f, 0xd5, 0x7c, 0x62, 0x61, 0x54, 0xe4, 0x3e, 0x91, 0x2e, 0xf0, 0x99, + 0x44, 0xef, 0xe0, 0xf0, 0x10, 0x33, 0xb1, 0x24, 0x9f, 0x6d, 0xcb, 0xf7, 0x18, 0x99, 0x7b, 0xda, + 0xd3, 0x95, 0xec, 0x96, 0x88, 0xc8, 0x5a, 0x8c, 0x0b, 0xbd, 0xf9, 0xb4, 0xd2, 0xa6, 0xff, 0xc6, + 0xf6, 0x00, 0xf4, 0x56, 0xb1, 0x93, 0x78, 0x58, 0x81, 0x9a, 0xb2, 0x2c, 0x5d, 0x45, 0x41, 0xe6, + 0x15, 0xa3, 0xa2, 0xff, 0x0a, 0x7b, 0x66, 0x41, 0x3f, 0xa7, 0x8b, 0xbb, 0xbb, 0xd9, 0xe1, 0xe8, + 0xfe, 0x7c, 0x1e, 0xf6, 0x56, 0x6d, 0xc2, 0x91, 0xc6, 0x03, 0xfa, 0x7a, 0xf5, 0x7b, 0xdf, 0xbc, + 0x50, 0x11, 0xe1, 0xab, 0x15, 0xd3, 0xf7, 0x55, 0x69, 0xd2, 0x74, 0x25, 0x9a, 0xf5, 0x38, 0x7e, + 0xfc, 0x18, 0x3a, 0x3a, 0xae, 0xe3, 0x8b, 0xf4, 0x54, 0x74, 0x4a, 0x26, 0xfa, 0xbe, 0x50, 0xd1, + 0xce, 0x75, 0x11, 0x4c, 0x79, 0x5e, 0xfa, 0x9d, 0x2d, 0x5b, 0x4a, 0x51, 0x58, 0x58, 0x88, 0xbd, + 0x5b, 0x37, 0xe3, 0xb8, 0x7a, 0x35, 0xba, 0x3c, 0x66, 0xde, 0xfd, 0x07, 0x3e, 0x0a, 0x38, 0xab, + 0xbb, 0xc7, 0x1e, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +const BITMAP_OPAQUE module_wizard_xpm[1] = {{ png, sizeof( png ), "module_wizard_xpm" }}; + +//EOF diff --git a/bitmaps_png/sources/module_wizard.svg b/bitmaps_png/sources/module_wizard.svg new file mode 100644 index 0000000000..a8fd1839e5 --- /dev/null +++ b/bitmaps_png/sources/module_wizard.svg @@ -0,0 +1,401 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/bitmaps.h b/include/bitmaps.h index 8a5d4242cb..97e3474827 100644 --- a/include/bitmaps.h +++ b/include/bitmaps.h @@ -278,6 +278,7 @@ EXTERN_BITMAP( mode_track_xpm ) EXTERN_BITMAP( mod_ratsnest_xpm ) EXTERN_BITMAP( module_check_xpm ) EXTERN_BITMAP( module_edit_xpm ) +EXTERN_BITMAP( module_wizard_xpm ) EXTERN_BITMAP( module_filtered_list_xpm ) EXTERN_BITMAP( module_pin_filtered_list_xpm ) EXTERN_BITMAP( module_full_list_xpm ) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index d20fa8afb0..bcf99737a6 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -97,8 +97,11 @@ set(PCBNEW_DIALOGS dialogs/dialog_set_grid_base.cpp dialogs/dialog_scripting_base.cpp dialogs/dialog_scripting.cpp + footprint_wizard.cpp + footprint_wizard_frame.cpp ) +# some of the files here may be going to the dialog srcs in fact.... set(PCBNEW_CLASS_SRCS tool_modview.cpp modview.cpp @@ -114,7 +117,6 @@ set(PCBNEW_CLASS_SRCS block.cpp block_module_editor.cpp build_BOM_from_board.cpp -# class_footprint_library.cpp class_pcb_layer_widget.cpp clean.cpp connect.cpp @@ -215,6 +217,7 @@ set(PCBNEW_CLASS_SRCS zones_polygons_insulated_copper_islands.cpp zones_polygons_test_connections.cpp zones_test_and_combine_areas.cpp + class_footprint_wizard.cpp ) set(PCBNEW_SRCS ${PCBNEW_CLASS_SRCS} ${PCBNEW_DIALOGS}) diff --git a/pcbnew/class_footprint_wizard.cpp b/pcbnew/class_footprint_wizard.cpp new file mode 100644 index 0000000000..6e85ac4b55 --- /dev/null +++ b/pcbnew/class_footprint_wizard.cpp @@ -0,0 +1,41 @@ +/** + * @file class_footprint_wizard.cpp + * @brief Class FOOTPRINT_WIZARD and FOOTPRINT_WIZARDS + */ + +#include "class_footprint_wizard.h" +#include + +void FOOTPRINT_WIZARD::register_wizard() +{ + FOOTPRINT_WIZARDS::register_wizard(this); +} + +std::vector FOOTPRINT_WIZARDS::m_FootprintWizards; + +void FOOTPRINT_WIZARDS::register_wizard(FOOTPRINT_WIZARD *aWizard) +{ + + wxString name = aWizard->GetName(); + m_FootprintWizards.push_back(aWizard); + + printf("Registered footprint wizard '%s'\n",(const char*)name.mb_str() ); + +#if 0 + /* just to test if it works correctly */ + int pages = fw->GetNumParameterPages(); + printf(" %d pages\n",pages); + + for (int n=0; n'%s'\n",n, + (const char*)fw->GetParameterPageName(n).mb_str()); + } +#endif + + +} + + + + diff --git a/pcbnew/class_footprint_wizard.h b/pcbnew/class_footprint_wizard.h new file mode 100644 index 0000000000..36442a6218 --- /dev/null +++ b/pcbnew/class_footprint_wizard.h @@ -0,0 +1,44 @@ +/** + * @file pcbnew_footprint_wizards.h + * @brief Class PCBNEW_FOOTPRINT_WIZARDS + */ + +#ifndef CLASS_FOOTPRINT_WIZARD_H +#define CLASS_FOOTPRINT_WIZARD_H +#include +#include + +/* This is the parent class from where any footprint wiizard class must + * derive */ +class FOOTPRINT_WIZARD +{ + +public: + FOOTPRINT_WIZARD() {} + ~FOOTPRINT_WIZARD() {} + virtual wxString GetName()=0; + virtual wxString GetImage()=0; + virtual wxString GetDescription()=0; + virtual int GetNumParameterPages()=0; + virtual wxString GetParameterPageName(int aPage)=0; + virtual wxArrayString GetParameterNames(int aPage)=0; + virtual wxArrayString GetParameterValues(int aPage)=0; + virtual wxString SetParameterValues(int aPage,wxArrayString& aValues)=0; + virtual MODULE *GetModule()=0; + void register_wizard(); + +}; + + +class FOOTPRINT_WIZARDS +{ +private: + static std::vector m_FootprintWizards; + +public: + static void register_wizard(FOOTPRINT_WIZARD *wizard); + +}; + +#endif /* PCBNEW_FOOTPRINT_WIZARDS_H */ + diff --git a/pcbnew/footprint_wizard.cpp b/pcbnew/footprint_wizard.cpp new file mode 100644 index 0000000000..a3abdac2fc --- /dev/null +++ b/pcbnew/footprint_wizard.cpp @@ -0,0 +1,160 @@ +/** + * @file footprint wizard.cpp + */ + +#include +#include +#include +#include +#include +#include <3d_viewer.h> +#include + +#include +#include + +#include +#include +#include "footprint_wizard_frame.h" +#include + + +#define NEXT_PART 1 +#define NEW_PART 0 +#define PREVIOUS_PART -1 + + +void FOOTPRINT_WIZARD_FRAME::Process_Special_Functions( wxCommandEvent& event ) +{ + wxString msg; + + switch( event.GetId() ) + { + case ID_FOOTPRINT_WIZARD_NEXT: + //SelectAndViewFootprint( NEXT_PART ); + break; + + case ID_FOOTPRINT_WIZARD_PREVIOUS: + //SelectAndViewFootprint( PREVIOUS_PART ); + break; + + default: + msg << wxT( "FOOTPRINT_WIZARD_FRAME::Process_Special_Functions error: id = " ) + << event.GetId(); + wxMessageBox( msg ); + break; + } +} + + +void FOOTPRINT_WIZARD_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) +{ +} + + +bool FOOTPRINT_WIZARD_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ) +{ + return true; +} + + +/* Displays the name of the current opened library in the caption */ +void FOOTPRINT_WIZARD_FRAME::DisplayWizardInfos() +{ + wxString msg; + + msg = _( "Footprint Wizard" ); + msg << wxT( " [" ); + + if( ! m_wizardName.IsEmpty() ) + msg << m_wizardName; + else + msg += _( "no wizard selected" ); + + msg << wxT( "]" ); + + SetTitle( msg ); +} + + +void FOOTPRINT_WIZARD_FRAME::SelectCurrentWizard( wxCommandEvent& event ) +{ + wxString msg; + + if( g_LibraryNames.GetCount() == 0 ) + return; + + EDA_LIST_DIALOG dlg( this, _( "Select Current Wizard:" ), + g_LibraryNames, m_wizardName ); + + if( dlg.ShowModal() != wxID_OK ) + return; + + if( m_wizardName == dlg.GetTextSelection() ) + return; + + m_wizardName = dlg.GetTextSelection(); + + DisplayWizardInfos(); + ReCreatePageList(); + ReCreateParameterList(); + + +} + +/** + * Function SelectCurrentFootprint + * Selects the current footprint name and display it + */ +void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxCommandEvent& event ) +{ + /* + // will pick it from the wizard + MODULE * module = new MODULE(NULL); + if( module ) + { + module->SetPosition( wxPoint( 0, 0 ) ); + + // Only one fotprint allowed: remove the previous footprint (if exists) + if( oldmodule ) + { + GetBoard()->Remove( oldmodule ); + delete oldmodule; + } + m_footprintName = module->GetLibRef(); + module->ClearFlags(); + SetCurItem( NULL ); + + Zoom_Automatique( false ); + m_canvas->Refresh( ); + Update3D_Frame(); + m_FootprintList->SetStringSelection( m_footprintName ); + } + * */ +} + + +/** + * Function RedrawActiveWindow + * Display the current selected component. + * If the component is an alias, the ROOT component is displayed +*/ +void FOOTPRINT_WIZARD_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) +{ + if( !GetBoard() ) + return; + + m_canvas->DrawBackGround( DC ); + GetBoard()->Draw( m_canvas, DC, GR_COPY ); + + MODULE* module = GetBoard()->m_Modules; + + if ( module ) + module->DisplayInfo( this ); + + m_canvas->DrawCrossHair( DC ); + + ClearMsgPanel(); + if( module ) + module->DisplayInfo( this ); +} diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp new file mode 100644 index 0000000000..ae534d96f9 --- /dev/null +++ b/pcbnew/footprint_wizard_frame.cpp @@ -0,0 +1,685 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 Jean-Pierre Charras, jaen-pierre.charras + * Copyright (C) 2008-2011 Wayne Stambaugh + * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file modview_frame.cpp + */ + +#include +#include +#include +#include +#include +#include <3d_viewer.h> +#include + +#include +#include + +#include +#include +#include "footprint_wizard_frame.h" +#include + +#include +#include + + +BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_FRAME, EDA_DRAW_FRAME ) + /* Window events */ + EVT_CLOSE( FOOTPRINT_WIZARD_FRAME::OnCloseWindow ) + EVT_SIZE( FOOTPRINT_WIZARD_FRAME::OnSize ) + EVT_ACTIVATE( FOOTPRINT_WIZARD_FRAME::OnActivate ) + + /* Sash drag events */ + EVT_SASH_DRAGGED( ID_FOOTPRINT_WIZARD_PAGES, FOOTPRINT_WIZARD_FRAME::OnSashDrag ) + EVT_SASH_DRAGGED( ID_FOOTPRINT_WIZARD_PARAMETERS, FOOTPRINT_WIZARD_FRAME::OnSashDrag ) + + /* Toolbar events */ + EVT_TOOL( ID_FOOTPRINT_WIZARD_NEXT, + FOOTPRINT_WIZARD_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_FOOTPRINT_WIZARD_PREVIOUS, + FOOTPRINT_WIZARD_FRAME::Process_Special_Functions ) +/* EVT_TOOL( ID_FOOTPRINT_WIZARD_DONE, + FOOTPRINT_WIZARD_FRAME::ExportSelectedFootprint )*/ + EVT_TOOL( ID_FOOTPRINT_WIZARD_SHOW_3D_VIEW, + FOOTPRINT_WIZARD_FRAME::Show3D_Frame ) + + /* listbox events */ + EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PAGE_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnPageList ) + EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PARAMETER_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnParameterList ) + + EVT_MENU( ID_SET_RELATIVE_OFFSET, FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset ) +END_EVENT_TABLE() + + +/* + * This emulates the zoom menu entries found in the other KiCad applications. + * The library viewer does not have any menus so add an accelerator table to + * the main frame. + */ +static wxAcceleratorEntry accels[] = +{ + wxAcceleratorEntry( wxACCEL_NORMAL, WXK_F1, ID_ZOOM_IN ), + wxAcceleratorEntry( wxACCEL_NORMAL, WXK_F2, ID_ZOOM_OUT ), + wxAcceleratorEntry( wxACCEL_NORMAL, WXK_F3, ID_ZOOM_REDRAW ), + wxAcceleratorEntry( wxACCEL_NORMAL, WXK_F4, ID_POPUP_ZOOM_CENTER ), + wxAcceleratorEntry( wxACCEL_NORMAL, WXK_HOME, ID_ZOOM_PAGE ), + wxAcceleratorEntry( wxACCEL_NORMAL, WXK_SPACE, ID_SET_RELATIVE_OFFSET ) +}; + +#define ACCEL_TABLE_CNT ( sizeof( accels ) / sizeof( wxAcceleratorEntry ) ) + +#define EXTRA_BORDER_SIZE 2 + + +FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( wxWindow* parent, wxSemaphore* semaphore ) : + PCB_BASE_FRAME( parent, MODULE_VIEWER_FRAME, _( "Footprint Wizard" ), + wxDefaultPosition, wxDefaultSize ) +{ + wxAcceleratorTable table( ACCEL_TABLE_CNT, accels ); + + m_FrameName = wxT( "FootprintWizard" ); + m_configPath = wxT( "FootprintWizard" ); + m_showAxis = true; // true to draw axis. + + // Give an icon + wxIcon icon; + icon.CopyFromBitmap( KiBitmap( modview_icon_xpm ) ); + SetIcon( icon ); + + m_HotkeysZoomAndGridList = g_Module_Viewer_Hokeys_Descr; + m_PageList= NULL; + m_ParameterList = NULL; + m_PageListWindow = NULL; + m_ParameterListWindow = NULL; + m_Semaphore = semaphore; + m_wizardName.Empty(); + + if( m_Semaphore ) + MakeModal(true); + + SetBoard( new BOARD() ); + // Ensure all layers and items are visible: + GetBoard()->SetVisibleAlls(); + SetScreen( new PCB_SCREEN(GetPageSizeIU()) ); + GetScreen()->m_Center = true; // Center coordinate origins on screen. + LoadSettings(); + + SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); + GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); + + ReCreateHToolbar(); + ReCreateVToolbar(); + + wxSize size = GetClientSize(); + size.y -= m_MsgFrameHeight + 2; + + m_PageListSize.y = -1; + + wxPoint win_pos( 0, 0 ); + + // Creates the libraries window display + m_PageListWindow = + new wxSashLayoutWindow( this, ID_FOOTPRINT_WIZARD_PAGES_WINDOW, win_pos, + wxDefaultSize, wxCLIP_CHILDREN | wxSW_3D, + wxT( "PagesWindow" ) ); + m_PageListWindow->SetOrientation( wxLAYOUT_VERTICAL ); + m_PageListWindow->SetAlignment( wxLAYOUT_LEFT ); + m_PageListWindow->SetSashVisible( wxSASH_RIGHT, true ); + m_PageListWindow->SetExtraBorderSize( EXTRA_BORDER_SIZE ); + m_PageList = new wxListBox( m_PageListWindow, ID_FOOTPRINT_WIZARD_PAGE_LIST, + wxPoint( 0, 0 ), wxDefaultSize, + 0, NULL, wxLB_HSCROLL ); + + // Creates the component window display + m_ParameterListSize.y = size.y; + win_pos.x = m_PageListSize.x; + m_ParameterListWindow = new wxSashLayoutWindow( this, + ID_FOOTPRINT_WIZARD_PARAMETERS_WINDOW, + win_pos, wxDefaultSize, + wxCLIP_CHILDREN | wxSW_3D, + wxT( "ParameterList" ) ); + + m_ParameterListWindow->SetOrientation( wxLAYOUT_VERTICAL ); + + m_ParameterListWindow->SetSashVisible( wxSASH_RIGHT, true ); + m_ParameterListWindow->SetExtraBorderSize( EXTRA_BORDER_SIZE ); + m_ParameterList = new wxListBox( m_ParameterListWindow, ID_FOOTPRINT_WIZARD_PARAMETER_LIST, + wxPoint( 0, 0 ), wxDefaultSize, + 0, NULL, wxLB_HSCROLL ); + + ReCreatePageList(); + + DisplayWizardInfos(); + + if( m_canvas ) + m_canvas->SetAcceleratorTable( table ); + + m_auimgr.SetManagedWindow( this ); + + + EDA_PANEINFO horiz; + horiz.HorizontalToolbarPane(); + + EDA_PANEINFO vert; + vert.VerticalToolbarPane(); + + EDA_PANEINFO info; + info.InfoToolbarPane(); + + EDA_PANEINFO mesg; + mesg.MessageToolbarPane(); + + + // Manage main toolbal + m_auimgr.AddPane( m_mainToolBar, + wxAuiPaneInfo( horiz ).Name( wxT ("m_mainToolBar" ) ).Top().Row( 0 ) ); + + wxSize minsize( 60, -1 ); + + // Manage the left window (list of pages) + if( m_PageListWindow ) + m_auimgr.AddPane( m_PageListWindow, wxAuiPaneInfo( info ).Name( wxT( "m_PageList" ) ). + Left().Row( 0 )); + + // Manage the list of parameters) + m_auimgr.AddPane( m_ParameterListWindow, + wxAuiPaneInfo( info ).Name( wxT( "m_ParameterList" ) ). + Left().Row( 1 ) ); + + // Manage the draw panel + m_auimgr.AddPane( m_canvas, + wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).Centre() ); + + // Manage the message panel + m_auimgr.AddPane( m_messagePanel, + wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) ); + + /* Now the minimum windows are fixed, set library list + * and component list of the previous values from last viewlib use + */ + if( m_PageListWindow ) + { + wxAuiPaneInfo& pane = m_auimgr.GetPane(m_PageListWindow); + pane.MinSize( wxSize(m_PageListSize.x, -1)); + } + wxAuiPaneInfo& pane = m_auimgr.GetPane(m_ParameterListWindow); + pane.MinSize(wxSize(m_ParameterListSize.x, -1)); + + m_auimgr.Update(); + + // Now Drawpanel is sized, we can use BestZoom to show the component (if any) +#ifdef USE_WX_GRAPHICS_CONTEXT + GetScreen()->SetZoom( BestZoom() ); +#else + Zoom_Automatique( false ); +#endif + + Show( true ); +} + + +FOOTPRINT_WIZARD_FRAME::~FOOTPRINT_WIZARD_FRAME() +{ + if( m_Draw3DFrame ) + m_Draw3DFrame->Destroy(); + PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent(); + frame->m_ModuleViewerFrame = NULL; +} + + +void FOOTPRINT_WIZARD_FRAME::OnCloseWindow( wxCloseEvent& Event ) +{ + SaveSettings(); + + if( m_Semaphore ) + { + m_Semaphore->Post(); + MakeModal(false); + // This window will be destroyed by the calling function, + // to avoid side effects + } + else + { + Destroy(); + } +} + + +void FOOTPRINT_WIZARD_FRAME::OnSashDrag( wxSashEvent& event ) +{ + if( event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE ) + return; + + m_PageListSize.y = GetClientSize().y - m_MsgFrameHeight; + m_ParameterListSize.y = m_PageListSize.y; + + switch( event.GetId() ) + { + case ID_FOOTPRINT_WIZARD_WINDOW: + if( m_PageListWindow ) + { + wxAuiPaneInfo& pane = m_auimgr.GetPane( m_PageListWindow ); + m_PageListSize.x = event.GetDragRect().width; + pane.MinSize( m_PageListSize ); + m_auimgr.Update(); + } + break; + + case ID_FOOTPRINT_WIZARD_PARAMETERS_WINDOW: + { + wxAuiPaneInfo& pane = m_auimgr.GetPane( m_ParameterListWindow ); + m_ParameterListSize.x = event.GetDragRect().width; + pane.MinSize( m_ParameterListSize ); + m_auimgr.Update(); + } + break; + } +} + + +void FOOTPRINT_WIZARD_FRAME::OnSize( wxSizeEvent& SizeEv ) +{ + if( m_auimgr.GetManagedWindow() ) + m_auimgr.Update(); + + SizeEv.Skip(); +} + + +void FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset( wxCommandEvent& event ) +{ + GetScreen()->m_O_Curseur = GetScreen()->GetCrossHairPosition(); + UpdateStatusBar(); +} + + +void FOOTPRINT_WIZARD_FRAME::ReCreatePageList() +{ + if( m_PageList == NULL ) + return; + + m_PageList->Clear(); + + m_PageList->Append(wxT("Pads")); + m_PageList->Append(wxT("Shield")); + + m_PageList->SetSelection( 0, true ); + + /*for( unsigned ii = 0; ii < g_LibraryNames.GetCount(); ii++ ) + { + m_PageList->Append( g_LibraryNames[ii] ); + }*/ + +#if 0 + // Search for a previous selection: + + int index = m_PageList->FindString( m_libraryName ); + + if( index != wxNOT_FOUND ) + { + m_PageList->SetSelection( index, true ); + } + else + { + /* If not found, clear current library selection because it can be + * deleted after a config change. */ + m_libraryName = wxEmptyString; + m_footprintName = wxEmptyString; + } +#endif + + ReCreateHToolbar(); + DisplayWizardInfos(); + m_canvas->Refresh(); +} + + +void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList() +{ + if( m_ParameterList == NULL ) + return; + + m_ParameterList->Clear(); + + wxArrayString fpList; + + m_ParameterList->Append( fpList ); + m_ParameterList->Append(wxT("N")); + m_ParameterList->Append(wxT("pitch")); + m_ParameterList->Append(wxT("width")); + m_ParameterList->Append(wxT("height")); + m_ParameterList->SetSelection( 0, true ); + + //m_ParameterList->SetSelection( index, true ); +} + + +void FOOTPRINT_WIZARD_FRAME::ClickOnPageList( wxCommandEvent& event ) +{ + int ii = m_PageList->GetSelection(); + + if( ii < 0 ) + return; + + wxString name = m_PageList->GetString( ii ); + + printf("page=%d\n",ii); + + ReCreateParameterList(); + m_canvas->Refresh(); + DisplayWizardInfos(); +} + + +void FOOTPRINT_WIZARD_FRAME::ClickOnParameterList( wxCommandEvent& event ) +{ + int ii = m_ParameterList->GetSelection(); + + if( ii < 0 ) + return; + + wxString name = m_ParameterList->GetString( ii ); + + SetCurItem( NULL ); + // Delete the current footprint + GetBoard()->m_Modules.DeleteAll(); + DisplayWizardInfos(); + Zoom_Automatique( false ); + m_canvas->Refresh(); +} + + +#define PARTLIST_WIDTH_KEY wxT( "Partlist_width" ) +#define PARAMLIST_WIDTH_KEY wxT( "Paramlist_width" ) + + +void FOOTPRINT_WIZARD_FRAME::LoadSettings( ) +{ + wxConfig* cfg ; + + EDA_DRAW_FRAME::LoadSettings(); + + wxConfigPathChanger cpc( wxGetApp().GetSettings(), m_configPath ); + cfg = wxGetApp().GetSettings(); + + m_PageListSize.x = 150; // default width of libs list + m_ParameterListSize.x = 150; // default width of component list + + cfg->Read( PARTLIST_WIDTH_KEY , &m_PageListSize.x ); + cfg->Read( PARAMLIST_WIDTH_KEY, &m_ParameterListSize.x ); + + // Set parameters to a reasonable value. + if ( m_PageListSize.x > m_FrameSize.x/2 ) + m_PageListSize.x = m_FrameSize.x/2; + + if ( m_ParameterListSize.x > m_FrameSize.x/2 ) + m_ParameterListSize.x = m_FrameSize.x/2; +} + + +void FOOTPRINT_WIZARD_FRAME::SaveSettings() +{ + wxConfig* cfg; + + EDA_DRAW_FRAME::SaveSettings(); + + wxConfigPathChanger cpc( wxGetApp().GetSettings(), m_configPath ); + cfg = wxGetApp().GetSettings(); + + if ( m_PageListSize.x ) + cfg->Write( PARTLIST_WIDTH_KEY, m_PageListSize.x ); + + cfg->Write( PARAMLIST_WIDTH_KEY, m_ParameterListSize.x ); +} + + +void FOOTPRINT_WIZARD_FRAME::OnActivate( wxActivateEvent& event ) +{ + EDA_DRAW_FRAME::OnActivate( event ); + + // Ensure we do not have old selection: + if( ! m_FrameIsActive ) + return; + + bool footprintWizardsChanged=false; + if (footprintWizardsChanged) + { + // If we are here, the library list has changed, rebuild it + ReCreatePageList(); + DisplayWizardInfos(); + + } +} + + +void FOOTPRINT_WIZARD_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey ) +{ + wxRealPoint gridSize; + wxPoint oldpos; + PCB_SCREEN* screen = GetScreen(); + wxPoint pos = aPosition; + + wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); + cmd.SetEventObject( this ); + + pos = screen->GetNearestGridPosition( pos ); + oldpos = screen->GetCrossHairPosition(); + gridSize = screen->GetGridSize(); + + switch( aHotKey ) + { + case WXK_F1: + cmd.SetId( ID_POPUP_ZOOM_IN ); + GetEventHandler()->ProcessEvent( cmd ); + break; + + case WXK_F2: + cmd.SetId( ID_POPUP_ZOOM_OUT ); + GetEventHandler()->ProcessEvent( cmd ); + break; + + case WXK_F3: + cmd.SetId( ID_ZOOM_REDRAW ); + GetEventHandler()->ProcessEvent( cmd ); + break; + + case WXK_F4: + cmd.SetId( ID_POPUP_ZOOM_CENTER ); + GetEventHandler()->ProcessEvent( cmd ); + break; + + case WXK_HOME: + cmd.SetId( ID_ZOOM_PAGE ); + GetEventHandler()->ProcessEvent( cmd ); + break; + + case ' ': + screen->m_O_Curseur = screen->GetCrossHairPosition(); + break; + + case WXK_NUMPAD8: /* cursor moved up */ + case WXK_UP: + pos.y -= KiROUND( gridSize.y ); + m_canvas->MoveCursor( pos ); + break; + + case WXK_NUMPAD2: /* cursor moved down */ + case WXK_DOWN: + pos.y += KiROUND( gridSize.y ); + m_canvas->MoveCursor( pos ); + break; + + case WXK_NUMPAD4: /* cursor moved left */ + case WXK_LEFT: + pos.x -= KiROUND( gridSize.x ); + m_canvas->MoveCursor( pos ); + break; + + case WXK_NUMPAD6: /* cursor moved right */ + case WXK_RIGHT: + pos.x += KiROUND( gridSize.x ); + m_canvas->MoveCursor( pos ); + break; + } + + screen->SetCrossHairPosition( pos ); + + if( oldpos != screen->GetCrossHairPosition() ) + { + pos = screen->GetCrossHairPosition(); + screen->SetCrossHairPosition( oldpos ); + m_canvas->CrossHairOff( aDC ); + screen->SetCrossHairPosition( pos ); + m_canvas->CrossHairOn( aDC ); + + if( m_canvas->IsMouseCaptured() ) + { + m_canvas->CallMouseCapture( aDC, aPosition, 0 ); + } + } + + UpdateStatusBar(); /* Display new cursor coordinates */ +} + + +void FOOTPRINT_WIZARD_FRAME::Show3D_Frame( wxCommandEvent& event ) +{ + if( m_Draw3DFrame ) + { + // Raising the window does not show the window on Windows if iconized. + // This should work on any platform. + if( m_Draw3DFrame->IsIconized() ) + m_Draw3DFrame->Iconize( false ); + + m_Draw3DFrame->Raise(); + + // Raising the window does not set the focus on Linux. This should work on any platform. + if( wxWindow::FindFocus() != m_Draw3DFrame ) + m_Draw3DFrame->SetFocus(); + + return; + } + + m_Draw3DFrame = new EDA_3D_FRAME( this, wxEmptyString ); + Update3D_Frame( false ); + m_Draw3DFrame->Show( true ); +} + +/** + * Function Update3D_Frame + * must be called after a footprint selection + * Updates the 3D view and 3D frame title. + */ +void FOOTPRINT_WIZARD_FRAME::Update3D_Frame( bool aForceReloadFootprint ) +{ + if( m_Draw3DFrame == NULL ) + return; + + wxString frm3Dtitle; + frm3Dtitle.Printf( _( "ModView: 3D Viewer [%s]" ), GetChars( m_wizardName ) ); + m_Draw3DFrame->SetTitle( frm3Dtitle ); + + if( aForceReloadFootprint ) + { + m_Draw3DFrame->ReloadRequest(); + // Force 3D screen refresh immediately + if( GetBoard()->m_Modules ) + m_Draw3DFrame->NewDisplay(); + } +} + + +void FOOTPRINT_WIZARD_FRAME::ReCreateHToolbar() +{ + wxString msg; + + if( m_mainToolBar == NULL ) + { + m_mainToolBar = new wxAuiToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, + wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT ); + + // Set up toolbar + m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_SELECT_WIZARD, wxEmptyString, + KiBitmap( library_xpm ), + _( "Select wizard to use" ) ); + + m_mainToolBar->AddSeparator(); + m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_PREVIOUS, wxEmptyString, + KiBitmap( lib_previous_xpm ), + _( "Display previous page" ) ); + + m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_NEXT, wxEmptyString, + KiBitmap( lib_next_xpm ), + _( "Display next page" ) ); + + m_mainToolBar->AddSeparator(); + m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_SHOW_3D_VIEW, wxEmptyString, + KiBitmap( three_d_xpm ), + _( "Show footprint in 3D viewer" ) ); + + m_mainToolBar->AddSeparator(); + msg = AddHotkeyName( _( "Zoom in" ), g_Module_Editor_Hokeys_Descr, + HK_ZOOM_IN, IS_COMMENT ); + m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString, + KiBitmap( zoom_in_xpm ), msg ); + + msg = AddHotkeyName( _( "Zoom out" ), g_Module_Editor_Hokeys_Descr, + HK_ZOOM_OUT, IS_COMMENT ); + m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString, + KiBitmap( zoom_out_xpm ), msg ); + + msg = AddHotkeyName( _( "Redraw view" ), g_Module_Editor_Hokeys_Descr, + HK_ZOOM_REDRAW, IS_COMMENT ); + m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString, + KiBitmap( zoom_redraw_xpm ), msg ); + + msg = AddHotkeyName( _( "Zoom auto" ), g_Module_Editor_Hokeys_Descr, + HK_ZOOM_AUTO, IS_COMMENT ); + m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, + KiBitmap( zoom_fit_in_page_xpm ), msg ); +#if 0 + if( m_Semaphore ) + { + // The library browser is called from a "load component" command + m_mainToolBar->AddSeparator(); + m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_FOOTPRINT_EXPORT_TO_BOARD, + wxEmptyString, KiBitmap( export_footprint_names_xpm ), + _( "Insert footprint in board" ) ); + } +#endif + // after adding the buttons to the toolbar, must call Realize() to + // reflect the changes + m_mainToolBar->Realize(); + } + + m_mainToolBar->Refresh(); +} + + +void FOOTPRINT_WIZARD_FRAME::ReCreateVToolbar() +{ +} diff --git a/pcbnew/footprint_wizard_frame.h b/pcbnew/footprint_wizard_frame.h new file mode 100644 index 0000000000..82777f246a --- /dev/null +++ b/pcbnew/footprint_wizard_frame.h @@ -0,0 +1,167 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 Miguel Angel Ajo Pelayo, miguelangel@nbee.es + * Copyright (C) 2012 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com + * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file footprint_wizard_frame.h + */ + +#ifndef FOOTPRINT_WIZARD_FRAME_H_ +#define FOOTPRINT_WIZARD_FRAME_H_ + + +#include + +class wxSashLayoutWindow; +class wxListBox; +class wxSemaphore; + + +/** + * Component library viewer main window. + */ +class FOOTPRINT_WIZARD_FRAME : public PCB_BASE_FRAME +{ +private: + // List of libraries (for selection ) + wxSashLayoutWindow* m_PageListWindow; + wxListBox* m_PageList; // The list of pages + wxSize m_PageListSize; // size of the window + + // List of components in the selected library + wxSashLayoutWindow* m_ParameterListWindow; + wxListBox* m_ParameterList; // The list of parameters + wxSize m_ParameterListSize; // size of the window + + // Flags + wxSemaphore* m_Semaphore; // != NULL if the frame must emulate a modal dialog + wxString m_configPath; // subpath for configuration + +protected: + wxString m_wizardName; //< name of the current wizard + wxString m_wizardDescription; //< description of the wizard + wxString m_wizardStatus; //< current wizard status + +public: + FOOTPRINT_WIZARD_FRAME( wxWindow* parent, wxSemaphore* semaphore = NULL ); + + ~FOOTPRINT_WIZARD_FRAME(); + + MODULE* GetBuiltFootrint( void ); + +private: + + void OnSize( wxSizeEvent& event ); + + /** + * Function OnSashDrag + * resizes the child windows when dragging a sash window border. + */ + + void OnSashDrag( wxSashEvent& event ); + + /** + * Function ReCreateLibraryList + * + * Creates or recreates the list of current loaded libraries. + * This list is sorted, with the library cache always at end of the list + */ + void ReCreatePageList(); + void ReCreateParameterList(); + + void Process_Special_Functions( wxCommandEvent& event ); + void DisplayWizardInfos(); + void RedrawActiveWindow( wxDC* DC, bool EraseBg ); + void OnCloseWindow( wxCloseEvent& Event ); + void ReCreateHToolbar(); + void ReCreateVToolbar(); + void OnLeftClick( wxDC* DC, const wxPoint& MousePos ); + void ClickOnPageList( wxCommandEvent& event ); + void ClickOnParameterList( wxCommandEvent& event ); + void OnSetRelativeOffset( wxCommandEvent& event ); + + void GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 ); + + /** + * Function LoadSettings + * loads the library viewer frame specific configuration settings. + * + * Don't forget to call this base method from any derived classes or the + * settings will not get loaded. + */ + void LoadSettings(); + + /** + * Function SaveSettings + * save library viewer frame specific configuration settings. + * + * Don't forget to call this base method from any derived classes or the + * settings will not get saved. + */ + void SaveSettings(); + + + /** + * Function OnActivate + * is called when the frame frame is activate to reload the libraries and component lists + * that can be changed by the schematic editor or the library editor. + */ + virtual void OnActivate( wxActivateEvent& event ); + + void SelectCurrentWizard( wxCommandEvent& event ); + + void ParametersUpdated( wxCommandEvent& event ); + + + + bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ); + + /** + * Function Show3D_Frame (virtual) + * displays 3D view of the footprint (module) being edited. + */ + void Show3D_Frame( wxCommandEvent& event ); + + /** + * Function Update3D_Frame + * must be called after a footprint selection + * Updates the 3D view and 3D frame title. + * @param aForceReloadFootprint = true to reload data (default) + * = false to update title only -(aftre creating the 3D viewer) + */ + void Update3D_Frame( bool aForceReloadFootprint = true ); + + /* + * Virtual functions, not used here, but needed by PCB_BASE_FRAME + * (virtual pure functions ) + */ + void OnLeftDClick(wxDC*, const wxPoint&) {} + void SaveCopyInUndoList(BOARD_ITEM*, UNDO_REDO_T, const wxPoint&) {} + void SaveCopyInUndoList(PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint&) {} + + + DECLARE_EVENT_TABLE() +}; + +#endif // FOOTPRINT_WIZARD_FRM_H_ diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 0c1ccc4363..f55c561d48 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -29,6 +29,8 @@ #include #include #include +#include + // Functions defined in block_module_editor, but used here // These 2 functions are used in modedit to rotate or mirror the whole footprint @@ -283,6 +285,36 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) } break; } + + case ID_MODEDIT_NEW_MODULE_FROM_WIZARD: + { + Clear_Pcb( true ); + GetScreen()->ClearUndoRedoList(); + SetCurItem( NULL ); + GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); + + MODULE* module = NULL; + + FOOTPRINT_WIZARD_FRAME *wizard = new FOOTPRINT_WIZARD_FRAME(this,NULL); + wizard->Show( true ); + wizard->Zoom_Automatique( false ); + + if( module ) // i.e. if create module command not aborted + { + // Initialize data relative to nets and netclasses (for a new + // module the defaults are used) + // This is mandatory to handle and draw pads + GetBoard()->BuildListOfNets(); + redraw = true; + module->SetPosition( wxPoint( 0, 0 ) ); + + if( GetBoard()->m_Modules ) + GetBoard()->m_Modules->ClearFlags(); + + Zoom_Automatique( false ); + } + break; + } case ID_MODEDIT_SAVE_LIBMODULE: if( GetBoard()->m_Modules == NULL ) diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 3c6261dede..7103043235 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -71,6 +71,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME ) EVT_TOOL( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_NEW_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_MODEDIT_NEW_MODULE_FROM_WIZARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_LOAD_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_IMPORT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h index 88bf2da19c..71d7769e5b 100644 --- a/pcbnew/pcbnew_id.h +++ b/pcbnew/pcbnew_id.h @@ -299,6 +299,7 @@ enum pcbnew_ids ID_MODEDIT_SAVE_LIBMODULE, ID_MODEDIT_DELETE_PART, ID_MODEDIT_NEW_MODULE, + ID_MODEDIT_NEW_MODULE_FROM_WIZARD, ID_MODEDIT_SHEET_SET, ID_MODEDIT_LOAD_MODULE, ID_MODEDIT_PAD_SETTINGS, @@ -323,8 +324,21 @@ enum pcbnew_ids ID_MODVIEW_PREVIOUS, ID_MODVIEW_NEXT, ID_MODVIEW_SHOW_3D_VIEW, - ID_MODVIEW_FOOTPRINT_EXPORT_TO_BOARD - + ID_MODVIEW_FOOTPRINT_EXPORT_TO_BOARD, + ID_FOOTPRINT_WIZARD_WINDOW, + ID_FOOTPRINT_WIZARD_PAGES, + ID_FOOTPRINT_WIZARD_PARAMETERS, + ID_FOOTPRINT_WIZARD_NEXT, + ID_FOOTPRINT_WIZARD_PREVIOUS, + ID_FOOTPRINT_WIZARD_DONE, + ID_FOOTPRINT_WIZARD_SHOW_3D_VIEW, + ID_FOOTPRINT_WIZARD_PAGE_LIST, + ID_FOOTPRINT_WIZARD_PARAMETER_LIST, + ID_FOOTPRINT_WIZARD_PAGES_WINDOW, + ID_FOOTPRINT_WIZARD_PARAMETERS_WINDOW, + ID_FOOTPRINT_WIZARD_SELECT_WIZARD, + ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD, + }; #endif /* __PCBNEW_IDS_H__ */ diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.cpp b/pcbnew/scripting/pcbnew_footprint_wizards.cpp index 8bd60af79e..83bcb90b1a 100644 --- a/pcbnew/scripting/pcbnew_footprint_wizards.cpp +++ b/pcbnew/scripting/pcbnew_footprint_wizards.cpp @@ -1,28 +1,28 @@ /** * @file pcbnew_footprint_wizards.cpp - * @brief Class PCBNEW_FOOTPRINT_WIZARDS + * @brief Class PCBNEW_PYTHON_FOOTPRINT_WIZARDS */ #include "pcbnew_footprint_wizards.h" #include -FOOTPRINT_WIZARD::FOOTPRINT_WIZARD(PyObject *aWizard) +PYTHON_FOOTPRINT_WIZARD::PYTHON_FOOTPRINT_WIZARD(PyObject *aWizard) { - this->py_wizard = aWizard; + this->m_PyWizard= aWizard; Py_XINCREF(aWizard); } -FOOTPRINT_WIZARD::~FOOTPRINT_WIZARD() +PYTHON_FOOTPRINT_WIZARD::~PYTHON_FOOTPRINT_WIZARD() { - Py_XDECREF(this->py_wizard); + Py_XDECREF(this->m_PyWizard); } -PyObject* FOOTPRINT_WIZARD::CallMethod(const char* aMethod, PyObject *aArglist) +PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod(const char* aMethod, PyObject *aArglist) { PyObject *pFunc; /* pFunc is a new reference to the desired method */ - pFunc = PyObject_GetAttrString(this->py_wizard, aMethod); + pFunc = PyObject_GetAttrString(this->m_PyWizard, aMethod); if (pFunc && PyCallable_Check(pFunc)) { @@ -39,7 +39,6 @@ PyObject* FOOTPRINT_WIZARD::CallMethod(const char* aMethod, PyObject *aArglist) printf (" : %s\n",PyString_AsString(PyObject_Str(b))); } - if (result) { Py_XDECREF(pFunc); @@ -57,7 +56,7 @@ PyObject* FOOTPRINT_WIZARD::CallMethod(const char* aMethod, PyObject *aArglist) return NULL; } -wxString FOOTPRINT_WIZARD::CallRetStrMethod(const char* aMethod, PyObject *aArglist) +wxString PYTHON_FOOTPRINT_WIZARD::CallRetStrMethod(const char* aMethod, PyObject *aArglist) { wxString ret; PyObject *result = CallMethod(aMethod,aArglist); @@ -74,22 +73,22 @@ wxString FOOTPRINT_WIZARD::CallRetStrMethod(const char* aMethod, PyObject *aArgl return ret; } -wxString FOOTPRINT_WIZARD::GetName() +wxString PYTHON_FOOTPRINT_WIZARD::GetName() { return CallRetStrMethod("GetName"); } -wxString FOOTPRINT_WIZARD::GetImage() +wxString PYTHON_FOOTPRINT_WIZARD::GetImage() { return CallRetStrMethod("GetImage"); } -wxString FOOTPRINT_WIZARD::GetDescription() +wxString PYTHON_FOOTPRINT_WIZARD::GetDescription() { return CallRetStrMethod("GetDescription"); } -int FOOTPRINT_WIZARD::GetNumParameterPages() +int PYTHON_FOOTPRINT_WIZARD::GetNumParameterPages() { int ret; PyObject *result; @@ -106,7 +105,7 @@ int FOOTPRINT_WIZARD::GetNumParameterPages() return ret; } -wxString FOOTPRINT_WIZARD::GetParameterPageName(int aPage) +wxString PYTHON_FOOTPRINT_WIZARD::GetParameterPageName(int aPage) { wxString ret; PyObject *arglist; @@ -126,41 +125,48 @@ wxString FOOTPRINT_WIZARD::GetParameterPageName(int aPage) return ret; } -wxArrayString FOOTPRINT_WIZARD::GetParameterNames(int aPage) +wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterNames(int aPage) { wxArrayString a; return a; } -wxArrayString FOOTPRINT_WIZARD::GetParameterValues(int aPage) +wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterValues(int aPage) { wxArrayString a; return a; } -wxString FOOTPRINT_WIZARD::SetParameterValues(int aPage,wxArrayString& aValues) +wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues(int aPage,wxArrayString& aValues) { wxString ret; return ret; } -MODULE FOOTPRINT_WIZARD::*GetModule() +MODULE *PYTHON_FOOTPRINT_WIZARD::GetModule() { return NULL; } -std::vector FOOTPRINT_WIZARDS::m_FootprintWizards; -void FOOTPRINT_WIZARDS::register_wizard(PyObject* wizard) +void PYTHON_FOOTPRINT_WIZARDS::register_wizard(PyObject* aPyWizard) { - FOOTPRINT_WIZARD *fw; + PYTHON_FOOTPRINT_WIZARD *fw; - fw = new FOOTPRINT_WIZARD(wizard); - m_FootprintWizards.push_back(fw); + fw = new PYTHON_FOOTPRINT_WIZARD(aPyWizard); printf("Registered python footprint wizard '%s'\n", - (const char*)fw->GetName().mb_str()); + (const char*)fw->GetName().mb_str() + ); + // this get the wizard registered in the common + // FOOTPRINT_WIZARDS class + + fw->register_wizard(); + + +#if 0 + /* just to test if it works correctly */ int pages = fw->GetNumParameterPages(); printf(" %d pages\n",pages); @@ -169,7 +175,7 @@ void FOOTPRINT_WIZARDS::register_wizard(PyObject* wizard) printf(" page %d->'%s'\n",n, (const char*)fw->GetParameterPageName(n).mb_str()); } - +#endif } diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.h b/pcbnew/scripting/pcbnew_footprint_wizards.h index 37349cd2d3..0e03b44a41 100644 --- a/pcbnew/scripting/pcbnew_footprint_wizards.h +++ b/pcbnew/scripting/pcbnew_footprint_wizards.h @@ -7,17 +7,17 @@ #define PCBNEW_FOOTPRINT_WIZARDS_H #include #include -#include +#include -class FOOTPRINT_WIZARD +class PYTHON_FOOTPRINT_WIZARD: public FOOTPRINT_WIZARD { - PyObject *py_wizard; + PyObject *m_PyWizard; PyObject *CallMethod(const char *aMethod, PyObject *aArglist=NULL); wxString CallRetStrMethod(const char *aMethod, PyObject *aArglist=NULL); public: - FOOTPRINT_WIZARD(PyObject *wizard); - ~FOOTPRINT_WIZARD(); + PYTHON_FOOTPRINT_WIZARD(PyObject *wizard); + ~PYTHON_FOOTPRINT_WIZARD(); wxString GetName(); wxString GetImage(); wxString GetDescription(); @@ -31,13 +31,10 @@ public: }; -class FOOTPRINT_WIZARDS +class PYTHON_FOOTPRINT_WIZARDS { -private: - static std::vector m_FootprintWizards; - public: - static void register_wizard(PyObject *wizard); + static void register_wizard(PyObject *aPyWizard); }; diff --git a/pcbnew/scripting/plugins.i b/pcbnew/scripting/plugins.i index 591ba79884..1957b7d2b4 100644 --- a/pcbnew/scripting/plugins.i +++ b/pcbnew/scripting/plugins.i @@ -3,7 +3,7 @@ #include %} -class FOOTPRINT_WIZARDS +class PYTHON_FOOTPRINT_WIZARDS { public: static void register_wizard(PyObject *wizard); diff --git a/pcbnew/tool_modedit.cpp b/pcbnew/tool_modedit.cpp index 85bfc7580c..3c20eb7afd 100644 --- a/pcbnew/tool_modedit.cpp +++ b/pcbnew/tool_modedit.cpp @@ -76,6 +76,12 @@ void FOOTPRINT_EDIT_FRAME::ReCreateHToolbar() m_mainToolBar->AddSeparator(); m_mainToolBar->AddTool( ID_MODEDIT_NEW_MODULE, wxEmptyString, KiBitmap( new_footprint_xpm ), _( "New module" ) ); + + m_mainToolBar->AddTool( ID_MODEDIT_NEW_MODULE_FROM_WIZARD, wxEmptyString, + KiBitmap( module_wizard_xpm ), + _( "New module from footprint wizard" ) ); + + m_mainToolBar->AddTool( ID_MODEDIT_LOAD_MODULE, wxEmptyString, KiBitmap( load_module_lib_xpm ), diff --git a/scripting/kicadplugins.i b/scripting/kicadplugins.i index 084561c711..5f1147604b 100644 --- a/scripting/kicadplugins.i +++ b/scripting/kicadplugins.i @@ -35,7 +35,7 @@ class KiCadPlugin: if isinstance(self,FilePlugin): pass # register to file plugins in C++ if isinstance(self,FootprintWizardPlugin): - FOOTPRINT_WIZARDS.register_wizard(self) + PYTHON_FOOTPRINT_WIZARDS.register_wizard(self) return if isinstance(self,ActionPlugin): From c051c1a4a92ae9eec2a68f1849f63dcf68beb4fe Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Thu, 10 May 2012 01:04:08 +0200 Subject: [PATCH 33/41] footprint wizard UI and footprint wizard lists --- pcbnew/CMakeLists.txt | 2 + pcbnew/class_footprint_wizard.cpp | 26 ++ pcbnew/class_footprint_wizard.h | 3 + .../dialogs/dialog_footprint_wizard_list.cpp | 70 +++++ .../dialogs/dialog_footprint_wizard_list.fbp | 263 ++++++++++++++++++ pcbnew/dialogs/dialog_footprint_wizard_list.h | 28 ++ .../dialog_footprint_wizard_list_base.cpp | 74 +++++ .../dialog_footprint_wizard_list_base.h | 49 ++++ pcbnew/footprint_wizard.cpp | 35 +-- pcbnew/footprint_wizard_frame.cpp | 68 ++--- pcbnew/footprint_wizard_frame.h | 6 +- pcbnew/scripting/pcbnew_footprint_wizards.cpp | 24 ++ pcbnew/scripting/pcbnew_footprint_wizards.h | 3 + 13 files changed, 596 insertions(+), 55 deletions(-) create mode 100644 pcbnew/dialogs/dialog_footprint_wizard_list.cpp create mode 100644 pcbnew/dialogs/dialog_footprint_wizard_list.fbp create mode 100644 pcbnew/dialogs/dialog_footprint_wizard_list.h create mode 100644 pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp create mode 100644 pcbnew/dialogs/dialog_footprint_wizard_list_base.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index bcf99737a6..8ed2faa588 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -99,6 +99,8 @@ set(PCBNEW_DIALOGS dialogs/dialog_scripting.cpp footprint_wizard.cpp footprint_wizard_frame.cpp + dialogs/dialog_footprint_wizard_list_base.cpp + dialogs/dialog_footprint_wizard_list.cpp ) # some of the files here may be going to the dialog srcs in fact.... diff --git a/pcbnew/class_footprint_wizard.cpp b/pcbnew/class_footprint_wizard.cpp index 6e85ac4b55..cabc5a2268 100644 --- a/pcbnew/class_footprint_wizard.cpp +++ b/pcbnew/class_footprint_wizard.cpp @@ -13,6 +13,32 @@ void FOOTPRINT_WIZARD::register_wizard() std::vector FOOTPRINT_WIZARDS::m_FootprintWizards; + +FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard(int aIndex) +{ + return m_FootprintWizards[aIndex]; +} + +FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard(wxString aName) +{ + int max = GetSize(); + + for(int i=0; iGetName(); + if (name.Cmp(aName)) + return wizard; + } + + return NULL; +} + +int FOOTPRINT_WIZARDS::GetSize() +{ + return m_FootprintWizards.size(); +} + void FOOTPRINT_WIZARDS::register_wizard(FOOTPRINT_WIZARD *aWizard) { diff --git a/pcbnew/class_footprint_wizard.h b/pcbnew/class_footprint_wizard.h index 36442a6218..2972aa55c9 100644 --- a/pcbnew/class_footprint_wizard.h +++ b/pcbnew/class_footprint_wizard.h @@ -37,6 +37,9 @@ private: public: static void register_wizard(FOOTPRINT_WIZARD *wizard); + static FOOTPRINT_WIZARD* GetWizard(wxString aName); + static FOOTPRINT_WIZARD* GetWizard(int aIndex); + static int GetSize(); }; diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.cpp b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp new file mode 100644 index 0000000000..d93711f0f2 --- /dev/null +++ b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp @@ -0,0 +1,70 @@ +/** + * @file dialog_scripting.cpp + */ + +#include + + + +#include +#include +#include +#include +#include +#include + + + +DIALOG_FOOTPRINT_WIZARD_LIST::DIALOG_FOOTPRINT_WIZARD_LIST( wxWindow* aParent ) + : DIALOG_FOOTPRINT_WIZARD_LIST_BASE( aParent ) +{ + SetFocus(); + int n_wizards = FOOTPRINT_WIZARDS::GetSize(); + + // Current wizard selection, empty or first + m_FootprintWizard = NULL; + + if (n_wizards) + m_FootprintWizard = FOOTPRINT_WIZARDS::GetWizard(0); + + // Choose selection mode and insert the needed rows + m_footprintWizardsGrid->SetSelectionMode(wxGrid::wxGridSelectRows); + m_footprintWizardsGrid->InsertRows(0,n_wizards,true); + + // Put all wizards in the list + for (int i=0;iGetName(); + wxString description = wizard->GetDescription(); + wxString image = wizard->GetImage(); + + m_footprintWizardsGrid->SetCellValue(i,1,name); + m_footprintWizardsGrid->SetCellValue(i,2,description); + + } + + // Select the first row + m_footprintWizardsGrid->ClearSelection(); + m_footprintWizardsGrid->SelectRow(0,false); + +} + + +void DIALOG_FOOTPRINT_WIZARD_LIST::OnCellWizardClick( wxGridEvent& event ) +{ + int click_row = event.GetRow(); + m_FootprintWizard = FOOTPRINT_WIZARDS::GetWizard(click_row); + +} + +FOOTPRINT_WIZARD* DIALOG_FOOTPRINT_WIZARD_LIST::GetWizard() +{ + return m_FootprintWizard; +} + +void DIALOG_FOOTPRINT_WIZARD_LIST::OnOpenButtonClick( wxCommandEvent& event ) +{ + this->MakeModal(false); + this->Close(true); +} diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.fbp b/pcbnew/dialogs/dialog_footprint_wizard_list.fbp new file mode 100644 index 0000000000..3c31fb3a71 --- /dev/null +++ b/pcbnew/dialogs/dialog_footprint_wizard_list.fbp @@ -0,0 +1,263 @@ + + + + + + C++ + 1 + source_name + 0 + UTF-8 + connect + dialog_footprint_wizard_list_base + 1000 + none + 1 + DIALOG_FOOTPRINT_WIZARD_LIST_BASE + + . + + 1 + 1 + 0 + 0 + + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_FOOTPRINT_WIZARD_LIST_BASE + + + wxDEFAULT_DIALOG_STYLE + + Footprint Wizards + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer4 + wxVERTICAL + none + + 5 + wxALL + 1 + + 0 + 1 + + + + wxALIGN_LEFT + + wxALIGN_TOP + wxALIGN_LEFT + 20 + "Preview" "Name" "Description" + wxALIGN_CENTRE + 3 + 80,80,325 + + 1 + 0 + 1 + 0 + 1 + 0 + 1 + + + + 1 + 0 + wxID_ANY + + + + 0 + 0 + + -1,120 + m_footprintWizardsGrid + protected + + wxALIGN_CENTRE + 1 + + wxALIGN_CENTRE + + 0 + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + OnCellWizardClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER|wxALL + 0 + + + + 1 + 0 + 1 + + + 0 + wxID_ANY + Open + + + m_btOpen + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnOpenButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.h b/pcbnew/dialogs/dialog_footprint_wizard_list.h new file mode 100644 index 0000000000..956df0c9d6 --- /dev/null +++ b/pcbnew/dialogs/dialog_footprint_wizard_list.h @@ -0,0 +1,28 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: dialog_footprint_wizard_list.h +///////////////////////////////////////////////////////////////////////////// + +#ifndef _DIALOG_FOOTPRINT_WIZARD_LIST_H_ +#define _DIALOG_FOOTPRINT_WIZARD_LIST_H_ + +#include +#include + +class DIALOG_FOOTPRINT_WIZARD_LIST: public DIALOG_FOOTPRINT_WIZARD_LIST_BASE +{ +private: + wxDialog * m_Parent; + FOOTPRINT_WIZARD *m_FootprintWizard; + +public: + DIALOG_FOOTPRINT_WIZARD_LIST(wxWindow * parent ); + + FOOTPRINT_WIZARD* GetWizard(); + +private: + + void OnCellWizardClick( wxGridEvent& event ); + void OnOpenButtonClick( wxCommandEvent& event ); +}; + +#endif // _DIALOG_FOOTPRINT_WIZARD_LIST_H_ diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp b/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp new file mode 100644 index 0000000000..c273fad1fb --- /dev/null +++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp @@ -0,0 +1,74 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Sep 8 2010) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialog_footprint_wizard_list_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_FOOTPRINT_WIZARD_LIST_BASE::DIALOG_FOOTPRINT_WIZARD_LIST_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer4; + bSizer4 = new wxBoxSizer( wxVERTICAL ); + + m_footprintWizardsGrid = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + + // Grid + m_footprintWizardsGrid->CreateGrid( 0, 3 ); + m_footprintWizardsGrid->EnableEditing( false ); + m_footprintWizardsGrid->EnableGridLines( true ); + m_footprintWizardsGrid->EnableDragGridSize( false ); + m_footprintWizardsGrid->SetMargins( 0, 0 ); + + // Columns + m_footprintWizardsGrid->SetColSize( 0, 80 ); + m_footprintWizardsGrid->SetColSize( 1, 80 ); + m_footprintWizardsGrid->SetColSize( 2, 325 ); + m_footprintWizardsGrid->EnableDragColMove( false ); + m_footprintWizardsGrid->EnableDragColSize( true ); + m_footprintWizardsGrid->SetColLabelSize( 20 ); + m_footprintWizardsGrid->SetColLabelValue( 0, _("Preview") ); + m_footprintWizardsGrid->SetColLabelValue( 1, _("Name") ); + m_footprintWizardsGrid->SetColLabelValue( 2, _("Description") ); + m_footprintWizardsGrid->SetColLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE ); + + // Rows + m_footprintWizardsGrid->AutoSizeRows(); + m_footprintWizardsGrid->EnableDragRowSize( true ); + m_footprintWizardsGrid->SetRowLabelSize( 1 ); + m_footprintWizardsGrid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Label Appearance + + // Cell Defaults + m_footprintWizardsGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + m_footprintWizardsGrid->SetMinSize( wxSize( -1,120 ) ); + + bSizer4->Add( m_footprintWizardsGrid, 1, wxALL, 5 ); + + m_btOpen = new wxButton( this, wxID_ANY, _("Open"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer4->Add( m_btOpen, 0, wxALIGN_CENTER|wxALL, 5 ); + + this->SetSizer( bSizer4 ); + this->Layout(); + bSizer4->Fit( this ); + + this->Centre( wxBOTH ); + + // Connect Events + m_footprintWizardsGrid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::OnCellWizardClick ), NULL, this ); + m_btOpen->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::OnOpenButtonClick ), NULL, this ); +} + +DIALOG_FOOTPRINT_WIZARD_LIST_BASE::~DIALOG_FOOTPRINT_WIZARD_LIST_BASE() +{ + // Disconnect Events + m_footprintWizardsGrid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::OnCellWizardClick ), NULL, this ); + m_btOpen->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::OnOpenButtonClick ), NULL, this ); + +} diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list_base.h b/pcbnew/dialogs/dialog_footprint_wizard_list_base.h new file mode 100644 index 0000000000..2d35c9e058 --- /dev/null +++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.h @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Sep 8 2010) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __dialog_footprint_wizard_list_base__ +#define __dialog_footprint_wizard_list_base__ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_FOOTPRINT_WIZARD_LIST_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_FOOTPRINT_WIZARD_LIST_BASE : public wxDialog +{ + private: + + protected: + wxGrid* m_footprintWizardsGrid; + wxButton* m_btOpen; + + // Virtual event handlers, overide them in your derived class + virtual void OnCellWizardClick( wxGridEvent& event ) { event.Skip(); } + virtual void OnOpenButtonClick( wxCommandEvent& event ) { event.Skip(); } + + + public: + + DIALOG_FOOTPRINT_WIZARD_LIST_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Footprint Wizards"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~DIALOG_FOOTPRINT_WIZARD_LIST_BASE(); + +}; + +#endif //__dialog_footprint_wizard_list_base__ diff --git a/pcbnew/footprint_wizard.cpp b/pcbnew/footprint_wizard.cpp index a3abdac2fc..151f7fd363 100644 --- a/pcbnew/footprint_wizard.cpp +++ b/pcbnew/footprint_wizard.cpp @@ -17,7 +17,7 @@ #include #include "footprint_wizard_frame.h" #include - +#include #define NEXT_PART 1 #define NEW_PART 0 @@ -77,28 +77,31 @@ void FOOTPRINT_WIZARD_FRAME::DisplayWizardInfos() } -void FOOTPRINT_WIZARD_FRAME::SelectCurrentWizard( wxCommandEvent& event ) +void FOOTPRINT_WIZARD_FRAME::SelectFootprintWizard() { - wxString msg; + DIALOG_FOOTPRINT_WIZARD_LIST *selectWizard = + new DIALOG_FOOTPRINT_WIZARD_LIST(this); + + selectWizard->ShowModal(); + + m_FootprintWizard = selectWizard->GetWizard(); - if( g_LibraryNames.GetCount() == 0 ) - return; - - EDA_LIST_DIALOG dlg( this, _( "Select Current Wizard:" ), - g_LibraryNames, m_wizardName ); - - if( dlg.ShowModal() != wxID_OK ) - return; - - if( m_wizardName == dlg.GetTextSelection() ) - return; - - m_wizardName = dlg.GetTextSelection(); + if (m_FootprintWizard) + { + m_wizardName = m_FootprintWizard->GetName(); + m_wizardDescription = m_FootprintWizard->GetDescription(); + } DisplayWizardInfos(); ReCreatePageList(); ReCreateParameterList(); +} + +void FOOTPRINT_WIZARD_FRAME::SelectCurrentWizard( wxCommandEvent& event ) +{ + + SelectFootprintWizard(); } diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index ae534d96f9..0446804350 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -58,8 +58,12 @@ BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_FRAME, EDA_DRAW_FRAME ) EVT_SASH_DRAGGED( ID_FOOTPRINT_WIZARD_PARAMETERS, FOOTPRINT_WIZARD_FRAME::OnSashDrag ) /* Toolbar events */ + EVT_TOOL( ID_FOOTPRINT_WIZARD_SELECT_WIZARD, + FOOTPRINT_WIZARD_FRAME::SelectCurrentWizard) + EVT_TOOL( ID_FOOTPRINT_WIZARD_NEXT, FOOTPRINT_WIZARD_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_FOOTPRINT_WIZARD_PREVIOUS, FOOTPRINT_WIZARD_FRAME::Process_Special_Functions ) /* EVT_TOOL( ID_FOOTPRINT_WIZARD_DONE, @@ -111,6 +115,7 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( wxWindow* parent, wxSemaphore* s SetIcon( icon ); m_HotkeysZoomAndGridList = g_Module_Viewer_Hokeys_Descr; + m_FootprintWizard = NULL; m_PageList= NULL; m_ParameterList = NULL; m_PageListWindow = NULL; @@ -238,7 +243,10 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( wxWindow* parent, wxSemaphore* s Zoom_Automatique( false ); #endif + Show( true ); + + this->SelectFootprintWizard(); } @@ -321,37 +329,21 @@ void FOOTPRINT_WIZARD_FRAME::ReCreatePageList() { if( m_PageList == NULL ) return; + + if (m_FootprintWizard == NULL) + return; m_PageList->Clear(); - - m_PageList->Append(wxT("Pads")); - m_PageList->Append(wxT("Shield")); - + int max_page = m_FootprintWizard->GetNumParameterPages(); + for (int i=0;iGetParameterPageName(i); + m_PageList->Append(name); + } + m_PageList->SetSelection( 0, true ); - /*for( unsigned ii = 0; ii < g_LibraryNames.GetCount(); ii++ ) - { - m_PageList->Append( g_LibraryNames[ii] ); - }*/ - -#if 0 - // Search for a previous selection: - - int index = m_PageList->FindString( m_libraryName ); - - if( index != wxNOT_FOUND ) - { - m_PageList->SetSelection( index, true ); - } - else - { - /* If not found, clear current library selection because it can be - * deleted after a config change. */ - m_libraryName = wxEmptyString; - m_footprintName = wxEmptyString; - } -#endif - + ReCreateParameterList(); ReCreateHToolbar(); DisplayWizardInfos(); m_canvas->Refresh(); @@ -362,19 +354,23 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList() { if( m_ParameterList == NULL ) return; + + if (m_FootprintWizard == NULL ) + return; + + int page = m_PageList->GetSelection(); + + if (page<0) + return; m_ParameterList->Clear(); - wxArrayString fpList; + wxArrayString fpList = m_FootprintWizard->GetParameterNames(page); m_ParameterList->Append( fpList ); - m_ParameterList->Append(wxT("N")); - m_ParameterList->Append(wxT("pitch")); - m_ParameterList->Append(wxT("width")); - m_ParameterList->Append(wxT("height")); m_ParameterList->SetSelection( 0, true ); - //m_ParameterList->SetSelection( index, true ); + } @@ -383,11 +379,7 @@ void FOOTPRINT_WIZARD_FRAME::ClickOnPageList( wxCommandEvent& event ) int ii = m_PageList->GetSelection(); if( ii < 0 ) - return; - - wxString name = m_PageList->GetString( ii ); - - printf("page=%d\n",ii); + return; ReCreateParameterList(); m_canvas->Refresh(); diff --git a/pcbnew/footprint_wizard_frame.h b/pcbnew/footprint_wizard_frame.h index 82777f246a..b4cead97d4 100644 --- a/pcbnew/footprint_wizard_frame.h +++ b/pcbnew/footprint_wizard_frame.h @@ -32,7 +32,7 @@ #include - +#include class wxSashLayoutWindow; class wxListBox; class wxSemaphore; @@ -57,6 +57,8 @@ private: // Flags wxSemaphore* m_Semaphore; // != NULL if the frame must emulate a modal dialog wxString m_configPath; // subpath for configuration + + FOOTPRINT_WIZARD* m_FootprintWizard; protected: wxString m_wizardName; //< name of the current wizard @@ -89,6 +91,8 @@ private: */ void ReCreatePageList(); void ReCreateParameterList(); + void SelectFootprintWizard(); + void Process_Special_Functions( wxCommandEvent& event ); void DisplayWizardInfos(); diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.cpp b/pcbnew/scripting/pcbnew_footprint_wizards.cpp index 83bcb90b1a..7313326a0e 100644 --- a/pcbnew/scripting/pcbnew_footprint_wizards.cpp +++ b/pcbnew/scripting/pcbnew_footprint_wizards.cpp @@ -73,6 +73,13 @@ wxString PYTHON_FOOTPRINT_WIZARD::CallRetStrMethod(const char* aMethod, PyObject return ret; } + +wxArrayString PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod + (const char *aMethod, PyObject *aArglist) +{ + +} + wxString PYTHON_FOOTPRINT_WIZARD::GetName() { return CallRetStrMethod("GetName"); @@ -128,6 +135,23 @@ wxString PYTHON_FOOTPRINT_WIZARD::GetParameterPageName(int aPage) wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterNames(int aPage) { wxArrayString a; + wxString ret; + PyObject *arglist; + PyObject *result; + + /* Time to call the callback */ + arglist = Py_BuildValue("(i)", aPage); + result = CallMethod("GetParameterPageNames",arglist); + Py_DECREF(arglist); + + if (result) + { + + // TODO GET ITEMS IN LIST + const char *str_res = PyString_AsString(result); + ret = wxString::FromUTF8(str_res); + Py_DECREF(result); + } return a; } diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.h b/pcbnew/scripting/pcbnew_footprint_wizards.h index 0e03b44a41..5faca66e31 100644 --- a/pcbnew/scripting/pcbnew_footprint_wizards.h +++ b/pcbnew/scripting/pcbnew_footprint_wizards.h @@ -15,6 +15,9 @@ class PYTHON_FOOTPRINT_WIZARD: public FOOTPRINT_WIZARD PyObject *m_PyWizard; PyObject *CallMethod(const char *aMethod, PyObject *aArglist=NULL); wxString CallRetStrMethod(const char *aMethod, PyObject *aArglist=NULL); + wxArrayString CallRetArrayStrMethod(const char *aMethod, + PyObject *aArglist=NULL); + public: PYTHON_FOOTPRINT_WIZARD(PyObject *wizard); ~PYTHON_FOOTPRINT_WIZARD(); From eff502328788b7f64613fd403c073f71347c6156 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Thu, 10 May 2012 08:44:08 +0200 Subject: [PATCH 34/41] * Read string array results from python methods~ --- pcbnew/pcbnew.cpp | 3 +- pcbnew/scripting/pcbnew_footprint_wizards.cpp | 57 ++++++++++++------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index 926b80d100..e20552f91d 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -204,8 +204,9 @@ Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); */ frame->SetFocus(); frame->GetCanvas()->SetFocus(); - +#if 0 DIALOG_SCRIPTING* sw = new DIALOG_SCRIPTING(frame); sw->Show(true); +#endif return true; } diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.cpp b/pcbnew/scripting/pcbnew_footprint_wizards.cpp index 7313326a0e..f7142a613b 100644 --- a/pcbnew/scripting/pcbnew_footprint_wizards.cpp +++ b/pcbnew/scripting/pcbnew_footprint_wizards.cpp @@ -59,6 +59,8 @@ PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod(const char* aMethod, PyObject *aAr wxString PYTHON_FOOTPRINT_WIZARD::CallRetStrMethod(const char* aMethod, PyObject *aArglist) { wxString ret; + + ret.Clear(); PyObject *result = CallMethod(aMethod,aArglist); if (result) { @@ -66,18 +68,45 @@ wxString PYTHON_FOOTPRINT_WIZARD::CallRetStrMethod(const char* aMethod, PyObject ret = wxString::FromUTF8(str_res); Py_DECREF(result); } - else - { - printf("method not found, or not callable: %s\n",aMethod); - } - return ret; } wxArrayString PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod (const char *aMethod, PyObject *aArglist) { + PyObject *result, *element; + wxArrayString ret; + wxString str_item; + + result = CallMethod(aMethod,aArglist); + + if (result) + { + if (!PyList_Check(result)) + { + Py_DECREF(result); + ret.Add(wxT("PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod, " + "result is not a list"),1); + return ret; + } + int list_size = PyList_Size(result); + + for (int n=0;n Date: Thu, 10 May 2012 10:53:05 +0200 Subject: [PATCH 35/41] Footprint wizard UI gets the module from python wizard, and show it --- .../dialogs/dialog_footprint_wizard_list.cpp | 2 +- pcbnew/footprint_wizard_frame.cpp | 12 ++++++++ pcbnew/scripting/module.i | 19 ++++++++++++ pcbnew/scripting/pcbnew_footprint_wizards.cpp | 30 +++++++++++++++++-- pcbnew/scripting/pcbnew_footprint_wizards.h | 2 ++ .../scripting/plugins/fpc_footprint_wizard.py | 5 +++- 6 files changed, 65 insertions(+), 5 deletions(-) diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.cpp b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp index d93711f0f2..798529aa39 100644 --- a/pcbnew/dialogs/dialog_footprint_wizard_list.cpp +++ b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp @@ -55,7 +55,7 @@ void DIALOG_FOOTPRINT_WIZARD_LIST::OnCellWizardClick( wxGridEvent& event ) { int click_row = event.GetRow(); m_FootprintWizard = FOOTPRINT_WIZARDS::GetWizard(click_row); - + m_footprintWizardsGrid->SelectRow(event.GetRow(),false); } FOOTPRINT_WIZARD* DIALOG_FOOTPRINT_WIZARD_LIST::GetWizard() diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index 0446804350..9c21caa2fa 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -399,6 +399,18 @@ void FOOTPRINT_WIZARD_FRAME::ClickOnParameterList( wxCommandEvent& event ) SetCurItem( NULL ); // Delete the current footprint GetBoard()->m_Modules.DeleteAll(); + MODULE *m = m_FootprintWizard->GetModule(); + if (m) + { + /* Here we should make a copy of the object before adding to board*/ + m->SetParent(GetBoard()); + GetBoard()->m_Modules.Append(m); + } + else + { + printf ("m_FootprintWizard->GetModule() returns NULL\n"); + } + DisplayWizardInfos(); Zoom_Automatique( false ); m_canvas->Refresh(); diff --git a/pcbnew/scripting/module.i b/pcbnew/scripting/module.i index 6443a630cd..0af8f725c6 100644 --- a/pcbnew/scripting/module.i +++ b/pcbnew/scripting/module.i @@ -95,3 +95,22 @@ def FootprintIsWritable(lpath): } + +%{ + MODULE *PyModule_to_MODULE(PyObject *obj0) + { + void *argp; + int res1 = SWIG_ConvertPtr(obj0, &argp,SWIGTYPE_p_MODULE, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + SWIG_exception_fail(SWIG_ArgError(res1), "Converting object to MODULE*"); + } + + return (MODULE*)argp; + + fail: + return NULL; + + } + +%} \ No newline at end of file diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.cpp b/pcbnew/scripting/pcbnew_footprint_wizards.cpp index f7142a613b..c2052ff582 100644 --- a/pcbnew/scripting/pcbnew_footprint_wizards.cpp +++ b/pcbnew/scripting/pcbnew_footprint_wizards.cpp @@ -176,8 +176,14 @@ wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterNames(int aPage) wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterValues(int aPage) { - wxArrayString a; - return a; + PyObject *arglist; + wxArrayString ret; + + arglist = Py_BuildValue("(i)", aPage); + ret = CallRetArrayStrMethod("GetParameterValues",arglist); + Py_DECREF(arglist); + + return ret; } wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues(int aPage,wxArrayString& aValues) @@ -186,9 +192,27 @@ wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues(int aPage,wxArrayString& aV return ret; } +/* this is a SWIG function declaration -from module.i*/ +MODULE *PyModule_to_MODULE(PyObject *obj0); + MODULE *PYTHON_FOOTPRINT_WIZARD::GetModule() { - return NULL; + PyObject *result, *obj; + result = CallMethod("GetModule",NULL); + if (!result) return NULL; + + obj = PyObject_GetAttrString(result, "this"); + if (PyErr_Occurred()) + { + PyObject *t, *v, *b; + PyErr_Fetch(&t, &v, &b); + printf ("calling GetModule()\n"); + printf ("Exception: %s\n",PyString_AsString(PyObject_Str(v))); + printf (" : %s\n",PyString_AsString(PyObject_Str(b))); + } + + + return PyModule_to_MODULE(obj); } diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.h b/pcbnew/scripting/pcbnew_footprint_wizards.h index 5faca66e31..bd951fa4a2 100644 --- a/pcbnew/scripting/pcbnew_footprint_wizards.h +++ b/pcbnew/scripting/pcbnew_footprint_wizards.h @@ -9,6 +9,8 @@ #include #include + + class PYTHON_FOOTPRINT_WIZARD: public FOOTPRINT_WIZARD { diff --git a/pcbnew/scripting/plugins/fpc_footprint_wizard.py b/pcbnew/scripting/plugins/fpc_footprint_wizard.py index 725da1a026..4abd3766fa 100644 --- a/pcbnew/scripting/plugins/fpc_footprint_wizard.py +++ b/pcbnew/scripting/plugins/fpc_footprint_wizard.py @@ -16,11 +16,13 @@ class FPCFootprintWizard(FootprintWizardPlugin): def smdRectPad(self,module,size,pos,name): pad = D_PAD(module) + # print "smdRectPad( size=",size,"pos=",pos,"name=",name,")" pad.SetSize(size) pad.SetShape(PAD_RECT) pad.SetAttribute(PAD_SMD) pad.SetLayerMask(PAD_SMD_DEFAULT_LAYERS) pad.SetPos0(pos) + pad.SetPosition(pos) pad.SetPadName(name) return pad @@ -43,7 +45,7 @@ class FPCFootprintWizard(FootprintWizardPlugin): module = MODULE(None) module.SetReference("FPC"+str(pads)) # give it a reference name module.m_Reference.SetPos0(wxPointMM(-1,-1)) - + module.m_Reference.SetPosition(wxPointMM(-1,-1)) # create a pad array and add it to the module for n in range (0,pads): @@ -75,6 +77,7 @@ class FPCFootprintWizard(FootprintWizardPlugin): module.SetLibRef("FPC"+str(pads)) self.module = module + # print "Module built and set:", module # create our footprint wizard fpc_wizard = FPCFootprintWizard() From 4ead38a83dc0eacc7e17b481621dcda869e20f93 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Thu, 10 May 2012 22:49:07 +0200 Subject: [PATCH 36/41] Cosmetic fixes, before moving to wxGrid --- pcbnew/footprint_wizard.cpp | 30 +++++++++-- pcbnew/footprint_wizard_frame.cpp | 19 ++----- pcbnew/footprint_wizard_frame.h | 1 + pcbnew/scripting/board.i | 16 ++++++ pcbnew/scripting/examples/listPcbLibrary.py | 2 +- .../scripting/plugins/fpc_footprint_wizard.py | 50 +++++++++++-------- 6 files changed, 76 insertions(+), 42 deletions(-) mode change 100644 => 100755 pcbnew/scripting/examples/listPcbLibrary.py diff --git a/pcbnew/footprint_wizard.cpp b/pcbnew/footprint_wizard.cpp index 151f7fd363..485072124c 100644 --- a/pcbnew/footprint_wizard.cpp +++ b/pcbnew/footprint_wizard.cpp @@ -31,11 +31,13 @@ void FOOTPRINT_WIZARD_FRAME::Process_Special_Functions( wxCommandEvent& event ) switch( event.GetId() ) { case ID_FOOTPRINT_WIZARD_NEXT: - //SelectAndViewFootprint( NEXT_PART ); + m_PageList->SetSelection(m_PageList->GetSelection()+1,true); break; case ID_FOOTPRINT_WIZARD_PREVIOUS: - //SelectAndViewFootprint( PREVIOUS_PART ); + int page = m_PageList->GetSelection()-1; + if (page<0) page=0; + m_PageList->SetSelection(page,true); break; default: @@ -76,10 +78,30 @@ void FOOTPRINT_WIZARD_FRAME::DisplayWizardInfos() SetTitle( msg ); } +void FOOTPRINT_WIZARD_FRAME::ReloadFootprint() +{ + SetCurItem( NULL ); + // Delete the current footprint + GetBoard()->m_Modules.DeleteAll(); + MODULE *m = m_FootprintWizard->GetModule(); + if (m) + { + /* Here we should make a copy of the object before adding to board*/ + m->SetParent((EDA_ITEM*)GetBoard()); + GetBoard()->m_Modules.Append(m); + wxPoint p(0,0); + m->SetPosition(p); + } + else + { + printf ("m_FootprintWizard->GetModule() returns NULL\n"); + } + m_canvas->Refresh(); +} void FOOTPRINT_WIZARD_FRAME::SelectFootprintWizard() { - DIALOG_FOOTPRINT_WIZARD_LIST *selectWizard = + DIALOG_FOOTPRINT_WIZARD_LIST *selectWizard = new DIALOG_FOOTPRINT_WIZARD_LIST(this); selectWizard->ShowModal(); @@ -92,6 +114,8 @@ void FOOTPRINT_WIZARD_FRAME::SelectFootprintWizard() m_wizardDescription = m_FootprintWizard->GetDescription(); } + ReloadFootprint(); + Zoom_Automatique(false); DisplayWizardInfos(); ReCreatePageList(); ReCreateParameterList(); diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index 9c21caa2fa..ec3004c02a 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -396,24 +396,11 @@ void FOOTPRINT_WIZARD_FRAME::ClickOnParameterList( wxCommandEvent& event ) wxString name = m_ParameterList->GetString( ii ); - SetCurItem( NULL ); - // Delete the current footprint - GetBoard()->m_Modules.DeleteAll(); - MODULE *m = m_FootprintWizard->GetModule(); - if (m) - { - /* Here we should make a copy of the object before adding to board*/ - m->SetParent(GetBoard()); - GetBoard()->m_Modules.Append(m); - } - else - { - printf ("m_FootprintWizard->GetModule() returns NULL\n"); - } + + ReloadFootprint(); DisplayWizardInfos(); - Zoom_Automatique( false ); - m_canvas->Refresh(); + } diff --git a/pcbnew/footprint_wizard_frame.h b/pcbnew/footprint_wizard_frame.h index b4cead97d4..f544151d27 100644 --- a/pcbnew/footprint_wizard_frame.h +++ b/pcbnew/footprint_wizard_frame.h @@ -92,6 +92,7 @@ private: void ReCreatePageList(); void ReCreateParameterList(); void SelectFootprintWizard(); + void ReloadFootprint(); void Process_Special_Functions( wxCommandEvent& event ); diff --git a/pcbnew/scripting/board.i b/pcbnew/scripting/board.i index 55426db705..e5b51cdef3 100644 --- a/pcbnew/scripting/board.i +++ b/pcbnew/scripting/board.i @@ -94,3 +94,19 @@ return self.ShowShape(self.GetShape()) } } + +%extend BOARD_ITEM +{ + %pythoncode + { + def SetPos(self,p): + self.SetPosition(p) + self.SetPos0(p) + + def SetStartEnd(self,start,end): + self.SetStart(start) + self.SetStart0(start) + self.SetEnd(end) + self.SetEnd0(end) + } +} diff --git a/pcbnew/scripting/examples/listPcbLibrary.py b/pcbnew/scripting/examples/listPcbLibrary.py old mode 100644 new mode 100755 index 10b82bf981..c8a6325f82 --- a/pcbnew/scripting/examples/listPcbLibrary.py +++ b/pcbnew/scripting/examples/listPcbLibrary.py @@ -5,5 +5,5 @@ for name in lst: m = FootprintLoad("/usr/share/kicad/modules/sockets.mod",name) print name,"->",m.GetLibRef(), m.GetReference() for p in m.GetPads(): - print "\t",p.GetPadName(),p.GetPosition(), p.GetOffset() + print "\t",p.GetPadName(),p.GetPosition(),p.GetPos0(), p.GetOffset() \ No newline at end of file diff --git a/pcbnew/scripting/plugins/fpc_footprint_wizard.py b/pcbnew/scripting/plugins/fpc_footprint_wizard.py index 4abd3766fa..a7a9c88ad5 100644 --- a/pcbnew/scripting/plugins/fpc_footprint_wizard.py +++ b/pcbnew/scripting/plugins/fpc_footprint_wizard.py @@ -9,57 +9,61 @@ class FPCFootprintWizard(FootprintWizardPlugin): self.description = "FPC Footprint Wizard" self.parameters = { "Pads": - {"n":40,"pitch":0.5,"width":0.25,"height":1.6}, + {"n":40,"pitch":FromMM(0.5), + "width":FromMM(0.25),"height":FromMM(1.6)}, "Shield": - {"shield_to_pad":1.6,"from_top":1.3,"width":1.5,"height":2} + {"shield_to_pad":FromMM(1.6),"from_top":FromMM(1.3), + "width":FromMM(1.5),"height":FromMM(2)}, + } def smdRectPad(self,module,size,pos,name): pad = D_PAD(module) - # print "smdRectPad( size=",size,"pos=",pos,"name=",name,")" + # print "smdRectPad( size=",size,"pos=",pos,"name=",name,")" pad.SetSize(size) pad.SetShape(PAD_RECT) pad.SetAttribute(PAD_SMD) pad.SetLayerMask(PAD_SMD_DEFAULT_LAYERS) pad.SetPos0(pos) - pad.SetPosition(pos) + pad.SetPosition(pos) pad.SetPadName(name) return pad def BuildFootprint(self): - pads = self.parameters["Pads"]["n"] - pad_width = self.parameters["Pads"]["width"] - pad_height = self.parameters["Pads"]["height"] - pad_pitch = self.parameters["Pads"]["pitch"] - shl_width = self.parameters["Shield"]["width"] - shl_height = self.parameters["Shield"]["height"] - shl_to_pad = self.parameters["Shield"]["shield_to_pad"] - shl_from_top = self.parameters["Shield"]["from_top"] + p = self.parameters + pads = p["Pads"]["n"] + pad_width = p["Pads"]["width"] + pad_height = p["Pads"]["height"] + pad_pitch = p["Pads"]["pitch"] + shl_width = p["Shield"]["width"] + shl_height = p["Shield"]["height"] + shl_to_pad = p["Shield"]["shield_to_pad"] + shl_from_top = p["Shield"]["from_top"] - size_pad = wxSizeMM(pad_width,pad_height) - size_shld = wxSizeMM(shl_width,shl_height) + size_pad = wxSize(pad_width,pad_height) + size_shld = wxSize(shl_width,shl_height) - # create a new module, it's parent is our previously created pcb + # create a new module module = MODULE(None) module.SetReference("FPC"+str(pads)) # give it a reference name - module.m_Reference.SetPos0(wxPointMM(-1,-1)) - module.m_Reference.SetPosition(wxPointMM(-1,-1)) + module.m_Reference.SetPos0(wxPointMM(-1,-2)) + module.m_Reference.SetPosition(wxPointMM(-1,-2)) + # create a pad array and add it to the module - for n in range (0,pads): - pad = self.smdRectPad(module,size_pad,wxPointMM(pad_pitch*n,0),str(n+1)) + pad = self.smdRectPad(module,size_pad,wxPoint(pad_pitch*n,0),str(n+1)) module.Add(pad) pad_s0 = self.smdRectPad(module, size_shld, - wxPointMM(-shl_to_pad,shl_from_top), + wxPoint(-shl_to_pad,shl_from_top), "0") pad_s1 = self.smdRectPad(module, size_shld, - wxPointMM((pads-1)*pad_pitch+shl_to_pad,shl_from_top), + wxPoint((pads-1)*pad_pitch+shl_to_pad,shl_from_top), "0") module.Add(pad_s0) @@ -67,7 +71,9 @@ class FPCFootprintWizard(FootprintWizardPlugin): e = EDGE_MODULE(module) e.SetStart0(wxPointMM(-1,0)) + e.SetStart(wxPointMM(-1,0)) e.SetEnd0(wxPointMM(0,0)) + e.SetEnd(wxPointMM(0,0)) e.SetWidth(FromMM(0.2)) e.SetLayer(EDGE_LAYER) e.SetShape(S_SEGMENT) @@ -77,7 +83,7 @@ class FPCFootprintWizard(FootprintWizardPlugin): module.SetLibRef("FPC"+str(pads)) self.module = module - # print "Module built and set:", module + # print "Module built and set:", module # create our footprint wizard fpc_wizard = FPCFootprintWizard() From 4dc70b2fc80649812f7caf437e73d0011ad2c4f0 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Fri, 11 May 2012 00:30:26 +0200 Subject: [PATCH 37/41] wxGrid instead of list, now we do really have values... --- pcbnew/footprint_wizard.cpp | 3 +- pcbnew/footprint_wizard_frame.cpp | 102 +++++++++++------- pcbnew/footprint_wizard_frame.h | 9 +- .../scripting/plugins/fpc_footprint_wizard.py | 13 ++- scripting/kicadplugins.i | 7 +- 5 files changed, 81 insertions(+), 53 deletions(-) diff --git a/pcbnew/footprint_wizard.cpp b/pcbnew/footprint_wizard.cpp index 485072124c..8bed4f1ed1 100644 --- a/pcbnew/footprint_wizard.cpp +++ b/pcbnew/footprint_wizard.cpp @@ -27,6 +27,7 @@ void FOOTPRINT_WIZARD_FRAME::Process_Special_Functions( wxCommandEvent& event ) { wxString msg; + int page; switch( event.GetId() ) { @@ -35,7 +36,7 @@ void FOOTPRINT_WIZARD_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_FOOTPRINT_WIZARD_PREVIOUS: - int page = m_PageList->GetSelection()-1; + page = m_PageList->GetSelection()-1; if (page<0) page=0; m_PageList->SetSelection(page,true); break; diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index ec3004c02a..c309febdd7 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -42,6 +42,7 @@ #include #include "footprint_wizard_frame.h" #include +#include #include #include @@ -73,7 +74,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_FRAME, EDA_DRAW_FRAME ) /* listbox events */ EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PAGE_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnPageList ) - EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PARAMETER_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnParameterList ) + EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PARAMETER_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnParameterGrid ) EVT_MENU( ID_SET_RELATIVE_OFFSET, FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset ) END_EVENT_TABLE() @@ -111,15 +112,15 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( wxWindow* parent, wxSemaphore* s // Give an icon wxIcon icon; - icon.CopyFromBitmap( KiBitmap( modview_icon_xpm ) ); + icon.CopyFromBitmap( KiBitmap( module_wizard_xpm) ); SetIcon( icon ); m_HotkeysZoomAndGridList = g_Module_Viewer_Hokeys_Descr; m_FootprintWizard = NULL; m_PageList= NULL; - m_ParameterList = NULL; + m_ParameterGrid = NULL; m_PageListWindow = NULL; - m_ParameterListWindow = NULL; + m_ParameterGridWindow = NULL; m_Semaphore = semaphore; m_wizardName.Empty(); @@ -160,22 +161,21 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( wxWindow* parent, wxSemaphore* s 0, NULL, wxLB_HSCROLL ); // Creates the component window display - m_ParameterListSize.y = size.y; + m_ParameterGridSize.y = size.y; win_pos.x = m_PageListSize.x; - m_ParameterListWindow = new wxSashLayoutWindow( this, + m_ParameterGridWindow = new wxSashLayoutWindow( this, ID_FOOTPRINT_WIZARD_PARAMETERS_WINDOW, win_pos, wxDefaultSize, wxCLIP_CHILDREN | wxSW_3D, wxT( "ParameterList" ) ); - m_ParameterListWindow->SetOrientation( wxLAYOUT_VERTICAL ); - - m_ParameterListWindow->SetSashVisible( wxSASH_RIGHT, true ); - m_ParameterListWindow->SetExtraBorderSize( EXTRA_BORDER_SIZE ); - m_ParameterList = new wxListBox( m_ParameterListWindow, ID_FOOTPRINT_WIZARD_PARAMETER_LIST, - wxPoint( 0, 0 ), wxDefaultSize, - 0, NULL, wxLB_HSCROLL ); + m_ParameterGridWindow->SetOrientation( wxLAYOUT_VERTICAL ); + m_ParameterGridWindow->SetSashVisible( wxSASH_RIGHT, true ); + m_ParameterGridWindow->SetExtraBorderSize( EXTRA_BORDER_SIZE ); + m_ParameterGrid = new wxGrid(m_ParameterGridWindow,ID_FOOTPRINT_WIZARD_PARAMETER_LIST, + wxPoint(0,0),wxDefaultSize); + ReCreatePageList(); DisplayWizardInfos(); @@ -211,8 +211,8 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( wxWindow* parent, wxSemaphore* s Left().Row( 0 )); // Manage the list of parameters) - m_auimgr.AddPane( m_ParameterListWindow, - wxAuiPaneInfo( info ).Name( wxT( "m_ParameterList" ) ). + m_auimgr.AddPane( m_ParameterGridWindow, + wxAuiPaneInfo( info ).Name( wxT( "m_ParameterGrid" ) ). Left().Row( 1 ) ); // Manage the draw panel @@ -231,8 +231,8 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( wxWindow* parent, wxSemaphore* s wxAuiPaneInfo& pane = m_auimgr.GetPane(m_PageListWindow); pane.MinSize( wxSize(m_PageListSize.x, -1)); } - wxAuiPaneInfo& pane = m_auimgr.GetPane(m_ParameterListWindow); - pane.MinSize(wxSize(m_ParameterListSize.x, -1)); + wxAuiPaneInfo& pane = m_auimgr.GetPane(m_ParameterGridWindow); + pane.MinSize(wxSize(m_ParameterGridSize.x, -1)); m_auimgr.Update(); @@ -283,7 +283,7 @@ void FOOTPRINT_WIZARD_FRAME::OnSashDrag( wxSashEvent& event ) return; m_PageListSize.y = GetClientSize().y - m_MsgFrameHeight; - m_ParameterListSize.y = m_PageListSize.y; + m_ParameterGridSize.y = m_PageListSize.y; switch( event.GetId() ) { @@ -299,9 +299,9 @@ void FOOTPRINT_WIZARD_FRAME::OnSashDrag( wxSashEvent& event ) case ID_FOOTPRINT_WIZARD_PARAMETERS_WINDOW: { - wxAuiPaneInfo& pane = m_auimgr.GetPane( m_ParameterListWindow ); - m_ParameterListSize.x = event.GetDragRect().width; - pane.MinSize( m_ParameterListSize ); + wxAuiPaneInfo& pane = m_auimgr.GetPane( m_ParameterGridWindow ); + m_ParameterGridSize.x = event.GetDragRect().width; + pane.MinSize( m_ParameterGridSize ); m_auimgr.Update(); } break; @@ -352,7 +352,7 @@ void FOOTPRINT_WIZARD_FRAME::ReCreatePageList() void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList() { - if( m_ParameterList == NULL ) + if( m_ParameterGrid == NULL ) return; if (m_FootprintWizard == NULL ) @@ -363,13 +363,38 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList() if (page<0) return; - m_ParameterList->Clear(); + m_ParameterGrid->ClearGrid(); + + + // Columns + m_ParameterGrid->AutoSizeColumns(); + m_ParameterGrid->SetColLabelSize( 20 ); + m_ParameterGrid->SetColLabelValue( 0, _("Parameter") ); + m_ParameterGrid->SetColLabelValue( 1, _("Value") ); + m_ParameterGrid->SetColLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE ); + + + // Rows + m_ParameterGrid->AutoSizeRows(); + m_ParameterGrid->EnableDragRowSize( true ); + m_ParameterGrid->SetRowLabelSize( 1 ); + m_ParameterGrid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + wxArrayString fpList = m_FootprintWizard->GetParameterNames(page); + wxArrayString fvList = m_FootprintWizard->GetParameterValues(page); + + m_ParameterGrid->CreateGrid(fpList.size(),2); + + for (unsigned int i=0;iSetCellValue( i, 0, fpList[i] ); + m_ParameterGrid->SetReadOnly( i, 0 ); + m_ParameterGrid->SetCellValue( i, 1 , fvList[i] ); + } + m_ParameterGrid->AutoSizeColumns(); - m_ParameterList->Append( fpList ); - m_ParameterList->SetSelection( 0, true ); - } @@ -387,15 +412,14 @@ void FOOTPRINT_WIZARD_FRAME::ClickOnPageList( wxCommandEvent& event ) } -void FOOTPRINT_WIZARD_FRAME::ClickOnParameterList( wxCommandEvent& event ) +void FOOTPRINT_WIZARD_FRAME::ClickOnParameterGrid( wxCommandEvent& event ) { - int ii = m_ParameterList->GetSelection(); - - if( ii < 0 ) - return; - - wxString name = m_ParameterList->GetString( ii ); - + int n=m_ParameterGrid->GetNumberRows(); + + for (int i=0;iRead( PARTLIST_WIDTH_KEY , &m_PageListSize.x ); - cfg->Read( PARAMLIST_WIDTH_KEY, &m_ParameterListSize.x ); + cfg->Read( PARAMLIST_WIDTH_KEY, &m_ParameterGridSize.x ); // Set parameters to a reasonable value. if ( m_PageListSize.x > m_FrameSize.x/2 ) m_PageListSize.x = m_FrameSize.x/2; - if ( m_ParameterListSize.x > m_FrameSize.x/2 ) - m_ParameterListSize.x = m_FrameSize.x/2; + if ( m_ParameterGridSize.x > m_FrameSize.x/2 ) + m_ParameterGridSize.x = m_FrameSize.x/2; } @@ -444,7 +468,7 @@ void FOOTPRINT_WIZARD_FRAME::SaveSettings() if ( m_PageListSize.x ) cfg->Write( PARTLIST_WIDTH_KEY, m_PageListSize.x ); - cfg->Write( PARAMLIST_WIDTH_KEY, m_ParameterListSize.x ); + cfg->Write( PARAMLIST_WIDTH_KEY, m_ParameterGridSize.x ); } diff --git a/pcbnew/footprint_wizard_frame.h b/pcbnew/footprint_wizard_frame.h index f544151d27..47747518f9 100644 --- a/pcbnew/footprint_wizard_frame.h +++ b/pcbnew/footprint_wizard_frame.h @@ -36,6 +36,7 @@ class wxSashLayoutWindow; class wxListBox; class wxSemaphore; +class wxGrid; /** @@ -50,9 +51,9 @@ private: wxSize m_PageListSize; // size of the window // List of components in the selected library - wxSashLayoutWindow* m_ParameterListWindow; - wxListBox* m_ParameterList; // The list of parameters - wxSize m_ParameterListSize; // size of the window + wxSashLayoutWindow* m_ParameterGridWindow; + wxGrid* m_ParameterGrid; // The list of parameters + wxSize m_ParameterGridSize; // size of the window // Flags wxSemaphore* m_Semaphore; // != NULL if the frame must emulate a modal dialog @@ -103,7 +104,7 @@ private: void ReCreateVToolbar(); void OnLeftClick( wxDC* DC, const wxPoint& MousePos ); void ClickOnPageList( wxCommandEvent& event ); - void ClickOnParameterList( wxCommandEvent& event ); + void ClickOnParameterGrid( wxCommandEvent& event ); void OnSetRelativeOffset( wxCommandEvent& event ); void GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 ); diff --git a/pcbnew/scripting/plugins/fpc_footprint_wizard.py b/pcbnew/scripting/plugins/fpc_footprint_wizard.py index a7a9c88ad5..2ae147c34c 100644 --- a/pcbnew/scripting/plugins/fpc_footprint_wizard.py +++ b/pcbnew/scripting/plugins/fpc_footprint_wizard.py @@ -17,6 +17,14 @@ class FPCFootprintWizard(FootprintWizardPlugin): } + def GetParameterValues(self,page_n): + name = self.GetParameterPageName(page_n) + values = self.parameters[name].values() + str_values = map( lambda x: str(x) , values) + + print values,str_values + return str_values + def smdRectPad(self,module,size,pos,name): pad = D_PAD(module) # print "smdRectPad( size=",size,"pos=",pos,"name=",name,")" @@ -70,10 +78,7 @@ class FPCFootprintWizard(FootprintWizardPlugin): module.Add(pad_s1) e = EDGE_MODULE(module) - e.SetStart0(wxPointMM(-1,0)) - e.SetStart(wxPointMM(-1,0)) - e.SetEnd0(wxPointMM(0,0)) - e.SetEnd(wxPointMM(0,0)) + e.SetStartEnd(wxPointMM(-1,0),wxPointMM(0,0)) e.SetWidth(FromMM(0.2)) e.SetLayer(EDGE_LAYER) e.SetShape(S_SEGMENT) diff --git a/scripting/kicadplugins.i b/scripting/kicadplugins.i index 5f1147604b..99d34b94ca 100644 --- a/scripting/kicadplugins.i +++ b/scripting/kicadplugins.i @@ -84,14 +84,11 @@ class FootprintWizardPlugin(KiCadPlugin): def GetParameterNames(self,page_n): name = self.GetParameterPageName(page_n) return self.parameters[name].keys() - - def GetParameterValues(self,page_n): - name = self.GetParameterPageName(page_n) - return self.parameters[name].keys() def GetParameterValues(self,page_n): name = self.GetParameterPageName(page_n) - return self.parameters[name].values() + values = self.parameters[name].values() + return map( lambda x: str(x) , values) def SetParameterValues(self,page_n,values): From 70df15175b50254c8856964e51851fbec0e0e782 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Wed, 16 May 2012 11:35:18 +0200 Subject: [PATCH 38/41] Footprint wizard, plus fixes --- pcbnew/CMakeLists.txt | 1 + pcbnew/class_footprint_wizard.h | 1 + .../dialogs/dialog_footprint_wizard_list.cpp | 3 ++ pcbnew/footprint_wizard.cpp | 45 +++++++++---------- pcbnew/footprint_wizard_frame.cpp | 17 +------ pcbnew/footprint_wizard_frame.h | 4 +- pcbnew/scripting/module.i | 5 ++- pcbnew/scripting/pcbnew_footprint_wizards.cpp | 40 ++++++++++++++++- pcbnew/scripting/pcbnew_footprint_wizards.h | 4 +- .../scripting/plugins/fpc_footprint_wizard.py | 40 ++++++++++++++--- scripting/kicadplugins.i | 45 ++++++++++++++++--- 11 files changed, 145 insertions(+), 60 deletions(-) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 8ed2faa588..d8efdd592e 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -290,6 +290,7 @@ if (KICAD_SCRIPTING) DEPENDS ../scripting/dlist.i DEPENDS ../scripting/kicad.i DEPENDS ../scripting/wx.i + DEPENDS ../scripting/kicadplugins.i # DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/pcbnew COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx scripting/pcbnew.i diff --git a/pcbnew/class_footprint_wizard.h b/pcbnew/class_footprint_wizard.h index 2972aa55c9..97b2a6c4d2 100644 --- a/pcbnew/class_footprint_wizard.h +++ b/pcbnew/class_footprint_wizard.h @@ -23,6 +23,7 @@ public: virtual wxString GetParameterPageName(int aPage)=0; virtual wxArrayString GetParameterNames(int aPage)=0; virtual wxArrayString GetParameterValues(int aPage)=0; + virtual wxArrayString GetParameterErrors(int aPage)=0; virtual wxString SetParameterValues(int aPage,wxArrayString& aValues)=0; virtual MODULE *GetModule()=0; void register_wizard(); diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.cpp b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp index 798529aa39..53e8ab3c36 100644 --- a/pcbnew/dialogs/dialog_footprint_wizard_list.cpp +++ b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp @@ -28,6 +28,9 @@ DIALOG_FOOTPRINT_WIZARD_LIST::DIALOG_FOOTPRINT_WIZARD_LIST( wxWindow* aParent ) m_FootprintWizard = FOOTPRINT_WIZARDS::GetWizard(0); // Choose selection mode and insert the needed rows + + m_footprintWizardsGrid->SetColSize( 0, 0 ); // hide the preview for now + m_footprintWizardsGrid->SetSelectionMode(wxGrid::wxGridSelectRows); m_footprintWizardsGrid->InsertRows(0,n_wizards,true); diff --git a/pcbnew/footprint_wizard.cpp b/pcbnew/footprint_wizard.cpp index 8bed4f1ed1..51a50c93b6 100644 --- a/pcbnew/footprint_wizard.cpp +++ b/pcbnew/footprint_wizard.cpp @@ -134,31 +134,28 @@ void FOOTPRINT_WIZARD_FRAME::SelectCurrentWizard( wxCommandEvent& event ) * Function SelectCurrentFootprint * Selects the current footprint name and display it */ -void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxCommandEvent& event ) +void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event ) { - /* - // will pick it from the wizard - MODULE * module = new MODULE(NULL); - if( module ) - { - module->SetPosition( wxPoint( 0, 0 ) ); - - // Only one fotprint allowed: remove the previous footprint (if exists) - if( oldmodule ) - { - GetBoard()->Remove( oldmodule ); - delete oldmodule; - } - m_footprintName = module->GetLibRef(); - module->ClearFlags(); - SetCurItem( NULL ); - - Zoom_Automatique( false ); - m_canvas->Refresh( ); - Update3D_Frame(); - m_FootprintList->SetStringSelection( m_footprintName ); - } - * */ + + int page = m_PageList->GetSelection(); + + if (page<0) + return; + + int n=m_ParameterGrid->GetNumberRows(); + wxArrayString arr; + + for (int i=0;iGetCellValue(i,1); + arr.Add(val); + } + + wxString res = m_FootprintWizard->SetParameterValues(page,arr); + + ReloadFootprint(); + DisplayWizardInfos(); + } diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index c309febdd7..9e612ea390 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -74,7 +74,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_FRAME, EDA_DRAW_FRAME ) /* listbox events */ EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PAGE_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnPageList ) - EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PARAMETER_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnParameterGrid ) + EVT_GRID_CMD_CELL_CHANGE( ID_FOOTPRINT_WIZARD_PARAMETER_LIST, FOOTPRINT_WIZARD_FRAME::ParametersUpdated ) EVT_MENU( ID_SET_RELATIVE_OFFSET, FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset ) END_EVENT_TABLE() @@ -412,21 +412,6 @@ void FOOTPRINT_WIZARD_FRAME::ClickOnPageList( wxCommandEvent& event ) } -void FOOTPRINT_WIZARD_FRAME::ClickOnParameterGrid( wxCommandEvent& event ) -{ - int n=m_ParameterGrid->GetNumberRows(); - - for (int i=0;i Date: Wed, 27 Jun 2012 23:19:19 +0200 Subject: [PATCH 39/41] code cleanup and comments --- pcbnew/class_footprint_wizard.cpp | 12 --- pcbnew/class_footprint_wizard.h | 90 ++++++++++++++++++ pcbnew/footprint_wizard.cpp | 13 ++- pcbnew/footprint_wizard_frame.cpp | 33 ++++++- pcbnew/scripting/TODO.txt | 21 +---- pcbnew/scripting/units.i | 20 ++-- scripting/python_scripting.cpp | 109 +++++++++++++--------- scripting/python_scripting.h | 6 +- scripting/wx_python_helpers.cpp | 146 +++++++++++++++++------------- scripting/wx_python_helpers.h | 12 +-- 10 files changed, 300 insertions(+), 162 deletions(-) diff --git a/pcbnew/class_footprint_wizard.cpp b/pcbnew/class_footprint_wizard.cpp index cabc5a2268..fd76899b54 100644 --- a/pcbnew/class_footprint_wizard.cpp +++ b/pcbnew/class_footprint_wizard.cpp @@ -46,18 +46,6 @@ void FOOTPRINT_WIZARDS::register_wizard(FOOTPRINT_WIZARD *aWizard) m_FootprintWizards.push_back(aWizard); printf("Registered footprint wizard '%s'\n",(const char*)name.mb_str() ); - -#if 0 - /* just to test if it works correctly */ - int pages = fw->GetNumParameterPages(); - printf(" %d pages\n",pages); - - for (int n=0; n'%s'\n",n, - (const char*)fw->GetParameterPageName(n).mb_str()); - } -#endif } diff --git a/pcbnew/class_footprint_wizard.h b/pcbnew/class_footprint_wizard.h index 97b2a6c4d2..08a9d049bf 100644 --- a/pcbnew/class_footprint_wizard.h +++ b/pcbnew/class_footprint_wizard.h @@ -16,16 +16,80 @@ class FOOTPRINT_WIZARD public: FOOTPRINT_WIZARD() {} ~FOOTPRINT_WIZARD() {} + + /** + * Function GetName + * @return the name of the wizard + */ virtual wxString GetName()=0; + + /** + * Function GetImage + * @return an svg image of the wizard to be rendered + */ virtual wxString GetImage()=0; + + /** + * Function GetDescription + * @return a description of the footprint wizard + */ virtual wxString GetDescription()=0; + + /** + * Function GetNumParameterPages + * @return the number of parameter pages that this wizard will show to the user + */ virtual int GetNumParameterPages()=0; + + /** + * Function GetParameterPageName + * @param aPage is the page we want the name of + * @return a string with the page name + */ virtual wxString GetParameterPageName(int aPage)=0; + + /** + * Function GetParameterNames + * @param aPage is the page we want the parameter names of + * @return an array string with the parameter names on a certain page + */ virtual wxArrayString GetParameterNames(int aPage)=0; + + /** + * Function GetParameterValues + * @param aPage is the page we want the parameter values of + * @return an array of parameter values + */ virtual wxArrayString GetParameterValues(int aPage)=0; + + /** + * Function GetParameterErrors + * @param aPAge is the page we want to know the errors of + * @return an array of errors (if any) for the parameters, empty strings for OK parameters + */ virtual wxArrayString GetParameterErrors(int aPage)=0; + + /** + * Function SetParameterValues + * @param aPage is the page we want to set the parameters in + * @param aValues are the values we want to set into the parameters + * @return an array of parameter values + */ virtual wxString SetParameterValues(int aPage,wxArrayString& aValues)=0; + + /** + * Function GetModule + * This method builds the module itself and returns it to the caller function + * @return PCB module built from the parameters given to the class + */ virtual MODULE *GetModule()=0; + + /** + * Function register_wizard + * It's the standard method of a "FOOTPRINT_WIZARD" to register itself into + * the FOOTPRINT_WIZARDS singleton manager + * + */ void register_wizard(); }; @@ -37,9 +101,35 @@ private: static std::vector m_FootprintWizards; public: + + /** + * Function register_wizard + * A footprint wizard calls this static method when it wants to register itself + * into the system wizards + * + * @param aWizard is the footprint wizard to be registered + * + */ static void register_wizard(FOOTPRINT_WIZARD *wizard); + + /** + * Function GetWizard + * @return a wizard object by it's name or NULL if it isn't available. + * + */ static FOOTPRINT_WIZARD* GetWizard(wxString aName); + + /** + * Function GetWizard + * @return a wizard object by it's number or NULL if it isn't available. + * + */ static FOOTPRINT_WIZARD* GetWizard(int aIndex); + + /** + * Function GetSize + * @return the number of wizards available into the system + */ static int GetSize(); }; diff --git a/pcbnew/footprint_wizard.cpp b/pcbnew/footprint_wizard.cpp index 51a50c93b6..74c16f74b4 100644 --- a/pcbnew/footprint_wizard.cpp +++ b/pcbnew/footprint_wizard.cpp @@ -1,5 +1,5 @@ /** - * @file footprint wizard.cpp + * @file footprint_wizard.cpp */ #include @@ -49,12 +49,18 @@ void FOOTPRINT_WIZARD_FRAME::Process_Special_Functions( wxCommandEvent& event ) } } - +/* Function OnLeftClick + * Captures a left click event in the dialog + * + */ void FOOTPRINT_WIZARD_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) { } - +/* Function OnRightClick + * Captures a right click event in the dialog + * + */ bool FOOTPRINT_WIZARD_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ) { return true; @@ -163,6 +169,7 @@ void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event ) * Function RedrawActiveWindow * Display the current selected component. * If the component is an alias, the ROOT component is displayed + * */ void FOOTPRINT_WIZARD_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) { diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index 9e612ea390..d795d85816 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -1,6 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. - * + * + * Copyright (C) 2012 Miguel Angel Ajo Pelayo * Copyright (C) 2012 Jean-Pierre Charras, jaen-pierre.charras * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. @@ -99,7 +100,10 @@ static wxAcceleratorEntry accels[] = #define EXTRA_BORDER_SIZE 2 - +/* Function FOOTPRINT_WIZARD_FRAME + * it's the constructor for the footprint wizard frame, it creates everything inside + * + */ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( wxWindow* parent, wxSemaphore* semaphore ) : PCB_BASE_FRAME( parent, MODULE_VIEWER_FRAME, _( "Footprint Wizard" ), wxDefaultPosition, wxDefaultSize ) @@ -259,6 +263,10 @@ FOOTPRINT_WIZARD_FRAME::~FOOTPRINT_WIZARD_FRAME() } +/* Function OnCloseWindow + * Handles the close event, saving settings an destroying or releasing a semaphore from caller + * + */ void FOOTPRINT_WIZARD_FRAME::OnCloseWindow( wxCloseEvent& Event ) { SaveSettings(); @@ -277,6 +285,9 @@ void FOOTPRINT_WIZARD_FRAME::OnCloseWindow( wxCloseEvent& Event ) } +/* Function OnSashDrag + * handles the horizontal separator (sash) drag, updating the pagelist or parameter list + */ void FOOTPRINT_WIZARD_FRAME::OnSashDrag( wxSashEvent& event ) { if( event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE ) @@ -309,6 +320,10 @@ void FOOTPRINT_WIZARD_FRAME::OnSashDrag( wxSashEvent& event ) } +/* Function OnSize + * It handles a dialog resize event, asking for an update + * + */ void FOOTPRINT_WIZARD_FRAME::OnSize( wxSizeEvent& SizeEv ) { if( m_auimgr.GetManagedWindow() ) @@ -317,14 +332,20 @@ void FOOTPRINT_WIZARD_FRAME::OnSize( wxSizeEvent& SizeEv ) SizeEv.Skip(); } - +/* Function OnSetRelativeOffset + * Updates the cursor position and the status bar + * + */ void FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset( wxCommandEvent& event ) { GetScreen()->m_O_Curseur = GetScreen()->GetCrossHairPosition(); UpdateStatusBar(); } - +/* Function ReCreatePageList + * It recreates the list of pages for a new loaded wizard + * + */ void FOOTPRINT_WIZARD_FRAME::ReCreatePageList() { if( m_PageList == NULL ) @@ -349,6 +370,10 @@ void FOOTPRINT_WIZARD_FRAME::ReCreatePageList() m_canvas->Refresh(); } +/* Function ReCreateParameterList + * It creates the parameter grid for a certain wizard page of the current wizard + * + */ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList() { diff --git a/pcbnew/scripting/TODO.txt b/pcbnew/scripting/TODO.txt index f92f806674..3c7adaabe7 100644 --- a/pcbnew/scripting/TODO.txt +++ b/pcbnew/scripting/TODO.txt @@ -1,20 +1,5 @@ -* Implement iterator for NETCLASSES (NETCLASS) see class_netclass.h - -* Saving modules to library (in librairi.cpp) - - see: - - void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewModulesOnly ) - - - - bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName, - MODULE* aModule, - bool aOverwrite, - bool aDisplayDialog ) - - What do we do about this?, ask Dick, these functions should be transplanted - to kicad plugin? - - - void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewModulesOnly ) +* finish wizard implementation +* cleanup +* better build script helpers diff --git a/pcbnew/scripting/units.i b/pcbnew/scripting/units.i index f496b42e7b..66ff1f4d69 100644 --- a/pcbnew/scripting/units.i +++ b/pcbnew/scripting/units.i @@ -40,40 +40,40 @@ def FromMM(iu): if type(iu) in [int,float]: - return int(iu / 0.00254) + return iu / 0.00254 elif type(iu) in [wxPoint,wxSize]: return tuple(map(FromMM,iu)) def ToMils(iu): if type(iu) in [int,float]: - return int(iu / 10.0) + return iu / 10.0 elif type(iu) in [wxPoint,wxSize]: return tuple(map(ToMils,iu)) def FromMils(iu): if type(iu) in [int,float]: - return int(iu*10.0) + return iu*10.0 elif type(iu) in [wxPoint,wxSize]: return tuple(map(FromMils,iu)) - def wxSizeMM(mmx,mmy): return wxSize(FromMM(mmx),FromMM(mmy)) - def wxSizeMils(mmx,mmy): return wxSize(FromMils(mmx),FromMils(mmy)) + def SizeMM(mmx,mmy): return wxSize(FromMM(mmx),FromMM(mmy)) + def SizeMils(mmx,mmy): return wxSize(FromMils(mmx),FromMils(mmy)) - def wxPointMM(mmx,mmy): return wxPoint(FromMM(mmx),FromMM(mmy)) - def wxPointMils(mmx,mmy): return wxPoint(FromMils(mmx),FromMils(mmy)) + def PointMM(mmx,mmy): return wxPoint(FromMM(mmx),FromMM(mmy)) + def PointMils(mmx,mmy): return wxPoint(FromMils(mmx),FromMils(mmy)) - def wxRectMM(x,y,wx,wy): + def RectMM(x,y,wx,wy): x = int(FromMM(x)) y = int(FromMM(y)) wx = int(FromMM(wx)) wy = int (FromMM(wy)) return wxRect(x,y,wx,wy) - def wxRectMils(x,y,wx,wy): + def RectMils(x,y,wx,wy): x = int(FromMils(x)) y = int(FromMils(y)) wx = int(FromMils(wx)) wy = int (FromMils(wy)) return wxRect(x,y,wx,wy) -} \ No newline at end of file +} diff --git a/scripting/python_scripting.cpp b/scripting/python_scripting.cpp index 8abd092e24..2b1ca6b18d 100644 --- a/scripting/python_scripting.cpp +++ b/scripting/python_scripting.cpp @@ -28,79 +28,104 @@ */ #include +#include +#include /* init functions defined by swig */ -extern "C" void init_kicad(void); -extern "C" void init_pcbnew(void); +extern "C" void init_kicad( void ); + +extern "C" void init_pcbnew( void ); + +#define EXTRA_PYTHON_MODULES 2 // this is the number of python + // modules that we want to add into the list -/* python inittab that links module names to module init functions +/* python inittab that links module names to module init functions * we will rebuild it to include the original python modules plus - * our own ones + * our own ones */ -struct _inittab SwigImportInittab[1000]; -static int SwigNumModules = 0; +struct _inittab *SwigImportInittab; +static int SwigNumModules = 0; /* Add a name + initfuction to our SwigImportInittab */ -static void swigAddModule(const char *name, void (*initfunc)()) +static void swigAddModule( const char* name, void (* initfunc)() ) { - SwigImportInittab[SwigNumModules].name = (char *)name; - SwigImportInittab[SwigNumModules].initfunc = initfunc; - SwigNumModules++; - SwigImportInittab[SwigNumModules].name = (char *) 0; - SwigImportInittab[SwigNumModules].initfunc = 0; + SwigImportInittab[SwigNumModules].name = (char*) name; + SwigImportInittab[SwigNumModules].initfunc = initfunc; + SwigNumModules++; + SwigImportInittab[SwigNumModules].name = (char*) 0; + SwigImportInittab[SwigNumModules].initfunc = 0; } + /* Add the builting python modules */ -static void swigAddBuiltin() +static void swigAddBuiltin() { - int i = 0; - while (PyImport_Inittab[i].name) { - swigAddModule(PyImport_Inittab[i].name, PyImport_Inittab[i].initfunc); - i++; - } + int i = 0; + while( PyImport_Inittab[i].name ) + { + i++; + } + + SwigImportInittab = (struct _inittab*) malloc( + sizeof(struct _inittab)*(i+EXTRA_PYTHON_MODULES)); + + while( PyImport_Inittab[i].name ) + { + swigAddModule( PyImport_Inittab[i].name, PyImport_Inittab[i].initfunc ); + i++; + } } + +/* Function swigAddModules + * adds the internal modules we offer to the python scripting, so they will be + * available to the scripts we run. + * + */ + static void swigAddModules() { - swigAddModule("_pcbnew",init_pcbnew); - - // finally it seems better to include all in just one module - // but in case we needed to include any other modules, - // it must be done like this: - // swigAddModule("_kicad",init_kicad); - + swigAddModule( "_pcbnew", init_pcbnew ); + + // finally it seems better to include all in just one module + // but in case we needed to include any other modules, + // it must be done like this: + // swigAddModule("_kicad",init_kicad); } +/* Function swigSwitchPythonBuiltin + * switches python module table to our built one . + * + */ + static void swigSwitchPythonBuiltin() { - PyImport_Inittab = SwigImportInittab; + PyImport_Inittab = SwigImportInittab; } - - +/* Function pcbnewInitPythonScripting + * Initializes all the python environment and publish our interface inside it + * + */ void pcbnewInitPythonScripting() { - swigAddBuiltin(); - swigAddModules(); - swigSwitchPythonBuiltin(); - - Py_Initialize(); + swigAddBuiltin(); // add builtin functions + swigAddModules(); // add our own modules + swigSwitchPythonBuiltin(); // switch the python builtin modules to our new list - /* setup the scripting path, we may need to add the installation path - of kicad here */ + Py_Initialize(); // call the python library to get it initialized - PyRun_SimpleString("import sys\n" - "sys.path.append(\".\")\n" - "import pcbnew\n" - "pcbnew.LoadPlugins()" + // load pcbnew inside python, and load all the user plugins, TODO: add system wide plugins + + PyRun_SimpleString( "import sys\n" + "sys.path.append(\".\")\n" + "import pcbnew\n" + "pcbnew.LoadPlugins()" ); - - } - \ No newline at end of file diff --git a/scripting/python_scripting.h b/scripting/python_scripting.h index 32dfd2278d..9ebafd0126 100644 --- a/scripting/python_scripting.h +++ b/scripting/python_scripting.h @@ -3,6 +3,10 @@ #include -void pcbnewInitPythonScripting(void); +/* Function pcbnewInitPythonScripting + * Initializes the Python engine inside pcbnew + */ + +void pcbnewInitPythonScripting( void ); #endif diff --git a/scripting/wx_python_helpers.cpp b/scripting/wx_python_helpers.cpp index 777fc014c4..ec01a396c8 100644 --- a/scripting/wx_python_helpers.cpp +++ b/scripting/wx_python_helpers.cpp @@ -33,141 +33,157 @@ #include - #define WX_DEFAULTENCODING_SIZE 64 static char wxPythonEncoding[WX_DEFAULTENCODING_SIZE] = "ascii"; -PyObject* wxArrayString2PyList(const wxArrayString& lst) +PyObject* wxArrayString2PyList( const wxArrayString& lst ) { - PyObject* list = PyList_New(0); - for (size_t i=0; i < lst.GetCount(); i++) { + PyObject* list = PyList_New( 0 ); + + for( size_t i = 0; i < lst.GetCount(); i++ ) + { #if wxUSE_UNICODE - PyObject* pyStr = PyUnicode_FromWideChar(lst[i].c_str(), - lst[i].Len() - ); + PyObject* pyStr = PyUnicode_FromWideChar( lst[i].c_str(), + lst[i].Len() + ); #else - PyObject* pyStr = PyString_FromStringAndSize(lst[i].c_str(), - lst[i].Len() - ); + PyObject* pyStr = PyString_FromStringAndSize( lst[i].c_str(), + lst[i].Len() + ); #endif - PyList_Append(list, pyStr); - Py_DECREF(pyStr); + PyList_Append( list, pyStr ); + Py_DECREF( pyStr ); } + return list; } +wxString* newWxStringFromPy( PyObject* src ) +{ + bool must_unref_str = false; -wxString* newWxStringFromPy(PyObject* src) { - - bool must_unref_str=false; - - wxString* result = NULL; - PyObject *obj=src; + wxString* result = NULL; + PyObject* obj = src; #if wxUSE_UNICODE - bool must_unref_obj=false; - // Unicode string to python unicode string - PyObject* uni_str = src; + 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)) + if( !PyString_Check( src ) && !PyUnicode_Check( src ) ) { - obj = PyObject_Str(src); - must_unref_obj = true; - if (PyErr_Occurred()) return NULL; + obj = PyObject_Str( src ); + must_unref_obj = true; + + if( PyErr_Occurred() ) + return NULL; } - if (PyString_Check(obj)) + if( PyString_Check( obj ) ) { - uni_str = PyUnicode_FromEncodedObject(obj, wxPythonEncoding, "strict"); + uni_str = PyUnicode_FromEncodedObject( obj, wxPythonEncoding, "strict" ); must_unref_str = true; - if (PyErr_Occurred()) return NULL; + + if( PyErr_Occurred() ) + return NULL; } result = new wxString(); - size_t len = PyUnicode_GET_SIZE(uni_str); - if (len) + size_t len = PyUnicode_GET_SIZE( uni_str ); + + if( len ) { - PyUnicode_AsWideChar((PyUnicodeObject*)uni_str, - wxStringBuffer(*result, len),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); + if( must_unref_str ) + Py_DECREF( uni_str ); + + if( must_unref_obj ) + Py_DECREF( obj ); + #else - // normal string (or object) to normal python string + // normal string (or object) to normal python string PyObject* str = src; - if (PyUnicode_Check(src)) // if it's unicode convert to normal string + if( PyUnicode_Check( src ) ) // if it's unicode convert to normal string { - str = PyUnicode_AsEncodedString(src, wxPythonEncoding, "strict"); - if (PyErr_Occurred()) return NULL; + str = PyUnicode_AsEncodedString( src, wxPythonEncoding, "strict" ); + + if( PyErr_Occurred() ) + return NULL; } - else if (!PyString_Check(src)) // if it's not a string, str(obj) + 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; + 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); + 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); + result = new wxString( str_ptr, str_size ); - if (must_unref_str) Py_DECREF(str); -#endif + if( must_unref_str ) + Py_DECREF( str ); + +#endif return result; } -wxString Py2wxString(PyObject* src) +wxString Py2wxString( PyObject* src ) { - wxString result; - wxString* resPtr = newWxStringFromPy(src); - - // In case of exception clear it and return an empty string - if (resPtr==NULL) + wxString result; + wxString* resPtr = newWxStringFromPy( src ); + + // In case of exception clear it and return an empty string + if( resPtr==NULL ) { - PyErr_Clear(); - return wxEmptyString; + PyErr_Clear(); + return wxEmptyString; } - + result = *resPtr; - delete resPtr; + delete resPtr; return result; } -PyObject* wx2PyString(const wxString& src) +PyObject* wx2PyString( const wxString& src ) { PyObject* str; + #if wxUSE_UNICODE - str = PyUnicode_FromWideChar(src.c_str(), src.Len()); + str = PyUnicode_FromWideChar( src.c_str(), src.Len() ); #else - str = PyString_FromStringAndSize(src.c_str(), src.Len()); + str = PyString_FromStringAndSize( src.c_str(), src.Len() ); #endif return str; } - -void wxSetDefaultPyEncoding(const char* encoding) +void wxSetDefaultPyEncoding( const char* encoding ) { - strncpy(wxPythonEncoding, encoding, WX_DEFAULTENCODING_SIZE); + strncpy( wxPythonEncoding, encoding, WX_DEFAULTENCODING_SIZE ); } + const char* wxGetDefaultPyEncoding() { return wxPythonEncoding; } - diff --git a/scripting/wx_python_helpers.h b/scripting/wx_python_helpers.h index fd40e0a9df..2da11d654a 100644 --- a/scripting/wx_python_helpers.h +++ b/scripting/wx_python_helpers.h @@ -7,14 +7,12 @@ #include +PyObject* wxArrayString2PyList( const wxArrayString& lst ); +wxString* newWxStringFromPy( PyObject* source ); +wxString Py2wxString( PyObject* source ); +PyObject* wx2PyString( const wxString& src ); - -PyObject* wxArrayString2PyList(const wxArrayString& lst); -wxString* newWxStringFromPy(PyObject* source); -wxString Py2wxString(PyObject* source); -PyObject* wx2PyString(const wxString& src); - -void wxSetDefaultPyEncoding(const char* encoding); +void wxSetDefaultPyEncoding( const char* encoding ); const char* wxGetDefaultPyEncoding(); #endif From 974fe74f66dd7898afeb4b1dc2d23511d91839b2 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Fri, 6 Jul 2012 21:10:55 +0200 Subject: [PATCH 40/41] Cleanup toward test-merge --- pcbnew/class_footprint_wizard.cpp | 19 +++++++----- pcbnew/class_footprint_wizard.h | 4 ++- pcbnew/footprint_wizard_frame.h | 49 ++++++++++++++++++++++--------- scripting/dlist.i | 9 +++--- scripting/fixswigimports.py | 7 +++-- scripting/kicad.i | 23 +++++++-------- scripting/kicadplugins.i | 48 ++++++++++++++++++++---------- scripting/wx.i | 10 +++++-- 8 files changed, 111 insertions(+), 58 deletions(-) diff --git a/pcbnew/class_footprint_wizard.cpp b/pcbnew/class_footprint_wizard.cpp index fd76899b54..3bc232b882 100644 --- a/pcbnew/class_footprint_wizard.cpp +++ b/pcbnew/class_footprint_wizard.cpp @@ -8,26 +8,31 @@ void FOOTPRINT_WIZARD::register_wizard() { - FOOTPRINT_WIZARDS::register_wizard(this); + FOOTPRINT_WIZARDS::register_wizard( this ); } +/** + * FOOTPRINT_WIZARD system wide static list + */ std::vector FOOTPRINT_WIZARDS::m_FootprintWizards; -FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard(int aIndex) +FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard( int aIndex ) { return m_FootprintWizards[aIndex]; } -FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard(wxString aName) +FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard( wxString aName ) { int max = GetSize(); - for(int i=0; iGetName(); - if (name.Cmp(aName)) + + if ( name.Cmp(aName) ) return wizard; } @@ -45,7 +50,7 @@ void FOOTPRINT_WIZARDS::register_wizard(FOOTPRINT_WIZARD *aWizard) wxString name = aWizard->GetName(); m_FootprintWizards.push_back(aWizard); - printf("Registered footprint wizard '%s'\n",(const char*)name.mb_str() ); + //printf("Registered footprint wizard '%s'\n",(const char*)name.mb_str() ); } diff --git a/pcbnew/class_footprint_wizard.h b/pcbnew/class_footprint_wizard.h index 08a9d049bf..7e0e3bf347 100644 --- a/pcbnew/class_footprint_wizard.h +++ b/pcbnew/class_footprint_wizard.h @@ -8,7 +8,9 @@ #include #include -/* This is the parent class from where any footprint wiizard class must +/** + * Class FOOTPRINT_WIZARD + * This is the parent class from where any footprint wizard class must * derive */ class FOOTPRINT_WIZARD { diff --git a/pcbnew/footprint_wizard_frame.h b/pcbnew/footprint_wizard_frame.h index 584445cf89..34f19c7290 100644 --- a/pcbnew/footprint_wizard_frame.h +++ b/pcbnew/footprint_wizard_frame.h @@ -46,19 +46,19 @@ class wxGridEvent; class FOOTPRINT_WIZARD_FRAME : public PCB_BASE_FRAME { private: - // List of libraries (for selection ) - wxSashLayoutWindow* m_PageListWindow; - wxListBox* m_PageList; // The list of pages - wxSize m_PageListSize; // size of the window + + wxSashLayoutWindow* m_PageListWindow; //< List of libraries (for selection ) + wxListBox* m_PageList; //< The list of pages + wxSize m_PageListSize; //< size of the window - // List of components in the selected library - wxSashLayoutWindow* m_ParameterGridWindow; - wxGrid* m_ParameterGrid; // The list of parameters - wxSize m_ParameterGridSize; // size of the window + + wxSashLayoutWindow* m_ParameterGridWindow; //< List of components in the selected library + wxGrid* m_ParameterGrid; //< The list of parameters + wxSize m_ParameterGridSize; //< size of the window // Flags - wxSemaphore* m_Semaphore; // != NULL if the frame must emulate a modal dialog - wxString m_configPath; // subpath for configuration + wxSemaphore* m_Semaphore; //< != NULL if the frame must emulate a modal dialog + wxString m_configPath; //< subpath for configuration FOOTPRINT_WIZARD* m_FootprintWizard; @@ -86,19 +86,40 @@ private: void OnSashDrag( wxSashEvent& event ); /** - * Function ReCreateLibraryList - * - * Creates or recreates the list of current loaded libraries. - * This list is sorted, with the library cache always at end of the list + * Function ReCreatePageList + * Creates or recreates the list of parameter pages for the current wizard. + * This list is sorted */ void ReCreatePageList(); + + /** + * Function ReCreateParameterList + * Creates the list of parameters for the current page + */ void ReCreateParameterList(); + + /** + * Function SelectFootprintWizard + * Shows the list of footprint wizards available into the system + */ void SelectFootprintWizard(); + + /** + * Function ReloadFootprint + * Reloads the current footprint + */ void ReloadFootprint(); void Process_Special_Functions( wxCommandEvent& event ); + + /** + * Function DisplayWizardInfos + * Shows all the details about the current wizard + */ void DisplayWizardInfos(); + + void RedrawActiveWindow( wxDC* DC, bool EraseBg ); void OnCloseWindow( wxCloseEvent& Event ); void ReCreateHToolbar(); diff --git a/scripting/dlist.i b/scripting/dlist.i index c05c6a237f..aa3f5e25ad 100644 --- a/scripting/dlist.i +++ b/scripting/dlist.i @@ -6,9 +6,9 @@ { class DLISTIter: def __init__(self,aList): - self.last = aList + self.last = aList # last item is the start of list - def next(self): + def next(self): # get the next item item = self.last try: @@ -16,7 +16,7 @@ except: pass - if item is None: + if item is None: # if the item is None, then finish the iteration raise StopIteration else: ret = None @@ -25,11 +25,12 @@ try: ret = self.last.Get() except: - ret = self.last #next items just not.. + ret = self.last # next items do not.. self.last = self.last.Next() # when the iterated object can be casted down in inheritance, just do it.. + if 'Cast' in dir(ret): ret = ret.Cast() diff --git a/scripting/fixswigimports.py b/scripting/fixswigimports.py index add960fa81..ece19a2e54 100755 --- a/scripting/fixswigimports.py +++ b/scripting/fixswigimports.py @@ -27,7 +27,6 @@ f = open(filename,"rb") lines = f.readlines() f.close() -f = open(filename,"wb") doneOk = False @@ -35,14 +34,18 @@ if (len(lines)<4000): print "still building" exit(0) +txt = "" + for l in lines: if l.startswith("if version_info >= (2,6,0):"): l = l.replace("version_info >= (2,6,0)","False") doneOk = True elif l.startswith("if False:"): # it was already patched? doneOk = True - f.write(l) + txt = txt + l +f = open(filename,"wb") +f.write(txt) f.close() if doneOk: diff --git a/scripting/kicad.i b/scripting/kicad.i index 7029044e1d..71b00bc7fe 100644 --- a/scripting/kicad.i +++ b/scripting/kicad.i @@ -27,14 +27,8 @@ * @brief General wrappers for kicad / wx structures and classes */ - -/* OFF NOW, it triggers an error with GCC 4.6 and swig-2.0.4 or trunk.. - http://sourceforge.net/tracker/index.php?func=detail&aid=3391906&group_id=1645&atid=101645 -*/ - - - %include - %include +%include +%include /* ignore some constructors of EDA_ITEM that will make the build fail */ @@ -44,11 +38,12 @@ %ignore EDA_ITEM::EDA_ITEM( const EDA_ITEM& base ); /* swig tries to wrap SetBack/SetNext on derived classes, but this method is - private for most childs, so if we don't ignore it it won't compile */ + private for most childs, so if we don't ignore it won't compile */ %ignore EDA_ITEM::SetBack; %ignore EDA_ITEM::SetNext; +/* ignore other functions that cause trouble */ %ignore InitKiCadAbout; %ignore GetCommandOptions; @@ -57,9 +52,10 @@ %ignore operator <<; %ignore operator=; +/* headers/imports that must be included in the _wrapper.cpp at top */ %{ - #include + #include #include #include #include @@ -72,7 +68,7 @@ #include #include #include - #include + #include %} @@ -95,6 +91,7 @@ } */ +/* header files that must be wrapped */ %include %include @@ -104,10 +101,12 @@ %include %include - +/* special iteration wrapper for DLIST objects */ %include "dlist.i" /* std template mappings */ %template(intVector) std::vector; +/* KiCad plugin handling */ %include "kicadplugins.i" + diff --git a/scripting/kicadplugins.i b/scripting/kicadplugins.i index 1bdae479e0..b3b14d5743 100644 --- a/scripting/kicadplugins.i +++ b/scripting/kicadplugins.i @@ -22,9 +22,41 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + /** + * This file builds the base classes for all kind of python plugins that + * can be included into kicad. + * they provide generic code to all the classes: + * + * KiCadPlugin + * /|\ + * | + * |\-FilePlugin + * |\-FootprintWizardPlugin + * |\-ActionPlugin + * + * It defines the LoadPlugins() function that loads all the plugins + * available in the system + * + */ %pythoncode { +def LoadPlugins(): + import os + import sys + + plugins_dir = os.environ['HOME']+'/.kicad_plugins/' + + sys.path.append(plugins_dir) + + for module in os.listdir(plugins_dir): + if os.path.isdir(plugins_dir+module): + __import__(module, locals(), globals()) + + if module == '__init__.py' or module[-3:] != '.py': + continue + __import__(module[:-3], locals(), globals()) + # KiCadPlugin base class will register any plugin into the right place class KiCadPlugin: @@ -159,21 +191,5 @@ class ActionPlugin(KiCadPlugin): KiCadPlugin.__init__(self) -def LoadPlugins(): - import os - import sys - - plugins_dir = os.environ['HOME']+'/.kicad_plugins/' - - sys.path.append(plugins_dir) - - for module in os.listdir(plugins_dir): - if os.path.isdir(plugins_dir+module): - __import__(module, locals(), globals()) - - if module == '__init__.py' or module[-3:] != '.py': - continue - __import__(module[:-3], locals(), globals()) - } diff --git a/scripting/wx.i b/scripting/wx.i index 20ac1ec398..d3421bd94f 100644 --- a/scripting/wx.i +++ b/scripting/wx.i @@ -25,6 +25,9 @@ /** * @file wx.i * @brief wx wrappers for basic things, wxString, wxPoint, wxRect, etc.. + * all the wx objects are very complex, and we don't want to pull + * and swig all depending objects, so we just define the methods + * we want to wrap. */ %{ @@ -67,7 +70,8 @@ public: int x, y, width, height; %extend - { + { + /* extend the wxRect object so it can be converted into a tuple */ PyObject* Get() { PyObject* res = PyTuple_New(4); @@ -191,7 +195,9 @@ public: }; -// wxChar wrappers /////////////////////////////////////////////////////////// +// wxChar typemaps /////////////////////////////////////////////////////////// + +/* they handle the conversion from/to strings */ %typemap(in) wxChar { wxString str = Py2wxString($input); $1 = str[0]; } %typemap(out) wxChar { wxString str($1); $result = wx2PyString(str); } From 2a9b8df88809bf5523cdd3ccdd47a07b960cf760 Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo Date: Sun, 15 Jul 2012 22:01:05 +0200 Subject: [PATCH 41/41] Support for nanometer build, extra example --- pcbnew/CMakeLists.txt | 14 ++++---- .../examples/hidePcbValuesShowReferences.py | 14 ++++++++ pcbnew/scripting/units.i | 36 +++++++++---------- scripting/kicad.i | 6 +++- scripting/python_scripting.cpp | 11 +++--- 5 files changed, 50 insertions(+), 31 deletions(-) create mode 100644 pcbnew/scripting/examples/hidePcbValuesShowReferences.py diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index f45d242228..c1fe7664ec 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -2,15 +2,12 @@ add_definitions(-DPCBNEW) if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) EXECUTE_PROCESS(COMMAND python2 -c "import sys;print\"%s.%s\"%sys.version_info[0:2]" OUTPUT_VARIABLE PYTHON_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) - SET(PYTHON_DEST "lib/python${PYTHON_VERSION}/dist-packages" ) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/scripting) - - FIND_PACKAGE(SWIG REQUIRED) - INCLUDE(${SWIG_USE_FILE}) - - FIND_PACKAGE(PythonLibs) - INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) + FIND_PACKAGE(SWIG REQUIRED) + INCLUDE(${SWIG_USE_FILE}) + FIND_PACKAGE(PythonLibs) + INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) add_definitions(-DPCBNEW -DKICAD_SCRIPTING) endif() @@ -280,6 +277,9 @@ if (KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES) if ( USE_NEW_PCBNEW_LOAD OR USE_NEW_PCBNEW_SAVE ) SET(SWIG_FLAGS ${SWIG_FLAGS} -DBUILD_WITH_PLUGIN) endif() + if ( USE_PCBNEW_NANOMETRES ) + SET(SWIG_FLAGS ${SWIG_FLAGS} -DUSE_PCBNEW_NANOMETRES) + endif() endif() diff --git a/pcbnew/scripting/examples/hidePcbValuesShowReferences.py b/pcbnew/scripting/examples/hidePcbValuesShowReferences.py new file mode 100644 index 0000000000..2d878d15b9 --- /dev/null +++ b/pcbnew/scripting/examples/hidePcbValuesShowReferences.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python +import sys +from pcbnew import * + +filename=sys.argv[1] + +pcb = LoadBoard(filename) + +for module in pcb.GetModules(): + print "* Module: %s"%module.GetReference() + module.GetValueObj().SetVisible(False) # set Value as Hidden + module.GetReferenceObj().SetVisible(True) # set Reference as Visible + +pcb.Save("mod_"+filename) \ No newline at end of file diff --git a/pcbnew/scripting/units.i b/pcbnew/scripting/units.i index 66ff1f4d69..83764b3d0e 100644 --- a/pcbnew/scripting/units.i +++ b/pcbnew/scripting/units.i @@ -34,42 +34,42 @@ { def ToMM(iu): if type(iu) in [int,float]: - return iu * 0.00254 + return float(iu) / float(IU_PER_MM) elif type(iu) in [wxPoint,wxSize]: return tuple(map(ToMM,iu)) - def FromMM(iu): - if type(iu) in [int,float]: - return iu / 0.00254 - elif type(iu) in [wxPoint,wxSize]: - return tuple(map(FromMM,iu)) + def FromMM(mm): + if type(mm) in [int,float]: + return int(float(mm) * float(IU_PER_MM)) + elif type(mm) in [wxPoint,wxSize]: + return tuple(map(FromMM,mm)) def ToMils(iu): if type(iu) in [int,float]: - return iu / 10.0 + return float(iu) / float(IU_PER_MILS) elif type(iu) in [wxPoint,wxSize]: return tuple(map(ToMils,iu)) - def FromMils(iu): - if type(iu) in [int,float]: - return iu*10.0 - elif type(iu) in [wxPoint,wxSize]: - return tuple(map(FromMils,iu)) + def FromMils(mils): + if type(mils) in [int,float]: + return int(float(mils)*float(IU_PER_MILS)) + elif type(mils) in [wxPoint,wxSize]: + return tuple(map(FromMils,mils)) - def SizeMM(mmx,mmy): return wxSize(FromMM(mmx),FromMM(mmy)) - def SizeMils(mmx,mmy): return wxSize(FromMils(mmx),FromMils(mmy)) + def wxSizeMM(mmx,mmy): return wxSize(FromMM(mmx),FromMM(mmy)) + def wxSizeMils(mmx,mmy): return wxSize(FromMils(mmx),FromMils(mmy)) - def PointMM(mmx,mmy): return wxPoint(FromMM(mmx),FromMM(mmy)) - def PointMils(mmx,mmy): return wxPoint(FromMils(mmx),FromMils(mmy)) + def wxPointMM(mmx,mmy): return wxPoint(FromMM(mmx),FromMM(mmy)) + def wxPointMils(mmx,mmy): return wxPoint(FromMils(mmx),FromMils(mmy)) - def RectMM(x,y,wx,wy): + def wxRectMM(x,y,wx,wy): x = int(FromMM(x)) y = int(FromMM(y)) wx = int(FromMM(wx)) wy = int (FromMM(wy)) return wxRect(x,y,wx,wy) - def RectMils(x,y,wx,wy): + def wxRectMils(x,y,wx,wy): x = int(FromMils(x)) y = int(FromMils(y)) wx = int(FromMils(wx)) diff --git a/scripting/kicad.i b/scripting/kicad.i index 71b00bc7fe..533e008762 100644 --- a/scripting/kicad.i +++ b/scripting/kicad.i @@ -68,7 +68,9 @@ #include #include #include - #include + #include + #include + #include %} @@ -100,6 +102,8 @@ %include %include %include +%include +%include /* special iteration wrapper for DLIST objects */ %include "dlist.i" diff --git a/scripting/python_scripting.cpp b/scripting/python_scripting.cpp index 2b1ca6b18d..90b6807e7d 100644 --- a/scripting/python_scripting.cpp +++ b/scripting/python_scripting.cpp @@ -68,14 +68,15 @@ static void swigAddBuiltin() { int i = 0; - while( PyImport_Inittab[i].name ) - { - i++; - } - + /* discover the length of the pyimport inittab */ + while( PyImport_Inittab[i].name ) i++; + + /* allocate memory for the python module table */ SwigImportInittab = (struct _inittab*) malloc( sizeof(struct _inittab)*(i+EXTRA_PYTHON_MODULES)); + /* copy all pre-existing python modules into our newly created table */ + i=0; while( PyImport_Inittab[i].name ) { swigAddModule( PyImport_Inittab[i].name, PyImport_Inittab[i].initfunc );