KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_print_pcbnew.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) 2010-2016 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * Copyright (C) 2018-2023 CERN
7 *
8 * @author Maciej Suminski <[email protected]>
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, see <https://www.gnu.org/licenses/>.
22 */
23
24#include <kiface_base.h>
25#include <pcbnew_settings.h>
26#include <pcbplot.h>
27#include <board.h>
28#include <tool/tool_manager.h>
29#include <tools/pcb_actions.h>
30#include <tools/pcb_control.h>
32#include <pcbnew_printout.h>
33#include <wx/checklst.h>
34
35
37{
38public:
41
42private:
43 enum
44 {
52 };
53
55 {
56 wxASSERT( dynamic_cast<PCBNEW_PRINTOUT_SETTINGS*>( m_settings ) );
57 return static_cast<PCBNEW_PRINTOUT_SETTINGS*>( m_settings );
58 }
59
60 bool TransferDataToWindow() override;
61
62 void createExtraOptions();
63 void createLeftPanel();
64
65 void onUseThemeClicked( wxCommandEvent& event );
66 void onPagePerLayerClicked( wxCommandEvent& event );
67 void onColorModeClicked( wxCommandEvent& event );
68 void onPopUpLayers( wxCommandEvent& event );
69
72
73 void saveSettings() override;
74
75 wxPrintout* createPrintout( const wxString& aTitle ) override
76 {
77 return new PCBNEW_PRINTOUT( m_parent->GetBoard(), *settings(),
78 m_parent->GetCanvas()->GetView(), aTitle );
79 }
80
82 LSEQ m_layerList; // List to hold CheckListBox layer numbers
83 wxMenu* m_popMenu;
84
85 wxCheckListBox* m_layerCheckListBox;
86 wxCheckBox* m_checkboxMirror;
90 wxCheckBox* m_checkAsItems;
91 wxCheckBox* m_checkBackground;
92 wxCheckBox* m_checkUseTheme;
93 wxChoice* m_colorTheme;
94};
95
96
98 DIALOG_PRINT_GENERIC( aParent, aSettings ),
99 m_parent( aParent )
100{
103
104 BOARD* board = m_parent->GetBoard();
105
106 // Create layer list
107 // Could devote a PlotOrder() function in place of UIOrder().
109
110 // Populate the check list box by all enabled layers names. They will be enabled later
111 // when the dlg settings are loaded (i.e. after DIALOG_PRINT_GENERIC::TransferDataToWindow()
112 // is called
113 for( PCB_LAYER_ID layer : m_layerList )
114 m_layerCheckListBox->Append( board->GetLayerName( layer ) );
115
116 m_infoText->SetFont( KIUI::GetSmallInfoFont( this ).Italic() );
117 m_infoText->SetLabel( _( "Right-click for layer selection commands." ) );
118 m_infoText->Show( true );
119
121
122 m_popMenu->Bind( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PRINT_PCBNEW::onPopUpLayers ),
124
125 m_outputMode->Bind( wxEVT_COMMAND_CHOICE_SELECTED, &DIALOG_PRINT_PCBNEW::onColorModeClicked, this );
126}
127
128
130{
131 m_popMenu->Unbind( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PRINT_PCBNEW::onPopUpLayers ),
133
134 m_outputMode->Unbind( wxEVT_COMMAND_CHOICE_SELECTED, &DIALOG_PRINT_PCBNEW::onColorModeClicked, this );
135}
136
137
139{
141 return false;
142
143 BOARD* board = m_parent->GetBoard();
144
145 // Enable layers from previous dlg settings
147 int choice_ly_id = 0;
148
149 for( PCB_LAYER_ID layer : m_layerList )
150 {
151 if( settings()->m_LayerSet.test( layer ) )
152 m_layerCheckListBox->Check( choice_ly_id );
153
154 choice_ly_id++;
155 }
156
157 m_checkAsItems->SetValue( settings()->m_AsItemCheckboxes );
158 m_checkboxMirror->SetValue( settings()->m_Mirror );
159 m_titleBlock->SetValue( settings()->m_titleBlock );
160
161 PCBNEW_SETTINGS* cfg = m_parent->GetPcbNewSettings();
162
163 m_checkBackground->SetValue( cfg->m_Printing.background );
164 m_checkUseTheme->SetValue( cfg->m_Printing.use_theme );
165
166 m_colorTheme->Clear();
167
168 int width = 0;
169 int height = 0;
170 int minwidth = width;
171
172 wxString target = cfg->m_Printing.use_theme ? cfg->m_Printing.color_theme : cfg->m_ColorTheme;
173
174 for( COLOR_SETTINGS* settings : m_parent->GetSettingsManager()->GetColorSettingsList() )
175 {
176 int pos = m_colorTheme->Append( settings->GetName(), static_cast<void*>( settings ) );
177
178 if( settings->GetFilename() == target )
179 m_colorTheme->SetSelection( pos );
180
181 m_colorTheme->GetTextExtent( settings->GetName(), &width, &height );
182 minwidth = std::max( minwidth, width );
183 }
184
185 m_colorTheme->SetMinSize( wxSize( minwidth + 50, -1 ) );
186
187 wxCommandEvent dummy;
189
190 // Options to plot pads and vias holes
191 m_drillMarksChoice->SetSelection( (int)settings()->m_DrillMarks );
192
193 // Print all layers one one page or separately
196
197 // Update the dialog layout when layers are added
198 GetSizer()->Fit( this );
199
200 return true;
201}
202
203
205{
206 wxGridBagSizer* optionsSizer = getOptionsSizer();
207 wxStaticBox* box = getOptionsBox();
208 int rows = optionsSizer->GetEffectiveRowsCount();
209
210 m_checkAsItems = new wxCheckBox( box, wxID_ANY, _( "Print according to objects tab of appearance manager" ) );
211 optionsSizer->Add( m_checkAsItems, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT|wxRIGHT|wxBOTTOM, 5 );
212
213 m_checkBackground = new wxCheckBox( box, wxID_ANY, _( "Print background color" ) );
214 optionsSizer->Add( m_checkBackground, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT|wxRIGHT|wxBOTTOM, 5 );
215
216 m_checkUseTheme = new wxCheckBox( box, wxID_ANY, _( "Use a different color theme for printing:" ) );
217 optionsSizer->Add( m_checkUseTheme, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT|wxRIGHT, 5 );
218
219 m_checkUseTheme->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &DIALOG_PRINT_PCBNEW::onUseThemeClicked, this );
220
221 wxArrayString choices;
222 m_colorTheme = new wxChoice( box, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices, 0 );
223 m_colorTheme->SetSelection( 0 );
224 m_colorTheme->SetMinSize( { 200, -1 } );
225 optionsSizer->Add( m_colorTheme, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT, 28 );
226
227 rows++;
228
229 // Drill marks option
230 auto drillMarksLabel = new wxStaticText( box, wxID_ANY, _( "Drill marks:" ) );
231 std::vector<wxString> drillMarkChoices = { _( "No drill mark" ),
232 _( "Small mark" ),
233 _( "Real drill" ) };
234 m_drillMarksChoice = new wxChoice( box, wxID_ANY, wxDefaultPosition, wxDefaultSize,
235 drillMarkChoices.size(), drillMarkChoices.data(), 0 );
236 m_drillMarksChoice->SetSelection( 0 );
237
238 optionsSizer->Add( drillMarksLabel, wxGBPosition( rows, 0 ), wxGBSpan( 1, 1 ),
239 wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
240 optionsSizer->Add( m_drillMarksChoice, wxGBPosition( rows++, 1 ), wxGBSpan( 1, 1 ),
241 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxBOTTOM, 5 );
242
243 // Print mirrored
244 m_checkboxMirror = new wxCheckBox( box, wxID_ANY, _( "Print mirrored" ) );
245
246 optionsSizer->Add( m_checkboxMirror, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ),
247 wxLEFT|wxRIGHT|wxBOTTOM, 5 );
248
249 // Pagination
250 m_checkboxPagePerLayer = new wxCheckBox( box, wxID_ANY, _( "Print one page per layer" ) );
251
252 m_checkboxPagePerLayer->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &DIALOG_PRINT_PCBNEW::onPagePerLayerClicked, this );
253
254 m_checkboxEdgesOnAllPages = new wxCheckBox( box, wxID_ANY, _( "Print board edges on all pages" ) );
255
256 optionsSizer->Add( m_checkboxPagePerLayer, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT|wxRIGHT, 5 );
257 optionsSizer->Add( m_checkboxEdgesOnAllPages, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT, 28 );
258}
259
260
262{
263 wxStaticBox* box = new wxStaticBox( this, wxID_ANY, _( "Include Layers" ) );
264 wxStaticBoxSizer* sbLayersSizer = new wxStaticBoxSizer( box, wxVERTICAL );
265
266 m_layerCheckListBox = new wxCheckListBox( sbLayersSizer->GetStaticBox(), wxID_ANY );
267 m_layerCheckListBox->SetMinSize( wxSize( 180, -1 ) );
268
269 sbLayersSizer->Add( m_layerCheckListBox, 1, wxEXPAND|wxBOTTOM|wxRIGHT, 5 );
270
271 getMainSizer()->Insert( 0, sbLayersSizer, 1, wxEXPAND | wxALL, 5 );
272
273 m_popMenu = new wxMenu();
274 m_popMenu->Append( new wxMenuItem( m_popMenu, ID_SELECT_FAB_LAYERS, _( "Select Fab Layers" ) ) );
275 m_popMenu->Append( new wxMenuItem( m_popMenu, ID_SELECT_COPPER_LAYERS, _( "Select all Copper Layers" ) ) );
276 m_popMenu->Append( new wxMenuItem( m_popMenu, ID_DESELECT_COPPER_LAYERS, _( "Deselect all Copper Layers" ) ) );
277 m_popMenu->Append( new wxMenuItem( m_popMenu, ID_SELECT_ALL_LAYERS, _( "Select all Layers" ) ) );
278 m_popMenu->Append( new wxMenuItem( m_popMenu, ID_DESELECT_ALL_LAYERS, _( "Deselect all Layers" ) ) );
279
280 this->Bind( wxEVT_RIGHT_DOWN,
281 [&]( wxMouseEvent& aEvent )
282 {
283 this->PopupMenu( m_popMenu, aEvent.GetPosition() );
284 } );
285
286 m_layerCheckListBox->Bind( wxEVT_RIGHT_DOWN,
287 [&]( wxMouseEvent& aEvent )
288 {
289 this->PopupMenu( m_popMenu, aEvent.GetPosition() );
290 } );
291}
292
293
294void DIALOG_PRINT_PCBNEW::onUseThemeClicked( wxCommandEvent& event )
295{
296 m_colorTheme->Enable( m_checkUseTheme->GetValue() );
297}
298
299
301{
302 if( m_checkboxPagePerLayer->GetValue() )
303 {
304 m_checkboxEdgesOnAllPages->Enable( true );
305 m_checkboxEdgesOnAllPages->SetValue( settings()->m_PrintEdgeCutsOnAllPages );
306 }
307 else
308 {
309 m_checkboxEdgesOnAllPages->Enable( false );
310 m_checkboxEdgesOnAllPages->SetValue( false );
311 }
312}
313
314
315void DIALOG_PRINT_PCBNEW::onColorModeClicked( wxCommandEvent& event )
316{
317 m_settings->m_blackWhite = m_outputMode->GetSelection();
318
319 m_checkBackground->Enable( !m_settings->m_blackWhite );
320 m_checkUseTheme->Enable( !m_settings->m_blackWhite );
321
322 if( PCBNEW_SETTINGS* cfg = m_parent->GetPcbNewSettings() )
323 m_colorTheme->Enable( !m_settings->m_blackWhite && cfg->m_Printing.use_theme );
324}
325
326
327// Select or deselect groups of layers in the layers list:
328void DIALOG_PRINT_PCBNEW::onPopUpLayers( wxCommandEvent& event )
329{
330 // Build a list of layers for usual fabrication: copper layers + tech layers without courtyard
331 LSET fab_layer_set = ( LSET::AllCuMask() | LSET::AllTechMask() ) & ~LSET( { B_CrtYd, F_CrtYd } );
332
333 switch( event.GetId() )
334 {
335 case ID_SELECT_FAB_LAYERS: // Select layers usually needed to build a board
336 for( unsigned i = 0; i < m_layerList.size(); i++ )
337 {
338 LSET layermask( { m_layerList[ i ] } );
339
340 if( ( layermask & fab_layer_set ).any() )
341 m_layerCheckListBox->Check( i, true );
342 else
343 m_layerCheckListBox->Check( i, false );
344 }
345
346 break;
347
349 for( unsigned i = 0; i < m_layerList.size(); i++ )
350 {
351 if( IsCopperLayer( m_layerList[i] ) )
352 m_layerCheckListBox->Check( i, true );
353 }
354
355 break;
356
358 for( unsigned i = 0; i < m_layerList.size(); i++ )
359 {
360 if( IsCopperLayer( m_layerList[i] ) )
361 m_layerCheckListBox->Check( i, false );
362 }
363
364 break;
365
367 for( unsigned i = 0; i < m_layerList.size(); i++ )
368 m_layerCheckListBox->Check( i, true );
369
370 break;
371
373 for( unsigned i = 0; i < m_layerList.size(); i++ )
374 m_layerCheckListBox->Check( i, false );
375
376 break;
377
378 default:
379 break;
380 }
381}
382
383
385{
386 settings()->m_LayerSet = LSET();
387 int& pageCount = settings()->m_pageCount;
388 pageCount = 0;
389
390 for( unsigned i = 0; i < m_layerList.size(); i++ )
391 {
392 if( m_layerCheckListBox->IsChecked( i ) )
393 {
394 ++pageCount;
396 }
397 }
398
399 // In Pcbnew force the EDGE layer to be printed or not with the other layers
401
402 // All layers on one page (only if there is at least one layer selected)
403 if( !m_checkboxPagePerLayer->GetValue() && pageCount > 0 )
404 pageCount = 1;
405
406 return pageCount;
407}
408
409
411{
413
415
416 settings()->m_DrillMarks = static_cast<DRILL_MARKS>( m_drillMarksChoice->GetSelection() );
417
418 if( m_checkboxPagePerLayer->GetValue() )
419 {
422 }
423 else
424 {
426 }
427
428 settings()->m_Mirror = m_checkboxMirror->GetValue();
429
430 PCBNEW_SETTINGS* cfg = m_parent->GetPcbNewSettings();
431
432 cfg->m_Printing.background = m_checkBackground->GetValue();
434 cfg->m_Printing.use_theme = m_checkUseTheme->GetValue();
435
436 int sel = m_colorTheme->GetSelection();
437 COLOR_SETTINGS* theme = nullptr;
438
439 if( sel >= 0 && sel < (int) m_colorTheme->GetCount() )
440 theme = static_cast<COLOR_SETTINGS*>( m_colorTheme->GetClientData( sel ) );
441
442 if( theme && m_checkUseTheme->IsChecked() )
443 {
444 cfg->m_Printing.color_theme = theme->GetFilename();
445 settings()->m_colorSettings = theme;
446 }
447 else
448 {
449 settings()->m_colorSettings = m_parent->GetColorSettings();
450 }
451
453
454 settings()->Save( cfg );
455}
456
457
458int PCB_CONTROL::Print( const TOOL_EVENT& aEvent )
459{
460 // Selection affects the origin item visibility
462
463 PCBNEW_PRINTOUT_SETTINGS settings( m_frame->GetPageSettings() );
464
465 // Load saved settings
466 PCBNEW_SETTINGS* cfg = static_cast<PCB_BASE_EDIT_FRAME*>( m_frame )->GetPcbNewSettings();
467 settings.Load( cfg );
468
470
472 dlg.ForcePrintBorder( false );
473
474 dlg.ShowModal();
475
476 return 0;
477}
478
479
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:220
wxString m_ColorTheme
Active color theme name.
BASE_SET & set(size_t pos)
Definition base_set.h:116
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition board.cpp:793
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition board.cpp:1034
Color settings are a bit different than most of the settings objects in that there can be more than o...
DIALOG_PRINT_GENERIC(EDA_DRAW_FRAME *aParent, PRINTOUT_SETTINGS *aSettings)
wxStaticBox * getOptionsBox()
bool TransferDataToWindow() override
void ForcePrintBorder(bool aValue)
Set 'print border and title block' to a requested value and hides the corresponding checkbox.
wxGridBagSizer * getOptionsSizer()
PRINTOUT_SETTINGS * m_settings
wxCheckBox * m_checkboxPagePerLayer
void onPopUpLayers(wxCommandEvent &event)
Update layerset basing on the selected layers.
wxPrintout * createPrintout(const wxString &aTitle) override
Create a printout with a requested title.
PCB_BASE_EDIT_FRAME * m_parent
DIALOG_PRINT_PCBNEW(PCB_BASE_EDIT_FRAME *aParent, PCBNEW_PRINTOUT_SETTINGS *aSettings)
wxCheckBox * m_checkboxEdgesOnAllPages
bool TransferDataToWindow() override
void onColorModeClicked(wxCommandEvent &event)
void onPagePerLayerClicked(wxCommandEvent &event)
wxCheckListBox * m_layerCheckListBox
void onUseThemeClicked(wxCommandEvent &event)
PCBNEW_PRINTOUT_SETTINGS * settings() const
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int ShowModal() override
wxString GetFilename() const
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:37
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition lset.cpp:604
LSEQ UIOrder() const
Return the copper, technical and user layers in the order shown in layer widget.
Definition lset.cpp:739
static const LSET & AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition lset.cpp:672
Common, abstract interface for edit frames.
PCB_BASE_FRAME * m_frame
int Print(const TOOL_EVENT &aEvent)
TOOL_MANAGER * m_toolMgr
Definition tool_base.h:220
Generic, UI-independent tool event.
Definition tool_event.h:167
A type-safe container of any type.
Definition ki_any.h:92
#define _(s)
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition layer_ids.h:675
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ F_CrtYd
Definition layer_ids.h:112
@ B_CrtYd
Definition layer_ids.h:111
KICOMMON_API wxFont GetSmallInfoFont(wxWindow *aWindow)
DRILL_MARKS
Plots and prints can show holes in pads and vias 3 options are available:
std::vector< FAB_LAYER_COLOR > dummy
bool background
Whether or not to print background color.
wxString color_theme
Color theme to use for printing.
bool use_theme
If false, display color theme will be used.
LSET m_LayerSet
Layers to print.
bool m_Mirror
Print mirrored.
enum PCBNEW_PRINTOUT_SETTINGS::PAGINATION_T m_Pagination
bool m_PrintEdgeCutsOnAllPages
Print board outline on each page.
enum DRILL_MARKS m_DrillMarks
bool m_AsItemCheckboxes
Honor checkboxes in the Items tab of the Layers Manager.
void Load(APP_SETTINGS_BASE *aConfig) override
void Save(APP_SETTINGS_BASE *aConfig) override
COLOR_SETTINGS * m_colorSettings
The color settings to be used for printing.
Definition printout.h:66
int m_pageCount
Number of pages to print.
Definition printout.h:61
bool m_background
Print background color.
Definition printout.h:62