kicad-patches/pcbnew-scripted.patch |
1 | | This patch adds several command line parameters to pcbnew. |
2 | | |
3 | | diff -ruN kicad.orig/common/confirm.cpp kicad/common/confirm.cpp |
4 | | +++ kicad/common/confirm.cpp 2010-12-24 21:01:00.966781920 +0000 |
5 | | @@ -66,6 +66,7 @@ |
6 | | * See not above as to why this doesn't work. */ |
7 | | } |
8 | | |
9 | | +bool g_scripted = false; |
10 | | |
11 | | /* Display an error or warning message. |
12 | | * If display time > 0 the dialog disappears after displayTime 0.1 seconds |
13 | | @@ -75,6 +76,12 @@ |
14 | | { |
15 | | wxMessageDialog* dialog; |
16 | | |
17 | | + if (g_scripted) |
18 | | + { |
19 | | + wxFprintf( stderr, text + _("\n") ); |
20 | | + return; |
21 | | + } |
22 | | + |
23 | | if( displaytime > 0 ) |
24 | | dialog = new WinEDA_MessageDialog( parent, text, _( "Warning" ), |
25 | | wxOK | wxICON_INFORMATION, |
26 | | @@ -95,6 +102,11 @@ |
27 | | { |
28 | | wxMessageDialog* dialog; |
29 | | |
30 | | + if (g_scripted) |
31 | | + { |
32 | | + wxPrintf( text + _("\n") ); |
33 | | + return; |
34 | | + } |
35 | | dialog = new WinEDA_MessageDialog( parent, text, _( "Info:" ), |
36 | | wxOK | wxICON_INFORMATION, displaytime ); |
37 | | |
38 | | diff -ruN kicad.orig/common/edaappl.cpp kicad/common/edaappl.cpp |
39 | | +++ kicad/common/edaappl.cpp 2010-12-28 08:57:27.929470001 +0000 |
40 | | @@ -272,6 +272,7 @@ |
41 | | wxString EnvLang; |
42 | | |
43 | | m_Id = aId; |
44 | | +if (!g_scripted) |
45 | | m_Checker = new wxSingleInstanceChecker( aName.Lower() + wxT( "-" ) + |
46 | | wxGetUserId() ); |
47 | | |
48 | | diff -ruN kicad.orig/include/common.h kicad/include/common.h |
49 | | +++ kicad/include/common.h 2010-12-22 18:47:54.974932729 +0000 |
50 | | @@ -6,6 +6,8 @@ |
51 | | #ifndef __INCLUDE__COMMON_H__ |
52 | | #define __INCLUDE__COMMON_H__ 1 |
53 | | |
54 | | +extern bool g_scripted; |
55 | | + |
56 | | #include "wx/confbase.h" |
57 | | #include "wx/fileconf.h" |
58 | | |
59 | | diff -ruN kicad.orig/include/wxPcbStruct.h kicad/include/wxPcbStruct.h |
60 | | +++ kicad/include/wxPcbStruct.h 2010-12-24 11:03:20.674781923 +0000 |
61 | | @@ -50,6 +50,7 @@ |
62 | | class WinEDA_PcbFrame : public WinEDA_BasePcbFrame |
63 | | { |
64 | | friend class PCB_LAYER_WIDGET; |
65 | | + friend bool Pcbnew_Scripted(); |
66 | | |
67 | | protected: |
68 | | |
69 | | diff -ruN kicad.orig/pcbnew/build_BOM_from_board.cpp kicad/pcbnew/build_BOM_from_board.cpp |
70 | | +++ kicad/pcbnew/build_BOM_from_board.cpp 2010-12-24 21:05:59.426781921 +0000 |
71 | | @@ -64,6 +64,7 @@ |
72 | | fn = GetScreen()->m_FileName; |
73 | | fn.SetExt( CsvFileExtension ); |
74 | | |
75 | | + if (!g_scripted) { |
76 | | wxFileDialog dlg( this, _( "Save Bill of Materials" ), wxGetCwd(), |
77 | | fn.GetFullName(), CsvFileWildcard, |
78 | | wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); |
79 | | @@ -72,6 +73,7 @@ |
80 | | return; |
81 | | |
82 | | fn = dlg.GetPath(); |
83 | | + } |
84 | | |
85 | | FichBom = wxFopen( fn.GetFullPath(), wxT( "wt" ) ); |
86 | | |
87 | | diff -ruN kicad.orig/pcbnew/CMakeLists.txt kicad/pcbnew/CMakeLists.txt |
88 | | +++ kicad/pcbnew/CMakeLists.txt 2010-12-22 02:19:48.597291239 +0000 |
89 | | @@ -142,6 +142,7 @@ |
90 | | onrightclick.cpp |
91 | | pcbnew.cpp |
92 | | pcbnew_config.cpp |
93 | | + pcbnew_scripted.cpp |
94 | | pcbplot.cpp |
95 | | plotgerb.cpp |
96 | | plothpgl.cpp |
97 | | diff -ruN kicad.orig/pcbnew/dialog_gendrill.h kicad/pcbnew/dialog_gendrill.h |
98 | | +++ kicad/pcbnew/dialog_gendrill.h 2010-12-22 18:23:00.054932711 +0000 |
99 | | @@ -12,6 +12,7 @@ |
100 | | |
101 | | class DIALOG_GENDRILL: public DIALOG_GENDRILL_BASE |
102 | | { |
103 | | +friend bool Pcbnew_Scripted(); |
104 | | |
105 | | private: |
106 | | WinEDA_PcbFrame* m_Parent; |
107 | | diff -ruN kicad.orig/pcbnew/drc_stuff.h kicad/pcbnew/drc_stuff.h |
108 | | +++ kicad/pcbnew/drc_stuff.h 2010-12-24 10:01:41.438781921 +0000 |
109 | | @@ -136,6 +136,7 @@ |
110 | | class DRC |
111 | | { |
112 | | friend class DIALOG_DRC_CONTROL; |
113 | | + friend bool Pcbnew_Scripted(); |
114 | | |
115 | | private: |
116 | | |
117 | | diff -ruN kicad.orig/pcbnew/gendrill.cpp kicad/pcbnew/gendrill.cpp |
118 | | +++ kicad/pcbnew/gendrill.cpp 2010-12-23 13:58:26.526933001 +0000 |
119 | | @@ -307,6 +307,43 @@ |
120 | | fn.SetName( fn.GetName() + layer_extend ); |
121 | | fn.SetExt( DrillFileExtension ); |
122 | | |
123 | | + if (g_scripted) |
124 | | + { |
125 | | + FILE* excellon_dest = wxFopen( fn.GetFullPath(), wxT( "w" ) ); |
126 | | + if( excellon_dest == 0 ) |
127 | | + { |
128 | | + printf("Unable to create %ls.\n", fn.GetFullPath().c_str()); |
129 | | + exit(0); |
130 | | + } |
131 | | + Create_Drill_File_EXCELLON( excellon_dest, s_HoleListBuffer, |
132 | | + s_ToolListBuffer ); |
133 | | + |
134 | | + switch( m_Choice_Drill_Map->GetSelection() ) |
135 | | + { |
136 | | + case 0: |
137 | | + break; |
138 | | + |
139 | | + case 1: |
140 | | + GenDrillMap( fn.GetPath(), s_HoleListBuffer, s_ToolListBuffer, |
141 | | + PLOT_FORMAT_HPGL ); |
142 | | + break; |
143 | | + |
144 | | + case 2: |
145 | | + GenDrillMap( fn.GetPath(), s_HoleListBuffer, s_ToolListBuffer, |
146 | | + PLOT_FORMAT_POST ); |
147 | | + break; |
148 | | + |
149 | | + case 3: |
150 | | + GenDrillMap( fn.GetPath(), s_HoleListBuffer, s_ToolListBuffer, |
151 | | + PLOT_FORMAT_GERBER ); |
152 | | + break; |
153 | | + |
154 | | + case 4: |
155 | | + GenDrillMap( fn.GetPath(), s_HoleListBuffer, s_ToolListBuffer, |
156 | | + PLOT_FORMAT_DXF ); |
157 | | + break; |
158 | | + } |
159 | | + } else { |
160 | | wxFileDialog dlg( this, _( "Save Drill File" ), fn.GetPath(), |
161 | | fn.GetFullName(), DrillFileWildcard, |
162 | | wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); |
163 | | @@ -352,6 +389,7 @@ |
164 | | PLOT_FORMAT_DXF ); |
165 | | break; |
166 | | } |
167 | | + } // !g_scripted |
168 | | |
169 | | if( !ExistsBuriedVias ) |
170 | | break; |
171 | | diff -ruN kicad.orig/pcbnew/pcbnew.cpp kicad/pcbnew/pcbnew.cpp |
172 | | +++ kicad/pcbnew/pcbnew.cpp 2010-12-28 09:18:32.577470003 +0000 |
173 | | @@ -29,6 +29,7 @@ |
174 | | #include "build_version.h" |
175 | | |
176 | | #include "protos.h" |
177 | | +#include "pcbnew_scripted.h" |
178 | | |
179 | | // Colors for layers and items |
180 | | COLORS_DESIGN_SETTINGS g_ColorsSettings; |
181 | | @@ -103,6 +104,9 @@ |
182 | | wxFileName fn; |
183 | | WinEDA_PcbFrame* frame = NULL; |
184 | | |
185 | | + if( Pcbnew_Scripted() ) |
186 | | + return false; |
187 | | + |
188 | | InitEDA_Appl( wxT( "PCBnew" ), APP_TYPE_PCBNEW ); |
189 | | |
190 | | if( m_Checker && m_Checker->IsAnotherRunning() ) |
191 | | diff -ruN kicad.orig/pcbnew/pcbnew_scripted.cpp kicad/pcbnew/pcbnew_scripted.cpp |
192 | | +++ kicad/pcbnew/pcbnew_scripted.cpp 2010-12-28 09:51:20.189470002 +0000 |
193 | | @@ -0,0 +1,552 @@ |
194 | | +///////////////////////////////////////////////////////////////////////////// |
195 | | +// Name: pcbnew_scripted.cpp |
196 | | +// Copyright: Wolfgang Spraul |
197 | | +// Licence: GPL v3 or higher |
198 | | +///////////////////////////////////////////////////////////////////////////// |
199 | | + |
200 | | +#include "fctsys.h" |
201 | | +#include "appl_wxstruct.h" |
202 | | +#include "confirm.h" |
203 | | + |
204 | | +#include <wx/file.h> |
205 | | +#include <wx/snglinst.h> |
206 | | +#include <wx/cmdline.h> |
207 | | +#include <wx/tokenzr.h> |
208 | | +#include <wx/svg/dcsvg.h> |
209 | | + |
210 | | +#include "common.h" |
211 | | +#include "pcbnew.h" |
212 | | +#include "wxPcbStruct.h" |
213 | | +#include "plot_common.h" |
214 | | +#include "gestfich.h" |
215 | | +#include "pcbplot.h" |
216 | | +#include "autorout.h" |
217 | | +#include "cell.h" |
218 | | +#include "worksheet.h" |
219 | | +#include "zones.h" |
220 | | +#include "drag.h" |
221 | | +#include "eda_dde.h" |
222 | | +#include "colors_selection.h" |
223 | | +#include "class_drawpanel.h" |
224 | | + |
225 | | +#include "id.h" |
226 | | + |
227 | | +#include "build_version.h" |
228 | | + |
229 | | +#include "protos.h" |
230 | | +#include "pcbnew_scripted.h" |
231 | | +#include "gendrill.h" |
232 | | +#include "dialog_gendrill.h" |
233 | | +#include "dialog_drc.h" |
234 | | +#include "printout_controler.h" |
235 | | + |
236 | | +extern int g_DrawDefaultLineThickness; |
237 | | + |
238 | | +static const wxCmdLineEntryDesc g_cmdLineDesc [] = |
239 | | +{ |
240 | | + { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), wxT("displays help on the command line parameters"), |
241 | | + wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, |
242 | | + { wxCMD_LINE_SWITCH, wxT("d"), wxT("drill"), wxT("generates a .drl drill file") }, |
243 | | + { wxCMD_LINE_SWITCH, wxT("list-layers"), wxT("list-layers"), wxT("lists the name of all enabled layers in the .brd file") }, |
244 | | + { wxCMD_LINE_OPTION, wxT("p"), wxT("plot"), wxT("plots the board [hpgl|gerber|ps|ps_a4|dxf]"), |
245 | | + wxCMD_LINE_VAL_STRING }, |
246 | | + { wxCMD_LINE_OPTION, wxT("l"), wxT("layers"), wxT("comma separated list of layer names (default: all layers)"), |
247 | | + wxCMD_LINE_VAL_STRING }, |
248 | | + { wxCMD_LINE_OPTION, wxT("ps-pads-drill-opt"), wxT("ps-pads-drill-opt"), wxT("Postscript pads drill option [none|small|real] (default:small)"), |
249 | | + wxCMD_LINE_VAL_STRING }, |
250 | | + { wxCMD_LINE_SWITCH, wxT("mirror"), wxT("mirror"), wxT("mirror plot (HPGL and Postscript only)") }, |
251 | | + { wxCMD_LINE_SWITCH, wxT("fill-all-zones"), wxT("fill-all-zones"), wxT("fill zones before plotting") }, |
252 | | + { wxCMD_LINE_SWITCH, wxT("drc"), wxT("drc"), wxT("generates a design rule check report (.rpt)") }, |
253 | | + { wxCMD_LINE_SWITCH, wxT("svg"), wxT("svg"), wxT("plots the board in SVG format") }, |
254 | | + { wxCMD_LINE_SWITCH, wxT("svg-merge"), wxT("svg-merge-layers"), wxT("merge layers into one SVG file") }, |
255 | | + { wxCMD_LINE_SWITCH, wxT("svg-edge"), wxT("svg-board-edges"), wxT("add board edges to SVG plots") }, |
256 | | + { wxCMD_LINE_SWITCH, wxT("pos"), wxT("pos"), wxT("create front and back .pos component position files") }, |
257 | | + { wxCMD_LINE_SWITCH, wxT("bom"), wxT("bom"), wxT("create a .csv bom") }, |
258 | | + { wxCMD_LINE_SWITCH, wxT("cmp"), wxT("cmp"), wxT("recreate .cmp components file for CvPcb") }, |
259 | | + { wxCMD_LINE_SWITCH, wxT("vrml"), wxT("vrml"), wxT("generates a .wrl vrml board representation") }, |
260 | | + { wxCMD_LINE_PARAM, 0, 0, wxT("<path to .brd file>"), |
261 | | + wxCMD_LINE_VAL_STRING }, |
262 | | + { wxCMD_LINE_NONE } |
263 | | +}; |
264 | | + |
265 | | +bool Pcbnew_Scripted() |
266 | | +{ |
267 | | + wxFileName fn; |
268 | | + wxString str; |
269 | | + WinEDA_PcbFrame* frame = NULL; |
270 | | + wxCommandEvent dummy; |
271 | | + int i; |
272 | | + |
273 | | + WinEDA_App& app = wxGetApp(); |
274 | | + if (app.argc < 2 || app.argv[1][0] != '-') |
275 | | + return false; |
276 | | + g_scripted = true; |
277 | | + wxLog::EnableLogging(false); // this should suppress some wx dialogs |
278 | | + app.InitEDA_Appl( wxT( "PCBnew" ), APP_TYPE_PCBNEW ); |
279 | | + |
280 | | + wxCmdLineParser parser; |
281 | | + parser.SetDesc(g_cmdLineDesc); |
282 | | + parser.SetCmdLine(app.argc, app.argv); |
283 | | + if (parser.Parse()) |
284 | | + return true; |
285 | | + if ( parser.Found( wxT("ps-pads-drill-opt"), &str ) |
286 | | + && str.CmpNoCase( wxT("none") ) |
287 | | + && str.CmpNoCase( wxT("small") ) |
288 | | + && str.CmpNoCase( wxT("real") )) |
289 | | + { |
290 | | + parser.Usage(); |
291 | | + wxPrintf(wxT("Unexpected pads drill option '%ls'.\n"), str.c_str()); |
292 | | + return true; |
293 | | + } |
294 | | + i = parser.Found( _("drill") ) |
295 | | + + parser.Found( _("list-layers") ) |
296 | | + + parser.Found( _("plot") ) |
297 | | + + parser.Found( _("drc") ) |
298 | | + + parser.Found( _("svg") ) |
299 | | + + parser.Found( _("pos") ) |
300 | | + + parser.Found( _("bom") ) |
301 | | + + parser.Found( _("cmp") ) |
302 | | + + parser.Found( _("vrml") ); |
303 | | + if ( !i ) |
304 | | + { |
305 | | + wxPrintf(wxT("One of --drill --list-layers --plot --drc --svg --pos --bom --cmp --vrml must be given.\n")); |
306 | | + return true; |
307 | | + } |
308 | | + if ( i > 1 ) |
309 | | + { |
310 | | + wxPrintf(wxT("Only one of --drill --list-layers --plot --drc --svg --pos --bom --cmp --vrml may be given at a time.\n")); |
311 | | + return true; |
312 | | + } |
313 | | + |
314 | | + fn = parser.GetParam(); |
315 | | + if( fn.GetExt() != PcbFileExtension ) |
316 | | + { |
317 | | + wxLogDebug( wxT( "PcbNew file <%s> has the wrong extension. Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); |
318 | | + fn.SetExt( PcbFileExtension ); |
319 | | + } |
320 | | + if( !fn.FileExists()) |
321 | | + { |
322 | | + wxPrintf( wxT("%ls: file '%ls' does not exist.\n" ), app.argv[0], fn.GetFullPath().c_str() ); |
323 | | + exit(0); |
324 | | + } |
325 | | + wxSetWorkingDirectory( fn.GetPath() ); |
326 | | + |
327 | | + app.InitEDA_Appl( wxT( "PCBnew" ), APP_TYPE_PCBNEW ); |
328 | | + ScreenPcb = new PCB_SCREEN(); |
329 | | + ActiveScreen = ScreenPcb; |
330 | | + app.GetSettings( false /* reopenLastUsedDirectory */ ); |
331 | | + |
332 | | + g_DrawBgColor = BLACK; |
333 | | + frame = new WinEDA_PcbFrame( NULL, wxT( "PcbNew" ), wxPoint( 0, 0 ), wxSize( 600, 400 ) ); |
334 | | + |
335 | | +#if 0 // enable this to see more of the GUI |
336 | | + app.SetTopWindow( frame ); |
337 | | + frame->Show( true ); |
338 | | + frame->Zoom_Automatique( true ); |
339 | | +#endif |
340 | | + |
341 | | + frame->LoadOnePcbFile( fn.GetFullPath() ); |
342 | | + frame->LoadProjectSettings( fn.GetFullPath() ); |
343 | | + |
344 | | + if ( parser.Found( wxT("drill") ) ) |
345 | | + { |
346 | | + DIALOG_GENDRILL* drill_frame = new DIALOG_GENDRILL( frame ); |
347 | | + drill_frame->GenDrillFiles( dummy ); |
348 | | + delete drill_frame; |
349 | | + } |
350 | | + if ( parser.Found( wxT("list-layers") ) ) |
351 | | + { |
352 | | + for ( i = 0; i < NB_LAYERS; i++ ) |
353 | | + { |
354 | | + if( frame->GetBoard()->IsLayerEnabled( i ) ) |
355 | | + { |
356 | | + str = frame->GetBoard()->GetLayerName( i ); |
357 | | + str.Trim( true ); str.Trim( false ); // remove leading and trailing spaces if any |
358 | | + wxPrintf(str + _("\n")); |
359 | | + } |
360 | | + } |
361 | | + } |
362 | | + if ( parser.Found( wxT("plot"), &str ) ) // see pcbplot.cpp |
363 | | + { |
364 | | + bool ps_use_a4; |
365 | | + int plot_format; |
366 | | + wxString ext, layers_str; |
367 | | + |
368 | | + g_pcb_plot_options.PlotLine_Width = g_DrawDefaultLineThickness; |
369 | | + if (!str.CmpNoCase( wxT("ps") ) ) |
370 | | + { |
371 | | + plot_format = PLOT_FORMAT_POST; |
372 | | + ext = wxT( "ps" ); |
373 | | + ps_use_a4 = false; |
374 | | + } |
375 | | + else if ( !str.CmpNoCase( wxT("ps_a4") ) ) |
376 | | + { |
377 | | + plot_format = PLOT_FORMAT_POST; |
378 | | + ext = wxT( "ps" ); |
379 | | + ps_use_a4 = true; |
380 | | + } |
381 | | + else if ( !str.CmpNoCase( wxT("hpgl") ) ) |
382 | | + { |
383 | | + plot_format = PLOT_FORMAT_HPGL; |
384 | | + ext = wxT( "plt" ); |
385 | | + } |
386 | | + else if ( !str.CmpNoCase( wxT("gerber") ) ) |
387 | | + { |
388 | | + plot_format = PLOT_FORMAT_GERBER; |
389 | | + ext = wxT( "pho" ); |
390 | | + } |
391 | | + else if ( !str.CmpNoCase( wxT("dxf") ) ) |
392 | | + { |
393 | | + plot_format = PLOT_FORMAT_DXF; |
394 | | + ext = wxT( "dxf" ); |
395 | | + } |
396 | | + else |
397 | | + { |
398 | | + parser.Usage(); |
399 | | + wxPrintf(wxT("Unexpected plot type '%ls'.\n"), str.c_str()); |
400 | | + exit(0); |
401 | | + } |
402 | | + |
403 | | + // --ps-pads-drill-opt |
404 | | + if ( plot_format == PLOT_FORMAT_POST && parser.Found( wxT("ps-pads-drill-opt"), &str ) ) |
405 | | + { |
406 | | + if (!str.CmpNoCase( wxT("none") ) ) |
407 | | + g_pcb_plot_options.DrillShapeOpt = PCB_Plot_Options::NO_DRILL_SHAPE; |
408 | | + else if ( !str.CmpNoCase( wxT("small") ) ) |
409 | | + g_pcb_plot_options.DrillShapeOpt = PCB_Plot_Options::SMALL_DRILL_SHAPE; |
410 | | + else if ( !str.CmpNoCase( wxT("real") ) ) |
411 | | + g_pcb_plot_options.DrillShapeOpt = PCB_Plot_Options::FULL_DRILL_SHAPE; |
412 | | + else |
413 | | + { |
414 | | + parser.Usage(); |
415 | | + wxPrintf(wxT("Unexpected Postscript pads drill option '%ls'.\n"), str.c_str()); |
416 | | + exit(0); |
417 | | + } |
418 | | + } |
419 | | + |
420 | | + // --mirror |
421 | | + if ( parser.Found( wxT("mirror") ) ) |
422 | | + g_pcb_plot_options.PlotOrient = PLOT_MIROIR; |
423 | | + |
424 | | + if ( parser.Found( wxT("fill-all-zones") ) ) |
425 | | + frame->Fill_All_Zones( false /* verbose */ ); |
426 | | + |
427 | | + parser.Found( wxT("layers"), &layers_str ); |
428 | | + wxStringTokenizer tokenizer( layers_str, _(",") ); |
429 | | + int layer_i = 0; |
430 | | + wxString layername; |
431 | | + while ( ( layers_str.IsEmpty() && layer_i < NB_LAYERS ) || tokenizer.HasMoreTokens() ) |
432 | | + { |
433 | | + if ( layers_str.IsEmpty() ) |
434 | | + { |
435 | | + if( !frame->GetBoard()->IsLayerEnabled( layer_i ) ) |
436 | | + { |
437 | | + layer_i++; |
438 | | + continue; |
439 | | + } |
440 | | + layername = frame->GetBoard()->GetLayerName( layer_i ); |
441 | | + layername.Trim( true ); layername.Trim( false ); // remove leading and trailing spaces if any |
442 | | + layer_i++; |
443 | | + } |
444 | | + else |
445 | | + { |
446 | | + layername = tokenizer.GetNextToken(); |
447 | | + for( layer_i = 0; layer_i < NB_LAYERS; layer_i++ ) |
448 | | + { |
449 | | + str = frame->GetBoard()->GetLayerName( layer_i ); |
450 | | + str.Trim( true ); str.Trim( false ); // remove leading and trailing spaces if any |
451 | | + if ( !str.Cmp( layername ) ) |
452 | | + break; |
453 | | + } |
454 | | + if (layer_i >= NB_LAYERS) |
455 | | + { |
456 | | + wxFprintf( stderr, _( "Unknown layer name '%ls'\n" ), layername.c_str() ); |
457 | | + continue; |
458 | | + } |
459 | | + } |
460 | | + fn = ScreenPcb->m_FileName; |
461 | | + fn.SetName( fn.GetName() + wxT( "-" ) + layername ); |
462 | | + |
463 | | + // Use Gerber Extensions based on layer number |
464 | | + // (See http://en.wikipedia.org/wiki/Gerber_File) |
465 | | + if( (plot_format == PLOT_FORMAT_GERBER) && true /* always use gerber extensions */ ) |
466 | | + { |
467 | | + switch( layer_i ) |
468 | | + { |
469 | | + case LAYER_N_FRONT: |
470 | | + fn.SetExt( wxT( "gtl" ) ); |
471 | | + break; |
472 | | + |
473 | | + case LAYER_N_2: |
474 | | + case LAYER_N_3: |
475 | | + case LAYER_N_4: |
476 | | + case LAYER_N_5: |
477 | | + case LAYER_N_6: |
478 | | + case LAYER_N_7: |
479 | | + case LAYER_N_8: |
480 | | + case LAYER_N_9: |
481 | | + case LAYER_N_10: |
482 | | + case LAYER_N_11: |
483 | | + case LAYER_N_12: |
484 | | + case LAYER_N_13: |
485 | | + case LAYER_N_14: |
486 | | + case LAYER_N_15: |
487 | | + |
488 | | + // TODO: see if we use .gbr or a layer identifier (gb1 .. gbnn ?) |
489 | | + // according to the new internal layers designation |
490 | | + // (1 is the first internal layer from the front layer) |
491 | | + fn.SetExt( wxT( "gbr" ) ); |
492 | | + break; |
493 | | + |
494 | | + case LAYER_N_BACK: |
495 | | + fn.SetExt( wxT( "gbl" ) ); |
496 | | + break; |
497 | | + |
498 | | + case ADHESIVE_N_BACK: |
499 | | + fn.SetExt( wxT( "gba" ) ); |
500 | | + break; |
501 | | + |
502 | | + case ADHESIVE_N_FRONT: |
503 | | + fn.SetExt( wxT( "gta" ) ); |
504 | | + break; |
505 | | + |
506 | | + case SOLDERPASTE_N_BACK: |
507 | | + fn.SetExt( wxT( "gbp" ) ); |
508 | | + break; |
509 | | + |
510 | | + case SOLDERPASTE_N_FRONT: |
511 | | + fn.SetExt( wxT( "gtp" ) ); |
512 | | + break; |
513 | | + |
514 | | + case SILKSCREEN_N_BACK: |
515 | | + fn.SetExt( wxT( "gbo" ) ); |
516 | | + break; |
517 | | + |
518 | | + case SILKSCREEN_N_FRONT: |
519 | | + fn.SetExt( wxT( "gto" ) ); |
520 | | + break; |
521 | | + |
522 | | + case SOLDERMASK_N_BACK: |
523 | | + fn.SetExt( wxT( "gbs" ) ); |
524 | | + break; |
525 | | + |
526 | | + case SOLDERMASK_N_FRONT: |
527 | | + fn.SetExt( wxT( "gts" ) ); |
528 | | + break; |
529 | | + |
530 | | + case DRAW_N: |
531 | | + case COMMENT_N: |
532 | | + case ECO1_N: |
533 | | + case ECO2_N: |
534 | | + case EDGE_N: |
535 | | + default: |
536 | | + fn.SetExt( wxT( "gbr" ) ); |
537 | | + break; |
538 | | + } |
539 | | + } |
540 | | + else |
541 | | + { |
542 | | + fn.SetExt( ext ); |
543 | | + } |
544 | | + |
545 | | + bool success = false; |
546 | | + |
547 | | + switch( plot_format ) |
548 | | + { |
549 | | + case PLOT_FORMAT_POST: |
550 | | + success = frame->Genere_PS( fn.GetFullPath(), layer_i, ps_use_a4, |
551 | | + FILLED /* trace_mode */ ); |
552 | | + break; |
553 | | + |
554 | | + case PLOT_FORMAT_GERBER: |
555 | | + success = frame->Genere_GERBER( fn.GetFullPath(), layer_i, |
556 | | + false /* PlotOriginIsAuxAxis */, |
557 | | + FILLED /* trace_mode */ ); |
558 | | + break; |
559 | | + |
560 | | + case PLOT_FORMAT_HPGL: |
561 | | + success = frame->Genere_HPGL( fn.GetFullPath(), layer_i, |
562 | | + FILLED /* trace_mode */ ); |
563 | | + break; |
564 | | + |
565 | | + case PLOT_FORMAT_DXF: |
566 | | + success = frame->Genere_DXF( fn.GetFullPath(), layer_i, |
567 | | + FILLED /* trace_mode */ ); |
568 | | + break; |
569 | | + } |
570 | | + |
571 | | + // Print diags in messages box: |
572 | | + wxString msg; |
573 | | + if( !success ) |
574 | | + wxFprintf( stderr, _( "Unable to create <%s>\n" ), GetChars( fn.GetFullPath() ) ); |
575 | | + } |
576 | | + } |
577 | | + if ( parser.Found( wxT("drc") ) ) // drc_stuff.h drc.cpp dialog_drc.{h,cpp} |
578 | | + { |
579 | | + fn = ScreenPcb->m_FileName; |
580 | | + fn.SetExt( _("rpt") ); |
581 | | + |
582 | | + // if you get a segfault, try adding frame->m_drc->ShowDialog() to run through the GUI codepath |
583 | | + frame->m_drc->updatePointers(); |
584 | | + frame->m_drc->SetSettings(true, // Pad to pad DRC test enabled |
585 | | + true, // unconnected pdas DRC test enabled |
586 | | + true, // DRC test for zones enabled |
587 | | + fn.GetFullPath(), // report file name |
588 | | + true /* aSaveReport */ ); |
589 | | + frame->m_drc->m_pcb->m_Status_Pcb = 0; // Force full connectivity and ratsnest recalculations |
590 | | + frame->m_drc->RunTests(); |
591 | | + FILE* fp = wxFopen( fn.GetFullPath(), wxT( "w" ) ); |
592 | | + { // strings should match dialog_drc.cpp:DIALOG_DRC_CONTROL::writeReport() |
593 | | + int count; |
594 | | + |
595 | | + fprintf( fp, "** Drc report for %s **\n", |
596 | | + CONV_TO_UTF8( ScreenPcb->m_FileName ) ); |
597 | | + |
598 | | + wxDateTime now = wxDateTime::Now(); |
599 | | + fprintf( fp, "** Created on %s **\n", CONV_TO_UTF8( now.Format( wxT( "%F %T" ) ) ) ); |
600 | | + |
601 | | + class DRC_LIST_MARKERS* markers = new DRC_LIST_MARKERS( frame->m_drc->m_pcb ); |
602 | | + count = markers->GetCount(); |
603 | | + fprintf( fp, "\n** Found %d DRC errors **\n", count ); |
604 | | + for ( i = 0; i < count; i++ ) |
605 | | + fprintf( fp, "%s", CONV_TO_UTF8( markers->GetItem( i )->ShowReport()) ); |
606 | | + delete markers; |
607 | | + |
608 | | + class DRC_LIST_UNCONNECTED* unconnected = new DRC_LIST_UNCONNECTED( &frame->m_drc->m_unconnected ); |
609 | | + count = unconnected->GetCount(); |
610 | | + fprintf( fp, "\n** Found %d unconnected pads **\n", count ); |
611 | | + for ( i = 0; i < count; i++ ) |
612 | | + fprintf( fp, "%s", CONV_TO_UTF8( unconnected->GetItem( i )->ShowReport()) ); |
613 | | + delete unconnected; |
614 | | + |
615 | | + fprintf( fp, "\n** End of Report **\n" ); |
616 | | + } |
617 | | + fclose( fp ); |
618 | | + } |
619 | | + if ( parser.Found( wxT("svg") ) ) // see dialog_SVG_print.cpp:DIALOG_SVG_PRINT::DrawPage() |
620 | | + { |
621 | | + BASE_SCREEN* screen = frame->GetBaseScreen(); |
622 | | + wxSize SheetSize; // Sheet size in internal units |
623 | | + wxString layers_str; |
624 | | + PRINT_PARAMETERS print_params; |
625 | | + long PrintMaskLayer; |
626 | | + int layer_i; |
627 | | + wxSVGFileDC* dc; |
628 | | + |
629 | | + screen->m_DrawOrg.x = screen->m_DrawOrg.y = 0; |
630 | | + screen->m_StartVisu.x = screen->m_StartVisu.y = 0; |
631 | | + SheetSize = screen->m_CurrentSheetDesc->m_Size; // size in 1/1000 inch |
632 | | + SheetSize.x *= frame->m_InternalUnits / 1000; |
633 | | + SheetSize.y *= frame->m_InternalUnits / 1000; // size in pixels |
634 | | + screen->SetScalingFactor( 1.0 ); |
635 | | + screen->m_IsPrinting = true; |
636 | | + float dpi = (float)frame->m_InternalUnits; |
637 | | + |
638 | | + frame->DrawPanel->m_ClipBox.SetX( 0 ); |
639 | | + frame->DrawPanel->m_ClipBox.SetY( 0 ); |
640 | | + frame->DrawPanel->m_ClipBox.SetWidth( 0x7FFFFF0 ); |
641 | | + frame->DrawPanel->m_ClipBox.SetHeight( 0x7FFFFF0 ); |
642 | | + |
643 | | + print_params.m_DrillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE; |
644 | | + print_params.m_Print_Sheet_Ref = false; // reference in bottom-right corner |
645 | | + |
646 | | + SetLocaleTo_C_standard(); // Switch the locale to standard C (needed |
647 | | + // to print floating point numbers like 1.3) |
648 | | + int bg_color = g_DrawBgColor; |
649 | | + g_DrawBgColor = WHITE; |
650 | | + |
651 | | + PrintMaskLayer = 0; |
652 | | + if ( parser.Found( wxT("layers"), &layers_str ) ) |
653 | | + { |
654 | | + wxStringTokenizer tokenizer( layers_str, _(",") ); |
655 | | + layer_i = 0; |
656 | | + wxString layername; |
657 | | + while ( tokenizer.HasMoreTokens() ) |
658 | | + { |
659 | | + layername = tokenizer.GetNextToken(); |
660 | | + for( layer_i = 0; layer_i < NB_LAYERS; layer_i++ ) |
661 | | + { |
662 | | + str = frame->GetBoard()->GetLayerName( layer_i ); |
663 | | + str.Trim( true ); str.Trim( false ); // remove leading and trailing spaces if any |
664 | | + if ( !str.Cmp( layername ) ) |
665 | | + break; |
666 | | + } |
667 | | + if (layer_i >= NB_LAYERS) |
668 | | + { |
669 | | + wxFprintf( stderr, _( "Unknown layer name '%ls'\n" ), layername.c_str() ); |
670 | | + continue; |
671 | | + } |
672 | | + PrintMaskLayer |= 1 << layer_i; |
673 | | + } |
674 | | + } |
675 | | + else |
676 | | + { |
677 | | + for ( layer_i = 0; layer_i < NB_LAYERS; layer_i++ ) |
678 | | + { |
679 | | + if ( frame->GetBoard()->IsLayerEnabled( layer_i ) ) |
680 | | + PrintMaskLayer |= 1 << layer_i; |
681 | | + } |
682 | | + } |
683 | | + |
684 | | + bool SvgMergeLayers = parser.Found( wxT("svg-merge-layers") ); |
685 | | + bool SvgEdgeLayer = parser.Found( wxT("svg-board-edges") ); |
686 | | + |
687 | | + for ( layer_i = 0; layer_i < NB_LAYERS; layer_i++ ) |
688 | | + { |
689 | | + long LayerMask; |
690 | | + |
691 | | + fn = ScreenPcb->m_FileName; |
692 | | + fn.SetExt( _("svg") ); |
693 | | + if ( SvgMergeLayers ) |
694 | | + { |
695 | | + fn.SetName( fn.GetName() + wxT( "-brd" ) ); |
696 | | + LayerMask = PrintMaskLayer; |
697 | | + } |
698 | | + else |
699 | | + { |
700 | | + if ( !(PrintMaskLayer & (1 << layer_i) )) |
701 | | + continue; |
702 | | + str = frame->GetBoard()->GetLayerName( layer_i ); |
703 | | + str.Trim( true ); str.Trim( false ); // remove leading and trailing spaces if any |
704 | | + fn.SetName( fn.GetName() + wxT( "-" ) + str ); |
705 | | + LayerMask = 1 << layer_i; |
706 | | + } |
707 | | + if ( SvgEdgeLayer ) |
708 | | + LayerMask |= EDGE_LAYER; |
709 | | + |
710 | | + dc = new wxSVGFileDC( fn.GetFullPath(), SheetSize.x, SheetSize.y, dpi ); |
711 | | + GRResetPenAndBrush( dc ); |
712 | | + frame->PrintPage( dc, false /* aPrint_Frame_Ref */, LayerMask, false /* aPrintMirrorMode */, &print_params); |
713 | | + delete dc; |
714 | | + dc = 0; |
715 | | + |
716 | | + if ( SvgMergeLayers ) |
717 | | + break; |
718 | | + } |
719 | | + g_DrawBgColor = bg_color; |
720 | | + SetLocaleTo_Default(); // revert to the current locale |
721 | | + screen->m_IsPrinting = false; |
722 | | + } |
723 | | + |
724 | | + if ( parser.Found( wxT("pos") ) ) // see gen_modules_placefile.cpp:WinEDA_PcbFrame::GenModulesPosition() |
725 | | + frame->GenModulesPosition( dummy ); |
726 | | + |
727 | | + if ( parser.Found( wxT("bom") ) ) // see build_BOM_from_board.cpp:WinEDA_PcbFrame::RecreateBOMFileFromBoard() |
728 | | + frame->RecreateBOMFileFromBoard( dummy ); |
729 | | + |
730 | | + if ( parser.Found( wxT("cmp") ) ) // see xchgmod.cpp:WinEDA_PcbFrame::RecreateCmpFileFromBoard() |
731 | | + frame->RecreateCmpFileFromBoard( dummy ); |
732 | | + |
733 | | + if ( parser.Found( wxT("vrml") ) ) // see export_vrml.cpp:WinEDA_PcbFrame::OnExportVRML() |
734 | | + { |
735 | | + wxString subDirFor3Dshapes( _( "shapes3D" ) ); |
736 | | + |
737 | | + fn = ScreenPcb->m_FileName; |
738 | | + fn.SetExt( _("wrl") ); |
739 | | + if( ! wxDirExists( subDirFor3Dshapes ) ) |
740 | | + wxMkdir( subDirFor3Dshapes ); |
741 | | + frame->ExportVRML_File( fn.GetFullPath(), 1.0 /* aScale */, true /* aExport3DFile */, subDirFor3Dshapes ); |
742 | | + } |
743 | | + delete frame; |
744 | | + return true; |
745 | | +} |
746 | | diff -ruN kicad.orig/pcbnew/pcbnew_scripted.h kicad/pcbnew/pcbnew_scripted.h |
747 | | +++ kicad/pcbnew/pcbnew_scripted.h 2010-12-22 18:47:58.774932729 +0000 |
748 | | @@ -0,0 +1,7 @@ |
749 | | +///////////////////////////////////////////////////////////////////////////// |
750 | | +// Name: pcbnew_scripted.h |
751 | | +// Copyright: Wolfgang Spraul |
752 | | +// Licence: GPL v3 or higher |
753 | | +///////////////////////////////////////////////////////////////////////////// |
754 | | + |
755 | | +bool Pcbnew_Scripted(); |
756 | | diff -ruN kicad.orig/pcbnew/xchgmod.cpp kicad/pcbnew/xchgmod.cpp |
757 | | +++ kicad/pcbnew/xchgmod.cpp 2010-12-24 21:11:13.642781922 +0000 |
758 | | @@ -577,6 +577,7 @@ |
759 | | wildcard = _( "Component files (." ) + NetCmpExtBuffer + wxT( ")|*." ) + |
760 | | NetCmpExtBuffer; |
761 | | |
762 | | + if (!g_scripted) { |
763 | | wxFileDialog dlg( this, _( "Save Component Files" ), wxGetCwd(), |
764 | | fn.GetFullName(), wildcard, |
765 | | wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); |
766 | | @@ -585,6 +586,7 @@ |
767 | | return; |
768 | | |
769 | | fn = dlg.GetPath(); |
770 | | + } |
771 | | |
772 | | FichCmp = wxFopen( fn.GetFullPath(), wxT( "wt" ) ); |
773 | | if( FichCmp == NULL ) |
kicad-patches/scripted.patch |
| 1 | diff -ruN kicad.orig/common/confirm.cpp kicad/common/confirm.cpp |
| 2 | --- kicad.orig/common/confirm.cpp 2010-10-19 08:48:07.000000000 +0000 |
| 3 | @@ -66,6 +66,7 @@ |
| 4 | * See not above as to why this doesn't work. */ |
| 5 | } |
| 6 | |
| 7 | +bool g_IsScripted = false; |
| 8 | |
| 9 | /* Display an error or warning message. |
| 10 | * If display time > 0 the dialog disappears after displayTime 0.1 seconds |
| 11 | @@ -75,6 +76,12 @@ |
| 12 | { |
| 13 | wxMessageDialog* dialog; |
| 14 | |
| 15 | + if (g_IsScripted) |
| 16 | + { |
| 17 | + wxFprintf( stderr, text + _("\n") ); |
| 18 | + return; |
| 19 | + } |
| 20 | + |
| 21 | if( displaytime > 0 ) |
| 22 | dialog = new WinEDA_MessageDialog( parent, text, _( "Warning" ), |
| 23 | wxOK | wxICON_INFORMATION, |
| 24 | @@ -95,6 +102,11 @@ |
| 25 | { |
| 26 | wxMessageDialog* dialog; |
| 27 | |
| 28 | + if (g_IsScripted) |
| 29 | + { |
| 30 | + wxPrintf( text + _("\n") ); |
| 31 | + return; |
| 32 | + } |
| 33 | dialog = new WinEDA_MessageDialog( parent, text, _( "Info:" ), |
| 34 | wxOK | wxICON_INFORMATION, displaytime ); |
| 35 | |
| 36 | diff -ruN kicad.orig/common/edaappl.cpp kicad/common/edaappl.cpp |
| 37 | --- kicad.orig/common/edaappl.cpp 2010-10-19 08:48:07.000000000 +0000 |
| 38 | @@ -272,6 +272,7 @@ |
| 39 | wxString EnvLang; |
| 40 | |
| 41 | m_Id = aId; |
| 42 | +if (!g_IsScripted) |
| 43 | m_Checker = new wxSingleInstanceChecker( aName.Lower() + wxT( "-" ) + |
| 44 | wxGetUserId() ); |
| 45 | |
| 46 | diff -ruN kicad.orig/eeschema/CMakeLists.txt kicad/eeschema/CMakeLists.txt |
| 47 | --- kicad.orig/eeschema/CMakeLists.txt 2010-10-19 08:48:07.000000000 +0000 |
| 48 | @@ -83,6 +83,7 @@ |
| 49 | eeredraw.cpp |
| 50 | eeschema.cpp |
| 51 | eeschema_config.cpp |
| 52 | + eeschema_scripted.cpp |
| 53 | erc.cpp |
| 54 | events_called_functions_for_edit.cpp |
| 55 | files-io.cpp |
| 56 | diff -ruN kicad.orig/eeschema/dialog_build_BOM.h kicad/eeschema/dialog_build_BOM.h |
| 57 | --- kicad.orig/eeschema/dialog_build_BOM.h 2010-10-19 08:48:07.000000000 +0000 |
| 58 | @@ -12,6 +12,7 @@ |
| 59 | |
| 60 | class DIALOG_BUILD_BOM : public DIALOG_BUILD_BOM_BASE |
| 61 | { |
| 62 | +friend class EESCHEMA_SCRIPTED; |
| 63 | private: |
| 64 | WinEDA_DrawFrame * m_Parent; |
| 65 | wxConfig* m_Config; |
| 66 | diff -ruN kicad.orig/eeschema/dialog_erc.h kicad/eeschema/dialog_erc.h |
| 67 | --- kicad.orig/eeschema/dialog_erc.h 2010-10-19 08:48:07.000000000 +0000 |
| 68 | @@ -30,6 +30,7 @@ |
| 69 | |
| 70 | class DIALOG_ERC : public DIALOG_ERC_BASE |
| 71 | { |
| 72 | +friend class EESCHEMA_SCRIPTED; |
| 73 | DECLARE_EVENT_TABLE() |
| 74 | |
| 75 | private: |
| 76 | diff -ruN kicad.orig/eeschema/dialog_SVG_print.cpp kicad/eeschema/dialog_SVG_print.cpp |
| 77 | --- kicad.orig/eeschema/dialog_SVG_print.cpp 2010-10-19 08:48:07.000000000 +0000 |
| 78 | @@ -33,6 +33,7 @@ |
| 79 | |
| 80 | class DIALOG_SVG_PRINT : public DIALOG_SVG_PRINT_base |
| 81 | { |
| 82 | +friend void ScriptedPrintSVGDoc( WinEDA_DrawFrame* frame, bool aPrintAll, bool aPrint_Sheet_Ref, bool aPrintBlackAndWhite ); |
| 83 | private: |
| 84 | WinEDA_DrawFrame * m_Parent; |
| 85 | wxConfig* m_Config; |
| 86 | @@ -57,6 +58,19 @@ |
| 87 | bool aPrint_Sheet_Ref = false); |
| 88 | }; |
| 89 | |
| 90 | +void ScriptedPrintSVGDoc( WinEDA_DrawFrame* frame, bool aPrintAll, bool aPrint_Sheet_Ref, bool aPrintBlackAndWhite ) |
| 91 | +{ |
| 92 | + // TBD: It would be better to iterate over the pages ourselves and use |
| 93 | + // DrawSVGPage() directly, bypassing the GUI dialog... |
| 94 | + class DIALOG_SVG_PRINT* dlg = new DIALOG_SVG_PRINT( frame ); |
| 95 | + dlg->m_DialogPenWidth->SetValue( |
| 96 | + ReturnStringFromValue(g_UserUnit, g_DrawDefaultLineThickness, |
| 97 | + dlg->m_Parent->m_InternalUnits ) ); |
| 98 | + dlg->m_ModeColorOption->SetSelection( aPrintBlackAndWhite ); |
| 99 | + dlg->PrintSVGDoc( aPrintAll, aPrint_Sheet_Ref ); |
| 100 | + delete dlg; |
| 101 | +} |
| 102 | + |
| 103 | |
| 104 | /* Prepare the data structures of print management and display the dialog |
| 105 | * window for printing sheets. |
| 106 | diff -ruN kicad.orig/eeschema/eeschema.cpp kicad/eeschema/eeschema.cpp |
| 107 | --- kicad.orig/eeschema/eeschema.cpp 2010-12-28 15:30:43.309392002 +0000 |
| 108 | @@ -15,6 +15,7 @@ |
| 109 | #include "program.h" |
| 110 | #include "general.h" |
| 111 | #include "protos.h" |
| 112 | +#include "eeschema_scripted.h" |
| 113 | |
| 114 | #include <wx/snglinst.h> |
| 115 | |
| 116 | @@ -128,6 +129,9 @@ |
| 117 | |
| 118 | g_DebugLevel = 0; // Debug level */ |
| 119 | |
| 120 | + if ( g_EESchemaScripted.Run() ) |
| 121 | + return false; |
| 122 | + |
| 123 | InitEDA_Appl( wxT( "EESchema" ), APP_TYPE_EESCHEMA ); |
| 124 | |
| 125 | if( m_Checker && m_Checker->IsAnotherRunning() ) |
| 126 | diff -ruN kicad.orig/eeschema/eeschema_scripted.cpp kicad/eeschema/eeschema_scripted.cpp |
| 127 | --- kicad.orig/eeschema/eeschema_scripted.cpp 1970-01-01 00:00:00.000000000 +0000 |
| 128 | @@ -0,0 +1,251 @@ |
| 129 | +///////////////////////////////////////////////////////////////////////////// |
| 130 | +// Name: eeschema_scripted.cpp |
| 131 | +// Copyright: Werner Almesberger, Wolfgang Spraul |
| 132 | +// Licence: GPL v2 or higher |
| 133 | +///////////////////////////////////////////////////////////////////////////// |
| 134 | + |
| 135 | +#include "fctsys.h" |
| 136 | +#include "appl_wxstruct.h" |
| 137 | +#include "common.h" |
| 138 | +#include "program.h" |
| 139 | +#include "general.h" |
| 140 | +#include "netlist.h" |
| 141 | +#include "protos.h" |
| 142 | +#include "gr_basic.h" |
| 143 | +#include "plotps.h" |
| 144 | +#include "wx/cmdline.h" |
| 145 | +#include "dialog_build_BOM.h" |
| 146 | +#include "dialog_SVG_print_base.h" |
| 147 | +#include "dialog_erc.h" |
| 148 | +#include "plotdxf.h" |
| 149 | +#include "class_drawsheetpath.h" |
| 150 | +#include "eeschema_scripted.h" |
| 151 | + |
| 152 | +EESCHEMA_SCRIPTED g_EESchemaScripted; |
| 153 | + |
| 154 | +static const wxCmdLineEntryDesc g_cmdLineDesc [] = |
| 155 | +{ |
| 156 | + { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), wxT("displays help on the command line parameters"), |
| 157 | + wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, |
| 158 | + |
| 159 | + { wxCMD_LINE_SWITCH, wxT("l"), wxT("list-sheets"), wxT("list schematics pages") }, |
| 160 | + |
| 161 | + { wxCMD_LINE_OPTION, wxT("px"), wxT("plotx"), wxT("plots the board [ps|svg|dxf]"), |
| 162 | + wxCMD_LINE_VAL_STRING }, |
| 163 | + { wxCMD_LINE_SWITCH, wxT("plotx-bw"), wxT("plotx-bw"), wxT("plot: black & white (default: color)") }, |
| 164 | + { wxCMD_LINE_SWITCH, wxT("plotx-sheetref"), wxT("plotx-sheetref"), wxT("plot: print sheet reference (default: off)") }, |
| 165 | + { wxCMD_LINE_SWITCH, wxT("p"), wxT("plot"), wxT("plots the schematics (deprecated, use --plotx=ps --plotx-bw)") }, |
| 166 | + |
| 167 | + { wxCMD_LINE_SWITCH, wxT("b"), wxT("bom"), wxT("generate bill of materials (.bom)") }, |
| 168 | + { wxCMD_LINE_SWITCH, wxT("e"), wxT("erc"), wxT("generate electric rules check (.erc) file") }, |
| 169 | + { wxCMD_LINE_SWITCH, wxT("n"), wxT("netlist"), wxT("generate netlist (.net)") }, |
| 170 | + { wxCMD_LINE_PARAM, 0, 0, wxT("<path to .sch file>"), |
| 171 | + wxCMD_LINE_VAL_STRING }, |
| 172 | + { wxCMD_LINE_NONE } |
| 173 | +}; |
| 174 | + |
| 175 | +bool ScriptedDrawSVGPage( WinEDA_DrawFrame * frame, |
| 176 | + const wxString& FullFileName, BASE_SCREEN* screen, |
| 177 | + bool aPrintBlackAndWhite = false, |
| 178 | + bool aPrint_Sheet_Ref = false); |
| 179 | + |
| 180 | +bool EESCHEMA_SCRIPTED::Run() |
| 181 | +{ |
| 182 | + wxFileName fn; |
| 183 | + WinEDA_SchematicFrame* frame; |
| 184 | + wxCommandEvent DummyCmd; |
| 185 | + wxString str; |
| 186 | + int i; |
| 187 | + |
| 188 | + WinEDA_App& app = wxGetApp(); |
| 189 | + if (app.argc < 2 || app.argv[1][0] != '-') |
| 190 | + return false; |
| 191 | + g_IsScripted = true; |
| 192 | + wxLog::EnableLogging(false); // this should suppress some wx dialogs |
| 193 | + app.InitEDA_Appl( wxT( "EESchema" ), APP_TYPE_EESCHEMA ); |
| 194 | + |
| 195 | + wxCmdLineParser parser; |
| 196 | + parser.SetDesc(g_cmdLineDesc); |
| 197 | + parser.SetCmdLine(app.argc, app.argv); |
| 198 | + if (parser.Parse()) |
| 199 | + return true; |
| 200 | + |
| 201 | + i = parser.Found( _("list-sheets") ) |
| 202 | + + parser.Found( _("plot") ) |
| 203 | + + parser.Found( _("plotx") ) |
| 204 | + + parser.Found( _("bom") ) |
| 205 | + + parser.Found( _("erc") ) |
| 206 | + + parser.Found( _("netlist") ); |
| 207 | + if ( !i ) |
| 208 | + { |
| 209 | + wxPrintf(wxT("One of --list-sheets --plot --plotx --bom --erc --netlist must be given.\n")); |
| 210 | + return true; |
| 211 | + } |
| 212 | + if ( i > 1 ) |
| 213 | + { |
| 214 | + wxPrintf(wxT("Only one of --list-sheets --plot --plotx --bom --erc --netlist may be given at a time.\n")); |
| 215 | + return true; |
| 216 | + } |
| 217 | + |
| 218 | + // parse plotting parameters |
| 219 | + enum PlotCommand { |
| 220 | + PLOT_NONE, |
| 221 | + PLOT_PS, |
| 222 | + PLOT_SVG, |
| 223 | + PLOT_DXF |
| 224 | + } PlotCmd; |
| 225 | + bool PlotBW; |
| 226 | + bool PlotSheetRef; |
| 227 | + |
| 228 | + PlotCmd = PLOT_NONE; |
| 229 | + if ( parser.Found( wxT("plot") ) ) // legacy parameter originally introduced by |
| 230 | + // Werner, still used in schhist and other places |
| 231 | + { |
| 232 | + PlotCmd = PLOT_PS; |
| 233 | + PlotBW = true; |
| 234 | + PlotSheetRef = false; |
| 235 | + } |
| 236 | + else if ( parser.Found( _("plotx"), &str ) ) |
| 237 | + { |
| 238 | + if (!str.CmpNoCase( wxT("ps") ) ) |
| 239 | + PlotCmd = PLOT_PS; |
| 240 | + else if ( !str.CmpNoCase( wxT("svg") ) ) |
| 241 | + PlotCmd = PLOT_SVG; |
| 242 | + else if ( !str.CmpNoCase( wxT("dxf") ) ) |
| 243 | + PlotCmd = PLOT_DXF; |
| 244 | + else |
| 245 | + { |
| 246 | + parser.Usage(); |
| 247 | + wxPrintf(wxT("Unexpected plot format '%ls'.\n"), str.c_str()); |
| 248 | + return true; |
| 249 | + } |
| 250 | + PlotBW = parser.Found( _("plotx-bw") ); |
| 251 | + PlotSheetRef = parser.Found( _("plotx-sheetref") ); |
| 252 | + } |
| 253 | + |
| 254 | + fn = parser.GetParam(); |
| 255 | + if( fn.GetExt() != SchematicFileExtension ) |
| 256 | + { |
| 257 | + wxLogDebug( wxT( "eeschema file <%s> has the wrong extension. Changing extension to .sch." ), GetChars( fn.GetFullPath() ) ); |
| 258 | + fn.SetExt( PcbFileExtension ); |
| 259 | + } |
| 260 | + if( !fn.FileExists()) |
| 261 | + { |
| 262 | + wxPrintf( wxT("%ls: file '%ls' does not exist.\n" ), app.argv[0], fn.GetFullPath().c_str() ); |
| 263 | + return true; |
| 264 | + } |
| 265 | + wxSetWorkingDirectory( fn.GetPath() ); |
| 266 | + |
| 267 | + g_DrawBgColor = BLACK; |
| 268 | + SeedLayers(); |
| 269 | + frame = new WinEDA_SchematicFrame( NULL, wxT( "EESchema" ), |
| 270 | + wxPoint( 0, 0 ), wxSize( 600, 400 ) ); |
| 271 | + ActiveScreen = frame->GetScreen(); |
| 272 | +#if 0 // enable this to see more of the GUI |
| 273 | + app.SetTopWindow( frame ); |
| 274 | + frame->Show( true ); |
| 275 | +#endif |
| 276 | + if( !frame->LoadOneEEProject( fn.GetFullPath(), false ) ) |
| 277 | + { |
| 278 | + fprintf( stderr, "%ls: can't load\n", fn.GetFullPath().c_str() ); |
| 279 | + return true; |
| 280 | + } |
| 281 | + |
| 282 | + if ( parser.Found( wxT("list-sheets") ) ) // class_drawsheetpath.h |
| 283 | + // dialog_SVG_print.cpp:DIALOG_SVG_PRINT:PrintSVGDoc() |
| 284 | + { |
| 285 | + SCH_SHEET_LIST SheetList( 0 /* aSheet */ ); |
| 286 | + SCH_SHEET_PATH* sheetpath, *oldsheetpath; |
| 287 | + SCH_SHEET_PATH list; |
| 288 | + SCH_SCREEN* schscreen; |
| 289 | + |
| 290 | + oldsheetpath = frame->GetSheet(); |
| 291 | + sheetpath = SheetList.GetFirst(); |
| 292 | + while ( sheetpath ) |
| 293 | + { |
| 294 | + list.Clear(); |
| 295 | + if ( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) ) |
| 296 | + { |
| 297 | + frame->m_CurrentSheet = &list; |
| 298 | + frame->m_CurrentSheet->UpdateAllScreenReferences(); |
| 299 | + frame->SetSheetNumberAndCount(); |
| 300 | + schscreen = frame->m_CurrentSheet->LastScreen(); |
| 301 | + ActiveScreen = schscreen; |
| 302 | + |
| 303 | + wxPrintf( sheetpath->Path() + _(" ") |
| 304 | + + sheetpath->PathHumanReadable() + _(" ") |
| 305 | + + sheetpath->Last()->GetFileName() + _(" ") |
| 306 | + + frame->GetUniqueFilenameForCurrentSheet( ) + wxT( ".sch\n") ); |
| 307 | + } |
| 308 | + sheetpath = SheetList.GetNext(); |
| 309 | + } |
| 310 | + frame->m_CurrentSheet = oldsheetpath; |
| 311 | + frame->m_CurrentSheet->UpdateAllScreenReferences(); |
| 312 | + frame->SetSheetNumberAndCount(); |
| 313 | + } |
| 314 | + else if ( PlotCmd == PLOT_PS ) // plotps.cpp |
| 315 | + { |
| 316 | + // values must be idential to plotps.cpp:PageFormatReq |
| 317 | + enum PageFormatReq { |
| 318 | + PAGE_SIZE_AUTO, |
| 319 | + PAGE_SIZE_A4, |
| 320 | + PAGE_SIZE_A |
| 321 | + }; |
| 322 | + |
| 323 | + WinEDA_PlotPSFrame* PlotPSFrame = new WinEDA_PlotPSFrame( frame ); |
| 324 | + PlotPSFrame->m_Plot_Sheet_Ref->SetValue( PlotSheetRef ); |
| 325 | + |
| 326 | + // Strangely it seems that the plots come out right when 'A4' is |
| 327 | + // selected, even if it's actually not A4 format. But when PAGE_SIZE_AUTO |
| 328 | + // is selected, pages are cut off. Until we understand this better we |
| 329 | + // always use A4. |
| 330 | + PlotPSFrame->m_SizeOption->SetSelection( PAGE_SIZE_A4 ); |
| 331 | + |
| 332 | + PlotPSFrame->m_PlotPSColorOption->SetSelection( !PlotBW ); |
| 333 | + PlotPSFrame->OnPlotPsAllExecuteClick( DummyCmd ); |
| 334 | + delete PlotPSFrame; |
| 335 | + } |
| 336 | + else if ( PlotCmd == PLOT_SVG ) // dialog_SVG_print.cpp:DIALOG_SVG_PRINT::DrawSVGPage() |
| 337 | + { |
| 338 | + void ScriptedPrintSVGDoc( WinEDA_DrawFrame* frame, bool aPrintAll, bool aPrint_Sheet_Ref, bool aPrintBlackAndWhite ); |
| 339 | + ScriptedPrintSVGDoc( frame, true /* aPrintAll */, PlotSheetRef, PlotBW ); |
| 340 | + } |
| 341 | + else if ( PlotCmd == PLOT_DXF ) // plotdxf.cpp:WinEDA_PlotDXFFrame::CreateDXFFile() |
| 342 | + { |
| 343 | + WinEDA_PlotDXFFrame* PlotDXFFrame = new WinEDA_PlotDXFFrame( frame ); |
| 344 | + PlotDXFFrame->m_Plot_Sheet_Ref->SetValue( PlotSheetRef ); |
| 345 | + PlotDXFFrame->m_PlotDXFColorOption->SetSelection( !PlotBW ); |
| 346 | + PlotDXFFrame->OnPlotDXFAllExecuteClick( DummyCmd ); |
| 347 | + delete PlotDXFFrame; |
| 348 | + } |
| 349 | + else if ( parser.Found( wxT("bom") ) ) // see build_BOM.cpp:DIALOG_BUILD_BOM::GenereListeOfItems() |
| 350 | + { |
| 351 | + DIALOG_BUILD_BOM* dlg = new DIALOG_BUILD_BOM( frame ); |
| 352 | + |
| 353 | + dlg->m_ListCmpbyRefItems->SetValue( true ); |
| 354 | + dlg->m_AddFootprintField->SetValue( true ); |
| 355 | + dlg->m_AddAllFields->SetValue( true ); |
| 356 | + |
| 357 | + fn = ActiveScreen->m_FileName; |
| 358 | + fn.SetExt( wxT( "lst" ) ); |
| 359 | + dlg->GenereListeOfItems( fn.GetFullPath(), false /* aIncludeSubComponents */ ); |
| 360 | + delete dlg; |
| 361 | + } |
| 362 | + else if ( parser.Found( wxT("erc") ) ) // erc.cpp:DIALOG_ERC::TestErc() |
| 363 | + { |
| 364 | + DIALOG_ERC* dlg = new DIALOG_ERC( frame ); |
| 365 | + dlg->m_WriteResultOpt->SetValue( true ); |
| 366 | + dlg->TestErc( 0 /* messageList */ ); |
| 367 | + delete dlg; |
| 368 | + } |
| 369 | + else if ( parser.Found( wxT("netlist") ) ) // netlist_control.cpp:WinEDA_SchematicFrame::CreateNetlist() |
| 370 | + { |
| 371 | + frame->BuildNetListBase(); |
| 372 | + fn = ActiveScreen->m_FileName; |
| 373 | + fn.SetExt( wxT( "net" ) ); |
| 374 | + frame->WriteNetListFile( NET_TYPE_PCBNEW /* aFormat */, fn.GetFullPath(), false /* aUse_netnames - only used for Spice */ ); |
| 375 | + } |
| 376 | + |
| 377 | + delete frame; |
| 378 | + return true; |
| 379 | +} |
| 380 | diff -ruN kicad.orig/eeschema/eeschema_scripted.h kicad/eeschema/eeschema_scripted.h |
| 381 | --- kicad.orig/eeschema/eeschema_scripted.h 1970-01-01 00:00:00.000000000 +0000 |
| 382 | @@ -0,0 +1,14 @@ |
| 383 | +///////////////////////////////////////////////////////////////////////////// |
| 384 | +// Name: eeschema_scripted.h |
| 385 | +// Copyright: Wolfgang Spraul |
| 386 | +// Licence: GPL v3 or higher |
| 387 | +///////////////////////////////////////////////////////////////////////////// |
| 388 | + |
| 389 | +class EESCHEMA_SCRIPTED |
| 390 | +{ |
| 391 | +public: |
| 392 | + EESCHEMA_SCRIPTED() { } |
| 393 | + bool Run(); |
| 394 | +}; |
| 395 | + |
| 396 | +extern EESCHEMA_SCRIPTED g_EESchemaScripted; |
| 397 | diff -ruN kicad.orig/eeschema/erc.cpp kicad/eeschema/erc.cpp |
| 398 | --- kicad.orig/eeschema/erc.cpp 2010-12-31 18:11:47.751823001 +0000 |
| 399 | @@ -557,6 +557,7 @@ |
| 400 | fn = g_RootSheet->m_AssociatedScreen->m_FileName; |
| 401 | fn.SetExt( wxT( "erc" ) ); |
| 402 | |
| 403 | +if (!g_IsScripted) { |
| 404 | wxFileDialog dlg( this, _( "ERC File" ), fn.GetPath(), fn.GetFullName(), |
| 405 | _( "Electronic rule check file (.erc)|*.erc" ), |
| 406 | wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); |
| 407 | @@ -570,6 +570,8 @@ |
| 408 | ExecuteFile( this, wxGetApp().GetEditorName(), |
| 409 | QuoteFullPath( fn ) ); |
| 410 | } |
| 411 | +} else |
| 412 | + WriteDiagnosticERC( fn.GetFullPath() ); |
| 413 | } |
| 414 | } |
| 415 | |
| 416 | diff -ruN kicad.orig/include/common.h kicad/include/common.h |
| 417 | --- kicad.orig/include/common.h 2010-10-19 08:48:07.000000000 +0000 |
| 418 | @@ -6,6 +6,8 @@ |
| 419 | #ifndef __INCLUDE__COMMON_H__ |
| 420 | #define __INCLUDE__COMMON_H__ 1 |
| 421 | |
| 422 | +extern bool g_IsScripted; |
| 423 | + |
| 424 | #include "wx/confbase.h" |
| 425 | #include "wx/fileconf.h" |
| 426 | |
| 427 | diff -ruN kicad.orig/include/wxPcbStruct.h kicad/include/wxPcbStruct.h |
| 428 | --- kicad.orig/include/wxPcbStruct.h 2010-10-19 08:48:07.000000000 +0000 |
| 429 | @@ -50,6 +50,7 @@ |
| 430 | class WinEDA_PcbFrame : public WinEDA_BasePcbFrame |
| 431 | { |
| 432 | friend class PCB_LAYER_WIDGET; |
| 433 | + friend bool Pcbnew_Scripted(); |
| 434 | |
| 435 | protected: |
| 436 | |
| 437 | diff -ruN kicad.orig/pcbnew/build_BOM_from_board.cpp kicad/pcbnew/build_BOM_from_board.cpp |
| 438 | --- kicad.orig/pcbnew/build_BOM_from_board.cpp 2010-10-19 08:48:07.000000000 +0000 |
| 439 | @@ -64,6 +64,7 @@ |
| 440 | fn = GetScreen()->m_FileName; |
| 441 | fn.SetExt( CsvFileExtension ); |
| 442 | |
| 443 | + if (!g_IsScripted) { |
| 444 | wxFileDialog dlg( this, _( "Save Bill of Materials" ), wxGetCwd(), |
| 445 | fn.GetFullName(), CsvFileWildcard, |
| 446 | wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); |
| 447 | @@ -72,6 +73,7 @@ |
| 448 | return; |
| 449 | |
| 450 | fn = dlg.GetPath(); |
| 451 | + } |
| 452 | |
| 453 | FichBom = wxFopen( fn.GetFullPath(), wxT( "wt" ) ); |
| 454 | |
| 455 | diff -ruN kicad.orig/pcbnew/CMakeLists.txt kicad/pcbnew/CMakeLists.txt |
| 456 | --- kicad.orig/pcbnew/CMakeLists.txt 2010-10-19 08:48:07.000000000 +0000 |
| 457 | @@ -142,6 +142,7 @@ |
| 458 | onrightclick.cpp |
| 459 | pcbnew.cpp |
| 460 | pcbnew_config.cpp |
| 461 | + pcbnew_scripted.cpp |
| 462 | pcbplot.cpp |
| 463 | plotgerb.cpp |
| 464 | plothpgl.cpp |
| 465 | diff -ruN kicad.orig/pcbnew/dialog_gendrill.h kicad/pcbnew/dialog_gendrill.h |
| 466 | --- kicad.orig/pcbnew/dialog_gendrill.h 2010-10-19 08:48:07.000000000 +0000 |
| 467 | @@ -12,6 +12,7 @@ |
| 468 | |
| 469 | class DIALOG_GENDRILL: public DIALOG_GENDRILL_BASE |
| 470 | { |
| 471 | +friend bool Pcbnew_Scripted(); |
| 472 | |
| 473 | private: |
| 474 | WinEDA_PcbFrame* m_Parent; |
| 475 | diff -ruN kicad.orig/pcbnew/drc_stuff.h kicad/pcbnew/drc_stuff.h |
| 476 | --- kicad.orig/pcbnew/drc_stuff.h 2010-10-19 08:48:07.000000000 +0000 |
| 477 | @@ -136,6 +136,7 @@ |
| 478 | class DRC |
| 479 | { |
| 480 | friend class DIALOG_DRC_CONTROL; |
| 481 | + friend bool Pcbnew_Scripted(); |
| 482 | |
| 483 | private: |
| 484 | |
| 485 | diff -ruN kicad.orig/pcbnew/gendrill.cpp kicad/pcbnew/gendrill.cpp |
| 486 | --- kicad.orig/pcbnew/gendrill.cpp 2010-10-19 08:48:07.000000000 +0000 |
| 487 | @@ -307,6 +307,43 @@ |
| 488 | fn.SetName( fn.GetName() + layer_extend ); |
| 489 | fn.SetExt( DrillFileExtension ); |
| 490 | |
| 491 | + if (g_IsScripted) |
| 492 | + { |
| 493 | + FILE* excellon_dest = wxFopen( fn.GetFullPath(), wxT( "w" ) ); |
| 494 | + if( excellon_dest == 0 ) |
| 495 | + { |
| 496 | + printf("Unable to create %ls.\n", fn.GetFullPath().c_str()); |
| 497 | + exit(0); |
| 498 | + } |
| 499 | + Create_Drill_File_EXCELLON( excellon_dest, s_HoleListBuffer, |
| 500 | + s_ToolListBuffer ); |
| 501 | + |
| 502 | + switch( m_Choice_Drill_Map->GetSelection() ) |
| 503 | + { |
| 504 | + case 0: |
| 505 | + break; |
| 506 | + |
| 507 | + case 1: |
| 508 | + GenDrillMap( fn.GetPath(), s_HoleListBuffer, s_ToolListBuffer, |
| 509 | + PLOT_FORMAT_HPGL ); |
| 510 | + break; |
| 511 | + |
| 512 | + case 2: |
| 513 | + GenDrillMap( fn.GetPath(), s_HoleListBuffer, s_ToolListBuffer, |
| 514 | + PLOT_FORMAT_POST ); |
| 515 | + break; |
| 516 | + |
| 517 | + case 3: |
| 518 | + GenDrillMap( fn.GetPath(), s_HoleListBuffer, s_ToolListBuffer, |
| 519 | + PLOT_FORMAT_GERBER ); |
| 520 | + break; |
| 521 | + |
| 522 | + case 4: |
| 523 | + GenDrillMap( fn.GetPath(), s_HoleListBuffer, s_ToolListBuffer, |
| 524 | + PLOT_FORMAT_DXF ); |
| 525 | + break; |
| 526 | + } |
| 527 | + } else { |
| 528 | wxFileDialog dlg( this, _( "Save Drill File" ), fn.GetPath(), |
| 529 | fn.GetFullName(), DrillFileWildcard, |
| 530 | wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); |
| 531 | @@ -352,6 +389,7 @@ |
| 532 | PLOT_FORMAT_DXF ); |
| 533 | break; |
| 534 | } |
| 535 | + } // !g_IsScripted |
| 536 | |
| 537 | if( !ExistsBuriedVias ) |
| 538 | break; |
| 539 | diff -ruN kicad.orig/pcbnew/pcbnew.cpp kicad/pcbnew/pcbnew.cpp |
| 540 | --- kicad.orig/pcbnew/pcbnew.cpp 2010-10-19 08:48:07.000000000 +0000 |
| 541 | @@ -29,6 +29,7 @@ |
| 542 | #include "build_version.h" |
| 543 | |
| 544 | #include "protos.h" |
| 545 | +#include "pcbnew_scripted.h" |
| 546 | |
| 547 | // Colors for layers and items |
| 548 | COLORS_DESIGN_SETTINGS g_ColorsSettings; |
| 549 | @@ -103,6 +104,9 @@ |
| 550 | wxFileName fn; |
| 551 | WinEDA_PcbFrame* frame = NULL; |
| 552 | |
| 553 | + if( Pcbnew_Scripted() ) |
| 554 | + return false; |
| 555 | + |
| 556 | InitEDA_Appl( wxT( "PCBnew" ), APP_TYPE_PCBNEW ); |
| 557 | |
| 558 | if( m_Checker && m_Checker->IsAnotherRunning() ) |
| 559 | diff -ruN kicad.orig/pcbnew/pcbnew_scripted.cpp kicad/pcbnew/pcbnew_scripted.cpp |
| 560 | --- kicad.orig/pcbnew/pcbnew_scripted.cpp 1970-01-01 00:00:00.000000000 +0000 |
| 561 | @@ -0,0 +1,552 @@ |
| 562 | +///////////////////////////////////////////////////////////////////////////// |
| 563 | +// Name: pcbnew_scripted.cpp |
| 564 | +// Copyright: Wolfgang Spraul |
| 565 | +// Licence: GPL v3 or higher |
| 566 | +///////////////////////////////////////////////////////////////////////////// |
| 567 | + |
| 568 | +#include "fctsys.h" |
| 569 | +#include "appl_wxstruct.h" |
| 570 | +#include "confirm.h" |
| 571 | + |
| 572 | +#include <wx/file.h> |
| 573 | +#include <wx/snglinst.h> |
| 574 | +#include <wx/cmdline.h> |
| 575 | +#include <wx/tokenzr.h> |
| 576 | +#include <wx/svg/dcsvg.h> |
| 577 | + |
| 578 | +#include "common.h" |
| 579 | +#include "pcbnew.h" |
| 580 | +#include "wxPcbStruct.h" |
| 581 | +#include "plot_common.h" |
| 582 | +#include "gestfich.h" |
| 583 | +#include "pcbplot.h" |
| 584 | +#include "autorout.h" |
| 585 | +#include "cell.h" |
| 586 | +#include "worksheet.h" |
| 587 | +#include "zones.h" |
| 588 | +#include "drag.h" |
| 589 | +#include "eda_dde.h" |
| 590 | +#include "colors_selection.h" |
| 591 | +#include "class_drawpanel.h" |
| 592 | + |
| 593 | +#include "id.h" |
| 594 | + |
| 595 | +#include "build_version.h" |
| 596 | + |
| 597 | +#include "protos.h" |
| 598 | +#include "pcbnew_scripted.h" |
| 599 | +#include "gendrill.h" |
| 600 | +#include "dialog_gendrill.h" |
| 601 | +#include "dialog_drc.h" |
| 602 | +#include "printout_controler.h" |
| 603 | + |
| 604 | +extern int g_DrawDefaultLineThickness; |
| 605 | + |
| 606 | +static const wxCmdLineEntryDesc g_cmdLineDesc [] = |
| 607 | +{ |
| 608 | + { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), wxT("displays help on the command line parameters"), |
| 609 | + wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, |
| 610 | + { wxCMD_LINE_SWITCH, wxT("d"), wxT("drill"), wxT("generates a .drl drill file") }, |
| 611 | + { wxCMD_LINE_SWITCH, wxT("list-layers"), wxT("list-layers"), wxT("lists the names of all enabled layers in the .brd file") }, |
| 612 | + { wxCMD_LINE_OPTION, wxT("p"), wxT("plot"), wxT("plots the board [hpgl|gerber|ps|ps_a4|dxf]"), |
| 613 | + wxCMD_LINE_VAL_STRING }, |
| 614 | + { wxCMD_LINE_OPTION, wxT("l"), wxT("layers"), wxT("comma separated list of layer names (default: all enabled layers)"), |
| 615 | + wxCMD_LINE_VAL_STRING }, |
| 616 | + { wxCMD_LINE_OPTION, wxT("ps-pads-drill-opt"), wxT("ps-pads-drill-opt"), wxT("Postscript pads drill option [none|small|real] (default:small)"), |
| 617 | + wxCMD_LINE_VAL_STRING }, |
| 618 | + { wxCMD_LINE_SWITCH, wxT("mirror"), wxT("mirror"), wxT("mirror plot (HPGL and Postscript only)") }, |
| 619 | + { wxCMD_LINE_SWITCH, wxT("fill-all-zones"), wxT("fill-all-zones"), wxT("fill zones before plotting") }, |
| 620 | + { wxCMD_LINE_SWITCH, wxT("drc"), wxT("drc"), wxT("generates a design rule check report (.rpt)") }, |
| 621 | + { wxCMD_LINE_SWITCH, wxT("svg"), wxT("svg"), wxT("plots the board in SVG format") }, |
| 622 | + { wxCMD_LINE_SWITCH, wxT("svg-merge"), wxT("svg-merge-layers"), wxT("merge layers into one SVG file") }, |
| 623 | + { wxCMD_LINE_SWITCH, wxT("svg-edge"), wxT("svg-board-edges"), wxT("add board edges to SVG plots") }, |
| 624 | + { wxCMD_LINE_SWITCH, wxT("pos"), wxT("pos"), wxT("create front and back .pos component position files") }, |
| 625 | + { wxCMD_LINE_SWITCH, wxT("bom"), wxT("bom"), wxT("create a .csv bom") }, |
| 626 | + { wxCMD_LINE_SWITCH, wxT("cmp"), wxT("cmp"), wxT("recreate .cmp components file for CvPcb") }, |
| 627 | + { wxCMD_LINE_SWITCH, wxT("vrml"), wxT("vrml"), wxT("generates a .wrl vrml board representation") }, |
| 628 | + { wxCMD_LINE_PARAM, 0, 0, wxT("<path to .brd file>"), |
| 629 | + wxCMD_LINE_VAL_STRING }, |
| 630 | + { wxCMD_LINE_NONE } |
| 631 | +}; |
| 632 | + |
| 633 | +bool Pcbnew_Scripted() |
| 634 | +{ |
| 635 | + wxFileName fn; |
| 636 | + wxString str; |
| 637 | + WinEDA_PcbFrame* frame = NULL; |
| 638 | + wxCommandEvent dummy; |
| 639 | + int i; |
| 640 | + |
| 641 | + WinEDA_App& app = wxGetApp(); |
| 642 | + if (app.argc < 2 || app.argv[1][0] != '-') |
| 643 | + return false; |
| 644 | + g_IsScripted = true; |
| 645 | + wxLog::EnableLogging(false); // this should suppress some wx dialogs |
| 646 | + app.InitEDA_Appl( wxT( "PCBnew" ), APP_TYPE_PCBNEW ); |
| 647 | + |
| 648 | + wxCmdLineParser parser; |
| 649 | + parser.SetDesc(g_cmdLineDesc); |
| 650 | + parser.SetCmdLine(app.argc, app.argv); |
| 651 | + if (parser.Parse()) |
| 652 | + return true; |
| 653 | + if ( parser.Found( wxT("ps-pads-drill-opt"), &str ) |
| 654 | + && str.CmpNoCase( wxT("none") ) |
| 655 | + && str.CmpNoCase( wxT("small") ) |
| 656 | + && str.CmpNoCase( wxT("real") )) |
| 657 | + { |
| 658 | + parser.Usage(); |
| 659 | + wxPrintf(wxT("Unexpected pads drill option '%ls'.\n"), str.c_str()); |
| 660 | + return true; |
| 661 | + } |
| 662 | + i = parser.Found( _("drill") ) |
| 663 | + + parser.Found( _("list-layers") ) |
| 664 | + + parser.Found( _("plot") ) |
| 665 | + + parser.Found( _("drc") ) |
| 666 | + + parser.Found( _("svg") ) |
| 667 | + + parser.Found( _("pos") ) |
| 668 | + + parser.Found( _("bom") ) |
| 669 | + + parser.Found( _("cmp") ) |
| 670 | + + parser.Found( _("vrml") ); |
| 671 | + if ( !i ) |
| 672 | + { |
| 673 | + wxPrintf(wxT("One of --drill --list-layers --plot --drc --svg --pos --bom --cmp --vrml must be given.\n")); |
| 674 | + return true; |
| 675 | + } |
| 676 | + if ( i > 1 ) |
| 677 | + { |
| 678 | + wxPrintf(wxT("Only one of --drill --list-layers --plot --drc --svg --pos --bom --cmp --vrml may be given at a time.\n")); |
| 679 | + return true; |
| 680 | + } |
| 681 | + |
| 682 | + fn = parser.GetParam(); |
| 683 | + if( fn.GetExt() != PcbFileExtension ) |
| 684 | + { |
| 685 | + wxLogDebug( wxT( "PcbNew file <%s> has the wrong extension. Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); |
| 686 | + fn.SetExt( PcbFileExtension ); |
| 687 | + } |
| 688 | + if( !fn.FileExists()) |
| 689 | + { |
| 690 | + wxPrintf( wxT("%ls: file '%ls' does not exist.\n" ), app.argv[0], fn.GetFullPath().c_str() ); |
| 691 | + exit(0); |
| 692 | + } |
| 693 | + wxSetWorkingDirectory( fn.GetPath() ); |
| 694 | + |
| 695 | + app.InitEDA_Appl( wxT( "PCBnew" ), APP_TYPE_PCBNEW ); |
| 696 | + ScreenPcb = new PCB_SCREEN(); |
| 697 | + ActiveScreen = ScreenPcb; |
| 698 | + app.GetSettings( false /* reopenLastUsedDirectory */ ); |
| 699 | + |
| 700 | + g_DrawBgColor = BLACK; |
| 701 | + frame = new WinEDA_PcbFrame( NULL, wxT( "PcbNew" ), wxPoint( 0, 0 ), wxSize( 600, 400 ) ); |
| 702 | + |
| 703 | +#if 0 // enable this to see more of the GUI |
| 704 | + app.SetTopWindow( frame ); |
| 705 | + frame->Show( true ); |
| 706 | + frame->Zoom_Automatique( true ); |
| 707 | +#endif |
| 708 | + |
| 709 | + frame->LoadOnePcbFile( fn.GetFullPath() ); |
| 710 | + frame->LoadProjectSettings( fn.GetFullPath() ); |
| 711 | + |
| 712 | + if ( parser.Found( wxT("drill") ) ) |
| 713 | + { |
| 714 | + DIALOG_GENDRILL* drill_frame = new DIALOG_GENDRILL( frame ); |
| 715 | + drill_frame->GenDrillFiles( dummy ); |
| 716 | + delete drill_frame; |
| 717 | + } |
| 718 | + if ( parser.Found( wxT("list-layers") ) ) |
| 719 | + { |
| 720 | + for ( i = 0; i < NB_LAYERS; i++ ) |
| 721 | + { |
| 722 | + if( frame->GetBoard()->IsLayerEnabled( i ) ) |
| 723 | + { |
| 724 | + str = frame->GetBoard()->GetLayerName( i ); |
| 725 | + str.Trim( true ); str.Trim( false ); // remove leading and trailing spaces if any |
| 726 | + wxPrintf(str + _("\n")); |
| 727 | + } |
| 728 | + } |
| 729 | + } |
| 730 | + if ( parser.Found( wxT("plot"), &str ) ) // see pcbplot.cpp |
| 731 | + { |
| 732 | + bool ps_use_a4; |
| 733 | + int plot_format; |
| 734 | + wxString ext, layers_str; |
| 735 | + |
| 736 | + g_pcb_plot_options.PlotLine_Width = g_DrawDefaultLineThickness; |
| 737 | + if (!str.CmpNoCase( wxT("ps") ) ) |
| 738 | + { |
| 739 | + plot_format = PLOT_FORMAT_POST; |
| 740 | + ext = wxT( "ps" ); |
| 741 | + ps_use_a4 = false; |
| 742 | + } |
| 743 | + else if ( !str.CmpNoCase( wxT("ps_a4") ) ) |
| 744 | + { |
| 745 | + plot_format = PLOT_FORMAT_POST; |
| 746 | + ext = wxT( "ps" ); |
| 747 | + ps_use_a4 = true; |
| 748 | + } |
| 749 | + else if ( !str.CmpNoCase( wxT("hpgl") ) ) |
| 750 | + { |
| 751 | + plot_format = PLOT_FORMAT_HPGL; |
| 752 | + ext = wxT( "plt" ); |
| 753 | + } |
| 754 | + else if ( !str.CmpNoCase( wxT("gerber") ) ) |
| 755 | + { |
| 756 | + plot_format = PLOT_FORMAT_GERBER; |
| 757 | + ext = wxT( "pho" ); |
| 758 | + } |
| 759 | + else if ( !str.CmpNoCase( wxT("dxf") ) ) |
| 760 | + { |
| 761 | + plot_format = PLOT_FORMAT_DXF; |
| 762 | + ext = wxT( "dxf" ); |
| 763 | + } |
| 764 | + else |
| 765 | + { |
| 766 | + parser.Usage(); |
| 767 | + wxPrintf(wxT("Unexpected plot type '%ls'.\n"), str.c_str()); |
| 768 | + exit(0); |
| 769 | + } |
| 770 | + |
| 771 | + // --ps-pads-drill-opt |
| 772 | + if ( plot_format == PLOT_FORMAT_POST && parser.Found( wxT("ps-pads-drill-opt"), &str ) ) |
| 773 | + { |
| 774 | + if (!str.CmpNoCase( wxT("none") ) ) |
| 775 | + g_pcb_plot_options.DrillShapeOpt = PCB_Plot_Options::NO_DRILL_SHAPE; |
| 776 | + else if ( !str.CmpNoCase( wxT("small") ) ) |
| 777 | + g_pcb_plot_options.DrillShapeOpt = PCB_Plot_Options::SMALL_DRILL_SHAPE; |
| 778 | + else if ( !str.CmpNoCase( wxT("real") ) ) |
| 779 | + g_pcb_plot_options.DrillShapeOpt = PCB_Plot_Options::FULL_DRILL_SHAPE; |
| 780 | + else |
| 781 | + { |
| 782 | + parser.Usage(); |
| 783 | + wxPrintf(wxT("Unexpected Postscript pads drill option '%ls'.\n"), str.c_str()); |
| 784 | + exit(0); |
| 785 | + } |
| 786 | + } |
| 787 | + |
| 788 | + // --mirror |
| 789 | + if ( parser.Found( wxT("mirror") ) ) |
| 790 | + g_pcb_plot_options.PlotOrient = PLOT_MIROIR; |
| 791 | + |
| 792 | + if ( parser.Found( wxT("fill-all-zones") ) ) |
| 793 | + frame->Fill_All_Zones( false /* verbose */ ); |
| 794 | + |
| 795 | + parser.Found( wxT("layers"), &layers_str ); |
| 796 | + wxStringTokenizer tokenizer( layers_str, _(",") ); |
| 797 | + int layer_i = 0; |
| 798 | + wxString layername; |
| 799 | + while ( ( layers_str.IsEmpty() && layer_i < NB_LAYERS ) || tokenizer.HasMoreTokens() ) |
| 800 | + { |
| 801 | + if ( layers_str.IsEmpty() ) |
| 802 | + { |
| 803 | + if( !frame->GetBoard()->IsLayerEnabled( layer_i ) ) |
| 804 | + { |
| 805 | + layer_i++; |
| 806 | + continue; |
| 807 | + } |
| 808 | + layername = frame->GetBoard()->GetLayerName( layer_i ); |
| 809 | + layername.Trim( true ); layername.Trim( false ); // remove leading and trailing spaces if any |
| 810 | + layer_i++; |
| 811 | + } |
| 812 | + else |
| 813 | + { |
| 814 | + layername = tokenizer.GetNextToken(); |
| 815 | + for( layer_i = 0; layer_i < NB_LAYERS; layer_i++ ) |
| 816 | + { |
| 817 | + str = frame->GetBoard()->GetLayerName( layer_i ); |
| 818 | + str.Trim( true ); str.Trim( false ); // remove leading and trailing spaces if any |
| 819 | + if ( !str.Cmp( layername ) ) |
| 820 | + break; |
| 821 | + } |
| 822 | + if (layer_i >= NB_LAYERS) |
| 823 | + { |
| 824 | + wxFprintf( stderr, _( "Unknown layer name '%ls'\n" ), layername.c_str() ); |
| 825 | + continue; |
| 826 | + } |
| 827 | + } |
| 828 | + fn = ScreenPcb->m_FileName; |
| 829 | + fn.SetName( fn.GetName() + wxT( "-" ) + layername ); |
| 830 | + |
| 831 | + // Use Gerber Extensions based on layer number |
| 832 | + // (See http://en.wikipedia.org/wiki/Gerber_File) |
| 833 | + if( (plot_format == PLOT_FORMAT_GERBER) && true /* always use gerber extensions */ ) |
| 834 | + { |
| 835 | + switch( layer_i ) |
| 836 | + { |
| 837 | + case LAYER_N_FRONT: |
| 838 | + fn.SetExt( wxT( "gtl" ) ); |
| 839 | + break; |
| 840 | + |
| 841 | + case LAYER_N_2: |
| 842 | + case LAYER_N_3: |
| 843 | + case LAYER_N_4: |
| 844 | + case LAYER_N_5: |
| 845 | + case LAYER_N_6: |
| 846 | + case LAYER_N_7: |
| 847 | + case LAYER_N_8: |
| 848 | + case LAYER_N_9: |
| 849 | + case LAYER_N_10: |
| 850 | + case LAYER_N_11: |
| 851 | + case LAYER_N_12: |
| 852 | + case LAYER_N_13: |
| 853 | + case LAYER_N_14: |
| 854 | + case LAYER_N_15: |
| 855 | + |
| 856 | + // TODO: see if we use .gbr or a layer identifier (gb1 .. gbnn ?) |
| 857 | + // according to the new internal layers designation |
| 858 | + // (1 is the first internal layer from the front layer) |
| 859 | + fn.SetExt( wxT( "gbr" ) ); |
| 860 | + break; |
| 861 | + |
| 862 | + case LAYER_N_BACK: |
| 863 | + fn.SetExt( wxT( "gbl" ) ); |
| 864 | + break; |
| 865 | + |
| 866 | + case ADHESIVE_N_BACK: |
| 867 | + fn.SetExt( wxT( "gba" ) ); |
| 868 | + break; |
| 869 | + |
| 870 | + case ADHESIVE_N_FRONT: |
| 871 | + fn.SetExt( wxT( "gta" ) ); |
| 872 | + break; |
| 873 | + |
| 874 | + case SOLDERPASTE_N_BACK: |
| 875 | + fn.SetExt( wxT( "gbp" ) ); |
| 876 | + break; |
| 877 | + |
| 878 | + case SOLDERPASTE_N_FRONT: |
| 879 | + fn.SetExt( wxT( "gtp" ) ); |
| 880 | + break; |
| 881 | + |
| 882 | + case SILKSCREEN_N_BACK: |
| 883 | + fn.SetExt( wxT( "gbo" ) ); |
| 884 | + break; |
| 885 | + |
| 886 | + case SILKSCREEN_N_FRONT: |
| 887 | + fn.SetExt( wxT( "gto" ) ); |
| 888 | + break; |
| 889 | + |
| 890 | + case SOLDERMASK_N_BACK: |
| 891 | + fn.SetExt( wxT( "gbs" ) ); |
| 892 | + break; |
| 893 | + |
| 894 | + case SOLDERMASK_N_FRONT: |
| 895 | + fn.SetExt( wxT( "gts" ) ); |
| 896 | + break; |
| 897 | + |
| 898 | + case DRAW_N: |
| 899 | + case COMMENT_N: |
| 900 | + case ECO1_N: |
| 901 | + case ECO2_N: |
| 902 | + case EDGE_N: |
| 903 | + default: |
| 904 | + fn.SetExt( wxT( "gbr" ) ); |
| 905 | + break; |
| 906 | + } |
| 907 | + } |
| 908 | + else |
| 909 | + { |
| 910 | + fn.SetExt( ext ); |
| 911 | + } |
| 912 | + |
| 913 | + bool success = false; |
| 914 | + |
| 915 | + switch( plot_format ) |
| 916 | + { |
| 917 | + case PLOT_FORMAT_POST: |
| 918 | + success = frame->Genere_PS( fn.GetFullPath(), layer_i, ps_use_a4, |
| 919 | + FILLED /* trace_mode */ ); |
| 920 | + break; |
| 921 | + |
| 922 | + case PLOT_FORMAT_GERBER: |
| 923 | + success = frame->Genere_GERBER( fn.GetFullPath(), layer_i, |
| 924 | + false /* PlotOriginIsAuxAxis */, |
| 925 | + FILLED /* trace_mode */ ); |
| 926 | + break; |
| 927 | + |
| 928 | + case PLOT_FORMAT_HPGL: |
| 929 | + success = frame->Genere_HPGL( fn.GetFullPath(), layer_i, |
| 930 | + FILLED /* trace_mode */ ); |
| 931 | + break; |
| 932 | + |
| 933 | + case PLOT_FORMAT_DXF: |
| 934 | + success = frame->Genere_DXF( fn.GetFullPath(), layer_i, |
| 935 | + FILLED /* trace_mode */ ); |
| 936 | + break; |
| 937 | + } |
| 938 | + |
| 939 | + // Print diags in messages box: |
| 940 | + wxString msg; |
| 941 | + if( !success ) |
| 942 | + wxFprintf( stderr, _( "Unable to create <%s>\n" ), GetChars( fn.GetFullPath() ) ); |
| 943 | + } |
| 944 | + } |
| 945 | + if ( parser.Found( wxT("drc") ) ) // drc_stuff.h drc.cpp dialog_drc.{h,cpp} |
| 946 | + { |
| 947 | + fn = ScreenPcb->m_FileName; |
| 948 | + fn.SetExt( _("rpt") ); |
| 949 | + |
| 950 | + // if you get a segfault, try adding frame->m_drc->ShowDialog() to run through the GUI codepath |
| 951 | + frame->m_drc->updatePointers(); |
| 952 | + frame->m_drc->SetSettings(true, // Pad to pad DRC test enabled |
| 953 | + true, // unconnected pdas DRC test enabled |
| 954 | + true, // DRC test for zones enabled |
| 955 | + fn.GetFullPath(), // report file name |
| 956 | + true /* aSaveReport */ ); |
| 957 | + frame->m_drc->m_pcb->m_Status_Pcb = 0; // Force full connectivity and ratsnest recalculations |
| 958 | + frame->m_drc->RunTests(); |
| 959 | + FILE* fp = wxFopen( fn.GetFullPath(), wxT( "w" ) ); |
| 960 | + { // strings should match dialog_drc.cpp:DIALOG_DRC_CONTROL::writeReport() |
| 961 | + int count; |
| 962 | + |
| 963 | + fprintf( fp, "** Drc report for %s **\n", |
| 964 | + CONV_TO_UTF8( ScreenPcb->m_FileName ) ); |
| 965 | + |
| 966 | + wxDateTime now = wxDateTime::Now(); |
| 967 | + fprintf( fp, "** Created on %s **\n", CONV_TO_UTF8( now.Format( wxT( "%F %T" ) ) ) ); |
| 968 | + |
| 969 | + class DRC_LIST_MARKERS* markers = new DRC_LIST_MARKERS( frame->m_drc->m_pcb ); |
| 970 | + count = markers->GetCount(); |
| 971 | + fprintf( fp, "\n** Found %d DRC errors **\n", count ); |
| 972 | + for ( i = 0; i < count; i++ ) |
| 973 | + fprintf( fp, "%s", CONV_TO_UTF8( markers->GetItem( i )->ShowReport()) ); |
| 974 | + delete markers; |
| 975 | + |
| 976 | + class DRC_LIST_UNCONNECTED* unconnected = new DRC_LIST_UNCONNECTED( &frame->m_drc->m_unconnected ); |
| 977 | + count = unconnected->GetCount(); |
| 978 | + fprintf( fp, "\n** Found %d unconnected pads **\n", count ); |
| 979 | + for ( i = 0; i < count; i++ ) |
| 980 | + fprintf( fp, "%s", CONV_TO_UTF8( unconnected->GetItem( i )->ShowReport()) ); |
| 981 | + delete unconnected; |
| 982 | + |
| 983 | + fprintf( fp, "\n** End of Report **\n" ); |
| 984 | + } |
| 985 | + fclose( fp ); |
| 986 | + } |
| 987 | + if ( parser.Found( wxT("svg") ) ) // see dialog_SVG_print.cpp:DIALOG_SVG_PRINT::DrawPage() |
| 988 | + { |
| 989 | + BASE_SCREEN* screen = frame->GetBaseScreen(); |
| 990 | + wxSize SheetSize; // Sheet size in internal units |
| 991 | + wxString layers_str; |
| 992 | + PRINT_PARAMETERS print_params; |
| 993 | + long PrintMaskLayer; |
| 994 | + int layer_i; |
| 995 | + wxSVGFileDC* dc; |
| 996 | + |
| 997 | + screen->m_DrawOrg.x = screen->m_DrawOrg.y = 0; |
| 998 | + screen->m_StartVisu.x = screen->m_StartVisu.y = 0; |
| 999 | + SheetSize = screen->m_CurrentSheetDesc->m_Size; // size in 1/1000 inch |
| 1000 | + SheetSize.x *= frame->m_InternalUnits / 1000; |
| 1001 | + SheetSize.y *= frame->m_InternalUnits / 1000; // size in pixels |
| 1002 | + screen->SetScalingFactor( 1.0 ); |
| 1003 | + screen->m_IsPrinting = true; |
| 1004 | + float dpi = (float)frame->m_InternalUnits; |
| 1005 | + |
| 1006 | + frame->DrawPanel->m_ClipBox.SetX( 0 ); |
| 1007 | + frame->DrawPanel->m_ClipBox.SetY( 0 ); |
| 1008 | + frame->DrawPanel->m_ClipBox.SetWidth( 0x7FFFFF0 ); |
| 1009 | + frame->DrawPanel->m_ClipBox.SetHeight( 0x7FFFFF0 ); |
| 1010 | + |
| 1011 | + print_params.m_DrillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE; |
| 1012 | + print_params.m_Print_Sheet_Ref = false; // reference in bottom-right corner |
| 1013 | + |
| 1014 | + SetLocaleTo_C_standard(); // Switch the locale to standard C (needed |
| 1015 | + // to print floating point numbers like 1.3) |
| 1016 | + int bg_color = g_DrawBgColor; |
| 1017 | + g_DrawBgColor = WHITE; |
| 1018 | + |
| 1019 | + PrintMaskLayer = 0; |
| 1020 | + if ( parser.Found( wxT("layers"), &layers_str ) ) |
| 1021 | + { |
| 1022 | + wxStringTokenizer tokenizer( layers_str, _(",") ); |
| 1023 | + layer_i = 0; |
| 1024 | + wxString layername; |
| 1025 | + while ( tokenizer.HasMoreTokens() ) |
| 1026 | + { |
| 1027 | + layername = tokenizer.GetNextToken(); |
| 1028 | + for( layer_i = 0; layer_i < NB_LAYERS; layer_i++ ) |
| 1029 | + { |
| 1030 | + str = frame->GetBoard()->GetLayerName( layer_i ); |
| 1031 | + str.Trim( true ); str.Trim( false ); // remove leading and trailing spaces if any |
| 1032 | + if ( !str.Cmp( layername ) ) |
| 1033 | + break; |
| 1034 | + } |
| 1035 | + if (layer_i >= NB_LAYERS) |
| 1036 | + { |
| 1037 | + wxFprintf( stderr, _( "Unknown layer name '%ls'\n" ), layername.c_str() ); |
| 1038 | + continue; |
| 1039 | + } |
| 1040 | + PrintMaskLayer |= 1 << layer_i; |
| 1041 | + } |
| 1042 | + } |
| 1043 | + else |
| 1044 | + { |
| 1045 | + for ( layer_i = 0; layer_i < NB_LAYERS; layer_i++ ) |
| 1046 | + { |
| 1047 | + if ( frame->GetBoard()->IsLayerEnabled( layer_i ) ) |
| 1048 | + PrintMaskLayer |= 1 << layer_i; |
| 1049 | + } |
| 1050 | + } |
| 1051 | + |
| 1052 | + bool SvgMergeLayers = parser.Found( wxT("svg-merge-layers") ); |
| 1053 | + bool SvgEdgeLayer = parser.Found( wxT("svg-board-edges") ); |
| 1054 | + |
| 1055 | + for ( layer_i = 0; layer_i < NB_LAYERS; layer_i++ ) |
| 1056 | + { |
| 1057 | + long LayerMask; |
| 1058 | + |
| 1059 | + fn = ScreenPcb->m_FileName; |
| 1060 | + fn.SetExt( _("svg") ); |
| 1061 | + if ( SvgMergeLayers ) |
| 1062 | + { |
| 1063 | + fn.SetName( fn.GetName() + wxT( "-brd" ) ); |
| 1064 | + LayerMask = PrintMaskLayer; |
| 1065 | + } |
| 1066 | + else |
| 1067 | + { |
| 1068 | + if ( !(PrintMaskLayer & (1 << layer_i) )) |
| 1069 | + continue; |
| 1070 | + str = frame->GetBoard()->GetLayerName( layer_i ); |
| 1071 | + str.Trim( true ); str.Trim( false ); // remove leading and trailing spaces if any |
| 1072 | + fn.SetName( fn.GetName() + wxT( "-" ) + str ); |
| 1073 | + LayerMask = 1 << layer_i; |
| 1074 | + } |
| 1075 | + if ( SvgEdgeLayer ) |
| 1076 | + LayerMask |= EDGE_LAYER; |
| 1077 | + |
| 1078 | + dc = new wxSVGFileDC( fn.GetFullPath(), SheetSize.x, SheetSize.y, dpi ); |
| 1079 | + GRResetPenAndBrush( dc ); |
| 1080 | + frame->PrintPage( dc, false /* aPrint_Frame_Ref */, LayerMask, false /* aPrintMirrorMode */, &print_params); |
| 1081 | + delete dc; |
| 1082 | + dc = 0; |
| 1083 | + |
| 1084 | + if ( SvgMergeLayers ) |
| 1085 | + break; |
| 1086 | + } |
| 1087 | + g_DrawBgColor = bg_color; |
| 1088 | + SetLocaleTo_Default(); // revert to the current locale |
| 1089 | + screen->m_IsPrinting = false; |
| 1090 | + } |
| 1091 | + |
| 1092 | + if ( parser.Found( wxT("pos") ) ) // see gen_modules_placefile.cpp:WinEDA_PcbFrame::GenModulesPosition() |
| 1093 | + frame->GenModulesPosition( dummy ); |
| 1094 | + |
| 1095 | + if ( parser.Found( wxT("bom") ) ) // see build_BOM_from_board.cpp:WinEDA_PcbFrame::RecreateBOMFileFromBoard() |
| 1096 | + frame->RecreateBOMFileFromBoard( dummy ); |
| 1097 | + |
| 1098 | + if ( parser.Found( wxT("cmp") ) ) // see xchgmod.cpp:WinEDA_PcbFrame::RecreateCmpFileFromBoard() |
| 1099 | + frame->RecreateCmpFileFromBoard( dummy ); |
| 1100 | + |
| 1101 | + if ( parser.Found( wxT("vrml") ) ) // see export_vrml.cpp:WinEDA_PcbFrame::OnExportVRML() |
| 1102 | + { |
| 1103 | + wxString subDirFor3Dshapes( _( "shapes3D" ) ); |
| 1104 | + |
| 1105 | + fn = ScreenPcb->m_FileName; |
| 1106 | + fn.SetExt( _("wrl") ); |
| 1107 | + if( ! wxDirExists( subDirFor3Dshapes ) ) |
| 1108 | + wxMkdir( subDirFor3Dshapes ); |
| 1109 | + frame->ExportVRML_File( fn.GetFullPath(), 1.0 /* aScale */, true /* aExport3DFile */, subDirFor3Dshapes ); |
| 1110 | + } |
| 1111 | + delete frame; |
| 1112 | + return true; |
| 1113 | +} |
| 1114 | diff -ruN kicad.orig/pcbnew/pcbnew_scripted.h kicad/pcbnew/pcbnew_scripted.h |
| 1115 | --- kicad.orig/pcbnew/pcbnew_scripted.h 1970-01-01 00:00:00.000000000 +0000 |
| 1116 | @@ -0,0 +1,7 @@ |
| 1117 | +///////////////////////////////////////////////////////////////////////////// |
| 1118 | +// Name: pcbnew_scripted.h |
| 1119 | +// Copyright: Wolfgang Spraul |
| 1120 | +// Licence: GPL v3 or higher |
| 1121 | +///////////////////////////////////////////////////////////////////////////// |
| 1122 | + |
| 1123 | +bool Pcbnew_Scripted(); |
| 1124 | diff -ruN kicad.orig/pcbnew/xchgmod.cpp kicad/pcbnew/xchgmod.cpp |
| 1125 | --- kicad.orig/pcbnew/xchgmod.cpp 2010-10-19 08:48:07.000000000 +0000 |
| 1126 | @@ -577,6 +577,7 @@ |
| 1127 | wildcard = _( "Component files (." ) + NetCmpExtBuffer + wxT( ")|*." ) + |
| 1128 | NetCmpExtBuffer; |
| 1129 | |
| 1130 | + if (!g_IsScripted) { |
| 1131 | wxFileDialog dlg( this, _( "Save Component Files" ), wxGetCwd(), |
| 1132 | fn.GetFullName(), wildcard, |
| 1133 | wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); |
| 1134 | @@ -585,6 +586,7 @@ |
| 1135 | return; |
| 1136 | |
| 1137 | fn = dlg.GetPath(); |
| 1138 | + } |
| 1139 | |
| 1140 | FichCmp = wxFopen( fn.GetFullPath(), wxT( "wt" ) ); |
| 1141 | if( FichCmp == NULL ) |