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-2018 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 {
51  SetName( DLG_WINDOW_NAME );
54  m_plotOpts = aParent->GetPlotSettings();
55  init_Dialog();
56 
57  // We use a sdbSizer here to get the order right, which is platform-dependent
58  m_sdbSizer1OK->SetLabel( _( "Plot" ) );
59  m_sdbSizer1Apply->SetLabel( _( "Generate Drill Files..." ) );
60  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
61  m_sizerButtons->Layout();
62 
63  m_sdbSizer1OK->SetDefault();
64 
65  GetSizer()->Fit( this );
66  GetSizer()->SetSizeHints( this );
67 }
68 
69 
71 {
72  BOARD* board = m_parent->GetBoard();
73  wxString msg;
74  wxFileName fileName;
75 
78 
79  bool checkZones;
80  m_config->Read( OPTKEY_PLOT_CHECK_ZONES, &checkZones, true );
81  m_zoneFillCheck->SetValue( checkZones );
82 
83  m_browseButton->SetBitmap( KiBitmap( browse_files_xpm ) );
84 
85  // m_PSWidthAdjust is stored in mm in user config
86  double dtmp;
87  m_config->Read( CONFIG_PS_FINEWIDTH_ADJ, &dtmp, 0 );
88  m_PSWidthAdjust = KiROUND( dtmp * IU_PER_MM );
89 
90  // The reasonable width correction value must be in a range of
91  // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils.
94 
95  switch( m_plotOpts.GetFormat() )
96  {
97  default:
98  case PLOT_FORMAT_GERBER:
99  m_plotFormatOpt->SetSelection( 0 );
100  break;
101 
102  case PLOT_FORMAT_POST:
103  m_plotFormatOpt->SetSelection( 1 );
104  break;
105 
106  case PLOT_FORMAT_SVG:
107  m_plotFormatOpt->SetSelection( 2 );
108  break;
109 
110  case PLOT_FORMAT_DXF:
111  m_plotFormatOpt->SetSelection( 3 );
112  break;
113 
114  case PLOT_FORMAT_HPGL:
115  m_plotFormatOpt->SetSelection( 4 );
116  break;
117 
118  case PLOT_FORMAT_PDF:
119  m_plotFormatOpt->SetSelection( 5 );
120  break;
121  }
122 
124  m_SolderMaskMarginCurrValue->SetLabel( msg );
126  m_SolderMaskMinWidthCurrValue->SetLabel( msg );
127 
128  // Set units and value for HPGL pen size (this param is stored in mils).
130 
132  m_plotOpts.GetHPGLPenDiameter() * IU_PER_MILS );
133  m_HPGLPenSizeOpt->SetValue( msg );
134 
137  m_linesWidth->SetValue( msg );
138 
139  // Set units for PS global width correction.
141 
142  // Test for a reasonable scale value. Set to 1 if problem
146 
147  msg.Printf( wxT( "%f" ), m_XScaleAdjust );
148  m_fineAdjustXscaleOpt->AppendText( msg );
149 
150  msg.Printf( wxT( "%f" ), m_YScaleAdjust );
151  m_fineAdjustYscaleOpt->SetValue( msg );
152 
153  // Test for a reasonable PS width correction value. Set to 0 if problem.
154  if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue )
155  m_PSWidthAdjust = 0.;
156 
157  msg.Printf( wxT( "%f" ), To_User_Unit( m_userUnits, m_PSWidthAdjust ) );
158  m_PSFineAdjustWidthOpt->SetValue( msg );
159 
162 
163  // Could devote a PlotOrder() function in place of UIOrder().
164  m_layerList = board->GetEnabledLayers().UIOrder();
165 
166  // Populate the check list box by all enabled layers names
167  for( LSEQ seq = m_layerList; seq; ++seq )
168  {
169  PCB_LAYER_ID layer = *seq;
170 
171  int checkIndex = m_layerCheckListBox->Append( board->GetLayerName( layer ) );
172 
173  if( m_plotOpts.GetLayerSelection()[layer] )
174  m_layerCheckListBox->Check( checkIndex );
175  }
176 
177  // Option for using proper Gerber extensions
179 
180  // Option for including Gerber attributes (from Gerber X2 format) in the output
182 
183  // Option for including Gerber netlist info (from Gerber X2 format) in the output
185 
186  // Grey out if m_useGerberX2Attributes is not checked
187  m_useGerberNetAttributes->Enable( m_useGerberX2Attributes->GetValue() );
188 
189  // Option to generate a Gerber job file
191 
192  // Gerber precision for coordinates
193  m_rbGerberFormat->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
194 
195  // Option for excluding contents of "Edges Pcb" layer
197 
198  // Option to exclude pads from silkscreen layers
200 
202 
203  // Option to plot page references:
205 
206  // Options to plot texts on footprints
210 
211  // Options to plot pads and vias holes
212  m_drillShapeOpt->SetSelection( m_plotOpts.GetDrillMarksType() );
213 
214  // Scale option
215  m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() );
216 
217  // Plot mode
219 
220  // Plot outline mode
222 
223  // Plot text mode
225 
226  // Plot mirror option
227  m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() );
228 
229  // Put vias on mask layer
231 
232  // Initialize a few other parameters, which can also be modified
233  // from the drill dialog
234  reInitDialog();
235 
236  // Update options values:
237  wxCommandEvent cmd_event;
238  SetPlotFormat( cmd_event );
239  OnSetScaleOpt( cmd_event );
240 }
241 
242 
244 {
245  // after calling drill dialog, some parameters can be modified.
246  // update them
247 
248  // Output directory
250 
251  // Origin of coordinates:
253 }
254 
255 
256 void DIALOG_PLOT::OnQuit( wxCommandEvent& event )
257 {
258  event.Skip();
259 
260  Destroy();
261 }
262 
263 
264 void DIALOG_PLOT::OnClose( wxCloseEvent& event )
265 {
266  Destroy();
267 }
268 
269 
270 // A helper function to show a popup menu, when the dialog is right clicked.
271 void DIALOG_PLOT::OnRightClick( wxMouseEvent& event )
272 {
273  PopupMenu( m_popMenu );
274 }
275 
276 
277 // Select or deselect groups of layers in the layers list:
279 void DIALOG_PLOT::OnPopUpLayers( wxCommandEvent& event )
280 {
281  unsigned int i;
282 
283  switch( event.GetId() )
284  {
285  case ID_LAYER_FAB: // Select layers usually needed to build a board
286  for( i = 0; i < m_layerList.size(); i++ )
287  {
288  LSET layermask( m_layerList[ i ] );
289 
290  if( ( layermask & ( LSET::AllCuMask() | LSET::AllTechMask() ) ).any() )
291  m_layerCheckListBox->Check( i, true );
292  else
293  m_layerCheckListBox->Check( i, false );
294  }
295  break;
296 
298  for( i = 0; i < m_layerList.size(); i++ )
299  {
300  if( IsCopperLayer( m_layerList[i] ) )
301  m_layerCheckListBox->Check( i, true );
302  }
303  break;
304 
306  for( i = 0; i < m_layerList.size(); i++ )
307  {
308  if( IsCopperLayer( m_layerList[i] ) )
309  m_layerCheckListBox->Check( i, false );
310  }
311  break;
312 
314  for( i = 0; i < m_layerList.size(); i++ )
315  m_layerCheckListBox->Check( i, true );
316  break;
317 
319  for( i = 0; i < m_layerList.size(); i++ )
320  m_layerCheckListBox->Check( i, false );
321  break;
322 
323  default:
324  break;
325  }
326 }
327 
328 
329 void DIALOG_PLOT::CreateDrillFile( wxCommandEvent& event )
330 {
331  // Be sure drill file use the same settings (axis option, plot directory)
332  // than plot files:
334  m_parent->InstallDrillFrame( event );
335 
336  // a few plot settings can be modified: take them in account
338  reInitDialog();
339 }
340 
341 
342 void DIALOG_PLOT::OnChangeDXFPlotMode( wxCommandEvent& event )
343 {
344  // m_DXF_plotTextStrokeFontOpt is disabled if m_DXF_plotModeOpt
345  // is checked (plot in DXF polygon mode)
346  m_DXF_plotTextStrokeFontOpt->Enable( !m_DXF_plotModeOpt->GetValue() );
347 
348  // if m_DXF_plotTextStrokeFontOpt option is disabled (plot DXF in polygon mode),
349  // force m_DXF_plotTextStrokeFontOpt to true to use Pcbnew stroke font
350  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() )
351  m_DXF_plotTextStrokeFontOpt->SetValue( true );
352 }
353 
354 
355 void DIALOG_PLOT::OnSetScaleOpt( wxCommandEvent& event )
356 {
357  /* Disable sheet reference for scale != 1:1 */
358  bool scale1 = ( m_scaleOpt->GetSelection() == 1 );
359 
360  m_plotSheetRef->Enable( scale1 );
361 
362  if( !scale1 )
363  m_plotSheetRef->SetValue( false );
364 }
365 
366 
367 void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
368 {
369  // Build the absolute path of current output plot directory
370  // to preselect it when opening the dialog.
371  wxFileName fn( m_outputDirectoryName->GetValue() );
372  wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
373 
374  wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
375 
376  if( dirDialog.ShowModal() == wxID_CANCEL )
377  return;
378 
379  wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
380 
381  fn = Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() );
382  wxString defaultPath = fn.GetPathWithSep();
383  wxString msg;
384  msg.Printf( _( "Do you want to use a path relative to\n\"%s\"" ),
385  GetChars( defaultPath ) );
386 
387  wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
388  wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
389 
390  if( dialog.ShowModal() == wxID_YES )
391  {
392  if( !dirName.MakeRelativeTo( defaultPath ) )
393  wxMessageBox( _( "Cannot make path relative (target volume different from file volume)!" ),
394  _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
395  }
396 
397  m_outputDirectoryName->SetValue( dirName.GetFullPath() );
398 }
399 
400 
402 {
403  // plot format id's are ordered like displayed in m_plotFormatOpt
404  static const PlotFormat plotFmt[] =
405  {
412  };
413 
414  return plotFmt[ m_plotFormatOpt->GetSelection() ];
415 }
416 
417 
418 // Enable or disable widgets according to the plot format selected
419 // and clear also some optional values
420 void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
421 {
422  // this option exist only in DXF format:
424 
425  switch( getPlotFormat() )
426  {
427  case PLOT_FORMAT_PDF:
428  case PLOT_FORMAT_SVG:
429  m_drillShapeOpt->Enable( true );
430  m_plotModeOpt->Enable( false );
432  m_plotMirrorOpt->Enable( true );
433  m_useAuxOriginCheckBox->Enable( false );
434  m_useAuxOriginCheckBox->SetValue( false );
435  m_linesWidth->Enable( true );
436  m_HPGLPenSizeOpt->Enable( false );
437  m_excludeEdgeLayerOpt->Enable( true );
438  m_scaleOpt->Enable( false );
439  m_scaleOpt->SetSelection( 1 );
440  m_fineAdjustXscaleOpt->Enable( false );
441  m_fineAdjustYscaleOpt->Enable( false );
442  m_PSFineAdjustWidthOpt->Enable( false );
443  m_plotPSNegativeOpt->Enable( true );
444  m_forcePSA4OutputOpt->Enable( false );
445  m_forcePSA4OutputOpt->SetValue( false );
446 
451  break;
452 
453  case PLOT_FORMAT_POST:
454  m_drillShapeOpt->Enable( true );
455  m_plotModeOpt->Enable( true );
456  m_plotMirrorOpt->Enable( true );
457  m_useAuxOriginCheckBox->Enable( false );
458  m_useAuxOriginCheckBox->SetValue( false );
459  m_linesWidth->Enable( true );
460  m_HPGLPenSizeOpt->Enable( false );
461  m_excludeEdgeLayerOpt->Enable( true );
462  m_scaleOpt->Enable( true );
463  m_fineAdjustXscaleOpt->Enable( true );
464  m_fineAdjustYscaleOpt->Enable( true );
465  m_PSFineAdjustWidthOpt->Enable( true );
466  m_plotPSNegativeOpt->Enable( true );
467  m_forcePSA4OutputOpt->Enable( true );
468 
473  break;
474 
475  case PLOT_FORMAT_GERBER:
476  m_drillShapeOpt->Enable( false );
477  m_drillShapeOpt->SetSelection( 0 );
478  m_plotModeOpt->Enable( false );
480  m_plotMirrorOpt->Enable( false );
481  m_plotMirrorOpt->SetValue( false );
482  m_useAuxOriginCheckBox->Enable( true );
483  m_linesWidth->Enable( true );
484  m_HPGLPenSizeOpt->Enable( false );
485  m_excludeEdgeLayerOpt->Enable( true );
486  m_scaleOpt->Enable( false );
487  m_scaleOpt->SetSelection( 1 );
488  m_fineAdjustXscaleOpt->Enable( false );
489  m_fineAdjustYscaleOpt->Enable( false );
490  m_PSFineAdjustWidthOpt->Enable( false );
491  m_plotPSNegativeOpt->Enable( false );
492  m_plotPSNegativeOpt->SetValue( false );
493  m_forcePSA4OutputOpt->Enable( false );
494  m_forcePSA4OutputOpt->SetValue( false );
495 
500  break;
501 
502  case PLOT_FORMAT_HPGL:
503  m_drillShapeOpt->Enable( true );
504  m_plotModeOpt->Enable( true );
505  m_plotMirrorOpt->Enable( true );
506  m_useAuxOriginCheckBox->Enable( false );
507  m_useAuxOriginCheckBox->SetValue( false );
508  m_linesWidth->Enable( false );
509  m_HPGLPenSizeOpt->Enable( true );
510  m_excludeEdgeLayerOpt->Enable( true );
511  m_scaleOpt->Enable( true );
512  m_fineAdjustXscaleOpt->Enable( false );
513  m_fineAdjustYscaleOpt->Enable( false );
514  m_PSFineAdjustWidthOpt->Enable( false );
515  m_plotPSNegativeOpt->SetValue( false );
516  m_plotPSNegativeOpt->Enable( false );
517  m_forcePSA4OutputOpt->Enable( true );
518 
523  break;
524 
525  case PLOT_FORMAT_DXF:
526  m_drillShapeOpt->Enable( true );
527  m_plotModeOpt->Enable( false );
529  m_plotMirrorOpt->Enable( false );
530  m_plotMirrorOpt->SetValue( false );
531  m_useAuxOriginCheckBox->Enable( true );
532  m_linesWidth->Enable( false );
533  m_HPGLPenSizeOpt->Enable( false );
534  m_excludeEdgeLayerOpt->Enable( true );
535  m_scaleOpt->Enable( false );
536  m_scaleOpt->SetSelection( 1 );
537  m_fineAdjustXscaleOpt->Enable( false );
538  m_fineAdjustYscaleOpt->Enable( false );
539  m_PSFineAdjustWidthOpt->Enable( false );
540  m_plotPSNegativeOpt->Enable( false );
541  m_plotPSNegativeOpt->SetValue( false );
542  m_forcePSA4OutputOpt->Enable( false );
543  m_forcePSA4OutputOpt->SetValue( false );
544 
549 
550  OnChangeDXFPlotMode( event );
551  break;
552  }
553 
554  /* Update the interlock between scale and frame reference
555  * (scaling would mess up the frame border...) */
556  OnSetScaleOpt( event );
557 
558  Layout();
559  m_MainSizer->SetSizeHints( this );
560 }
561 
562 
563 // A helper function to "clip" aValue between aMin and aMax
564 // and write result in * aResult
565 // return false if clipped, true if aValue is just copied into * aResult
566 static bool setDouble( double* aResult, double aValue, double aMin, double aMax )
567 {
568  if( aValue < aMin )
569  {
570  *aResult = aMin;
571  return false;
572  }
573  else if( aValue > aMax )
574  {
575  *aResult = aMax;
576  return false;
577  }
578 
579  *aResult = aValue;
580  return true;
581 }
582 
583 
584 static bool setInt( int* aResult, int aValue, int aMin, int aMax )
585 {
586  if( aValue < aMin )
587  {
588  *aResult = aMin;
589  return false;
590  }
591  else if( aValue > aMax )
592  {
593  *aResult = aMax;
594  return false;
595  }
596 
597  *aResult = aValue;
598  return true;
599 }
600 
601 
603 {
604  REPORTER& reporter = m_messagesPanel->Reporter();
605 
606  PCB_PLOT_PARAMS tempOptions;
607 
608  tempOptions.SetExcludeEdgeLayer( m_excludeEdgeLayerOpt->GetValue() );
609  tempOptions.SetSubtractMaskFromSilk( m_subtractMaskFromSilk->GetValue() );
610  tempOptions.SetPlotFrameRef( m_plotSheetRef->GetValue() );
611  tempOptions.SetPlotPadsOnSilkLayer( !m_excludePadsFromSilkscreen->GetValue() );
612  tempOptions.SetUseAuxOrigin( m_useAuxOriginCheckBox->GetValue() );
613  tempOptions.SetPlotValue( m_plotModuleValueOpt->GetValue() );
614  tempOptions.SetPlotReference( m_plotModuleRefOpt->GetValue() );
615  tempOptions.SetPlotInvisibleText( m_plotInvisibleText->GetValue() );
616  tempOptions.SetScaleSelection( m_scaleOpt->GetSelection() );
617  tempOptions.SetDrillMarksType( static_cast<PCB_PLOT_PARAMS::DrillMarksType>
618  ( m_drillShapeOpt->GetSelection() ) );
619  tempOptions.SetMirror( m_plotMirrorOpt->GetValue() );
620  tempOptions.SetPlotMode( m_plotModeOpt->GetSelection() == 1 ? SKETCH : FILLED );
621  tempOptions.SetDXFPlotPolygonMode( m_DXF_plotModeOpt->GetValue() );
622  tempOptions.SetPlotViaOnMaskLayer( m_plotNoViaOnMaskOpt->GetValue() );
623 
624  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() ) // Currently, only DXF supports this option
625  tempOptions.SetTextMode( PLOTTEXTMODE_DEFAULT );
626  else
627  tempOptions.SetTextMode( m_DXF_plotTextStrokeFontOpt->GetValue() ?
629 
630  // Update settings from text fields. Rewrite values back to the fields,
631  // since the values may have been constrained by the setters.
632  wxString msg;
633 
634  // read HPLG pen size (this param is stored in mils)
635  // However, due to issues when converting this value from or to mm
636  // that can slightly change the value, update this param only if it
637  // is in use
638  if( m_HPGLPenSizeOpt->IsEnabled() )
639  {
640  msg = m_HPGLPenSizeOpt->GetValue();
641  double dtmp = DoubleValueFromString( m_userUnits, msg ) / IU_PER_MILS;
642 
643  if( !tempOptions.SetHPGLPenDiameter( dtmp ) )
644  {
645  msg = StringFromValue( m_userUnits, tempOptions.GetHPGLPenDiameter() * IU_PER_MILS );
646  m_HPGLPenSizeOpt->SetValue( msg );
647  msg.Printf( _( "HPGL pen size constrained." ) );
648  reporter.Report( msg, REPORTER::RPT_INFO );
649  }
650  }
651  else // keep the last value (initial value if no HPGL plot made)
653 
654  // Default linewidth
655  msg = m_linesWidth->GetValue();
656  int tmp = ValueFromString( m_userUnits, msg );
657 
658  if( !tempOptions.SetLineWidth( tmp ) )
659  {
660  msg = StringFromValue( m_userUnits, tempOptions.GetLineWidth() );
661  m_linesWidth->SetValue( msg );
662  msg.Printf( _( "Default line width constrained." ) );
663  reporter.Report( msg, REPORTER::RPT_INFO );
664  }
665 
666  // X scale
667  double tmpDouble;
668  msg = m_fineAdjustXscaleOpt->GetValue();
669  msg.ToDouble( &tmpDouble );
670 
671  if( !setDouble( &m_XScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
672  {
673  msg.Printf( wxT( "%f" ), m_XScaleAdjust );
674  m_fineAdjustXscaleOpt->SetValue( msg );
675  msg.Printf( _( "X scale constrained." ) );
676  reporter.Report( msg, REPORTER::RPT_INFO );
677  }
678 
680 
681  // Y scale
682  msg = m_fineAdjustYscaleOpt->GetValue();
683  msg.ToDouble( &tmpDouble );
684 
685  if( !setDouble( &m_YScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
686  {
687  msg.Printf( wxT( "%f" ), m_YScaleAdjust );
688  m_fineAdjustYscaleOpt->SetValue( msg );
689  msg.Printf( _( "Y scale constrained." ) );
690  reporter.Report( msg, REPORTER::RPT_INFO );
691  }
692 
694 
695  m_config->Write( OPTKEY_PLOT_CHECK_ZONES, m_zoneFillCheck->GetValue() );
696 
697  // PS Width correction
698  msg = m_PSFineAdjustWidthOpt->GetValue();
699  int itmp = ValueFromString( m_userUnits, msg );
700 
702  {
704  m_PSFineAdjustWidthOpt->SetValue( msg );
705  msg.Printf( _( "Width correction constrained. "
706  "The reasonable width correction value must be in a range of "
707  " [%+f; %+f] (%s) for current design rules." ),
710  ( m_userUnits == INCHES ) ? wxT( "\"" ) : wxT( "mm" ) );
711  reporter.Report( msg, REPORTER::RPT_WARNING );
712  }
713 
714  // Store m_PSWidthAdjust in mm in user config
716  (double)m_PSWidthAdjust / IU_PER_MM );
717 
718  tempOptions.SetFormat( getPlotFormat() );
719 
720  tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
721  tempOptions.SetUseGerberAttributes( m_useGerberX2Attributes->GetValue() );
722  tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
723  tempOptions.SetCreateGerberJobFile( m_generateGerberJobFile->GetValue() );
724 
725  tempOptions.SetGerberPrecision( m_rbGerberFormat->GetSelection() == 0 ? 5 : 6 );
726 
727  LSET selectedLayers;
728  for( unsigned i = 0; i < m_layerList.size(); i++ )
729  {
730  if( m_layerCheckListBox->IsChecked( i ) )
731  selectedLayers.set( m_layerList[i] );
732  }
733  // Get a list of copper layers that aren't being used by inverting enabled layers.
734  LSET disabledCopperLayers = LSET::AllCuMask() & ~m_parent->GetBoard()->GetEnabledLayers();
735  // Enable all of the disabled copper layers.
736  // If someone enables more copper layers they will be selected by default.
737  selectedLayers = selectedLayers | disabledCopperLayers;
738  tempOptions.SetLayerSelection( selectedLayers );
739 
740  tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() );
741  tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() );
742 
743  // Set output directory and replace backslashes with forward ones
744  wxString dirStr;
745  dirStr = m_outputDirectoryName->GetValue();
746  dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
747  tempOptions.SetOutputDirectory( dirStr );
748 
749  if( !m_plotOpts.IsSameAs( tempOptions, false ) )
750  {
751  // First, mark board as modified only for parameters saved in file
752  if( !m_plotOpts.IsSameAs( tempOptions, true ) )
753  m_parent->OnModify();
754 
755  // Now, save any change, for the session
756  m_parent->SetPlotSettings( tempOptions );
757  m_plotOpts = tempOptions;
758  }
759 }
760 
761 
762 void DIALOG_PLOT::OnGerberX2Checked( wxCommandEvent& event )
763 {
764  // m_useGerberNetAttributes is useless if m_useGerberX2Attributes
765  // is not checked. So disabled (greyed out) when Gerber X2 gets unchecked
766  // to make it clear to the user.
767  if( m_useGerberX2Attributes->GetValue() )
768  {
769  m_useGerberNetAttributes->Enable( true );
770  }
771  else
772  {
773  m_useGerberNetAttributes->Enable( false );
774  m_useGerberNetAttributes->SetValue( false );
775  }
776 }
777 
778 
779 void DIALOG_PLOT::Plot( wxCommandEvent& event )
780 {
781  BOARD* board = m_parent->GetBoard();
782 
784 
785  // If no layer selected, we have nothing plotted.
786  // Prompt user if it happens because he could think there is a bug in Pcbnew.
787  if( !m_plotOpts.GetLayerSelection().any() )
788  {
789  DisplayError( this, _( "No layer selected, Nothing to plot" ) );
790  return;
791  }
792 
793  // Create output directory if it does not exist (also transform it in
794  // absolute form). Bail if it fails
795  wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
796  wxString boardFilename = m_parent->GetBoard()->GetFileName();
797  REPORTER& reporter = m_messagesPanel->Reporter();
798 
799  if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
800  {
801  wxString msg;
802  msg.Printf( _( "Could not write plot files to folder \"%s\"." ),
803  GetChars( outputDir.GetPath() ) );
804  DisplayError( this, msg );
805  return;
806  }
807 
808  if( m_zoneFillCheck->GetValue() )
809  m_parent->Check_All_Zones( this );
810 
811  m_plotOpts.SetAutoScale( false );
812  m_plotOpts.SetScale( 1 );
813 
814  switch( m_plotOpts.GetScaleSelection() )
815  {
816  default:
817  break;
818 
819  case 0: // Autoscale option
820  m_plotOpts.SetAutoScale( true );
821  break;
822 
823  case 2: // 3:2 option
824  m_plotOpts.SetScale( 1.5 );
825  break;
826 
827  case 3: // 2:1 option
828  m_plotOpts.SetScale( 2 );
829  break;
830 
831  case 4: // 3:1 option
832  m_plotOpts.SetScale( 3 );
833  break;
834  }
835 
836  /* If the scale factor edit controls are disabled or the scale value
837  * is 0, don't adjust the base scale factor. This fixes a bug when
838  * the default scale adjust is initialized to 0 and saved in program
839  * settings resulting in a divide by zero fault.
840  */
841  if( m_fineAdjustXscaleOpt->IsEnabled() && m_XScaleAdjust != 0.0 )
843 
844  if( m_fineAdjustYscaleOpt->IsEnabled() && m_YScaleAdjust != 0.0 )
846 
847  if( m_PSFineAdjustWidthOpt->IsEnabled() )
849 
850  wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
851 
852  // Test for a reasonable scale value
853  // XXX could this actually happen? isn't it constrained in the apply
854  // function?
856  DisplayInfoMessage( this,
857  _( "Warning: Scale option set to a very small value" ) );
858 
860  DisplayInfoMessage( this,
861  _( "Warning: Scale option set to a very large value" ) );
862 
863  GERBER_JOBFILE_WRITER jobfile_writer( board, &reporter );
864 
865  // Save the current plot options in the board
867 
868  wxBusyCursor dummy;
869 
870  for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq )
871  {
872  PCB_LAYER_ID layer = *seq;
873 
874  // All copper layers that are disabled are actually selected
875  // This is due to wonkyness in automatically selecting copper layers
876  // for plotting when adding more than two layers to a board.
877  // If plot options become accessible to the layers setup dialog
878  // please move this functionality there!
879  // This skips a copper layer if it is actually disabled on the board.
880  if( ( LSET::AllCuMask() & ~board->GetEnabledLayers() )[layer] )
881  continue;
882 
883  // Pick the basename from the board file
884  wxFileName fn( boardFilename );
885 
886  // Use Gerber Extensions based on layer number
887  // (See http://en.wikipedia.org/wiki/Gerber_File)
889  file_ext = GetGerberProtelExtension( layer );
890 
891  BuildPlotFileName( &fn, outputDir.GetPath(), board->GetLayerName( layer ), file_ext );
892  wxString fullname = fn.GetFullName();
893  jobfile_writer.AddGbrFile( layer, fullname );
894 
895  LOCALE_IO toggle;
896 
897  PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
898 
899  // Print diags in messages box:
900  wxString msg;
901 
902  if( plotter )
903  {
904  PlotOneBoardLayer( board, plotter, layer, m_plotOpts );
905  plotter->EndPlot();
906  delete plotter;
907 
908  msg.Printf( _( "Plot file \"%s\" created." ), GetChars( fn.GetFullPath() ) );
909  reporter.Report( msg, REPORTER::RPT_ACTION );
910  }
911  else
912  {
913  msg.Printf( _( "Unable to create file \"%s\"." ), GetChars( fn.GetFullPath() ) );
914  reporter.Report( msg, REPORTER::RPT_ERROR );
915  }
916  }
917 
919  {
920  // Pick the basename from the board file
921  wxFileName fn( boardFilename );
922  // Build gerber job file from basename
923  BuildPlotFileName( &fn, outputDir.GetPath(), "job", GerberJobFileExtension );
924  jobfile_writer.CreateJobFile( fn.GetFullPath() );
925  }
926 }
927 
928 
929 void DIALOG_PLOT::onRunDRC( wxCommandEvent& event )
930 {
931  PCB_EDIT_FRAME* parent = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
932 
933  if( parent )
934  {
935  // First close an existing dialog if open
936  // (low probability, but can happen)
937  parent->GetDrcController()->DestroyDRCDialog( wxID_OK );
938 
939  // Open a new drc dialod, with the right parent frame, and in Modal Mode
940  parent->GetDrcController()->ShowDRCDialog( this );
941  }
942 }
943 
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:48
void SetIncludeGerberNetlistInfo(bool aUse)
int m_SolderMaskMargin
Solder mask margin.
double GetHPGLPenDiameter() const
void SetDXFPlotPolygonMode(bool aFlag)
wxTextCtrl * m_linesWidth
bool GetMirror() const
double m_YScaleAdjust
Definition: dialog_plot.h:51
virtual void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
bool GetSubtractMaskFromSilk() const
wxTextCtrl * m_fineAdjustYscaleOpt
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:117
double GetScale() const
void SetGerberPrecision(int aPrecision)
void OnOutputDirectoryBrowseClicked(wxCommandEvent &event) override
wxButton * m_sdbSizer1Cancel
void SetPlotViaOnMaskLayer(bool aFlag)
bool CreateJobFile(const wxString &aFullFilename)
Creates a Gerber job file.
wxStaticText * m_SolderMaskMarginCurrValue
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:106
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown...
Definition: common.h:167
#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:69
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.
void Check_All_Zones(wxWindow *aActiveWindow)
Function Check_All_Zones Checks for out-of-date fills and fills them if requested by the user...
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:47
PlotFormat
Enum PlotFormat is the set of supported output plot formats.
Definition: plotter.h:50
BOARD * GetBoard() const
wxCheckBox * m_plotMirrorOpt
wxCheckBox * m_zoneFillCheck
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:49
wxButton * m_sdbSizer1Apply
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
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:45
int GetLineWidth() const
int m_widthAdjustMaxValue
Definition: dialog_plot.h:58
wxStaticText * m_SolderMaskMinWidthCurrValue
const wxString & GetFileName() const
Definition: class_board.h:236
PlotTextMode GetTextMode() const
int m_TrackMinWidth
track min value for width ((min copper size value
Definition: common.h:146
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:282
REPORTER & Reporter()
returns the reporter object that reports to this panel
#define PLOT_MAX_SCALE
Definition: pcbplot.h:70
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:53
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:383
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:535
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:84
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:57
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:61
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)
bool SetHPGLPenDiameter(double aValue)
Base plotter engine class.
Definition: plotter.h:96
wxBoxSizer * m_sizerButtons
wxCheckBox * m_subtractMaskFromSilk
void init_Dialog()
Definition: dialog_plot.cpp:70
EDA_UNITS_T m_userUnits
Definition: dialog_plot.h:46
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
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
bool GetPlotPadsOnSilkLayer() const
wxCheckBox * m_useAuxOriginCheckBox
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.
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
#define OPTKEY_PLOT_CHECK_ZONES
Definition: pcbplot.h:64
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...
#define DLG_WINDOW_NAME
Definition: dialog_plot.h:33
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
double DoubleValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:303
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