You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

781 lines
26 KiB

18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
  1. /***********************/
  2. /* fichier pcbplot.cpp */
  3. /***********************/
  4. #include "fctsys.h"
  5. #include "appl_wxstruct.h"
  6. #include "common.h"
  7. #include "plot_common.h"
  8. #include "confirm.h"
  9. #include "gestfich.h"
  10. #include "pcbnew.h"
  11. #include "pcbplot.h"
  12. #include "worksheet.h"
  13. #include "id.h"
  14. #include "protos.h"
  15. #define PLOT_DEFAULT_MARGE 300 // mils
  16. /* Keywords to r/w options in config */
  17. #define OPTKEY_EDGELAYER_GERBER wxT( "EdgeLayerGerberOpt" )
  18. #define OPTKEY_XFINESCALE_ADJ wxT( "PlotXFineScaleAdj" )
  19. #define OPTKEY_YFINESCALE_ADJ wxT( "PlotYFineScaleAdj" )
  20. #define OPTKEY_PADS_ON_SILKSCREEN wxT( "PlotPadsOnSilkscreen" )
  21. #define OPTKEY_ALWAYS_PRINT_PADS wxT( "PlotAlwaysPads" )
  22. #define OPTKEY_OUTPUT_FORMAT wxT( "PlotOutputFormat" )
  23. // Define min et max reasonnable values for print scale
  24. #define MIN_SCALE 0.01
  25. #define MAX_SCALE 100.0
  26. static long s_SelectedLayers = CUIVRE_LAYER | CMP_LAYER |
  27. SILKSCREEN_LAYER_CMP | SILKSCREEN_LAYER_CU;
  28. static bool s_PlotOriginIsAuxAxis = FALSE;
  29. enum id_plotps {
  30. ID_DRILL_SHAPE_OPT = 8020,
  31. ID_SCALE_OPT,
  32. ID_ROTATE_OPT,
  33. ID_MIROR_OPT,
  34. ID_EXEC_PLOT,
  35. ID_PLOT_MODE_OPT,
  36. ID_MASKVIA_OPT,
  37. ID_PLOT_CENTRE_OPT,
  38. ID_SEL_PLOT_FORMAT,
  39. ID_SEL_GERBER_FORMAT,
  40. ID_SAVE_OPT_PLOT,
  41. ID_EXCLUDE_EDGES_PCB,
  42. ID_PRINT_REF,
  43. ID_PRINT_VALUE,
  44. ID_PRINT_MODULE_TEXTS,
  45. ID_FORCE_PRINT_INVISIBLE_TEXT,
  46. ID_PRINT_PAD_ON_SILKSCREEN,
  47. ID_FORCE_PRINT_PAD,
  48. ID_CREATE_DRILL_FILE,
  49. ID_SEL_PLOT_OFFSET_OPTION
  50. };
  51. /*******************************/
  52. /* Dialog box for plot control */
  53. /*******************************/
  54. class WinEDA_PlotFrame : public wxDialog
  55. {
  56. public:
  57. WinEDA_BasePcbFrame* m_Parent;
  58. wxButton* m_PlotButton; // button with initial focus
  59. wxCheckBox* m_BoxSelectLayer[32];
  60. wxRadioBox* m_PlotFormatOpt;
  61. wxRadioBox* m_Choice_Plot_Offset;
  62. wxRadioBox* m_Drill_Shape_Opt;
  63. wxRadioBox* m_Scale_Opt;
  64. wxRadioBox* m_PlotModeOpt;
  65. wxCheckBox* m_PlotMirorOpt;
  66. wxCheckBox* m_PlotNoViaOnMaskOpt;
  67. wxCheckBox* m_HPGL_PlotCenter_Opt;
  68. wxCheckBox* m_Exclude_Edges_Pcb;
  69. wxCheckBox* m_Plot_Sheet_Ref;
  70. wxCheckBox* m_Plot_Invisible_Text;
  71. wxCheckBox* m_Plot_Text_Value;
  72. wxCheckBox* m_Plot_Text_Ref;
  73. wxCheckBox* m_Plot_Text_Div;
  74. wxCheckBox* m_Plot_Pads_on_Silkscreen;
  75. wxCheckBox* m_Force_Plot_Pads;
  76. wxCheckBox* m_Plot_PS_Negative;
  77. WinEDA_ValueCtrl* m_LinesWidth;
  78. WinEDA_ValueCtrl* m_HPGLPenSizeOpt;
  79. WinEDA_ValueCtrl* m_HPGLPenSpeedOpt;
  80. WinEDA_ValueCtrl* m_HPGLPenOverlayOpt;
  81. wxStaticBox* m_HPGL_OptionsBox;
  82. WinEDA_DFloatValueCtrl* m_FineAdjustXscaleOpt;
  83. WinEDA_DFloatValueCtrl* m_FineAdjustYscaleOpt;
  84. double m_XScaleAdjust;
  85. double m_YScaleAdjust;
  86. bool useA4()
  87. {
  88. return m_PlotFormatOpt->GetSelection() == 3;
  89. }
  90. /**
  91. * Function getFormat
  92. * returns one of the values from the PlotFormat enum. If the 4th
  93. * radio button is selected, map this back to postscript.
  94. */
  95. PlotFormat getFormat()
  96. {
  97. int radioNdx = m_PlotFormatOpt->GetSelection();
  98. // change the A4 to the simple postscript, according to the
  99. // PlotFormat enum
  100. if( radioNdx == 3 )
  101. radioNdx = PLOT_FORMAT_POST;
  102. return PlotFormat( radioNdx );
  103. }
  104. public:
  105. WinEDA_PlotFrame( WinEDA_BasePcbFrame* parent );
  106. private:
  107. void OnInitDialog( wxInitDialogEvent& event );
  108. void Plot( wxCommandEvent& event );
  109. void OnQuit( wxCommandEvent& event );
  110. void OnClose( wxCloseEvent& event );
  111. void SetCommands( wxCommandEvent& event );
  112. void SaveOptPlot( wxCommandEvent& event );
  113. void CreateDrillFile( wxCommandEvent& event );
  114. DECLARE_EVENT_TABLE()
  115. };
  116. BEGIN_EVENT_TABLE( WinEDA_PlotFrame, wxDialog )
  117. EVT_INIT_DIALOG( WinEDA_PlotFrame::OnInitDialog )
  118. EVT_CLOSE( WinEDA_PlotFrame::OnClose )
  119. EVT_BUTTON( wxID_CANCEL, WinEDA_PlotFrame::OnQuit )
  120. EVT_BUTTON( ID_EXEC_PLOT, WinEDA_PlotFrame::Plot )
  121. EVT_BUTTON( ID_SAVE_OPT_PLOT, WinEDA_PlotFrame::SaveOptPlot )
  122. EVT_BUTTON( ID_CREATE_DRILL_FILE, WinEDA_PlotFrame::CreateDrillFile )
  123. EVT_RADIOBOX( ID_SEL_PLOT_FORMAT, WinEDA_PlotFrame::SetCommands )
  124. END_EVENT_TABLE()
  125. const int UNITS_MILS = 1000;
  126. WinEDA_PlotFrame::WinEDA_PlotFrame( WinEDA_BasePcbFrame* parent ) :
  127. wxDialog( parent, -1, _( "Plot" ), wxPoint( -1, -1 ), wxDefaultSize,
  128. wxDEFAULT_DIALOG_STYLE )
  129. {
  130. m_Parent = parent;
  131. Centre();
  132. }
  133. void WinEDA_PlotFrame::OnInitDialog( wxInitDialogEvent& event )
  134. {
  135. wxButton* button;
  136. BOARD* board = m_Parent->GetBoard();
  137. wxConfig* config = wxGetApp().m_EDA_Config;
  138. m_Plot_Sheet_Ref = NULL;
  139. wxBoxSizer* MainBoxSizer = new wxBoxSizer( wxHORIZONTAL );
  140. SetSizer( MainBoxSizer );
  141. wxBoxSizer* RightBoxSizer = new wxBoxSizer( wxVERTICAL );
  142. wxBoxSizer* MidRightBoxSizer = new wxBoxSizer( wxVERTICAL );
  143. wxBoxSizer* MidLeftBoxSizer = new wxBoxSizer( wxVERTICAL );
  144. wxBoxSizer* LeftBoxSizer = new wxBoxSizer( wxVERTICAL );
  145. MainBoxSizer->Add( LeftBoxSizer, 0, wxGROW | wxALL, 5 );
  146. MainBoxSizer->Add( MidLeftBoxSizer, 0, wxGROW | wxALL, 5 );
  147. MainBoxSizer->Add( MidRightBoxSizer, 0, wxGROW | wxALL, 5 );
  148. MainBoxSizer->Add( RightBoxSizer, 0, wxGROW | wxALL, 5 );
  149. wxBoxSizer* LayersBoxSizer = new wxBoxSizer( wxHORIZONTAL );
  150. LeftBoxSizer->Add( LayersBoxSizer, 0, wxGROW | wxALL, 5 );
  151. static const wxString fmtmsg[4] =
  152. {
  153. wxT( "HPGL" ),
  154. wxT( "Gerber" ),
  155. wxT( "Postscript" ),
  156. wxT( "Postscript A4" )
  157. };
  158. m_PlotFormatOpt = new wxRadioBox( this, ID_SEL_PLOT_FORMAT,
  159. _( "Plot Format" ), wxDefaultPosition,
  160. wxSize( -1, -1 ),
  161. 4, fmtmsg, 1, wxRA_SPECIFY_COLS );
  162. MidRightBoxSizer->Add( m_PlotFormatOpt, 0, wxGROW | wxALL, 5 );
  163. if( config )
  164. {
  165. config->Read( OPTKEY_OUTPUT_FORMAT, &g_PlotFormat );
  166. config->Read( OPTKEY_PLOT_LINEWIDTH_VALUE, &g_PlotLine_Width );
  167. }
  168. m_PlotFormatOpt->SetSelection( g_PlotFormat );
  169. // Creation des menus d'option du format HPGL
  170. m_HPGL_OptionsBox = new wxStaticBox( this, wxID_ANY, _( "HPGL Options:" ) );
  171. wxStaticBoxSizer* HPGL_OptionsBoxSizer =
  172. new wxStaticBoxSizer( m_HPGL_OptionsBox, wxVERTICAL );
  173. MidRightBoxSizer->Add( HPGL_OptionsBoxSizer, 0, wxGROW | wxALL, 5 );
  174. m_HPGLPenSizeOpt = new WinEDA_ValueCtrl( this, _( "Pen Size" ),
  175. g_HPGL_Pen_Diam,
  176. g_UnitMetric,
  177. HPGL_OptionsBoxSizer,
  178. UNITS_MILS );
  179. // unites standards = cm pour vitesse plume en HPGL
  180. m_HPGLPenSpeedOpt = new WinEDA_ValueCtrl( this, _( "Pen Speed (cm/s)" ),
  181. g_HPGL_Pen_Speed, CENTIMETRE,
  182. HPGL_OptionsBoxSizer, 1 );
  183. m_HPGLPenSpeedOpt->SetToolTip( _( "Set pen speed in cm/s" ) );
  184. m_HPGLPenOverlayOpt = new WinEDA_ValueCtrl( this, _( "Pen ovr" ),
  185. g_HPGL_Pen_Recouvrement,
  186. g_UnitMetric,
  187. HPGL_OptionsBoxSizer,
  188. UNITS_MILS );
  189. m_HPGLPenOverlayOpt->SetToolTip( _( "Set plot overlay for filling" ) );
  190. m_LinesWidth = new WinEDA_ValueCtrl( this, _( "Lines Width" ),
  191. g_PlotLine_Width,
  192. g_UnitMetric,
  193. MidRightBoxSizer,
  194. PCB_INTERNAL_UNIT );
  195. m_LinesWidth->SetToolTip( _( "Set lines width used to plot in sketch \
  196. mode and plot pads outlines on silk screen layers" ) );
  197. // Create the right column commands
  198. static const wxString choice_plot_offset_msg[] =
  199. { _( "Absolute" ), _( "Auxiliary axis" ) };
  200. m_Choice_Plot_Offset = new wxRadioBox( this, ID_SEL_PLOT_OFFSET_OPTION,
  201. _( "Plot Origin" ),
  202. wxDefaultPosition,
  203. wxSize( -1, -1 ),
  204. 2, choice_plot_offset_msg, 1,
  205. wxRA_SPECIFY_COLS );
  206. if( s_PlotOriginIsAuxAxis )
  207. m_Choice_Plot_Offset->SetSelection( 1 );
  208. RightBoxSizer->Add( m_Choice_Plot_Offset, 0, wxGROW | wxALL, 5 );
  209. /* Add a spacer for a better look */
  210. RightBoxSizer->Add( 5, 5, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 20 );
  211. // Create scale adjust option
  212. m_XScaleAdjust = m_YScaleAdjust = 1.0;
  213. if( config )
  214. {
  215. config->Read( OPTKEY_EDGELAYER_GERBER, &g_Exclude_Edges_Pcb );
  216. config->Read( OPTKEY_XFINESCALE_ADJ, &m_XScaleAdjust );
  217. config->Read( OPTKEY_YFINESCALE_ADJ, &m_YScaleAdjust );
  218. }
  219. // Test for a reasonnable scale value. Set to 1 if problem
  220. if( m_XScaleAdjust < MIN_SCALE || m_YScaleAdjust < MIN_SCALE
  221. || m_XScaleAdjust > MAX_SCALE || m_YScaleAdjust > MAX_SCALE )
  222. m_XScaleAdjust = m_YScaleAdjust = 1.0;
  223. m_FineAdjustXscaleOpt = new WinEDA_DFloatValueCtrl( this,
  224. _( "X scale adjust" ),
  225. m_XScaleAdjust,
  226. RightBoxSizer );
  227. m_FineAdjustXscaleOpt->SetToolTip( _( "Set X scale adjust for exact \
  228. scale plotting" ) );
  229. m_FineAdjustYscaleOpt = new WinEDA_DFloatValueCtrl( this,
  230. _( "Y scale adjust" ),
  231. m_YScaleAdjust,
  232. RightBoxSizer );
  233. m_FineAdjustYscaleOpt->SetToolTip( _( "Set Y scale adjust for exact \
  234. scale plotting" ) );
  235. m_Plot_PS_Negative = new wxCheckBox( this, -1, _( "Plot negative" ) );
  236. m_Plot_PS_Negative->SetValue( g_Plot_PS_Negative );
  237. RightBoxSizer->Add( m_Plot_PS_Negative, 0, wxGROW | wxALL, 5 );
  238. /* Create the command buttons */
  239. m_PlotButton = new wxButton( this, ID_EXEC_PLOT, _( "Plot" ) );
  240. RightBoxSizer->Add( m_PlotButton, 0, wxGROW | wxALL, 5 );
  241. button = new wxButton( this, ID_SAVE_OPT_PLOT, _( "Save Options" ) );
  242. RightBoxSizer->Add( button, 0, wxGROW | wxALL, 5 );
  243. button = new wxButton( this, ID_CREATE_DRILL_FILE,
  244. _( "Generate drill file" ) );
  245. RightBoxSizer->Add( button, 0, wxGROW | wxALL, 5 );
  246. button = new wxButton( this, wxID_CANCEL, _( "Close" ) );
  247. RightBoxSizer->Add( button, 0, wxGROW | wxALL, 5 );
  248. // Creation de la liste des layers
  249. wxBoxSizer* OneColumnLayerBoxSizer = new wxBoxSizer( wxVERTICAL );
  250. LayersBoxSizer->Add( OneColumnLayerBoxSizer, 0, wxGROW | wxALL, 5 );
  251. int mask = 1;
  252. for( int layer = 0; layer<NB_LAYERS; layer++, mask <<= 1 )
  253. {
  254. if( layer == 16 )
  255. {
  256. OneColumnLayerBoxSizer = new wxBoxSizer( wxVERTICAL );
  257. LayersBoxSizer->Add( OneColumnLayerBoxSizer, 0, wxGROW | wxALL, 5 );
  258. }
  259. m_BoxSelectLayer[layer] =
  260. new wxCheckBox( this, -1, board->GetLayerName( layer ) );
  261. if( mask & s_SelectedLayers )
  262. m_BoxSelectLayer[layer]->SetValue( true );
  263. OneColumnLayerBoxSizer->Add( m_BoxSelectLayer[layer],
  264. 0, wxGROW | wxALL, 1 );
  265. }
  266. if( config )
  267. {
  268. wxString layerKey;
  269. for( int layer = 0; layer < NB_LAYERS; ++layer )
  270. {
  271. bool option;
  272. layerKey.Printf( OPTKEY_LAYERBASE, layer );
  273. if( config->Read( layerKey, &option ) )
  274. m_BoxSelectLayer[layer]->SetValue( option );
  275. }
  276. }
  277. // Option for excluding contents of "Edges Pcb" layer
  278. m_Exclude_Edges_Pcb = new wxCheckBox( this,
  279. ID_EXCLUDE_EDGES_PCB,
  280. _( "Exclude Edges_Pcb layer" ) );
  281. m_Exclude_Edges_Pcb->SetValue( g_Exclude_Edges_Pcb );
  282. m_Exclude_Edges_Pcb->SetToolTip(
  283. _( "Exclude contents of Edges_Pcb layer from all other layers" ) );
  284. LeftBoxSizer->Add( m_Exclude_Edges_Pcb, 0, wxGROW | wxALL, 1 );
  285. // Option to plot page references:
  286. if( m_Parent->m_Print_Sheet_Ref )
  287. {
  288. m_Plot_Sheet_Ref = new wxCheckBox( this, ID_PRINT_REF,
  289. _( "Print sheet ref" ) );
  290. m_Plot_Sheet_Ref->SetValue( g_Plot_Frame_Ref );
  291. LeftBoxSizer->Add( m_Plot_Sheet_Ref, 0, wxGROW | wxALL, 1 );
  292. }
  293. else
  294. g_Plot_Frame_Ref = false;
  295. // Option to plot pads on silkscreen layers or all layers
  296. m_Plot_Pads_on_Silkscreen = new wxCheckBox( this,
  297. ID_PRINT_PAD_ON_SILKSCREEN,
  298. _( "Print pads on silkscreen" ) );
  299. if( config )
  300. config->Read( OPTKEY_PADS_ON_SILKSCREEN, &PlotPadsOnSilkLayer );
  301. m_Plot_Pads_on_Silkscreen->SetValue( PlotPadsOnSilkLayer );
  302. m_Plot_Pads_on_Silkscreen->SetToolTip(
  303. _( "Enable/disable print/plot pads on silkscreen layers" ) );
  304. LeftBoxSizer->Add( m_Plot_Pads_on_Silkscreen, 0, wxGROW | wxALL, 1 );
  305. m_Force_Plot_Pads = new wxCheckBox( this, ID_FORCE_PRINT_PAD,
  306. _( "Always print pads" ) );
  307. if( config )
  308. config->Read( OPTKEY_ALWAYS_PRINT_PADS, &Plot_Pads_All_Layers );
  309. m_Force_Plot_Pads->SetValue( Plot_Pads_All_Layers );
  310. m_Force_Plot_Pads->SetToolTip( _( "Force print/plot pads on ALL layers" ) );
  311. LeftBoxSizer->Add( m_Force_Plot_Pads, 0, wxGROW | wxALL, 1 );
  312. // Options to plot texts on footprints
  313. m_Plot_Text_Value = new wxCheckBox( this, ID_PRINT_VALUE,
  314. _( "Print module value" ) );
  315. m_Plot_Text_Value->SetValue( Sel_Texte_Valeur );
  316. m_Plot_Text_Value->SetToolTip(
  317. _( "Enable/disable print/plot module value on silkscreen layers" ) );
  318. LeftBoxSizer->Add( m_Plot_Text_Value, 0, wxGROW | wxALL, 1 );
  319. m_Plot_Text_Ref = new wxCheckBox( this, ID_PRINT_REF,
  320. _( "Print module reference" ) );
  321. m_Plot_Text_Ref->SetValue( Sel_Texte_Reference );
  322. m_Plot_Text_Ref->SetToolTip(
  323. _( "Enable/disable print/plot module reference on silkscreen layers" ) );
  324. LeftBoxSizer->Add( m_Plot_Text_Ref, 0, wxGROW | wxALL, 1 );
  325. m_Plot_Text_Div = new wxCheckBox( this, ID_PRINT_MODULE_TEXTS,
  326. _( "Print other module texts" ) );
  327. m_Plot_Text_Div->SetValue( Sel_Texte_Divers );
  328. m_Plot_Text_Div->SetToolTip(
  329. _( "Enable/disable print/plot module field texts on silkscreen layers" ) );
  330. LeftBoxSizer->Add( m_Plot_Text_Div, 0, wxGROW | wxALL, 1 );
  331. m_Plot_Invisible_Text = new wxCheckBox( this,
  332. ID_FORCE_PRINT_INVISIBLE_TEXT,
  333. _( "Force print invisible texts" ) );
  334. m_Plot_Invisible_Text->SetValue( Sel_Texte_Invisible );
  335. m_Plot_Invisible_Text->SetToolTip(
  336. _( "Force print/plot module invisible texts on silkscreen layers" ) );
  337. LeftBoxSizer->Add( m_Plot_Invisible_Text, 0, wxGROW | wxALL, 1 );
  338. static const wxString drillmsg[3] = {
  339. _( "No drill mark" ),
  340. _( "Small mark" ),
  341. _( "Real drill" )
  342. };
  343. m_Drill_Shape_Opt = new wxRadioBox( this, ID_DRILL_SHAPE_OPT,
  344. _( "Pads Drill Opt" ),
  345. wxDefaultPosition, wxSize( -1, -1 ),
  346. 3, drillmsg, 1, wxRA_SPECIFY_COLS );
  347. m_Drill_Shape_Opt->SetSelection( g_DrillShapeOpt );
  348. MidLeftBoxSizer->Add( m_Drill_Shape_Opt, 0, wxGROW | wxALL, 5 );
  349. static const wxString scalemsg[5] =
  350. {
  351. _( "Auto scale" ),
  352. _( "Scale 1" ),
  353. _( "Scale 1.5" ),
  354. _( "Scale 2" ),
  355. _( "Scale 3" )
  356. };
  357. m_Scale_Opt = new wxRadioBox( this, ID_SCALE_OPT,
  358. _( "Scale Opt" ), wxDefaultPosition,
  359. wxSize( -1, -1 ),
  360. 5, scalemsg, 1, wxRA_SPECIFY_COLS );
  361. m_Scale_Opt->SetSelection( g_PlotScaleOpt );
  362. MidLeftBoxSizer->Add( m_Scale_Opt, 0, wxGROW | wxALL, 5 );
  363. static const wxString list_opt3[3] = { _( "Line" ), _( "Filled" ), _(
  364. "Sketch" ) };
  365. m_PlotModeOpt = new wxRadioBox( this, ID_PLOT_MODE_OPT, _( "Plot Mode" ),
  366. wxDefaultPosition, wxDefaultSize,
  367. 3, list_opt3, 1 );
  368. m_PlotModeOpt->SetSelection( g_Plot_Mode );
  369. MidLeftBoxSizer->Add( m_PlotModeOpt, 0, wxGROW | wxALL, 5 );
  370. m_PlotMirorOpt = new wxCheckBox( this, ID_MIROR_OPT,
  371. _( "Plot mirror" ) );
  372. m_PlotMirorOpt->SetValue( Plot_Set_MIROIR );
  373. MidLeftBoxSizer->Add( m_PlotMirorOpt, 0, wxGROW | wxALL, 5 );
  374. m_PlotNoViaOnMaskOpt = new wxCheckBox( this, ID_MASKVIA_OPT,
  375. _( "Vias on mask" ) );
  376. m_PlotNoViaOnMaskOpt->SetValue( g_DrawViaOnMaskLayer );
  377. m_PlotNoViaOnMaskOpt->SetToolTip(
  378. _( "Print/plot vias on mask layers. They are in this case not protected" ) );
  379. MidLeftBoxSizer->Add( m_PlotNoViaOnMaskOpt, 0, wxGROW | wxALL, 5 );
  380. m_HPGL_PlotCenter_Opt = new wxCheckBox( this, ID_PLOT_CENTRE_OPT,
  381. _( "Org = Centre" ) );
  382. m_HPGL_PlotCenter_Opt->SetValue( HPGL_Org_Centre );
  383. m_HPGL_PlotCenter_Opt->SetToolTip( _( "Draw origin ( 0,0 ) in sheet center" ) );
  384. MidLeftBoxSizer->Add( m_HPGL_PlotCenter_Opt, 0, wxGROW | wxALL, 5 );
  385. // Update options values:
  386. wxCommandEvent cmd_event;
  387. SetCommands( cmd_event );
  388. GetSizer()->Fit( this );
  389. GetSizer()->SetSizeHints( this );
  390. // without this line, the ESC key does not work
  391. SetFocus();
  392. }
  393. void WinEDA_PlotFrame::OnQuit( wxCommandEvent& WXUNUSED( event ) )
  394. {
  395. Close( true ); // true is to force the frame to close
  396. }
  397. void WinEDA_PlotFrame::OnClose( wxCloseEvent& event )
  398. {
  399. EndModal( 0 );
  400. }
  401. void WinEDA_PlotFrame::CreateDrillFile( wxCommandEvent& event )
  402. {
  403. ( (WinEDA_PcbFrame*) m_Parent )->InstallDrillFrame( event );
  404. }
  405. void WinEDA_PlotFrame::SetCommands( wxCommandEvent& event )
  406. {
  407. int format = getFormat();
  408. switch( format )
  409. {
  410. case PLOT_FORMAT_POST:
  411. default:
  412. m_Drill_Shape_Opt->Enable( true );
  413. m_PlotModeOpt->Enable( true );
  414. m_PlotMirorOpt->Enable( true );
  415. m_Choice_Plot_Offset->Enable( false );
  416. m_LinesWidth->Enable( true );
  417. m_HPGL_OptionsBox->Enable( false );
  418. m_HPGLPenSizeOpt->Enable( false );
  419. m_HPGLPenSpeedOpt->Enable( false );
  420. m_HPGLPenOverlayOpt->Enable( false );
  421. m_HPGL_PlotCenter_Opt->Enable( false );
  422. m_Exclude_Edges_Pcb->Enable( false );
  423. m_Plot_Sheet_Ref->Enable( true );
  424. m_Scale_Opt->Enable( true );
  425. m_FineAdjustXscaleOpt->Enable( true );
  426. m_FineAdjustYscaleOpt->Enable( true );
  427. m_Plot_PS_Negative->Enable( true );
  428. break;
  429. case PLOT_FORMAT_GERBER:
  430. m_Drill_Shape_Opt->Enable( false );
  431. m_PlotModeOpt->Enable( false );
  432. m_PlotMirorOpt->Enable( false );
  433. m_Choice_Plot_Offset->Enable( true );
  434. m_LinesWidth->Enable( true );
  435. m_HPGL_OptionsBox->Enable( false );
  436. m_HPGLPenSizeOpt->Enable( false );
  437. m_HPGLPenSpeedOpt->Enable( false );
  438. m_HPGLPenOverlayOpt->Enable( false );
  439. m_HPGL_PlotCenter_Opt->Enable( false );
  440. m_Exclude_Edges_Pcb->Enable( true );
  441. m_Plot_Sheet_Ref->Enable( false );
  442. m_Scale_Opt->Enable( false );
  443. m_FineAdjustXscaleOpt->Enable( false );
  444. m_FineAdjustYscaleOpt->Enable( false );
  445. m_Plot_PS_Negative->Enable( false );
  446. break;
  447. case PLOT_FORMAT_HPGL:
  448. m_PlotMirorOpt->Enable( true );
  449. m_Drill_Shape_Opt->Enable( false );
  450. m_PlotModeOpt->Enable( true );
  451. m_Choice_Plot_Offset->Enable( false );
  452. m_LinesWidth->Enable( false );
  453. m_HPGL_OptionsBox->Enable( true );
  454. m_HPGLPenSizeOpt->Enable( true );
  455. m_HPGLPenSpeedOpt->Enable( true );
  456. m_HPGLPenOverlayOpt->Enable( true );
  457. m_HPGL_PlotCenter_Opt->Enable( true );
  458. m_Exclude_Edges_Pcb->Enable( false );
  459. m_Plot_Sheet_Ref->Enable( true );
  460. m_Scale_Opt->Enable( true );
  461. m_FineAdjustXscaleOpt->Enable( false );
  462. m_FineAdjustYscaleOpt->Enable( false );
  463. m_Plot_PS_Negative->Enable( false );
  464. break;
  465. }
  466. g_PlotFormat = format;
  467. }
  468. void WinEDA_PlotFrame::SaveOptPlot( wxCommandEvent& event )
  469. {
  470. g_Exclude_Edges_Pcb = m_Exclude_Edges_Pcb->GetValue();
  471. if( m_Plot_Sheet_Ref )
  472. g_Plot_Frame_Ref = m_Plot_Sheet_Ref->GetValue();
  473. PlotPadsOnSilkLayer = m_Plot_Pads_on_Silkscreen->GetValue();
  474. Plot_Pads_All_Layers = m_Force_Plot_Pads->GetValue();
  475. s_PlotOriginIsAuxAxis =
  476. (m_Choice_Plot_Offset->GetSelection() == 0) ? FALSE : TRUE;
  477. Sel_Texte_Valeur = m_Plot_Text_Value->GetValue();
  478. Sel_Texte_Reference = m_Plot_Text_Ref->GetValue();
  479. Sel_Texte_Divers = m_Plot_Text_Div->GetValue();
  480. Sel_Texte_Invisible = m_Plot_Invisible_Text->GetValue();
  481. g_PlotScaleOpt = m_Scale_Opt->GetSelection();
  482. g_DrillShapeOpt = m_Drill_Shape_Opt->GetSelection();
  483. Plot_Set_MIROIR = m_PlotMirorOpt->GetValue();
  484. if( Plot_Set_MIROIR )
  485. g_PlotOrient = PLOT_MIROIR;
  486. else
  487. g_PlotOrient = 0;
  488. g_Plot_Mode = m_PlotModeOpt->GetSelection();
  489. g_DrawViaOnMaskLayer = m_PlotNoViaOnMaskOpt->GetValue();
  490. g_HPGL_Pen_Diam = m_HPGLPenSizeOpt->GetValue();
  491. g_HPGL_Pen_Speed = m_HPGLPenSpeedOpt->GetValue();
  492. g_HPGL_Pen_Recouvrement = m_HPGLPenOverlayOpt->GetValue();
  493. HPGL_Org_Centre = m_HPGL_PlotCenter_Opt->GetValue();
  494. g_PlotLine_Width = m_LinesWidth->GetValue();
  495. m_XScaleAdjust = m_FineAdjustXscaleOpt->GetValue();
  496. m_YScaleAdjust = m_FineAdjustYscaleOpt->GetValue();
  497. wxConfig* config = wxGetApp().m_EDA_Config;
  498. if( config )
  499. {
  500. config->Write( OPTKEY_EDGELAYER_GERBER, g_Exclude_Edges_Pcb );
  501. config->Write( OPTKEY_XFINESCALE_ADJ, m_XScaleAdjust );
  502. config->Write( OPTKEY_YFINESCALE_ADJ, m_YScaleAdjust );
  503. config->Write( OPTKEY_PADS_ON_SILKSCREEN, PlotPadsOnSilkLayer );
  504. config->Write( OPTKEY_ALWAYS_PRINT_PADS, Plot_Pads_All_Layers );
  505. int formatNdx = m_PlotFormatOpt->GetSelection();
  506. config->Write( OPTKEY_OUTPUT_FORMAT, formatNdx );
  507. config->Write( OPTKEY_PLOT_LINEWIDTH_VALUE, g_PlotLine_Width );
  508. wxString layerKey;
  509. for( int layer = 0; layer<NB_LAYERS; ++layer )
  510. {
  511. layerKey.Printf( OPTKEY_LAYERBASE, layer );
  512. config->Write( layerKey, m_BoxSelectLayer[layer]->IsChecked() );
  513. }
  514. }
  515. g_Plot_PS_Negative = m_Plot_PS_Negative->GetValue();
  516. }
  517. void WinEDA_PlotFrame::Plot( wxCommandEvent& event )
  518. {
  519. int layer_to_plot;
  520. wxFileName fn;
  521. wxString ext;
  522. wxString wildcard;
  523. BOARD* board = m_Parent->GetBoard();
  524. SaveOptPlot( event );
  525. switch( g_PlotScaleOpt )
  526. {
  527. default:
  528. Scale_X = Scale_Y = 1;
  529. break;
  530. case 2:
  531. Scale_X = Scale_Y = 1.5;
  532. break;
  533. case 3:
  534. Scale_X = Scale_Y = 2;
  535. break;
  536. case 4:
  537. Scale_X = Scale_Y = 3;
  538. break;
  539. }
  540. /* If the scale factor edit controls are disabled or the scale value
  541. * is 0, don't adjust the base scale factor. This fixes a bug when
  542. * the default scale adjust is initialized to 0 and saved in program
  543. * settings resulting in a divide by zero fault.
  544. */
  545. if( m_FineAdjustXscaleOpt->m_ValueCtrl->IsEnabled()
  546. && m_XScaleAdjust != 0.0 )
  547. Scale_X *= m_XScaleAdjust;
  548. if( m_FineAdjustYscaleOpt->m_ValueCtrl->IsEnabled()
  549. && m_YScaleAdjust != 0.0 )
  550. Scale_Y *= m_YScaleAdjust;
  551. int format = getFormat();
  552. switch( format )
  553. {
  554. case PLOT_FORMAT_POST:
  555. ext = wxT( "ps" );
  556. wildcard = _( "Adobe post script files (.ps)|*.ps" );
  557. break;
  558. default:
  559. case PLOT_FORMAT_GERBER:
  560. Scale_X = Scale_Y = 1.0; // No scale option allowed in gerber format
  561. ext = wxT( "pho" );
  562. wildcard = _( "GERBER photo plot files (.pho)|*.pho" );
  563. break;
  564. case PLOT_FORMAT_HPGL:
  565. ext = wxT( "plt" );
  566. wildcard = _( "HPGL plot files (.plt)|*.plt" );
  567. break;
  568. }
  569. // Test for a reasonnable scale value
  570. if( Scale_X < MIN_SCALE || Scale_Y < MIN_SCALE )
  571. DisplayInfoMessage( this,
  572. _( "Warning: Scale option set to a very small value" ) );
  573. if( Scale_X > MAX_SCALE || Scale_Y > MAX_SCALE )
  574. DisplayInfoMessage( this,
  575. _( "Warning: Scale option set to a very large value" ) );
  576. int mask = 1;
  577. s_SelectedLayers = 0;
  578. for( layer_to_plot = 0;
  579. layer_to_plot < NB_LAYERS;
  580. layer_to_plot++, mask <<= 1 )
  581. {
  582. if( m_BoxSelectLayer[layer_to_plot]->GetValue() )
  583. {
  584. s_SelectedLayers |= mask;
  585. fn = m_Parent->GetScreen()->m_FileName;
  586. // Calcul du nom du fichier
  587. fn.SetName( fn.GetName() + wxT( "-" ) +
  588. board->GetLayerName( layer_to_plot ) );
  589. fn.SetExt( ext );
  590. switch( format )
  591. {
  592. case PLOT_FORMAT_POST:
  593. m_Parent->Genere_PS( fn.GetFullPath(), layer_to_plot, useA4() );
  594. break;
  595. default:
  596. case PLOT_FORMAT_GERBER:
  597. m_Parent->Genere_GERBER( fn.GetFullPath(), layer_to_plot,
  598. s_PlotOriginIsAuxAxis );
  599. break;
  600. case PLOT_FORMAT_HPGL:
  601. m_Parent->Genere_HPGL( fn.GetFullPath(), layer_to_plot );
  602. break;
  603. }
  604. }
  605. }
  606. // If no layer selected, we have no plot. prompt user if it happens
  607. // because he could think there is a bug in pcbnew:
  608. if( s_SelectedLayers == 0 )
  609. DisplayError( this, _( "No layer selected" ) );
  610. }
  611. void WinEDA_BasePcbFrame::ToPlotter( wxCommandEvent& event )
  612. {
  613. WinEDA_PlotFrame* frame = new WinEDA_PlotFrame( this );
  614. frame->ShowModal();
  615. frame->Destroy();
  616. }