KiCad PCB EDA Suite
dialog_plot.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, you may find one here:
22  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23  * or you may search the http://www.gnu.org website for the version 2 license,
24  * or you may write to the Free Software Foundation, Inc.,
25  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27 
28 
29 #include <kiface_i.h>
30 #include <plotter.h>
31 #include <confirm.h>
32 #include <pcb_edit_frame.h>
33 #include <pcbplot.h>
34 #include <gerber_jobfile_writer.h>
35 #include <base_units.h>
36 #include <macros.h>
37 #include <reporter.h>
39 #include <bitmaps.h>
40 
41 #include <class_board.h>
42 #include <wx/ffile.h>
43 #include <dialog_plot.h>
44 #include <wx_html_report_panel.h>
45 #include <drc.h>
46 
47 
49  DIALOG_PLOT_BASE( aParent ), m_parent( aParent )
50 {
52  m_plotOpts = aParent->GetPlotSettings();
53  init_Dialog();
54 
55  GetSizer()->Fit( this );
56  GetSizer()->SetSizeHints( this );
57 }
58 
59 
61 {
62  BOARD* board = m_parent->GetBoard();
63  wxString msg;
64  wxFileName fileName;
65 
68 
69  m_browseButton->SetBitmap( KiBitmap( browse_files_xpm ) );
70 
71  // m_PSWidthAdjust is stored in mm in user config
72  double dtmp;
73  m_config->Read( CONFIG_PS_FINEWIDTH_ADJ, &dtmp, 0 );
74  m_PSWidthAdjust = KiROUND( dtmp * IU_PER_MM );
75 
76  // The reasonable width correction value must be in a range of
77  // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils.
80 
81  switch( m_plotOpts.GetFormat() )
82  {
83  default:
84  case PLOT_FORMAT_GERBER:
85  m_plotFormatOpt->SetSelection( 0 );
86  break;
87 
88  case PLOT_FORMAT_POST:
89  m_plotFormatOpt->SetSelection( 1 );
90  break;
91 
92  case PLOT_FORMAT_SVG:
93  m_plotFormatOpt->SetSelection( 2 );
94  break;
95 
96  case PLOT_FORMAT_DXF:
97  m_plotFormatOpt->SetSelection( 3 );
98  break;
99 
100  case PLOT_FORMAT_HPGL:
101  m_plotFormatOpt->SetSelection( 4 );
102  break;
103 
104  case PLOT_FORMAT_PDF:
105  m_plotFormatOpt->SetSelection( 5 );
106  break;
107  }
108 
110  m_SolderMaskMarginCurrValue->SetLabel( msg );
112  m_SolderMaskMinWidthCurrValue->SetLabel( msg );
113 
114  // Set units and value for HPGL pen size (this param in in mils).
117  m_plotOpts.GetHPGLPenDiameter() * IU_PER_MILS );
118  m_HPGLPenSizeOpt->AppendText( msg );
119 
122  m_linesWidth->AppendText( msg );
123 
124  // Set units for PS global width correction.
126 
127  // Test for a reasonable scale value. Set to 1 if problem
131 
132  msg.Printf( wxT( "%f" ), m_XScaleAdjust );
133  m_fineAdjustXscaleOpt->AppendText( msg );
134 
135  msg.Printf( wxT( "%f" ), m_YScaleAdjust );
136  m_fineAdjustYscaleOpt->AppendText( msg );
137 
138  // Test for a reasonable PS width correction value. Set to 0 if problem.
139  if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue )
140  m_PSWidthAdjust = 0.;
141 
142  msg.Printf( wxT( "%f" ), To_User_Unit( g_UserUnit, m_PSWidthAdjust ) );
143  m_PSFineAdjustWidthOpt->AppendText( msg );
144 
147 
148  // Could devote a PlotOrder() function in place of UIOrder().
149  m_layerList = board->GetEnabledLayers().UIOrder();
150 
151  // Populate the check list box by all enabled layers names
152  for( LSEQ seq = m_layerList; seq; ++seq )
153  {
154  PCB_LAYER_ID layer = *seq;
155 
156  int checkIndex = m_layerCheckListBox->Append( board->GetLayerName( layer ) );
157 
158  if( m_plotOpts.GetLayerSelection()[layer] )
159  m_layerCheckListBox->Check( checkIndex );
160  }
161 
162  // Option for using proper Gerber extensions
164 
165  // Option for including Gerber attributes (from Gerber X2 format) in the output
167 
168  // Option for including Gerber netlist info (from Gerber X2 format) in the output
170 
171  // Grey out if m_useGerberX2Attributes is not checked
172  m_useGerberNetAttributes->Enable( m_useGerberX2Attributes->GetValue() );
173 
174  // Option to generate a Gerber job file
176 
177  // Gerber precision for coordinates
178  m_rbGerberFormat->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
179 
180  // Option for excluding contents of "Edges Pcb" layer
182 
183  // Option to exclude pads from silkscreen layers
185 
187 
188  // Option to plot page references:
190 
191  // Options to plot texts on footprints
195 
196  // Options to plot pads and vias holes
197  m_drillShapeOpt->SetSelection( m_plotOpts.GetDrillMarksType() );
198 
199  // Scale option
200  m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() );
201 
202  // Plot mode
204 
205  // Plot outline mode
207 
208  // Plot text mode
210 
211  // Plot mirror option
212  m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() );
213 
214  // Put vias on mask layer
216 
217  // Initialize a few other parameters, which can also be modified
218  // from the drill dialog
219  reInitDialog();
220 
221  // Update options values:
222  wxCommandEvent cmd_event;
223  SetPlotFormat( cmd_event );
224  OnSetScaleOpt( cmd_event );
225 }
226 
227 
229 {
230  // after calling drill dialog, some parameters can be modified.
231  // update them
232 
233  // Output directory
235 
236  // Origin of coordinates:
238 }
239 
240 void DIALOG_PLOT::OnQuit( wxCommandEvent& event )
241 {
242  // Put a wxID_CANCEL event through the dialog infrastrucutre
243  event.SetId( wxID_CANCEL );
244  event.Skip();
245 }
246 
247 
248 void DIALOG_PLOT::OnClose( wxCloseEvent& event )
249 {
251 
252  // Put an wxID_OK event through the dialog infrastrucutre
253  event.SetId( wxID_OK );
254  event.Skip();
255 }
256 
257 
258 // A helper function to show a popup menu, when the dialog is right clicked.
259 void DIALOG_PLOT::OnRightClick( wxMouseEvent& event )
260 {
261  PopupMenu( m_popMenu );
262 }
263 
264 
265 // Select or deselect groups of layers in the layers list:
267 void DIALOG_PLOT::OnPopUpLayers( wxCommandEvent& event )
268 {
269  unsigned int i;
270 
271  switch( event.GetId() )
272  {
273  case ID_LAYER_FAB: // Select layers usually needed to build a board
274  for( i = 0; i < m_layerList.size(); i++ )
275  {
276  LSET layermask( m_layerList[ i ] );
277 
278  if( ( layermask & ( LSET::AllCuMask() | LSET::AllTechMask() ) ).any() )
279  m_layerCheckListBox->Check( i, true );
280  else
281  m_layerCheckListBox->Check( i, false );
282  }
283  break;
284 
286  for( i = 0; i < m_layerList.size(); i++ )
287  {
288  if( IsCopperLayer( m_layerList[i] ) )
289  m_layerCheckListBox->Check( i, true );
290  }
291  break;
292 
294  for( i = 0; i < m_layerList.size(); i++ )
295  {
296  if( IsCopperLayer( m_layerList[i] ) )
297  m_layerCheckListBox->Check( i, false );
298  }
299  break;
300 
302  for( i = 0; i < m_layerList.size(); i++ )
303  m_layerCheckListBox->Check( i, true );
304  break;
305 
307  for( i = 0; i < m_layerList.size(); i++ )
308  m_layerCheckListBox->Check( i, false );
309  break;
310 
311  default:
312  break;
313  }
314 }
315 
316 
317 void DIALOG_PLOT::CreateDrillFile( wxCommandEvent& event )
318 {
319  // Be sure drill file use the same settings (axis option, plot directory)
320  // than plot files:
322  m_parent->InstallDrillFrame( event );
323 
324  // a few plot settings can be modified: take them in account
326  reInitDialog();
327 }
328 
329 
330 void DIALOG_PLOT::OnChangeDXFPlotMode( wxCommandEvent& event )
331 {
332  // m_DXF_plotTextStrokeFontOpt is disabled if m_DXF_plotModeOpt
333  // is checked (plot in DXF polygon mode)
334  m_DXF_plotTextStrokeFontOpt->Enable( !m_DXF_plotModeOpt->GetValue() );
335 
336  // if m_DXF_plotTextStrokeFontOpt option is disabled (plot DXF in polygon mode),
337  // force m_DXF_plotTextStrokeFontOpt to true to use Pcbnew stroke font
338  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() )
339  m_DXF_plotTextStrokeFontOpt->SetValue( true );
340 }
341 
342 
343 void DIALOG_PLOT::OnSetScaleOpt( wxCommandEvent& event )
344 {
345  /* Disable sheet reference for scale != 1:1 */
346  bool scale1 = ( m_scaleOpt->GetSelection() == 1 );
347 
348  m_plotSheetRef->Enable( scale1 );
349 
350  if( !scale1 )
351  m_plotSheetRef->SetValue( false );
352 }
353 
354 
355 void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
356 {
357  // Build the absolute path of current output plot directory
358  // to preselect it when opening the dialog.
359  wxFileName fn( m_outputDirectoryName->GetValue() );
360  wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
361 
362  wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
363 
364  if( dirDialog.ShowModal() == wxID_CANCEL )
365  return;
366 
367  wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
368 
369  fn = Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() );
370  wxString defaultPath = fn.GetPathWithSep();
371  wxString msg;
372  msg.Printf( _( "Do you want to use a path relative to\n\"%s\"" ),
373  GetChars( defaultPath ) );
374 
375  wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
376  wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
377 
378  if( dialog.ShowModal() == wxID_YES )
379  {
380  if( !dirName.MakeRelativeTo( defaultPath ) )
381  wxMessageBox( _( "Cannot make path relative (target volume different from file volume)!" ),
382  _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
383  }
384 
385  m_outputDirectoryName->SetValue( dirName.GetFullPath() );
386 }
387 
388 
390 {
391  // plot format id's are ordered like displayed in m_plotFormatOpt
392  static const PlotFormat plotFmt[] =
393  {
400  };
401 
402  return plotFmt[ m_plotFormatOpt->GetSelection() ];
403 }
404 
405 
406 // Enable or disable widgets according to the plot format selected
407 // and clear also some optional values
408 void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
409 {
410  // this option exist only in DXF format:
412 
413  switch( getPlotFormat() )
414  {
415  case PLOT_FORMAT_PDF:
416  case PLOT_FORMAT_SVG:
417  m_drillShapeOpt->Enable( true );
418  m_plotModeOpt->Enable( false );
420  m_plotMirrorOpt->Enable( true );
421  m_useAuxOriginCheckBox->Enable( false );
422  m_useAuxOriginCheckBox->SetValue( false );
423  m_linesWidth->Enable( true );
424  m_HPGLPenSizeOpt->Enable( false );
425  m_excludeEdgeLayerOpt->Enable( true );
426  m_scaleOpt->Enable( false );
427  m_scaleOpt->SetSelection( 1 );
428  m_fineAdjustXscaleOpt->Enable( false );
429  m_fineAdjustYscaleOpt->Enable( false );
430  m_PSFineAdjustWidthOpt->Enable( false );
431  m_plotPSNegativeOpt->Enable( true );
432  m_forcePSA4OutputOpt->Enable( false );
433  m_forcePSA4OutputOpt->SetValue( false );
434 
439  break;
440 
441  case PLOT_FORMAT_POST:
442  m_drillShapeOpt->Enable( true );
443  m_plotModeOpt->Enable( true );
444  m_plotMirrorOpt->Enable( true );
445  m_useAuxOriginCheckBox->Enable( false );
446  m_useAuxOriginCheckBox->SetValue( false );
447  m_linesWidth->Enable( true );
448  m_HPGLPenSizeOpt->Enable( false );
449  m_excludeEdgeLayerOpt->Enable( true );
450  m_scaleOpt->Enable( true );
451  m_fineAdjustXscaleOpt->Enable( true );
452  m_fineAdjustYscaleOpt->Enable( true );
453  m_PSFineAdjustWidthOpt->Enable( true );
454  m_plotPSNegativeOpt->Enable( true );
455  m_forcePSA4OutputOpt->Enable( true );
456 
461  break;
462 
463  case PLOT_FORMAT_GERBER:
464  m_drillShapeOpt->Enable( false );
465  m_drillShapeOpt->SetSelection( 0 );
466  m_plotModeOpt->Enable( false );
468  m_plotMirrorOpt->Enable( false );
469  m_plotMirrorOpt->SetValue( false );
470  m_useAuxOriginCheckBox->Enable( true );
471  m_linesWidth->Enable( true );
472  m_HPGLPenSizeOpt->Enable( false );
473  m_excludeEdgeLayerOpt->Enable( true );
474  m_scaleOpt->Enable( false );
475  m_scaleOpt->SetSelection( 1 );
476  m_fineAdjustXscaleOpt->Enable( false );
477  m_fineAdjustYscaleOpt->Enable( false );
478  m_PSFineAdjustWidthOpt->Enable( false );
479  m_plotPSNegativeOpt->Enable( false );
480  m_plotPSNegativeOpt->SetValue( false );
481  m_forcePSA4OutputOpt->Enable( false );
482  m_forcePSA4OutputOpt->SetValue( false );
483 
488  break;
489 
490  case PLOT_FORMAT_HPGL:
491  m_drillShapeOpt->Enable( true );
492  m_plotModeOpt->Enable( true );
493  m_plotMirrorOpt->Enable( true );
494  m_useAuxOriginCheckBox->Enable( false );
495  m_useAuxOriginCheckBox->SetValue( false );
496  m_linesWidth->Enable( false );
497  m_HPGLPenSizeOpt->Enable( true );
498  m_excludeEdgeLayerOpt->Enable( true );
499  m_scaleOpt->Enable( true );
500  m_fineAdjustXscaleOpt->Enable( false );
501  m_fineAdjustYscaleOpt->Enable( false );
502  m_PSFineAdjustWidthOpt->Enable( false );
503  m_plotPSNegativeOpt->SetValue( false );
504  m_plotPSNegativeOpt->Enable( false );
505  m_forcePSA4OutputOpt->Enable( true );
506 
511  break;
512 
513  case PLOT_FORMAT_DXF:
514  m_drillShapeOpt->Enable( true );
515  m_plotModeOpt->Enable( false );
517  m_plotMirrorOpt->Enable( false );
518  m_plotMirrorOpt->SetValue( false );
519  m_useAuxOriginCheckBox->Enable( true );
520  m_linesWidth->Enable( false );
521  m_HPGLPenSizeOpt->Enable( false );
522  m_excludeEdgeLayerOpt->Enable( true );
523  m_scaleOpt->Enable( false );
524  m_scaleOpt->SetSelection( 1 );
525  m_fineAdjustXscaleOpt->Enable( false );
526  m_fineAdjustYscaleOpt->Enable( false );
527  m_PSFineAdjustWidthOpt->Enable( false );
528  m_plotPSNegativeOpt->Enable( false );
529  m_plotPSNegativeOpt->SetValue( false );
530  m_forcePSA4OutputOpt->Enable( false );
531  m_forcePSA4OutputOpt->SetValue( false );
532 
537 
538  OnChangeDXFPlotMode( event );
539  break;
540  }
541 
542  /* Update the interlock between scale and frame reference
543  * (scaling would mess up the frame border...) */
544  OnSetScaleOpt( event );
545 
546  Layout();
547  m_MainSizer->SetSizeHints( this );
548 }
549 
550 
551 // A helper function to "clip" aValue between aMin and aMax
552 // and write result in * aResult
553 // return false if clipped, true if aValue is just copied into * aResult
554 static bool setDouble( double* aResult, double aValue, double aMin, double aMax )
555 {
556  if( aValue < aMin )
557  {
558  *aResult = aMin;
559  return false;
560  }
561  else if( aValue > aMax )
562  {
563  *aResult = aMax;
564  return false;
565  }
566 
567  *aResult = aValue;
568  return true;
569 }
570 
571 
572 static bool setInt( int* aResult, int aValue, int aMin, int aMax )
573 {
574  if( aValue < aMin )
575  {
576  *aResult = aMin;
577  return false;
578  }
579  else if( aValue > aMax )
580  {
581  *aResult = aMax;
582  return false;
583  }
584 
585  *aResult = aValue;
586  return true;
587 }
588 
589 
591 {
592  REPORTER& reporter = m_messagesPanel->Reporter();
593 
594  PCB_PLOT_PARAMS tempOptions;
595 
596  tempOptions.SetExcludeEdgeLayer( m_excludeEdgeLayerOpt->GetValue() );
597  tempOptions.SetSubtractMaskFromSilk( m_subtractMaskFromSilk->GetValue() );
598  tempOptions.SetPlotFrameRef( m_plotSheetRef->GetValue() );
599  tempOptions.SetPlotPadsOnSilkLayer( !m_excludePadsFromSilkscreen->GetValue() );
600  tempOptions.SetUseAuxOrigin( m_useAuxOriginCheckBox->GetValue() );
601  tempOptions.SetPlotValue( m_plotModuleValueOpt->GetValue() );
602  tempOptions.SetPlotReference( m_plotModuleRefOpt->GetValue() );
603  tempOptions.SetPlotInvisibleText( m_plotInvisibleText->GetValue() );
604  tempOptions.SetScaleSelection( m_scaleOpt->GetSelection() );
605  tempOptions.SetDrillMarksType( static_cast<PCB_PLOT_PARAMS::DrillMarksType>
606  ( m_drillShapeOpt->GetSelection() ) );
607  tempOptions.SetMirror( m_plotMirrorOpt->GetValue() );
608  tempOptions.SetPlotMode( m_plotModeOpt->GetSelection() == 1 ? SKETCH : FILLED );
609  tempOptions.SetDXFPlotPolygonMode( m_DXF_plotModeOpt->GetValue() );
610  tempOptions.SetPlotViaOnMaskLayer( m_plotNoViaOnMaskOpt->GetValue() );
611 
612  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() ) // Currently, only DXF supports this option
613  tempOptions.SetTextMode( PLOTTEXTMODE_DEFAULT );
614  else
615  tempOptions.SetTextMode( m_DXF_plotTextStrokeFontOpt->GetValue() ?
617 
618  // Update settings from text fields. Rewrite values back to the fields,
619  // since the values may have been constrained by the setters.
620 
621  // read HPLG pen size (this param is stored in mils)
622  wxString msg = m_HPGLPenSizeOpt->GetValue();
623  int tmp = ValueFromString( g_UserUnit, msg ) / IU_PER_MILS;
624 
625  if( !tempOptions.SetHPGLPenDiameter( tmp ) )
626  {
627  msg = StringFromValue( g_UserUnit, tempOptions.GetHPGLPenDiameter() * IU_PER_MILS );
628  m_HPGLPenSizeOpt->SetValue( msg );
629  msg.Printf( _( "HPGL pen size constrained." ) );
630  reporter.Report( msg, REPORTER::RPT_INFO );
631  }
632 
633  // Default linewidth
634  msg = m_linesWidth->GetValue();
635  tmp = ValueFromString( g_UserUnit, msg );
636 
637  if( !tempOptions.SetLineWidth( tmp ) )
638  {
639  msg = StringFromValue( g_UserUnit, tempOptions.GetLineWidth() );
640  m_linesWidth->SetValue( msg );
641  msg.Printf( _( "Default line width constrained." ) );
642  reporter.Report( msg, REPORTER::RPT_INFO );
643  }
644 
645  // X scale
646  double tmpDouble;
647  msg = m_fineAdjustXscaleOpt->GetValue();
648  msg.ToDouble( &tmpDouble );
649 
650  if( !setDouble( &m_XScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
651  {
652  msg.Printf( wxT( "%f" ), m_XScaleAdjust );
653  m_fineAdjustXscaleOpt->SetValue( msg );
654  msg.Printf( _( "X scale constrained." ) );
655  reporter.Report( msg, REPORTER::RPT_INFO );
656  }
657 
659 
660  // Y scale
661  msg = m_fineAdjustYscaleOpt->GetValue();
662  msg.ToDouble( &tmpDouble );
663 
664  if( !setDouble( &m_YScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
665  {
666  msg.Printf( wxT( "%f" ), m_YScaleAdjust );
667  m_fineAdjustYscaleOpt->SetValue( msg );
668  msg.Printf( _( "Y scale constrained." ) );
669  reporter.Report( msg, REPORTER::RPT_INFO );
670  }
671 
673 
674  // PS Width correction
675  msg = m_PSFineAdjustWidthOpt->GetValue();
676  int itmp = ValueFromString( g_UserUnit, msg );
677 
679  {
681  m_PSFineAdjustWidthOpt->SetValue( msg );
682  msg.Printf( _( "Width correction constrained. "
683  "The reasonable width correction value must be in a range of "
684  " [%+f; %+f] (%s) for current design rules." ),
687  ( g_UserUnit == INCHES ) ? wxT( "\"" ) : wxT( "mm" ) );
688  reporter.Report( msg, REPORTER::RPT_WARNING );
689  }
690 
691  // Store m_PSWidthAdjust in mm in user config
693  (double)m_PSWidthAdjust / IU_PER_MM );
694 
695  tempOptions.SetFormat( getPlotFormat() );
696 
697  tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
698  tempOptions.SetUseGerberAttributes( m_useGerberX2Attributes->GetValue() );
699  tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
700  tempOptions.SetCreateGerberJobFile( m_generateGerberJobFile->GetValue() );
701 
702  tempOptions.SetGerberPrecision( m_rbGerberFormat->GetSelection() == 0 ? 5 : 6 );
703 
704  LSET selectedLayers;
705  for( unsigned i = 0; i < m_layerList.size(); i++ )
706  {
707  if( m_layerCheckListBox->IsChecked( i ) )
708  selectedLayers.set( m_layerList[i] );
709  }
710  // Get a list of copper layers that aren't being used by inverting enabled layers.
711  LSET disabledCopperLayers = LSET::AllCuMask() & ~m_parent->GetBoard()->GetEnabledLayers();
712  // Enable all of the disabled copper layers.
713  // If someone enables more copper layers they will be selected by default.
714  selectedLayers = selectedLayers | disabledCopperLayers;
715  tempOptions.SetLayerSelection( selectedLayers );
716 
717  tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() );
718  tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() );
719 
720  // Set output directory and replace backslashes with forward ones
721  wxString dirStr;
722  dirStr = m_outputDirectoryName->GetValue();
723  dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
724  tempOptions.SetOutputDirectory( dirStr );
725 
726  if( !m_plotOpts.IsSameAs( tempOptions, false ) )
727  {
728  // First, mark board as modified only for parameters saved in file
729  if( !m_plotOpts.IsSameAs( tempOptions, true ) )
730  m_parent->OnModify();
731 
732  // Now, save any change, for the session
733  m_parent->SetPlotSettings( tempOptions );
734  m_plotOpts = tempOptions;
735  }
736 }
737 
738 
739 void DIALOG_PLOT::OnGerberX2Checked( wxCommandEvent& event )
740 {
741  // m_useGerberNetAttributes is useless if m_useGerberX2Attributes
742  // is not checked. So disabled (greyed out) when Gerber X2 gets unchecked
743  // to make it clear to the user.
744  if( m_useGerberX2Attributes->GetValue() )
745  {
746  m_useGerberNetAttributes->Enable( true );
747  }
748  else
749  {
750  m_useGerberNetAttributes->Enable( false );
751  m_useGerberNetAttributes->SetValue( false );
752  }
753 }
754 
755 
756 void DIALOG_PLOT::Plot( wxCommandEvent& event )
757 {
758  BOARD* board = m_parent->GetBoard();
759 
761 
762  // If no layer selected, we have nothing plotted.
763  // Prompt user if it happens because he could think there is a bug in Pcbnew.
764  if( !m_plotOpts.GetLayerSelection().any() )
765  {
766  DisplayError( this, _( "No layer selected, Nothing to plot" ) );
767  return;
768  }
769 
770  // Create output directory if it does not exist (also transform it in
771  // absolute form). Bail if it fails
772  wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
773  wxString boardFilename = m_parent->GetBoard()->GetFileName();
774  REPORTER& reporter = m_messagesPanel->Reporter();
775 
776  if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
777  {
778  wxString msg;
779  msg.Printf( _( "Could not write plot files to folder \"%s\"." ),
780  GetChars( outputDir.GetPath() ) );
781  DisplayError( this, msg );
782  return;
783  }
784 
785  m_plotOpts.SetAutoScale( false );
786  m_plotOpts.SetScale( 1 );
787 
788  switch( m_plotOpts.GetScaleSelection() )
789  {
790  default:
791  break;
792 
793  case 0: // Autoscale option
794  m_plotOpts.SetAutoScale( true );
795  break;
796 
797  case 2: // 3:2 option
798  m_plotOpts.SetScale( 1.5 );
799  break;
800 
801  case 3: // 2:1 option
802  m_plotOpts.SetScale( 2 );
803  break;
804 
805  case 4: // 3:1 option
806  m_plotOpts.SetScale( 3 );
807  break;
808  }
809 
810  /* If the scale factor edit controls are disabled or the scale value
811  * is 0, don't adjust the base scale factor. This fixes a bug when
812  * the default scale adjust is initialized to 0 and saved in program
813  * settings resulting in a divide by zero fault.
814  */
815  if( m_fineAdjustXscaleOpt->IsEnabled() && m_XScaleAdjust != 0.0 )
817 
818  if( m_fineAdjustYscaleOpt->IsEnabled() && m_YScaleAdjust != 0.0 )
820 
821  if( m_PSFineAdjustWidthOpt->IsEnabled() )
823 
824  wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
825 
826  // Test for a reasonable scale value
827  // XXX could this actually happen? isn't it constrained in the apply
828  // function?
830  DisplayInfoMessage( this,
831  _( "Warning: Scale option set to a very small value" ) );
832 
834  DisplayInfoMessage( this,
835  _( "Warning: Scale option set to a very large value" ) );
836 
837  GERBER_JOBFILE_WRITER jobfile_writer( board, &reporter );
838 
839  // Save the current plot options in the board
841 
842  wxBusyCursor dummy;
843 
844  for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq )
845  {
846  PCB_LAYER_ID layer = *seq;
847 
848  // All copper layers that are disabled are actually selected
849  // This is due to wonkyness in automatically selecting copper layers
850  // for plotting when adding more than two layers to a board.
851  // If plot options become accessible to the layers setup dialog
852  // please move this functionality there!
853  // This skips a copper layer if it is actually disabled on the board.
854  if( ( LSET::AllCuMask() & ~board->GetEnabledLayers() )[layer] )
855  continue;
856 
857  // Pick the basename from the board file
858  wxFileName fn( boardFilename );
859 
860  // Use Gerber Extensions based on layer number
861  // (See http://en.wikipedia.org/wiki/Gerber_File)
863  file_ext = GetGerberProtelExtension( layer );
864 
865  BuildPlotFileName( &fn, outputDir.GetPath(), board->GetLayerName( layer ), file_ext );
866  wxString fullname = fn.GetFullName();
867  jobfile_writer.AddGbrFile( layer, fullname );
868 
869  LOCALE_IO toggle;
870 
871  PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
872 
873  // Print diags in messages box:
874  wxString msg;
875 
876  if( plotter )
877  {
878  PlotOneBoardLayer( board, plotter, layer, m_plotOpts );
879  plotter->EndPlot();
880  delete plotter;
881 
882  msg.Printf( _( "Plot file \"%s\" created." ), GetChars( fn.GetFullPath() ) );
883  reporter.Report( msg, REPORTER::RPT_ACTION );
884  }
885  else
886  {
887  msg.Printf( _( "Unable to create file \"%s\"." ), GetChars( fn.GetFullPath() ) );
888  reporter.Report( msg, REPORTER::RPT_ERROR );
889  }
890  }
891 
893  {
894  // Pick the basename from the board file
895  wxFileName fn( boardFilename );
896  // Build gerber job file from basename
897  BuildPlotFileName( &fn, outputDir.GetPath(), "job", GerberJobFileExtension );
898  jobfile_writer.CreateJobFile( fn.GetFullPath() );
899  }
900 }
901 
902 
903 void DIALOG_PLOT::onRunDRC( wxCommandEvent& event )
904 {
905  PCB_EDIT_FRAME* parent = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
906 
907  if( parent )
908  {
909  // First close an existing dialog if open
910  // (low probability, but can happen)
911  parent->GetDrcController()->DestroyDRCDialog( wxID_OK );
912 
913  // Open a new drc dialod, with the right parent frame, and in Modal Mode
914  parent->GetDrcController()->ShowDRCDialog( this );
915  }
916 }
917 
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:673
void SetUseGerberProtelExtensions(bool aUse)
void SetPlotReference(bool aFlag)
void SetExcludeEdgeLayer(bool aFlag)
bool GetUseGerberProtelExtensions() const
WX_HTML_REPORT_PANEL * m_messagesPanel
wxStaticBoxSizer * m_HPGLOptionsSizer
void SetScaleSelection(int aSelection)
wxStaticText * m_textPSFineAdjustWidth
LSEQ m_layerList
Definition: dialog_plot.h:44
void SetIncludeGerberNetlistInfo(bool aUse)
int m_SolderMaskMargin
Solder mask margin.
void SetDXFPlotPolygonMode(bool aFlag)
wxTextCtrl * m_linesWidth
bool GetMirror() const
double m_YScaleAdjust
Definition: dialog_plot.h:47
virtual void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
bool GetSubtractMaskFromSilk() const
wxTextCtrl * m_fineAdjustYscaleOpt
int GetHPGLPenDiameter() const
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:106
double GetScale() const
void SetGerberPrecision(int aPrecision)
void OnOutputDirectoryBrowseClicked(wxCommandEvent &event) override
void SetPlotViaOnMaskLayer(bool aFlag)
bool CreateJobFile(const wxString &aFullFilename)
Creates a Gerber job file.
wxStaticText * m_SolderMaskMarginCurrValue
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:166
#define OPTKEY_PLOT_Y_FINESCALE_ADJ
Definition: pcbplot.h:62
void SetLayerSelection(LSET aSelection)
void OnGerberX2Checked(wxCommandEvent &event) override
void SetUseAuxOrigin(bool aAux)
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
int GetSmallestClearanceValue()
Function GetSmallestClearanceValue.
bool GetUseGerberAttributes() const
wxStaticText * m_textPenSize
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.
wxRadioBox * m_rbGerberFormat
wxString StringFromValue(EDA_UNITS_T aUnit, int aValue, bool aAddUnitSymbol)
Function StringFromValue returns the string from aValue according to units (inch, mm ...
Definition: base_units.cpp:205
void SetFormat(PlotFormat aFormat)
PlotFormat getPlotFormat()
wxString GetDefaultPlotExtension(PlotFormat aFormat)
Returns the default plot extension for a format.
wxCheckBox * m_excludeEdgeLayerOpt
void SetCreateGerberJobFile(bool aCreate)
void onRunDRC(wxCommandEvent &event) override
void SetMirror(bool aFlag)
const wxString GetGerberProtelExtension(LAYER_NUM aLayer)
Function GetGerberProtelExtension.
Definition: pcbplot.cpp:47
PlotFormat
Enum PlotFormat is the set of supported output plot formats.
Definition: plotter.h:50
BOARD * GetBoard() const
wxCheckBox * m_plotMirrorOpt
bool GetUseAuxOrigin() const
void SetDrillMarksType(DrillMarksType aVal)
Class REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:61
LSET GetLayerSelection() const
wxChoice * m_plotFormatOpt
static LSET AllTechMask()
Function AllTechMask returns a mask holding all technical layers (no CU layer) on both side...
Definition: lset.cpp:743
void CreateDrillFile(wxCommandEvent &event) override
Classes used to generate a Gerber job file in JSON.
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
wxStaticBoxSizer * m_SizerDXF_options
bool GetPlotValue() const
wxCheckBox * m_useGerberX2Attributes
virtual const PCB_PLOT_PARAMS & GetPlotSettings() const
Function GetPlotSettings returns the PCB_PLOT_PARAMS for the BOARD owned by this frame.
void SetA4Output(int aForce)
double m_XScaleAdjust
Definition: dialog_plot.h:45
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
bool SetHPGLPenDiameter(int aValue)
wxCheckBox * m_DXF_plotModeOpt
bool SetLineWidth(int aValue)
This file contains miscellaneous commonly used macros and functions.
void SetPlotValue(bool aFlag)
bool GetA4Output() const
bool GetExcludeEdgeLayer() const
Board plot function definition file.
wxCheckBox * m_plotSheetRef
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Function KiBitmap constructs a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:78
virtual bool EndPlot()=0
void SetPlotFrameRef(bool aFlag)
wxString GetOutputDirectory() const
void SetPlotFormat(wxCommandEvent &event) override
void Plot(wxCommandEvent &event) override
wxTextCtrl * m_PSFineAdjustWidthOpt
DrillMarksType GetDrillMarksType() const
Class DIALOG_PLOT_BASE.
PCB_LAYER_ID
A quick note on layer IDs:
GERBER_JOBFILE_WRITER is a class used to create Gerber job file a Gerber job file stores info to make...
bool GetIncludeGerberNetlistInfo() const
Class LSET is a set of PCB_LAYER_IDs.
#define OPTKEY_PLOT_X_FINESCALE_ADJ
Definition: pcbplot.h:61
PCB_EDIT_FRAME * m_parent
Definition: dialog_plot.h:42
int GetLineWidth() const
int m_widthAdjustMaxValue
Definition: dialog_plot.h:54
wxStaticText * m_SolderMaskMinWidthCurrValue
const wxString & GetFileName() const
Definition: class_board.h:234
PlotTextMode GetTextMode() const
int m_TrackMinWidth
track min value for width ((min copper size value
Definition: common.h:145
static bool setDouble(double *aResult, double aValue, double aMin, double aMax)
bool EnsureFileDirectoryExists(wxFileName *aTargetFullFileName, const wxString &aBaseFilename, REPORTER *aReporter)
Helper function EnsureFileDirectoryExists make aTargetFullFileName absolute and creates the path of t...
Definition: common.cpp:282
REPORTER & Reporter()
returns the reporter object that reports to this panel
#define PLOT_MAX_SCALE
Definition: pcbplot.h:69
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
int m_PSWidthAdjust
Definition: dialog_plot.h:49
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
int ValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application...
Definition: base_units.cpp:370
The common library.
wxCheckBox * m_forcePSA4OutputOpt
void OnPopUpLayers(wxCommandEvent &event) override
void SetSubtractMaskFromSilk(bool aSubtract)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
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:63
void setPlotModeChoiceSelection(EDA_DRAW_MODE_T aPlotMode)
Definition: dialog_plot.h:79
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
bool GetPlotViaOnMaskLayer() const
int GetScaleSelection() const
virtual void SetPlotSettings(const PCB_PLOT_PARAMS &aSettings)
void OnSetScaleOpt(wxCommandEvent &event) override
wxStaticBoxSizer * m_GerberOptionsSizer
bool GetCreateGerberJobFile() const
wxCheckBox * m_useGerberNetAttributes
void SetOutputDirectory(wxString aDir)
bool GetPlotReference() const
int m_widthAdjustMinValue
Definition: dialog_plot.h:53
PlotFormat GetFormat() const
void SetUseGerberAttributes(bool aUse)
wxCheckBox * m_generateGerberJobFile
Class PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board...
wxTextCtrl * m_outputDirectoryName
void SetPlotInvisibleText(bool aFlag)
bool IsSameAs(const PCB_PLOT_PARAMS &aPcbPlotParams, bool aCompareOnlySavedPrms) const
Compare current settings to aPcbPlotParams, including not saved parameters in brd file...
void SetScale(double aVal)
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
wxCheckBox * m_DXF_plotTextStrokeFontOpt
const wxString GerberJobFileExtension
PCB_PLOT_PARAMS m_plotOpts
Definition: dialog_plot.h:57
void SetNegative(bool aFlag)
bool GetDXFPlotPolygonMode() const
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:57
void SetFineScaleAdjustX(double aVal)
wxChoice * m_scaleOpt
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:484
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)
Base plotter engine class.
Definition: plotter.h:96
wxCheckBox * m_subtractMaskFromSilk
void init_Dialog()
Definition: dialog_plot.cpp:60
wxCheckBox * m_plotNoViaOnMaskOpt
wxCheckBox * m_plotModuleValueOpt
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:59
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
bool GetPlotInvisibleText() const
wxChoice * m_drillShapeOpt
void AddUnitSymbol(wxStaticText &Stext, EDA_UNITS_T aUnit)
Definition: base_units.cpp:515
Board layer functions and definitions.
wxTextCtrl * m_fineAdjustXscaleOpt
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:169
bool GetNegative() const
static bool setInt(int *aResult, int aValue, int aMin, int aMax)
bool GetPlotFrameRef() const
wxTextCtrl * m_HPGLPenSizeOpt
size_t i
Definition: json11.cpp:597
wxCheckBox * m_plotInvisibleText
EDA_DRAW_MODE_T GetPlotMode() const
bool GetPlotPadsOnSilkLayer() const
wxCheckBox * m_useAuxOriginCheckBox
void SetAutoScale(bool aFlag)
void SetFineScaleAdjustY(double aVal)
wxChoice * m_plotModeOpt
wxConfigBase * m_config
Definition: dialog_plot.h:43
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.
double To_User_Unit(EDA_UNITS_T aUnit, double aValue)
Function To_User_Unit convert aValue in internal units to the appropriate user units defined by aUnit...
Definition: base_units.cpp:91
wxCheckBox * m_excludePadsFromSilkscreen
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...
wxStaticText * m_textDefaultPenSize
void OnQuit(wxCommandEvent &event) override
wxCheckListBox * m_layerCheckListBox
DRC * GetDrcController()
wxStaticBoxSizer * m_PSOptionsSizer
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:216
void OnClose(wxCloseEvent &event) override
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:185
wxBoxSizer * m_PlotOptionsSizer
void InstallDrillFrame(wxCommandEvent &event)
DIALOG_PLOT(PCB_EDIT_FRAME *parent)
Definition: dialog_plot.cpp:48
int m_SolderMaskMinWidth
Solder mask min width.
LSEQ UIOrder() const
Definition: lset.cpp:786
int GetGerberPrecision() const