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
51#define RESOLVE_PAGE( T, pageIndex ) static_cast<T*>( m_treebook->ResolvePage( pageIndex ) )
52
54 PAGED_DIALOG( aFrame, _( "Board Setup" ), false, false,
55 _( "Import Settings from Another Board..." ), wxSize( 980, 600 ) ),
56 m_frame( aFrame ),
57 m_layers( nullptr ),
58 m_boardFinish( 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 {
104 }, _( "Physical Stackup" ) );
105
106 m_boardFinishPage = m_treebook->GetPageCount();
108 [this]( wxWindow* aParent ) -> wxWindow*
109 {
110 return new PANEL_SETUP_BOARD_FINISH( aParent, m_frame );
111 }, _( "Board Finish" ) );
112
113 m_maskAndPagePage = m_treebook->GetPageCount();
115 [this]( wxWindow* aParent ) -> wxWindow*
116 {
117 return new PANEL_SETUP_MASK_AND_PASTE( aParent, m_frame );
118 }, _( "Solder Mask/Paste" ) );
119
120 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Text & Graphics" ) );
121
122 m_textAndGraphicsPage = m_treebook->GetPageCount();
124 [this]( wxWindow* aParent ) -> wxWindow*
125 {
126 return new PANEL_SETUP_TEXT_AND_GRAPHICS( aParent, m_frame );
127 }, _( "Defaults" ) );
128
129 m_formattingPage = m_treebook->GetPageCount();
131 [this]( wxWindow* aParent ) -> wxWindow*
132 {
133 return new PANEL_SETUP_FORMATTING( aParent, m_frame );
134 }, _( "Formatting" ) );
135
137 [this]( wxWindow* aParent ) -> wxWindow*
138 {
139 return new PANEL_TEXT_VARIABLES( aParent, &Prj() );
140 }, _( "Text Variables" ) );
141
142 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Design Rules" ) );
143
144 m_constraintsPage = m_treebook->GetPageCount();
146 [this]( wxWindow* aParent ) -> wxWindow*
147 {
148 return new PANEL_SETUP_CONSTRAINTS( aParent, m_frame );
149 }, _( "Constraints" ) );
150
151 m_tracksAndViasPage = m_treebook->GetPageCount();
153 [this]( wxWindow* aParent ) -> wxWindow*
154 {
155 return new PANEL_SETUP_TRACKS_AND_VIAS( aParent, m_frame );
156 }, _( "Pre-defined Sizes" ) );
157
158 m_teardropsPage = m_treebook->GetPageCount();
160 [this]( wxWindow* aParent ) -> wxWindow*
161 {
162 return new PANEL_SETUP_TEARDROPS( aParent, m_frame );
163 }, _( "Teardrops" ) );
164
165 m_tuningPatternsPage = m_treebook->GetPageCount();
167 [this]( wxWindow* aParent ) -> wxWindow*
168 {
170
171 return new PANEL_SETUP_TUNING_PATTERNS( aParent, m_frame,
175 }, _( "Length-tuning Patterns" ) );
176
177 m_netclassesPage = m_treebook->GetPageCount();
179 [this]( wxWindow* aParent ) -> wxWindow*
180 {
181 BOARD* board = m_frame->GetBoard();
182 return new PANEL_SETUP_NETCLASSES( aParent, m_frame,
185 false );
186 }, _( "Net Classes" ) );
187
188 m_customRulesPage = m_treebook->GetPageCount();
190 [this]( wxWindow* aParent ) -> wxWindow*
191 {
192 return new PANEL_SETUP_RULES( aParent, m_frame );
193 }, _( "Custom Rules" ) );
194
195 m_severitiesPage = m_treebook->GetPageCount();
197 [this]( wxWindow* aParent ) -> wxWindow*
198 {
199 BOARD* board = m_frame->GetBoard();
202 }, _( "Violation Severity" ) );
203
204 m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Board Data" ) );
205 m_embeddedFilesPage = m_treebook->GetPageCount();
207 [this]( wxWindow* aParent ) -> wxWindow*
208 {
209 return new PANEL_EMBEDDED_FILES( aParent, m_frame->GetBoard() );
210 }, _( "Embedded Files" ) );
211
212 for( size_t i = 0; i < m_treebook->GetPageCount(); ++i )
213 m_treebook->ExpandNode( i );
214
215 SetEvtHandlerEnabled( true );
216
218
219 if( Prj().IsReadOnly() )
220 {
221 m_infoBar->ShowMessage( _( "Project is missing or read-only. Some settings will not "
222 "be editable." ), wxICON_WARNING );
223 }
224
225 wxBookCtrlEvent evt( wxEVT_TREEBOOK_PAGE_CHANGED, wxID_ANY, 0 );
226
227 wxQueueEvent( m_treebook, evt.Clone() );
228}
229
230
232{
233}
234
235
236void DIALOG_BOARD_SETUP::onPageChanged( wxBookCtrlEvent& aEvent )
237{
239
240 size_t page = aEvent.GetSelection();
241
242 if( m_physicalStackupPage > 0 ) // Don't run this during initialization
243 {
245 {
248 }
249
250 // Ensure layer page always gets updated even if we aren't moving towards it
253
254 if( page == m_physicalStackupPage )
256 else if( Prj().IsReadOnly() )
257 KIUI::Disable( m_treebook->GetPage( page ) );
258 }
259
260 m_currentPage = page;
261}
262
263
264void DIALOG_BOARD_SETUP::onAuxiliaryAction( wxCommandEvent& aEvent )
265{
266 DIALOG_IMPORT_SETTINGS importDlg( this, m_frame );
267
268 if( importDlg.ShowModal() == wxID_CANCEL )
269 return;
270
271 wxFileName boardFn( importDlg.GetFilePath() );
272 wxFileName projectFn( boardFn );
273
274 projectFn.SetExt( FILEEXT::ProjectFileExtension );
275
276 if( !m_frame->GetSettingsManager()->LoadProject( projectFn.GetFullPath(), false ) )
277 {
278 wxString msg = wxString::Format( _( "Error importing settings from board:\n"
279 "Associated project file %s could not be loaded" ),
280 projectFn.GetFullPath() );
281 DisplayErrorMessage( this, msg );
282
283 return;
284 }
285
289
290 // Flag so user can stop work if it will result in deleted inner copper layers
291 // and still clean up this function properly.
292 bool okToProceed = true;
293
294 PROJECT* otherPrj = m_frame->GetSettingsManager()->GetProject( projectFn.GetFullPath() );
295
297 BOARD* otherBoard = nullptr;
298
299 try
300 {
301 WX_PROGRESS_REPORTER progressReporter( this, _( "Loading PCB" ), 1 );
302
303 pi->SetProgressReporter( &progressReporter );
304
305 otherBoard = pi->LoadBoard( boardFn.GetFullPath(), nullptr );
306
307 if( importDlg.m_LayersOpt->GetValue() )
308 {
309 BOARD* loadedBoard = m_frame->GetBoard();
310
311 // Check if "Import Settings" board has more layers than the current board.
312 okToProceed = m_layers->CheckCopperLayerCount( loadedBoard, otherBoard );
313 }
314 }
315 catch( const IO_ERROR& ioe )
316 {
317 // You wouldn't think boardFn.GetFullPath() would throw, but we get a stack buffer
318 // underflow from ASAN. While it's probably an ASAN error, a second try/catch doesn't
319 // cost us much.
320 try
321 {
322 if( ioe.Problem() != wxT( "CANCEL" ) )
323 {
324 wxString msg = wxString::Format( _( "Error loading board file:\n%s" ),
325 boardFn.GetFullPath() );
326 DisplayErrorMessage( this, msg, ioe.What() );
327 }
328
329 if( otherPrj != &m_frame->Prj() )
330 m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
331 }
332 catch(...)
333 {
334 // That was already our best-efforts
335 }
336
337 return;
338 }
339
340 if( okToProceed )
341 {
342 otherBoard->SetProject( otherPrj );
343
344 // If layers options are imported, import also the stackup
345 // layers options and stackup are linked, so they cannot be imported
346 // separately, and stackup can be imported only after layers options
347 if( importDlg.m_LayersOpt->GetValue() )
348 {
350 m_layers->ImportSettingsFrom( otherBoard );
351 m_boardFinish->ImportSettingsFrom( otherBoard );
352 }
353
354 if( importDlg.m_TextAndGraphicsOpt->GetValue() )
355 {
357 m_textAndGraphicsPage )->ImportSettingsFrom( otherBoard );
358 }
359
360 if( importDlg.m_FormattingOpt->GetValue() )
361 {
363 m_formattingPage )->ImportSettingsFrom( otherBoard );
364 }
365
366 if( importDlg.m_ConstraintsOpt->GetValue() )
367 {
369 m_constraintsPage )->ImportSettingsFrom( otherBoard );
370 }
371
372 if( importDlg.m_NetclassesOpt->GetValue() )
373 {
374 PROJECT_FILE& otherProjectFile = otherPrj->GetProjectFile();
375
377 m_netclassesPage )->ImportSettingsFrom( otherProjectFile.m_NetSettings );
378 }
379
380 if( importDlg.m_TracksAndViasOpt->GetValue() )
381 {
383 m_tracksAndViasPage )->ImportSettingsFrom( otherBoard );
384 }
385
386 if( importDlg.m_TeardropsOpt->GetValue() )
387 {
389 m_teardropsPage )->ImportSettingsFrom( otherBoard );
390 }
391
392 if( importDlg.m_TuningPatternsOpt->GetValue() )
393 {
395 m_tuningPatternsPage )->ImportSettingsFrom( otherBoard );
396 }
397
398 if( importDlg.m_MaskAndPasteOpt->GetValue() )
399 {
401 m_maskAndPagePage )->ImportSettingsFrom( otherBoard );
402 }
403
404 if( importDlg.m_CustomRulesOpt->GetValue() )
405 {
407 m_customRulesPage )->ImportSettingsFrom( otherBoard );
408 }
409
410 if( importDlg.m_SeveritiesOpt->GetValue() )
411 {
412 BOARD_DESIGN_SETTINGS& otherSettings = otherBoard->GetDesignSettings();
413
415 m_severitiesPage )->ImportSettingsFrom( otherSettings.m_DRCSeverities );
416 }
417
418 if( otherPrj != &m_frame->Prj() )
419 otherBoard->ClearProject();
420 }
421
422 // Clean up and free memory before leaving
423 if( otherPrj != &m_frame->Prj() )
424 m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
425
426 delete otherBoard;
427}
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:290
std::set< wxString > GetNetClassAssignmentCandidates() const
Return the set of netname candidates for netclass assignment.
Definition: board.cpp:2028
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition: board.cpp:197
void ClearProject()
Definition: board.cpp:235
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:892
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
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...
int ShowModal() override
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities()
Definition: drc_item.h:130
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:69
@ 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:72
std::shared_ptr< NET_SETTINGS > & NetSettings()
Definition: project_file.h:103
std::shared_ptr< NET_SETTINGS > m_NetSettings
Net settings for this project (owned here)
Definition: project_file.h:178
Container for project specific data.
Definition: project.h:64
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:200
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.