KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_edit_frame.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) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright (C) 2013 Wayne Stambaugh <[email protected]>
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software: you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include <advanced_config.h>
25#include <kiface_base.h>
26#include <kiway.h>
28#include <pgm_base.h>
29#include <pcb_edit_frame.h>
32#include <fp_lib_table.h>
34#include <bitmaps.h>
35#include <confirm.h>
36#include <lset.h>
37#include <trace_helpers.h>
38#include <algorithm>
39#include <type_traits>
40#include <unordered_map>
41#include <unordered_set>
42#include <vector>
43#include <pcbnew_id.h>
44#include <pcbnew_settings.h>
47#include <dialog_find.h>
50#include <dialog_board_setup.h>
54#include <pcb_target.h>
55#include <pcb_point.h>
56#include <layer_pairs.h>
59#include <functional>
60#include <pcb_painter.h>
63#include <python_scripting.h>
66#include <tool/tool_manager.h>
68#include <tool/action_toolbar.h>
69#include <tool/common_control.h>
70#include <tool/common_tools.h>
71#include <tool/embed_tool.h>
73#include <tool/selection.h>
74#include <tool/zoom_tool.h>
75#include <tools/array_tool.h>
80#include <tools/edit_tool.h>
84#include <tools/drc_tool.h>
86#include <tools/convert_tool.h>
87#include <tools/drawing_tool.h>
88#include <tools/pcb_control.h>
96#include <tools/pad_tool.h>
101#include <router/router_tool.h>
105#include <wx/socket.h>
106#include <wx/wupdlock.h>
107#include <dialog_drc.h> // for DIALOG_DRC_WINDOW_NAME definition
112#include <widgets/wx_infobar.h>
116#include <widgets/wx_aui_utils.h>
117#include <kiplatform/app.h>
118#include <kiplatform/ui.h>
119#include <core/profile.h>
120#include <math/box2_minmax.h>
124#include <toolbars_pcb_editor.h>
125#include <wx/log.h>
126
127#ifdef KICAD_IPC_API
128#include <api/api_server.h>
129#include <api/api_handler_pcb.h>
131#include <api/api_utils.h>
132#endif
133
134#include <action_plugin.h>
136#include "../scripting/python_scripting.h"
137
138#include <wx/filedlg.h>
139
140using namespace std::placeholders;
141
142
143#define INSPECT_DRC_ERROR_DIALOG_NAME wxT( "InspectDrcErrorDialog" )
144#define INSPECT_CLEARANCE_DIALOG_NAME wxT( "InspectClearanceDialog" )
145#define INSPECT_CONSTRAINTS_DIALOG_NAME wxT( "InspectConstraintsDialog" )
146#define FOOTPRINT_DIFF_DIALOG_NAME wxT( "FootprintDiffDialog" )
147
148
149BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
152
155
156 EVT_SIZE( PCB_EDIT_FRAME::OnSize )
157
158 // Menu Files:
161
162 EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit )
163 EVT_MENU( wxID_CLOSE, PCB_EDIT_FRAME::OnQuit )
164
165 // Horizontal toolbar
168
169 // Tracks and vias sizes general options
171 PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event )
172
173 // User interface update event handlers.
174 EVT_UPDATE_UI( ID_AUX_TOOLBAR_PCB_TRACK_WIDTH, PCB_EDIT_FRAME::OnUpdateSelectTrackWidth )
175 EVT_UPDATE_UI( ID_AUX_TOOLBAR_PCB_VIA_SIZE, PCB_EDIT_FRAME::OnUpdateSelectViaSize )
177 PCB_EDIT_FRAME::OnUpdateSelectTrackWidth )
179 PCB_EDIT_FRAME::OnUpdateSelectViaSize )
180 // Drop files event
181 EVT_DROP_FILES( PCB_EDIT_FRAME::OnDropFiles )
182END_EVENT_TABLE()
183
184
185PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
186 PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB_EDITOR, _( "PCB Editor" ),
187 wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE,
189 m_exportNetlistAction( nullptr ),
190 m_findDialog( nullptr ),
191 m_inspectDrcErrorDlg( nullptr ),
192 m_inspectClearanceDlg( nullptr ),
193 m_inspectConstraintsDlg( nullptr ),
194 m_footprintDiffDlg( nullptr ),
195 m_boardSetupDlg( nullptr ),
196 m_designBlocksPane( nullptr ),
197 m_importProperties( nullptr ),
198 m_eventCounterTimer( nullptr )
199{
200 m_maximizeByDefault = true;
201 m_showBorderAndTitleBlock = true; // true to display sheet references
202 m_SelTrackWidthBox = nullptr;
203 m_SelViaSizeBox = nullptr;
204 m_show_layer_manager_tools = true;
205 m_supportsAutoSave = true;
206 m_probingSchToPcb = false;
207 m_show_search = false;
208 m_show_net_inspector = false;
209 // Ensure timer has an owner before binding so it generates events.
210 m_crossProbeFlashTimer.SetOwner( this );
211 Bind( wxEVT_TIMER, &PCB_EDIT_FRAME::OnCrossProbeFlashTimer, this, m_crossProbeFlashTimer.GetId() );
212
213 // We don't know what state board was in when it was last saved, so we have to
214 // assume dirty
215 m_ZoneFillsDirty = true;
216
217 m_aboutTitle = _HKI( "KiCad PCB Editor" );
218
219 // Must be created before the menus are created.
220 if( ADVANCED_CFG::GetCfg().m_ShowPcbnewExportNetlist )
221 {
222 m_exportNetlistAction = new TOOL_ACTION( "pcbnew.EditorControl.exportNetlist",
223 AS_GLOBAL, 0, "", _( "Netlist..." ),
224 _( "Export netlist used to update schematics" ) );
225 }
226
227 // Create GAL canvas
228 auto canvas = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_frameSize,
229 GetGalDisplayOptions(),
231
232 SetCanvas( canvas );
233 SetBoard( new BOARD() );
234
235 wxIcon icon;
236 wxIconBundle icon_bundle;
237
238 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew, 48 ) );
239 icon_bundle.AddIcon( icon );
240 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew, 128 ) );
241 icon_bundle.AddIcon( icon );
242 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew, 256 ) );
243 icon_bundle.AddIcon( icon );
244 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew_32 ) );
245 icon_bundle.AddIcon( icon );
246 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew_16 ) );
247 icon_bundle.AddIcon( icon );
248
249 SetIcons( icon_bundle );
250
251 // LoadSettings() *after* creating m_LayersManager, because LoadSettings()
252 // initialize parameters in m_LayersManager
253 LoadSettings( config() );
254
255 SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU( pcbIUScale.IU_PER_MILS ) ) );
256
257 // PCB drawings start in the upper left corner.
258 GetScreen()->m_Center = false;
259
260 setupTools();
261 setupUIConditions();
262
263 m_toolbarSettings = GetToolbarSettings<PCB_EDIT_TOOLBAR_SETTINGS>( "pcbnew-toolbars" );
264 configureToolbars();
265 RecreateToolbars();
266 PrepareLayerIndicator( true );
267
268 ReCreateMenuBar();
269
270#ifdef KICAD_IPC_API
272 &PCB_EDIT_FRAME::onPluginAvailabilityChanged, this );
273#endif
274
275 // Fetch a COPY of the config as a lot of these initializations are going to overwrite our
276 // data.
277 PCBNEW_SETTINGS::AUI_PANELS aui_cfg = GetPcbNewSettings()->m_AuiPanels;
278
279 m_propertiesPanel = new PCB_PROPERTIES_PANEL( this, this );
280 m_propertiesPanel->SetSplitterProportion( aui_cfg.properties_splitter );
281
282 m_selectionFilterPanel = new PANEL_SELECTION_FILTER( this );
283
284 m_appearancePanel = new APPEARANCE_CONTROLS( this, GetCanvas() );
285 m_searchPane = new PCB_SEARCH_PANE( this );
286 m_netInspectorPanel = new PCB_NET_INSPECTOR_PANEL( this, this );
287 m_designBlocksPane = new PCB_DESIGN_BLOCK_PANE( this, nullptr, m_designBlockHistoryList );
288
289 m_auimgr.SetManagedWindow( this );
290
291 CreateInfoBar();
292
293 unsigned int auiFlags = wxAUI_MGR_DEFAULT;
294#if !defined( _WIN32 )
295 // Windows cannot redraw the UI fast enough during a live resize and may lead to all kinds
296 // of graphical glitches.
297 auiFlags |= wxAUI_MGR_LIVE_RESIZE;
298#endif
299 m_auimgr.SetFlags( auiFlags );
300
301 // Rows; layers 4 - 6
302 m_auimgr.AddPane( m_tbTopMain, EDA_PANE().HToolbar().Name( wxS( "TopMainToolbar" ) )
303 .Top().Layer( 6 ) );
304 m_auimgr.AddPane( m_tbTopAux, EDA_PANE().HToolbar().Name( wxS( "TopAuxToolbar" ) )
305 .Top().Layer( 5 ) );
306 m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( wxS( "MsgPanel" ) )
307 .Bottom().Layer( 6 ) );
308
309 // Columns; layers 1 - 3
310 m_auimgr.AddPane( m_tbLeft, EDA_PANE().VToolbar().Name( wxS( "LeftToolbar" ) )
311 .Left().Layer( 3 ) );
312
313 m_auimgr.AddPane( m_tbRight, EDA_PANE().VToolbar().Name( wxS( "RightToolbar" ) )
314 .Right().Layer( 3 ) );
315
316 m_auimgr.AddPane( m_appearancePanel, EDA_PANE().Name( wxS( "LayersManager" ) )
317 .Right().Layer( 4 )
318 .Caption( _( "Appearance" ) ).PaneBorder( false )
319 .MinSize( m_appearancePanel->GetMinSize().x, -1 )
320#ifdef __WXMAC__
321 // Best size for this pane is calculated larger than necessary on wxMac
322 .BestSize( m_appearancePanel->GetMinSize().x, -1 )
323#else
324 .BestSize( m_appearancePanel->GetBestSize().x, -1 )
325#endif
326 .FloatingSize( m_appearancePanel->GetBestSize() )
327 .CloseButton( false ) );
328
329 m_auimgr.AddPane( m_selectionFilterPanel, EDA_PANE().Name( wxS( "SelectionFilter" ) )
330 .Right().Layer( 4 ).Position( 2 )
331 .Caption( _( "Selection Filter" ) ).PaneBorder( false )
332 .MinSize( m_selectionFilterPanel->GetMinSize().x, -1 )
333 .BestSize( m_selectionFilterPanel->GetBestSize().x, -1 )
334 .FloatingSize( m_selectionFilterPanel->GetBestSize() )
335 .CloseButton( false ) );
336
337 m_auimgr.AddPane( m_designBlocksPane, EDA_PANE().Name( DesignBlocksPaneName() )
338 .Right().Layer( 5 )
339 .Caption( _( "Design Blocks" ) )
340 .CaptionVisible( true )
341 .PaneBorder( true )
342 .TopDockable( false )
343 .BottomDockable( false )
344 .CloseButton( true )
345 .MinSize( FromDIP( wxSize( 240, 60 ) ) )
346 .BestSize( FromDIP( wxSize( 300, 200 ) ) )
347 .FloatingSize( FromDIP( wxSize( 800, 600 ) ) )
348 .FloatingPosition( FromDIP( wxPoint( 50, 200 ) ) )
349 .Show( true ) );
350
351 m_auimgr.AddPane( m_propertiesPanel, EDA_PANE().Name( PropertiesPaneName() )
352 .Left().Layer( 5 )
353 .Caption( _( "Properties" ) ).PaneBorder( false )
354 .MinSize( FromDIP( wxSize( 240, 60 ) ) )
355 .BestSize( FromDIP( wxSize( 300, 200 ) ) )
356 .FloatingSize( wxSize( 300, 200 ) )
357 .CloseButton( true ) );
358
359 // Center
360 m_auimgr.AddPane( GetCanvas(), EDA_PANE().Canvas().Name( wxS( "DrawFrame" ) )
361 .Center() );
362
363 m_auimgr.AddPane( m_netInspectorPanel, EDA_PANE().Name( NetInspectorPanelName() )
364 .Bottom()
365 .Caption( _( "Net Inspector" ) )
366 .PaneBorder( false )
367 .MinSize( FromDIP( wxSize( 240, 60 ) ) )
368 .BestSize( FromDIP( wxSize( 300, 200 ) ) )
369 .FloatingSize( wxSize( 300, 200 ) )
370 .CloseButton( true ) );
371
372 m_auimgr.AddPane( m_searchPane, EDA_PANE().Name( SearchPaneName() )
373 .Bottom()
374 .Caption( _( "Search" ) ).PaneBorder( false )
375 .MinSize( FromDIP( wxSize ( 180, 60 ) ) )
376 .BestSize( FromDIP( wxSize ( 180, 100 ) ) )
377 .FloatingSize( FromDIP( wxSize( 480, 200 ) ) )
378 .DestroyOnClose( false )
379 .CloseButton( true ) );
380
381
382 m_auimgr.GetPane( "LayersManager" ).Show( m_show_layer_manager_tools );
383 m_auimgr.GetPane( "SelectionFilter" ).Show( m_show_layer_manager_tools );
384 m_auimgr.GetPane( PropertiesPaneName() ).Show( GetPcbNewSettings()->m_AuiPanels.show_properties );
385 m_auimgr.GetPane( NetInspectorPanelName() ).Show( m_show_net_inspector );
386 m_auimgr.GetPane( SearchPaneName() ).Show( m_show_search );
387 m_auimgr.GetPane( DesignBlocksPaneName() ).Show( GetPcbNewSettings()->m_AuiPanels.design_blocks_show );
388
389 // The selection filter doesn't need to grow in the vertical direction when docked
390 m_auimgr.GetPane( "SelectionFilter" ).dock_proportion = 0;
391
392 FinishAUIInitialization();
393
394 if( aui_cfg.right_panel_width > 0 )
395 {
396 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( wxS( "LayersManager" ) );
397 SetAuiPaneSize( m_auimgr, layersManager, aui_cfg.right_panel_width, -1 );
398
399 wxAuiPaneInfo& designBlocksPane = m_auimgr.GetPane( DesignBlocksPaneName() );
400 SetAuiPaneSize( m_auimgr, designBlocksPane, aui_cfg.design_blocks_panel_docked_width, -1 );
401 }
402
403 if( aui_cfg.properties_panel_width > 0 && m_propertiesPanel )
404 {
405 wxAuiPaneInfo& propertiesPanel = m_auimgr.GetPane( PropertiesPaneName() );
406 SetAuiPaneSize( m_auimgr, propertiesPanel, aui_cfg.properties_panel_width, -1 );
407 }
408
409 if( aui_cfg.search_panel_height > 0
410 && ( aui_cfg.search_panel_dock_direction == wxAUI_DOCK_TOP
411 || aui_cfg.search_panel_dock_direction == wxAUI_DOCK_BOTTOM ) )
412 {
413 wxAuiPaneInfo& searchPane = m_auimgr.GetPane( SearchPaneName() );
414 searchPane.Direction( aui_cfg.search_panel_dock_direction );
415 SetAuiPaneSize( m_auimgr, searchPane, -1, aui_cfg.search_panel_height );
416 }
417 else if( aui_cfg.search_panel_width > 0
418 && ( aui_cfg.search_panel_dock_direction == wxAUI_DOCK_LEFT
419 || aui_cfg.search_panel_dock_direction == wxAUI_DOCK_RIGHT ) )
420 {
421 wxAuiPaneInfo& searchPane = m_auimgr.GetPane( SearchPaneName() );
422 searchPane.Direction( aui_cfg.search_panel_dock_direction );
423 SetAuiPaneSize( m_auimgr, searchPane, aui_cfg.search_panel_width, -1 );
424 }
425
426 m_appearancePanel->SetTabIndex( aui_cfg.appearance_panel_tab );
427
428 {
429 m_layerPairSettings = std::make_unique<LAYER_PAIR_SETTINGS>();
430
431 m_layerPairSettings->Bind( PCB_LAYER_PAIR_PRESETS_CHANGED, [&]( wxCommandEvent& aEvt )
432 {
433 // Update the project file list
434 std::span<const LAYER_PAIR_INFO> newPairInfos = m_layerPairSettings->GetLayerPairs();
436 std::vector<LAYER_PAIR_INFO>{ newPairInfos.begin(), newPairInfos.end() };
437 });
438
439 m_layerPairSettings->Bind( PCB_CURRENT_LAYER_PAIR_CHANGED, [&]( wxCommandEvent& aEvt )
440 {
441 const LAYER_PAIR& layerPair = m_layerPairSettings->GetCurrentLayerPair();
442 PCB_SCREEN& screen = *GetScreen();
443
444 screen.m_Route_Layer_TOP = layerPair.GetLayerA();
445 screen.m_Route_Layer_BOTTOM = layerPair.GetLayerB();
446
447 // Update the toolbar icon
448 PrepareLayerIndicator();
449 });
450 }
451
452 GetToolManager()->PostAction( ACTIONS::zoomFitScreen );
453
454 // This is used temporarily to fix a client size issue on GTK that causes zoom to fit
455 // to calculate the wrong zoom size. See PCB_EDIT_FRAME::onSize().
456 Bind( wxEVT_SIZE, &PCB_EDIT_FRAME::onSize, this );
457
458 Bind( wxEVT_IDLE,
459 [this]( wxIdleEvent& aEvent )
460 {
461 BOX2D viewport = GetCanvas()->GetView()->GetViewport();
462
463 if( viewport != m_lastNetnamesViewport )
464 {
465 redrawNetnames();
466 m_lastNetnamesViewport = viewport;
467 }
468
469 // Do not forget to pass the Idle event to other clients:
470 aEvent.Skip();
471 } );
472
473 resolveCanvasType();
474
475 setupUnits( config() );
476
477 // Ensure the DRC engine is initialized so that constraints can be resolved even before a
478 // board is loaded or saved
479 try
480 {
481 m_toolManager->GetTool<DRC_TOOL>()->GetDRCEngine()->InitEngine( wxFileName() );
482 }
483 catch( PARSE_ERROR& )
484 {
485 }
486
487 // Ensure the Python interpreter is up to date with its environment variables
488 PythonSyncEnvironmentVariables();
489 PythonSyncProjectName();
490
491 // Sync action plugins in case they changed since the last time the frame opened
492 GetToolManager()->RunAction( ACTIONS::pluginsReload );
493
494#ifdef KICAD_IPC_API
495 m_apiHandler = std::make_unique<API_HANDLER_PCB>( this );
496 Pgm().GetApiServer().RegisterHandler( m_apiHandler.get() );
497
498 if( Kiface().IsSingle() )
499 {
500 m_apiHandlerCommon = std::make_unique<API_HANDLER_COMMON>();
501 Pgm().GetApiServer().RegisterHandler( m_apiHandlerCommon.get() );
502 }
503#endif
504
505 GetCanvas()->SwitchBackend( m_canvasType );
506 ActivateGalCanvas();
507
508 // Default shutdown reason until a file is loaded
509 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "New PCB file is unsaved" ) );
510
511 // disable Export STEP item if kicad2step does not exist
512 wxString strK2S = Pgm().GetExecutablePath();
513
514#ifdef __WXMAC__
515 if( strK2S.Find( wxT( "pcbnew.app" ) ) != wxNOT_FOUND )
516 {
517 // On macOS, we have standalone applications inside the main bundle, so we handle that here:
518 strK2S += wxT( "../../" );
519 }
520
521 strK2S += wxT( "Contents/MacOS/" );
522#endif
523
524 wxFileName appK2S( strK2S, wxT( "kicad2step" ) );
525
526#ifdef _WIN32
527 appK2S.SetExt( wxT( "exe" ) );
528#endif
529
530 // Ensure the window is on top
531 Raise();
532
533// if( !appK2S.FileExists() )
534 // GetMenuBar()->FindItem( ID_GEN_EXPORT_FILE_STEP )->Enable( false );
535
536 // AUI doesn't refresh properly on wxMac after changes in eb7dc6dd, so force it to
537#ifdef __WXMAC__
538 if( Kiface().IsSingle() )
539 {
540 CallAfter( [this]()
541 {
542 m_appearancePanel->OnBoardChanged();
543 } );
544 }
545#endif
546
547 // Register a call to update the toolbar sizes. It can't be done immediately because
548 // it seems to require some sizes calculated that aren't yet (at least on GTK).
549 CallAfter( [this]()
550 {
551 // Ensure the controls on the toolbars all are correctly sized
552 UpdateToolbarControlSizes();
553 } );
554
555 if( ADVANCED_CFG::GetCfg().m_ShowEventCounters )
556 {
557 m_eventCounterTimer = new wxTimer( this );
558
559 Bind( wxEVT_TIMER,
560 [&]( wxTimerEvent& aEvent )
561 {
562 GetCanvas()->m_PaintEventCounter->Show();
563 GetCanvas()->m_PaintEventCounter->Reset();
564
566 static_cast<KIGFX::WX_VIEW_CONTROLS*>( GetCanvas()->GetViewControls() );
569
570 },
571 m_eventCounterTimer->GetId() );
572
573 m_eventCounterTimer->Start( 1000 );
574 }
575
578 m_acceptedExts.emplace( wxS( "dxf" ), &PCB_ACTIONS::ddImportGraphics );
580 DragAcceptFiles( true );
581
582 Bind( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, &PCB_EDIT_FRAME::onCloseModelessBookReporterDialogs, this );
583}
584
585void PCB_EDIT_FRAME::StartCrossProbeFlash( const std::vector<BOARD_ITEM*>& aItems )
586{
587 if( !GetPcbNewSettings()->m_CrossProbing.flash_selection )
588 {
589 wxLogTrace( "CROSS_PROBE_FLASH", "StartCrossProbeFlash(PCB): aborted (setting disabled) items=%zu", aItems.size() );
590 return;
591 }
592
593 if( aItems.empty() )
594 {
595 wxLogTrace( "CROSS_PROBE_FLASH", "StartCrossProbeFlash(PCB): aborted (no items)" );
596 return;
597 }
598
600 {
601 wxLogTrace( "CROSS_PROBE_FLASH", "StartCrossProbeFlash(PCB): restarting existing flash (phase=%d)" , m_crossProbeFlashPhase );
603 }
604
605 wxLogTrace( "CROSS_PROBE_FLASH", "StartCrossProbeFlash(PCB): starting with %zu items", aItems.size() );
606 // Store uuids
608 for( BOARD_ITEM* it : aItems )
609 m_crossProbeFlashItems.push_back( it->m_Uuid );
610
613 if( !m_crossProbeFlashTimer.GetOwner() )
614 m_crossProbeFlashTimer.SetOwner( this );
615
616 bool started = m_crossProbeFlashTimer.Start( 500, wxTIMER_CONTINUOUS ); // 0.5s intervals -> 3s total for 6 phases
617 wxLogTrace( "CROSS_PROBE_FLASH", "StartCrossProbeFlash(PCB): timer start=%d id=%d", (int) started, m_crossProbeFlashTimer.GetId() );
618}
619
620void PCB_EDIT_FRAME::OnCrossProbeFlashTimer( wxTimerEvent& aEvent )
621{
622 wxLogTrace( "CROSS_PROBE_FLASH", "Timer(PCB) fired: phase=%d running=%d items=%zu", m_crossProbeFlashPhase, (int) m_crossProbeFlashing, m_crossProbeFlashItems.size() );
623
625 {
626 wxLogTrace( "CROSS_PROBE_FLASH", "Timer(PCB) fired but not flashing (ignored)" );
627 return;
628 }
629
631 if( !selTool )
632 return;
633
634 // Prevent recursion / IPC during flashing
635 bool prevGuard = m_probingSchToPcb;
636 m_probingSchToPcb = true;
637
638 if( m_crossProbeFlashPhase % 2 == 0 )
639 {
640 // Hide selection
641 selTool->ClearSelection( true );
642 wxLogTrace( "CROSS_PROBE_FLASH", "Phase %d (PCB): cleared selection", m_crossProbeFlashPhase );
643 }
644 else
645 {
646 // Restore selection
647 for( const KIID& id : m_crossProbeFlashItems )
648 {
649 if( EDA_ITEM* item = GetBoard()->ResolveItem( id, true ) )
650 selTool->AddItemToSel( item, true );
651 }
652 wxLogTrace( "CROSS_PROBE_FLASH", "Phase %d (PCB): restored %zu items", m_crossProbeFlashPhase, m_crossProbeFlashItems.size() );
653 }
654
655 // Force a redraw even if the canvas / frame does not currently have focus (mouse elsewhere)
656 if( GetCanvas() )
657 {
659 wxLogTrace( "CROSS_PROBE_FLASH", "Phase %d (PCB): forced canvas refresh", m_crossProbeFlashPhase );
660 }
661
662 m_probingSchToPcb = prevGuard;
663
665 if( m_crossProbeFlashPhase > 6 )
666 {
667 // Ensure final state (selected)
668 for( const KIID& id : m_crossProbeFlashItems )
669 {
670 if( EDA_ITEM* item = GetBoard()->ResolveItem( id, true ) )
671 selTool->AddItemToSel( item, true );
672 }
673 m_crossProbeFlashing = false;
675 wxLogTrace( "CROSS_PROBE_FLASH", "Flashing complete (PCB). Final selection size=%zu", m_crossProbeFlashItems.size() );
676 }
677}
678
679
681{
683
684 if( ADVANCED_CFG::GetCfg().m_ShowEventCounters )
685 {
686 // Stop the timer during destruction early to avoid potential event race conditions (that
687 // do happen on windows)
688 m_eventCounterTimer->Stop();
689 delete m_eventCounterTimer;
690 }
691
692 // Close modeless dialogs
693 wxWindow* open_dlg = wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME );
694
695 if( open_dlg )
696 open_dlg->Close( true );
697
698 // Shutdown all running tools
699 if( m_toolManager )
700 m_toolManager->ShutdownAllTools();
701
702 if( GetBoard() )
704
705 // We passed ownership of these to wxAuiManager.
706 // delete m_selectionFilterPanel;
707 // delete m_appearancePanel;
708 // delete m_propertiesPanel;
709 // delete m_netInspectorPanel;
710
712}
713
714
715void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard, bool aBuildConnectivity,
716 PROGRESS_REPORTER* aReporter )
717{
718 if( m_pcb )
719 m_pcb->ClearProject();
720
721 PCB_BASE_EDIT_FRAME::SetBoard( aBoard, aReporter );
722
723 aBoard->SetProject( &Prj() );
724
725 if( aBuildConnectivity )
726 aBoard->BuildConnectivity();
727
728 // reload the drawing-sheet
729 SetPageSettings( aBoard->GetPageSettings() );
730}
731
732
737
738
739std::unique_ptr<GRID_HELPER> PCB_EDIT_FRAME::MakeGridHelper()
740{
741 return std::make_unique<PCB_GRID_HELPER>( m_toolManager, GetMagneticItemsSettings() );
742}
743
744
746{
747 /*
748 * While new items being scrolled into the view will get painted, they will only get
749 * annotated with netname instances currently within the view. Subsequent panning will not
750 * draw newly-visible netname instances because the item has already been drawn.
751 *
752 * This routine, fired on idle if the viewport has changed, looks for visible items that
753 * might have multiple netname instances and redraws them. (It does not need to handle pads
754 * and vias because they only ever have a single netname instance drawn on them.)
755 */
756 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
757
758 if( !cfg || cfg->m_Display.m_NetNames < 2 )
759 return;
760
761 KIGFX::VIEW* view = GetCanvas()->GetView();
762 BOX2D viewport = view->GetViewport();
763
764 // Inflate to catch most of the track width
765 BOX2I_MINMAX clipbox( BOX2ISafe( viewport.Inflate( pcbIUScale.mmToIU( 2.0 ) ) ) );
766
767 for( PCB_TRACK* track : GetBoard()->Tracks() )
768 {
769 // Don't need to update vias
770 if( track->Type() == PCB_VIA_T )
771 continue;
772
773 // Don't update invisible tracks
774 if( !clipbox.Intersects( BOX2I_MINMAX( track->GetStart(), track->GetEnd() ) ) )
775 continue;
776
777 if( track->ViewGetLOD( GetNetnameLayer( track->GetLayer() ), view ) < view->GetScale() )
778 view->Update( track, KIGFX::REPAINT );
779 }
780}
781
782
783void PCB_EDIT_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
784{
785 PCB_BASE_FRAME::SetPageSettings( aPageSettings );
786
787 // Prepare drawing-sheet template
789 &m_pcb->GetPageSettings(),
790 m_pcb->GetProject(),
791 &m_pcb->GetTitleBlock(),
792 &m_pcb->GetProperties() );
793
794 drawingSheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) );
795 drawingSheet->SetSheetPath( std::string( GetFullScreenDesc().mb_str() ) );
796
797 // A board is not like a schematic having a main page and sub sheets.
798 // So for the drawing sheet, use only the first page option to display items
799 drawingSheet->SetIsFirstPage( true );
800
801 BASE_SCREEN* screen = GetScreen();
802
803 if( screen != nullptr )
804 {
805 drawingSheet->SetPageNumber(TO_UTF8( screen->GetPageNumber() ) );
806 drawingSheet->SetSheetCount( screen->GetPageCount() );
807 }
808
809 if( BOARD* board = GetBoard() )
810 drawingSheet->SetFileName( TO_UTF8( board->GetFileName() ) );
811
812 // PCB_DRAW_PANEL_GAL takes ownership of the drawing-sheet
813 GetCanvas()->SetDrawingSheet( drawingSheet );
814}
815
816
818{
819 return GetScreen() && GetScreen()->IsContentModified();
820}
821
822
824{
825 return m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
826}
827
828
830{
831 // Create the manager and dispatcher & route draw panel events to the dispatcher
833 m_toolManager->SetEnvironment( m_pcb, GetCanvas()->GetView(),
834 GetCanvas()->GetViewControls(), config(), this );
835 m_actions = new PCB_ACTIONS();
837
838 // Register tools
839 m_toolManager->RegisterTool( new COMMON_CONTROL );
840 m_toolManager->RegisterTool( new COMMON_TOOLS );
841 m_toolManager->RegisterTool( new PCB_SELECTION_TOOL );
842 m_toolManager->RegisterTool( new ZOOM_TOOL );
843 m_toolManager->RegisterTool( new PCB_PICKER_TOOL );
844 m_toolManager->RegisterTool( new ROUTER_TOOL );
845 m_toolManager->RegisterTool( new EDIT_TOOL );
846 m_toolManager->RegisterTool( new PCB_EDIT_TABLE_TOOL );
847 m_toolManager->RegisterTool( new GLOBAL_EDIT_TOOL );
848 m_toolManager->RegisterTool( new PAD_TOOL );
849 m_toolManager->RegisterTool( new DRAWING_TOOL );
850 m_toolManager->RegisterTool( new PCB_POINT_EDITOR );
851 m_toolManager->RegisterTool( new PCB_CONTROL );
852 m_toolManager->RegisterTool( new PCB_DESIGN_BLOCK_CONTROL );
853 m_toolManager->RegisterTool( new BOARD_EDITOR_CONTROL );
854 m_toolManager->RegisterTool( new BOARD_INSPECTION_TOOL );
855 m_toolManager->RegisterTool( new BOARD_REANNOTATE_TOOL );
856 m_toolManager->RegisterTool( new ALIGN_DISTRIBUTE_TOOL );
857 m_toolManager->RegisterTool( new MICROWAVE_TOOL );
858 m_toolManager->RegisterTool( new POSITION_RELATIVE_TOOL );
859 m_toolManager->RegisterTool( new ARRAY_TOOL );
860 m_toolManager->RegisterTool( new ZONE_FILLER_TOOL );
861 m_toolManager->RegisterTool( new AUTOPLACE_TOOL );
862 m_toolManager->RegisterTool( new DRC_TOOL );
863 m_toolManager->RegisterTool( new PCB_VIEWER_TOOLS );
864 m_toolManager->RegisterTool( new CONVERT_TOOL );
865 m_toolManager->RegisterTool( new PCB_GROUP_TOOL );
866 m_toolManager->RegisterTool( new GENERATOR_TOOL );
867 m_toolManager->RegisterTool( new SCRIPTING_TOOL );
868 m_toolManager->RegisterTool( new PROPERTIES_TOOL );
869 m_toolManager->RegisterTool( new MULTICHANNEL_TOOL );
870 m_toolManager->RegisterTool( new EMBED_TOOL );
871 m_toolManager->InitTools();
872
873 for( TOOL_BASE* tool : m_toolManager->Tools() )
874 {
875 if( PCB_TOOL_BASE* pcbTool = dynamic_cast<PCB_TOOL_BASE*>( tool ) )
876 pcbTool->SetIsBoardEditor( true );
877 }
878
879 // Run the selection tool, it is supposed to be always active
880 m_toolManager->InvokeTool( "common.InteractiveSelection" );
881}
882
883
885{
887
888 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
889 PCB_EDITOR_CONDITIONS cond( this );
890
891 auto undoCond =
892 [ this ] (const SELECTION& aSel )
893 {
894 DRAWING_TOOL* drawingTool = m_toolManager->GetTool<DRAWING_TOOL>();
895
896 if( drawingTool && drawingTool->GetDrawingMode() != DRAWING_TOOL::MODE::NONE )
897 return true;
898
899 ROUTER_TOOL* routerTool = m_toolManager->GetTool<ROUTER_TOOL>();
900
901 if( routerTool && routerTool->RoutingInProgress() )
902 return true;
903
904 return GetUndoCommandCount() > 0;
905 };
906
907 auto groupWithDesignBlockLink =
908 [] ( const SELECTION& aSel )
909 {
910 if( aSel.Size() != 1 )
911 return false;
912
913 if( aSel[0]->Type() != PCB_GROUP_T )
914 return false;
915
916 PCB_GROUP* group = static_cast<PCB_GROUP*>( aSel.GetItem( 0 ) );
917
918 return group->HasDesignBlockLink();
919 };
920
921 wxASSERT( mgr );
922
923#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
924#define CHECK( x ) ACTION_CONDITIONS().Check( x )
925// clang-format off
926
928 mgr->SetConditions( ACTIONS::undo, ENABLE( undoCond ) );
930
940
941 mgr->SetConditions( ACTIONS::cut, ENABLE( cond.HasItems() ) );
942 mgr->SetConditions( ACTIONS::copy, ENABLE( cond.HasItems() ) );
949
950 static const std::vector<KICAD_T> groupTypes = { PCB_GROUP_T, PCB_GENERATOR_T };
951
956
957 mgr->SetConditions( PCB_ACTIONS::placeLinkedDesignBlock, ENABLE( groupWithDesignBlockLink) );
958 mgr->SetConditions( PCB_ACTIONS::saveToLinkedDesignBlock, ENABLE( groupWithDesignBlockLink) );
959
965
966 if( SCRIPTING::IsWxAvailable() )
968
969 auto enableZoneControlCondition =
970 [this] ( const SELECTION& )
971 {
974 };
975
977 ENABLE( enableZoneControlCondition )
980 ENABLE( enableZoneControlCondition )
983 ENABLE( enableZoneControlCondition )
986 ENABLE( enableZoneControlCondition )
988
990
991 auto hasElements =
992 [ this ] ( const SELECTION& aSel )
993 {
994 return GetBoard() &&
995 ( !GetBoard()->IsEmpty() || !SELECTION_CONDITIONS::Idle( aSel ) );
996 };
997
998 auto constrainedDrawingModeCond =
999 [this]( const SELECTION& )
1000 {
1002 };
1003
1004 auto boardFlippedCond =
1005 [this]( const SELECTION& )
1006 {
1007 return GetCanvas() && GetCanvas()->GetView()->IsMirroredX();
1008 };
1009
1010 auto layerManagerCond =
1011 [this] ( const SELECTION& )
1012 {
1013 return LayerManagerShown();
1014 };
1015
1016 auto propertiesCond =
1017 [this] ( const SELECTION& )
1018 {
1019 return PropertiesShown();
1020 };
1021
1022 auto netInspectorCond =
1023 [this] ( const SELECTION& )
1024 {
1025 return NetInspectorShown();
1026 };
1027
1028 auto searchPaneCond =
1029 [this] ( const SELECTION& )
1030 {
1031 return m_auimgr.GetPane( SearchPaneName() ).IsShown();
1032 };
1033
1034 auto designBlockCond =
1035 [ this ] (const SELECTION& aSel )
1036 {
1037 return m_auimgr.GetPane( DesignBlocksPaneName() ).IsShown();
1038 };
1039
1040 auto highContrastCond =
1041 [this] ( const SELECTION& )
1042 {
1044 };
1045
1046 auto globalRatsnestCond =
1047 [this] (const SELECTION& )
1048 {
1050 };
1051
1052 auto curvedRatsnestCond =
1053 [this] (const SELECTION& )
1054 {
1056 };
1057
1058 auto netHighlightCond =
1059 [this]( const SELECTION& )
1060 {
1062 return !settings->GetHighlightNetCodes().empty();
1063 };
1064
1065 auto enableNetHighlightCond =
1066 [this]( const SELECTION& )
1067 {
1069 return tool && tool->IsNetHighlightSet();
1070 };
1071
1072 mgr->SetConditions( PCB_ACTIONS::toggleHV45Mode, CHECK( constrainedDrawingModeCond ) );
1073 mgr->SetConditions( ACTIONS::highContrastMode, CHECK( highContrastCond ) );
1074 mgr->SetConditions( PCB_ACTIONS::flipBoard, CHECK( boardFlippedCond ) );
1075 mgr->SetConditions( PCB_ACTIONS::showLayersManager, CHECK( layerManagerCond ) );
1076 mgr->SetConditions( PCB_ACTIONS::showRatsnest, CHECK( globalRatsnestCond ) );
1077 mgr->SetConditions( PCB_ACTIONS::ratsnestLineMode, CHECK( curvedRatsnestCond ) );
1078 mgr->SetConditions( PCB_ACTIONS::toggleNetHighlight, CHECK( netHighlightCond )
1079 .Enable( enableNetHighlightCond ) );
1080 mgr->SetConditions( ACTIONS::showProperties, CHECK( propertiesCond ) );
1081 mgr->SetConditions( PCB_ACTIONS::showNetInspector, CHECK( netInspectorCond ) );
1082 mgr->SetConditions( PCB_ACTIONS::showSearch, CHECK( searchPaneCond ) );
1083 mgr->SetConditions( PCB_ACTIONS::showDesignBlockPanel, CHECK( designBlockCond ) );
1084
1087
1088 const auto isArcKeepCenterMode =
1089 [this]( const SELECTION& )
1090 {
1092 };
1093
1094 const auto isArcKeepEndpointMode =
1095 [this]( const SELECTION& )
1096 {
1098 };
1099
1100 const auto isArcKeepRadiusMode =
1101 [this]( const SELECTION& )
1102 {
1104 };
1105
1106 mgr->SetConditions( ACTIONS::pointEditorArcKeepCenter, CHECK( isArcKeepCenterMode ) );
1107 mgr->SetConditions( ACTIONS::pointEditorArcKeepEndpoint, CHECK( isArcKeepEndpointMode ) );
1108 mgr->SetConditions( ACTIONS::pointEditorArcKeepRadius, CHECK( isArcKeepRadiusMode ) );
1109
1110 auto isHighlightMode =
1111 [this]( const SELECTION& )
1112 {
1113 ROUTER_TOOL* tool = m_toolManager->GetTool<ROUTER_TOOL>();
1114 return tool && tool->GetRouterMode() == PNS::RM_MarkObstacles;
1115 };
1116
1117 auto isShoveMode =
1118 [this]( const SELECTION& )
1119 {
1120 ROUTER_TOOL* tool = m_toolManager->GetTool<ROUTER_TOOL>();
1121 return tool && tool->GetRouterMode() == PNS::RM_Shove;
1122 };
1123
1124 auto isWalkaroundMode =
1125 [this]( const SELECTION& )
1126 {
1127 ROUTER_TOOL* tool = m_toolManager->GetTool<ROUTER_TOOL>();
1128 return tool && tool->GetRouterMode() == PNS::RM_Walkaround;
1129 };
1130
1131 mgr->SetConditions( PCB_ACTIONS::routerHighlightMode, CHECK( isHighlightMode ) );
1132 mgr->SetConditions( PCB_ACTIONS::routerShoveMode, CHECK( isShoveMode ) );
1133 mgr->SetConditions( PCB_ACTIONS::routerWalkaroundMode, CHECK( isWalkaroundMode ) );
1134
1135 auto isAutoTrackWidth =
1136 [this]( const SELECTION& )
1137 {
1139 };
1140
1141 mgr->SetConditions( PCB_ACTIONS::autoTrackWidth, CHECK( isAutoTrackWidth ) );
1142
1143 auto haveNetCond =
1144 [] ( const SELECTION& aSel )
1145 {
1146 for( EDA_ITEM* item : aSel )
1147 {
1148 if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
1149 {
1150 if( bci->GetNetCode() > 0 )
1151 return true;
1152 }
1153 }
1154
1155 return false;
1156 };
1157
1158 mgr->SetConditions( PCB_ACTIONS::showNetInRatsnest, ENABLE( haveNetCond ) );
1159 mgr->SetConditions( PCB_ACTIONS::hideNetInRatsnest, ENABLE( haveNetCond ) );
1162
1163 static const std::vector<KICAD_T> trackTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T };
1164 static const std::vector<KICAD_T> padOwnerTypes = { PCB_FOOTPRINT_T, PCB_PAD_T };
1165 static const std::vector<KICAD_T> footprintTypes = { PCB_FOOTPRINT_T };
1166 static const std::vector<KICAD_T> crossProbeTypes = { PCB_PAD_T, PCB_FOOTPRINT_T, PCB_GROUP_T };
1167 static const std::vector<KICAD_T> zoneTypes = { PCB_ZONE_T };
1168
1174
1175
1177 && SELECTION_CONDITIONS::OnlyTypes( zoneTypes );
1178
1180 && SELECTION_CONDITIONS::OnlyTypes( zoneTypes );
1181
1182 mgr->SetConditions( PCB_ACTIONS::zoneDuplicate, ENABLE( singleZoneCond ) );
1183 mgr->SetConditions( PCB_ACTIONS::drawZoneCutout, ENABLE( singleZoneCond ) );
1184 mgr->SetConditions( PCB_ACTIONS::drawSimilarZone, ENABLE( singleZoneCond ) );
1185 mgr->SetConditions( PCB_ACTIONS::zoneMerge, ENABLE( zoneMergeCond ) );
1186
1188
1189#define CURRENT_TOOL( action ) mgr->SetConditions( action, CHECK( cond.CurrentTool( action ) ) )
1190
1191 // These tools can be used at any time to inspect the board
1196
1197 auto isDRCIdle =
1198 [this] ( const SELECTION& )
1199 {
1200 DRC_TOOL* tool = m_toolManager->GetTool<DRC_TOOL>();
1201 return !( tool && tool->IsDRCRunning() );
1202 };
1203
1204#define CURRENT_EDIT_TOOL( action ) \
1205 mgr->SetConditions( action, ACTION_CONDITIONS().Check( cond.CurrentTool( action ) ) \
1206 .Enable( isDRCIdle ) )
1207
1208 // These tools edit the board, so they must be disabled during some operations
1240
1246
1247#undef CURRENT_TOOL
1248#undef CURRENT_EDIT_TOOL
1249#undef ENABLE
1250#undef CHECK
1251// clang-format on
1252}
1253
1254
1255void PCB_EDIT_FRAME::OnQuit( wxCommandEvent& event )
1256{
1257 if( event.GetId() == wxID_EXIT )
1258 Kiway().OnKiCadExit();
1259
1260 if( event.GetId() == wxID_CLOSE || Kiface().IsSingle() )
1261 Close( false );
1262}
1263
1264
1265void PCB_EDIT_FRAME::ResolveDRCExclusions( bool aCreateMarkers )
1266{
1267 BOARD_COMMIT commit( this );
1268
1269 for( PCB_MARKER* marker : GetBoard()->ResolveDRCExclusions( aCreateMarkers ) )
1270 {
1271 if( marker->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
1272 marker->GetRCItem()->SetItems( GetCanvas()->GetDrawingSheet() );
1273
1274 commit.Add( marker );
1275 }
1276
1277 commit.Push( wxEmptyString, SKIP_UNDO | SKIP_SET_DIRTY );
1278
1279 for( PCB_MARKER* marker : GetBoard()->Markers() )
1280 {
1281 if( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION )
1282 GetCanvas()->GetView()->Update( marker );
1283 }
1284
1286}
1287
1288
1289bool PCB_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
1290{
1291 // Shutdown blocks must be determined and vetoed as early as possible
1292 if( KIPLATFORM::APP::SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
1293 && IsContentModified() )
1294 {
1295 return false;
1296 }
1297
1298 ZONE_FILLER_TOOL* zoneFillerTool = m_toolManager->GetTool<ZONE_FILLER_TOOL>();
1299
1300 if( zoneFillerTool->IsBusy() )
1301 {
1302 wxBell();
1303
1304 if( wxWindow* reporter = dynamic_cast<wxWindow*>( zoneFillerTool->GetProgressReporter() ) )
1305 reporter->ShowWithEffect( wxSHOW_EFFECT_EXPAND );
1306
1307 return false;
1308 }
1309
1310 if( Kiface().IsSingle() )
1311 {
1312 auto* fpEditor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_FOOTPRINT_EDITOR, false );
1313
1314 if( fpEditor && !fpEditor->Close() ) // Can close footprint editor?
1315 return false;
1316
1317 auto* fpViewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_VIEWER, false );
1318
1319 if( fpViewer && !fpViewer->Close() ) // Can close footprint viewer?
1320 return false;
1321
1322 // FOOTPRINT_CHOOSER_FRAME is always modal so this shouldn't come up, but better safe than
1323 // sorry.
1324 auto* chooser = (FOOTPRINT_CHOOSER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_CHOOSER, false );
1325
1326 if( chooser && !chooser->Close() ) // Can close footprint chooser?
1327 return false;
1328 }
1329 else
1330 {
1331 auto* fpEditor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_FOOTPRINT_EDITOR, false );
1332
1333 if( fpEditor && fpEditor->IsCurrentFPFromBoard() )
1334 {
1335 if( !fpEditor->CanCloseFPFromBoard( true ) )
1336 return false;
1337 }
1338 }
1339
1340 if( IsContentModified() )
1341 {
1342 wxFileName fileName = GetBoard()->GetFileName();
1343 wxString msg = _( "Save changes to '%s' before closing?" );
1344
1345 if( !HandleUnsavedChanges( this, wxString::Format( msg, fileName.GetFullName() ),
1346 [&]() -> bool
1347 {
1348 return SaveBoard();
1349 } ) )
1350 {
1351 return false;
1352 }
1353 }
1354
1355 return PCB_BASE_EDIT_FRAME::canCloseWindow( aEvent );
1356}
1357
1358
1360{
1361 // On Windows 7 / 32 bits, on OpenGL mode only, Pcbnew crashes
1362 // when closing this frame if a footprint was selected, and the footprint editor called
1363 // to edit this footprint, and when closing pcbnew if this footprint is still selected
1364 // See https://bugs.launchpad.net/kicad/+bug/1655858
1365 // I think this is certainly a OpenGL event fired after frame deletion, so this workaround
1366 // avoid the crash (JPC)
1367 GetCanvas()->SetEvtHandlerEnabled( false );
1368
1370
1371#ifdef KICAD_IPC_API
1372 Pgm().GetApiServer().DeregisterHandler( m_apiHandler.get() );
1373 wxTheApp->Unbind( EDA_EVT_PLUGIN_AVAILABILITY_CHANGED,
1374 &PCB_EDIT_FRAME::onPluginAvailabilityChanged, this );
1375#endif
1376
1377 // Clean up mode-less dialogs.
1378 Unbind( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, &PCB_EDIT_FRAME::onCloseModelessBookReporterDialogs,
1379 this );
1380
1381 wxWindow* open_dlg = wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME );
1382
1383 if( open_dlg )
1384 open_dlg->Close( true );
1385
1386 if( m_findDialog )
1387 {
1388 m_findDialog->Destroy();
1389 m_findDialog = nullptr;
1390 }
1391
1393 {
1394 m_inspectDrcErrorDlg->Destroy();
1395 m_inspectDrcErrorDlg = nullptr;
1396 }
1397
1399 {
1400 m_inspectClearanceDlg->Destroy();
1401 m_inspectClearanceDlg = nullptr;
1402 }
1403
1405 {
1406 m_inspectConstraintsDlg->Destroy();
1407 m_inspectConstraintsDlg = nullptr;
1408 }
1409
1410 if( m_footprintDiffDlg )
1411 {
1412 m_footprintDiffDlg->Destroy();
1413 m_footprintDiffDlg = nullptr;
1414 }
1415
1416 // Delete the auto save file if it exists.
1417 wxFileName fn = GetBoard()->GetFileName();
1418
1419 // Auto save file name is the normal file name prefixed with 'FILEEXT::AutoSaveFilePrefix'.
1420 fn.SetName( FILEEXT::AutoSaveFilePrefix + fn.GetName() );
1421
1422 // When the auto save feature does not have write access to the board file path, it falls
1423 // back to a platform specific user temporary file path.
1424 if( !fn.IsOk() || !fn.IsDirWritable() )
1425 fn.SetPath( wxFileName::GetTempDir() );
1426
1427 wxLogTrace( traceAutoSave, wxT( "Deleting auto save file <" ) + fn.GetFullPath() + wxT( ">" ) );
1428
1429 // Remove the auto save file on a normal close of Pcbnew.
1430 if( fn.FileExists() && !wxRemoveFile( fn.GetFullPath() ) )
1431 {
1432 wxLogTrace( traceAutoSave, wxT( "The auto save file could not be removed!" ) );
1433 }
1434
1435 // Make sure local settings are persisted
1436 if( Prj().GetLocalSettings().ShouldAutoSave() )
1437 {
1438 m_netInspectorPanel->SaveSettings();
1440 }
1441 else
1442 {
1443 wxLogTrace( traceAutoSave, wxT( "Skipping auto-save of migrated local settings" ) );
1444 }
1445
1446 // Do not show the layer manager during closing to avoid flicker
1447 // on some platforms (Windows) that generate useless redraw of items in
1448 // the Layer Manager
1450 {
1451 m_auimgr.GetPane( wxS( "LayersManager" ) ).Show( false );
1452 m_auimgr.GetPane( wxS( "TabbedPanel" ) ).Show( false );
1453 }
1454
1455 // Unlink the old project if needed
1457
1458 // Delete board structs and undo/redo lists, to avoid crash on exit
1459 // when deleting some structs (mainly in undo/redo lists) too late
1460 Clear_Pcb( false, true );
1461
1462 // do not show the window because ScreenPcb will be deleted and we do not
1463 // want any paint event
1464 Show( false );
1465
1467}
1468
1469
1476
1477
1478void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage, wxWindow* aParent )
1479{
1480 static std::mutex dialogMutex; // Local static mutex
1481
1482 std::unique_lock<std::mutex> dialogLock( dialogMutex, std::try_to_lock );
1483
1484 // One dialog at a time.
1485 if( !dialogLock.owns_lock() )
1486 {
1487 if( m_boardSetupDlg && m_boardSetupDlg->IsShown() )
1488 {
1489 m_boardSetupDlg->Raise(); // Brings the existing dialog to the front
1490 }
1491
1492 return;
1493 }
1494
1495 // Make sure everything's up-to-date
1497
1498 DIALOG_BOARD_SETUP dlg( this, aParent );
1499
1500 if( !aInitialPage.IsEmpty() )
1501 dlg.SetInitialPage( aInitialPage, wxEmptyString );
1502
1503 // Assign dlg to the m_boardSetupDlg pointer to track its status.
1504 m_boardSetupDlg = &dlg;
1505
1506 // QuasiModal required for Scintilla auto-complete
1507 if( dlg.ShowQuasiModal() == wxID_OK )
1508 {
1509 // Note: We must synchronise time domain properties before nets and classes, otherwise the updates
1510 // called by the board listener events are using stale data
1513
1514 if( !GetBoard()->SynchronizeComponentClasses( std::unordered_set<wxString>() ) )
1515 {
1516 m_infoBar->RemoveAllButtons();
1517 m_infoBar->AddCloseButton();
1518 m_infoBar->ShowMessage( _( "Could not load component class assignment rules" ),
1519 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::GENERIC );
1520 }
1521
1522 // We don't know if anything was modified, so err on the side of requiring a save
1523 OnModify();
1524
1526
1529
1530 PCBNEW_SETTINGS* settings = GetPcbNewSettings();
1531 static LSET maskAndPasteLayers = LSET( { F_Mask, F_Paste, B_Mask, B_Paste } );
1532
1534 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
1535 {
1536 int flags = 0;
1537
1538 if( !aItem->IsBOARD_ITEM() )
1539 return flags;
1540
1541 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aItem );
1542
1543 if( item->Type() == PCB_VIA_T || item->Type() == PCB_PAD_T )
1544 {
1545 // Note: KIGFX::REPAINT isn't enough for things that go from invisible
1546 // to visible as they won't be found in the view layer's itemset for
1547 // re-painting.
1548 if( ( GetBoard()->GetVisibleLayers() & maskAndPasteLayers ).any() )
1549 flags |= KIGFX::ALL;
1550 }
1551
1552 if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T || item->Type() == PCB_VIA_T )
1553 {
1555 flags |= KIGFX::REPAINT;
1556 }
1557
1558 if( item->Type() == PCB_PAD_T )
1559 {
1560 if( settings->m_Display.m_PadClearance )
1561 flags |= KIGFX::REPAINT;
1562 }
1563
1564 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aItem ) )
1565 {
1566 if( text->HasTextVars() )
1567 {
1568 text->ClearRenderCache();
1569 text->ClearBoundingBoxCache();
1571 }
1572 }
1573
1574 return flags;
1575 } );
1576
1577 GetCanvas()->Refresh();
1578
1582
1583 //this event causes the routing tool to reload its design rules information
1585 toolEvent.SetHasPosition( false );
1586 m_toolManager->ProcessEvent( toolEvent );
1587 }
1588
1589 GetCanvas()->SetFocus();
1590
1591 // Reset m_boardSetupDlg after the dialog is closed
1592 m_boardSetupDlg = nullptr;
1593}
1594
1595
1597{
1598 m_searchPane->FocusSearch();
1599}
1600
1601
1603{
1605
1606 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( aCfg );
1607 wxASSERT( cfg );
1608
1609 if( cfg )
1610 {
1614 }
1615}
1616
1617
1619{
1621
1622 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( aCfg );
1623 wxASSERT( cfg );
1624
1625 if( cfg )
1626 {
1627 wxAuiPaneInfo& apperancePane = m_auimgr.GetPane( AppearancePanelName() );
1628 cfg->m_AuiPanels.show_layer_manager = apperancePane.IsShown();
1629
1630 if( m_propertiesPanel )
1631 {
1632 cfg->m_AuiPanels.show_properties = m_propertiesPanel->IsShownOnScreen();
1634 cfg->m_AuiPanels.properties_splitter = m_propertiesPanel->SplitterProportion();
1635 }
1636
1637 // ensure m_show_search is up to date (the pane can be closed)
1638 wxAuiPaneInfo& searchPaneInfo = m_auimgr.GetPane( SearchPaneName() );
1639 m_show_search = searchPaneInfo.IsShown();
1641 cfg->m_AuiPanels.search_panel_height = m_searchPane->GetSize().y;
1642 cfg->m_AuiPanels.search_panel_width = m_searchPane->GetSize().x;
1643 cfg->m_AuiPanels.search_panel_dock_direction = searchPaneInfo.dock_direction;
1644
1646 {
1647 wxAuiPaneInfo& netInspectorhPaneInfo = m_auimgr.GetPane( NetInspectorPanelName() );
1648 m_show_net_inspector = netInspectorhPaneInfo.IsShown();
1650 }
1651
1652 if( m_appearancePanel )
1653 {
1656 cfg->m_AuiPanels.appearance_expand_layer_display = m_appearancePanel->IsLayerOptionsExpanded();
1657 cfg->m_AuiPanels.appearance_expand_net_display = m_appearancePanel->IsNetOptionsExpanded();
1658 }
1659
1660 wxAuiPaneInfo& designBlocksPane = m_auimgr.GetPane( DesignBlocksPaneName() );
1661 cfg->m_AuiPanels.design_blocks_show = designBlocksPane.IsShown();
1662
1663 if( designBlocksPane.IsDocked() )
1665 else
1666 {
1667 cfg->m_AuiPanels.design_blocks_panel_float_height = designBlocksPane.floating_size.y;
1668 cfg->m_AuiPanels.design_blocks_panel_float_width = designBlocksPane.floating_size.x;
1669 }
1670
1671 m_designBlocksPane->SaveSettings();
1672 }
1673}
1674
1675
1677{
1678 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( config() );
1679
1680 return cfg ? cfg->m_RotationAngle : ANGLE_90;
1681}
1682
1683
1688
1689
1691{
1692
1693 GetColorSettings()->SetColor( LAYER_GRID, aColor );
1694 GetCanvas()->GetGAL()->SetGridColor( aColor );
1695}
1696
1697
1698void PCB_EDIT_FRAME::SetActiveLayer( PCB_LAYER_ID aLayer, bool aForceRedraw )
1699{
1700 const PCB_LAYER_ID oldLayer = GetActiveLayer();
1701
1702 if( oldLayer == aLayer && !aForceRedraw )
1703 return;
1704
1706
1707 m_appearancePanel->OnLayerChanged();
1708
1709 m_toolManager->PostAction( PCB_ACTIONS::layerChanged ); // notify other tools
1710 GetCanvas()->SetFocus(); // allow capture of hotkeys
1711 GetCanvas()->SetHighContrastLayer( aLayer );
1712
1713 /*
1714 * Only show pad, via and track clearances when a copper layer is active
1715 * and then only show the clearance layer for that copper layer. For
1716 * front/back non-copper layers, show the clearance layer for the outer
1717 * layer on that side.
1718 *
1719 * For pads/vias, this is to avoid clutter when there are pad/via layers
1720 * that vary in flash (i.e. clearance from the hole or pad edge), padstack
1721 * shape on each layer or clearances on each layer.
1722 *
1723 * For tracks, this follows the same logic as pads/vias, but in theory could
1724 * have their own set of independent clearance layers to allow track clearance
1725 * to be shown for more layers.
1726 */
1727 const auto getClearanceLayerForActive = []( PCB_LAYER_ID aActiveLayer ) -> std::optional<int>
1728 {
1729 if( IsCopperLayer( aActiveLayer ) )
1730 return CLEARANCE_LAYER_FOR( aActiveLayer );
1731
1732 return std::nullopt;
1733 };
1734
1735 if( std::optional<int> oldClearanceLayer = getClearanceLayerForActive( oldLayer ) )
1736 GetCanvas()->GetView()->SetLayerVisible( *oldClearanceLayer, false );
1737
1738 if( std::optional<int> newClearanceLayer = getClearanceLayerForActive( aLayer ) )
1739 GetCanvas()->GetView()->SetLayerVisible( *newClearanceLayer, true );
1740
1742 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
1743 {
1744 if( !aItem->IsBOARD_ITEM() )
1745 return 0;
1746
1747 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aItem );
1748
1749 // Note: KIGFX::REPAINT isn't enough for things that go from invisible to visible
1750 // as they won't be found in the view layer's itemset for re-painting.
1751 if( GetDisplayOptions().m_ContrastModeDisplay == HIGH_CONTRAST_MODE::HIDDEN )
1752 {
1753 if( item->IsOnLayer( oldLayer ) || item->IsOnLayer( aLayer ) )
1754 return KIGFX::ALL;
1755 }
1756
1757 if( item->Type() == PCB_VIA_T )
1758 {
1759 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1760
1761 // Vias on a restricted layer set must be redrawn when the active layer
1762 // is changed
1763 if( via->GetViaType() == VIATYPE::BLIND_BURIED
1764 || via->GetViaType() == VIATYPE::MICROVIA )
1765 {
1766 return KIGFX::REPAINT;
1767 }
1768
1769 if( via->GetRemoveUnconnected() )
1770 return KIGFX::ALL;
1771 }
1772 else if( item->Type() == PCB_PAD_T )
1773 {
1774 PAD* pad = static_cast<PAD*>( item );
1775
1776 if( pad->GetRemoveUnconnected() )
1777 return KIGFX::ALL;
1778 }
1779
1780 return 0;
1781 } );
1782
1783 GetCanvas()->Refresh();
1784}
1785
1786
1788{
1790
1791 layerEnum.Choices().Clear();
1792 layerEnum.Undefined( UNDEFINED_LAYER );
1793
1794 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
1795 {
1796 // Canonical name
1797 layerEnum.Map( layer, LSET::Name( layer ) );
1798
1799 // User name
1800 layerEnum.Map( layer, GetBoard()->GetLayerName( layer ) );
1801 }
1802
1803 DRC_TOOL* drcTool = m_toolManager->GetTool<DRC_TOOL>();
1804
1805 try
1806 {
1808 }
1809 catch( PARSE_ERROR& )
1810 {
1811 // Not sure this is the best place to tell the user their rules are buggy, so
1812 // we'll stay quiet for now. Feel free to revisit this decision....
1813 }
1814
1815 UpdateTitle();
1816
1817 wxFileName fn = GetBoard()->GetFileName();
1818
1819 // Display a warning that the file is read only
1820 if( fn.FileExists() && !fn.IsFileWritable() )
1821 {
1822 m_infoBar->RemoveAllButtons();
1823 m_infoBar->AddCloseButton();
1824 m_infoBar->ShowMessage( _( "Board file is read only." ),
1826 }
1827
1829
1830 // Sync layer and item visibility
1832
1833 SetElementVisibility( LAYER_RATSNEST, GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest );
1834
1835 m_appearancePanel->OnBoardChanged();
1836
1837 // Apply saved display state to the appearance panel after it has been set up
1838 PROJECT_LOCAL_SETTINGS& localSettings = Prj().GetLocalSettings();
1839
1840 m_appearancePanel->ApplyLayerPreset( localSettings.m_ActiveLayerPreset );
1841
1842 if( GetBoard()->GetDesignSettings().IsLayerEnabled( localSettings.m_ActiveLayer ) )
1843 SetActiveLayer( localSettings.m_ActiveLayer, true );
1844 else
1845 SetActiveLayer( GetActiveLayer(), true ); // Make sure to repaint even if not switching
1846
1847 PROJECT_FILE& projectFile = Prj().GetProjectFile();
1848
1849 m_layerPairSettings->SetLayerPairs( projectFile.m_LayerPairInfos );
1850 m_layerPairSettings->SetCurrentLayerPair( LAYER_PAIR{ F_Cu, B_Cu } );
1851
1852 // Updates any auto dimensions and the auxiliary toolbar tracks/via sizes
1854
1855 // Sync the net inspector now we have connectivity calculated
1857 m_netInspectorPanel->OnBoardChanged();
1858
1859 // Display the loaded board:
1860 Zoom_Automatique( false );
1861
1862 // Invalidate painting as loading the DRC engine will cause clearances to become valid
1864
1865 Refresh();
1866
1867 SetMsgPanel( GetBoard() );
1868 SetStatusText( wxEmptyString );
1869
1870 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "PCB file changes are unsaved" ) );
1871}
1872
1873
1875{
1876 m_appearancePanel->UpdateDisplayOptions();
1877}
1878
1879
1881{
1882 return GetBoard()->IsElementVisible( aElement );
1883}
1884
1885
1887{
1888 // Force the RATSNEST visible
1889 if( aElement == LAYER_RATSNEST )
1890 GetCanvas()->GetView()->SetLayerVisible( aElement, true );
1891 else
1892 GetCanvas()->GetView()->SetLayerVisible( aElement , aNewState );
1893
1894 GetBoard()->SetElementVisibility( aElement, aNewState );
1895}
1896
1897
1899{
1900 // call my base class
1902
1903 m_auimgr.GetPane( m_appearancePanel ).Caption( _( "Appearance" ) );
1904 m_auimgr.GetPane( m_selectionFilterPanel ).Caption( _( "Selection Filter" ) );
1905 m_auimgr.GetPane( m_propertiesPanel ).Caption( _( "Properties" ) );
1906 m_auimgr.GetPane( m_netInspectorPanel ).Caption( _( "Net Inspector" ) );
1907 m_auimgr.Update();
1908
1909 UpdateTitle();
1910}
1911
1912
1914{
1916
1917 if( project.m_PcbLastPath[ aType ].IsEmpty() )
1918 return wxEmptyString;
1919
1920 wxFileName absoluteFileName = project.m_PcbLastPath[ aType ];
1921 wxFileName pcbFileName = GetBoard()->GetFileName();
1922
1923 absoluteFileName.MakeAbsolute( pcbFileName.GetPath() );
1924 return absoluteFileName.GetFullPath();
1925}
1926
1927
1928void PCB_EDIT_FRAME::SetLastPath( LAST_PATH_TYPE aType, const wxString& aLastPath )
1929{
1931
1932 wxFileName relativeFileName = aLastPath;
1933 wxFileName pcbFileName = GetBoard()->GetFileName();
1934
1935 relativeFileName.MakeRelativeTo( pcbFileName.GetPath() );
1936
1937 if( relativeFileName.GetFullPath() != project.m_PcbLastPath[ aType ] )
1938 {
1939 project.m_PcbLastPath[ aType ] = relativeFileName.GetFullPath();
1940 OnModify();
1941 }
1942}
1943
1944
1946{
1948 m_ZoneFillsDirty = true;
1949
1950 if( m_isClosing )
1951 return;
1952
1953 Update3DView( true, GetPcbNewSettings()->m_Display.m_Live3DRefresh );
1954
1955 if( !GetTitle().StartsWith( wxT( "*" ) ) )
1956 UpdateTitle();
1957
1958}
1959
1960
1962{
1963 Update3DView( true, true );
1964
1965 std::shared_ptr<CONNECTIVITY_DATA> connectivity = GetBoard()->GetConnectivity();
1966 connectivity->RecalculateRatsnest( nullptr );
1968
1969 std::vector<MSG_PANEL_ITEM> msg_list;
1970 GetBoard()->GetMsgPanelInfo( this, msg_list );
1971 SetMsgPanel( msg_list );
1972}
1973
1974
1976{
1977 wxFileName fn = GetBoard()->GetFileName();
1978 bool readOnly = false;
1979 bool unsaved = false;
1980
1981 if( fn.IsOk() && fn.FileExists() )
1982 readOnly = !fn.IsFileWritable();
1983 else
1984 unsaved = true;
1985
1986 wxString title;
1987
1988 if( IsContentModified() )
1989 title = wxT( "*" );
1990
1991 title += fn.GetName();
1992
1993 if( readOnly )
1994 title += wxS( " " ) + _( "[Read Only]" );
1995
1996 if( unsaved )
1997 title += wxS( " " ) + _( "[Unsaved]" );
1998
1999 title += wxT( " \u2014 " ) + _( "PCB Editor" );
2000
2001 SetTitle( title );
2002}
2003
2004
2006{
2007 // Update the layer manager and other widgets from the board setup
2008 // (layer and items visibility, colors ...)
2009
2010 // Rebuild list of nets (full ratsnest rebuild)
2012
2013 // Update info shown by the horizontal toolbars
2015
2016 LSET activeLayers = GetBoard()->GetEnabledLayers();
2017
2018 if( !activeLayers.test( GetActiveLayer() ) )
2019 SetActiveLayer( activeLayers.Seq().front() );
2020
2021 m_SelLayerBox->SetLayerSelection( GetActiveLayer() );
2022
2024
2025 layerEnum.Choices().Clear();
2026 layerEnum.Undefined( UNDEFINED_LAYER );
2027
2028 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
2029 {
2030 // Canonical name
2031 layerEnum.Map( layer, LSET::Name( layer ) );
2032
2033 // User name
2034 layerEnum.Map( layer, GetBoard()->GetLayerName( layer ) );
2035 }
2036
2037 // Sync visibility with canvas
2038 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
2039 GetCanvas()->GetView()->SetLayerVisible( layer, GetBoard()->IsLayerVisible( layer ) );
2040
2041 // Stackup and/or color theme may have changed
2042 m_appearancePanel->OnBoardChanged();
2043 m_netInspectorPanel->OnParentSetupChanged();
2044}
2045
2046
2048{
2049 // switches currently used canvas (Cairo / OpenGL).
2050 PCB_BASE_FRAME::SwitchCanvas( aCanvasType );
2051}
2052
2053
2055{
2056 if( !m_findDialog )
2057 {
2058 m_findDialog = new DIALOG_FIND( this );
2059 m_findDialog->SetCallback( std::bind( &PCB_SELECTION_TOOL::FindItem,
2060 m_toolManager->GetTool<PCB_SELECTION_TOOL>(), _1 ) );
2061 }
2062
2063 wxString findString;
2064
2065 PCB_SELECTION& selection = m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
2066
2067 if( selection.Size() == 1 )
2068 {
2069 EDA_ITEM* front = selection.Front();
2070
2071 switch( front->Type() )
2072 {
2073 case PCB_FOOTPRINT_T:
2074 findString = UnescapeString( static_cast<FOOTPRINT*>( front )->GetValue() );
2075 break;
2076
2077 case PCB_FIELD_T:
2078 case PCB_TEXT_T:
2079 findString = UnescapeString( static_cast<PCB_TEXT*>( front )->GetText() );
2080
2081 if( findString.Contains( wxT( "\n" ) ) )
2082 findString = findString.Before( '\n' );
2083
2084 break;
2085
2086 default:
2087 break;
2088 }
2089 }
2090
2091 m_findDialog->Preload( findString );
2092
2093 m_findDialog->Show( true );
2094}
2095
2096
2097void PCB_EDIT_FRAME::FindNext( bool reverse )
2098{
2099 if( !m_findDialog )
2101
2102 m_findDialog->FindNext( reverse );
2103}
2104
2105
2107{
2108 if( Kiface().IsSingle() )
2109 return 0;
2110
2111 // Update PCB requires a netlist. Therefore the schematic editor must be running
2112 // If this is not the case, open the schematic editor
2113 KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH, true );
2114
2115 // If Kiway() cannot create the eeschema frame, it shows a error message, and
2116 // frame is null
2117 if( !frame )
2118 return -1;
2119
2120 if( !frame->IsShownOnScreen() )
2121 {
2122 wxEventBlocker blocker( this );
2123 wxFileName fn( Prj().GetProjectPath(), Prj().GetProjectName(),
2125
2126 // Maybe the file hasn't been converted to the new s-expression file format so
2127 // see if the legacy schematic file is still in play.
2128 if( !fn.FileExists() )
2129 {
2131
2132 if( !fn.FileExists() )
2133 {
2134 DisplayErrorMessage( this, _( "The schematic for this board cannot be found." ) );
2135 return -2;
2136 }
2137 }
2138
2139 frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
2140
2141 // we show the schematic editor frame, because do not show is seen as
2142 // a not yet opened schematic by Kicad manager, which is not the case
2143 frame->Show( true );
2144
2145 // bring ourselves back to the front
2146 Raise();
2147 }
2148
2149 return 1; //Success!
2150}
2151
2152
2154 const wxString& aAnnotateMessage )
2155{
2156 int standalone = TestStandalone();
2157
2158 if( standalone == 0 )
2159 {
2160 DisplayErrorMessage( this, _( "Cannot update the PCB because PCB editor is opened in "
2161 "stand-alone mode. In order to create or update PCBs from "
2162 "schematics, you must launch the KiCad project manager and "
2163 "create a project." ) );
2164 return false; // Not in standalone mode
2165 }
2166
2167 if( standalone < 0 ) // Problem with Eeschema or the schematic
2168 return false;
2169
2170 Raise(); // Show
2171
2172 std::string payload( aAnnotateMessage );
2173
2174 Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_GET_NETLIST, payload, this );
2175
2176 if( payload == aAnnotateMessage )
2177 {
2178 Raise();
2179 DisplayErrorMessage( this, aAnnotateMessage );
2180 return false;
2181 }
2182
2183 try
2184 {
2185 auto lineReader = new STRING_LINE_READER( payload, _( "Eeschema netlist" ) );
2186 KICAD_NETLIST_READER netlistReader( lineReader, &aNetlist );
2187 netlistReader.LoadNetlist();
2188 }
2189 catch( const IO_ERROR& e )
2190 {
2191 Raise();
2192
2193 // Do not translate extra_info strings. These are for developers
2194 wxString extra_info = e.Problem() + wxT( " : " ) + e.What() + wxT( " at " ) + e.Where();
2195
2196 DisplayErrorMessage( this, _( "Received an error while reading netlist. Please "
2197 "report this issue to the KiCad team using the menu "
2198 "Help->Report Bug."), extra_info );
2199 return false;
2200 }
2201
2202 return true;
2203}
2204
2205
2207{
2208 const ENV_VAR_MAP& vars = Pgm().GetLocalEnvVariables();
2209
2210 // Set the environment variables for python scripts
2211 // note: the string will be encoded UTF8 for python env
2212 for( const std::pair<const wxString, ENV_VAR_ITEM>& var : vars )
2213 UpdatePythonEnvVar( var.first, var.second.GetValue() );
2214
2215 // Because the env vars can be modified by the python scripts (rewritten in UTF8),
2216 // regenerate them (in Unicode) for our normal environment
2217 for( const std::pair<const wxString, ENV_VAR_ITEM>& var : vars )
2218 wxSetEnv( var.first, var.second.GetValue() );
2219}
2220
2221
2223{
2224 wxString evValue;
2225 wxGetEnv( PROJECT_VAR_NAME, &evValue );
2226 UpdatePythonEnvVar( wxString( PROJECT_VAR_NAME ).ToStdString(), evValue );
2227
2228 // Because PROJECT_VAR_NAME can be modified by the python scripts (rewritten in UTF8),
2229 // regenerate it (in Unicode) for our normal environment
2230 wxSetEnv( PROJECT_VAR_NAME, evValue );
2231}
2232
2233
2235{
2236 if( aFootprint == nullptr )
2237 return;
2238
2240
2241 /*
2242 * Make sure dlg is destroyed before GetCanvas->Refresh is called
2243 * later or the refresh will try to modify its properties since
2244 * they share a GL context.
2245 */
2246 {
2247 DIALOG_FOOTPRINT_PROPERTIES dlg( this, aFootprint );
2248
2249 dlg.ShowQuasiModal();
2250 retvalue = dlg.GetReturnValue();
2251 }
2252
2253 /*
2254 * retvalue =
2255 * FP_PROPS_UPDATE_FP to show Update Footprints dialog
2256 * FP_PROPS_CHANGE_FP to show Change Footprints dialog
2257 * FP_PROPS_OK for normal edit
2258 * FP_PROPS_CANCEL if aborted
2259 * FP_PROPS_EDIT_BOARD_FP to load board footprint into Footprint Editor
2260 * FP_PROPS_EDIT_LIBRARY_FP to load library footprint into Footprint Editor
2261 */
2262
2264 {
2265 // If something edited, push a refresh request
2266 GetCanvas()->Refresh();
2267 }
2269 {
2270 if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_EDITOR, true ) )
2271 {
2272 FOOTPRINT_EDIT_FRAME* fp_editor = static_cast<FOOTPRINT_EDIT_FRAME*>( frame );
2273
2274 fp_editor->LoadFootprintFromBoard( aFootprint );
2275 fp_editor->Show( true );
2276 fp_editor->Raise(); // Iconize( false );
2277 }
2278 }
2280 {
2281 if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_EDITOR, true ) )
2282 {
2283 FOOTPRINT_EDIT_FRAME* fp_editor = static_cast<FOOTPRINT_EDIT_FRAME*>( frame );
2284
2285 fp_editor->LoadFootprintFromLibrary( aFootprint->GetFPID() );
2286 fp_editor->Show( true );
2287 fp_editor->Raise(); // Iconize( false );
2288 }
2289 }
2291 {
2292 ShowExchangeFootprintsDialog( aFootprint, true, true );
2293 }
2295 {
2296 ShowExchangeFootprintsDialog( aFootprint, false, true );
2297 }
2298}
2299
2300
2302 bool aSelectedMode )
2303{
2304 DIALOG_EXCHANGE_FOOTPRINTS dialog( this, aFootprint, aUpdateMode, aSelectedMode );
2305
2306 return dialog.ShowQuasiModal();
2307}
2308
2309
2321static void processTextItem( const PCB_TEXT& aSrc, PCB_TEXT& aDest,
2322 bool aResetText, bool aResetTextLayers, bool aResetTextEffects,
2323 bool aResetTextPositions, bool* aUpdated )
2324{
2325 if( aResetText )
2326 *aUpdated |= aSrc.GetText() != aDest.GetText();
2327 else
2328 aDest.SetText( aSrc.GetText() );
2329
2330 if( aResetTextLayers )
2331 {
2332 *aUpdated |= aSrc.GetLayer() != aDest.GetLayer();
2333 *aUpdated |= aSrc.IsVisible() != aDest.IsVisible();
2334 }
2335 else
2336 {
2337 aDest.SetLayer( aSrc.GetLayer() );
2338 aDest.SetVisible( aSrc.IsVisible() );
2339 }
2340
2341 VECTOR2I origPos = aDest.GetFPRelativePosition();
2342
2343 if( aResetTextEffects )
2344 {
2345 *aUpdated |= aSrc.GetHorizJustify() != aDest.GetHorizJustify();
2346 *aUpdated |= aSrc.GetVertJustify() != aDest.GetVertJustify();
2347 *aUpdated |= aSrc.GetTextSize() != aDest.GetTextSize();
2348 *aUpdated |= aSrc.GetTextThickness() != aDest.GetTextThickness();
2349 *aUpdated |= aSrc.GetTextAngle() != aDest.GetTextAngle();
2350 }
2351 else
2352 {
2353 aDest.SetAttributes( aSrc );
2354 }
2355
2356 if( aResetTextPositions )
2357 {
2358 *aUpdated |= aSrc.GetFPRelativePosition() != origPos;
2359 aDest.SetFPRelativePosition( origPos );
2360 }
2361 else
2362 {
2364 }
2365
2366 aDest.SetLocked( aSrc.IsLocked() );
2367 const_cast<KIID&>( aDest.m_Uuid ) = aSrc.m_Uuid;
2368}
2369
2370
2371template<typename T>
2372static std::vector<std::pair<T*, T*>> matchItemsBySimilarity( const std::vector<T*>& aExisting,
2373 const std::vector<T*>& aNew )
2374{
2375 struct MATCH_CANDIDATE
2376 {
2377 T* existing;
2378 T* updated;
2379 double score;
2380 };
2381
2382 std::vector<MATCH_CANDIDATE> candidates;
2383
2384 for( T* existing : aExisting )
2385 {
2386 for( T* updated : aNew )
2387 {
2388 if( existing->Type() != updated->Type() )
2389 continue;
2390
2391 double similarity = existing->Similarity( *updated );
2392
2393 if( similarity <= 0.0 )
2394 continue;
2395
2396 double score = similarity;
2397
2398 if constexpr( std::is_same_v<T, PAD> )
2399 {
2400 if( existing->GetNumber() == updated->GetNumber() )
2401 score += 2.0;
2402 }
2403
2404 candidates.push_back( { existing, updated, score } );
2405 }
2406 }
2407
2408 std::sort( candidates.begin(), candidates.end(),
2409 []( const MATCH_CANDIDATE& a, const MATCH_CANDIDATE& b )
2410 {
2411 if( a.score != b.score )
2412 return a.score > b.score;
2413
2414 if( a.existing != b.existing )
2415 return a.existing < b.existing;
2416
2417 return a.updated < b.updated;
2418 } );
2419
2420 std::vector<std::pair<T*, T*>> matches;
2421 matches.reserve( candidates.size() );
2422
2423 std::unordered_set<T*> matchedExisting;
2424 std::unordered_set<T*> matchedNew;
2425
2426 for( const MATCH_CANDIDATE& candidate : candidates )
2427 {
2428 if( matchedExisting.find( candidate.existing ) != matchedExisting.end() )
2429 continue;
2430
2431 if( matchedNew.find( candidate.updated ) != matchedNew.end() )
2432 continue;
2433
2434 matchedExisting.insert( candidate.existing );
2435 matchedNew.insert( candidate.updated );
2436 matches.emplace_back( candidate.existing, candidate.updated );
2437 }
2438
2439 return matches;
2440}
2441
2442
2444 BOARD_COMMIT& aCommit,
2445 bool deleteExtraTexts,
2446 bool resetTextLayers,
2447 bool resetTextEffects,
2448 bool resetTextPositions,
2449 bool resetTextContent,
2450 bool resetFabricationAttrs,
2451 bool resetClearanceOverrides,
2452 bool reset3DModels,
2453 bool* aUpdated )
2454{
2455 EDA_GROUP* parentGroup = aExisting->GetParentGroup();
2456 bool dummyBool = false;
2457
2458 if( !aUpdated )
2459 aUpdated = &dummyBool;
2460
2461 if( parentGroup )
2462 {
2463 aCommit.Modify( parentGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
2464 parentGroup->RemoveItem( aExisting );
2465 parentGroup->AddItem( aNew );
2466 }
2467
2468 aNew->SetParent( GetBoard() );
2469
2470 PlaceFootprint( aNew, false );
2471
2472 // PlaceFootprint will move the footprint to the cursor position, which we don't want. Copy
2473 // the original position across.
2474 aNew->SetPosition( aExisting->GetPosition() );
2475
2476 if( aNew->GetLayer() != aExisting->GetLayer() )
2477 aNew->Flip( aNew->GetPosition(), GetPcbNewSettings()->m_FlipDirection );
2478
2479 if( aNew->GetOrientation() != aExisting->GetOrientation() )
2480 aNew->SetOrientation( aExisting->GetOrientation() );
2481
2482 aNew->SetLocked( aExisting->IsLocked() );
2483
2484 const_cast<KIID&>( aNew->m_Uuid ) = aExisting->m_Uuid;
2485 const_cast<KIID&>( aNew->Reference().m_Uuid ) = aExisting->Reference().m_Uuid;
2486 const_cast<KIID&>( aNew->Value().m_Uuid ) = aExisting->Value().m_Uuid;
2487
2488 std::vector<PAD*> oldPads;
2489 oldPads.reserve( aExisting->Pads().size() );
2490
2491 for( PAD* pad : aExisting->Pads() )
2492 oldPads.push_back( pad );
2493
2494 std::vector<PAD*> newPads;
2495 newPads.reserve( aNew->Pads().size() );
2496
2497 for( PAD* pad : aNew->Pads() )
2498 newPads.push_back( pad );
2499
2500 auto padMatches = matchItemsBySimilarity<PAD>( oldPads, newPads );
2501 std::unordered_set<PAD*> matchedNewPads;
2502
2503 for( const auto& match : padMatches )
2504 {
2505 PAD* oldPad = match.first;
2506 PAD* newPad = match.second;
2507
2508 matchedNewPads.insert( newPad );
2509 const_cast<KIID&>( newPad->m_Uuid ) = oldPad->m_Uuid;
2511 newPad->SetPinFunction( oldPad->GetPinFunction() );
2512 newPad->SetPinType( oldPad->GetPinType() );
2513
2514 if( newPad->IsOnCopperLayer() )
2515 newPad->SetNetCode( oldPad->GetNetCode() );
2516 else
2518 }
2519
2520 for( PAD* newPad : aNew->Pads() )
2521 {
2522 if( matchedNewPads.find( newPad ) != matchedNewPads.end() )
2523 continue;
2524
2525 const_cast<KIID&>( newPad->m_Uuid ) = KIID();
2526 newPad->SetNetCode( NETINFO_LIST::UNCONNECTED );
2527 }
2528
2529 std::vector<BOARD_ITEM*> oldDrawings;
2530 oldDrawings.reserve( aExisting->GraphicalItems().size() );
2531
2532 for( BOARD_ITEM* item : aExisting->GraphicalItems() )
2533 oldDrawings.push_back( item );
2534
2535 std::vector<BOARD_ITEM*> newDrawings;
2536 newDrawings.reserve( aNew->GraphicalItems().size() );
2537
2538 for( BOARD_ITEM* item : aNew->GraphicalItems() )
2539 newDrawings.push_back( item );
2540
2541 auto drawingMatches = matchItemsBySimilarity<BOARD_ITEM>( oldDrawings, newDrawings );
2542 std::unordered_map<BOARD_ITEM*, BOARD_ITEM*> oldToNewDrawings;
2543 std::unordered_set<BOARD_ITEM*> matchedNewDrawings;
2544
2545 for( const auto& match : drawingMatches )
2546 {
2547 BOARD_ITEM* oldItem = match.first;
2548 BOARD_ITEM* newItem = match.second;
2549
2550 oldToNewDrawings[ oldItem ] = newItem;
2551 matchedNewDrawings.insert( newItem );
2552 const_cast<KIID&>( newItem->m_Uuid ) = oldItem->m_Uuid;
2553 }
2554
2555 for( BOARD_ITEM* newItem : newDrawings )
2556 {
2557 if( matchedNewDrawings.find( newItem ) == matchedNewDrawings.end() )
2558 const_cast<KIID&>( newItem->m_Uuid ) = KIID();
2559 }
2560
2561 std::vector<ZONE*> oldZones;
2562 oldZones.reserve( aExisting->Zones().size() );
2563
2564 for( ZONE* zone : aExisting->Zones() )
2565 oldZones.push_back( zone );
2566
2567 std::vector<ZONE*> newZones;
2568 newZones.reserve( aNew->Zones().size() );
2569
2570 for( ZONE* zone : aNew->Zones() )
2571 newZones.push_back( zone );
2572
2573 auto zoneMatches = matchItemsBySimilarity<ZONE>( oldZones, newZones );
2574 std::unordered_set<ZONE*> matchedNewZones;
2575
2576 for( const auto& match : zoneMatches )
2577 {
2578 ZONE* oldZone = match.first;
2579 ZONE* newZone = match.second;
2580
2581 matchedNewZones.insert( newZone );
2582 const_cast<KIID&>( newZone->m_Uuid ) = oldZone->m_Uuid;
2583 }
2584
2585 for( ZONE* newZone : newZones )
2586 {
2587 if( matchedNewZones.find( newZone ) == matchedNewZones.end() )
2588 const_cast<KIID&>( newZone->m_Uuid ) = KIID();
2589 }
2590
2591 std::vector<PCB_POINT*> oldPoints;
2592 oldPoints.reserve( aExisting->Points().size() );
2593
2594 for( PCB_POINT* point : aExisting->Points() )
2595 oldPoints.push_back( point );
2596
2597 std::vector<PCB_POINT*> newPoints;
2598 newPoints.reserve( aNew->Points().size() );
2599
2600 for( PCB_POINT* point : aNew->Points() )
2601 newPoints.push_back( point );
2602
2603 auto pointMatches = matchItemsBySimilarity<PCB_POINT>( oldPoints, newPoints );
2604 std::unordered_set<PCB_POINT*> matchedNewPoints;
2605
2606 for( const auto& match : pointMatches )
2607 {
2608 PCB_POINT* oldPoint = match.first;
2609 PCB_POINT* newPoint = match.second;
2610
2611 matchedNewPoints.insert( newPoint );
2612 const_cast<KIID&>( newPoint->m_Uuid ) = oldPoint->m_Uuid;
2613 }
2614
2615 for( PCB_POINT* newPoint : newPoints )
2616 {
2617 if( matchedNewPoints.find( newPoint ) == matchedNewPoints.end() )
2618 const_cast<KIID&>( newPoint->m_Uuid ) = KIID();
2619 }
2620
2621 std::vector<PCB_GROUP*> oldGroups;
2622 oldGroups.reserve( aExisting->Groups().size() );
2623
2624 for( PCB_GROUP* group : aExisting->Groups() )
2625 oldGroups.push_back( group );
2626
2627 std::vector<PCB_GROUP*> newGroups;
2628 newGroups.reserve( aNew->Groups().size() );
2629
2630 for( PCB_GROUP* group : aNew->Groups() )
2631 newGroups.push_back( group );
2632
2633 auto groupMatches = matchItemsBySimilarity<PCB_GROUP>( oldGroups, newGroups );
2634 std::unordered_set<PCB_GROUP*> matchedNewGroups;
2635
2636 for( const auto& match : groupMatches )
2637 {
2638 PCB_GROUP* oldGroup = match.first;
2639 PCB_GROUP* newGroup = match.second;
2640
2641 matchedNewGroups.insert( newGroup );
2642 const_cast<KIID&>( newGroup->m_Uuid ) = oldGroup->m_Uuid;
2643 }
2644
2645 for( PCB_GROUP* newGroup : newGroups )
2646 {
2647 if( matchedNewGroups.find( newGroup ) == matchedNewGroups.end() )
2648 const_cast<KIID&>( newGroup->m_Uuid ) = KIID();
2649 }
2650
2651 std::vector<PCB_FIELD*> oldFieldsVec;
2652 std::vector<PCB_FIELD*> newFieldsVec;
2653
2654 oldFieldsVec.reserve( aExisting->GetFields().size() );
2655
2656 for( PCB_FIELD* field : aExisting->GetFields() )
2657 {
2658 if( field->IsReference() || field->IsValue() )
2659 continue;
2660
2661 oldFieldsVec.push_back( field );
2662 }
2663
2664 newFieldsVec.reserve( aNew->GetFields().size() );
2665
2666 for( PCB_FIELD* field : aNew->GetFields() )
2667 {
2668 if( field->IsReference() || field->IsValue() )
2669 continue;
2670
2671 newFieldsVec.push_back( field );
2672 }
2673
2674 auto fieldMatches = matchItemsBySimilarity<PCB_FIELD>( oldFieldsVec, newFieldsVec );
2675 std::unordered_map<PCB_FIELD*, PCB_FIELD*> oldToNewFields;
2676 std::unordered_set<PCB_FIELD*> matchedNewFields;
2677
2678 for( const auto& match : fieldMatches )
2679 {
2680 PCB_FIELD* oldField = match.first;
2681 PCB_FIELD* newField = match.second;
2682
2683 oldToNewFields[ oldField ] = newField;
2684 matchedNewFields.insert( newField );
2685 const_cast<KIID&>( newField->m_Uuid ) = oldField->m_Uuid;
2686 }
2687
2688 for( PCB_FIELD* newField : newFieldsVec )
2689 {
2690 if( matchedNewFields.find( newField ) == matchedNewFields.end() )
2691 const_cast<KIID&>( newField->m_Uuid ) = KIID();
2692 }
2693
2694 std::unordered_map<PCB_TEXT*, PCB_TEXT*> oldToNewTexts;
2695
2696 for( const auto& match : drawingMatches )
2697 {
2698 PCB_TEXT* oldText = dynamic_cast<PCB_TEXT*>( match.first );
2699 PCB_TEXT* newText = dynamic_cast<PCB_TEXT*>( match.second );
2700
2701 if( oldText && newText )
2702 oldToNewTexts[ oldText ] = newText;
2703 }
2704
2705 std::set<PCB_TEXT*> handledTextItems;
2706
2707 for( BOARD_ITEM* oldItem : aExisting->GraphicalItems() )
2708 {
2709 PCB_TEXT* oldTextItem = dynamic_cast<PCB_TEXT*>( oldItem );
2710
2711 if( oldTextItem )
2712 {
2713 // Dimensions have PCB_TEXT base but are not treated like texts in the updater
2714 if( dynamic_cast<PCB_DIMENSION_BASE*>( oldTextItem ) )
2715 continue;
2716
2717 PCB_TEXT* newTextItem = nullptr;
2718
2719 auto textMatchIt = oldToNewTexts.find( oldTextItem );
2720
2721 if( textMatchIt != oldToNewTexts.end() )
2722 newTextItem = textMatchIt->second;
2723
2724 if( newTextItem )
2725 {
2726 handledTextItems.insert( newTextItem );
2727 processTextItem( *oldTextItem, *newTextItem, resetTextContent, resetTextLayers,
2728 resetTextEffects, resetTextPositions, aUpdated );
2729 }
2730 else if( deleteExtraTexts )
2731 {
2732 *aUpdated = true;
2733 }
2734 else
2735 {
2736 newTextItem = static_cast<PCB_TEXT*>( oldTextItem->Clone() );
2737 handledTextItems.insert( newTextItem );
2738 aNew->Add( newTextItem );
2739 }
2740 }
2741 }
2742
2743 // Check for any newly-added text items and set the update flag as appropriate
2744 for( BOARD_ITEM* newItem : aNew->GraphicalItems() )
2745 {
2746 PCB_TEXT* newTextItem = dynamic_cast<PCB_TEXT*>( newItem );
2747
2748 if( newTextItem )
2749 {
2750 // Dimensions have PCB_TEXT base but are not treated like texts in the updater
2751 if( dynamic_cast<PCB_DIMENSION_BASE*>( newTextItem ) )
2752 continue;
2753
2754 if( !handledTextItems.contains( newTextItem ) )
2755 {
2756 *aUpdated = true;
2757 break;
2758 }
2759 }
2760 }
2761
2762 // Copy reference. The initial text is always used, never resetted
2763 processTextItem( aExisting->Reference(), aNew->Reference(), false, resetTextLayers,
2764 resetTextEffects, resetTextPositions, aUpdated );
2765
2766 // Copy value
2767 processTextItem( aExisting->Value(), aNew->Value(),
2768 // reset value text only when it is a proxy for the footprint ID
2769 // (cf replacing value "MountingHole-2.5mm" with "MountingHole-4.0mm")
2770 aExisting->GetValue() == aExisting->GetFPID().GetLibItemName().wx_str(),
2771 resetTextLayers, resetTextEffects, resetTextPositions, aUpdated );
2772
2773 std::set<PCB_FIELD*> handledFields;
2774
2775 // Copy fields in accordance with the reset* flags
2776 for( PCB_FIELD* oldField : aExisting->GetFields() )
2777 {
2778 // Reference and value are already handled
2779 if( oldField->IsReference() || oldField->IsValue() )
2780 continue;
2781
2782 PCB_FIELD* newField = nullptr;
2783
2784 auto fieldMatchIt = oldToNewFields.find( oldField );
2785
2786 if( fieldMatchIt != oldToNewFields.end() )
2787 newField = fieldMatchIt->second;
2788
2789 if( newField )
2790 {
2791 handledFields.insert( newField );
2792 processTextItem( *oldField, *newField, resetTextContent, resetTextLayers,
2793 resetTextEffects, resetTextPositions, aUpdated );
2794 }
2795 else if( deleteExtraTexts )
2796 {
2797 *aUpdated = true;
2798 }
2799 else
2800 {
2801 newField = new PCB_FIELD( *oldField );
2802 handledFields.insert( newField );
2803 aNew->Add( newField );
2804 }
2805 }
2806
2807 // Check for any newly-added fields and set the update flag as appropriate
2808 for( PCB_FIELD* newField : aNew->GetFields() )
2809 {
2810 // Reference and value are already handled
2811 if( newField->IsReference() || newField->IsValue() )
2812 continue;
2813
2814 if( !handledFields.contains( newField ) )
2815 {
2816 *aUpdated = true;
2817 break;
2818 }
2819 }
2820
2821 if( resetFabricationAttrs )
2822 {
2823 // We've replaced the existing footprint with the library one, so the fabrication attrs
2824 // are already reset. Just set the aUpdated flag if appropriate.
2825 if( aNew->GetAttributes() != aExisting->GetAttributes() )
2826 *aUpdated = true;
2827 }
2828 else
2829 {
2830 aNew->SetAttributes( aExisting->GetAttributes() );
2831 }
2832
2833 if( resetClearanceOverrides )
2834 {
2835 if( aExisting->AllowSolderMaskBridges() != aNew->AllowSolderMaskBridges() )
2836 *aUpdated = true;
2837
2838 if( ( aExisting->GetLocalClearance() != aNew->GetLocalClearance() )
2839 || ( aExisting->GetLocalSolderMaskMargin() != aNew->GetLocalSolderMaskMargin() )
2840 || ( aExisting->GetLocalSolderPasteMargin() != aNew->GetLocalSolderPasteMargin() )
2842 || ( aExisting->GetLocalZoneConnection() != aNew->GetLocalZoneConnection() ) )
2843 {
2844 *aUpdated = true;
2845 }
2846 }
2847 else
2848 {
2849 aNew->SetLocalClearance( aExisting->GetLocalClearance() );
2853 aNew->SetLocalZoneConnection( aExisting->GetLocalZoneConnection() );
2855 }
2856
2857 if( reset3DModels )
2858 {
2859 // We've replaced the existing footprint with the library one, so the 3D models are
2860 // already reset. Just set the aUpdated flag if appropriate.
2861 if( aNew->Models().size() != aExisting->Models().size() )
2862 {
2863 *aUpdated = true;
2864 }
2865 else
2866 {
2867 for( size_t ii = 0; ii < aNew->Models().size(); ++ii )
2868 {
2869 if( aNew->Models()[ii] != aExisting->Models()[ii] )
2870 {
2871 *aUpdated = true;
2872 break;
2873 }
2874 }
2875 }
2876 }
2877 else
2878 {
2879 aNew->Models() = aExisting->Models(); // Linked list of 3D models.
2880 }
2881
2882 // Updating other parameters
2883 aNew->SetPath( aExisting->GetPath() );
2884 aNew->SetSheetfile( aExisting->GetSheetfile() );
2885 aNew->SetSheetname( aExisting->GetSheetname() );
2886 aNew->SetFilters( aExisting->GetFilters() );
2887 aNew->SetStaticComponentClass( aExisting->GetComponentClass() );
2888
2889 if( *aUpdated == false )
2890 {
2891 // Check pad shapes, graphics, zones, etc. for changes
2893 *aUpdated = true;
2894 }
2895
2896 aCommit.Remove( aExisting );
2897 aCommit.Add( aNew );
2898
2899 aNew->ClearFlags();
2900}
2901
2902
2904{
2906
2908
2909 SetElementVisibility( LAYER_RATSNEST, GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest );
2910
2912
2913 // Netclass definitions could have changed, either by us or by Eeschema, so we need to
2914 // recompile the implicit rules
2915 DRC_TOOL* drcTool = m_toolManager->GetTool<DRC_TOOL>();
2916 WX_INFOBAR* infobar = GetInfoBar();
2917
2918 try
2919 {
2921
2922 if( infobar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::DRC_RULES_ERROR )
2923 infobar->Dismiss();
2924 }
2925 catch( PARSE_ERROR& )
2926 {
2927 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _( "Edit design rules" ),
2928 wxEmptyString );
2929
2930 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
2931 [&]( wxHyperlinkEvent& aEvent )
2932 {
2933 ShowBoardSetupDialog( _( "Custom Rules" ) );
2934 } ) );
2935
2936 infobar->RemoveAllButtons();
2937 infobar->AddButton( button );
2938 infobar->AddCloseButton();
2939 infobar->ShowMessage( _( "Could not compile custom design rules." ), wxICON_ERROR,
2941 }
2942
2945
2946 // Update the environment variables in the Python interpreter
2947 if( aFlags & ENVVARS_CHANGED )
2949
2950 Layout();
2951 SendSizeEvent();
2952}
2953
2954
2959
2960
2965
2966
2968{
2969 // For now, be conservative: Don't allow any API use while the user is changing things
2970 if( GetToolManager()->GetCurrentTool() != GetToolManager()->GetTool<PCB_SELECTION_TOOL>() )
2971 return false;
2972
2973 ZONE_FILLER_TOOL* zoneFillerTool = m_toolManager->GetTool<ZONE_FILLER_TOOL>();
2974
2975 if( zoneFillerTool->IsBusy() )
2976 return false;
2977
2978 ROUTER_TOOL* routerTool = m_toolManager->GetTool<ROUTER_TOOL>();
2979
2980 if( routerTool && routerTool->RoutingInProgress() )
2981 return false;
2982
2984}
2985
2986
2987
2989{
2990 return GetBoard()->GetFileName();
2991}
2992
2993
2995{
2996 return m_auimgr.GetPane( wxS( "LayersManager" ) ).IsShown();
2997}
2998
2999
3001{
3002 return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
3003}
3004
3005
3007{
3008 return m_auimgr.GetPane( NetInspectorPanelName() ).IsShown();
3009}
3010
3011
3012void PCB_EDIT_FRAME::onSize( wxSizeEvent& aEvent )
3013{
3014 if( IsShownOnScreen() )
3015 {
3016 // We only need this until the frame is done resizing and the final client size is
3017 // established.
3018 Unbind( wxEVT_SIZE, &PCB_EDIT_FRAME::onSize, this );
3020 }
3021
3022 // Skip() is called in the base class.
3023 EDA_DRAW_FRAME::OnSize( aEvent );
3024}
3025
3026
3037
3038
3049
3050
3061
3062
3064{
3065 if( !m_footprintDiffDlg )
3066 {
3068 _( "Compare Footprint with Library" ) );
3069 }
3070
3071 return m_footprintDiffDlg;
3072}
3073
3074
3076{
3077 if( m_inspectDrcErrorDlg && aEvent.GetString() == INSPECT_DRC_ERROR_DIALOG_NAME )
3078 {
3079 m_inspectDrcErrorDlg->Destroy();
3080 m_inspectDrcErrorDlg = nullptr;
3081 }
3082 else if( m_inspectClearanceDlg && aEvent.GetString() == INSPECT_CLEARANCE_DIALOG_NAME )
3083 {
3084 m_inspectClearanceDlg->Destroy();
3085 m_inspectClearanceDlg = nullptr;
3086 }
3087 else if( m_inspectConstraintsDlg && aEvent.GetString() == INSPECT_CONSTRAINTS_DIALOG_NAME )
3088 {
3089 m_inspectConstraintsDlg->Destroy();
3090 m_inspectConstraintsDlg = nullptr;
3091 }
3092 else if( m_footprintDiffDlg && aEvent.GetString() == INSPECT_CONSTRAINTS_DIALOG_NAME )
3093 {
3094 m_footprintDiffDlg->Destroy();
3095 m_footprintDiffDlg = nullptr;
3096 }
3097}
3098
3099#ifdef KICAD_IPC_API
3100void PCB_EDIT_FRAME::onPluginAvailabilityChanged( wxCommandEvent& aEvt )
3101{
3102 wxLogTrace( traceApi, "PCB frame: EDA_EVT_PLUGIN_AVAILABILITY_CHANGED" );
3104 aEvt.Skip();
3105}
3106#endif
3107
3108
3110{
3111 PCB_LAYER_ID curLayer = GetActiveLayer();
3112 const PCB_DISPLAY_OPTIONS& displ_opts = GetDisplayOptions();
3113
3114 // Check if the specified layer matches the present layer
3115 if( layer == curLayer )
3116 return;
3117
3118 // Copper layers cannot be selected unconditionally; how many of those layers are currently
3119 // enabled needs to be checked.
3120 if( IsCopperLayer( layer ) )
3121 {
3122 if( layer > GetBoard()->GetCopperLayerStackMaxId() )
3123 return;
3124 }
3125
3126 // Is yet more checking required? E.g. when the layer to be selected is a non-copper layer,
3127 // or when switching between a copper layer and a non-copper layer, or vice-versa?
3128
3129 SetActiveLayer( layer );
3130
3132 GetCanvas()->Refresh();
3133}
3134
3135
3137{
3138 switch( aItem->Type() )
3139 {
3142 break;
3143
3144 case PCB_FIELD_T:
3145 case PCB_TEXT_T:
3146 ShowTextPropertiesDialog( static_cast<PCB_TEXT*>( aItem ) );
3147 break;
3148
3149 case PCB_TEXTBOX_T:
3150 ShowTextBoxPropertiesDialog( static_cast<PCB_TEXTBOX*>( aItem ) );
3151 break;
3152
3153 case PCB_TABLE_T:
3154 {
3155 DIALOG_TABLE_PROPERTIES dlg( this, static_cast<PCB_TABLE*>( aItem ) );
3156
3157 //QuasiModal required for Scintilla auto-complete
3158 dlg.ShowQuasiModal();
3159 break;
3160 }
3161
3162 case PCB_PAD_T:
3163 ShowPadPropertiesDialog( static_cast<PAD*>( aItem ) );
3164 break;
3165
3166 case PCB_FOOTPRINT_T:
3167 ShowFootprintPropertiesDialog( static_cast<FOOTPRINT*>( aItem ) );
3168 break;
3169
3170 case PCB_TARGET_T:
3171 ShowTargetOptionsDialog( static_cast<PCB_TARGET*>( aItem ) );
3172 break;
3173
3174 case PCB_DIM_ALIGNED_T:
3175 case PCB_DIM_CENTER_T:
3176 case PCB_DIM_RADIAL_T:
3178 case PCB_DIM_LEADER_T:
3179 {
3180 DIALOG_DIMENSION_PROPERTIES dlg( this, static_cast<PCB_DIMENSION_BASE*>( aItem ) );
3181
3182 // TODO: why is this QuasiModal?
3183 dlg.ShowQuasiModal();
3184 break;
3185 }
3186
3187 case PCB_SHAPE_T:
3188 ShowGraphicItemPropertiesDialog( static_cast<PCB_SHAPE*>( aItem ) );
3189 break;
3190
3191 case PCB_ZONE_T:
3192 Edit_Zone_Params( static_cast<ZONE*>( aItem ) );
3193 break;
3194
3195 case PCB_GROUP_T:
3197 static_cast<EDA_GROUP*>( static_cast<PCB_GROUP*>( aItem ) ) );
3198 break;
3199
3200 case PCB_GENERATOR_T:
3201 static_cast<PCB_GENERATOR*>( aItem )->ShowPropertiesDialog( this );
3202 break;
3203
3204 case PCB_MARKER_T:
3205 m_toolManager->GetTool<DRC_TOOL>()->CrossProbe( static_cast<PCB_MARKER*>( aItem ) );
3206 break;
3207
3208 case PCB_POINT_T:
3209 break;
3210
3211 default:
3212 break;
3213 }
3214}
Class PCBNEW_ACTION_PLUGINS.
const KICOMMON_API wxEventTypeTag< wxCommandEvent > EDA_EVT_PLUGIN_AVAILABILITY_CHANGED
Notifies other parts of KiCad when plugin availability changes.
@ KEEP_ENDPOINTS_OR_START_DIRECTION
Whe editing endpoints, the other end remains in place.
@ KEEP_CENTER_ENDS_ADJUST_ANGLE
When editing endpoints, only the angle is adjusted.
@ KEEP_CENTER_ADJUST_ANGLE_RADIUS
When editing endpoints, the angle and radius are adjusted.
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:112
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition bitmap.cpp:104
@ NORMAL
Inactive layers are shown normally (no high-contrast mode)
@ HIDDEN
Inactive layers are hidden.
constexpr BOX2I BOX2ISafe(const BOX2D &aInput)
Definition box2.h:929
BOX2< VECTOR2D > BOX2D
Definition box2.h:923
static TOOL_ACTION toggleGrid
Definition actions.h:197
static TOOL_ACTION paste
Definition actions.h:80
static TOOL_ACTION millimetersUnits
Definition actions.h:205
static TOOL_ACTION unselectAll
Definition actions.h:83
static TOOL_ACTION cursorSmallCrosshairs
Definition actions.h:151
static TOOL_ACTION togglePolarCoords
Definition actions.h:208
static TOOL_ACTION copy
Definition actions.h:78
static TOOL_ACTION pluginsReload
Definition actions.h:295
static TOOL_ACTION group
Definition actions.h:238
static TOOL_ACTION pasteSpecial
Definition actions.h:81
static TOOL_ACTION groupProperties
Definition actions.h:246
static TOOL_ACTION pointEditorArcKeepCenter
Definition actions.h:274
static TOOL_ACTION milsUnits
Definition actions.h:204
static TOOL_ACTION ungroup
Definition actions.h:239
static TOOL_ACTION toggleBoundingBoxes
Definition actions.h:156
static TOOL_ACTION pointEditorArcKeepRadius
Definition actions.h:276
static TOOL_ACTION showSearch
Definition actions.h:115
static TOOL_ACTION undo
Definition actions.h:75
static TOOL_ACTION duplicate
Definition actions.h:84
static TOOL_ACTION inchesUnits
Definition actions.h:203
static TOOL_ACTION highContrastMode
Definition actions.h:154
static TOOL_ACTION embeddedFiles
Definition actions.h:298
static TOOL_ACTION measureTool
Definition actions.h:251
static TOOL_ACTION doDelete
Definition actions.h:85
static TOOL_ACTION selectionTool
Definition actions.h:250
static TOOL_ACTION save
Definition actions.h:58
static TOOL_ACTION zoomFitScreen
Definition actions.h:141
static TOOL_ACTION redo
Definition actions.h:76
static TOOL_ACTION deleteTool
Definition actions.h:86
static TOOL_ACTION zoomTool
Definition actions.h:145
static TOOL_ACTION cursor45Crosshairs
Definition actions.h:153
static TOOL_ACTION showProperties
Definition actions.h:265
static TOOL_ACTION cut
Definition actions.h:77
static TOOL_ACTION gridSetOrigin
Definition actions.h:194
static TOOL_ACTION toggleGridOverrides
Definition actions.h:198
static TOOL_ACTION selectAll
Definition actions.h:82
static TOOL_ACTION pointEditorArcKeepEndpoint
Definition actions.h:275
static TOOL_ACTION cursorFullCrosshairs
Definition actions.h:152
Manage TOOL_ACTION objects.
void SetConditions(const TOOL_ACTION &aAction, const ACTION_CONDITIONS &aConditions)
Set the conditions the UI elements for activating a specific tool action should use for determining t...
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void OnColorThemeChanged()
Respond to change in OS's DarkMode.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
The array tool.
Definition array_tool.h:48
Tool responsible for automagic placement of components.
Handles how to draw a screen (a board, a schematic ...)
Definition base_screen.h:41
int GetPageCount() const
Definition base_screen.h:72
bool IsContentModified() const
Definition base_screen.h:60
const wxString & GetPageNumber() const
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
void SetLocalRatsnestVisible(bool aVisible)
Handle actions specific to the board editor in PcbNew.
Tool for pcb inspection.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:79
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:232
void SetLocked(bool aLocked) override
Definition board_item.h:323
bool IsLocked() const override
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition board_item.h:314
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:280
VECTOR2I GetFPRelativePosition() const
@ INSTANCE_TO_INSTANCE
Definition board_item.h:436
void SetFPRelativePosition(const VECTOR2I &aPos)
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:317
void BuildListOfNets()
Definition board.h:896
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition board.cpp:989
void RemoveAllListeners()
Remove all listeners.
Definition board.cpp:2853
const PAGE_INFO & GetPageSettings() const
Definition board.h:741
GAL_SET GetVisibleElements() const
Return a set of all the element categories that are visible.
Definition board.cpp:983
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition board.cpp:188
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:2287
void SynchronizeTimeDomainProperties()
Ensure that all time domain properties providers are in sync with current settings.
Definition board.cpp:2281
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:198
const wxString & GetFileName() const
Definition board.h:354
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Change the visibility of an element category.
Definition board.cpp:995
void ClearProject()
Definition board.cpp:236
bool IsEmpty() const
Definition board.cpp:559
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition board.cpp:1956
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition board.cpp:923
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition board.cpp:300
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition board.h:521
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:558
void SetColor(int aLayer, const COLOR4D &aColor)
COLOR4D GetColor(int aLayer) const
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
Definition commit.h:90
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:106
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition commit.h:78
Handle actions that are shared between different applications.
Handles action that are shared between different applications.
enum FP_PROPS_RETVALUE GetReturnValue()
Tool responsible for drawing graphical elements like lines, arcs, circles, etc.
MODE GetDrawingMode() const
Return the current drawing mode of the DRAWING_TOOL or MODE::NONE if not currently in any drawing mod...
void InitEngine(const wxFileName &aRulePath)
Initialize the DRC engine.
std::shared_ptr< DRC_ENGINE > GetDRCEngine()
Definition drc_tool.h:80
bool IsDRCRunning() const
Check to see if the DRC engine is running the tests.
Definition drc_tool.h:73
void SetSheetPath(const std::string &aSheetPath)
Set the sheet path displayed in the title block.
void SetSheetCount(int aSheetCount)
Change the sheet-count number displayed in the title block.
void SetPageNumber(const std::string &aPageNumber)
Change the page number displayed in the title block.
void SetSheetName(const std::string &aSheetName)
Set the sheet name displayed in the title block.
void SetIsFirstPage(bool aIsFirstPage)
Change if this is first page.
void SetFileName(const std::string &aFileName)
Set the file name displayed in the title block.
void CommonSettingsChanged(int aFlags) override
Notification event that some of the common (suite-wide) settings have changed.
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
virtual void setupUIConditions()
Setup the UI conditions for the various actions and their controls in this frame.
virtual void ThemeChanged()
Process light/dark theme change.
WX_INFOBAR * m_infoBar
wxAuiManager m_auimgr
virtual bool CanAcceptApiCommands()
Check if this frame is ready to accept API commands.
virtual void OnSize(wxSizeEvent &aEvent)
virtual bool canCloseWindow(wxCloseEvent &aCloseEvent)
virtual int GetUndoCommandCount() const
bool m_isClosing
Set by the close window event handler after frames are asked if they can close.
WX_INFOBAR * GetInfoBar()
static const wxString AppearancePanelName()
virtual wxString GetFullScreenDesc() const
void OnSelectGrid(wxCommandEvent &event)
Command event handler for selecting grid sizes.
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
virtual void SwitchCanvas(EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType)
Change the current rendering backend.
virtual void OnSize(wxSizeEvent &event) override
Recalculate the size of toolbars and display panel when the frame size changes.
virtual void OnSelectZoom(wxCommandEvent &event)
Set the zoom factor when selected by the zoom list box in the main tool bar.
GAL_DISPLAY_OPTIONS_IMPL & GetGalDisplayOptions()
Return a reference to the gal rendering options used by GAL for rendering.
virtual wxString GetScreenDesc() const
static const wxString PropertiesPaneName()
virtual void ReCreateAuxiliaryToolbar()
virtual void ReCreateHToolbar()
virtual void Zoom_Automatique(bool aWarpPointer)
Redraw the screen with best zoom level and the best centering that shows all the page or the board.
NET_INSPECTOR_PANEL * m_netInspectorPanel
static const wxString NetInspectorPanelName()
SEARCH_PANE * m_searchPane
static const wxString DesignBlocksPaneName()
PROPERTIES_PANEL * m_propertiesPanel
static constexpr GAL_TYPE GAL_FALLBACK
void StopDrawing()
Prevent the GAL canvas from further drawing until it is recreated or StartDrawing() is called.
void ForceRefresh()
Force a redraw.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
KIGFX::GAL * GetGAL() const
Return a pointer to the GAL instance used in the panel.
void SetFocus() override
A set of EDA_ITEMs (i.e., without duplicates).
Definition eda_group.h:46
void RemoveItem(EDA_ITEM *aItem)
Remove item from group.
Definition eda_group.cpp:40
void AddItem(EDA_ITEM *aItem)
Add item to group.
Definition eda_group.cpp:27
virtual EDA_ITEM * AsEdaItem()=0
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
const KIID m_Uuid
Definition eda_item.h:516
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:116
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition eda_item.h:144
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.h:113
Specialization of the wxAuiPaneInfo class for KiCad panels.
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:79
const EDA_ANGLE & GetTextAngle() const
Definition eda_text.h:146
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:97
virtual bool IsVisible() const
Definition eda_text.h:186
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:434
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:199
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:387
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:202
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:271
int GetTextThickness() const
Definition eda_text.h:127
VECTOR2I GetTextSize() const
Definition eda_text.h:260
SELECTION_CONDITION NoActiveTool()
Create a functor testing if there are no tools active in the frame.
SELECTION_CONDITION BoundingBoxes()
SELECTION_CONDITION RedoAvailable()
Create a functor that tests if there are any items in the redo queue.
SELECTION_CONDITION ScriptingConsoleVisible()
Create a functor testing if the python scripting console window is visible.
SELECTION_CONDITION Units(EDA_UNITS aUnit)
Create a functor that tests if the frame has the specified units.
SELECTION_CONDITION CursorSmallCrosshairs()
Create a functor testing if the cursor is full screen in a frame.
SELECTION_CONDITION GridVisible()
Create a functor testing if the grid is visible in a frame.
SELECTION_CONDITION PolarCoordinates()
Create a functor testing if polar coordinates are current being used.
SELECTION_CONDITION GridOverrides()
Create a functor testing if the grid overrides wires is enabled in a frame.
SELECTION_CONDITION Cursor45Crosshairs()
SELECTION_CONDITION CursorFullCrosshairs()
The interactive edit tool.
Definition edit_tool.h:56
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition property.h:705
static ENUM_MAP< T > & Instance()
Definition property.h:699
ENUM_MAP & Undefined(T aValue)
Definition property.h:712
wxPGChoices & Choices()
Definition property.h:748
void LoadFootprintFromLibrary(LIB_ID aFPID)
bool LoadFootprintFromBoard(FOOTPRINT *aFootprint)
Load a footprint from the main board into the Footprint Editor.
Component library viewer main window.
bool AllowSolderMaskBridges() const
Definition footprint.h:333
void SetPosition(const VECTOR2I &aPos) override
ZONE_CONNECTION GetLocalZoneConnection() const
Definition footprint.h:309
void SetLocked(bool isLocked) override
Set the #MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition footprint.h:464
EDA_ANGLE GetOrientation() const
Definition footprint.h:248
ZONES & Zones()
Definition footprint.h:230
PCB_POINTS & Points()
Definition footprint.h:236
void SetOrientation(const EDA_ANGLE &aNewAngle)
void SetAllowSolderMaskBridges(bool aAllow)
Definition footprint.h:334
void SetLocalSolderPasteMarginRatio(std::optional< double > aRatio)
Definition footprint.h:306
wxString GetSheetname() const
Definition footprint.h:287
void SetPath(const KIID_PATH &aPath)
Definition footprint.h:285
void SetFilters(const wxString &aFilters)
Definition footprint.h:294
void SetStaticComponentClass(const COMPONENT_CLASS *aClass) const
Sets the component class object pointer for this footprint.
bool FootprintNeedsUpdate(const FOOTPRINT *aLibFP, int aCompareFlags=0, REPORTER *aReporter=nullptr)
Return true if a board footprint differs from the library version.
void SetAttributes(int aAttributes)
Definition footprint.h:328
void SetSheetfile(const wxString &aSheetfile)
Definition footprint.h:291
std::optional< int > GetLocalSolderPasteMargin() const
Definition footprint.h:302
PCB_FIELD & Value()
read/write accessors:
Definition footprint.h:697
std::optional< int > GetLocalClearance() const
Definition footprint.h:296
std::deque< PAD * > & Pads()
Definition footprint.h:224
int GetAttributes() const
Definition footprint.h:327
const COMPONENT_CLASS * GetComponentClass() const
Returns the component class for this footprint.
void SetLocalZoneConnection(ZONE_CONNECTION aType)
Definition footprint.h:308
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition footprint.h:257
wxString GetSheetfile() const
Definition footprint.h:290
const LIB_ID & GetFPID() const
Definition footprint.h:269
bool IsLocked() const override
Definition footprint.h:454
PCB_FIELD & Reference()
Definition footprint.h:698
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
std::optional< double > GetLocalSolderPasteMarginRatio() const
Definition footprint.h:305
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
GROUPS & Groups()
Definition footprint.h:233
wxString GetFilters() const
Definition footprint.h:293
void SetSheetname(const wxString &aSheetname)
Definition footprint.h:288
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly) const
Populate a std::vector with PCB_TEXTs.
std::vector< FP_3DMODEL > & Models()
Definition footprint.h:241
const wxString & GetValue() const
Definition footprint.h:683
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition footprint.h:300
void SetLocalClearance(std::optional< int > aClearance)
Definition footprint.h:297
const KIID_PATH & GetPath() const
Definition footprint.h:284
std::optional< int > GetLocalSolderMaskMargin() const
Definition footprint.h:299
void SetLocalSolderPasteMargin(std::optional< int > aMargin)
Definition footprint.h:303
VECTOR2I GetPosition() const override
Definition footprint.h:245
DRAWINGS & GraphicalItems()
Definition footprint.h:227
void ReadWindowSettings(WINDOW_SETTINGS &aCfg)
Read GAL config options from application-level config.
bool Contains(GAL_LAYER_ID aPos)
Definition layer_ids.h:436
Handle actions specific to filling copper zones.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual const wxString Problem() const
what was the problem?
virtual const wxString Where() const
where did the Problem() occur?
Read the new s-expression based KiCad netlist format.
virtual void LoadNetlist() override
Load the contents of the netlist file into aNetlist.
APP_SETTINGS_BASE * KifaceSettings() const
Definition kiface_base.h:95
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:104
void SetGridColor(const COLOR4D &aGridColor)
Set the grid color.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition pcb_view.cpp:91
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const std::set< int > & GetHighlightNetCodes() const
Return the netcode of currently highlighted net.
An abstract base class for deriving all objects that can be added to a VIEW.
Definition view_item.h:86
bool IsBOARD_ITEM() const
Definition view_item.h:102
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:66
double GetScale() const
Definition view.h:276
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition view.cpp:530
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition view.cpp:1685
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition view.h:400
bool IsMirroredX() const
Return true if view is flipped across the X axis.
Definition view.h:250
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:1561
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition view.h:220
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition view.h:639
void UpdateAllItemsConditionally(int aUpdateFlags, std::function< bool(VIEW_ITEM *)> aCondition)
Update items in the view according to the given flags and condition.
Definition view.cpp:1571
An implementation of class VIEW_CONTROLS for wxWidgets library.
std::unique_ptr< PROF_COUNTER > m_MotionEventCounter
Definition kiid.h:49
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual bool OpenProjectFiles(const std::vector< wxString > &aFileList, int aCtl=0)
Open a project or set of files given by aFileList.
void OnSockRequestServer(wxSocketEvent &evt)
Definition eda_dde.cpp:99
void OnSockRequest(wxSocketEvent &evt)
Definition eda_dde.cpp:69
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:286
void OnKiCadExit()
Definition kiway.cpp:717
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:395
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
Definition kiway.cpp:499
virtual void CommonSettingsChanged(int aFlags=0)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition kiway.cpp:589
PCB_LAYER_ID GetLayerA() const
PCB_LAYER_ID GetLayerB() const
const UTF8 & GetLibItemName() const
Definition lib_id.h:102
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition lset.cpp:296
static const LSET & AllLayersMask()
Definition lset.cpp:624
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition lset.cpp:188
@ MARKER_DRAWING_SHEET
Definition marker_base.h:56
Tool responsible for adding microwave features to PCBs.
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition netinfo.h:365
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
Definition pad.h:54
void SetPinType(const wxString &aType)
Set the pad electrical type.
Definition pad.h:152
const wxString & GetPinType() const
Definition pad.h:153
const wxString & GetPinFunction() const
Definition pad.h:147
bool IsOnCopperLayer() const override
Definition pad.cpp:1083
void SetPinFunction(const wxString &aName)
Set the pad function (pin name in schematic)
Definition pad.h:146
void SetInitialPage(const wxString &aPage, const wxString &aParentPage=wxEmptyString)
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition page_info.h:79
DISPLAY_OPTIONS m_Display
EDA_ANGLE m_RotationAngle
ARC_EDIT_MODE m_ArcEditMode
LEADER_MODE m_AngleSnapMode
AUI_PANELS m_AuiPanels
Gather all the actions that are shared by tools.
Definition pcb_actions.h:51
static TOOL_ACTION toggleHV45Mode
static TOOL_ACTION drawRuleArea
static TOOL_ACTION microwaveCreateGap
static TOOL_ACTION drawBezier
static TOOL_ACTION placeText
static TOOL_ACTION drawOrthogonalDimension
static TOOL_ACTION drawRectangle
static TOOL_ACTION padDisplayMode
static TOOL_ACTION placeReferenceImage
static TOOL_ACTION showRatsnest
static TOOL_ACTION showLayersManager
static TOOL_ACTION toggleNetHighlight
static TOOL_ACTION saveSelectionAsDesignBlock
static TOOL_ACTION drawCircle
static TOOL_ACTION routeDiffPair
Activation of the Push and Shove router (differential pair mode)
static TOOL_ACTION tuneDiffPair
static TOOL_ACTION saveToLinkedDesignBlock
static TOOL_ACTION layerChanged
static TOOL_ACTION ddAppendBoard
Drag and drop.
static TOOL_ACTION highlightNet
static TOOL_ACTION autoTrackWidth
static TOOL_ACTION drawTable
static TOOL_ACTION drawTextBox
static TOOL_ACTION routerHighlightMode
Actions to enable switching modes via hotkey assignments.
static TOOL_ACTION routerWalkaroundMode
static TOOL_ACTION routerShoveMode
static TOOL_ACTION drawZoneCutout
static TOOL_ACTION drawPolygon
static TOOL_ACTION hideNetInRatsnest
static TOOL_ACTION zoneDisplayFilled
static TOOL_ACTION showNetInRatsnest
static TOOL_ACTION drawRadialDimension
static TOOL_ACTION tuneSingleTrack
static TOOL_ACTION viaDisplayMode
static TOOL_ACTION drawLeader
static TOOL_ACTION saveBoardAsDesignBlock
static TOOL_ACTION drillOrigin
static TOOL_ACTION tuneSkew
static TOOL_ACTION trackDisplayMode
static TOOL_ACTION showNetInspector
static TOOL_ACTION microwaveCreateStubArc
static TOOL_ACTION zoneDisplayTriangulated
static TOOL_ACTION placeDesignBlock
static TOOL_ACTION selectUnconnected
Select unconnected footprints from ratsnest of selection.
Definition pcb_actions.h:88
static TOOL_ACTION zoneDisplayFractured
static TOOL_ACTION drawVia
static TOOL_ACTION drawArc
static TOOL_ACTION zoneDuplicate
Duplicate zone onto another layer.
static TOOL_ACTION graphicsOutlines
Display footprint graphics as outlines.
static TOOL_ACTION drawSimilarZone
static TOOL_ACTION showDesignBlockPanel
static TOOL_ACTION drawCenterDimension
static TOOL_ACTION selectSameSheet
Select all components on the same sheet as the selected footprint.
Definition pcb_actions.h:97
static TOOL_ACTION microwaveCreateStub
static TOOL_ACTION selectNet
Select all connections belonging to a single net.
Definition pcb_actions.h:82
static TOOL_ACTION ddImportGraphics
static TOOL_ACTION microwaveCreateLine
static TOOL_ACTION flipBoard
static TOOL_ACTION zoneDisplayOutline
static TOOL_ACTION ratsnestLineMode
static TOOL_ACTION textOutlines
Display texts as lines.
static TOOL_ACTION highlightNetSelection
static TOOL_ACTION microwaveCreateFunctionShape
static TOOL_ACTION placePoint
static TOOL_ACTION zoneMerge
static TOOL_ACTION unlock
static TOOL_ACTION placeFootprint
static TOOL_ACTION routeSingleTrack
Activation of the Push and Shove router.
static TOOL_ACTION createArray
Tool for creating an array of objects.
static TOOL_ACTION deselectNet
Remove all connections belonging to a single net from the active selection.
Definition pcb_actions.h:85
static TOOL_ACTION showPythonConsole
static TOOL_ACTION drawLine
static TOOL_ACTION placeLinkedDesignBlock
static TOOL_ACTION localRatsnestTool
static TOOL_ACTION drawAlignedDimension
static TOOL_ACTION drawZone
static TOOL_ACTION selectOnSchematic
Select symbols/pins on schematic corresponding to selected footprints/pads.
static TOOL_ACTION lock
Common, abstract interface for edit frames.
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
void doCloseWindow() override
int ShowTextBoxPropertiesDialog(PCB_TEXTBOX *aTextBox)
void unitsChangeRefresh() override
Called when when the units setting has changed to allow for any derived classes to handle refreshing ...
PCB_LAYER_BOX_SELECTOR * m_SelLayerBox
virtual void SetBoard(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr) override
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
std::unique_ptr< LAYER_PAIR_SETTINGS > m_layerPairSettings
APPEARANCE_CONTROLS * GetAppearancePanel()
APPEARANCE_CONTROLS * m_appearancePanel
void ShowReferenceImagePropertiesDialog(BOARD_ITEM *aBitmap)
Set the angle used for rotate operations.
PANEL_SELECTION_FILTER * m_selectionFilterPanel
void ShowGraphicItemPropertiesDialog(PCB_SHAPE *aShape)
void ActivateGalCanvas() override
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
void ShowPadPropertiesDialog(PAD *aPad)
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
PCBNEW_SETTINGS * GetPcbNewSettings() const
virtual PCB_LAYER_ID GetActiveLayer() const
void OnModify() override
Must be called after a change in order to set the "modify" flag and update other data structures and ...
virtual MAGNETIC_SETTINGS * GetMagneticItemsSettings()
EDA_ITEM * ResolveItem(const KIID &aId, bool aAllowNullptrReturn=false) const override
Fetch an item by KIID.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
virtual void SetPageSettings(const PAGE_INFO &aPageSettings) override
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
BOARD * GetBoard() const
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Return the BOARD_DESIGN_SETTINGS for the open project.
void PlaceFootprint(FOOTPRINT *aFootprint, bool aRecreateRatsnest=true)
Place aFootprint at the current cursor position and updates footprint coordinates with the new positi...
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
Handle actions that are shared between different frames in PcbNew.
Definition pcb_control.h:47
Handle design block actions in the PCB editor.
Abstract dimension API.
double m_ZoneOpacity
Opacity override for filled zone areas.
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
void UpdateColors()
Update the color settings in the painter and GAL.
void SetDrawingSheet(DS_PROXY_VIEW_ITEM *aDrawingSheet)
Sets (or updates) drawing-sheet used by the draw panel.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void SyncLayersVisibility(const BOARD *aBoard)
Update "visibility" property of each layer of a given BOARD.
virtual void SetHighContrastLayer(int aLayer) override
SetHighContrastLayer(), with some extra smarts for PCB.
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
Group generic conditions for PCB editor states.
SELECTION_CONDITION PadFillDisplay()
Create a functor that tests if the frame fills the pads.
SELECTION_CONDITION TrackFillDisplay()
Create a functor that tests if the frame fills tracks.
SELECTION_CONDITION HasItems()
Create a functor that tests if there are items in the board.
SELECTION_CONDITION GraphicsFillDisplay()
Create a functor that tests if the frame fills graphics items.
SELECTION_CONDITION ZoneDisplayMode(ZONE_DISPLAY_MODE aMode)
Create a functor that tests the current zone display mode in the frame.
SELECTION_CONDITION ViaFillDisplay()
Create a functor that tests if the frame fills vias.
SELECTION_CONDITION Get45degMode()
Create a functor that tests whether angle constraints are enabled.
SELECTION_CONDITION TextFillDisplay()
Create a functor that tests if the frame fills text items.
The main frame for Pcbnew.
void HardRedraw() override
Rebuild the GAL and redraws the screen.
void OnDisplayOptionsChanged() override
void OnEditItemRequest(BOARD_ITEM *aItem) override
Install the corresponding dialog editor for the given item.
Definition edit.cpp:98
void SetLastPath(LAST_PATH_TYPE aType, const wxString &aLastPath)
Set the path of the last file successfully read.
int m_crossProbeFlashPhase
Phase counter.
void FindNext(bool reverse=false)
Find the next item using our existing search parameters.
void ResolveDRCExclusions(bool aCreateMarkers)
If aCreateMarkers then create DRC exclusion markers from the serialized data.
void SetBoard(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr) override
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
void SetActiveLayer(PCB_LAYER_ID aLayer) override
Change the currently active layer to aLayer and also update the APPEARANCE_CONTROLS.
void OnModify() override
Must be called after a board change to set the modified flag.
void ThemeChanged() override
Called when light/dark theme is changed.
void SwitchLayer(PCB_LAYER_ID layer) override
Change the active layer in the editor.
Definition edit.cpp:71
wxTimer m_crossProbeFlashTimer
Timer to toggle selection visibility for flash.
void StartCrossProbeFlash(const std::vector< BOARD_ITEM * > &aItems)
void OnCrossProbeFlashTimer(wxTimerEvent &aEvent)
void setupUIConditions() override
Setup the UI conditions for the various actions and their controls in this frame.
void SetElementVisibility(GAL_LAYER_ID aElement, bool aNewState)
Change the visibility of an element category.
DIALOG_BOOK_REPORTER * m_inspectDrcErrorDlg
void OnClearFileHistory(wxCommandEvent &aEvent)
std::unique_ptr< GRID_HELPER > MakeGridHelper() override
virtual ~PCB_EDIT_FRAME()
void SwitchCanvas(EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType) override
Switch currently used canvas (Cairo / OpenGL).
void CommonSettingsChanged(int aFlags) override
Called after the preferences dialog is run.
BOARD_ITEM_CONTAINER * GetModel() const override
DIALOG_BOOK_REPORTER * GetInspectDrcErrorDialog()
void ShowTargetOptionsDialog(PCB_TARGET *aTarget)
void ShowBoardSetupDialog(const wxString &aInitialPage=wxEmptyString, wxWindow *aParent=nullptr)
DIALOG_FIND * m_findDialog
DIALOG_BOOK_REPORTER * m_inspectConstraintsDlg
void SetPageSettings(const PAGE_INFO &aPageSettings) override
bool IsElementVisible(GAL_LAYER_ID aElement) const
Test whether a given element category is visible.
bool CanAcceptApiCommands() override
Check if this frame is ready to accept API commands.
void UpdateUserInterface()
Update the layer manager and other widgets from the board setup (layer and items visibility,...
void SetGridColor(const COLOR4D &aColor) override
void ProjectChanged() override
Notification event that the project has changed.
wxString GetLastPath(LAST_PATH_TYPE aType)
Get the last path for a particular type.
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
void doCloseWindow() override
void ReCreateLayerBox(bool aForceResizeToolbar=true)
Recreate the layer box by clearing the old list and building a new one from the new layer names and c...
void SaveProjectLocalSettings() override
Save changes to the project local settings.
void PythonSyncProjectName()
Synchronize the project name from KiCad's environment into the Python interpreter.
bool m_show_layer_manager_tools
void ShowFindDialog()
Show the Find dialog.
void onSize(wxSizeEvent &aEvent)
int ShowExchangeFootprintsDialog(FOOTPRINT *aFootprint, bool aUpdateMode, bool aSelectedMode)
int TestStandalone()
Test if standalone mode.
void ShowFootprintPropertiesDialog(FOOTPRINT *aFootprint)
bool IsContentModified() const override
Get if the current board has been modified but not saved.
void PythonSyncEnvironmentVariables()
Synchronize the environment variables from KiCad's environment into the Python interpreter.
bool Clear_Pcb(bool doAskAboutUnsavedChanges, bool aFinal=false)
Delete all and reinitialize the current board.
Definition initpcb.cpp:42
bool m_crossProbeFlashing
Currently flashing guard.
TOOL_ACTION * m_exportNetlistAction
The export board netlist tool action object.
void OnBoardLoaded()
Update the state of the GUI after a new board is loaded or created.
void Edit_Zone_Params(ZONE *zone_container)
Edit params (layer, clearance, ...) for a zone outline.
bool FetchNetlistFromSchematic(NETLIST &aNetlist, const wxString &aAnnotateMessage)
wxString GetCurrentFileName() const override
Get the full filename + path of the currently opened file in the frame.
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
DIALOG_BOOK_REPORTER * GetFootprintDiffDialog()
EDA_ANGLE GetRotationAngle() const override
Return the angle used for rotate operations.
COLOR4D GetGridColor() override
std::vector< KIID > m_crossProbeFlashItems
Items to flash (by UUID)
void UpdateTitle()
Set the main window title bar text.
void ExchangeFootprint(FOOTPRINT *aExisting, FOOTPRINT *aNew, BOARD_COMMIT &aCommit, bool deleteExtraTexts=true, bool resetTextLayers=true, bool resetTextEffects=true, bool resetTextPositions=true, bool resetTextContent=true, bool resetFabricationAttrs=true, bool resetClearanceOverrides=true, bool reset3DModels=true, bool *aUpdated=nullptr)
Replace aExisting footprint by aNew footprint using the Existing footprint settings (position,...
DIALOG_BOOK_REPORTER * m_footprintDiffDlg
void ActivateGalCanvas() override
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
SELECTION & GetCurrentSelection() override
Get the current selection from the canvas area.
void OnQuit(wxCommandEvent &event)
void onCloseModelessBookReporterDialogs(wxCommandEvent &aEvent)
PCB_DESIGN_BLOCK_PANE * m_designBlocksPane
bool canCloseWindow(wxCloseEvent &aCloseEvent) override
DIALOG_BOARD_SETUP * m_boardSetupDlg
DIALOG_BOOK_REPORTER * GetInspectClearanceDialog()
wxTimer * m_eventCounterTimer
void Tracks_and_Vias_Size_Event(wxCommandEvent &event)
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
static const wxString SearchPaneName()
DIALOG_BOOK_REPORTER * m_inspectClearanceDlg
void OnFileHistory(wxCommandEvent &event)
DIALOG_BOOK_REPORTER * GetInspectConstraintsDialog()
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:53
PCB net inspection panel.
Generic tool for picking an item.
Tool that displays edit points allowing to modify items by dragging the points.
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
Definition pcb_point.h:43
PCB_LAYER_ID m_Route_Layer_TOP
Definition pcb_screen.h:43
PCB_LAYER_ID m_Route_Layer_BOTTOM
Definition pcb_screen.h:44
static bool HasUnlockedItems(const SELECTION &aSelection)
Test if any selected items are unlocked.
static bool HasLockedItems(const SELECTION &aSelection)
Test if any selected items are locked.
The selection tool: currently supports:
int ClearSelection(const TOOL_EVENT &aEvent)
void FindItem(BOARD_ITEM *aItem)
Take necessary actions to mark an item as found.
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition pcb_text.cpp:478
Tool useful for viewing footprints.
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
Definition pgm_base.cpp:822
virtual const wxString & GetExecutablePath() const
Definition pgm_base.cpp:890
The interactive edit tool.
void Show(std::ostream &aStream=std::cerr)
Definition profile.h:277
void Reset()
Definition profile.h:267
A progress reporter interface for use in multi-threaded environments.
The backing store for a PROJECT, in JSON format.
std::vector< LAYER_PAIR_INFO > m_LayerPairInfos
List of stored 3D viewports (view matrixes)
The project local settings are things that are attached to a particular project, but also might be pa...
wxString m_ActiveLayerPreset
The name of a LAYER_PRESET that is currently activated (or blank if none)
PCB_LAYER_ID m_ActiveLayer
The current (active) board layer for editing.
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition project.h:210
void IncrementNetclassesTicker()
Definition project.h:122
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:204
void IncrementTextVarsTicker()
Definition project.h:119
Action handler for the Properties panel.
PNS::PNS_MODE GetRouterMode()
bool RoutingInProgress()
Returns whether routing is currently active.
Tool relating to pads and pad settings.
static SELECTION_CONDITION HasTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if among the selected items there is at least one of a given types.
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static bool Idle(const SELECTION &aSelection)
Test if there no items selected or being edited.
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
int AddItemToSel(const TOOL_EVENT &aEvent)
EDA_ITEM * Front() const
Definition selection.h:177
int Size() const
Returns the number of selected parts.
Definition selection.h:121
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition richio.h:253
TOOL_MANAGER * m_toolManager
TOOL_DISPATCHER * m_toolDispatcher
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
ACTIONS * m_actions
Represent a single user action.
Base abstract interface for all kinds of tools.
Definition tool_base.h:66
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition tool_base.h:80
Generic, UI-independent tool event.
Definition tool_event.h:171
void SetHasPosition(bool aHasPosition)
Definition tool_event.h:261
Master controller class:
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
wxString wx_str() const
Definition utf8.cpp:45
A modified version of the wxInfoBar class that allows us to:
Definition wx_infobar.h:76
@ OUTDATED_SAVE
OUTDATED_SAVE Messages that should be cleared on save.
Definition wx_infobar.h:96
@ GENERIC
GENERIC Are messages that do not have special handling.
Definition wx_infobar.h:95
Handle actions specific to filling copper zones.
PROGRESS_REPORTER * GetProgressReporter()
Handle a list of polygons defining a copper zone.
Definition zone.h:74
A type-safe container of any type.
Definition ki_any.h:93
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition confirm.cpp:129
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 CHECK(x)
#define ENABLE(x)
#define DIALOG_DRC_WINDOW_NAME
Definition dialog_drc.h:41
#define _(s)
Declaration of the eda_3d_viewer class.
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
#define KICAD_DEFAULT_DRAWFRAME_STYLE
#define PCB_EDIT_FRAME_NAME
@ NO_RECURSE
Definition eda_item.h:52
static const std::vector< KICAD_T > footprintTypes
Definition edit_tool.cpp:82
static const std::vector< KICAD_T > groupTypes
Definition edit_tool.cpp:84
static const std::vector< KICAD_T > trackTypes
Definition edit_tool.cpp:86
EVT_MENU_RANGE(ID_GERBVIEW_DRILL_FILE1, ID_GERBVIEW_DRILL_FILEMAX, GERBVIEW_FRAME::OnDrlFileHistory) EVT_MENU_RANGE(ID_GERBVIEW_ZIP_FILE1
#define CURRENT_EDIT_TOOL(action)
@ FRAME_PCB_EDITOR
Definition frame_type.h:42
@ FRAME_FOOTPRINT_VIEWER
Definition frame_type.h:45
@ FRAME_SCH
Definition frame_type.h:34
@ FRAME_FOOTPRINT_CHOOSER
Definition frame_type.h:44
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:43
a few functions useful in geometry calculations.
@ DIRECT
Unconstrained point-to-point.
static const std::string LegacySchematicFileExtension
static const std::string LegacyPcbFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string AutoSaveFilePrefix
static const std::string SVGFileExtension
static const std::string KiCadPcbFileExtension
const wxChar *const traceAutoSave
Flag to enable auto save feature debug tracing.
const wxChar *const traceApi
Flag to enable debug output related to the IPC API and its plugin system.
Definition api_utils.cpp:27
@ ID_ON_GRID_SELECT
Definition id.h:114
@ ID_FILE_LIST_CLEAR
Definition id.h:62
@ ID_EDA_SOCKET_EVENT
Definition id.h:132
@ ID_EDA_SOCKET_EVENT_SERV
Definition id.h:131
@ ID_ON_ZOOM_SELECT
Definition id.h:112
@ ID_FILEMAX
Definition id.h:60
@ ID_FILE1
Definition id.h:59
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
PROJECT & Prj()
Definition kicad.cpp:612
int GetNetnameLayer(int aLayer)
Return a netname layer corresponding to the given layer.
Definition layer_ids.h:850
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition layer_ids.h:674
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition layer_ids.h:228
@ LAYER_GRID
Definition layer_ids.h:253
@ LAYER_ZONES
Control for copper zone opacity/visibility (color ignored).
Definition layer_ids.h:294
@ LAYER_RATSNEST
Definition layer_ids.h:252
#define CLEARANCE_LAYER_FOR(boardLayer)
Definition layer_ids.h:370
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ F_Paste
Definition layer_ids.h:104
@ B_Mask
Definition layer_ids.h:98
@ B_Cu
Definition layer_ids.h:65
@ F_Mask
Definition layer_ids.h:97
@ B_Paste
Definition layer_ids.h:105
@ UNDEFINED_LAYER
Definition layer_ids.h:61
@ F_Cu
Definition layer_ids.h:64
@ MAIL_SCH_GET_NETLIST
Definition mail_type.h:49
@ REPAINT
Item needs to be redrawn.
Definition view_item.h:58
@ GEOMETRY
Position or shape has changed.
Definition view_item.h:55
@ ALL
All except INITIAL_ADD.
Definition view_item.h:59
@ TARGET_NONCACHED
Auxiliary rendering target (noncached)
Definition definitions.h:38
void SetShutdownBlockReason(wxWindow *aWindow, const wxString &aReason)
Sets the block reason why the window/application is preventing OS shutdown.
Definition unix/app.cpp:90
bool SupportsShutdownBlockReason()
Whether or not the window supports setting a shutdown block reason.
Definition unix/app.cpp:79
@ RM_MarkObstacles
Ignore collisions, mark obstacles.
@ RM_Walkaround
Only walk around.
@ RM_Shove
Only shove.
#define _HKI(x)
Definition page_info.cpp:44
static void processTextItem(const PCB_TEXT &aSrc, PCB_TEXT &aDest, bool aResetText, bool aResetTextLayers, bool aResetTextEffects, bool aResetTextPositions, bool *aUpdated)
copy text settings from aSrc to aDest
static std::vector< std::pair< T *, T * > > matchItemsBySimilarity(const std::vector< T * > &aExisting, const std::vector< T * > &aNew)
#define FOOTPRINT_DIFF_DIALOG_NAME
EVT_MENU_RANGE(ID_POPUP_PCB_SELECT_WIDTH_START_RANGE, ID_POPUP_PCB_SELECT_WIDTH_END_RANGE, PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event) EVT_UPDATE_UI_RANGE(ID_POPUP_PCB_SELECT_WIDTH1
ID_POPUP_PCB_SELECT_WIDTH8
#define INSPECT_CLEARANCE_DIALOG_NAME
PCB_EDIT_FRAME::OnUpdateSelectTrackWidth EVT_UPDATE_UI_RANGE(ID_POPUP_PCB_SELECT_VIASIZE1, ID_POPUP_PCB_SELECT_VIASIZE8, PCB_EDIT_FRAME::OnUpdateSelectViaSize) PCB_EDIT_FRAME
#define INSPECT_DRC_ERROR_DIALOG_NAME
#define INSPECT_CONSTRAINTS_DIALOG_NAME
@ BLIND_BURIED
Definition pcb_track.h:68
@ MICROVIA
Definition pcb_track.h:69
@ ID_POPUP_PCB_SELECT_WIDTH_START_RANGE
Definition pcbnew_id.h:19
@ ID_POPUP_PCB_SELECT_WIDTH1
Definition pcbnew_id.h:23
@ ID_POPUP_PCB_SELECT_VIASIZE8
Definition pcbnew_id.h:46
@ ID_AUX_TOOLBAR_PCB_VIA_SIZE
Definition pcbnew_id.h:17
@ ID_POPUP_PCB_SELECT_WIDTH_END_RANGE
Definition pcbnew_id.h:73
@ ID_POPUP_PCB_SELECT_VIASIZE1
Definition pcbnew_id.h:39
@ ID_AUX_TOOLBAR_PCB_TRACK_WIDTH
Definition pcbnew_id.h:18
void ScriptingOnDestructPcbEditFrame(PCB_EDIT_FRAME *aPcbEditFrame)
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
@ SHOW_WITH_VIA_ALWAYS
PGM_BASE & Pgm()
The global program "get" accessor.
Definition pgm_base.cpp:913
see class PGM_BASE
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition project.h:40
LAST_PATH_TYPE
For storing PcbNew MRU paths of various types.
@ RPT_SEVERITY_EXCLUSION
#define SKIP_SET_DIRTY
Definition sch_commit.h:42
#define SKIP_UNDO
Definition sch_commit.h:40
#define CURRENT_TOOL(action)
std::function< bool(const SELECTION &)> SELECTION_CONDITION
Functor type that checks a specific condition for selected items.
T * GetToolbarSettings(const wxString &aFilename)
KIWAY Kiway(KFCTL_STANDALONE)
wxString UnescapeString(const wxString &aSource)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
A min-max version of BOX2 for fast intersection checking.
Definition box2_minmax.h:37
bool Intersects(const BOX2I_MINMAX &aOther) const
Definition box2_minmax.h:73
A filename or source description, a problem input line, a line number, a byte offset,...
TRACK_CLEARANCE_MODE m_TrackClearance
@ AS_GLOBAL
Global action (toolbar/main menu event, global shortcut)
Definition tool_action.h:49
@ AS_ACTIVE
All active tools.
Definition tool_action.h:48
@ TA_MODEL_CHANGE
Model has changed (partial update).
Definition tool_event.h:121
@ TC_COMMAND
Definition tool_event.h:57
#define TEXTVARS_CHANGED
#define ENVVARS_CHANGED
wxLogTrace helper definitions.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition typeinfo.h:88
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition typeinfo.h:105
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition typeinfo.h:102
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
Definition typeinfo.h:91
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:97
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition typeinfo.h:103
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:110
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:93
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition typeinfo.h:107
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:92
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
Definition typeinfo.h:89
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:90
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
Definition typeinfo.h:99
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition typeinfo.h:106
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:86
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition typeinfo.h:101
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition typeinfo.h:98
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
Definition typeinfo.h:94
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
Definition typeinfo.h:112
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition typeinfo.h:96
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition typeinfo.h:104
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
Definition of file extensions used in Kicad.
void SetAuiPaneSize(wxAuiManager &aManager, wxAuiPaneInfo &aPane, int aWidth, int aHeight)
Sets the size of an AUI pane, working around http://trac.wxwidgets.org/ticket/13180.
WX_VIEW_CONTROLS class definition.