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 <pcb_io/pcb_io.h>
33#include <pcb_io/pcb_io_mgr.h>
41#include <project.h>
47
48#include "dialog_board_setup.h"
49
50
52
53
54#define RESOLVE_PAGE( T, pageIndex ) static_cast<T*>( m_treebook->ResolvePage( pageIndex ) )
55
57 PAGED_DIALOG( aFrame, _( "Board Setup" ), false, false,
58 _( "Import Settings from Another Board..." ), wxSize( 980, 600 ) ),
59 m_frame( aFrame ),
60 m_layers( nullptr ),
61 m_boardFinish( nullptr ),
62 m_physicalStackup( nullptr ),
63 m_currentPage( 0 ),
64 m_layersPage( 0 ),
65 m_physicalStackupPage( 0 ),
66 m_boardFinishPage( 0 ),
67 m_textAndGraphicsPage( 0 ),
68 m_formattingPage( 0 ),
69 m_maskAndPagePage( 0 ),
70 m_constraintsPage( 0 ),
71 m_tracksAndViasPage( 0 ),
72 m_teardropsPage( 0 ),
73 m_tuningPatternsPage( 0 ),
74 m_netclassesPage( 0 ),
75 m_customRulesPage( 0 ),
76 m_severitiesPage( 0 )
77
78{
79 SetEvtHandlerEnabled( false );
80
81 /*
82 * WARNING: If you change page names you MUST update calls to ShowBoardSetupDialog().
83 */
84
85 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Board Stackup" ) );
86
87 /*
88 * WARNING: Code currently relies on the layers setup coming before the physical stackup panel,
89 * and thus transferring data to the board first. See comment in
90 * PANEL_SETUP_BOARD_STACKUP::TransferDataFromWindow and rework this logic if it is determined
91 * that the order of these pages should be changed.
92 */
93 m_layersPage = m_treebook->GetPageCount();
95 [this]( wxWindow* aParent ) -> wxWindow*
96 {
97 return new PANEL_SETUP_LAYERS( aParent, m_frame );
98 }, _( "Board Editor Layers" ) );
99
100 m_physicalStackupPage = m_treebook->GetPageCount();
102 [this]( wxWindow* aParent ) -> wxWindow*
103 {
107 }, _( "Physical Stackup" ) );
108
109 m_boardFinishPage = m_treebook->GetPageCount();
111 [this]( wxWindow* aParent ) -> wxWindow*
112 {
113 return new PANEL_SETUP_BOARD_FINISH( aParent, m_frame );
114 }, _( "Board Finish" ) );
115
116 m_maskAndPagePage = m_treebook->GetPageCount();
118 [this]( wxWindow* aParent ) -> wxWindow*
119 {
120 return new PANEL_SETUP_MASK_AND_PASTE( aParent, m_frame );
121 }, _( "Solder Mask/Paste" ) );
122
123 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Text & Graphics" ) );
124
125 m_textAndGraphicsPage = m_treebook->GetPageCount();
127 [this]( wxWindow* aParent ) -> wxWindow*
128 {
129 return new PANEL_SETUP_TEXT_AND_GRAPHICS( aParent, m_frame );
130 }, _( "Defaults" ) );
131
132 m_formattingPage = m_treebook->GetPageCount();
134 [this]( wxWindow* aParent ) -> wxWindow*
135 {
136 return new PANEL_SETUP_FORMATTING( aParent, m_frame );
137 }, _( "Formatting" ) );
138
140 [this]( wxWindow* aParent ) -> wxWindow*
141 {
142 return new PANEL_TEXT_VARIABLES( aParent, &Prj() );
143 }, _( "Text Variables" ) );
144
145 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Design Rules" ) );
146
147 m_constraintsPage = m_treebook->GetPageCount();
149 [this]( wxWindow* aParent ) -> wxWindow*
150 {
151 return new PANEL_SETUP_CONSTRAINTS( aParent, m_frame );
152 }, _( "Constraints" ) );
153
154 m_tracksAndViasPage = m_treebook->GetPageCount();
156 [this]( wxWindow* aParent ) -> wxWindow*
157 {
158 return new PANEL_SETUP_TRACKS_AND_VIAS( aParent, m_frame );
159 }, _( "Pre-defined Sizes" ) );
160
161 m_teardropsPage = m_treebook->GetPageCount();
163 [this]( wxWindow* aParent ) -> wxWindow*
164 {
165 return new PANEL_SETUP_TEARDROPS( aParent, m_frame );
166 }, _( "Teardrops" ) );
167
168 m_tuningPatternsPage = m_treebook->GetPageCount();
170 [this]( wxWindow* aParent ) -> wxWindow*
171 {
173
174 return new PANEL_SETUP_TUNING_PATTERNS( aParent, m_frame,
178 }, _( "Length-tuning Patterns" ) );
179
180 m_netclassesPage = m_treebook->GetPageCount();
182 [this]( wxWindow* aParent ) -> wxWindow*
183 {
184 BOARD* board = m_frame->GetBoard();
185 return new PANEL_SETUP_NETCLASSES( aParent, m_frame,
188 false );
189 }, _( "Net Classes" ) );
190
191 m_customRulesPage = m_treebook->GetPageCount();
193 [this]( wxWindow* aParent ) -> wxWindow*
194 {
195 return new PANEL_SETUP_RULES( aParent, m_frame );
196 }, _( "Custom Rules" ) );
197
198 m_severitiesPage = m_treebook->GetPageCount();
200 [this]( wxWindow* aParent ) -> wxWindow*
201 {
202 BOARD* board = m_frame->GetBoard();
205 }, _( "Violation Severity" ) );
206
207 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Board Data" ) );
208 m_embeddedFilesPage = m_treebook->GetPageCount();
210 [this]( wxWindow* aParent ) -> wxWindow*
211 {
212 return new PANEL_EMBEDDED_FILES( aParent, m_frame->GetBoard() );
213 }, _( "Embedded Files" ) );
214
215 for( size_t i = 0; i < m_treebook->GetPageCount(); ++i )
216 m_treebook->ExpandNode( i );
217
218 SetEvtHandlerEnabled( true );
219
221
222 if( Prj().IsReadOnly() )
223 {
224 m_infoBar->ShowMessage( _( "Project is missing or read-only. Some settings will not "
225 "be editable." ), wxICON_WARNING );
226 }
227
228 wxBookCtrlEvent evt( wxEVT_TREEBOOK_PAGE_CHANGED, wxID_ANY, 0 );
229
230 wxQueueEvent( m_treebook, evt.Clone() );
231}
232
233
235{
236}
237
238
239void DIALOG_BOARD_SETUP::onPageChanged( wxBookCtrlEvent& aEvent )
240{
242
243 size_t page = aEvent.GetSelection();
244
245 if( m_physicalStackupPage > 0 ) // Don't run this during initialization
246 {
248 {
251 }
252
253 // Ensure layer page always gets updated even if we aren't moving towards it
256
257 if( page == m_physicalStackupPage )
259 else if( Prj().IsReadOnly() )
260 KIUI::Disable( m_treebook->GetPage( page ) );
261 }
262
263 m_currentPage = page;
264}
265
266
267void DIALOG_BOARD_SETUP::onAuxiliaryAction( wxCommandEvent& aEvent )
268{
269 DIALOG_IMPORT_SETTINGS importDlg( this, m_frame );
270
271 if( importDlg.ShowModal() == wxID_CANCEL )
272 return;
273
274 wxFileName boardFn( importDlg.GetFilePath() );
275 wxFileName projectFn( boardFn );
276
277 projectFn.SetExt( FILEEXT::ProjectFileExtension );
278
279 if( !m_frame->GetSettingsManager()->LoadProject( projectFn.GetFullPath(), false ) )
280 {
281 wxString msg = wxString::Format( _( "Error importing settings from board:\n"
282 "Associated project file %s could not be loaded" ),
283 projectFn.GetFullPath() );
284 DisplayErrorMessage( this, msg );
285
286 return;
287 }
288
292
293 // Flag so user can stop work if it will result in deleted inner copper layers
294 // and still clean up this function properly.
295 bool okToProceed = true;
296
297 PROJECT* otherPrj = m_frame->GetSettingsManager()->GetProject( projectFn.GetFullPath() );
298
300 BOARD* otherBoard = nullptr;
301
302 try
303 {
304 WX_PROGRESS_REPORTER progressReporter( this, _( "Loading PCB" ), 1 );
305
306 pi->SetProgressReporter( &progressReporter );
307
308 otherBoard = pi->LoadBoard( boardFn.GetFullPath(), nullptr );
309
310 if( importDlg.m_LayersOpt->GetValue() )
311 {
312 BOARD* loadedBoard = m_frame->GetBoard();
313
314 // Check if "Import Settings" board has more layers than the current board.
315 okToProceed = m_layers->CheckCopperLayerCount( loadedBoard, otherBoard );
316 }
317 }
318 catch( const IO_ERROR& ioe )
319 {
320 // You wouldn't think boardFn.GetFullPath() would throw, but we get a stack buffer
321 // underflow from ASAN. While it's probably an ASAN error, a second try/catch doesn't
322 // cost us much.
323 try
324 {
325 if( ioe.Problem() != wxT( "CANCEL" ) )
326 {
327 wxString msg = wxString::Format( _( "Error loading board file:\n%s" ),
328 boardFn.GetFullPath() );
329 DisplayErrorMessage( this, msg, ioe.What() );
330 }
331
332 if( otherPrj != &m_frame->Prj() )
333 m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
334 }
335 catch(...)
336 {
337 // That was already our best-efforts
338 }
339
340 return;
341 }
342
343 if( okToProceed )
344 {
345 otherBoard->SetProject( otherPrj );
346
347 // If layers options are imported, import also the stackup
348 // layers options and stackup are linked, so they cannot be imported
349 // separately, and stackup can be imported only after layers options
350 if( importDlg.m_LayersOpt->GetValue() )
351 {
353 m_layers->ImportSettingsFrom( otherBoard );
354 m_boardFinish->ImportSettingsFrom( otherBoard );
355 }
356
357 if( importDlg.m_TextAndGraphicsOpt->GetValue() )
358 {
360 m_textAndGraphicsPage )->ImportSettingsFrom( otherBoard );
361 }
362
363 if( importDlg.m_FormattingOpt->GetValue() )
364 {
366 m_formattingPage )->ImportSettingsFrom( otherBoard );
367 }
368
369 if( importDlg.m_ConstraintsOpt->GetValue() )
370 {
372 m_constraintsPage )->ImportSettingsFrom( otherBoard );
373 }
374
375 if( importDlg.m_NetclassesOpt->GetValue() )
376 {
377 PROJECT_FILE& otherProjectFile = otherPrj->GetProjectFile();
378
380 m_netclassesPage )->ImportSettingsFrom( otherProjectFile.m_NetSettings );
381 }
382
383 if( importDlg.m_TracksAndViasOpt->GetValue() )
384 {
386 m_tracksAndViasPage )->ImportSettingsFrom( otherBoard );
387 }
388
389 if( importDlg.m_TeardropsOpt->GetValue() )
390 {
392 m_teardropsPage )->ImportSettingsFrom( otherBoard );
393 }
394
395 if( importDlg.m_TuningPatternsOpt->GetValue() )
396 {
398 m_tuningPatternsPage )->ImportSettingsFrom( otherBoard );
399 }
400
401 if( importDlg.m_MaskAndPasteOpt->GetValue() )
402 {
404 m_maskAndPagePage )->ImportSettingsFrom( otherBoard );
405 }
406
407 if( importDlg.m_CustomRulesOpt->GetValue() )
408 {
410 m_customRulesPage )->ImportSettingsFrom( otherBoard );
411 }
412
413 if( importDlg.m_SeveritiesOpt->GetValue() )
414 {
415 BOARD_DESIGN_SETTINGS& otherSettings = otherBoard->GetDesignSettings();
416
418 m_severitiesPage )->ImportSettingsFrom( otherSettings.m_DRCSeverities );
419 }
420
421 if( otherPrj != &m_frame->Prj() )
422 otherBoard->ClearProject();
423 }
424
425 // Clean up and free memory before leaving
426 if( otherPrj != &m_frame->Prj() )
427 m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
428
429 delete otherBoard;
430}
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:289
std::set< wxString > GetNetClassAssignmentCandidates() const
Return the set of netname candidates for netclass assignment.
Definition: board.cpp:2010
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition: board.cpp:196
void ClearProject()
Definition: board.cpp:235
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:874
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_BOARD_FINISH * m_boardFinish
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:126
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(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.
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:65
@ 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: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:195
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:323
Definition of file extensions used in Kicad.