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