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 (C) 2017-2023 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 <io_mgr.h>
39#include <project.h>
45
46#include "dialog_board_setup.h"
47
48
50
51
52#define RESOLVE_PAGE( T, pageIndex ) static_cast<T*>( m_treebook->ResolvePage( pageIndex ) )
53
55 PAGED_DIALOG( aFrame, _( "Board Setup" ), false, false,
56 _( "Import Settings from Another Board..." ), wxSize( 980, 600 ) ),
57 m_frame( aFrame ),
58 m_layers( nullptr ),
59 m_physicalStackup( nullptr ),
60 m_currentPage( 0 ),
61 m_layersPage( 0 ),
62 m_physicalStackupPage( 0 ),
63 m_boardFinishPage( 0 ),
64 m_textAndGraphicsPage( 0 ),
65 m_formattingPage( 0 ),
66 m_maskAndPagePage( 0 ),
67 m_constraintsPage( 0 ),
68 m_tracksAndViasPage( 0 ),
69 m_teardropsPage( 0 ),
70 m_tuningPatternsPage( 0 ),
71 m_netclassesPage( 0 ),
72 m_customRulesPage( 0 ),
73 m_severitiesPage( 0 )
74
75{
76 SetEvtHandlerEnabled( false );
77
78 /*
79 * WARNING: If you change page names you MUST update calls to ShowBoardSetupDialog().
80 */
81
82 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Board Stackup" ) );
83
84 /*
85 * WARNING: Code currently relies on the layers setup coming before the physical stackup panel,
86 * and thus transferring data to the board first. See comment in
87 * PANEL_SETUP_BOARD_STACKUP::TransferDataFromWindow and rework this logic if it is determined
88 * that the order of these pages should be changed.
89 */
90 m_layersPage = m_treebook->GetPageCount();
92 [this]( wxWindow* aParent ) -> wxWindow*
93 {
94 return new PANEL_SETUP_LAYERS( aParent, m_frame );
95 }, _( "Board Editor Layers" ) );
96
97 m_physicalStackupPage = m_treebook->GetPageCount();
99 [this]( wxWindow* aParent ) -> wxWindow*
100 {
102 return new PANEL_SETUP_BOARD_STACKUP( aParent, m_frame, m_layers );
103 }, _( "Physical Stackup" ) );
104
105 m_boardFinishPage = m_treebook->GetPageCount();
107 [this]( wxWindow* aParent ) -> wxWindow*
108 {
109 return new PANEL_SETUP_BOARD_FINISH( aParent, m_frame );
110 }, _( "Board Finish" ) );
111
112 m_maskAndPagePage = m_treebook->GetPageCount();
114 [this]( wxWindow* aParent ) -> wxWindow*
115 {
116 return new PANEL_SETUP_MASK_AND_PASTE( aParent, m_frame );
117 }, _( "Solder Mask/Paste" ) );
118
119 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Text & Graphics" ) );
120
121 m_textAndGraphicsPage = m_treebook->GetPageCount();
123 [this]( wxWindow* aParent ) -> wxWindow*
124 {
125 return new PANEL_SETUP_TEXT_AND_GRAPHICS( aParent, m_frame );
126 }, _( "Defaults" ) );
127
128 m_formattingPage = m_treebook->GetPageCount();
130 [this]( wxWindow* aParent ) -> wxWindow*
131 {
132 return new PANEL_SETUP_FORMATTING( aParent, m_frame );
133 }, _( "Formatting" ) );
134
136 [this]( wxWindow* aParent ) -> wxWindow*
137 {
138 return new PANEL_TEXT_VARIABLES( aParent, &Prj() );
139 }, _( "Text Variables" ) );
140
141 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Design Rules" ) );
142
143 m_constraintsPage = m_treebook->GetPageCount();
145 [this]( wxWindow* aParent ) -> wxWindow*
146 {
147 return new PANEL_SETUP_CONSTRAINTS( aParent, m_frame );
148 }, _( "Constraints" ) );
149
150 m_tracksAndViasPage = m_treebook->GetPageCount();
152 [this]( wxWindow* aParent ) -> wxWindow*
153 {
154 return new PANEL_SETUP_TRACKS_AND_VIAS( aParent, m_frame );
155 }, _( "Pre-defined Sizes" ) );
156
157 m_teardropsPage = m_treebook->GetPageCount();
159 [this]( wxWindow* aParent ) -> wxWindow*
160 {
161 return new PANEL_SETUP_TEARDROPS( aParent, m_frame );
162 }, _( "Teardrops" ) );
163
164 m_tuningPatternsPage = m_treebook->GetPageCount();
166 [this]( wxWindow* aParent ) -> wxWindow*
167 {
169
170 return new PANEL_SETUP_TUNING_PATTERNS( aParent, m_frame,
174 }, _( "Length-tuning Patterns" ) );
175
176 m_netclassesPage = m_treebook->GetPageCount();
178 [this]( wxWindow* aParent ) -> wxWindow*
179 {
180 BOARD* board = m_frame->GetBoard();
181 return new PANEL_SETUP_NETCLASSES( aParent, m_frame,
184 false );
185 }, _( "Net Classes" ) );
186
187 m_customRulesPage = m_treebook->GetPageCount();
189 [this]( wxWindow* aParent ) -> wxWindow*
190 {
191 return new PANEL_SETUP_RULES( aParent, m_frame );
192 }, _( "Custom Rules" ) );
193
194 m_severitiesPage = m_treebook->GetPageCount();
196 [this]( wxWindow* aParent ) -> wxWindow*
197 {
198 BOARD* board = m_frame->GetBoard();
201 }, _( "Violation Severity" ) );
202
203 for( size_t i = 0; i < m_treebook->GetPageCount(); ++i )
204 m_treebook->ExpandNode( i );
205
206 SetEvtHandlerEnabled( true );
207
209
210 if( Prj().IsReadOnly() )
211 {
212 m_infoBar->ShowMessage( _( "Project is missing or read-only. Some settings will not "
213 "be editable." ), wxICON_WARNING );
214 }
215
216 wxBookCtrlEvent evt( wxEVT_TREEBOOK_PAGE_CHANGED, wxID_ANY, 0 );
217
218 wxQueueEvent( m_treebook, evt.Clone() );
219}
220
221
223{
224}
225
226
227void DIALOG_BOARD_SETUP::onPageChanged( wxBookCtrlEvent& aEvent )
228{
230
231 size_t page = aEvent.GetSelection();
232
233 if( m_physicalStackupPage > 0 ) // Don't run this during initialization
234 {
236 {
239 }
240
241 // Ensure layer page always gets updated even if we aren't moving towards it
244
245 if( page == m_physicalStackupPage )
247 else if( Prj().IsReadOnly() )
248 KIUI::Disable( m_treebook->GetPage( page ) );
249 }
250
251 m_currentPage = page;
252}
253
254
255void DIALOG_BOARD_SETUP::onAuxiliaryAction( wxCommandEvent& aEvent )
256{
257 DIALOG_IMPORT_SETTINGS importDlg( this, m_frame );
258
259 if( importDlg.ShowModal() == wxID_CANCEL )
260 return;
261
262 wxFileName boardFn( importDlg.GetFilePath() );
263 wxFileName projectFn( boardFn );
264
265 projectFn.SetExt( ProjectFileExtension );
266
267 if( !m_frame->GetSettingsManager()->LoadProject( projectFn.GetFullPath(), false ) )
268 {
269 wxString msg = wxString::Format( _( "Error importing settings from board:\n"
270 "Associated project file %s could not be loaded" ),
271 projectFn.GetFullPath() );
272 DisplayErrorMessage( this, msg );
273
274 return;
275 }
276
279
280 // Flag so user can stop work if it will result in deleted inner copper layers
281 // and still clean up this function properly.
282 bool okToProceed = true;
283
284 PROJECT* otherPrj = m_frame->GetSettingsManager()->GetProject( projectFn.GetFullPath() );
285
287 BOARD* otherBoard = nullptr;
288
289 try
290 {
291 WX_PROGRESS_REPORTER progressReporter( this, _( "Loading PCB" ), 1 );
292
293 otherBoard = pi->LoadBoard( boardFn.GetFullPath(), nullptr, nullptr, nullptr,
294 &progressReporter );
295
296 if( importDlg.m_LayersOpt->GetValue() )
297 {
298 BOARD* loadedBoard = m_frame->GetBoard();
299
300 // Check if "Import Settings" board has more layers than the current board.
301 okToProceed = m_layers->CheckCopperLayerCount( loadedBoard, otherBoard );
302 }
303 }
304 catch( const IO_ERROR& ioe )
305 {
306 // You wouldn't think boardFn.GetFullPath() would throw, but we get a stack buffer
307 // underflow from ASAN. While it's probably an ASAN error, a second try/catch doesn't
308 // cost us much.
309 try
310 {
311 if( ioe.Problem() != wxT( "CANCEL" ) )
312 {
313 wxString msg = wxString::Format( _( "Error loading board file:\n%s" ),
314 boardFn.GetFullPath() );
315 DisplayErrorMessage( this, msg, ioe.What() );
316 }
317
318 if( otherPrj != &m_frame->Prj() )
319 m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
320 }
321 catch(...)
322 {
323 // That was already our best-efforts
324 }
325
326 return;
327 }
328
329 if( okToProceed )
330 {
331 otherBoard->SetProject( otherPrj );
332
333 // If layers options are imported, import also the stackup
334 // layers options and stackup are linked, so they cannot be imported
335 // separately, and stackup can be imported only after layers options
336 if( importDlg.m_LayersOpt->GetValue() )
337 {
339 m_layers->ImportSettingsFrom( otherBoard );
340
342 m_boardFinishPage )->ImportSettingsFrom( otherBoard );
343 }
344
345 if( importDlg.m_TextAndGraphicsOpt->GetValue() )
346 {
348 m_textAndGraphicsPage )->ImportSettingsFrom( otherBoard );
349 }
350
351 if( importDlg.m_FormattingOpt->GetValue() )
352 {
354 m_formattingPage )->ImportSettingsFrom( otherBoard );
355 }
356
357 if( importDlg.m_ConstraintsOpt->GetValue() )
358 {
360 m_constraintsPage )->ImportSettingsFrom( otherBoard );
361 }
362
363 if( importDlg.m_NetclassesOpt->GetValue() )
364 {
365 PROJECT_FILE& otherProjectFile = otherPrj->GetProjectFile();
366
368 m_netclassesPage )->ImportSettingsFrom( otherProjectFile.m_NetSettings );
369 }
370
371 if( importDlg.m_TracksAndViasOpt->GetValue() )
372 {
374 m_tracksAndViasPage )->ImportSettingsFrom( otherBoard );
375 }
376
377 if( importDlg.m_TeardropsOpt->GetValue() )
378 {
380 m_teardropsPage )->ImportSettingsFrom( otherBoard );
381 }
382
383 if( importDlg.m_TuningPatternsOpt->GetValue() )
384 {
386 m_tuningPatternsPage )->ImportSettingsFrom( otherBoard );
387 }
388
389 if( importDlg.m_MaskAndPasteOpt->GetValue() )
390 {
392 m_maskAndPagePage )->ImportSettingsFrom( otherBoard );
393 }
394
395 if( importDlg.m_CustomRulesOpt->GetValue() )
396 {
398 m_customRulesPage )->ImportSettingsFrom( otherBoard );
399 }
400
401 if( importDlg.m_SeveritiesOpt->GetValue() )
402 {
403 BOARD_DESIGN_SETTINGS& otherSettings = otherBoard->GetDesignSettings();
404
406 m_severitiesPage )->ImportSettingsFrom( otherSettings.m_DRCSeverities );
407 }
408
409 if( otherPrj != &m_frame->Prj() )
410 otherBoard->ClearProject();
411 }
412
413 // Clean up and free memory before leaving
414 if( otherPrj != &m_frame->Prj() )
415 m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
416
417 delete otherBoard;
418}
Container for design settings for a BOARD object.
std::map< int, SEVERITY > m_DRCSeverities
PNS::MEANDER_SETTINGS m_skewMeanderSettings
PNS::MEANDER_SETTINGS m_diffPairMeanderSettings
PNS::MEANDER_SETTINGS m_singleTrackMeanderSettings
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:276
std::set< wxString > GetNetClassAssignmentCandidates() const
Return the set of netname candidates for netclass assignment.
Definition: board.cpp:1731
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition: board.cpp:192
void ClearProject()
Definition: board.cpp:231
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:745
DIALOG_BOARD_SETUP(PCB_EDIT_FRAME *aFrame)
static std::mutex g_Mutex
PCB_EDIT_FRAME * m_frame
void onAuxiliaryAction(wxCommandEvent &aEvent) override
PANEL_SETUP_BOARD_STACKUP * m_physicalStackup
PANEL_SETUP_LAYERS * m_layers
void onPageChanged(wxBookCtrlEvent &aEvent) override
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities()
Definition: drc_item.h:122
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
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition: io_mgr.h:56
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Return a PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: io_mgr.cpp:64
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 OnLayersOptionsChanged(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)
BOARD * GetBoard() const
The main frame for Pcbnew.
Releases a PLUGIN in the context of a potential thrown exception through its destructor.
Definition: io_mgr.h:614
virtual BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const STRING_UTF8_MAP *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Load information from some input file format that this PLUGIN implementation knows about into either ...
Definition: plugin.cpp:144
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:70
std::shared_ptr< NET_SETTINGS > & NetSettings()
Definition: project_file.h:101
std::shared_ptr< NET_SETTINGS > m_NetSettings
Net settings for this project (owned here)
Definition: project_file.h:173
Container for project specific data.
Definition: project.h:62
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:166
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Loads a project or sets up a new project with a specified path.
PROJECT * GetProject(const wxString &aFullPath) const
Retrieves a loaded project by name.
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Saves, unloads and unregisters 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:154
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:305
This file is part of the common library.
#define RESOLVE_PAGE(T, pageIndex)
#define _(s)
const std::string ProjectFileExtension
void Disable(wxWindow *aWindow)
Makes a window read-only.
Definition: ui_common.cpp:320
Definition of file extensions used in Kicad.