KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 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#include <wx/bmpbuttn.h>
25#include <wx/clntdata.h>
26#include <wx/rearrangectrl.h>
27
28#include <plotters/plotter.h>
29#include <confirm.h>
30#include <pcb_edit_frame.h>
32#include <pcbplot.h>
33#include <pgm_base.h>
35#include <reporter.h>
37#include <layer_ids.h>
38#include <locale_io.h>
39#include <bitmaps.h>
40#include <dialog_plot.h>
41#include <dialog_gendrill.h>
44#include <tool/tool_manager.h>
46#include <tools/drc_tool.h>
47#include <math/util.h> // for KiROUND
48#include <macros.h>
52
53#include <wx/dirdlg.h>
54#include <wx/msgdlg.h>
55
56
60
61
65class PCB_LAYER_ID_CLIENT_DATA : public wxClientData
66{
67public:
70 { }
71
73 m_id( aId )
74 { }
75
76 void SetData( PCB_LAYER_ID aId ) { m_id = aId; }
77 PCB_LAYER_ID Layer() const { return m_id; }
78
79private:
81};
82
83
84PCB_LAYER_ID_CLIENT_DATA* getLayerClientData( const wxRearrangeList* aList, int aIdx )
85{
86 return static_cast<PCB_LAYER_ID_CLIENT_DATA*>( aList->GetClientObject( aIdx ) );
87}
88
89
91 : DIALOG_PLOT( aEditFrame, aEditFrame )
92{
93}
94
95
96DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent,
97 JOB_EXPORT_PCB_PLOT* aJob ) :
98 DIALOG_PLOT_BASE( aParent ),
99 m_editFrame( aEditFrame ),
100 m_defaultPenSize( m_editFrame, m_hpglPenLabel, m_hpglPenCtrl, m_hpglPenUnits ),
101 m_trackWidthCorrection( m_editFrame, m_widthAdjustLabel, m_widthAdjustCtrl, m_widthAdjustUnits ),
102 m_job( aJob )
103{
104 BOARD* board = m_editFrame->GetBoard();
105
106 SetName( DLG_WINDOW_NAME );
109
110 if( m_job )
111 {
112 m_messagesPanel->Hide();
113
114 m_browseButton->Hide();
115 m_staticTextPlotFmt->Hide();
116 m_plotFormatOpt->Hide();
117 m_sdbSizer1Apply->Hide();
118 }
119 else
120 {
121 m_messagesPanel->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) );
122 }
123
124 int order = 0;
125 LSET plotOnAllLayersSelection = m_plotOpts.GetPlotOnAllLayersSelection();
126 wxArrayInt plotAllLayersOrder;
127 wxArrayString plotAllLayersChoicesStrings;
128 std::vector<PCB_LAYER_ID> layersIdChoiceList;
129 int textWidth = 0;
130
131 for( PCB_LAYER_ID layer : board->GetEnabledLayers().SeqStackupForPlotting() )
132 {
133 wxString layerName = board->GetLayerName( layer );
134
135 // wxCOL_WIDTH_AUTOSIZE doesn't work on all platforms, so we calculate width here
136 textWidth = std::max( textWidth, KIUI::GetTextSize( layerName, m_layerCheckListBox ).x );
137
138 plotAllLayersChoicesStrings.Add( layerName );
139 layersIdChoiceList.push_back( layer );
140
141 size_t size = plotOnAllLayersSelection.size();
142
143 if( ( static_cast<size_t>( layer ) <= size ) && plotOnAllLayersSelection.test( layer ) )
144 plotAllLayersOrder.push_back( order );
145 else
146 plotAllLayersOrder.push_back( ~order );
147
148 order += 1;
149 }
150
151 int checkColSize = 22;
152 int layerColSize = textWidth + 15;
153
154#ifdef __WXMAC__
155 // TODO: something in wxWidgets 3.1.x pads checkbox columns with extra space. (It used to
156 // also be that the width of the column would get set too wide (to 30), but that's patched in
157 // our local wxWidgets fork.)
158 checkColSize += 30;
159#endif
160
161 m_layerCheckListBox->SetMinClientSize( wxSize( checkColSize + layerColSize,
162 m_layerCheckListBox->GetMinClientSize().y ) );
163
164 wxStaticBox* allLayersLabel = new wxStaticBox( this, wxID_ANY, _( "Plot on All Layers" ) );
165 wxStaticBoxSizer* sbSizer = new wxStaticBoxSizer( allLayersLabel, wxVERTICAL );
166
167 m_plotAllLayersList = new wxRearrangeList( sbSizer->GetStaticBox(), wxID_ANY,
168 wxDefaultPosition, wxDefaultSize,
169 plotAllLayersOrder, plotAllLayersChoicesStrings, 0 );
170
171 m_plotAllLayersList->SetMinClientSize( wxSize( checkColSize + layerColSize,
172 m_plotAllLayersList->GetMinClientSize().y ) );
173
174 // Attach the LAYER_ID to each item in m_plotAllLayersList
175 // plotAllLayersChoicesStrings and layersIdChoiceList are in the same order,
176 // but m_plotAllLayersList has these strings in a different order
177 for( size_t idx = 0; idx < layersIdChoiceList.size(); idx++ )
178 {
179 wxString& txt = plotAllLayersChoicesStrings[idx];
180 int list_idx = m_plotAllLayersList->FindString( txt, true );
181
182 PCB_LAYER_ID layer_id = layersIdChoiceList[idx];
183 m_plotAllLayersList->SetClientObject( list_idx, new PCB_LAYER_ID_CLIENT_DATA( layer_id ) );
184 }
185
186 sbSizer->Add( m_plotAllLayersList, 1, wxALL | wxEXPAND | wxFIXED_MINSIZE, 3 );
187
188 wxBoxSizer* bButtonSizer;
189 bButtonSizer = new wxBoxSizer( wxHORIZONTAL );
190
191 m_bpMoveUp = new STD_BITMAP_BUTTON( sbSizer->GetStaticBox(), wxID_ANY, wxNullBitmap,
192 wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | 0 );
193 m_bpMoveUp->SetToolTip( _( "Move current selection up" ) );
194 m_bpMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
195
196 bButtonSizer->Add( m_bpMoveUp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3 );
197
198 m_bpMoveDown = new STD_BITMAP_BUTTON( sbSizer->GetStaticBox(), wxID_ANY, wxNullBitmap,
199 wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | 0 );
200 m_bpMoveDown->SetToolTip( _( "Move current selection down" ) );
201 m_bpMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
202
203 bButtonSizer->Add( m_bpMoveDown, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 );
204
205 sbSizer->Add( bButtonSizer, 0, wxALL | wxEXPAND, 3 );
206
207 bmiddleSizer->Insert( 1, sbSizer, 1, wxALL | wxEXPAND, 5 );
208
209 init_Dialog();
210
211 if( m_job )
212 {
213 SetupStandardButtons( { { wxID_OK, _( "Save" ) },
214 { wxID_CANCEL, _( "Close" ) } } );
215 }
216 else
217 {
218 SetupStandardButtons( { { wxID_OK, _( "Plot" ) },
219 { wxID_APPLY, _( "Generate Drill Files..." ) },
220 { wxID_CANCEL, _( "Close" ) } } );
221 }
222
223 GetSizer()->Fit( this );
224 GetSizer()->SetSizeHints( this );
225
226 m_bpMoveUp->Bind( wxEVT_COMMAND_BUTTON_CLICKED, &DIALOG_PLOT::onPlotAllListMoveUp, this );
227 m_bpMoveDown->Bind( wxEVT_COMMAND_BUTTON_CLICKED, &DIALOG_PLOT::onPlotAllListMoveDown, this );
228
229 m_layerCheckListBox->Connect( wxEVT_RIGHT_DOWN,
230 wxMouseEventHandler( DIALOG_PLOT::OnRightClickLayers ), nullptr,
231 this );
232
233 m_plotAllLayersList->Connect( wxEVT_RIGHT_DOWN,
234 wxMouseEventHandler( DIALOG_PLOT::OnRightClickAllLayers ), nullptr,
235 this );
236}
237
238
240{
241 s_lastAllLayersOrder.clear();
242
243 for( int ii = 0; ii < (int) m_plotAllLayersList->GetCount(); ++ii )
245
246 m_bpMoveDown->Unbind( wxEVT_COMMAND_BUTTON_CLICKED, &DIALOG_PLOT::onPlotAllListMoveDown, this );
247 m_bpMoveUp->Unbind( wxEVT_COMMAND_BUTTON_CLICKED, &DIALOG_PLOT::onPlotAllListMoveUp, this );
248}
249
250
252{
253 BOARD* board = m_editFrame->GetBoard();
254 wxFileName fileName;
255
256 PROJECT_FILE& projectFile = m_editFrame->Prj().GetProjectFile();
257
258 // Could devote a PlotOrder() function in place of UIOrder().
260
261 if( !m_job )
262 {
264
265 if( !projectFile.m_PcbLastPath[ LAST_PATH_PLOT ].IsEmpty() )
267
270
272
273 m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
274 m_openDirButton->SetBitmap( KiBitmapBundle( BITMAPS::small_new_window ) );
275
276 // m_PSWidthAdjust is stored in mm in user config
278
279 // The reasonable width correction value must be in a range of
280 // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils.
283
284 switch( m_plotOpts.GetFormat() )
285 {
286 default:
287 case PLOT_FORMAT::GERBER: m_plotFormatOpt->SetSelection( 0 ); break;
288 case PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 1 ); break;
289 case PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break;
290 case PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break;
291 case PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
292 case PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 5 ); break;
293 }
294
295 // Set units and value for HPGL pen size (this param is in mils).
297
298 // Test for a reasonable scale value. Set to 1 if problem
301 {
303 }
304
306 unityScale, EDA_UNITS::UNSCALED, m_XScaleAdjust ) );
307
309 unityScale, EDA_UNITS::UNSCALED, m_YScaleAdjust ) );
310
311 // Test for a reasonable PS width correction value. Set to 0 if problem.
312 if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue )
313 m_PSWidthAdjust = 0.;
314
316
319
320 // Populate the check list box by all enabled layers names.
321 for( PCB_LAYER_ID layer : m_layerList )
322 {
323 int checkIndex = m_layerCheckListBox->Append( board->GetLayerName( layer ) );
324
325 if( m_plotOpts.GetLayerSelection()[layer] )
326 m_layerCheckListBox->Check( checkIndex );
327 }
328
330
331 // Option for disabling Gerber Aperture Macro (for broken Gerber readers)
333
334 // Option for using proper Gerber extensions. Note also Protel extensions are
335 // a broken feature. However, for now, we need to handle it.
337
338 // Option for including Gerber attributes, from Gerber X2 format, in the output
339 // In X1 format, they will be added as comments
341
342 // Option for including Gerber netlist info (from Gerber X2 format) in the output
344
345 // Option to generate a Gerber job file
347
348 // Gerber precision for coordinates
349 m_coordFormatCtrl->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
350
351 // SVG precision and units for coordinates
353
354 // Option to exclude pads from silkscreen layers
358
362
363 if( m_plotDNP->GetValue() )
364 {
366 m_hideDNP->SetValue( true );
367 else
368 m_crossoutDNP->SetValue( true );
369 }
370
371 m_hideDNP->Enable( m_plotDNP->GetValue() );
372 m_crossoutDNP->Enable( m_plotDNP->GetValue() );
373
374 // Option to tent vias
376
377 // Option to use aux origin
379
380 // Option to plot page references:
382
383 // Option to force ploting of hidden text in footprints
385
386 // Options to plot pads and vias holes
387 m_drillShapeOpt->SetSelection( (int) m_plotOpts.GetDrillMarksType() );
388
389 // Scale option
390 m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() );
391
392 // Plot mode
394
395 // DXF outline mode
397
398 // DXF text mode
400 == PLOT_TEXT_MODE::DEFAULT );
401
402 // DXF units selection
403 m_DXF_plotUnits->SetSelection( m_plotOpts.GetDXFPlotUnits() == DXF_UNITS::INCHES ? 0 : 1 );
404
405 // Plot mirror option
406 m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() );
407
408 // Black and white plotting
409 m_SVGColorChoice->SetSelection( m_plotOpts.GetBlackAndWhite() ? 1 : 0 );
410 m_PDFColorChoice->SetSelection( m_plotOpts.GetBlackAndWhite() ? 1 : 0 );
414 }
415 else
416 {
417 m_plotFormatOpt->Hide();
418
419 switch( m_job->m_plotFormat )
420 {
421 default:
422 case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::GERBER: m_plotFormatOpt->SetSelection( 0 ); break;
423 case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 1 ); break;
424 case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break;
425 case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break;
426 case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
427 case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 5 ); break;
428 }
429 }
430
431 // Initialize a few other parameters, which can also be modified
432 // from the drill dialog
433 reInitDialog();
434
435 // Update options values:
436 wxCommandEvent cmd_event;
437 SetPlotFormat( cmd_event );
438 OnSetScaleOpt( cmd_event );
439}
440
441
443{
444 // after calling the Drill or DRC dialogs some parameters can be modified....
445
446 // Output directory
448
449 // Origin of coordinates:
451
452 int knownViolations = 0;
453 int exclusions = 0;
454
455 for( PCB_MARKER* marker : m_editFrame->GetBoard()->Markers() )
456 {
457 if( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION )
458 exclusions++;
459 else
460 knownViolations++;
461 }
462
463 if( knownViolations || exclusions )
464 {
465 m_DRCExclusionsWarning->SetLabel( wxString::Format( m_DRCWarningTemplate, knownViolations,
466 exclusions ) );
468 }
469 else
470 {
472 }
473
474 BOARD* board = m_editFrame->GetBoard();
475 const BOARD_DESIGN_SETTINGS& brd_settings = board->GetDesignSettings();
476
477 if( getPlotFormat() == PLOT_FORMAT::GERBER &&
478 ( brd_settings.m_SolderMaskExpansion || brd_settings.m_SolderMaskMinWidth ) )
479 {
481 }
482 else
483 {
485 }
486}
487
488
490{
491 auto findLayer =
492 [&]( wxRearrangeList* aList, PCB_LAYER_ID aLayer ) -> int
493 {
494 for( int ii = 0; ii < (int) aList->GetCount(); ++ii )
495 {
496 if( getLayerClientData( aList, ii )->Layer() == aLayer )
497 return ii;
498 }
499
500 return -1;
501 };
502
503 int idx = 0;
504
505 for( PCB_LAYER_ID layer : aSeq )
506 {
507 int currentPos = findLayer( m_plotAllLayersList, layer );
508
509 while( currentPos > idx )
510 {
511 m_plotAllLayersList->Select( currentPos );
512 m_plotAllLayersList->MoveCurrentUp();
513 currentPos--;
514 }
515 }
516}
517
518
519#define ID_LAYER_FAB 13001
520#define ID_SELECT_COPPER_LAYERS 13002
521#define ID_DESELECT_COPPER_LAYERS 13003
522#define ID_SELECT_ALL_LAYERS 13004
523#define ID_DESELECT_ALL_LAYERS 13005
524#define ID_STACKUP_ORDER 13006
525
526
527// A helper function to show a popup menu, when the dialog is right clicked.
528void DIALOG_PLOT::OnRightClickLayers( wxMouseEvent& event )
529{
530 // Build a list of layers for usual fabrication: copper layers + tech layers without courtyard
531 LSET fab_layer_set = ( LSET::AllCuMask() | LSET::AllTechMask() ) & ~LSET( { B_CrtYd, F_CrtYd } );
532
533 wxMenu menu;
534 menu.Append( new wxMenuItem( &menu, ID_LAYER_FAB, _( "Select Fab Layers" ) ) );
535
536 menu.AppendSeparator();
537 menu.Append( new wxMenuItem( &menu, ID_SELECT_COPPER_LAYERS, _( "Select All Copper Layers" ) ) );
538 menu.Append( new wxMenuItem( &menu, ID_DESELECT_COPPER_LAYERS, _( "Deselect All Copper Layers" ) ) );
539
540 menu.AppendSeparator();
541 menu.Append( new wxMenuItem( &menu, ID_SELECT_ALL_LAYERS, _( "Select All Layers" ) ) );
542 menu.Append( new wxMenuItem( &menu, ID_DESELECT_ALL_LAYERS, _( "Deselect All Layers" ) ) );
543
544 menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
545 [&]( wxCommandEvent& aCmd )
546 {
547 switch( aCmd.GetId() )
548 {
549 case ID_LAYER_FAB: // Select layers usually needed to build a board
550 {
551 for( unsigned i = 0; i < m_layerList.size(); i++ )
552 {
553 LSET layermask( { m_layerList[ i ] } );
554
555 if( ( layermask & fab_layer_set ).any() )
556 m_layerCheckListBox->Check( i, true );
557 else
558 m_layerCheckListBox->Check( i, false );
559 }
560
561 break;
562 }
563
565 for( unsigned i = 0; i < m_layerList.size(); i++ )
566 {
567 if( IsCopperLayer( m_layerList[i] ) )
568 m_layerCheckListBox->Check( i, true );
569 }
570
571 break;
572
574 for( unsigned i = 0; i < m_layerList.size(); i++ )
575 {
576 if( IsCopperLayer( m_layerList[i] ) )
577 m_layerCheckListBox->Check( i, false );
578 }
579
580 break;
581
583 for( unsigned i = 0; i < m_layerList.size(); i++ )
584 m_layerCheckListBox->Check( i, true );
585
586 break;
587
589 for( unsigned i = 0; i < m_layerList.size(); i++ )
590 m_layerCheckListBox->Check( i, false );
591
592 break;
593
594 default:
595 aCmd.Skip();
596 }
597 } );
598
599 PopupMenu( &menu );
600}
601
602
603void DIALOG_PLOT::OnRightClickAllLayers( wxMouseEvent& event )
604{
605 wxMenu menu;
606 menu.Append( new wxMenuItem( &menu, ID_SELECT_ALL_LAYERS, _( "Select All Layers" ) ) );
607 menu.Append( new wxMenuItem( &menu, ID_DESELECT_ALL_LAYERS, _( "Deselect All Layers" ) ) );
608
609 menu.AppendSeparator();
610 menu.Append( new wxMenuItem( &menu, ID_STACKUP_ORDER, _( "Order as Board Stackup" ) ) );
611
612 menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
613 [&]( wxCommandEvent& aCmd )
614 {
615 switch( aCmd.GetId() )
616 {
617 case ID_SELECT_ALL_LAYERS:
618 for( unsigned i = 0; i < m_plotAllLayersList->GetCount(); i++ )
619 m_plotAllLayersList->Check( i, true );
620
621 break;
622
623 case ID_DESELECT_ALL_LAYERS:
624 for( unsigned i = 0; i < m_plotAllLayersList->GetCount(); i++ )
625 m_plotAllLayersList->Check( i, false );
626
627 break;
628
629 case ID_STACKUP_ORDER:
630 {
631 LSEQ stackup = m_editFrame->GetBoard()->GetEnabledLayers().SeqStackupForPlotting();
632 arrangeAllLayersList( stackup );
633 m_plotAllLayersList->Select( -1 );
634 break;
635 }
636
637 default:
638 aCmd.Skip();
639 }
640 } );
641
642 PopupMenu( &menu );
643}
644
645
646void DIALOG_PLOT::CreateDrillFile( wxCommandEvent& event )
647{
648 // Be sure drill file use the same settings (axis option, plot directory) as plot files:
650
651 DIALOG_GENDRILL dlg( m_editFrame, this );
652 dlg.ShowModal();
653
654 // a few plot settings can be modified: take them in account
656 reInitDialog();
657}
658
659
660void DIALOG_PLOT::OnChangeDXFPlotMode( wxCommandEvent& event )
661{
662 // m_DXF_plotTextStrokeFontOpt is disabled if m_DXF_plotModeOpt is checked (plot in DXF
663 // polygon mode)
664 m_DXF_plotTextStrokeFontOpt->Enable( !m_DXF_plotModeOpt->GetValue() );
665
666 // if m_DXF_plotTextStrokeFontOpt option is disabled (plot DXF in polygon mode), force
667 // m_DXF_plotTextStrokeFontOpt to true to use Pcbnew stroke font
668 if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() )
669 m_DXF_plotTextStrokeFontOpt->SetValue( true );
670}
671
672
673void DIALOG_PLOT::OnSetScaleOpt( wxCommandEvent& event )
674{
675 /* Disable sheet reference for scale != 1:1 */
676 bool scale1 = ( m_scaleOpt->GetSelection() == 1 );
677
678 m_plotSheetRef->Enable( scale1 );
679
680 if( !scale1 )
681 m_plotSheetRef->SetValue( false );
682}
683
684
686{
687 // Build the absolute path of current output directory to preselect it in the file browser.
688 std::function<bool( wxString* )> textResolver =
689 [&]( wxString* token ) -> bool
690 {
691 return m_editFrame->GetBoard()->ResolveTextVar( token, 0 );
692 };
693
694 wxString path = m_outputDirectoryName->GetValue();
695 path = ExpandTextVars( path, &textResolver );
697 path = Prj().AbsolutePath( path );
698
699 wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
700
701 if( dirDialog.ShowModal() == wxID_CANCEL )
702 return;
703
704 wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
705
706 wxFileName fn( Prj().AbsolutePath( m_editFrame->GetBoard()->GetFileName() ) );
707 wxString defaultPath = fn.GetPathWithSep();
708 wxString msg;
709 wxFileName relPathTest; // Used to test if we can make the path relative
710
711 relPathTest.Assign( dirDialog.GetPath() );
712
713 // Test if making the path relative is possible before asking the user if they want to do it
714 if( relPathTest.MakeRelativeTo( defaultPath ) )
715 {
716 msg.Printf( _( "Do you want to use a path relative to\n'%s'?" ), defaultPath );
717
718 wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
719 wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
720
721 if( dialog.ShowModal() == wxID_YES )
722 dirName.MakeRelativeTo( defaultPath );
723 }
724
725 m_outputDirectoryName->SetValue( dirName.GetFullPath() );
726}
727
728
730{
731 // plot format id's are ordered like displayed in m_plotFormatOpt
732 static const PLOT_FORMAT plotFmt[] = {
733 PLOT_FORMAT::GERBER,
734 PLOT_FORMAT::POST,
735 PLOT_FORMAT::SVG,
736 PLOT_FORMAT::DXF,
737 PLOT_FORMAT::HPGL,
738 PLOT_FORMAT::PDF };
739
740 return plotFmt[m_plotFormatOpt->GetSelection()];
741}
742
743
744void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
745{
746 // this option exist only in DXF format:
747 m_DXF_plotModeOpt->Enable( getPlotFormat() == PLOT_FORMAT::DXF );
748
749 // The alert message about non 0 solder mask min width and margin is shown
750 // only in gerber format and if min mask width or mask margin is not 0
751 BOARD* board = m_editFrame->GetBoard();
752 const BOARD_DESIGN_SETTINGS& brd_settings = board->GetDesignSettings();
753
754 if( getPlotFormat() == PLOT_FORMAT::GERBER
755 && ( brd_settings.m_SolderMaskExpansion || brd_settings.m_SolderMaskMinWidth ) )
756 {
758 }
759 else
760 {
762 }
763
764 switch( getPlotFormat() )
765 {
766 case PLOT_FORMAT::SVG:
767 case PLOT_FORMAT::PDF:
768 m_drillShapeOpt->Enable( true );
769 m_plotModeOpt->Enable( false );
771 m_plotMirrorOpt->Enable( true );
772 m_useAuxOriginCheckBox->Enable( true );
773 m_defaultPenSize.Enable( false );
774 m_scaleOpt->Enable( false );
775 m_scaleOpt->SetSelection( 1 );
776 m_fineAdjustXCtrl->Enable( false );
777 m_fineAdjustYCtrl->Enable( false );
779 m_plotPSNegativeOpt->Enable( true );
780 m_forcePSA4OutputOpt->Enable( false );
781 m_forcePSA4OutputOpt->SetValue( false );
782
783 if( getPlotFormat() == PLOT_FORMAT::SVG )
784 {
787 }
788 else
789 {
792 }
793
798 break;
799
800 case PLOT_FORMAT::POST:
801 m_drillShapeOpt->Enable( true );
802 m_plotModeOpt->Enable( true );
803 m_plotMirrorOpt->Enable( true );
804 m_useAuxOriginCheckBox->Enable( false );
805 m_useAuxOriginCheckBox->SetValue( false );
806 m_defaultPenSize.Enable( false );
807 m_scaleOpt->Enable( true );
808 m_fineAdjustXCtrl->Enable( true );
809 m_fineAdjustYCtrl->Enable( true );
811 m_plotPSNegativeOpt->Enable( true );
812 m_forcePSA4OutputOpt->Enable( true );
813
820 break;
821
822 case PLOT_FORMAT::GERBER:
823 m_drillShapeOpt->Enable( false );
824 m_drillShapeOpt->SetSelection( 0 );
825 m_plotModeOpt->Enable( false );
827 m_plotMirrorOpt->Enable( false );
828 m_plotMirrorOpt->SetValue( false );
829 m_useAuxOriginCheckBox->Enable( true );
830 m_defaultPenSize.Enable( false );
831 m_scaleOpt->Enable( false );
832 m_scaleOpt->SetSelection( 1 );
833 m_fineAdjustXCtrl->Enable( false );
834 m_fineAdjustYCtrl->Enable( false );
836 m_plotPSNegativeOpt->Enable( false );
837 m_plotPSNegativeOpt->SetValue( false );
838 m_forcePSA4OutputOpt->Enable( false );
839 m_forcePSA4OutputOpt->SetValue( false );
840
847 break;
848
849 case PLOT_FORMAT::HPGL:
850 m_drillShapeOpt->Enable( true );
851 m_plotModeOpt->Enable( true );
852 m_plotMirrorOpt->Enable( true );
853 m_useAuxOriginCheckBox->Enable( false );
854 m_useAuxOriginCheckBox->SetValue( false );
855 m_defaultPenSize.Enable( true );
856 m_scaleOpt->Enable( true );
857 m_fineAdjustXCtrl->Enable( false );
858 m_fineAdjustYCtrl->Enable( false );
860 m_plotPSNegativeOpt->SetValue( false );
861 m_plotPSNegativeOpt->Enable( false );
862 m_forcePSA4OutputOpt->Enable( true );
863
870 break;
871
872 case PLOT_FORMAT::DXF:
873 m_drillShapeOpt->Enable( true );
874 m_plotModeOpt->Enable( false );
876 m_plotMirrorOpt->Enable( false );
877 m_plotMirrorOpt->SetValue( false );
878 m_useAuxOriginCheckBox->Enable( true );
879 m_defaultPenSize.Enable( false );
880 m_scaleOpt->Enable( false );
881 m_scaleOpt->SetSelection( 1 );
882 m_fineAdjustXCtrl->Enable( false );
883 m_fineAdjustYCtrl->Enable( false );
885 m_plotPSNegativeOpt->Enable( false );
886 m_plotPSNegativeOpt->SetValue( false );
887 m_forcePSA4OutputOpt->Enable( false );
888 m_forcePSA4OutputOpt->SetValue( false );
889
896
897 OnChangeDXFPlotMode( event );
898 break;
899
900 case PLOT_FORMAT::UNDEFINED:
901 break;
902 }
903
904 /* Update the interlock between scale and frame reference
905 * (scaling would mess up the frame border...) */
906 OnSetScaleOpt( event );
907
908 Layout();
909 m_MainSizer->SetSizeHints( this );
910}
911
912
913// A helper function to "clip" aValue between aMin and aMax and write result in * aResult
914// return false if clipped, true if aValue is just copied into * aResult
915static bool setDouble( double* aResult, double aValue, double aMin, double aMax )
916{
917 if( aValue < aMin )
918 {
919 *aResult = aMin;
920 return false;
921 }
922 else if( aValue > aMax )
923 {
924 *aResult = aMax;
925 return false;
926 }
927
928 *aResult = aValue;
929 return true;
930}
931
932
933static bool setInt( int* aResult, int aValue, int aMin, int aMax )
934{
935 if( aValue < aMin )
936 {
937 *aResult = aMin;
938 return false;
939 }
940 else if( aValue > aMax )
941 {
942 *aResult = aMax;
943 return false;
944 }
945
946 *aResult = aValue;
947 return true;
948}
949
950
952{
953 REPORTER& reporter = m_messagesPanel->Reporter();
954 PCB_PLOT_PARAMS tempOptions;
955
956 tempOptions.SetSubtractMaskFromSilk( m_subtractMaskFromSilk->GetValue() );
957 tempOptions.SetPlotFrameRef( m_plotSheetRef->GetValue() );
958 tempOptions.SetSketchPadsOnFabLayers( m_sketchPadsOnFabLayers->GetValue() );
959 tempOptions.SetPlotPadNumbers( m_plotPadNumbers->GetValue() );
960 tempOptions.SetHideDNPFPsOnFabLayers( m_plotDNP->GetValue()
961 && m_hideDNP->GetValue() );
962 tempOptions.SetSketchDNPFPsOnFabLayers( m_plotDNP->GetValue()
963 && m_crossoutDNP->GetValue() );
964 tempOptions.SetCrossoutDNPFPsOnFabLayers( m_plotDNP->GetValue()
965 && m_crossoutDNP->GetValue() );
966 tempOptions.SetUseAuxOrigin( m_useAuxOriginCheckBox->GetValue() );
967 tempOptions.SetPlotInvisibleText( m_plotInvisibleText->GetValue() );
968 tempOptions.SetScaleSelection( m_scaleOpt->GetSelection() );
969
970 int sel = m_drillShapeOpt->GetSelection();
971 tempOptions.SetDrillMarksType( static_cast<DRILL_MARKS>( sel ) );
972
973 tempOptions.SetMirror( m_plotMirrorOpt->GetValue() );
974 tempOptions.SetPlotMode( m_plotModeOpt->GetSelection() == 1 ? SKETCH : FILLED );
975 tempOptions.SetDXFPlotPolygonMode( m_DXF_plotModeOpt->GetValue() );
976
977 sel = m_DXF_plotUnits->GetSelection();
978 tempOptions.SetDXFPlotUnits( sel == 0 ? DXF_UNITS::INCHES : DXF_UNITS::MILLIMETERS );
979
980 if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() ) // Currently, only DXF supports this option
981 tempOptions.SetTextMode( PLOT_TEXT_MODE::DEFAULT );
982 else
983 tempOptions.SetTextMode( m_DXF_plotTextStrokeFontOpt->GetValue() ? PLOT_TEXT_MODE::DEFAULT :
984 PLOT_TEXT_MODE::NATIVE );
985
986 if( getPlotFormat() == PLOT_FORMAT::SVG )
987 {
988 tempOptions.SetBlackAndWhite( !!m_SVGColorChoice->GetSelection() );
989 }
990 else if( getPlotFormat() == PLOT_FORMAT::PDF )
991 {
992 tempOptions.SetBlackAndWhite( !!m_PDFColorChoice->GetSelection() );
993 tempOptions.m_PDFFrontFPPropertyPopups = m_frontFPPropertyPopups->GetValue();
994 tempOptions.m_PDFBackFPPropertyPopups = m_backFPPropertyPopups->GetValue();
995 tempOptions.m_PDFMetadata = m_pdfMetadata->GetValue();
996 }
997 else
998 {
999 tempOptions.SetBlackAndWhite( true );
1000 }
1001
1002 // Update settings from text fields. Rewrite values back to the fields,
1003 // since the values may have been constrained by the setters.
1004 wxString msg;
1005
1006 // read HPLG pen size (this param is stored in mils)
1007 // However, due to issues when converting this value from or to mm
1008 // that can slightly change the value, update this param only if it
1009 // is in use
1010 if( getPlotFormat() == PLOT_FORMAT::HPGL )
1011 {
1013 {
1015 msg.Printf( _( "HPGL pen size constrained." ) );
1016 reporter.Report( msg, RPT_SEVERITY_INFO );
1017 }
1018 }
1019 else // keep the last value (initial value if no HPGL plot made)
1020 {
1022 }
1023
1024 // X scale
1025 double tmpDouble;
1026 msg = m_fineAdjustXCtrl->GetValue();
1027 msg.ToDouble( &tmpDouble );
1028
1030 {
1031 msg.Printf( wxT( "%f" ), m_XScaleAdjust );
1032 m_fineAdjustXCtrl->SetValue( msg );
1033 msg.Printf( _( "X scale constrained." ) );
1034 reporter.Report( msg, RPT_SEVERITY_INFO );
1035 }
1036
1037 // Y scale
1038 msg = m_fineAdjustYCtrl->GetValue();
1039 msg.ToDouble( &tmpDouble );
1040
1042 {
1043 msg.Printf( wxT( "%f" ), m_YScaleAdjust );
1044 m_fineAdjustYCtrl->SetValue( msg );
1045 msg.Printf( _( "Y scale constrained." ) );
1046 reporter.Report( msg, RPT_SEVERITY_INFO );
1047 }
1048
1049 auto cfg = m_editFrame->GetPcbNewSettings();
1050
1052 cfg->m_Plot.fine_scale_y = m_YScaleAdjust;
1053
1054 cfg->m_Plot.check_zones_before_plotting = m_zoneFillCheck->GetValue();
1055
1056 // PS Width correction
1059 {
1061 msg.Printf( _( "Width correction constrained. The width correction value must be in the"
1062 " range of [%s; %s] for the current design rules." ),
1065 reporter.Report( msg, RPT_SEVERITY_WARNING );
1066 }
1067
1068 // Store m_PSWidthAdjust in mm in user config
1069 cfg->m_Plot.ps_fine_width_adjust = pcbIUScale.IUTomm( m_PSWidthAdjust );
1070
1071 tempOptions.SetFormat( getPlotFormat() );
1072
1073 tempOptions.SetDisableGerberMacros( m_disableApertMacros->GetValue() );
1074 tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
1075 tempOptions.SetUseGerberX2format( m_useGerberX2Format->GetValue() );
1076 tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
1077 tempOptions.SetCreateGerberJobFile( m_generateGerberJobFile->GetValue() );
1078
1079 tempOptions.SetGerberPrecision( m_coordFormatCtrl->GetSelection() == 0 ? 5 : 6 );
1080 tempOptions.SetSvgPrecision( m_svgPrecsision->GetValue() );
1081
1082 LSET selectedLayers;
1083
1084 for( unsigned i = 0; i < m_layerList.size(); i++ )
1085 {
1086 if( m_layerCheckListBox->IsChecked( i ) )
1087 selectedLayers.set( m_layerList[i] );
1088 }
1089
1090 // Get a list of copper layers that aren't being used by inverting enabled layers.
1091 LSET disabledCopperLayers = LSET::AllCuMask() & ~m_editFrame->GetBoard()->GetEnabledLayers();
1092
1093 LSET plotOnAllLayers;
1094
1095 // Add selected layers from plot on all layers list in order set by user.
1096 wxArrayInt plotOnAllLayersSelections;
1097
1098 m_plotAllLayersList->GetCheckedItems( plotOnAllLayersSelections );
1099
1100 size_t count = plotOnAllLayersSelections.GetCount();
1101
1102 for( size_t i = 0; i < count; i++ )
1103 {
1104 int index = plotOnAllLayersSelections.Item( i );
1105 wxClientData* tmp = m_plotAllLayersList->GetClientObject( index );
1106 PCB_LAYER_ID_CLIENT_DATA* layerId = dynamic_cast<PCB_LAYER_ID_CLIENT_DATA*>( tmp );
1107
1108 wxCHECK2( layerId, continue );
1109
1110 plotOnAllLayers.set( layerId->Layer() );
1111 }
1112
1113 tempOptions.SetPlotOnAllLayersSelection( plotOnAllLayers );
1114
1115 // Enable all of the disabled copper layers.
1116 // If someone enables more copper layers they will be selected by default.
1117 selectedLayers = selectedLayers | disabledCopperLayers;
1118 tempOptions.SetLayerSelection( selectedLayers );
1119
1120 tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() );
1121 tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() );
1122
1123 // Set output directory and replace backslashes with forward ones
1124 wxString dirStr;
1125 dirStr = m_outputDirectoryName->GetValue();
1126 dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
1127 tempOptions.SetOutputDirectory( dirStr );
1129
1130 if( !m_plotOpts.IsSameAs( tempOptions ) )
1131 {
1132 m_editFrame->SetPlotSettings( tempOptions );
1134 m_plotOpts = tempOptions;
1135 }
1136}
1137
1138
1139void DIALOG_PLOT::OnGerberX2Checked( wxCommandEvent& event )
1140{
1141 // Currently: do nothing
1142}
1143
1144
1146{
1147 m_job->m_mirror = m_plotMirrorOpt->GetValue();
1149 m_job->m_hideDNPFPsOnFabLayers = m_plotDNP->GetValue() && m_hideDNP->GetValue();
1150 m_job->m_sketchDNPFPsOnFabLayers = m_plotDNP->GetValue() && m_crossoutDNP->GetValue();
1151 m_job->m_crossoutDNPFPsOnFabLayers = m_plotDNP->GetValue() && m_crossoutDNP->GetValue();
1152 //m_job->m_plotInvisibleText = m_plotInvisibleText->GetValue();
1153 m_job->m_drillShapeOption = static_cast<int>( m_drillShapeOpt->GetSelection() );
1154}
1155
1156
1157void DIALOG_PLOT::Plot( wxCommandEvent& event )
1158{
1159 if( m_job )
1160 {
1162 }
1163 else
1164 {
1165 BOARD* board = m_editFrame->GetBoard();
1166
1168
1171
1173
1175
1176 // If no layer selected, we have nothing plotted.
1177 // Prompt user if it happens because he could think there is a bug in Pcbnew.
1178 if( !m_plotOpts.GetLayerSelection().any() )
1179 {
1180 DisplayError( this, _( "No layer selected, Nothing to plot" ) );
1181 return;
1182 }
1183
1184 // Create output directory if it does not exist (also transform it in absolute form).
1185 // Bail if it fails.
1186
1187 std::function<bool( wxString* )> textResolver =
1188 [&]( wxString* token ) -> bool
1189 {
1190 // Handles board->GetTitleBlock() *and* board->GetProject()
1191 return m_editFrame->GetBoard()->ResolveTextVar( token, 0 );
1192 };
1193
1194 wxString path = m_plotOpts.GetOutputDirectory();
1195 path = ExpandTextVars( path, &textResolver );
1197
1198 wxFileName outputDir = wxFileName::DirName( path );
1199 wxString boardFilename = m_editFrame->GetBoard()->GetFileName();
1200 REPORTER& reporter = m_messagesPanel->Reporter();
1201
1202 if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
1203 {
1204 wxString msg;
1205 msg.Printf( _( "Could not write plot files to folder '%s'." ), outputDir.GetPath() );
1206 DisplayError( this, msg );
1207 return;
1208 }
1209
1210 if( m_zoneFillCheck->GetValue() )
1211 m_editFrame->GetToolManager()->GetTool<ZONE_FILLER_TOOL>()->CheckAllZones( this );
1212
1213 m_plotOpts.SetAutoScale( false );
1214
1215 switch( m_plotOpts.GetScaleSelection() )
1216 {
1217 default: m_plotOpts.SetScale( 1 ); break;
1218 case 0: m_plotOpts.SetAutoScale( true ); break;
1219 case 2: m_plotOpts.SetScale( 1.5 ); break;
1220 case 3: m_plotOpts.SetScale( 2 ); break;
1221 case 4: m_plotOpts.SetScale( 3 ); break;
1222 }
1223
1224 /* If the scale factor edit controls are disabled or the scale value
1225 * is 0, don't adjust the base scale factor. This fixes a bug when
1226 * the default scale adjust is initialized to 0 and saved in program
1227 * settings resulting in a divide by zero fault.
1228 */
1229 if( getPlotFormat() == PLOT_FORMAT::POST )
1230 {
1231 if( m_XScaleAdjust != 0.0 )
1233
1234 if( m_YScaleAdjust != 0.0 )
1236
1238 }
1239
1240 wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
1241
1242 // Test for a reasonable scale value
1243 // XXX could this actually happen? isn't it constrained in the apply function?
1245 DisplayInfoMessage( this, _( "Warning: Scale option set to a very small value" ) );
1246
1248 DisplayInfoMessage( this, _( "Warning: Scale option set to a very large value" ) );
1249
1250 GERBER_JOBFILE_WRITER jobfile_writer( board, &reporter );
1251
1252 // Save the current plot options in the board
1254
1255 wxBusyCursor dummy;
1256
1258 {
1259 LSEQ plotSequence;
1260
1261 // Base layer always gets plotted first.
1262 plotSequence.push_back( layer );
1263
1264 // Add selected layers from plot on all layers list in order set by user.
1265 wxArrayInt plotOnAllLayers;
1266
1267 if( m_plotAllLayersList->GetCheckedItems( plotOnAllLayers ) )
1268 {
1269 size_t count = plotOnAllLayers.GetCount();
1270
1271 for( size_t i = 0; i < count; i++ )
1272 {
1273 int index = plotOnAllLayers.Item( i );
1274 PCB_LAYER_ID client_layer = getLayerClientData( m_plotAllLayersList, index )->Layer();
1275
1276 // Don't plot the same layer more than once;
1277 if( find( plotSequence.begin(), plotSequence.end(), client_layer ) != plotSequence.end() )
1278 continue;
1279
1280 plotSequence.push_back( client_layer );
1281 }
1282 }
1283
1284 wxString layerName = board->GetLayerName( layer );
1285 //@todo allow controlling the sheet name and path that will be displayed in the title block
1286 // Leave blank for now
1287 wxString sheetName;
1288 wxString sheetPath;
1289
1290 // All copper layers that are disabled are actually selected
1291 // This is due to wonkyness in automatically selecting copper layers
1292 // for plotting when adding more than two layers to a board.
1293 // If plot options become accessible to the layers setup dialog
1294 // please move this functionality there!
1295 // This skips a copper layer if it is actually disabled on the board.
1296 if( ( LSET::AllCuMask() & ~board->GetEnabledLayers() )[layer] )
1297 continue;
1298
1299 // Pick the basename from the board file
1300 wxFileName fn( boardFilename );
1301
1302 // Use Gerber Extensions based on layer number
1303 // (See http://en.wikipedia.org/wiki/Gerber_File)
1304 if( m_plotOpts.GetFormat() == PLOT_FORMAT::GERBER && m_useGerberExtensions->GetValue() )
1305 file_ext = GetGerberProtelExtension( layer );
1306
1307 BuildPlotFileName( &fn, outputDir.GetPath(), layerName, file_ext );
1308 wxString fullname = fn.GetFullName();
1309 jobfile_writer.AddGbrFile( layer, fullname );
1310
1311 LOCALE_IO toggle;
1312
1313 PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, layerName, fn.GetFullPath(),
1314 sheetName, sheetPath );
1315
1316 // Print diags in messages box:
1317 wxString msg;
1318
1319 if( plotter )
1320 {
1321 plotter->SetTitle( ExpandTextVars( board->GetTitleBlock().GetTitle(), &textResolver ) );
1322
1324 {
1325 msg = wxS( "AUTHOR" );
1326
1327 if( board->ResolveTextVar( &msg, 0 ) )
1328 plotter->SetAuthor( msg );
1329
1330 msg = wxS( "SUBJECT" );
1331
1332 if( board->ResolveTextVar( &msg, 0 ) )
1333 plotter->SetSubject( msg );
1334 }
1335
1336 PlotBoardLayers( board, plotter, plotSequence, m_plotOpts );
1337 PlotInteractiveLayer( board, plotter, m_plotOpts );
1338 plotter->EndPlot();
1339 delete plotter->RenderSettings();
1340 delete plotter;
1341
1342 msg.Printf( _( "Plotted to '%s'." ), fn.GetFullPath() );
1343 reporter.Report( msg, RPT_SEVERITY_ACTION );
1344 }
1345 else
1346 {
1347 msg.Printf( _( "Failed to create file '%s'." ), fn.GetFullPath() );
1348 reporter.Report( msg, RPT_SEVERITY_ERROR );
1349 }
1350
1351 wxSafeYield(); // displays report message.
1352 }
1353
1354 if( m_plotOpts.GetFormat() == PLOT_FORMAT::GERBER && m_plotOpts.GetCreateGerberJobFile() )
1355 {
1356 // Pick the basename from the board file
1357 wxFileName fn( boardFilename );
1358
1359 // Build gerber job file from basename
1360 BuildPlotFileName( &fn, outputDir.GetPath(), wxT( "job" ),
1362 jobfile_writer.CreateJobFile( fn.GetFullPath() );
1363 }
1364
1365 reporter.ReportTail( _( "Done." ), RPT_SEVERITY_INFO );
1366 }
1367}
1368
1369
1370void DIALOG_PLOT::onRunDRC( wxCommandEvent& event )
1371{
1372 PCB_EDIT_FRAME* parent = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
1373
1374 if( parent )
1375 {
1376 DRC_TOOL* drcTool = parent->GetToolManager()->GetTool<DRC_TOOL>();
1377
1378 // First close an existing dialog if open
1379 // (low probability, but can happen)
1380 drcTool->DestroyDRCDialog();
1381
1382 // Open a new drc dialog, with the right parent frame, and in Modal Mode
1383 drcTool->ShowDRCDialog( this );
1384
1385 // Update DRC warnings on return to this dialog
1386 reInitDialog();
1387 }
1388}
1389
1390
1391void DIALOG_PLOT::onOpenOutputDirectory( wxCommandEvent& event )
1392{
1393 std::function<bool( wxString* )> textResolver = [&]( wxString* token ) -> bool
1394 {
1395 return m_editFrame->GetBoard()->ResolveTextVar( token, 0 );
1396 };
1397
1398 wxString path = m_outputDirectoryName->GetValue();
1399 path = ExpandTextVars( path, &textResolver );
1401 path = Prj().AbsolutePath( path );
1402
1403 if( !wxDirExists( path ) )
1404 {
1405 DisplayError( this, wxString::Format( _( "Directory '%s' does not exist." ), path ) );
1406 return;
1407 }
1408
1409 wxLaunchDefaultApplication( path );
1410}
1411
1412
1413void DIALOG_PLOT::onBoardSetup( wxHyperlinkEvent& aEvent )
1414{
1415 PCB_EDIT_FRAME* parent = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
1416
1417 if( parent )
1418 {
1419 parent->ShowBoardSetupDialog( _( "Solder Mask/Paste" ) );
1420
1421 // Update warnings on return to this dialog
1422 reInitDialog();
1423 }
1424}
1425
1426
1427void DIALOG_PLOT::onPlotAllListMoveUp( wxCommandEvent& aEvent )
1428{
1429 if( m_plotAllLayersList->CanMoveCurrentUp() )
1430 m_plotAllLayersList->MoveCurrentUp();
1431}
1432
1433
1434void DIALOG_PLOT::onPlotAllListMoveDown( wxCommandEvent& aEvent )
1435{
1436 if( m_plotAllLayersList->CanMoveCurrentDown() )
1437 m_plotAllLayersList->MoveCurrentDown();
1438}
1439
1440
1441void DIALOG_PLOT::onDNPCheckbox( wxCommandEvent& aEvent )
1442{
1443 m_hideDNP->Enable( aEvent.IsChecked() );
1444 m_crossoutDNP->Enable( aEvent.IsChecked() );
1445}
1446
1447
1448void DIALOG_PLOT::onSketchPads( wxCommandEvent& aEvent )
1449{
1450 m_plotPadNumbers->Enable( aEvent.IsChecked() );
1451}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
constexpr EDA_IU_SCALE unityScale
Definition: base_units.h:111
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:189
BASE_SET & set(size_t pos)
Definition: base_set.h:115
Container for design settings for a BOARD object.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:290
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:775
bool ResolveTextVar(wxString *token, int aDepth) const
Definition: board.cpp:433
const MARKERS & Markers() const
Definition: board.h:339
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:695
const wxString & GetFileName() const
Definition: board.h:327
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:579
PROJECT * GetProject() const
Definition: board.h:491
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:892
Class DIALOG_PLOT_BASE.
wxCheckBox * m_frontFPPropertyPopups
wxStaticText * m_DRCExclusionsWarning
wxCheckBox * m_backFPPropertyPopups
wxTextCtrl * m_fineAdjustXCtrl
wxBoxSizer * bmiddleSizer
wxStaticBoxSizer * m_PDFOptionsSizer
wxCheckBox * m_disableApertMacros
wxChoice * m_scaleOpt
wxChoice * m_coordFormatCtrl
wxCheckBox * m_DXF_plotModeOpt
wxChoice * m_SVGColorChoice
wxStaticText * m_staticTextPlotFmt
STD_BITMAP_BUTTON * m_browseButton
wxTextCtrl * m_outputDirectoryName
wxSpinCtrl * m_svgPrecsision
wxTextCtrl * m_fineAdjustYCtrl
wxCheckBox * m_plotPadNumbers
wxStaticBoxSizer * m_HPGLOptionsSizer
wxCheckBox * m_useAuxOriginCheckBox
wxStaticBoxSizer * m_PSOptionsSizer
STD_BITMAP_BUTTON * m_openDirButton
wxCheckBox * m_plotPSNegativeOpt
wxCheckBox * m_DXF_plotTextStrokeFontOpt
wxChoice * m_plotModeOpt
wxCheckBox * m_useGerberExtensions
wxCheckBox * m_plotSheetRef
wxBoxSizer * m_SizerSolderMaskAlert
wxCheckBox * m_generateGerberJobFile
wxRadioButton * m_crossoutDNP
wxButton * m_sdbSizer1Apply
wxCheckBox * m_useGerberX2Format
wxCheckListBox * m_layerCheckListBox
wxCheckBox * m_plotMirrorOpt
wxStaticBoxSizer * m_svgOptionsSizer
wxCheckBox * m_forcePSA4OutputOpt
wxCheckBox * m_useGerberNetAttributes
wxCheckBox * m_sketchPadsOnFabLayers
wxCheckBox * m_subtractMaskFromSilk
wxCheckBox * m_plotDNP
wxBoxSizer * m_PlotOptionsSizer
wxChoice * m_DXF_plotUnits
wxStaticBoxSizer * m_SizerDXF_options
wxCheckBox * m_plotInvisibleText
wxCheckBox * m_pdfMetadata
wxChoice * m_drillShapeOpt
wxRadioButton * m_hideDNP
wxCheckBox * m_zoneFillCheck
wxStaticBoxSizer * m_GerberOptionsSizer
WX_HTML_REPORT_PANEL * m_messagesPanel
wxChoice * m_PDFColorChoice
wxChoice * m_plotFormatOpt
wxBoxSizer * m_MainSizer
A dialog to set the plot options and create plot files in various formats.
Definition: dialog_plot.h:41
static LSET s_lastAllLayersSet
Definition: dialog_plot.h:116
DIALOG_PLOT(PCB_EDIT_FRAME *aEditFrame)
Definition: dialog_plot.cpp:90
void reInitDialog()
void OnRightClickLayers(wxMouseEvent &event)
static LSEQ s_lastAllLayersOrder
The plot on all layers ordering the last time the dialog was opened.
Definition: dialog_plot.h:119
JOB_EXPORT_PCB_PLOT * m_job
Definition: dialog_plot.h:112
PCB_PLOT_PARAMS m_plotOpts
Definition: dialog_plot.h:105
STD_BITMAP_BUTTON * m_bpMoveUp
Definition: dialog_plot.h:109
void onPlotAllListMoveUp(wxCommandEvent &aEvent)
void OnChangeDXFPlotMode(wxCommandEvent &event) override
int m_widthAdjustMinValue
Definition: dialog_plot.h:97
UNIT_BINDER m_trackWidthCorrection
Definition: dialog_plot.h:101
void onBoardSetup(wxHyperlinkEvent &aEvent) override
void OnRightClickAllLayers(wxMouseEvent &event)
void onSketchPads(wxCommandEvent &event) override
void Plot(wxCommandEvent &event) override
void applyPlotSettings()
int m_PSWidthAdjust
Definition: dialog_plot.h:93
wxString m_DRCWarningTemplate
Definition: dialog_plot.h:103
void setPlotModeChoiceSelection(OUTLINE_MODE aPlotMode)
Definition: dialog_plot.h:79
void OnOutputDirectoryBrowseClicked(wxCommandEvent &event) override
wxRearrangeList * m_plotAllLayersList
Definition: dialog_plot.h:107
void onPlotAllListMoveDown(wxCommandEvent &aEvent)
void updateJobFromDialog()
void onRunDRC(wxCommandEvent &event) override
void arrangeAllLayersList(const LSEQ &aSeq)
double m_YScaleAdjust
Definition: dialog_plot.h:91
void onOpenOutputDirectory(wxCommandEvent &event) override
void OnSetScaleOpt(wxCommandEvent &event) override
PCB_EDIT_FRAME * m_editFrame
Definition: dialog_plot.h:87
virtual ~DIALOG_PLOT()
STD_BITMAP_BUTTON * m_bpMoveDown
Definition: dialog_plot.h:110
void CreateDrillFile(wxCommandEvent &event) override
void onDNPCheckbox(wxCommandEvent &event) override
UNIT_BINDER m_defaultPenSize
Definition: dialog_plot.h:100
double m_XScaleAdjust
Definition: dialog_plot.h:89
PLOT_FORMAT getPlotFormat()
static LSET s_lastLayerSet
The plot layer set that last time the dialog was opened.
Definition: dialog_plot.h:115
int m_widthAdjustMaxValue
Definition: dialog_plot.h:98
void OnGerberX2Checked(wxCommandEvent &event) override
void init_Dialog()
void SetPlotFormat(wxCommandEvent &event) override
LSEQ m_layerList
Definition: dialog_plot.h:88
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int ShowModal() override
void ShowDRCDialog(wxWindow *aParent)
Opens the DRC dialog.
Definition: drc_tool.cpp:71
void DestroyDRCDialog()
Close and free the DRC dialog.
Definition: drc_tool.cpp:122
GERBER_JOBFILE_WRITER is a class used to create Gerber job file a Gerber job file stores info to make...
bool CreateJobFile(const wxString &aFullFilename)
Creates a Gerber job file.
void AddGbrFile(PCB_LAYER_ID aLayer, wxString &aFilename)
add a gerber file name and type in job file list
bool m_mirror
Common Options.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:49
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: lseq.h:47
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:36
LSEQ UIOrder() const
Returns the copper, technical and user layers in the order shown in layer widget.
Definition: lset.cpp:799
LSEQ SeqStackupForPlotting() const
Return the sequence that is typical for a bottom-to-top stack-up.
Definition: lset.cpp:500
static LSET AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:734
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:676
DIALOG_PLOT m_Plot
virtual const PCB_PLOT_PARAMS & GetPlotSettings() const
Return the PCB_PLOT_PARAMS for the BOARD owned by this frame.
PCBNEW_SETTINGS * GetPcbNewSettings() const
BOARD * GetBoard() const
virtual void SetPlotSettings(const PCB_PLOT_PARAMS &aSettings)
The main frame for Pcbnew.
void ShowBoardSetupDialog(const wxString &aInitialPage=wxEmptyString)
void OnModify() override
Must be called after a board change to set the modified flag.
A helper wxWidgets control client data object to store layer IDs.
Definition: dialog_plot.cpp:66
PCB_LAYER_ID Layer() const
Definition: dialog_plot.cpp:77
void SetData(PCB_LAYER_ID aId)
Definition: dialog_plot.cpp:76
PCB_LAYER_ID_CLIENT_DATA(PCB_LAYER_ID aId)
Definition: dialog_plot.cpp:72
Parameters and options when plotting/printing a board.
bool GetNegative() const
PLOT_FORMAT GetFormat() const
void SetDrillMarksType(DRILL_MARKS aVal)
bool GetUseAuxOrigin() const
bool GetHideDNPFPsOnFabLayers() const
void SetLayerSelection(LSET aSelection)
void SetOutputDirectory(const wxString &aDir)
void SetSketchPadsOnFabLayers(bool aFlag)
void SetUseGerberX2format(bool aUse)
bool GetMirror() const
DXF_UNITS GetDXFPlotUnits() const
bool GetPlotInvisibleText() const
void SetA4Output(int aForce)
PLOT_TEXT_MODE GetTextMode() const
bool GetCrossoutDNPFPsOnFabLayers() const
bool GetSketchDNPFPsOnFabLayers() const
void SetDXFPlotPolygonMode(bool aFlag)
void SetAutoScale(bool aFlag)
double GetHPGLPenDiameter() const
unsigned GetSvgPrecision() const
void SetPlotFrameRef(bool aFlag)
void SetSketchDNPFPsOnFabLayers(bool aFlag)
bool m_PDFMetadata
Generate PDF metadata for SUBJECT and AUTHOR.
unsigned GetBlackAndWhite() const
double GetScale() const
bool GetCreateGerberJobFile() const
void SetPlotPadNumbers(bool aFlag)
bool GetDXFPlotPolygonMode() const
void SetSketchPadLineWidth(int aWidth)
LSET GetLayerSelection() const
wxString GetOutputDirectory() const
int GetScaleSelection() const
void SetPlotOnAllLayersSelection(LSET aSelection)
LSET GetPlotOnAllLayersSelection() const
bool SetHPGLPenDiameter(double aValue)
bool m_PDFFrontFPPropertyPopups
Generate PDF property popup menus for footprints.
void SetScale(double aVal)
void SetDisableGerberMacros(bool aDisable)
void SetScaleSelection(int aSelection)
void SetFineScaleAdjustX(double aVal)
void SetMirror(bool aFlag)
void SetBlackAndWhite(bool blackAndWhite)
void SetGerberPrecision(int aPrecision)
void SetSubtractMaskFromSilk(bool aSubtract)
bool GetSketchPadsOnFabLayers() const
void SetHideDNPFPsOnFabLayers(bool aFlag)
bool GetSubtractMaskFromSilk() const
int GetGerberPrecision() const
void SetUseGerberProtelExtensions(bool aUse)
bool GetPlotPadNumbers() const
bool GetA4Output() const
DRILL_MARKS GetDrillMarksType() const
bool GetUseGerberX2format() const
void SetDXFPlotUnits(DXF_UNITS aUnit)
void SetColorSettings(COLOR_SETTINGS *aSettings)
bool IsSameAs(const PCB_PLOT_PARAMS &aPcbPlotParams) const
Compare current settings to aPcbPlotParams, including not saved parameters in brd file.
void SetIncludeGerberNetlistInfo(bool aUse)
void SetPlotInvisibleText(bool aFlag)
void SetCreateGerberJobFile(bool aCreate)
bool GetIncludeGerberNetlistInfo() const
void SetNegative(bool aFlag)
void SetPlotMode(OUTLINE_MODE aPlotMode)
void SetUseAuxOrigin(bool aAux)
bool m_PDFBackFPPropertyPopups
on front and/or back of board
void SetTextMode(PLOT_TEXT_MODE aVal)
bool GetUseGerberProtelExtensions() const
void SetSvgPrecision(unsigned aPrecision)
bool GetPlotFrameRef() const
void SetCrossoutDNPFPsOnFabLayers(bool aFlag)
void SetFormat(PLOT_FORMAT aFormat)
bool GetDisableGerberMacros() const
void SetFineScaleAdjustY(double aVal)
OUTLINE_MODE GetPlotMode() const
void SetWidthAdjust(int aVal)
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
Base plotter engine class.
Definition: plotter.h:105
virtual void SetAuthor(const wxString &aAuthor)
Definition: plotter.h:156
virtual void SetTitle(const wxString &aTitle)
Definition: plotter.h:155
virtual bool EndPlot()=0
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:136
virtual void SetSubject(const wxString &aSubject)
Definition: plotter.h:157
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:72
wxString m_PcbLastPath[LAST_PATH_SIZE]
MRU path storage.
Definition: project_file.h:162
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:200
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Definition: project.cpp:359
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:72
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the end of the list, for objects that support report ordering.
Definition: reporter.h:100
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieves a color settings object that applications can read colors from.
A bitmap button widget that behaves like a standard dialog button except with an icon.
void SetBitmap(const wxBitmapBundle &aBmp)
const wxString & GetTitle() const
Definition: title_block.h:63
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aValue in internal units into a united string.
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void SetFileName(const wxString &aReportFileName)
Handle actions specific to filling copper zones.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:348
bool EnsureFileDirectoryExists(wxFileName *aTargetFullFileName, const wxString &aBaseFilename, REPORTER *aReporter)
Make aTargetFullFileName absolute and create the path of this file if it doesn't yet exist.
Definition: common.cpp:369
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
Definition: common.cpp:59
wxString GetDefaultPlotExtension(PLOT_FORMAT aFormat)
Returns the default plot extension for a format.
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:222
This file is part of the common library.
#define ID_STACKUP_ORDER
static bool setDouble(double *aResult, double aValue, double aMin, double aMax)
static bool setInt(int *aResult, int aValue, int aMin, int aMax)
PCB_LAYER_ID_CLIENT_DATA * getLayerClientData(const wxRearrangeList *aList, int aIdx)
Definition: dialog_plot.cpp:84
#define ID_SELECT_ALL_LAYERS
#define ID_DESELECT_COPPER_LAYERS
#define ID_DESELECT_ALL_LAYERS
#define ID_LAYER_FAB
#define ID_SELECT_COPPER_LAYERS
#define DLG_WINDOW_NAME
Definition: dialog_plot.h:30
#define _(s)
Classes used to generate a Gerber job file in JSON.
static const bool FILLED
Definition: gr_basic.cpp:30
static const std::string GerberJobFileExtension
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:531
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ F_CrtYd
Definition: layer_ids.h:116
@ F_Fab
Definition: layer_ids.h:119
@ B_CrtYd
Definition: layer_ids.h:115
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API wxString StringFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Returns the string from aValue according to aUnits (inch, mm ...) for display.
Definition: eda_units.cpp:300
KICOMMON_API wxSize GetTextSize(const wxString &aSingleLine, wxWindow *aWindow)
Return the size of aSingleLine of text when it is rendered in aWindow using whatever font is currentl...
Definition: ui_common.cpp:77
@ SKETCH
Definition: outline_mode.h:26
const wxString GetGerberProtelExtension(int aLayer)
Definition: pcbplot.cpp:43
void BuildPlotFileName(wxFileName *aFilename, const wxString &aOutputDir, const wxString &aSuffix, const wxString &aExtension)
Complete a plot filename.
Definition: pcbplot.cpp:379
void PlotBoardLayers(BOARD *aBoard, PLOTTER *aPlotter, const LSEQ &aLayerSequence, const PCB_PLOT_PARAMS &aPlotOptions)
Plot a sequence of board layer IDs.
void PlotInteractiveLayer(BOARD *aBoard, PLOTTER *aPlotter, const PCB_PLOT_PARAMS &aPlotOpt)
Plot interactive items (hypertext links, properties, etc.).
#define PLOT_MIN_SCALE
Definition: pcbplot.h:57
PLOTTER * StartPlotBoard(BOARD *aBoard, const PCB_PLOT_PARAMS *aPlotOpts, int aLayer, const wxString &aLayerName, const wxString &aFullFileName, const wxString &aSheetName, const wxString &aSheetPath)
Open a new plotfile using the options (and especially the format) specified in the options and prepar...
#define PLOT_MAX_SCALE
Definition: pcbplot.h:58
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
DRILL_MARKS
Plots and prints can show holes in pads and vias 3 options are available:
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:65
@ LAST_PATH_PLOT
Definition: project_file.h:58
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_INFO
@ RPT_SEVERITY_ACTION
std::vector< FAB_LAYER_COLOR > dummy
constexpr double IUTomm(int iu) const
Definition: base_units.h:86
const double IU_PER_MM
Definition: base_units.h:76
const double IU_PER_MILS
Definition: base_units.h:77
Definition of file extensions used in Kicad.