KiCad PCB EDA Suite
dialog_plot.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 
25 #include <kiface_i.h>
26 #include <plotter.h>
27 #include <confirm.h>
28 #include <pcb_edit_frame.h>
29 #include <pcbplot.h>
30 #include <gerber_jobfile_writer.h>
31 #include <reporter.h>
33 #include <bitmaps.h>
34 #include <class_board.h>
35 #include <dialog_plot.h>
36 #include <wx_html_report_panel.h>
37 #include <drc.h>
38 
39 
41  DIALOG_PLOT_BASE( aParent ), m_parent( aParent ),
42  m_defaultLineWidth( aParent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits, true ),
43  m_defaultPenSize( aParent, m_hpglPenLabel, m_hpglPenCtrl, m_hpglPenUnits, true ),
44  m_trackWidthCorrection( aParent, m_widthAdjustLabel, m_widthAdjustCtrl, m_widthAdjustUnits, true )
45 {
46  SetName( DLG_WINDOW_NAME );
48  m_plotOpts = aParent->GetPlotSettings();
49  init_Dialog();
50 
51  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
52  // that requires us to correct the button labels here.
53  m_sdbSizer1OK->SetLabel( _( "Plot" ) );
54  m_sdbSizer1Apply->SetLabel( _( "Generate Drill Files..." ) );
55  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
56  m_sizerButtons->Layout();
57 
58  m_sdbSizer1OK->SetDefault();
59 
60  GetSizer()->Fit( this );
61  GetSizer()->SetSizeHints( this );
62 }
63 
64 
66 {
67  BOARD* board = m_parent->GetBoard();
68  wxFileName fileName;
69 
72 
73  bool checkZones;
74  m_config->Read( OPTKEY_PLOT_CHECK_ZONES, &checkZones, true );
75  m_zoneFillCheck->SetValue( checkZones );
76 
77  m_browseButton->SetBitmap( KiBitmap( folder_xpm ) );
78 
79  // m_PSWidthAdjust is stored in mm in user config
80  double dtmp;
81  m_config->Read( CONFIG_PS_FINEWIDTH_ADJ, &dtmp, 0 );
82  m_PSWidthAdjust = KiROUND( dtmp * IU_PER_MM );
83 
84  // The reasonable width correction value must be in a range of
85  // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils.
88 
89  switch( m_plotOpts.GetFormat() )
90  {
91  default:
92  case PLOT_FORMAT_GERBER: m_plotFormatOpt->SetSelection( 0 ); break;
93  case PLOT_FORMAT_POST: m_plotFormatOpt->SetSelection( 1 ); break;
94  case PLOT_FORMAT_SVG: m_plotFormatOpt->SetSelection( 2 ); break;
95  case PLOT_FORMAT_DXF: m_plotFormatOpt->SetSelection( 3 ); break;
96  case PLOT_FORMAT_HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
97  case PLOT_FORMAT_PDF: m_plotFormatOpt->SetSelection( 5 ); break;
98  }
99 
100  // Set units and value for HPGL pen size (this param is in mils).
102 
104 
105  // Test for a reasonable scale value. Set to 1 if problem
109 
112 
113  // Test for a reasonable PS width correction value. Set to 0 if problem.
114  if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue )
115  m_PSWidthAdjust = 0.;
116 
118 
121 
122  // Could devote a PlotOrder() function in place of UIOrder().
123  m_layerList = board->GetEnabledLayers().UIOrder();
124 
125  // Populate the check list box by all enabled layers names
126  for( LSEQ seq = m_layerList; seq; ++seq )
127  {
128  PCB_LAYER_ID layer = *seq;
129 
130  int checkIndex = m_layerCheckListBox->Append( board->GetLayerName( layer ) );
131 
132  if( m_plotOpts.GetLayerSelection()[layer] )
133  m_layerCheckListBox->Check( checkIndex );
134  }
135 
136  // Option for using proper Gerber extensions. Note also Protel extensions are
137  // a broken feature. However, for now, we need to handle it.
139 
140  // Option for including Gerber attributes, from Gerber X2 format, in the output
141  // In X1 format, they will be added as comments
143 
144  // Option for including Gerber netlist info (from Gerber X2 format) in the output
146 
147  // Option to generate a Gerber job file
149 
150  // Gerber precision for coordinates
151  m_coordFormatCtrl->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
152 
153  // Option for excluding contents of "Edges Pcb" layer
155 
156  // Option to exclude pads from silkscreen layers
158 
160 
161  // Option to plot page references:
163 
164  // Options to plot texts on footprints
168 
169  // Options to plot pads and vias holes
170  m_drillShapeOpt->SetSelection( m_plotOpts.GetDrillMarksType() );
171 
172  // Scale option
173  m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() );
174 
175  // Plot mode
177 
178  // Plot outline mode
180 
181  // Plot text mode
183 
184  // Plot mirror option
185  m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() );
186 
187  // Put vias on mask layer
189 
190  // Initialize a few other parameters, which can also be modified
191  // from the drill dialog
192  reInitDialog();
193 
194  // Update options values:
195  wxCommandEvent cmd_event;
196  SetPlotFormat( cmd_event );
197  OnSetScaleOpt( cmd_event );
198 }
199 
200 
202 {
203  // after calling drill dialog, some parameters can be modified.
204  // update them
205 
206  // Output directory
208 
209  // Origin of coordinates:
211 }
212 
213 
214 // A helper function to show a popup menu, when the dialog is right clicked.
215 void DIALOG_PLOT::OnRightClick( wxMouseEvent& event )
216 {
217  PopupMenu( m_popMenu );
218 }
219 
220 
221 // Select or deselect groups of layers in the layers list:
223 void DIALOG_PLOT::OnPopUpLayers( wxCommandEvent& event )
224 {
225  // Build a list of layers for usual fabrication:
226  // copper layers + tech layers without courtyard
227  LSET fab_layer_set = ( LSET::AllCuMask() | LSET::AllTechMask() )
228  & ~LSET( 2, B_CrtYd, F_CrtYd );
229 
230  switch( event.GetId() )
231  {
232  case ID_LAYER_FAB: // Select layers usually needed to build a board
233  for( unsigned i = 0; i < m_layerList.size(); i++ )
234  {
235  LSET layermask( m_layerList[ i ] );
236 
237  if( ( layermask & fab_layer_set ).any() )
238  m_layerCheckListBox->Check( i, true );
239  else
240  m_layerCheckListBox->Check( i, false );
241  }
242  break;
243 
245  for( unsigned i = 0; i < m_layerList.size(); i++ )
246  {
247  if( IsCopperLayer( m_layerList[i] ) )
248  m_layerCheckListBox->Check( i, true );
249  }
250  break;
251 
253  for( unsigned i = 0; i < m_layerList.size(); i++ )
254  {
255  if( IsCopperLayer( m_layerList[i] ) )
256  m_layerCheckListBox->Check( i, false );
257  }
258  break;
259 
261  for( unsigned i = 0; i < m_layerList.size(); i++ )
262  m_layerCheckListBox->Check( i, true );
263  break;
264 
266  for( unsigned i = 0; i < m_layerList.size(); i++ )
267  m_layerCheckListBox->Check( i, false );
268  break;
269 
270  default:
271  break;
272  }
273 }
274 
275 
276 void DIALOG_PLOT::CreateDrillFile( wxCommandEvent& event )
277 {
278  // Be sure drill file use the same settings (axis option, plot directory)
279  // than plot files:
281  m_parent->InstallDrillFrame( event );
282 
283  // a few plot settings can be modified: take them in account
285  reInitDialog();
286 }
287 
288 
289 void DIALOG_PLOT::OnChangeDXFPlotMode( wxCommandEvent& event )
290 {
291  // m_DXF_plotTextStrokeFontOpt is disabled if m_DXF_plotModeOpt
292  // is checked (plot in DXF polygon mode)
293  m_DXF_plotTextStrokeFontOpt->Enable( !m_DXF_plotModeOpt->GetValue() );
294 
295  // if m_DXF_plotTextStrokeFontOpt option is disabled (plot DXF in polygon mode),
296  // force m_DXF_plotTextStrokeFontOpt to true to use Pcbnew stroke font
297  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() )
298  m_DXF_plotTextStrokeFontOpt->SetValue( true );
299 }
300 
301 
302 void DIALOG_PLOT::OnSetScaleOpt( wxCommandEvent& event )
303 {
304  /* Disable sheet reference for scale != 1:1 */
305  bool scale1 = ( m_scaleOpt->GetSelection() == 1 );
306 
307  m_plotSheetRef->Enable( scale1 );
308 
309  if( !scale1 )
310  m_plotSheetRef->SetValue( false );
311 }
312 
313 
314 void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
315 {
316  // Build the absolute path of current output plot directory
317  // to preselect it when opening the dialog.
318  wxFileName fn( m_outputDirectoryName->GetValue() );
319  wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
320 
321  wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
322 
323  if( dirDialog.ShowModal() == wxID_CANCEL )
324  return;
325 
326  wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
327 
328  fn = Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() );
329  wxString defaultPath = fn.GetPathWithSep();
330  wxString msg;
331  msg.Printf( _( "Do you want to use a path relative to\n\"%s\"" ),
332  GetChars( defaultPath ) );
333 
334  wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
335  wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
336 
337  if( dialog.ShowModal() == wxID_YES )
338  {
339  if( !dirName.MakeRelativeTo( defaultPath ) )
340  wxMessageBox( _( "Cannot make path relative (target volume different from file volume)!" ),
341  _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
342  }
343 
344  m_outputDirectoryName->SetValue( dirName.GetFullPath() );
345 }
346 
347 
349 {
350  // plot format id's are ordered like displayed in m_plotFormatOpt
351  static const PlotFormat plotFmt[] =
352  {
359  };
360 
361  return plotFmt[ m_plotFormatOpt->GetSelection() ];
362 }
363 
364 
365 // Enable or disable widgets according to the plot format selected
366 // and clear also some optional values
367 void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
368 {
369  // this option exist only in DXF format:
371 
372  switch( getPlotFormat() )
373  {
374  case PLOT_FORMAT_PDF:
375  case PLOT_FORMAT_SVG:
376  m_drillShapeOpt->Enable( true );
377  m_plotModeOpt->Enable( false );
379  m_plotMirrorOpt->Enable( true );
380  m_useAuxOriginCheckBox->Enable( false );
381  m_useAuxOriginCheckBox->SetValue( false );
382  m_defaultLineWidth.Enable( true );
383  m_defaultPenSize.Enable( false );
384  m_excludeEdgeLayerOpt->Enable( true );
385  m_scaleOpt->Enable( false );
386  m_scaleOpt->SetSelection( 1 );
387  m_fineAdjustXCtrl->Enable( false );
388  m_fineAdjustYCtrl->Enable( false );
390  m_plotPSNegativeOpt->Enable( true );
391  m_forcePSA4OutputOpt->Enable( false );
392  m_forcePSA4OutputOpt->SetValue( false );
393 
398  break;
399 
400  case PLOT_FORMAT_POST:
401  m_drillShapeOpt->Enable( true );
402  m_plotModeOpt->Enable( true );
403  m_plotMirrorOpt->Enable( true );
404  m_useAuxOriginCheckBox->Enable( false );
405  m_useAuxOriginCheckBox->SetValue( false );
406  m_defaultLineWidth.Enable( true );
407  m_defaultPenSize.Enable( false );
408  m_excludeEdgeLayerOpt->Enable( true );
409  m_scaleOpt->Enable( true );
410  m_fineAdjustXCtrl->Enable( true );
411  m_fineAdjustYCtrl->Enable( true );
413  m_plotPSNegativeOpt->Enable( true );
414  m_forcePSA4OutputOpt->Enable( true );
415 
420  break;
421 
422  case PLOT_FORMAT_GERBER:
423  m_drillShapeOpt->Enable( false );
424  m_drillShapeOpt->SetSelection( 0 );
425  m_plotModeOpt->Enable( false );
427  m_plotMirrorOpt->Enable( false );
428  m_plotMirrorOpt->SetValue( false );
429  m_useAuxOriginCheckBox->Enable( true );
430  m_defaultLineWidth.Enable( true );
431  m_defaultPenSize.Enable( false );
432  m_excludeEdgeLayerOpt->Enable( true );
433  m_scaleOpt->Enable( false );
434  m_scaleOpt->SetSelection( 1 );
435  m_fineAdjustXCtrl->Enable( false );
436  m_fineAdjustYCtrl->Enable( false );
438  m_plotPSNegativeOpt->Enable( false );
439  m_plotPSNegativeOpt->SetValue( false );
440  m_forcePSA4OutputOpt->Enable( false );
441  m_forcePSA4OutputOpt->SetValue( false );
442 
447  break;
448 
449  case PLOT_FORMAT_HPGL:
450  m_drillShapeOpt->Enable( true );
451  m_plotModeOpt->Enable( true );
452  m_plotMirrorOpt->Enable( true );
453  m_useAuxOriginCheckBox->Enable( false );
454  m_useAuxOriginCheckBox->SetValue( false );
455  m_defaultLineWidth.Enable( false );
456  m_defaultPenSize.Enable( true );
457  m_excludeEdgeLayerOpt->Enable( true );
458  m_scaleOpt->Enable( true );
459  m_fineAdjustXCtrl->Enable( false );
460  m_fineAdjustYCtrl->Enable( false );
462  m_plotPSNegativeOpt->SetValue( false );
463  m_plotPSNegativeOpt->Enable( false );
464  m_forcePSA4OutputOpt->Enable( true );
465 
470  break;
471 
472  case PLOT_FORMAT_DXF:
473  m_drillShapeOpt->Enable( true );
474  m_plotModeOpt->Enable( false );
476  m_plotMirrorOpt->Enable( false );
477  m_plotMirrorOpt->SetValue( false );
478  m_useAuxOriginCheckBox->Enable( true );
479  m_defaultLineWidth.Enable( false );
480  m_defaultPenSize.Enable( false );
481  m_excludeEdgeLayerOpt->Enable( true );
482  m_scaleOpt->Enable( false );
483  m_scaleOpt->SetSelection( 1 );
484  m_fineAdjustXCtrl->Enable( false );
485  m_fineAdjustYCtrl->Enable( false );
487  m_plotPSNegativeOpt->Enable( false );
488  m_plotPSNegativeOpt->SetValue( false );
489  m_forcePSA4OutputOpt->Enable( false );
490  m_forcePSA4OutputOpt->SetValue( false );
491 
496 
497  OnChangeDXFPlotMode( event );
498  break;
499 
501  break;
502  }
503 
504  /* Update the interlock between scale and frame reference
505  * (scaling would mess up the frame border...) */
506  OnSetScaleOpt( event );
507 
508  Layout();
509  m_MainSizer->SetSizeHints( this );
510 }
511 
512 
513 // A helper function to "clip" aValue between aMin and aMax
514 // and write result in * aResult
515 // return false if clipped, true if aValue is just copied into * aResult
516 static bool setDouble( double* aResult, double aValue, double aMin, double aMax )
517 {
518  if( aValue < aMin )
519  {
520  *aResult = aMin;
521  return false;
522  }
523  else if( aValue > aMax )
524  {
525  *aResult = aMax;
526  return false;
527  }
528 
529  *aResult = aValue;
530  return true;
531 }
532 
533 
534 static bool setInt( int* aResult, int aValue, int aMin, int aMax )
535 {
536  if( aValue < aMin )
537  {
538  *aResult = aMin;
539  return false;
540  }
541  else if( aValue > aMax )
542  {
543  *aResult = aMax;
544  return false;
545  }
546 
547  *aResult = aValue;
548  return true;
549 }
550 
551 
553 {
554  REPORTER& reporter = m_messagesPanel->Reporter();
555 
556  PCB_PLOT_PARAMS tempOptions;
557 
558  tempOptions.SetExcludeEdgeLayer( m_excludeEdgeLayerOpt->GetValue() );
559  tempOptions.SetSubtractMaskFromSilk( m_subtractMaskFromSilk->GetValue() );
560  tempOptions.SetPlotFrameRef( m_plotSheetRef->GetValue() );
561  tempOptions.SetPlotPadsOnSilkLayer( !m_excludePadsFromSilkscreen->GetValue() );
562  tempOptions.SetUseAuxOrigin( m_useAuxOriginCheckBox->GetValue() );
563  tempOptions.SetPlotValue( m_plotModuleValueOpt->GetValue() );
564  tempOptions.SetPlotReference( m_plotModuleRefOpt->GetValue() );
565  tempOptions.SetPlotInvisibleText( m_plotInvisibleText->GetValue() );
566  tempOptions.SetScaleSelection( m_scaleOpt->GetSelection() );
567  tempOptions.SetDrillMarksType( static_cast<PCB_PLOT_PARAMS::DrillMarksType>
568  ( m_drillShapeOpt->GetSelection() ) );
569  tempOptions.SetMirror( m_plotMirrorOpt->GetValue() );
570  tempOptions.SetPlotMode( m_plotModeOpt->GetSelection() == 1 ? SKETCH : FILLED );
571  tempOptions.SetDXFPlotPolygonMode( m_DXF_plotModeOpt->GetValue() );
572  tempOptions.SetPlotViaOnMaskLayer( m_plotNoViaOnMaskOpt->GetValue() );
573 
574  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() ) // Currently, only DXF supports this option
575  tempOptions.SetTextMode( PLOTTEXTMODE_DEFAULT );
576  else
577  tempOptions.SetTextMode( m_DXF_plotTextStrokeFontOpt->GetValue() ?
579 
580  // Update settings from text fields. Rewrite values back to the fields,
581  // since the values may have been constrained by the setters.
582  wxString msg;
583 
584  // read HPLG pen size (this param is stored in mils)
585  // However, due to issues when converting this value from or to mm
586  // that can slightly change the value, update this param only if it
587  // is in use
589  {
590  if( !tempOptions.SetHPGLPenDiameter( m_defaultPenSize.GetValue() / IU_PER_MILS ) )
591  {
593  msg.Printf( _( "HPGL pen size constrained." ) );
594  reporter.Report( msg, REPORTER::RPT_INFO );
595  }
596  }
597  else // keep the last value (initial value if no HPGL plot made)
599 
600  // Default linewidth
601  if( !tempOptions.SetLineWidth( m_defaultLineWidth.GetValue() ) )
602  {
603  m_defaultLineWidth.SetValue( tempOptions.GetLineWidth() );
604  msg.Printf( _( "Default line width constrained." ) );
605  reporter.Report( msg, REPORTER::RPT_INFO );
606  }
607 
608  // X scale
609  double tmpDouble;
610  msg = m_fineAdjustXCtrl->GetValue();
611  msg.ToDouble( &tmpDouble );
612 
613  if( !setDouble( &m_XScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
614  {
615  msg.Printf( wxT( "%f" ), m_XScaleAdjust );
616  m_fineAdjustXCtrl->SetValue( msg );
617  msg.Printf( _( "X scale constrained." ) );
618  reporter.Report( msg, REPORTER::RPT_INFO );
619  }
620 
622 
623  // Y scale
624  msg = m_fineAdjustYCtrl->GetValue();
625  msg.ToDouble( &tmpDouble );
626 
627  if( !setDouble( &m_YScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
628  {
629  msg.Printf( wxT( "%f" ), m_YScaleAdjust );
630  m_fineAdjustYCtrl->SetValue( msg );
631  msg.Printf( _( "Y scale constrained." ) );
632  reporter.Report( msg, REPORTER::RPT_INFO );
633  }
634 
636 
637  m_config->Write( OPTKEY_PLOT_CHECK_ZONES, m_zoneFillCheck->GetValue() );
638 
639  // PS Width correction
642  {
644  msg.Printf( _( "Width correction constrained. "
645  "The reasonable width correction value must be in a range of "
646  " [%s; %s] (%s) for current design rules." ),
650  reporter.Report( msg, REPORTER::RPT_WARNING );
651  }
652 
653  // Store m_PSWidthAdjust in mm in user config
655  (double)m_PSWidthAdjust / IU_PER_MM );
656 
657  tempOptions.SetFormat( getPlotFormat() );
658 
659  tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
660  tempOptions.SetUseGerberX2format( m_useGerberX2Format->GetValue() );
661  tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
662  tempOptions.SetCreateGerberJobFile( m_generateGerberJobFile->GetValue() );
663 
664  tempOptions.SetGerberPrecision( m_coordFormatCtrl->GetSelection() == 0 ? 5 : 6 );
665 
666  LSET selectedLayers;
667  for( unsigned i = 0; i < m_layerList.size(); i++ )
668  {
669  if( m_layerCheckListBox->IsChecked( i ) )
670  selectedLayers.set( m_layerList[i] );
671  }
672  // Get a list of copper layers that aren't being used by inverting enabled layers.
673  LSET disabledCopperLayers = LSET::AllCuMask() & ~m_parent->GetBoard()->GetEnabledLayers();
674  // Enable all of the disabled copper layers.
675  // If someone enables more copper layers they will be selected by default.
676  selectedLayers = selectedLayers | disabledCopperLayers;
677  tempOptions.SetLayerSelection( selectedLayers );
678 
679  tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() );
680  tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() );
681 
682  // Set output directory and replace backslashes with forward ones
683  wxString dirStr;
684  dirStr = m_outputDirectoryName->GetValue();
685  dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
686  tempOptions.SetOutputDirectory( dirStr );
687 
688  if( !m_plotOpts.IsSameAs( tempOptions, false ) )
689  {
690  // First, mark board as modified only for parameters saved in file
691  if( !m_plotOpts.IsSameAs( tempOptions, true ) )
692  m_parent->OnModify();
693 
694  // Now, save any change, for the session
695  m_parent->SetPlotSettings( tempOptions );
696  m_plotOpts = tempOptions;
697  }
698 }
699 
700 
701 void DIALOG_PLOT::OnGerberX2Checked( wxCommandEvent& event )
702 {
703  // Currently: do nothing
704 }
705 
706 
707 void DIALOG_PLOT::Plot( wxCommandEvent& event )
708 {
709  BOARD* board = m_parent->GetBoard();
710 
712 
713  // If no layer selected, we have nothing plotted.
714  // Prompt user if it happens because he could think there is a bug in Pcbnew.
715  if( !m_plotOpts.GetLayerSelection().any() )
716  {
717  DisplayError( this, _( "No layer selected, Nothing to plot" ) );
718  return;
719  }
720 
721  // Create output directory if it does not exist (also transform it in
722  // absolute form). Bail if it fails
723  wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
724  wxString boardFilename = m_parent->GetBoard()->GetFileName();
725  REPORTER& reporter = m_messagesPanel->Reporter();
726 
727  if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
728  {
729  wxString msg;
730  msg.Printf( _( "Could not write plot files to folder \"%s\"." ),
731  GetChars( outputDir.GetPath() ) );
732  DisplayError( this, msg );
733  return;
734  }
735 
736  if( m_zoneFillCheck->GetValue() )
737  m_parent->Check_All_Zones( this );
738 
739  m_plotOpts.SetAutoScale( false );
740  m_plotOpts.SetScale( 1 );
741 
742  switch( m_plotOpts.GetScaleSelection() )
743  {
744  default:
745  break;
746 
747  case 0: // Autoscale option
748  m_plotOpts.SetAutoScale( true );
749  break;
750 
751  case 2: // 3:2 option
752  m_plotOpts.SetScale( 1.5 );
753  break;
754 
755  case 3: // 2:1 option
756  m_plotOpts.SetScale( 2 );
757  break;
758 
759  case 4: // 3:1 option
760  m_plotOpts.SetScale( 3 );
761  break;
762  }
763 
764  /* If the scale factor edit controls are disabled or the scale value
765  * is 0, don't adjust the base scale factor. This fixes a bug when
766  * the default scale adjust is initialized to 0 and saved in program
767  * settings resulting in a divide by zero fault.
768  */
770  {
771  if( m_XScaleAdjust != 0.0 )
773 
774  if( m_YScaleAdjust != 0.0 )
776 
778  }
779 
780  wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
781 
782  // Test for a reasonable scale value
783  // XXX could this actually happen? isn't it constrained in the apply
784  // function?
786  DisplayInfoMessage( this, _( "Warning: Scale option set to a very small value" ) );
787 
789  DisplayInfoMessage( this, _( "Warning: Scale option set to a very large value" ) );
790 
791  GERBER_JOBFILE_WRITER jobfile_writer( board, &reporter );
792 
793  // Save the current plot options in the board
795 
796  wxBusyCursor dummy;
797 
798  for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq )
799  {
800  PCB_LAYER_ID layer = *seq;
801 
802  // All copper layers that are disabled are actually selected
803  // This is due to wonkyness in automatically selecting copper layers
804  // for plotting when adding more than two layers to a board.
805  // If plot options become accessible to the layers setup dialog
806  // please move this functionality there!
807  // This skips a copper layer if it is actually disabled on the board.
808  if( ( LSET::AllCuMask() & ~board->GetEnabledLayers() )[layer] )
809  continue;
810 
811  // Pick the basename from the board file
812  wxFileName fn( boardFilename );
813 
814  // Use Gerber Extensions based on layer number
815  // (See http://en.wikipedia.org/wiki/Gerber_File)
817  file_ext = GetGerberProtelExtension( layer );
818 
819  BuildPlotFileName( &fn, outputDir.GetPath(), board->GetLayerName( layer ), file_ext );
820  wxString fullname = fn.GetFullName();
821  jobfile_writer.AddGbrFile( layer, fullname );
822 
823  LOCALE_IO toggle;
824 
825  PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
826 
827  // Print diags in messages box:
828  wxString msg;
829 
830  if( plotter )
831  {
832  PlotOneBoardLayer( board, plotter, layer, m_plotOpts );
833  plotter->EndPlot();
834  delete plotter;
835 
836  msg.Printf( _( "Plot file \"%s\" created." ), GetChars( fn.GetFullPath() ) );
837  reporter.Report( msg, REPORTER::RPT_ACTION );
838  }
839  else
840  {
841  msg.Printf( _( "Unable to create file \"%s\"." ), GetChars( fn.GetFullPath() ) );
842  reporter.Report( msg, REPORTER::RPT_ERROR );
843  }
844  }
845 
847  {
848  // Pick the basename from the board file
849  wxFileName fn( boardFilename );
850  // Build gerber job file from basename
851  BuildPlotFileName( &fn, outputDir.GetPath(), "job", GerberJobFileExtension );
852  jobfile_writer.CreateJobFile( fn.GetFullPath() );
853  }
854 }
855 
856 
857 void DIALOG_PLOT::onRunDRC( wxCommandEvent& event )
858 {
859  PCB_EDIT_FRAME* parent = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
860 
861  if( parent )
862  {
863  // First close an existing dialog if open
864  // (low probability, but can happen)
865  parent->GetDrcController()->DestroyDRCDialog( wxID_OK );
866 
867  // Open a new drc dialod, with the right parent frame, and in Modal Mode
868  parent->GetDrcController()->ShowDRCDialog( this );
869  }
870 }
871 
void SetTextMode(PlotTextMode aVal)
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:676
void SetUseGerberProtelExtensions(bool aUse)
void SetPlotReference(bool aFlag)
void SetExcludeEdgeLayer(bool aFlag)
WX_HTML_REPORT_PANEL * m_messagesPanel
wxStaticBoxSizer * m_HPGLOptionsSizer
void SetScaleSelection(int aSelection)
LSEQ m_layerList
Definition: dialog_plot.h:48
void SetIncludeGerberNetlistInfo(bool aUse)
void SetDXFPlotPolygonMode(bool aFlag)
double m_YScaleAdjust
Definition: dialog_plot.h:51
bool GetCreateGerberJobFile() const
virtual void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
wxCheckBox * m_useGerberExtensions
void DestroyDRCDialog(int aReason)
Deletes this ui dialog box and zeros out its pointer to remember the state of the dialog&#39;s existence...
Definition: drc.cpp:119
void SetGerberPrecision(int aPrecision)
void OnOutputDirectoryBrowseClicked(wxCommandEvent &event) override
wxButton * m_sdbSizer1Cancel
void SetPlotViaOnMaskLayer(bool aFlag)
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
bool GetPlotFrameRef() const
bool CreateJobFile(const wxString &aFullFilename)
Creates a Gerber job file.
bool GetDXFPlotPolygonMode() const
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:121
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown...
Definition: common.h:180
#define OPTKEY_PLOT_Y_FINESCALE_ADJ
Definition: pcbplot.h:61
void SetLayerSelection(LSET aSelection)
void OnGerberX2Checked(wxCommandEvent &event) override
void SetUseAuxOrigin(bool aAux)
This file is part of the common library.
int GetSmallestClearanceValue()
Function GetSmallestClearanceValue.
void OnChangeDXFPlotMode(wxCommandEvent &event) override
void PlotOneBoardLayer(BOARD *aBoard, PLOTTER *aPlotter, PCB_LAYER_ID aLayer, const PCB_PLOT_PARAMS &aPlotOpt)
Function PlotOneBoardLayer main function to plot one copper or technical layer.
wxCheckBox * m_plotPSNegativeOpt
#define PLOT_MIN_SCALE
Definition: pcbplot.h:68
Class BOARD to handle a board.
void SetFormat(PlotFormat aFormat)
PlotFormat getPlotFormat()
wxString GetDefaultPlotExtension(PlotFormat aFormat)
Returns the default plot extension for a format.
void Check_All_Zones(wxWindow *aActiveWindow)
Function Check_All_Zones Checks for out-of-date fills and fills them if requested by the user...
PlotFormat GetFormat() const
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
wxCheckBox * m_excludeEdgeLayerOpt
void SetCreateGerberJobFile(bool aCreate)
void onRunDRC(wxCommandEvent &event) override
void SetMirror(bool aFlag)
wxButton * m_sdbSizer1OK
const wxString GetGerberProtelExtension(LAYER_NUM aLayer)
Function GetGerberProtelExtension.
Definition: pcbplot.cpp:48
PlotFormat
Enum PlotFormat is the set of supported output plot formats.
Definition: plotter.h:50
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:539
wxCheckBox * m_plotMirrorOpt
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
wxCheckBox * m_zoneFillCheck
void SetDrillMarksType(DrillMarksType aVal)
Class REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:61
wxChoice * m_plotFormatOpt
static LSET AllTechMask()
Function AllTechMask returns a mask holding all technical layers (no CU layer) on both side...
Definition: lset.cpp:746
virtual const PCB_PLOT_PARAMS & GetPlotSettings() const
Function GetPlotSettings returns the PCB_PLOT_PARAMS for the BOARD owned by this frame.
wxChoice * m_coordFormatCtrl
void CreateDrillFile(wxCommandEvent &event) override
const wxString & GetFileName() const
Definition: class_board.h:238
Classes used to generate a Gerber job file in JSON.
wxStaticBoxSizer * m_SizerDXF_options
double GetScale() const
UNIT_BINDER m_trackWidthCorrection
Definition: dialog_plot.h:62
void SetA4Output(int aForce)
bool GetUseGerberX2format() const
double m_XScaleAdjust
Definition: dialog_plot.h:49
wxButton * m_sdbSizer1Apply
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
wxTextCtrl * m_fineAdjustYCtrl
wxCheckBox * m_DXF_plotModeOpt
VTBL_ENTRY const wxString AbsolutePath(const wxString &aFileName) const
Function AbsolutePath fixes up aFileName if it is relative to the project&#39;s directory to be an absolu...
Definition: project.cpp:380
bool SetLineWidth(int aValue)
bool GetMirror() const
void SetPlotValue(bool aFlag)
Board plot function definition file.
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
wxCheckBox * m_plotSheetRef
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
virtual bool EndPlot()=0
void SetPlotFrameRef(bool aFlag)
void SetPlotFormat(wxCommandEvent &event) override
void Plot(wxCommandEvent &event) override
wxTextCtrl * m_fineAdjustXCtrl
Class DIALOG_PLOT_BASE.
PCB_LAYER_ID
A quick note on layer IDs:
bool GetA4Output() const
int GetGerberPrecision() const
GERBER_JOBFILE_WRITER is a class used to create Gerber job file a Gerber job file stores info to make...
Class LSET is a set of PCB_LAYER_IDs.
#define OPTKEY_PLOT_X_FINESCALE_ADJ
Definition: pcbplot.h:60
PCB_EDIT_FRAME * m_parent
Definition: dialog_plot.h:46
int m_widthAdjustMaxValue
Definition: dialog_plot.h:58
bool GetUseGerberProtelExtensions() const
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
int m_TrackMinWidth
track min value for width ((min copper size value
static bool setDouble(double *aResult, double aValue, double aMin, double aMax)
bool EnsureFileDirectoryExists(wxFileName *aTargetFullFileName, const wxString &aBaseFilename, REPORTER *aReporter)
Make aTargetFullFileName absolute and create the path of this file if it doesn&#39;t yet exist...
Definition: common.cpp:485
REPORTER & Reporter()
returns the reporter object that reports to this panel
#define PLOT_MAX_SCALE
Definition: pcbplot.h:69
bool GetIncludeGerberNetlistInfo() const
int m_PSWidthAdjust
Definition: dialog_plot.h:53
const std::string GerberJobFileExtension
Definition of file extensions used in Kicad.
wxCheckBox * m_forcePSA4OutputOpt
void OnPopUpLayers(wxCommandEvent &event) override
void SetSubtractMaskFromSilk(bool aSubtract)
void AddGbrFile(PCB_LAYER_ID aLayer, wxString &aFilename)
add a gerber file name and type in job file list
#define CONFIG_PS_FINEWIDTH_ADJ
Definition: pcbplot.h:62
void setPlotModeChoiceSelection(EDA_DRAW_MODE_T aPlotMode)
Definition: dialog_plot.h:84
void SetUseGerberX2format(bool aUse)
virtual void SetPlotSettings(const PCB_PLOT_PARAMS &aSettings)
void OnSetScaleOpt(wxCommandEvent &event) override
wxStaticBoxSizer * m_GerberOptionsSizer
wxCheckBox * m_useGerberNetAttributes
void SetOutputDirectory(wxString aDir)
int m_widthAdjustMinValue
Definition: dialog_plot.h:57
wxCheckBox * m_generateGerberJobFile
Class PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board...
wxTextCtrl * m_outputDirectoryName
void SetPlotInvisibleText(bool aFlag)
void SetScale(double aVal)
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
wxCheckBox * m_DXF_plotTextStrokeFontOpt
PCB_PLOT_PARAMS m_plotOpts
Definition: dialog_plot.h:64
void SetNegative(bool aFlag)
bool GetPlotValue() const
wxString GetOutputDirectory() const
void SetFineScaleAdjustX(double aVal)
wxChoice * m_scaleOpt
int GetLineWidth() const
void BuildPlotFileName(wxFileName *aFilename, const wxString &aOutputDir, const wxString &aSuffix, const wxString &aExtension)
Function BuildPlotFileName (helper function) Complete a plot filename: forces the output directory...
Definition: pcbplot.cpp:371
void reInitDialog()
wxCheckBox * m_plotModuleRefOpt
void ConfigBaseWriteDouble(wxConfigBase *aConfig, const wxString &aKey, double aValue)
Function ConfigBaseWriteDouble This is a helper function to write doubles in config We cannot use wxC...
void SetPlotPadsOnSilkLayer(bool aFlag)
void SetPlotMode(EDA_DRAW_MODE_T aPlotMode)
UNIT_BINDER m_defaultLineWidth
Definition: dialog_plot.h:60
bool SetHPGLPenDiameter(double aValue)
Base plotter engine class.
Definition: plotter.h:97
wxBoxSizer * m_sizerButtons
wxCheckBox * m_subtractMaskFromSilk
void init_Dialog()
Definition: dialog_plot.cpp:65
wxCheckBox * m_plotNoViaOnMaskOpt
wxCheckBox * m_plotModuleValueOpt
bool GetPlotViaOnMaskLayer() const
void ShowDRCDialog(wxWindow *aParent=NULL)
Open a dialog and prompts the user, then if a test run button is clicked, runs the test(s) and create...
Definition: drc.cpp:61
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
wxChoice * m_drillShapeOpt
Board layer functions and definitions.
void applyPlotSettings()
void SetWidthAdjust(int aVal)
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:171
bool GetSubtractMaskFromSilk() const
static bool setInt(int *aResult, int aValue, int aMin, int aMax)
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
size_t i
Definition: json11.cpp:597
wxCheckBox * m_plotInvisibleText
double GetHPGLPenDiameter() const
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
bool IsSameAs(const PCB_PLOT_PARAMS &aPcbPlotParams, bool aCompareOnlySavedPrms) const
Compare current settings to aPcbPlotParams, including not saved parameters in brd file...
#define IU_PER_MILS
Definition: plotter.cpp:134
wxCheckBox * m_useAuxOriginCheckBox
PlotTextMode GetTextMode() const
bool GetPlotInvisibleText() const
void SetAutoScale(bool aFlag)
void SetFineScaleAdjustY(double aVal)
wxChoice * m_plotModeOpt
wxConfigBase * m_config
Definition: dialog_plot.h:47
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
wxString StringFromValue(EDA_UNITS_T aUnits, int aValue, bool aAddUnitSymbol, bool aUseMils)
Function StringFromValue returns the string from aValue according to units (inch, mm ...
Definition: base_units.cpp:210
int GetScaleSelection() const
wxCheckBox * m_excludePadsFromSilkscreen
bool GetPlotPadsOnSilkLayer() const
#define OPTKEY_PLOT_CHECK_ZONES
Definition: pcbplot.h:63
UNIT_BINDER m_defaultPenSize
Definition: dialog_plot.h:61
void OnRightClick(wxMouseEvent &event) override
wxBitmapButton * m_browseButton
wxBoxSizer * m_MainSizer
PLOTTER * StartPlotBoard(BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, int aLayer, const wxString &aFullFileName, const wxString &aSheetDesc)
Open a new plotfile using the options (and especially the format) specified in the options and prepar...
bool GetNegative() const
#define DLG_WINDOW_NAME
Definition: dialog_plot.h:34
wxCheckBox * m_useGerberX2Format
BOARD * GetBoard() const
bool GetUseAuxOrigin() const
wxCheckListBox * m_layerCheckListBox
DRC * GetDrcController()
Function GetDrcController.
wxStaticBoxSizer * m_PSOptionsSizer
LSET GetLayerSelection() const
LSEQ UIOrder() const
Definition: lset.cpp:803
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:277
DrillMarksType GetDrillMarksType() const
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245
wxBoxSizer * m_PlotOptionsSizer
bool GetPlotReference() const
void InstallDrillFrame(wxCommandEvent &event)
DIALOG_PLOT(PCB_EDIT_FRAME *parent)
Definition: dialog_plot.cpp:40
void Enable(bool aEnable)
Function Enable Enables/diasables the label, widget and units label.
bool GetExcludeEdgeLayer() const
wxString GetAbbreviatedUnitsLabel(EDA_UNITS_T aUnit, bool aUseMils)
Get the units string for a given units type.
Definition: base_units.cpp:432
EDA_DRAW_MODE_T GetPlotMode() const
EDA_UNITS_T GetUserUnits() const override
Definition: dialog_shim.h:133