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, 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#include <kiface_base.h>
29#include <pcbnew_settings.h>
30#include <pcbplot.h>
31#include <board.h>
32#include <tool/tool_manager.h>
33#include <tools/pcb_actions.h>
34#include <tools/pcb_control.h>
36#include <pcbnew_printout.h>
37#include <wx/checklst.h>
38
39
41{
42public:
45
46private:
47 enum
48 {
56 };
57
59 {
60 wxASSERT( dynamic_cast<PCBNEW_PRINTOUT_SETTINGS*>( m_settings ) );
61 return static_cast<PCBNEW_PRINTOUT_SETTINGS*>( m_settings );
62 }
63
64 bool TransferDataToWindow() override;
65
66 void createExtraOptions();
67 void createLeftPanel();
68
69 void onUseThemeClicked( wxCommandEvent& event );
70 void onPagePerLayerClicked( wxCommandEvent& event );
71 void onColorModeClicked( wxCommandEvent& event );
72 void onPopUpLayers( wxCommandEvent& event );
73
76
77 void saveSettings() override;
78
79 wxPrintout* createPrintout( const wxString& aTitle ) override
80 {
81 return new PCBNEW_PRINTOUT( m_parent->GetBoard(), *settings(),
82 m_parent->GetCanvas()->GetView(), aTitle );
83 }
84
86 LSEQ m_layerList; // List to hold CheckListBox layer numbers
87 wxMenu* m_popMenu;
88
89 wxCheckListBox* m_layerCheckListBox;
90 wxCheckBox* m_checkboxMirror;
94 wxCheckBox* m_checkAsItems;
95 wxCheckBox* m_checkBackground;
96 wxCheckBox* m_checkUseTheme;
97 wxChoice* m_colorTheme;
98};
99
100
102 DIALOG_PRINT_GENERIC( aParent, aSettings ),
103 m_parent( aParent )
104{
107
108 BOARD* board = m_parent->GetBoard();
109
110 // Create layer list
111 // Could devote a PlotOrder() function in place of UIOrder().
113
114 // Populate the check list box by all enabled layers names. They will be enabled later
115 // when the dlg settings are loaded (i.e. after DIALOG_PRINT_GENERIC::TransferDataToWindow()
116 // is called
117 for( PCB_LAYER_ID layer : m_layerList )
118 m_layerCheckListBox->Append( board->GetLayerName( layer ) );
119
120 m_infoText->SetFont( KIUI::GetSmallInfoFont( this ).Italic() );
121 m_infoText->SetLabel( _( "Right-click for layer selection commands." ) );
122 m_infoText->Show( true );
123
125
126 m_popMenu->Bind( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PRINT_PCBNEW::onPopUpLayers ),
128
129 m_outputMode->Bind( wxEVT_COMMAND_CHOICE_SELECTED, &DIALOG_PRINT_PCBNEW::onColorModeClicked, this );
130}
131
132
134{
135 m_popMenu->Unbind( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PRINT_PCBNEW::onPopUpLayers ),
137
138 m_outputMode->Unbind( wxEVT_COMMAND_CHOICE_SELECTED, &DIALOG_PRINT_PCBNEW::onColorModeClicked, this );
139}
140
141
143{
145 return false;
146
147 BOARD* board = m_parent->GetBoard();
148
149 // Enable layers from previous dlg settings
151 int choice_ly_id = 0;
152
153 for( PCB_LAYER_ID layer : m_layerList )
154 {
155 if( settings()->m_LayerSet.test( layer ) )
156 m_layerCheckListBox->Check( choice_ly_id );
157
158 choice_ly_id++;
159 }
160
161 m_checkAsItems->SetValue( settings()->m_AsItemCheckboxes );
162 m_checkboxMirror->SetValue( settings()->m_Mirror );
163 m_titleBlock->SetValue( settings()->m_titleBlock );
164
166
167 m_checkBackground->SetValue( cfg->m_Printing.background );
168 m_checkUseTheme->SetValue( cfg->m_Printing.use_theme );
169
170 m_colorTheme->Clear();
171
172 int width = 0;
173 int height = 0;
174 int minwidth = width;
175
176 wxString target = cfg->m_Printing.use_theme ? cfg->m_Printing.color_theme : cfg->m_ColorTheme;
177
179 {
180 int pos = m_colorTheme->Append( settings->GetName(), static_cast<void*>( settings ) );
181
182 if( settings->GetFilename() == target )
183 m_colorTheme->SetSelection( pos );
184
185 m_colorTheme->GetTextExtent( settings->GetName(), &width, &height );
186 minwidth = std::max( minwidth, width );
187 }
188
189 m_colorTheme->SetMinSize( wxSize( minwidth + 50, -1 ) );
190
191 wxCommandEvent dummy;
193
194 // Options to plot pads and vias holes
195 m_drillMarksChoice->SetSelection( (int)settings()->m_DrillMarks );
196
197 // Print all layers one one page or separately
200
201 // Update the dialog layout when layers are added
202 GetSizer()->Fit( this );
203
204 return true;
205}
206
207
209{
210 wxGridBagSizer* optionsSizer = getOptionsSizer();
211 wxStaticBox* box = getOptionsBox();
212 int rows = optionsSizer->GetEffectiveRowsCount();
213
214 m_checkAsItems = new wxCheckBox( box, wxID_ANY, _( "Print according to objects tab of appearance manager" ) );
215 optionsSizer->Add( m_checkAsItems, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT|wxRIGHT|wxBOTTOM, 5 );
216
217 m_checkBackground = new wxCheckBox( box, wxID_ANY, _( "Print background color" ) );
218 optionsSizer->Add( m_checkBackground, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT|wxRIGHT|wxBOTTOM, 5 );
219
220 m_checkUseTheme = new wxCheckBox( box, wxID_ANY, _( "Use a different color theme for printing:" ) );
221 optionsSizer->Add( m_checkUseTheme, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT|wxRIGHT, 5 );
222
223 m_checkUseTheme->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &DIALOG_PRINT_PCBNEW::onUseThemeClicked, this );
224
225 wxArrayString choices;
226 m_colorTheme = new wxChoice( box, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices, 0 );
227 m_colorTheme->SetSelection( 0 );
228 m_colorTheme->SetMinSize( { 200, -1 } );
229 optionsSizer->Add( m_colorTheme, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT, 28 );
230
231 rows++;
232
233 // Drill marks option
234 auto drillMarksLabel = new wxStaticText( box, wxID_ANY, _( "Drill marks:" ) );
235 std::vector<wxString> drillMarkChoices = { _( "No drill mark" ),
236 _( "Small mark" ),
237 _( "Real drill" ) };
238 m_drillMarksChoice = new wxChoice( box, wxID_ANY, wxDefaultPosition, wxDefaultSize,
239 drillMarkChoices.size(), drillMarkChoices.data(), 0 );
240 m_drillMarksChoice->SetSelection( 0 );
241
242 optionsSizer->Add( drillMarksLabel, wxGBPosition( rows, 0 ), wxGBSpan( 1, 1 ),
243 wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
244 optionsSizer->Add( m_drillMarksChoice, wxGBPosition( rows++, 1 ), wxGBSpan( 1, 1 ),
245 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxBOTTOM, 5 );
246
247 // Print mirrored
248 m_checkboxMirror = new wxCheckBox( box, wxID_ANY, _( "Print mirrored" ) );
249
250 optionsSizer->Add( m_checkboxMirror, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ),
251 wxLEFT|wxRIGHT|wxBOTTOM, 5 );
252
253 // Pagination
254 m_checkboxPagePerLayer = new wxCheckBox( box, wxID_ANY, _( "Print one page per layer" ) );
255
256 m_checkboxPagePerLayer->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &DIALOG_PRINT_PCBNEW::onPagePerLayerClicked, this );
257
258 m_checkboxEdgesOnAllPages = new wxCheckBox( box, wxID_ANY, _( "Print board edges on all pages" ) );
259
260 optionsSizer->Add( m_checkboxPagePerLayer, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT|wxRIGHT, 5 );
261 optionsSizer->Add( m_checkboxEdgesOnAllPages, wxGBPosition( rows++, 0 ), wxGBSpan( 1, 2 ), wxLEFT, 28 );
262}
263
264
266{
267 wxStaticBox* box = new wxStaticBox( this, wxID_ANY, _( "Include Layers" ) );
268 wxStaticBoxSizer* sbLayersSizer = new wxStaticBoxSizer( box, wxVERTICAL );
269
270 m_layerCheckListBox = new wxCheckListBox( sbLayersSizer->GetStaticBox(), wxID_ANY );
271 m_layerCheckListBox->SetMinSize( wxSize( 180, -1 ) );
272
273 sbLayersSizer->Add( m_layerCheckListBox, 1, wxEXPAND|wxBOTTOM|wxRIGHT, 5 );
274
275 getMainSizer()->Insert( 0, sbLayersSizer, 1, wxEXPAND | wxALL, 5 );
276
277 m_popMenu = new wxMenu();
278 m_popMenu->Append( new wxMenuItem( m_popMenu, ID_SELECT_FAB_LAYERS, _( "Select Fab Layers" ) ) );
279 m_popMenu->Append( new wxMenuItem( m_popMenu, ID_SELECT_COPPER_LAYERS, _( "Select all Copper Layers" ) ) );
280 m_popMenu->Append( new wxMenuItem( m_popMenu, ID_DESELECT_COPPER_LAYERS, _( "Deselect all Copper Layers" ) ) );
281 m_popMenu->Append( new wxMenuItem( m_popMenu, ID_SELECT_ALL_LAYERS, _( "Select all Layers" ) ) );
282 m_popMenu->Append( new wxMenuItem( m_popMenu, ID_DESELECT_ALL_LAYERS, _( "Deselect all Layers" ) ) );
283
284 this->Bind( wxEVT_RIGHT_DOWN,
285 [&]( wxMouseEvent& aEvent )
286 {
287 this->PopupMenu( m_popMenu, aEvent.GetPosition() );
288 } );
289
290 m_layerCheckListBox->Bind( wxEVT_RIGHT_DOWN,
291 [&]( wxMouseEvent& aEvent )
292 {
293 this->PopupMenu( m_popMenu, aEvent.GetPosition() );
294 } );
295}
296
297
298void DIALOG_PRINT_PCBNEW::onUseThemeClicked( wxCommandEvent& event )
299{
300 m_colorTheme->Enable( m_checkUseTheme->GetValue() );
301}
302
303
305{
306 if( m_checkboxPagePerLayer->GetValue() )
307 {
308 m_checkboxEdgesOnAllPages->Enable( true );
309 m_checkboxEdgesOnAllPages->SetValue( settings()->m_PrintEdgeCutsOnAllPages );
310 }
311 else
312 {
313 m_checkboxEdgesOnAllPages->Enable( false );
314 m_checkboxEdgesOnAllPages->SetValue( false );
315 }
316}
317
318
319void DIALOG_PRINT_PCBNEW::onColorModeClicked( wxCommandEvent& event )
320{
321 m_settings->m_blackWhite = m_outputMode->GetSelection();
322
325
327 m_colorTheme->Enable( !m_settings->m_blackWhite && cfg->m_Printing.use_theme );
328}
329
330
331// Select or deselect groups of layers in the layers list:
332void DIALOG_PRINT_PCBNEW::onPopUpLayers( wxCommandEvent& event )
333{
334 // Build a list of layers for usual fabrication: copper layers + tech layers without courtyard
335 LSET fab_layer_set = ( LSET::AllCuMask() | LSET::AllTechMask() ) & ~LSET( { B_CrtYd, F_CrtYd } );
336
337 switch( event.GetId() )
338 {
339 case ID_SELECT_FAB_LAYERS: // Select layers usually needed to build a board
340 for( unsigned i = 0; i < m_layerList.size(); i++ )
341 {
342 LSET layermask( { m_layerList[ i ] } );
343
344 if( ( layermask & fab_layer_set ).any() )
345 m_layerCheckListBox->Check( i, true );
346 else
347 m_layerCheckListBox->Check( i, false );
348 }
349 break;
350
352 for( unsigned i = 0; i < m_layerList.size(); i++ )
353 {
354 if( IsCopperLayer( m_layerList[i] ) )
355 m_layerCheckListBox->Check( i, true );
356 }
357 break;
358
360 for( unsigned i = 0; i < m_layerList.size(); i++ )
361 {
362 if( IsCopperLayer( m_layerList[i] ) )
363 m_layerCheckListBox->Check( i, false );
364 }
365 break;
366
368 for( unsigned i = 0; i < m_layerList.size(); i++ )
369 m_layerCheckListBox->Check( i, true );
370 break;
371
373 for( unsigned i = 0; i < m_layerList.size(); i++ )
374 m_layerCheckListBox->Check( i, false );
375 break;
376
377 default:
378 break;
379 }
380}
381
382
384{
385 settings()->m_LayerSet = LSET();
386 int& pageCount = settings()->m_pageCount;
387 pageCount = 0;
388
389 for( unsigned i = 0; i < m_layerList.size(); i++ )
390 {
391 if( m_layerCheckListBox->IsChecked( i ) )
392 {
393 ++pageCount;
395 }
396 }
397
398 // In Pcbnew force the EDGE layer to be printed or not with the other layers
400
401 // All layers on one page (only if there is at least one layer selected)
402 if( !m_checkboxPagePerLayer->GetValue() && pageCount > 0 )
403 pageCount = 1;
404
405 return pageCount;
406}
407
408
410{
412
414
415 settings()->m_DrillMarks = static_cast<DRILL_MARKS>( m_drillMarksChoice->GetSelection() );
416
417 if( m_checkboxPagePerLayer->GetValue() )
418 {
421 }
422 else
423 {
425 }
426
427 settings()->m_Mirror = m_checkboxMirror->GetValue();
428
430
431 cfg->m_Printing.background = m_checkBackground->GetValue();
433 cfg->m_Printing.use_theme = m_checkUseTheme->GetValue();
434
435 int sel = m_colorTheme->GetSelection();
436 COLOR_SETTINGS* theme = nullptr;
437
438 if( sel >= 0 && sel < (int) m_colorTheme->GetCount() )
439 theme = static_cast<COLOR_SETTINGS*>( m_colorTheme->GetClientData( sel ) );
440
441 if( theme && m_checkUseTheme->IsChecked() )
442 {
443 cfg->m_Printing.color_theme = theme->GetFilename();
444 settings()->m_colorSettings = theme;
445 }
446 else
447 {
449 }
450
452}
453
454
455int PCB_CONTROL::Print( const TOOL_EVENT& aEvent )
456{
457 // Selection affects the origin item visibility
459
462
464 dlg.ForcePrintBorder( false );
465
466 dlg.ShowModal();
467
468 return 0;
469}
470
471
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: actions.h:221
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:236
BASE_SET & set(size_t pos)
Definition: base_set.h:116
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:317
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:680
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:907
Color settings are a bit different than most of the settings objects in that there can be more than o...
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 saveSettings() 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
SETTINGS_MANAGER * GetSettingsManager() const
wxString GetFilename() const
Definition: json_settings.h:86
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
LSEQ UIOrder() const
Return the copper, technical and user layers in the order shown in layer widget.
Definition: lset.cpp:733
static const LSET & AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:659
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition: lset.cpp:591
Common, abstract interface for edit frames.
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
PCBNEW_SETTINGS * GetPcbNewSettings() const
const PAGE_INFO & GetPageSettings() const override
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
BOARD * GetBoard() const
PCB_BASE_FRAME * m_frame
Definition: pcb_control.h:164
int Print(const TOOL_EVENT &aEvent)
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
bool m_isFootprintEditor
std::vector< COLOR_SETTINGS * > GetColorSettingsList()
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:220
Generic, UI-independent tool event.
Definition: tool_event.h:168
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:150
#define _(s)
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition: layer_ids.h:665
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ F_CrtYd
Definition: layer_ids.h:116
@ B_CrtYd
Definition: layer_ids.h:115
KICOMMON_API wxFont GetSmallInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:162
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.
Definition: app_settings.h:173
wxString color_theme
Color theme to use for printing.
Definition: app_settings.h:177
bool use_theme
If false, display color theme will be used.
Definition: app_settings.h:176
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.
COLOR_SETTINGS * m_colorSettings
The color settings to be used for printing.
Definition: printout.h:66
bool m_blackWhite
Print in B&W or Color.
Definition: printout.h:60
int m_pageCount
Number of pages to print.
Definition: printout.h:61
bool m_background
Print background color.
Definition: printout.h:62