KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_board_setup.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#include <pcb_edit_frame.h>
20#include <panel_setup_layers.h>
25#include <../board_stackup_manager/panel_board_stackup.h>
26#include <../board_stackup_manager/panel_board_finish.h>
27#include <confirm.h>
29#include <kiface_base.h>
30#include <drc/drc_item.h>
32#include <pcb_io/pcb_io.h>
33#include <pcb_io/pcb_io_mgr.h>
43#include <project.h>
49
50#include "dialog_board_setup.h"
51
52#include <advanced_config.h>
53#include <footprint.h>
54
55
56#define RESOLVE_PAGE( T, pageIndex ) static_cast<T*>( m_treebook->ResolvePage( pageIndex ) )
57
59 PAGED_DIALOG( aFrame, _( "Board Setup" ), false, false,
60 _( "Import Settings from Another Board..." ), wxSize( 980, 600 ) ),
61 m_frame( aFrame ),
62 m_layers( nullptr ),
63 m_boardFinish( nullptr ),
64 m_physicalStackup( nullptr ),
65 m_timeDomainParameters( nullptr ),
66 m_netClasses( nullptr ),
67 m_currentPage( 0 ),
68 m_layersPage( 0 ),
69 m_physicalStackupPage( 0 ),
70 m_boardFinishPage( 0 ),
71 m_textAndGraphicsPage( 0 ),
72 m_formattingPage( 0 ),
73 m_maskAndPagePage( 0 ),
74 m_constraintsPage( 0 ),
75 m_tracksAndViasPage( 0 ),
76 m_teardropsPage( 0 ),
77 m_tuningPatternsPage( 0 ),
78 m_netclassesPage( 0 ),
79 m_customRulesPage( 0 ),
80 m_severitiesPage( 0 ),
81 m_timeDomainParametersPage( 0 )
82{
83 SetEvtHandlerEnabled( false );
84
85 /*
86 * WARNING: If you change page names you MUST update calls to ShowBoardSetupDialog().
87 */
88
89 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Board Stackup" ) );
90
91 /*
92 * WARNING: Code currently relies on the layers setup coming before the physical stackup panel,
93 * and thus transferring data to the board first. See comment in
94 * PANEL_SETUP_BOARD_STACKUP::TransferDataFromWindow and rework this logic if it is determined
95 * that the order of these pages should be changed.
96 */
97 m_layersPage = m_treebook->GetPageCount();
99 [this]( wxWindow* aParent ) -> wxWindow*
100 {
101 return new PANEL_SETUP_LAYERS( aParent, m_frame );
102 }, _( "Board Editor Layers" ) );
103
104 m_physicalStackupPage = m_treebook->GetPageCount();
106 [this]( wxWindow* aParent ) -> wxWindow*
107 {
111 }, _( "Physical Stackup" ) );
112
113 m_boardFinishPage = m_treebook->GetPageCount();
115 [this]( wxWindow* aParent ) -> wxWindow*
116 {
117 return new PANEL_SETUP_BOARD_FINISH( aParent, m_frame );
118 }, _( "Board Finish" ) );
119
120 m_maskAndPagePage = m_treebook->GetPageCount();
122 [this]( wxWindow* aParent ) -> wxWindow*
123 {
124 return new PANEL_SETUP_MASK_AND_PASTE( aParent, m_frame );
125 }, _( "Solder Mask/Paste" ) );
126
127 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Text & Graphics" ) );
128
129 m_textAndGraphicsPage = m_treebook->GetPageCount();
131 [this]( wxWindow* aParent ) -> wxWindow*
132 {
133 return new PANEL_SETUP_TEXT_AND_GRAPHICS( aParent, m_frame );
134 }, _( "Defaults" ) );
135
136 m_formattingPage = m_treebook->GetPageCount();
138 [this]( wxWindow* aParent ) -> wxWindow*
139 {
140 return new PANEL_SETUP_FORMATTING( aParent, m_frame );
141 }, _( "Formatting" ) );
142
144 [this]( wxWindow* aParent ) -> wxWindow*
145 {
146 return new PANEL_TEXT_VARIABLES( aParent, &Prj() );
147 }, _( "Text Variables" ) );
148
149 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Design Rules" ) );
150
151 m_constraintsPage = m_treebook->GetPageCount();
153 [this]( wxWindow* aParent ) -> wxWindow*
154 {
155 return new PANEL_SETUP_CONSTRAINTS( aParent, m_frame );
156 }, _( "Constraints" ) );
157
158 m_tracksAndViasPage = m_treebook->GetPageCount();
160 [this]( wxWindow* aParent ) -> wxWindow*
161 {
162 return new PANEL_SETUP_TRACKS_AND_VIAS( aParent, m_frame );
163 }, _( "Pre-defined Sizes" ) );
164
165 m_teardropsPage = m_treebook->GetPageCount();
167 [this]( wxWindow* aParent ) -> wxWindow*
168 {
169 return new PANEL_SETUP_TEARDROPS( aParent, m_frame );
170 }, _( "Teardrops" ) );
171
172 m_tuningPatternsPage = m_treebook->GetPageCount();
174 [this]( wxWindow* aParent ) -> wxWindow*
175 {
177
178 return new PANEL_SETUP_TUNING_PATTERNS( aParent, m_frame,
182 }, _( "Length-tuning Patterns" ) );
183
184 m_netclassesPage = m_treebook->GetPageCount();
186 [this]( wxWindow* aParent ) -> wxWindow*
187 {
188 BOARD* board = m_frame->GetBoard();
189 return new PANEL_SETUP_NETCLASSES( aParent, m_frame,
192 false );
193 }, _( "Net Classes" ) );
194
195 m_componentClassesPage = m_treebook->GetPageCount();
197 [this]( wxWindow* aParent ) -> wxWindow*
198 {
199 // Construct the panel
202 this );
203 },
204 _( "Component Classes" ) );
205
206 m_timeDomainParametersPage = m_treebook->GetPageCount();
208 [this]( wxWindow* aParent ) -> wxWindow*
209 {
210 BOARD* board = m_frame->GetBoard();
212 aParent, m_frame, board, m_frame->Prj().GetProjectFile().TimeDomainParameters() );
213 },
214 _( "Time Domain Parameters" ) );
215
216 m_customRulesPage = m_treebook->GetPageCount();
218 [this]( wxWindow* aParent ) -> wxWindow*
219 {
220 return new PANEL_SETUP_RULES( aParent, m_frame );
221 },
222 _( "Custom Rules" ) );
223
224 m_severitiesPage = m_treebook->GetPageCount();
226 [this]( wxWindow* aParent ) -> wxWindow*
227 {
228 BOARD* board = m_frame->GetBoard();
231 },
232 _( "Violation Severity" ) );
233
234 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Board Data" ) );
235 m_embeddedFilesPage = m_treebook->GetPageCount();
237 [this]( wxWindow* aParent ) -> wxWindow*
238 {
239 return new PANEL_EMBEDDED_FILES( aParent, m_frame->GetBoard() );
240 },
241 _( "Embedded Files" ) );
242
243 for( size_t i = 0; i < m_treebook->GetPageCount(); ++i )
244 m_treebook->ExpandNode( i );
245
246 SetEvtHandlerEnabled( true );
247
249
250 if( Prj().IsReadOnly() )
251 {
252 m_infoBar->ShowMessage( _( "Project is missing or read-only. Some settings will not "
253 "be editable." ),
254 wxICON_WARNING );
255 }
256
257 wxBookCtrlEvent evt( wxEVT_TREEBOOK_PAGE_CHANGED, wxID_ANY, 0 );
258
259 wxQueueEvent( m_treebook, evt.Clone() );
260}
261
262
264{
265}
266
267
268void DIALOG_BOARD_SETUP::onPageChanged( wxBookCtrlEvent& aEvent )
269{
271
272 size_t page = aEvent.GetSelection();
273
274 if( m_physicalStackupPage > 0 ) // Don't run this during initialization
275 {
277 || page == m_physicalStackupPage || page == m_timeDomainParametersPage || page == m_netclassesPage )
278 {
283 }
284
285 // Ensure layer page always gets updated even if we aren't moving towards it
287 {
289
290 // Avoid calling SyncCopperLayers twice if moving from stackup to time domain directly
292 }
293
294 if( page == m_physicalStackupPage )
295 {
297 }
299 {
301 }
302 else if( page == m_timeDomainParametersPage )
303 {
305 }
306
307 if( Prj().IsReadOnly() )
308 {
309 KIUI::Disable( m_treebook->GetPage( page ) );
310 }
311 }
312
313 m_currentPage = page;
314}
315
316
317void DIALOG_BOARD_SETUP::onAuxiliaryAction( wxCommandEvent& aEvent )
318{
319 DIALOG_IMPORT_SETTINGS importDlg( this, m_frame );
320
321 if( importDlg.ShowModal() == wxID_CANCEL )
322 return;
323
324 wxFileName boardFn( importDlg.GetFilePath() );
325 wxFileName projectFn( boardFn );
326
327 projectFn.SetExt( FILEEXT::ProjectFileExtension );
328
329 if( !m_frame->GetSettingsManager()->LoadProject( projectFn.GetFullPath(), false ) )
330 {
331 wxString msg = wxString::Format( _( "Error importing settings from board:\n"
332 "Associated project file %s could not be loaded" ),
333 projectFn.GetFullPath() );
334 DisplayErrorMessage( this, msg );
335
336 return;
337 }
338
342
343 // Flag so user can stop work if it will result in deleted inner copper layers
344 // and still clean up this function properly.
345 bool okToProceed = true;
346
347 PROJECT* otherPrj = m_frame->GetSettingsManager()->GetProject( projectFn.GetFullPath() );
348
350 BOARD* otherBoard = nullptr;
351
352 try
353 {
354 WX_PROGRESS_REPORTER progressReporter( this, _( "Load PCB" ), 1, PR_CAN_ABORT );
355
356 pi->SetProgressReporter( &progressReporter );
357
358 otherBoard = pi->LoadBoard( boardFn.GetFullPath(), nullptr );
359
360 if( importDlg.m_LayersOpt->GetValue() )
361 {
362 BOARD* loadedBoard = m_frame->GetBoard();
363
364 // Check if "Import Settings" board has more layers than the current board.
365 okToProceed = m_layers->CheckCopperLayerCount( loadedBoard, otherBoard );
366 }
367 }
368 catch( const IO_ERROR& ioe )
369 {
370 // You wouldn't think boardFn.GetFullPath() would throw, but we get a stack buffer
371 // underflow from ASAN. While it's probably an ASAN error, a second try/catch doesn't
372 // cost us much.
373 try
374 {
375 if( ioe.Problem() != wxT( "CANCEL" ) )
376 {
377 wxString msg = wxString::Format( _( "Error loading board file:\n%s" ),
378 boardFn.GetFullPath() );
379 DisplayErrorMessage( this, msg, ioe.What() );
380 }
381
382 if( otherPrj != &m_frame->Prj() )
383 m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
384 }
385 catch(...)
386 {
387 // That was already our best-efforts
388 }
389
390 return;
391 }
392
393 if( okToProceed )
394 {
395 otherBoard->SetProject( otherPrj );
396
397 // If layers options are imported, import also the stackup
398 // layers options and stackup are linked, so they cannot be imported
399 // separately, and stackup can be imported only after layers options
400 if( importDlg.m_LayersOpt->GetValue() )
401 {
403 m_layers->ImportSettingsFrom( otherBoard );
404 m_boardFinish->ImportSettingsFrom( otherBoard );
405 }
406
407 if( importDlg.m_TextAndGraphicsOpt->GetValue() )
408 {
410 m_textAndGraphicsPage )->ImportSettingsFrom( otherBoard );
411 }
412
413 if( importDlg.m_FormattingOpt->GetValue() )
414 {
416 m_formattingPage )->ImportSettingsFrom( otherBoard );
417 }
418
419 if( importDlg.m_ConstraintsOpt->GetValue() )
420 {
422 m_constraintsPage )->ImportSettingsFrom( otherBoard );
423 }
424
425 if( importDlg.m_NetclassesOpt->GetValue() )
426 {
427 PROJECT_FILE& otherProjectFile = otherPrj->GetProjectFile();
428
430 m_netclassesPage )->ImportSettingsFrom( otherProjectFile.m_NetSettings );
431 }
432
433 if( importDlg.m_ComponentClassesOpt->GetValue() )
434 {
435 PROJECT_FILE& otherProjectFile = otherPrj->GetProjectFile();
436
438 ->ImportSettingsFrom( otherProjectFile.m_ComponentClassSettings );
439 }
440
441 if( importDlg.m_TracksAndViasOpt->GetValue() )
442 {
444 m_tracksAndViasPage )->ImportSettingsFrom( otherBoard );
445 }
446
447 if( importDlg.m_TeardropsOpt->GetValue() )
448 {
450 m_teardropsPage )->ImportSettingsFrom( otherBoard );
451 }
452
453 if( importDlg.m_TuningPatternsOpt->GetValue() )
454 {
456 m_tuningPatternsPage )->ImportSettingsFrom( otherBoard );
457 }
458
459 if( importDlg.m_MaskAndPasteOpt->GetValue() )
460 {
462 m_maskAndPagePage )->ImportSettingsFrom( otherBoard );
463 }
464
465 if( importDlg.m_CustomRulesOpt->GetValue() )
466 {
468 m_customRulesPage )->ImportSettingsFrom( otherBoard );
469 }
470
471 if( importDlg.m_SeveritiesOpt->GetValue() )
472 {
473 BOARD_DESIGN_SETTINGS& otherSettings = otherBoard->GetDesignSettings();
474
476 m_severitiesPage )->ImportSettingsFrom( otherSettings.m_DRCSeverities );
477 }
478
479 if( importDlg.m_TimeDomainParametersOpt->GetValue() )
480 {
481 PROJECT_FILE& otherProjectFile = otherPrj->GetProjectFile();
482
484 ->ImportSettingsFrom( otherProjectFile.TimeDomainParameters() );
485 }
486
487 if( otherPrj != &m_frame->Prj() )
488 otherBoard->ClearProject();
489 }
490
491 // Clean up and free memory before leaving
492 if( otherPrj != &m_frame->Prj() )
493 m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
494
495 delete otherBoard;
496}
Container for design settings for a BOARD object.
std::map< int, SEVERITY > m_DRCSeverities
PNS::MEANDER_SETTINGS m_DiffPairMeanderSettings
PNS::MEANDER_SETTINGS m_SingleTrackMeanderSettings
PNS::MEANDER_SETTINGS m_SkewMeanderSettings
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:317
std::set< wxString > GetNetClassAssignmentCandidates() const
Return the set of netname candidates for netclass assignment.
Definition: board.cpp:2207
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition: board.cpp:196
void ClearProject()
Definition: board.cpp:234
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:1024
DIALOG_BOARD_SETUP(PCB_EDIT_FRAME *aFrame)
PCB_EDIT_FRAME * m_frame
void onAuxiliaryAction(wxCommandEvent &aEvent) override
PANEL_SETUP_BOARD_STACKUP * m_physicalStackup
PANEL_SETUP_BOARD_FINISH * m_boardFinish
PANEL_SETUP_LAYERS * m_layers
PANEL_SETUP_TIME_DOMAIN_PARAMETERS * m_timeDomainParameters
void onPageChanged(wxBookCtrlEvent &aEvent) override
PANEL_SETUP_NETCLASSES * m_netClasses
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int ShowModal() override
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities(bool aIncludeDeprecated=false)
Definition: drc_item.h:133
SETTINGS_MANAGER * GetSettingsManager() const
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:46
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
WX_TREEBOOK * GetTreebook()
Definition: paged_dialog.h:39
WX_INFOBAR * m_infoBar
Definition: paged_dialog.h:72
WX_TREEBOOK * m_treebook
Definition: paged_dialog.h:68
virtual void onPageChanged(wxBookCtrlEvent &aEvent)
void ImportSettingsFrom(BOARD *aBoard)
void ImportSettingsFrom(BOARD *aBoard)
void OnLayersOptionsChanged(const LSET &aNewLayerSet)
Must be called if the copper layers count has changed or solder mask, solder paste or silkscreen laye...
bool CheckCopperLayerCount(BOARD *aWorkingBoard, BOARD *aImportedBoard)
Check and warn if inner copper layers will be deleted.
void SyncCopperLayers(int aNumCopperLayers)
Called when switching to this tab to make sure that any changes to the copper layer count made on the...
void ImportSettingsFrom(BOARD *aBoard)
void UpdateDelayProfileNames(const std::vector< wxString > &aNames) const
void SyncCopperLayers(int aNumCopperLayers)
Called when switching to this tab to make sure that any changes to the copper layer count made on the...
std::vector< wxString > GetDelayProfileNames() const
Returns all configured tuning profile names. Used by the netclass setup panel.
BOARD * GetBoard() const
The main frame for Pcbnew.
static PCB_IO * PluginFind(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: pcb_io_mgr.cpp:68
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition: pcb_io_mgr.h:58
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:68
std::shared_ptr< NET_SETTINGS > & NetSettings()
Definition: project_file.h:99
std::shared_ptr< NET_SETTINGS > m_NetSettings
Net settings for this project (owned here)
Definition: project_file.h:189
std::shared_ptr< COMPONENT_CLASS_SETTINGS > & ComponentClassSettings()
Definition: project_file.h:104
std::shared_ptr< TIME_DOMAIN_PARAMETERS > & TimeDomainParameters()
Definition: project_file.h:109
std::shared_ptr< COMPONENT_CLASS_SETTINGS > m_ComponentClassSettings
Component class settings for the project (owned here)
Definition: project_file.h:196
Container for project specific data.
Definition: project.h:65
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:204
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
PROJECT * GetProject(const wxString &aFullPath) const
Retrieve a loaded project by name.
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Save, unload and unregister the given PROJECT.
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: wx_infobar.cpp:156
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
bool AddLazySubPage(std::function< wxWindow *(wxWindow *aParent)> aLazyCtor, const wxString &text, bool bSelect=false, int imageId=NO_IMAGE)
Definition: wx_treebook.cpp:96
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:194
This file is part of the common library.
#define RESOLVE_PAGE(T, pageIndex)
#define _(s)
static const std::string ProjectFileExtension
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition: io_mgr.h:33
KICOMMON_API void Disable(wxWindow *aWindow)
Makes a window read-only.
Definition: ui_common.cpp:332
Definition of file extensions used in Kicad.
#define PR_CAN_ABORT