KiCad PCB EDA Suite
pcbnew_footprint_wizards.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013 NBEE Embedded Systems SL, Miguel Angel Ajo <[email protected]>
5  * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
31 #include <cstdio>
32 #include <macros.h>
33 #include <wx/msgdlg.h>
34 #include "../../scripting/python_scripting.h"
35 
36 
38 {
39  PyLOCK lock;
40 
41  m_PyWizard = aWizard;
42  Py_XINCREF( aWizard );
43 }
44 
45 
47 {
48  PyLOCK lock;
49 
50  Py_XDECREF( m_PyWizard );
51 }
52 
53 
54 PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod( const char* aMethod, PyObject* aArglist )
55 {
56  PyLOCK lock;
57 
58  PyErr_Clear();
59  // pFunc is a new reference to the desired method
60  PyObject* pFunc = PyObject_GetAttrString( m_PyWizard, aMethod );
61 
62  if( pFunc && PyCallable_Check( pFunc ) )
63  {
64  PyObject* result = PyObject_CallObject( pFunc, aArglist );
65 
66  if( PyErr_Occurred() )
67  {
68 #if 1 // defined(DEBUG)
69  wxMessageBox( PyErrStringWithTraceback(),
70  _( "Exception on python footprint wizard code" ),
71  wxICON_ERROR | wxOK );
72 #endif
73  }
74 
75  if( result )
76  {
77  Py_XDECREF( pFunc );
78  return result;
79  }
80  }
81  else
82  {
83  wxString msg = wxString::Format(_( "Method '%s' not found, or not callable" ), aMethod );
84  wxMessageBox( msg, _( "Unknown Method" ), wxICON_ERROR | wxOK );
85  }
86 
87  if( pFunc )
88  {
89  Py_XDECREF( pFunc );
90  }
91 
92  return nullptr;
93 }
94 
95 
96 wxString PYTHON_FOOTPRINT_WIZARD::CallRetStrMethod( const char* aMethod, PyObject* aArglist )
97 {
98  wxString ret;
99  PyLOCK lock;
100 
101  PyObject* result = CallMethod( aMethod, aArglist );
102 
103  if( result == Py_None )
104  {
105  Py_DECREF( result );
106  return ret;
107  }
108 
109  ret = PyStringToWx( result );
110  Py_XDECREF( result );
111 
112  return ret;
113 }
114 
115 
116 wxArrayString PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod( const char* aMethod,
117  PyObject* aArglist )
118 {
119  wxArrayString ret;
120  wxString str_item;
121  PyLOCK lock;
122 
123  PyObject* result = CallMethod( aMethod, aArglist );
124 
125  if( result )
126  {
127  if( !PyList_Check( result ) )
128  {
129  Py_DECREF( result );
130  ret.Add( wxT( "PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod, result is not a list" ),
131  1 );
132  return ret;
133  }
134 
135  ret = PyArrayStringToWx( result );
136 
137  Py_DECREF( result );
138  }
139 
140  return ret;
141 }
142 
143 
145 {
146  PyLOCK lock;
147 
148  return CallRetStrMethod( "GetName" );
149 }
150 
151 
153 {
154  PyLOCK lock;
155 
156  return CallRetStrMethod( "GetImage" );
157 }
158 
159 
161 {
162  PyLOCK lock;
163 
164  return CallRetStrMethod( "GetDescription" );
165 }
166 
167 
169 {
170  int ret = 0;
171  PyLOCK lock;
172 
173  // Time to call the callback
174  PyObject* result = CallMethod( "GetNumParameterPages", nullptr );
175 
176  if( result )
177  {
178  if( !PyLong_Check( result ) )
179  return -1;
180 
181  ret = PyLong_AsLong( result );
182  Py_DECREF( result );
183  }
184 
185  return ret;
186 }
187 
188 
190 {
191  wxString ret;
192  PyLOCK lock;
193 
194  // Time to call the callback
195  PyObject* arglist = Py_BuildValue( "(i)", aPage );
196  PyObject* result = CallMethod( "GetParameterPageName", arglist );
197 
198  Py_DECREF( arglist );
199 
200  if( result == Py_None )
201  {
202  Py_DECREF( result );
203  return ret;
204  }
205 
206  ret = PyStringToWx( result );
207  Py_XDECREF( result );
208 
209  return ret;
210 }
211 
212 
214 {
215  wxArrayString ret;
216  PyLOCK lock;
217 
218  PyObject* arglist = Py_BuildValue( "(i)", aPage );
219 
220  ret = CallRetArrayStrMethod( "GetParameterNames", arglist );
221  Py_DECREF( arglist );
222 
223  for( unsigned i = 0; i < ret.GetCount(); i++ )
224  {
225  wxString rest;
226  wxString item = ret[i];
227 
228  if( item.StartsWith( wxT( "*" ), &rest ) )
229  {
230  ret[i] = rest;
231  }
232  }
233 
234  return ret;
235 }
236 
237 
239 {
240  wxArrayString ret;
241  PyLOCK lock;
242 
243  PyObject* arglist = Py_BuildValue( "(i)", aPage );
244 
245  ret = CallRetArrayStrMethod( "GetParameterTypes", arglist );
246  Py_DECREF( arglist );
247 
248  return ret;
249 }
250 
251 
253 {
254  PyLOCK lock;
255 
256  PyObject* arglist = Py_BuildValue( "(i)", aPage );
257  wxArrayString ret = CallRetArrayStrMethod( "GetParameterValues", arglist );
258 
259  Py_DECREF( arglist );
260 
261  return ret;
262 }
263 
264 
266 {
267  PyLOCK lock;
268 
269  PyObject* arglist = Py_BuildValue( "(i)", aPage );
270  wxArrayString ret = CallRetArrayStrMethod( "GetParameterErrors", arglist );
271 
272  Py_DECREF( arglist );
273 
274  return ret;
275 }
276 
278 {
279  PyLOCK lock;
280 
281  PyObject* arglist = Py_BuildValue( "(i)", aPage );
282  wxArrayString ret = CallRetArrayStrMethod( "GetParameterHints", arglist );
283 
284  Py_DECREF( arglist );
285 
286  return ret;
287 }
288 
290 {
291  PyLOCK lock;
292 
293  PyObject* arglist = Py_BuildValue( "(i)", aPage );
294  wxArrayString ret = CallRetArrayStrMethod( "GetParameterDesignators", arglist );
295 
296  Py_DECREF( arglist );
297 
298  return ret;
299 }
300 
301 wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues( int aPage, wxArrayString& aValues )
302 {
303  int len = aValues.size();
304 
305  PyLOCK lock;
306 
307  PyObject* py_list = PyList_New( len );
308 
309  for( int i = 0; i < len; i++ )
310  {
311  wxString& str = aValues[i];
312  PyObject* py_str = PyUnicode_FromString( (const char*) str.mb_str() );
313  PyList_SetItem( py_list, i, py_str );
314  }
315 
316  PyObject* arglist;
317 
318  arglist = Py_BuildValue( "(i,O)", aPage, py_list );
319  wxString res = CallRetStrMethod( "SetParameterValues", arglist );
320  Py_DECREF( arglist );
321 
322  return res;
323 }
324 
326 {
327  PyLOCK lock;
328 
329  CallMethod( "ResetWizard", nullptr );
330 }
331 
332 
333 // this is a SWIG function declaration -from footprint.i
334 FOOTPRINT* PyFootprint_to_FOOTPRINT( PyObject* obj0 );
335 
336 
338 {
339  PyLOCK lock;
340 
341  PyObject* result = CallMethod( "GetFootprint", nullptr );
342 
343  if( aMessages )
344  *aMessages = CallRetStrMethod( "GetBuildMessages", nullptr );
345 
346  if( !result )
347  return nullptr;
348 
349  PyObject* obj = PyObject_GetAttrString( result, "this" );
350 
351  if( PyErr_Occurred() )
352  {
353  PyErr_Print();
354  PyErr_Clear();
355  }
356 
357  FOOTPRINT* footprint = PyFootprint_to_FOOTPRINT( obj );
358 
359  return footprint;
360 }
361 
362 
364 {
365  return (void*) m_PyWizard;
366 }
367 
368 
370 {
371  PYTHON_FOOTPRINT_WIZARD* fw = new PYTHON_FOOTPRINT_WIZARD( aPyWizard );
372 
373  fw->register_wizard();
374 }
375 
376 
378 {
379  // deregister also destroys the previously created "PYTHON_FOOTPRINT_WIZARD object"
380  FOOTPRINT_WIZARD_LIST::deregister_object( (void*) aPyWizard );
381 }
Class PCBNEW_FOOTPRINT_WIZARDS.
PyObject * CallMethod(const char *aMethod, PyObject *aArglist=nullptr)
void register_wizard()
The standard method of a "FOOTPRINT_WIZARD" to register itself into the FOOTPRINT_WIZARD_LIST singlet...
void ResetParameters() override
Reset all wizard parameters to default values.
wxArrayString GetParameterTypes(int aPage) override
FOOTPRINT * GetFootprint(wxString *aMessages) override
Build the footprint itself and returns it to the caller function.
This file contains miscellaneous commonly used macros and functions.
PYTHON_FOOTPRINT_WIZARD(PyObject *wizard)
wxArrayString GetParameterNames(int aPage) override
wxArrayString GetParameterHints(int aPage) override
#define _(s)
wxArrayString GetParameterErrors(int aPage) override
wxArrayString GetParameterDesignators(int aPage=0) override
wxArrayString CallRetArrayStrMethod(const char *aMethod, PyObject *aArglist=nullptr)
FOOTPRINT * PyFootprint_to_FOOTPRINT(PyObject *obj0)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
static void deregister_wizard(PyObject *aPyWizard)
wxString SetParameterValues(int aPage, wxArrayString &aValues) override
static void register_wizard(PyObject *aPyWizard)
wxString CallRetStrMethod(const char *aMethod, PyObject *aArglist=nullptr)
wxArrayString GetParameterValues(int aPage) override
void * GetObject() override
Get the object from where this wizard constructs.
static bool deregister_object(void *aObject)
Unregister an object which builds a wizard.
wxString GetParameterPageName(int aPage) override