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 <algorithm>
24#include <type_traits>
25#include <unordered_map>
26#include <unordered_set>
27#include <vector>
28
29#include <wx/log.h>
30#include <wx/filename.h>
31#include <wx/filedlg.h>
32#include <wx/hyperlink.h>
33#include <wx/socket.h>
34#include <wx/wupdlock.h>
35
36#include <advanced_config.h>
38#include <kiface_base.h>
39#include <kiway.h>
42#include <pgm_base.h>
43#include <pcb_edit_frame.h>
47#include <bitmaps.h>
48#include <confirm.h>
49#include <footprint.h>
50#include <footprint_utils.h>
51#include <lset.h>
52#include <trace_helpers.h>
53#include <pcbnew_id.h>
54#include <pcbnew_settings.h>
57#include <dialog_find.h>
62#include <dialog_board_setup.h>
66#include <pad.h>
67#include <pcb_target.h>
68#include <pcb_point.h>
69#include <pcb_track.h>
70#include <layer_pairs.h>
73#include <text_var_dependency.h>
74#include <view/view.h>
76#include <functional>
77#include <pcb_barcode.h>
78#include <pcb_painter.h>
83#include <local_history.h>
84#include <tool/tool_manager.h>
86#include <tool/action_toolbar.h>
87#include <tool/common_control.h>
88#include <tool/common_tools.h>
89#include <tool/embed_tool.h>
91#include <tool/selection.h>
92#include <tool/zoom_tool.h>
93#include <tools/array_tool.h>
98#include <tools/edit_tool.h>
100#include <tools/pcb_group_tool.h>
101#include <tools/generator_tool.h>
102#include <tools/drc_tool.h>
105#include <tools/convert_tool.h>
106#include <tools/drawing_tool.h>
107#include <tools/pcb_control.h>
115#include <tools/pad_tool.h>
117#include <properties/property.h>
122#include <router/router_tool.h>
125#include <dialog_drc.h> // for DIALOG_DRC_WINDOW_NAME definition
130#include <widgets/wx_infobar.h>
134#include <widgets/wx_aui_utils.h>
135#include <kiplatform/app.h>
136#include <kiplatform/ui.h>
137#include <core/profile.h>
138#include <math/box2_minmax.h>
142#include <toolbars_pcb_editor.h>
144
145#ifdef KICAD_IPC_API
146#include <api/api_server.h>
147#include <api/api_handler_pcb.h>
149#include <api/api_utils.h>
150#endif
151
152#include <richio.h>
153
154using namespace std::placeholders;
155
156
157#define INSPECT_DRC_ERROR_DIALOG_NAME wxT( "InspectDrcErrorDialog" )
158#define INSPECT_CLEARANCE_DIALOG_NAME wxT( "InspectClearanceDialog" )
159#define INSPECT_CONSTRAINTS_DIALOG_NAME wxT( "InspectConstraintsDialog" )
160#define FOOTPRINT_DIFF_DIALOG_NAME wxT( "FootprintDiffDialog" )
161
162
163BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
166
169
170 EVT_SIZE( PCB_EDIT_FRAME::OnSize )
171
172 // Menu Files:
175
176 EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit )
177 EVT_MENU( wxID_CLOSE, PCB_EDIT_FRAME::OnQuit )
178
179 // Horizontal toolbar
183
184 // Tracks and vias sizes general options
186 PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event )
187
188 // User interface update event handlers.
189 EVT_UPDATE_UI( ID_AUX_TOOLBAR_PCB_TRACK_WIDTH, PCB_EDIT_FRAME::OnUpdateSelectTrackWidth )
190 EVT_UPDATE_UI( ID_AUX_TOOLBAR_PCB_VIA_SIZE, PCB_EDIT_FRAME::OnUpdateSelectViaSize )
192 PCB_EDIT_FRAME::OnUpdateSelectTrackWidth )
194 PCB_EDIT_FRAME::OnUpdateSelectViaSize )
195 // Drop files event
196 EVT_DROP_FILES( PCB_EDIT_FRAME::OnDropFiles )
197END_EVENT_TABLE()
198
199
200PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
201 PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB_EDITOR, _( "PCB Editor" ), wxDefaultPosition, wxDefaultSize,
203 m_exportNetlistAction( nullptr ),
204 m_findDialog( nullptr ),
205 m_findByPropertiesDialog( nullptr ),
206 m_inspectDrcErrorDlg( nullptr ),
207 m_inspectClearanceDlg( nullptr ),
208 m_inspectConstraintsDlg( nullptr ),
209 m_footprintDiffDlg( nullptr ),
210 m_boardSetupDlg( nullptr ),
211 m_designBlocksPane( nullptr ),
212 m_importProperties( nullptr ),
213 m_eventCounterTimer( nullptr )
214{
215 m_maximizeByDefault = true;
216 m_showBorderAndTitleBlock = true; // true to display sheet references
217 m_SelTrackWidthBox = nullptr;
218 m_SelViaSizeBox = nullptr;
219 m_CurrentVariantCtrl = nullptr;
220 m_ShowLayerManagerTools = true;
221 m_supportsAutoSave = true;
222 m_ProbingSchToPcb = false;
223 m_ShowSearch = false;
224 m_ShowNetInspector = false;
225 // Ensure timer has an owner before binding so it generates events.
226 m_crossProbeFlashTimer.SetOwner( this );
227 Bind( wxEVT_TIMER, &PCB_EDIT_FRAME::OnCrossProbeFlashTimer, this, m_crossProbeFlashTimer.GetId() );
228
229 // We don't know what state board was in when it was last saved, so we have to
230 // assume dirty
231 m_ZoneFillsDirty = true;
232
233 m_aboutTitle = _HKI( "KiCad PCB Editor" );
234
235 // Must be created before the menus are created.
236 if( ADVANCED_CFG::GetCfg().m_ShowPcbnewExportNetlist )
237 {
238 m_exportNetlistAction = new TOOL_ACTION( "pcbnew.EditorControl.exportNetlist",
239 AS_GLOBAL, 0, "", _( "Netlist..." ),
240 _( "Export netlist used to update schematics" ) );
241 }
242
243 // Create GAL canvas
244 auto canvas = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_frameSize,
245 GetGalDisplayOptions(),
247
248 SetCanvas( canvas );
249 SetBoard( new BOARD() );
250
251 wxIcon icon;
252 wxIconBundle icon_bundle;
253
254 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew, 48 ) );
255 icon_bundle.AddIcon( icon );
256 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew, 128 ) );
257 icon_bundle.AddIcon( icon );
258 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew, 256 ) );
259 icon_bundle.AddIcon( icon );
260 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew_32 ) );
261 icon_bundle.AddIcon( icon );
262 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew_16 ) );
263 icon_bundle.AddIcon( icon );
264
265 SetIcons( icon_bundle );
266
267 // LoadSettings() *after* creating m_LayersManager, because LoadSettings()
268 // initialize parameters in m_LayersManager
269 LoadSettings( config() );
270
271 SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU( pcbIUScale.IU_PER_MILS ) ) );
272
273 // PCB drawings start in the upper left corner.
274 GetScreen()->m_Center = false;
275
276 setupTools();
277 setupUIConditions();
278
279 m_toolbarSettings = GetToolbarSettings<PCB_EDIT_TOOLBAR_SETTINGS>( "pcbnew-toolbars" );
280 configureToolbars();
281 RecreateToolbars();
282 PrepareLayerIndicator( true );
283
284 ReCreateMenuBar();
285
286#ifdef KICAD_IPC_API
288 &PCB_EDIT_FRAME::onPluginAvailabilityChanged, this );
289#endif
290
291 // Fetch a COPY of the config as a lot of these initializations are going to overwrite our
292 // data.
293 PCBNEW_SETTINGS::AUI_PANELS aui_cfg = GetPcbNewSettings()->m_AuiPanels;
294
295 m_propertiesPanel = new PCB_PROPERTIES_PANEL( this, this );
296 m_propertiesPanel->SetSplitterProportion( aui_cfg.properties_splitter );
297
298 m_selectionFilterPanel = new PANEL_SELECTION_FILTER( this );
299
300 m_appearancePanel = new APPEARANCE_CONTROLS( this, GetCanvas() );
301 m_searchPane = new PCB_SEARCH_PANE( this );
302 m_netInspectorPanel = new PCB_NET_INSPECTOR_PANEL( this, this );
303 m_designBlocksPane = new PCB_DESIGN_BLOCK_PANE( this, nullptr, m_designBlockHistoryList );
304
305 m_auimgr.SetManagedWindow( this );
306
307 CreateInfoBar();
308
309 // Secondary infobar stacked above the main one. Load-time notices (such as
310 // the WRL -> STEP migration prompt) belong here so they aren't clobbered by
311 // the main infobar's read-only warnings, DRC rule errors, etc.
312#if defined( __WXOSX_MAC__ )
313 m_loadNoticeInfoBar = new WX_INFOBAR( GetToolCanvas() );
314#else
315 m_loadNoticeInfoBar = new WX_INFOBAR( this, &m_auimgr );
316 m_auimgr.AddPane( m_loadNoticeInfoBar,
317 EDA_PANE().InfoBar().Name( wxS( "LoadNoticeInfoBar" ) ).Top().Layer( 1 )
318 .Row( 1 ) );
319#endif
320
321 unsigned int auiFlags = wxAUI_MGR_DEFAULT;
322#if !defined( _WIN32 )
323 // Windows cannot redraw the UI fast enough during a live resize and may lead to all kinds
324 // of graphical glitches.
325 auiFlags |= wxAUI_MGR_LIVE_RESIZE;
326#endif
327 m_auimgr.SetFlags( auiFlags );
328
329 // Rows; layers 4 - 6
330 m_auimgr.AddPane( m_tbTopMain, EDA_PANE().HToolbar().Name( wxS( "TopMainToolbar" ) )
331 .Top().Layer( 6 ) );
332 m_auimgr.AddPane( m_tbTopAux, EDA_PANE().HToolbar().Name( wxS( "TopAuxToolbar" ) )
333 .Top().Layer( 5 ) );
334 m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( wxS( "MsgPanel" ) )
335 .Bottom().Layer( 6 ) );
336
337 // Columns; layers 1 - 3
338 m_auimgr.AddPane( m_tbLeft, EDA_PANE().VToolbar().Name( wxS( "LeftToolbar" ) )
339 .Left().Layer( 3 ) );
340
341 m_auimgr.AddPane( m_tbRight, EDA_PANE().VToolbar().Name( wxS( "RightToolbar" ) )
342 .Right().Layer( 3 ) );
343
344 m_auimgr.AddPane( m_appearancePanel, EDA_PANE().Name( wxS( "LayersManager" ) )
345 .Right().Layer( 4 )
346 .Caption( _( "Appearance" ) ).PaneBorder( false )
347 // Don't use -1 for don't-change-height on a growable panel; it has side-effects.
348 .MinSize( m_appearancePanel->GetMinSize().x, FromDIP( 60 ) )
349#ifdef __WXMAC__
350 // Best size for this pane is calculated larger than necessary on wxMac
351 .BestSize( m_appearancePanel->GetMinSize().x, -1 )
352#else
353 .BestSize( m_appearancePanel->GetBestSize().x, -1 )
354#endif
355 .FloatingSize( m_appearancePanel->GetBestSize() )
356 .CloseButton( false ) );
357
358 m_auimgr.AddPane( m_selectionFilterPanel, EDA_PANE().Name( wxS( "SelectionFilter" ) )
359 .Right().Layer( 4 ).Position( 2 )
360 .Caption( _( "Selection Filter" ) ).PaneBorder( false )
361 // Fixed-size pane; -1 for MinSize height is required
362 .MinSize( m_selectionFilterPanel->GetMinSize().x, -1 )
363 .BestSize( m_selectionFilterPanel->GetBestSize().x, -1 )
364 .FloatingSize( m_selectionFilterPanel->GetBestSize() )
365 .CloseButton( false ) );
366
367 m_auimgr.AddPane( m_designBlocksPane, EDA_PANE().Name( DesignBlocksPaneName() )
368 .Right().Layer( 5 )
369 .Caption( _( "Design Blocks" ) )
370 .CaptionVisible( true )
371 .PaneBorder( true )
372 .TopDockable( false )
373 .BottomDockable( false )
374 .CloseButton( true )
375 .MinSize( FromDIP( wxSize( 240, 60 ) ) )
376 .BestSize( FromDIP( wxSize( 300, 200 ) ) )
377 .FloatingSize( FromDIP( wxSize( 800, 600 ) ) )
378 .FloatingPosition( FromDIP( wxPoint( 50, 200 ) ) )
379 .Show( true ) );
380
381 m_auimgr.AddPane( m_propertiesPanel, EDA_PANE().Name( PropertiesPaneName() )
382 .Left().Layer( 5 )
383 .Caption( _( "Properties" ) ).PaneBorder( false )
384 .MinSize( FromDIP( wxSize( 240, 60 ) ) )
385 .BestSize( FromDIP( wxSize( 300, 200 ) ) )
386 .FloatingSize( wxSize( 300, 200 ) )
387 .CloseButton( true ) );
388
389 // Center
390 m_auimgr.AddPane( GetCanvas(), EDA_PANE().Canvas().Name( wxS( "DrawFrame" ) )
391 .Center() );
392
393 m_auimgr.AddPane( m_netInspectorPanel, EDA_PANE().Name( NetInspectorPanelName() )
394 .Bottom()
395 .Caption( _( "Net Inspector" ) )
396 .PaneBorder( false )
397 .MinSize( FromDIP( wxSize( 240, 60 ) ) )
398 .BestSize( FromDIP( wxSize( 300, 200 ) ) )
399 .FloatingSize( wxSize( 300, 200 ) )
400 .CloseButton( true ) );
401
402 m_auimgr.AddPane( m_searchPane, EDA_PANE().Name( SearchPaneName() )
403 .Bottom()
404 .Caption( _( "Search" ) ).PaneBorder( false )
405 .MinSize( FromDIP( wxSize ( 180, 60 ) ) )
406 .BestSize( FromDIP( wxSize ( 180, 100 ) ) )
407 .FloatingSize( FromDIP( wxSize( 480, 200 ) ) )
408 .DestroyOnClose( false )
409 .CloseButton( true ) );
410
411 RestoreAuiLayout();
412
413 m_auimgr.GetPane( "LayersManager" ).Show( m_ShowLayerManagerTools );
414 m_auimgr.GetPane( "SelectionFilter" ).Show( m_ShowLayerManagerTools );
415 m_auimgr.GetPane( PropertiesPaneName() ).Show( GetPcbNewSettings()->m_AuiPanels.show_properties );
416 m_auimgr.GetPane( NetInspectorPanelName() ).Show( m_ShowNetInspector );
417 m_auimgr.GetPane( SearchPaneName() ).Show( m_ShowSearch );
418 m_auimgr.GetPane( DesignBlocksPaneName() ).Show( GetPcbNewSettings()->m_AuiPanels.design_blocks_show );
419
420 // The selection filter doesn't need to grow in the vertical direction when docked
421 m_auimgr.GetPane( "SelectionFilter" ).dock_proportion = 0;
422 FinishAUIInitialization();
423
424 // FinishAUIInitialization only hides the primary "InfoBar" pane; the
425 // stacked load-notice bar has to be hidden explicitly.
426#if !defined( __WXOSX_MAC__ )
427 if( wxAuiPaneInfo& pane = m_auimgr.GetPane( wxS( "LoadNoticeInfoBar" ) ); pane.IsOk() )
428 {
429 pane.Hide();
430 m_auimgr.Update();
431 }
432#endif
433
434 if( aui_cfg.right_panel_width > 0 )
435 {
436 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( wxS( "LayersManager" ) );
437 SetAuiPaneSize( m_auimgr, layersManager, aui_cfg.right_panel_width, -1 );
438
439 wxAuiPaneInfo& designBlocksPane = m_auimgr.GetPane( DesignBlocksPaneName() );
440 SetAuiPaneSize( m_auimgr, designBlocksPane, aui_cfg.design_blocks_panel_docked_width, -1 );
441 }
442
443 if( aui_cfg.properties_panel_width > 0 && m_propertiesPanel )
444 {
445 wxAuiPaneInfo& propertiesPanel = m_auimgr.GetPane( PropertiesPaneName() );
446 SetAuiPaneSize( m_auimgr, propertiesPanel, aui_cfg.properties_panel_width, -1 );
447 }
448
449 if( aui_cfg.search_panel_height > 0
450 && ( aui_cfg.search_panel_dock_direction == wxAUI_DOCK_TOP
451 || aui_cfg.search_panel_dock_direction == wxAUI_DOCK_BOTTOM ) )
452 {
453 wxAuiPaneInfo& searchPane = m_auimgr.GetPane( SearchPaneName() );
454 searchPane.Direction( aui_cfg.search_panel_dock_direction );
455 SetAuiPaneSize( m_auimgr, searchPane, -1, aui_cfg.search_panel_height );
456 }
457 else if( aui_cfg.search_panel_width > 0
458 && ( aui_cfg.search_panel_dock_direction == wxAUI_DOCK_LEFT
459 || aui_cfg.search_panel_dock_direction == wxAUI_DOCK_RIGHT ) )
460 {
461 wxAuiPaneInfo& searchPane = m_auimgr.GetPane( SearchPaneName() );
462 searchPane.Direction( aui_cfg.search_panel_dock_direction );
463 SetAuiPaneSize( m_auimgr, searchPane, aui_cfg.search_panel_width, -1 );
464 }
465
466 m_appearancePanel->SetTabIndex( aui_cfg.appearance_panel_tab );
467
468 {
469 m_layerPairSettings = std::make_unique<LAYER_PAIR_SETTINGS>();
470
471 m_layerPairSettings->Bind( PCB_LAYER_PAIR_PRESETS_CHANGED, [&]( wxCommandEvent& aEvt )
472 {
473 // Update the project file list
474 std::span<const LAYER_PAIR_INFO> newPairInfos = m_layerPairSettings->GetLayerPairs();
476 std::vector<LAYER_PAIR_INFO>{ newPairInfos.begin(), newPairInfos.end() };
477 });
478
479 m_layerPairSettings->Bind( PCB_CURRENT_LAYER_PAIR_CHANGED, [&]( wxCommandEvent& aEvt )
480 {
481 const LAYER_PAIR& layerPair = m_layerPairSettings->GetCurrentLayerPair();
482 PCB_SCREEN& screen = *GetScreen();
483
484 screen.m_Route_Layer_TOP = layerPair.GetLayerA();
485 screen.m_Route_Layer_BOTTOM = layerPair.GetLayerB();
486
487 // Update the toolbar icon
488 PrepareLayerIndicator();
489 });
490 }
491
492 GetToolManager()->PostAction( ACTIONS::zoomFitScreen );
493
494 // This is used temporarily to fix a client size issue on GTK that causes zoom to fit
495 // to calculate the wrong zoom size. See PCB_EDIT_FRAME::onSize().
496 Bind( wxEVT_SIZE, &PCB_EDIT_FRAME::onSize, this );
497
498 Bind( wxEVT_IDLE,
499 [this]( wxIdleEvent& aEvent )
500 {
501 BOX2D viewport = GetCanvas()->GetView()->GetViewport();
502
503 if( viewport != m_lastNetnamesViewport )
504 {
505 redrawNetnames();
506 m_lastNetnamesViewport = viewport;
507 }
508
509 // Do not forget to pass the Idle event to other clients:
510 aEvent.Skip();
511 } );
512
513 resolveCanvasType();
514
515 setupUnits( config() );
516
517 // Ensure the DRC engine is initialized so that constraints can be resolved even before a
518 // board is loaded or saved
519 try
520 {
521 m_toolManager->GetTool<DRC_TOOL>()->GetDRCEngine()->InitEngine( wxFileName() );
522 }
523 catch( PARSE_ERROR& )
524 {
525 }
526
527 // Sync action plugins in case they changed since the last time the frame opened
528 GetToolManager()->RunAction( ACTIONS::pluginsReload );
529
530#ifdef KICAD_IPC_API
531 m_apiHandler = std::make_unique<API_HANDLER_PCB>( this );
532 Pgm().GetApiServer().RegisterHandler( m_apiHandler.get() );
533
534 if( Kiface().IsSingle() )
535 {
536 m_apiHandlerCommon = std::make_unique<API_HANDLER_COMMON>();
537 Pgm().GetApiServer().RegisterHandler( m_apiHandlerCommon.get() );
538 }
539#endif
540
541 GetCanvas()->SwitchBackend( m_canvasType );
542 ActivateGalCanvas();
543
544 // Default shutdown reason until a file is loaded
545 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "New PCB file is unsaved" ) );
546
547 // disable Export STEP item if kicad2step does not exist
548 wxString strK2S = Pgm().GetExecutablePath();
549
550#ifdef __WXMAC__
551 if( strK2S.Find( wxT( "pcbnew.app" ) ) != wxNOT_FOUND )
552 {
553 // On macOS, we have standalone applications inside the main bundle, so we handle that here:
554 strK2S += wxT( "../../" );
555 }
556
557 strK2S += wxT( "Contents/MacOS/" );
558#endif
559
560 wxFileName appK2S( strK2S, wxT( "kicad2step" ) );
561
562#ifdef _WIN32
563 appK2S.SetExt( wxT( "exe" ) );
564#endif
565
566 // Ensure the window is on top
567 Raise();
568
569// if( !appK2S.FileExists() )
570 // GetMenuBar()->FindItem( ID_GEN_EXPORT_FILE_STEP )->Enable( false );
571
572 // AUI doesn't refresh properly on wxMac after changes in eb7dc6dd, so force it to
573#ifdef __WXMAC__
574 if( Kiface().IsSingle() )
575 {
576 CallAfter( [this]()
577 {
578 m_appearancePanel->OnBoardChanged();
579 } );
580 }
581#endif
582
583 // Register a call to update the toolbar sizes. It can't be done immediately because
584 // it seems to require some sizes calculated that aren't yet (at least on GTK).
585 CallAfter( [this]()
586 {
587 // Ensure the controls on the toolbars all are correctly sized
588 UpdateToolbarControlSizes();
589
590 // Update the angle snap mode toolbar button to reflect the current preference
591 GetToolManager()->RunAction( PCB_ACTIONS::angleSnapModeChanged );
592 } );
593
594 if( ADVANCED_CFG::GetCfg().m_ShowEventCounters )
595 {
596 m_eventCounterTimer = new wxTimer( this );
597
598 Bind( wxEVT_TIMER,
599 [&]( wxTimerEvent& aEvent )
600 {
601 GetCanvas()->m_PaintEventCounter->Show();
602 GetCanvas()->m_PaintEventCounter->Reset();
603
605 static_cast<KIGFX::WX_VIEW_CONTROLS*>( GetCanvas()->GetViewControls() );
608
609 },
610 m_eventCounterTimer->GetId() );
611
612 m_eventCounterTimer->Start( 1000 );
613 }
614
617 m_acceptedExts.emplace( wxS( "dxf" ), &PCB_ACTIONS::ddImportGraphics );
619 DragAcceptFiles( true );
620
621 Bind( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, &PCB_EDIT_FRAME::onCloseModelessBookReporterDialogs, this );
622}
623
624
625void PCB_EDIT_FRAME::StartCrossProbeFlash( const std::vector<BOARD_ITEM*>& aItems )
626{
627 if( !GetPcbNewSettings()->m_CrossProbing.flash_selection )
628 {
629 wxLogTrace( traceCrossProbeFlash, "StartCrossProbeFlash(PCB): aborted (setting disabled) items=%zu",
630 aItems.size() );
631 return;
632 }
633
634 if( aItems.empty() )
635 {
636 wxLogTrace( traceCrossProbeFlash, "StartCrossProbeFlash(PCB): aborted (no items)" );
637 return;
638 }
639
640 // Don't start flashing if any of the items are being moved. The flash timer toggles
641 // selection hide/show which corrupts the VIEW overlay state during an active move.
642 for( const BOARD_ITEM* item : aItems )
643 {
644 if( item->IsMoving() )
645 {
646 wxLogTrace( traceCrossProbeFlash,
647 "StartCrossProbeFlash(PCB): aborted (items are moving)" );
648 return;
649 }
650 }
651
653 {
654 wxLogTrace( traceCrossProbeFlash, "StartCrossProbeFlash(PCB): restarting existing flash (phase=%d)",
657 }
658
659 wxLogTrace( traceCrossProbeFlash, "StartCrossProbeFlash(PCB): starting with %zu items", aItems.size() );
660
661 // Store uuids
663 for( BOARD_ITEM* it : aItems )
664 m_crossProbeFlashItems.push_back( it->m_Uuid );
665
668
669 if( !m_crossProbeFlashTimer.GetOwner() )
670 m_crossProbeFlashTimer.SetOwner( this );
671
672 bool started = m_crossProbeFlashTimer.Start( 500, wxTIMER_CONTINUOUS ); // 0.5s intervals -> 3s total for 6 phases
673 wxLogTrace( traceCrossProbeFlash, "StartCrossProbeFlash(PCB): timer start=%d id=%d",
674 (int) started, m_crossProbeFlashTimer.GetId() );
675}
676
677
678void PCB_EDIT_FRAME::OnCrossProbeFlashTimer( wxTimerEvent& aEvent )
679{
680 wxLogTrace( traceCrossProbeFlash, "Timer(PCB) fired: phase=%d running=%d items=%zu",
682
684 {
685 wxLogTrace( traceCrossProbeFlash, "Timer(PCB) fired but not flashing (ignored)" );
686 return;
687 }
688
690
691 if( !selTool )
692 return;
693
694 // Don't manipulate the selection while items are being moved. The move tool holds a
695 // live reference to the selection and toggling hide/show on selected items corrupts
696 // the VIEW overlay state, causing crashes.
697 for( const KIID& id : m_crossProbeFlashItems )
698 {
699 if( EDA_ITEM* item = GetBoard()->ResolveItem( id, true ) )
700 {
701 if( item->IsMoving() )
702 {
703 wxLogTrace( traceCrossProbeFlash,
704 "Timer(PCB) phase=%d: items are moving, stopping flash",
706 m_crossProbeFlashing = false;
708 return;
709 }
710 }
711 }
712
713 // Prevent recursion / IPC during flashing
714 bool prevGuard = m_ProbingSchToPcb;
715 m_ProbingSchToPcb = true;
716
717 if( m_crossProbeFlashPhase % 2 == 0 )
718 {
719 // Hide selection
720 selTool->ClearSelection( true );
721 wxLogTrace( traceCrossProbeFlash, "Phase %d (PCB): cleared selection", m_crossProbeFlashPhase );
722 }
723 else
724 {
725 // Restore selection
726 for( const KIID& id : m_crossProbeFlashItems )
727 {
728 if( EDA_ITEM* item = GetBoard()->ResolveItem( id, true ) )
729 selTool->AddItemToSel( item, true );
730 }
731
732 wxLogTrace( traceCrossProbeFlash, "Phase %d (PCB): restored %zu items",
734 }
735
736 // Force a redraw even if the canvas / frame does not currently have focus (mouse elsewhere)
737 if( GetCanvas() )
738 {
740 wxLogTrace( traceCrossProbeFlash, "Phase %d (PCB): forced canvas refresh",
742 }
743
744 m_ProbingSchToPcb = prevGuard;
745
747
748 if( m_crossProbeFlashPhase > 6 )
749 {
750 // Ensure final state (selected)
751 for( const KIID& id : m_crossProbeFlashItems )
752 {
753 if( EDA_ITEM* item = GetBoard()->ResolveItem( id, true ) )
754 selTool->AddItemToSel( item, true );
755 }
756
757 m_crossProbeFlashing = false;
759
760 wxLogTrace( traceCrossProbeFlash, "Flashing complete (PCB). Final selection size=%zu",
761 m_crossProbeFlashItems.size() );
762 }
763}
764
765
767{
768 // PCB_BASE_FRAME's dtor deletes m_pcb; canvas children outlive it. Drop
769 // every cached TEXT_VAR_TRACKER* before the tracker is freed.
771
772 if( ADVANCED_CFG::GetCfg().m_ShowEventCounters )
773 {
774 // Stop the timer during destruction early to avoid potential event race conditions (that
775 // do happen on windows)
776 m_eventCounterTimer->Stop();
777 delete m_eventCounterTimer;
778 }
779
780 // Close modeless dialogs
781 wxWindow* drcDlg = wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME );
782
783 if( drcDlg )
784 drcDlg->Close( true );
785
786 wxWindow* ruleEditorDlg = wxWindow::FindWindowByName( DIALOG_DRC_RULE_EDITOR_WINDOW_NAME );
787
788 if( ruleEditorDlg )
789 ruleEditorDlg->Close( true );
790
791 // Shutdown all running tools
792 if( m_toolManager )
793 m_toolManager->ShutdownAllTools();
794
795 if( GetBoard() )
797
798 // We passed ownership of these to wxAuiManager.
799 // delete m_selectionFilterPanel;
800 // delete m_appearancePanel;
801 // delete m_propertiesPanel;
802 // delete m_netInspectorPanel;
803
805}
806
807
809{
810 if( GetCanvas() )
811 {
812 if( DS_PROXY_VIEW_ITEM* sheet = GetCanvas()->GetDrawingSheet() )
813 sheet->AttachToTracker( nullptr );
814 }
815
817 {
818 m_textVarListenerTracker->RemoveInvalidateListener( m_textVarListenerHandle );
820 m_textVarListenerTracker = nullptr;
821 }
822}
823
824
825void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard, bool aBuildConnectivity,
826 PROGRESS_REPORTER* aReporter )
827{
828 // PCB_BASE_FRAME::SetBoard deletes m_pcb; detach tracker consumers first.
829 if( m_pcb )
830 {
832 m_pcb->ClearProject();
833 }
834
835 PCB_BASE_EDIT_FRAME::SetBoard( aBoard, aReporter );
836
837 aBoard->SetProject( &Prj() );
838
839 if( aBuildConnectivity )
840 aBoard->BuildConnectivity();
841
842 // reload the drawing-sheet
843 SetPageSettings( aBoard->GetPageSettings() );
844
846}
847
848
853
854
855std::unique_ptr<GRID_HELPER> PCB_EDIT_FRAME::MakeGridHelper()
856{
857 return std::make_unique<PCB_GRID_HELPER>( m_toolManager, GetMagneticItemsSettings() );
858}
859
860
862{
863 /*
864 * While new items being scrolled into the view will get painted, they will only get
865 * annotated with netname instances currently within the view. Subsequent panning will not
866 * draw newly-visible netname instances because the item has already been drawn.
867 *
868 * This routine, fired on idle if the viewport has changed, looks for visible items that
869 * might have multiple netname instances and redraws them. (It does not need to handle pads
870 * and vias because they only ever have a single netname instance drawn on them.)
871 */
872 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
873
874 if( !cfg || cfg->m_Display.m_NetNames < 2 )
875 return;
876
877 KIGFX::VIEW* view = GetCanvas()->GetView();
878 BOX2D viewport = view->GetViewport();
879
880 // Inflate to catch most of the track width
881 BOX2I_MINMAX clipbox( BOX2ISafe( viewport.Inflate( pcbIUScale.mmToIU( 2.0 ) ) ) );
882
883 for( PCB_TRACK* track : GetBoard()->Tracks() )
884 {
885 // Don't need to update vias
886 if( track->Type() == PCB_VIA_T )
887 continue;
888
889 // Don't update invisible tracks
890 if( !clipbox.Intersects( BOX2I_MINMAX( track->GetStart(), track->GetEnd() ) ) )
891 continue;
892
893 if( track->ViewGetLOD( GetNetnameLayer( track->GetLayer() ), view ) < view->GetScale() )
894 view->Update( track, KIGFX::REPAINT );
895 }
896}
897
898
899void PCB_EDIT_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
900{
901 PCB_BASE_FRAME::SetPageSettings( aPageSettings );
902
903 // Prepare drawing-sheet template
905 &m_pcb->GetPageSettings(),
906 m_pcb->GetProject(),
907 &m_pcb->GetTitleBlock(),
908 &m_pcb->GetProperties() );
909
910 drawingSheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) );
911 drawingSheet->SetSheetPath( std::string( GetFullScreenDesc().mb_str() ) );
912
913 // A board is not like a schematic having a main page and sub sheets.
914 // So for the drawing sheet, use only the first page option to display items
915 drawingSheet->SetIsFirstPage( true );
916
917 BASE_SCREEN* screen = GetScreen();
918
919 if( screen != nullptr )
920 {
921 drawingSheet->SetPageNumber(TO_UTF8( screen->GetPageNumber() ) );
922 drawingSheet->SetSheetCount( screen->GetPageCount() );
923 }
924
925 if( BOARD* board = GetBoard() )
926 {
927 drawingSheet->SetFileName( TO_UTF8( board->GetFileName() ) );
928 wxString currentVariant = board->GetCurrentVariant();
929 wxString variantDesc = board->GetVariantDescription( currentVariant );
930 drawingSheet->SetVariantName( TO_UTF8( currentVariant ) );
931 drawingSheet->SetVariantDesc( TO_UTF8( variantDesc ) );
932 }
933
934 // PCB_DRAW_PANEL_GAL takes ownership of the drawing-sheet
935 GetCanvas()->SetDrawingSheet( drawingSheet );
936
937 // Reactive title-block repaint: register the proxy with the BOARD's
938 // text-var tracker so source changes fan out to a repaint. The one-time
939 // listener installation is idempotent; calling AddInvalidateListener
940 // here each time would accumulate stale listeners across SetPageSettings
941 // calls, which is why the listener check below is guarded.
942 if( BOARD* board = GetBoard() )
943 {
944 if( BOARD_TEXT_VAR_ADAPTER* adapter = board->GetTextVarAdapter() )
945 {
946 TEXT_VAR_TRACKER* tracker = &adapter->Tracker();
947
948 drawingSheet->AttachToTracker( tracker );
949
950 // Project reload / board swap can point GetBoard() at a new
951 // tracker; detach from the previous one first so we don't leak
952 // a stale lambda that still captures `this`.
953 if( m_textVarListenerTracker != tracker
955 {
956 m_textVarListenerTracker->RemoveInvalidateListener( m_textVarListenerHandle );
958 m_textVarListenerTracker = nullptr;
959 }
960
962 {
963 KIGFX::VIEW* view = GetCanvas()->GetView();
964 m_textVarListenerTracker = tracker;
966 [this, view]( EDA_ITEM* aDep, const TEXT_VAR_REF_KEY& )
967 {
968 if( !aDep )
969 return;
970
972
973 if( aDep == current )
974 {
975 view->Update( current, KIGFX::REPAINT );
976 return;
977 }
978
979 if( aDep->IsBOARD_ITEM() )
980 view->Update( aDep, KIGFX::REPAINT );
981 } );
982 }
983 }
984 }
985}
986
987
989{
990 return GetScreen() && GetScreen()->IsContentModified();
991}
992
993
995{
996 return m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
997}
998
999
1001{
1002 // Create the manager and dispatcher & route draw panel events to the dispatcher
1004 m_toolManager->SetEnvironment( m_pcb, GetCanvas()->GetView(),
1005 GetCanvas()->GetViewControls(), config(), this );
1006 m_actions = new PCB_ACTIONS();
1008
1009 // Register tools
1010 m_toolManager->RegisterTool( new COMMON_CONTROL );
1011 m_toolManager->RegisterTool( new COMMON_TOOLS );
1012 m_toolManager->RegisterTool( new PCB_SELECTION_TOOL );
1013 m_toolManager->RegisterTool( new ZOOM_TOOL );
1014 m_toolManager->RegisterTool( new PCB_PICKER_TOOL );
1015 m_toolManager->RegisterTool( new ROUTER_TOOL );
1016 m_toolManager->RegisterTool( new EDIT_TOOL );
1017 m_toolManager->RegisterTool( new PCB_EDIT_TABLE_TOOL );
1018 m_toolManager->RegisterTool( new GLOBAL_EDIT_TOOL );
1019 m_toolManager->RegisterTool( new PAD_TOOL );
1020 m_toolManager->RegisterTool( new DRAWING_TOOL );
1021 m_toolManager->RegisterTool( new PCB_POINT_EDITOR );
1022 m_toolManager->RegisterTool( new PCB_CONTROL );
1023 m_toolManager->RegisterTool( new PCB_DESIGN_BLOCK_CONTROL );
1024 m_toolManager->RegisterTool( new BOARD_EDITOR_CONTROL );
1025 m_toolManager->RegisterTool( new BOARD_INSPECTION_TOOL );
1026 m_toolManager->RegisterTool( new BOARD_REANNOTATE_TOOL );
1027 m_toolManager->RegisterTool( new ALIGN_DISTRIBUTE_TOOL );
1028 m_toolManager->RegisterTool( new MICROWAVE_TOOL );
1029 m_toolManager->RegisterTool( new POSITION_RELATIVE_TOOL );
1030 m_toolManager->RegisterTool( new ARRAY_TOOL );
1031 m_toolManager->RegisterTool( new ZONE_FILLER_TOOL );
1032 m_toolManager->RegisterTool( new AUTOPLACE_TOOL );
1033 m_toolManager->RegisterTool( new DRC_TOOL );
1034 m_toolManager->RegisterTool( new PCB_VIEWER_TOOLS );
1035 m_toolManager->RegisterTool( new CONVERT_TOOL );
1036 m_toolManager->RegisterTool( new PCB_GROUP_TOOL );
1037 m_toolManager->RegisterTool( new GENERATOR_TOOL );
1038 m_toolManager->RegisterTool( new PROPERTIES_TOOL );
1039 m_toolManager->RegisterTool( new MULTICHANNEL_TOOL );
1040 m_toolManager->RegisterTool( new EMBED_TOOL );
1041 m_toolManager->RegisterTool( new DRC_RULE_EDITOR_TOOL );
1042 m_toolManager->InitTools();
1043
1044 for( TOOL_BASE* tool : m_toolManager->Tools() )
1045 {
1046 if( PCB_TOOL_BASE* pcbTool = dynamic_cast<PCB_TOOL_BASE*>( tool ) )
1047 pcbTool->SetIsBoardEditor( true );
1048 }
1049
1050 // Run the selection tool, it is supposed to be always active
1051 m_toolManager->InvokeTool( "common.InteractiveSelection" );
1052}
1053
1054
1056{
1058
1059 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
1060 PCB_EDITOR_CONDITIONS cond( this );
1061
1062 auto undoCond =
1063 [ this ] (const SELECTION& aSel )
1064 {
1065 DRAWING_TOOL* drawingTool = m_toolManager->GetTool<DRAWING_TOOL>();
1066
1067 if( drawingTool && drawingTool->GetDrawingMode() != DRAWING_TOOL::MODE::NONE )
1068 return true;
1069
1070 ROUTER_TOOL* routerTool = m_toolManager->GetTool<ROUTER_TOOL>();
1071
1072 if( routerTool && routerTool->RoutingInProgress() )
1073 return true;
1074
1075 return GetUndoCommandCount() > 0;
1076 };
1077
1078 auto groupWithDesignBlockLink =
1079 [] ( const SELECTION& aSel )
1080 {
1081 if( aSel.Size() != 1 )
1082 return false;
1083
1084 if( aSel[0]->Type() != PCB_GROUP_T )
1085 return false;
1086
1087 PCB_GROUP* group = static_cast<PCB_GROUP*>( aSel.GetItem( 0 ) );
1088
1089 return group->HasDesignBlockLink();
1090 };
1091
1092 wxASSERT( mgr );
1093
1094#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
1095#define CHECK( x ) ACTION_CONDITIONS().Check( x )
1096// clang-format off
1097
1099 mgr->SetConditions( ACTIONS::undo, ENABLE( undoCond ) );
1101
1105
1106 mgr->SetConditions( ACTIONS::cut, ENABLE( cond.HasItems() ) );
1107 mgr->SetConditions( ACTIONS::copy, ENABLE( cond.HasItems() ) );
1114
1115 static const std::vector<KICAD_T> groupTypes = { PCB_GROUP_T, PCB_GENERATOR_T };
1116
1121
1122 mgr->SetConditions( PCB_ACTIONS::placeLinkedDesignBlock, ENABLE( groupWithDesignBlockLink) );
1123 mgr->SetConditions( PCB_ACTIONS::saveToLinkedDesignBlock, ENABLE( groupWithDesignBlockLink) );
1124
1130
1131 auto enableZoneControlCondition =
1132 [this] ( const SELECTION& )
1133 {
1136 };
1137
1139 ENABLE( enableZoneControlCondition )
1142 ENABLE( enableZoneControlCondition )
1145 ENABLE( enableZoneControlCondition )
1148 ENABLE( enableZoneControlCondition )
1150
1152
1153 auto hasElements =
1154 [ this ] ( const SELECTION& aSel )
1155 {
1156 return GetBoard() &&
1157 ( !GetBoard()->IsEmpty() || !SELECTION_CONDITIONS::Idle( aSel ) );
1158 };
1159
1160 auto boardFlippedCond =
1161 [this]( const SELECTION& )
1162 {
1164 };
1165
1166 auto layerManagerCond =
1167 [this] ( const SELECTION& )
1168 {
1169 return LayerManagerShown();
1170 };
1171
1172 auto propertiesCond =
1173 [this] ( const SELECTION& )
1174 {
1175 return PropertiesShown();
1176 };
1177
1178 auto netInspectorCond =
1179 [this] ( const SELECTION& )
1180 {
1181 return NetInspectorShown();
1182 };
1183
1184 auto searchPaneCond =
1185 [this] ( const SELECTION& )
1186 {
1187 return m_auimgr.GetPane( SearchPaneName() ).IsShown();
1188 };
1189
1190 auto designBlockCond =
1191 [ this ] (const SELECTION& aSel )
1192 {
1193 return m_auimgr.GetPane( DesignBlocksPaneName() ).IsShown();
1194 };
1195
1196 auto highContrastCond =
1197 [this] ( const SELECTION& )
1198 {
1200 };
1201
1202 auto globalRatsnestCond =
1203 [this] (const SELECTION& )
1204 {
1206 return cfg && cfg->m_Display.m_ShowGlobalRatsnest;
1207 };
1208
1209 auto curvedRatsnestCond =
1210 [this] (const SELECTION& )
1211 {
1213 return cfg && cfg->m_Display.m_DisplayRatsnestLinesCurved;
1214 };
1215
1216 auto netHighlightCond =
1217 [this]( const SELECTION& )
1218 {
1219 if( auto* canvas = GetCanvas() )
1220 {
1221 if( auto* view = canvas->GetView() )
1222 {
1223 if( auto* painter = view->GetPainter() )
1224 {
1225 if( auto* settings = painter->GetSettings() )
1226 return !settings->GetHighlightNetCodes().empty();
1227 }
1228 }
1229 }
1230
1231 return false;
1232 };
1233
1234 auto enableNetHighlightCond =
1235 [this]( const SELECTION& )
1236 {
1238 return tool && tool->IsNetHighlightSet();
1239 };
1240
1241 mgr->SetConditions( ACTIONS::highContrastMode, CHECK( highContrastCond ) );
1242 mgr->SetConditions( PCB_ACTIONS::flipBoard, CHECK( boardFlippedCond ) );
1243 mgr->SetConditions( PCB_ACTIONS::showLayersManager, CHECK( layerManagerCond ) );
1244 mgr->SetConditions( PCB_ACTIONS::showRatsnest, CHECK( globalRatsnestCond ) );
1245 mgr->SetConditions( PCB_ACTIONS::ratsnestLineMode, CHECK( curvedRatsnestCond ) );
1246 mgr->SetConditions( PCB_ACTIONS::toggleNetHighlight, CHECK( netHighlightCond )
1247 .Enable( enableNetHighlightCond ) );
1248 mgr->SetConditions( ACTIONS::showProperties, CHECK( propertiesCond ) );
1249 mgr->SetConditions( PCB_ACTIONS::showNetInspector, CHECK( netInspectorCond ) );
1250 mgr->SetConditions( PCB_ACTIONS::showSearch, CHECK( searchPaneCond ) );
1251 mgr->SetConditions( PCB_ACTIONS::showDesignBlockPanel, CHECK( designBlockCond ) );
1252
1255
1256 const auto isArcKeepCenterMode =
1257 [this]( const SELECTION& )
1258 {
1261 };
1262
1263 const auto isArcKeepEndpointMode =
1264 [this]( const SELECTION& )
1265 {
1268 };
1269
1270 const auto isArcKeepRadiusMode =
1271 [this]( const SELECTION& )
1272 {
1275 };
1276
1277 mgr->SetConditions( ACTIONS::pointEditorArcKeepCenter, CHECK( isArcKeepCenterMode ) );
1278 mgr->SetConditions( ACTIONS::pointEditorArcKeepEndpoint, CHECK( isArcKeepEndpointMode ) );
1279 mgr->SetConditions( ACTIONS::pointEditorArcKeepRadius, CHECK( isArcKeepRadiusMode ) );
1280
1281 auto isHighlightMode =
1282 [this]( const SELECTION& )
1283 {
1284 ROUTER_TOOL* tool = m_toolManager->GetTool<ROUTER_TOOL>();
1285 return tool && tool->GetRouterMode() == PNS::RM_MarkObstacles;
1286 };
1287
1288 auto isShoveMode =
1289 [this]( const SELECTION& )
1290 {
1291 ROUTER_TOOL* tool = m_toolManager->GetTool<ROUTER_TOOL>();
1292 return tool && tool->GetRouterMode() == PNS::RM_Shove;
1293 };
1294
1295 auto isWalkaroundMode =
1296 [this]( const SELECTION& )
1297 {
1298 ROUTER_TOOL* tool = m_toolManager->GetTool<ROUTER_TOOL>();
1299 return tool && tool->GetRouterMode() == PNS::RM_Walkaround;
1300 };
1301
1302 mgr->SetConditions( PCB_ACTIONS::routerHighlightMode, CHECK( isHighlightMode ) );
1303 mgr->SetConditions( PCB_ACTIONS::routerShoveMode, CHECK( isShoveMode ) );
1304 mgr->SetConditions( PCB_ACTIONS::routerWalkaroundMode, CHECK( isWalkaroundMode ) );
1305
1306 auto isAutoTrackWidth =
1307 [this]( const SELECTION& )
1308 {
1310 };
1311
1312 mgr->SetConditions( PCB_ACTIONS::autoTrackWidth, CHECK( isAutoTrackWidth ) );
1313
1314 auto haveNetCond =
1315 [] ( const SELECTION& aSel )
1316 {
1317 for( EDA_ITEM* item : aSel )
1318 {
1319 if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
1320 {
1321 if( bci->GetNetCode() > 0 )
1322 return true;
1323 }
1324 }
1325
1326 return false;
1327 };
1328
1329 mgr->SetConditions( PCB_ACTIONS::showNetInRatsnest, ENABLE( haveNetCond ) );
1330 mgr->SetConditions( PCB_ACTIONS::hideNetInRatsnest, ENABLE( haveNetCond ) );
1333
1334 static const std::vector<KICAD_T> trackTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T };
1335 static const std::vector<KICAD_T> padOwnerTypes = { PCB_FOOTPRINT_T, PCB_PAD_T };
1336 static const std::vector<KICAD_T> footprintTypes = { PCB_FOOTPRINT_T };
1337 static const std::vector<KICAD_T> crossProbeTypes = { PCB_PAD_T, PCB_FOOTPRINT_T, PCB_GROUP_T };
1338 static const std::vector<KICAD_T> zoneTypes = { PCB_ZONE_T };
1339
1345
1346
1348 && SELECTION_CONDITIONS::OnlyTypes( zoneTypes );
1349
1351 && SELECTION_CONDITIONS::OnlyTypes( zoneTypes );
1352
1353 mgr->SetConditions( PCB_ACTIONS::zoneDuplicate, ENABLE( singleZoneCond ) );
1354 mgr->SetConditions( PCB_ACTIONS::drawZoneCutout, ENABLE( singleZoneCond ) );
1355 mgr->SetConditions( PCB_ACTIONS::drawSimilarZone, ENABLE( singleZoneCond ) );
1356 mgr->SetConditions( PCB_ACTIONS::zoneMerge, ENABLE( zoneMergeCond ) );
1357
1360
1361#define CURRENT_TOOL( action ) mgr->SetConditions( action, CHECK( cond.CurrentTool( action ) ) )
1362
1363 // These tools can be used at any time to inspect the board
1368
1369 auto isDRCIdle =
1370 [this] ( const SELECTION& )
1371 {
1372 DRC_TOOL* tool = m_toolManager->GetTool<DRC_TOOL>();
1373 return !( tool && tool->IsDRCRunning() );
1374 };
1375
1376#define CURRENT_EDIT_TOOL( action ) \
1377 mgr->SetConditions( action, ACTION_CONDITIONS().Check( cond.CurrentTool( action ) ) \
1378 .Enable( isDRCIdle ) )
1379
1380 // These tools edit the board, so they must be disabled during some operations
1414
1420
1421#undef CURRENT_TOOL
1422#undef CURRENT_EDIT_TOOL
1423#undef ENABLE
1424#undef CHECK
1425// clang-format on
1426}
1427
1428
1429void PCB_EDIT_FRAME::OnQuit( wxCommandEvent& event )
1430{
1431 if( event.GetId() == wxID_EXIT )
1432 Kiway().OnKiCadExit();
1433
1434 if( event.GetId() == wxID_CLOSE || Kiface().IsSingle() )
1435 Close( false );
1436}
1437
1438
1439void PCB_EDIT_FRAME::ResolveDRCExclusions( bool aCreateMarkers )
1440{
1441 BOARD_COMMIT commit( this );
1442
1443 for( PCB_MARKER* marker : GetBoard()->ResolveDRCExclusions( aCreateMarkers ) )
1444 {
1445 if( marker->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
1446 marker->GetRCItem()->SetItems( GetCanvas()->GetDrawingSheet() );
1447
1448 commit.Add( marker );
1449 }
1450
1451 commit.Push( wxEmptyString, SKIP_UNDO | SKIP_SET_DIRTY );
1452
1453 for( PCB_MARKER* marker : GetBoard()->Markers() )
1454 {
1455 if( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION )
1456 GetCanvas()->GetView()->Update( marker );
1457 }
1458
1460}
1461
1462
1463bool PCB_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
1464{
1465 // Shutdown blocks must be determined and vetoed as early as possible
1466 if( KIPLATFORM::APP::SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
1467 && IsContentModified() )
1468 {
1469 return false;
1470 }
1471
1472 ZONE_FILLER_TOOL* zoneFillerTool = m_toolManager->GetTool<ZONE_FILLER_TOOL>();
1473
1474 if( zoneFillerTool->IsBusy() )
1475 {
1476 wxBell();
1477
1478 if( wxWindow* reporter = dynamic_cast<wxWindow*>( zoneFillerTool->GetProgressReporter() ) )
1479 reporter->ShowWithEffect( wxSHOW_EFFECT_EXPAND );
1480
1481 return false;
1482 }
1483
1484 // Don't allow closing while the modal footprint chooser is open
1485 auto* chooser = (FOOTPRINT_CHOOSER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_CHOOSER, false );
1486
1487 if( chooser && chooser->IsModal() ) // Can close footprint chooser?
1488 return false;
1489
1490 if( Kiface().IsSingle() )
1491 {
1492 auto* fpEditor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_FOOTPRINT_EDITOR, false );
1493
1494 if( fpEditor && !fpEditor->Close() ) // Can close footprint editor?
1495 return false;
1496
1497 auto* fpViewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_VIEWER, false );
1498
1499 if( fpViewer && !fpViewer->Close() ) // Can close footprint viewer?
1500 return false;
1501 }
1502 else
1503 {
1504 auto* fpEditor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_FOOTPRINT_EDITOR, false );
1505
1506 if( fpEditor && fpEditor->IsCurrentFPFromBoard() )
1507 {
1508 if( !fpEditor->CanCloseFPFromBoard( true ) )
1509 return false;
1510 }
1511 }
1512
1513 if( IsContentModified() )
1514 {
1515 wxFileName fileName = GetBoard()->GetFileName();
1516 wxString msg = _( "Save changes to '%s' before closing?" );
1517
1518 if( !HandleUnsavedChanges( this, wxString::Format( msg, fileName.GetFullName() ),
1519 [&]() -> bool
1520 {
1521 return SaveBoard();
1522 } ) )
1523 {
1524 return false;
1525 }
1526
1527 // If user discarded changes, create a duplicate commit of last saved PCB state and
1528 // advance Last_Save_pcb tag for explicit history event.
1529 if( GetLastUnsavedChangesResponse() == wxID_NO )
1530 {
1531 wxString projPath = Prj().GetProjectPath();
1532
1533 if( !projPath.IsEmpty() && Kiway().LocalHistory().HistoryExists( projPath ) )
1534 {
1535 Kiway().LocalHistory().CommitDuplicateOfLastSave( projPath, wxS("pcb"),
1536 wxS("Discard unsaved pcb changes") );
1537 }
1538 }
1539 }
1540
1541 return PCB_BASE_EDIT_FRAME::canCloseWindow( aEvent );
1542}
1543
1544
1546{
1547 // Unregister the autosave saver before any cleanup that might invalidate the board
1548 if( GetBoard() )
1550
1551 // On Windows 7 / 32 bits, on OpenGL mode only, Pcbnew crashes
1552 // when closing this frame if a footprint was selected, and the footprint editor called
1553 // to edit this footprint, and when closing pcbnew if this footprint is still selected
1554 // See https://bugs.launchpad.net/kicad/+bug/1655858
1555 // I think this is certainly a OpenGL event fired after frame deletion, so this workaround
1556 // avoid the crash (JPC)
1557 GetCanvas()->SetEvtHandlerEnabled( false );
1558
1560
1561#ifdef KICAD_IPC_API
1562 Pgm().GetApiServer().DeregisterHandler( m_apiHandler.get() );
1563 wxTheApp->Unbind( EDA_EVT_PLUGIN_AVAILABILITY_CHANGED,
1564 &PCB_EDIT_FRAME::onPluginAvailabilityChanged, this );
1565#endif
1566
1567 // Clean up mode-less dialogs.
1568 Unbind( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, &PCB_EDIT_FRAME::onCloseModelessBookReporterDialogs,
1569 this );
1570
1571 wxWindow* drcDlg = wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME );
1572
1573 if( drcDlg )
1574 drcDlg->Close( true );
1575
1576 wxWindow* ruleEditorDlg = wxWindow::FindWindowByName( DIALOG_DRC_RULE_EDITOR_WINDOW_NAME );
1577
1578 if( ruleEditorDlg )
1579 ruleEditorDlg->Close( true );
1580
1581
1582 if( m_findDialog )
1583 {
1584 m_findDialog->Destroy();
1585 m_findDialog = nullptr;
1586 }
1587
1589 {
1590 m_findByPropertiesDialog->Destroy();
1591 m_findByPropertiesDialog = nullptr;
1592 }
1593
1595 {
1596 m_inspectDrcErrorDlg->Destroy();
1597 m_inspectDrcErrorDlg = nullptr;
1598 }
1599
1601 {
1602 m_inspectClearanceDlg->Destroy();
1603 m_inspectClearanceDlg = nullptr;
1604 }
1605
1607 {
1608 m_inspectConstraintsDlg->Destroy();
1609 m_inspectConstraintsDlg = nullptr;
1610 }
1611
1612 if( m_footprintDiffDlg )
1613 {
1614 m_footprintDiffDlg->Destroy();
1615 m_footprintDiffDlg = nullptr;
1616 }
1617
1618 // Delete the auto save file if it exists. Only sweep when the board was actually
1619 // dirtied in this session; otherwise an existing autosave is a previous-session
1620 // leftover the user explicitly deferred in the recovery dialog.
1621 if( !Prj().IsNullProject() && GetBoard() && IsContentModified() )
1622 {
1623 Kiway().LocalHistory().RemoveAutosaveFiles( Prj().GetProjectPath(),
1624 { GetBoard()->GetFileName() } );
1625 }
1626
1627 // Make sure local settings are persisted
1628 if( Prj().GetLocalSettings().ShouldAutoSave() )
1629 {
1630 m_netInspectorPanel->SaveSettings();
1632 }
1633 else
1634 {
1635 wxLogTrace( traceAutoSave, wxT( "Skipping auto-save of migrated local settings" ) );
1636 }
1637
1638 // Do not show the layer manager during closing to avoid flicker
1639 // on some platforms (Windows) that generate useless redraw of items in
1640 // the Layer Manager
1642 {
1643 m_auimgr.GetPane( wxS( "LayersManager" ) ).Show( false );
1644 m_auimgr.GetPane( wxS( "TabbedPanel" ) ).Show( false );
1645 }
1646
1647 // Unlink the old project if needed
1649
1650 // Delete board structs and undo/redo lists, to avoid crash on exit
1651 // when deleting some structs (mainly in undo/redo lists) too late
1652 Clear_Pcb( false, true );
1653
1654 // do not show the window because ScreenPcb will be deleted and we do not
1655 // want any paint event
1656 Show( false );
1657
1659}
1660
1661
1668
1669
1670void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage, wxWindow* aParent )
1671{
1672 static std::mutex dialogMutex; // Local static mutex
1673
1674 std::unique_lock<std::mutex> dialogLock( dialogMutex, std::try_to_lock );
1675
1676 // One dialog at a time.
1677 if( !dialogLock.owns_lock() )
1678 {
1679 if( m_boardSetupDlg && m_boardSetupDlg->IsShown() )
1680 {
1681 m_boardSetupDlg->Raise(); // Brings the existing dialog to the front
1682 }
1683
1684 return;
1685 }
1686
1687 // Make sure everything's up-to-date
1689
1690 DIALOG_BOARD_SETUP dlg( this, aParent );
1691
1692 if( !aInitialPage.IsEmpty() )
1693 dlg.SetInitialPage( aInitialPage, wxEmptyString );
1694
1695 // Assign dlg to the m_boardSetupDlg pointer to track its status.
1696 m_boardSetupDlg = &dlg;
1697
1698 // QuasiModal required for Scintilla auto-complete
1699 if( dlg.ShowQuasiModal() == wxID_OK )
1700 {
1701 // Note: We must synchronise time domain properties before nets and classes, otherwise the updates
1702 // called by the board listener events are using stale data
1705
1706 if( !GetBoard()->SynchronizeComponentClasses( std::unordered_set<wxString>() ) )
1707 {
1708 m_infoBar->RemoveAllButtons();
1709 m_infoBar->AddCloseButton();
1710 m_infoBar->ShowMessage( _( "Could not load component class assignment rules" ),
1711 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::GENERIC );
1712 }
1713
1714 // We don't know if anything was modified, so err on the side of requiring a save
1715 OnModify();
1716
1718
1721
1722 // CROSS_REF keys deliberately excluded — those are driven by per-item
1723 // BOARD_COMMIT changes.
1724 if( BOARD_TEXT_VAR_ADAPTER* adapter = GetBoard()->GetTextVarAdapter() )
1725 adapter->Tracker().InvalidateProjectScoped();
1726
1727 PCBNEW_SETTINGS* settings = GetPcbNewSettings();
1728 static LSET maskAndPasteLayers = LSET( { F_Mask, F_Paste, B_Mask, B_Paste } );
1729
1731 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
1732 {
1733 int flags = 0;
1734
1735 if( !aItem->IsBOARD_ITEM() )
1736 return flags;
1737
1738 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aItem );
1739
1740 if( item->Type() == PCB_VIA_T || item->Type() == PCB_PAD_T )
1741 {
1742 // Note: KIGFX::REPAINT isn't enough for things that go from invisible
1743 // to visible as they won't be found in the view layer's itemset for
1744 // re-painting.
1745 if( ( GetBoard()->GetVisibleLayers() & maskAndPasteLayers ).any() )
1746 flags |= KIGFX::ALL;
1747 }
1748
1749 if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T || item->Type() == PCB_VIA_T )
1750 {
1752 flags |= KIGFX::REPAINT;
1753 }
1754
1755 if( item->Type() == PCB_PAD_T )
1756 {
1757 if( settings->m_Display.m_PadClearance )
1758 flags |= KIGFX::REPAINT;
1759 }
1760
1761 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aItem ) )
1762 {
1763 if( text->HasTextVars() )
1764 {
1765 text->ClearRenderCache();
1766 text->ClearBoundingBoxCache();
1768 }
1769 }
1770
1771 return flags;
1772 } );
1773
1774 GetCanvas()->Refresh();
1775
1779
1780 //this event causes the routing tool to reload its design rules information
1782 toolEvent.SetHasPosition( false );
1783 m_toolManager->ProcessEvent( toolEvent );
1784 }
1785
1786 GetCanvas()->SetFocus();
1787
1788 // Reset m_boardSetupDlg after the dialog is closed
1789 m_boardSetupDlg = nullptr;
1790}
1791
1792
1794{
1795 m_searchPane->FocusSearch();
1796}
1797
1798
1800{
1802
1803 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( aCfg );
1804 wxASSERT( cfg );
1805
1806 if( cfg )
1807 {
1811 }
1812}
1813
1814
1816{
1818
1819 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( aCfg );
1820 wxASSERT( cfg );
1821
1822 if( cfg )
1823 {
1824 wxAuiPaneInfo& apperancePane = m_auimgr.GetPane( AppearancePanelName() );
1825 cfg->m_AuiPanels.show_layer_manager = apperancePane.IsShown();
1826
1827 if( m_propertiesPanel )
1828 {
1829 cfg->m_AuiPanels.show_properties = m_propertiesPanel->IsShownOnScreen();
1831 cfg->m_AuiPanels.properties_splitter = m_propertiesPanel->SplitterProportion();
1832 }
1833
1834 // ensure m_ShowSearch is up to date (the pane can be closed)
1835 wxAuiPaneInfo& searchPaneInfo = m_auimgr.GetPane( SearchPaneName() );
1836 m_ShowSearch = searchPaneInfo.IsShown();
1838 cfg->m_AuiPanels.search_panel_height = m_searchPane->GetSize().y;
1839 cfg->m_AuiPanels.search_panel_width = m_searchPane->GetSize().x;
1840 cfg->m_AuiPanels.search_panel_dock_direction = searchPaneInfo.dock_direction;
1841
1843 {
1844 wxAuiPaneInfo& netInspectorhPaneInfo = m_auimgr.GetPane( NetInspectorPanelName() );
1845 m_ShowNetInspector = netInspectorhPaneInfo.IsShown();
1847 }
1848
1849 if( m_appearancePanel )
1850 {
1853 cfg->m_AuiPanels.appearance_expand_layer_display = m_appearancePanel->IsLayerOptionsExpanded();
1854 cfg->m_AuiPanels.appearance_expand_net_display = m_appearancePanel->IsNetOptionsExpanded();
1855 }
1856
1857 wxAuiPaneInfo& designBlocksPane = m_auimgr.GetPane( DesignBlocksPaneName() );
1858 cfg->m_AuiPanels.design_blocks_show = designBlocksPane.IsShown();
1859
1860 if( designBlocksPane.IsDocked() )
1862 else
1863 {
1864 cfg->m_AuiPanels.design_blocks_panel_float_height = designBlocksPane.floating_size.y;
1865 cfg->m_AuiPanels.design_blocks_panel_float_width = designBlocksPane.floating_size.x;
1866 }
1867
1868 m_designBlocksPane->SaveSettings();
1869 }
1870}
1871
1872
1874{
1875 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( config() );
1876
1877 return cfg ? cfg->m_RotationAngle : ANGLE_90;
1878}
1879
1880
1885
1886
1888{
1889
1890 GetColorSettings()->SetColor( LAYER_GRID, aColor );
1891 GetCanvas()->GetGAL()->SetGridColor( aColor );
1892}
1893
1894
1895void PCB_EDIT_FRAME::SetActiveLayer( PCB_LAYER_ID aLayer, bool aForceRedraw )
1896{
1897 const PCB_LAYER_ID oldLayer = GetActiveLayer();
1898
1899 if( oldLayer == aLayer && !aForceRedraw )
1900 return;
1901
1903
1904 m_appearancePanel->OnLayerChanged();
1905
1906 m_toolManager->PostAction( PCB_ACTIONS::layerChanged ); // notify other tools
1907 GetCanvas()->SetFocus(); // allow capture of hotkeys
1908 GetCanvas()->SetHighContrastLayer( aLayer );
1909
1910 /*
1911 * Only show pad, via and track clearances when a copper layer is active
1912 * and then only show the clearance layer for that copper layer. For
1913 * front/back non-copper layers, show the clearance layer for the outer
1914 * layer on that side.
1915 *
1916 * For pads/vias, this is to avoid clutter when there are pad/via layers
1917 * that vary in flash (i.e. clearance from the hole or pad edge), padstack
1918 * shape on each layer or clearances on each layer.
1919 *
1920 * For tracks, this follows the same logic as pads/vias, but in theory could
1921 * have their own set of independent clearance layers to allow track clearance
1922 * to be shown for more layers.
1923 */
1924 const auto getClearanceLayerForActive = []( PCB_LAYER_ID aActiveLayer ) -> std::optional<int>
1925 {
1926 if( IsCopperLayer( aActiveLayer ) )
1927 return CLEARANCE_LAYER_FOR( aActiveLayer );
1928
1929 return std::nullopt;
1930 };
1931
1932 if( std::optional<int> oldClearanceLayer = getClearanceLayerForActive( oldLayer ) )
1933 GetCanvas()->GetView()->SetLayerVisible( *oldClearanceLayer, false );
1934
1935 if( std::optional<int> newClearanceLayer = getClearanceLayerForActive( aLayer ) )
1936 GetCanvas()->GetView()->SetLayerVisible( *newClearanceLayer, true );
1937
1939 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
1940 {
1941 if( !aItem->IsBOARD_ITEM() )
1942 return 0;
1943
1944 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aItem );
1945
1946 // Note: KIGFX::REPAINT isn't enough for things that go from invisible to visible
1947 // as they won't be found in the view layer's itemset for re-painting.
1948 if( GetDisplayOptions().m_ContrastModeDisplay == HIGH_CONTRAST_MODE::HIDDEN )
1949 {
1950 if( item->IsOnLayer( oldLayer ) || item->IsOnLayer( aLayer ) )
1951 return KIGFX::ALL;
1952 }
1953
1954 if( item->Type() == PCB_VIA_T )
1955 {
1956 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1957
1958 // Vias on a restricted layer set must be redrawn when the active layer
1959 // is changed
1960 if( via->GetViaType() == VIATYPE::BLIND
1961 || via->GetViaType() == VIATYPE::BURIED
1962 || via->GetViaType() == VIATYPE::MICROVIA )
1963 {
1964 return KIGFX::REPAINT;
1965 }
1966
1967 if( via->GetRemoveUnconnected() )
1968 return KIGFX::ALL;
1969 }
1970 else if( item->Type() == PCB_PAD_T )
1971 {
1972 PAD* pad = static_cast<PAD*>( item );
1973
1974 if( pad->GetRemoveUnconnected() )
1975 return KIGFX::ALL;
1976 }
1977
1978 return 0;
1979 } );
1980
1981 GetCanvas()->Refresh();
1982}
1983
1984
1986{
1987 wxFileName fn( GetBoard()->GetFileName() );
1988
1989 if( !Prj().IsNullProject() )
1990 Kiway().LocalHistory().Init( Prj().GetProjectPath() );
1991
1993
1994 layerEnum.Choices().Clear();
1995 layerEnum.Undefined( UNDEFINED_LAYER );
1996
1997 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
1998 {
1999 // Canonical name
2000 layerEnum.Map( layer, LSET::Name( layer ) );
2001
2002 // User name
2003 layerEnum.Map( layer, GetBoard()->GetLayerName( layer ) );
2004 }
2005
2006 DRC_TOOL* drcTool = m_toolManager->GetTool<DRC_TOOL>();
2007
2008 try
2009 {
2011 }
2012 catch( PARSE_ERROR& )
2013 {
2014 // Not sure this is the best place to tell the user their rules are buggy, so
2015 // we'll stay quiet for now. Feel free to revisit this decision....
2016 }
2017
2019
2020 // Migrate obsolete WRL 3D model references to current STEP models. Only
2021 // runs in the GUI: CLI and scripting load paths must not mutate board
2022 // state on load. The STEP exporter does its own WRL->STEP substitution at
2023 // export time via the --subst-models flag, and the 3D cache quietly falls
2024 // back to sibling STEP files for missing WRLs in headless contexts.
2025 if( Pgm().IsGUI() )
2026 {
2027 // Silently replace references whose filename uniquely identifies a
2028 // STEP sibling. Leaves ambiguous cases for the infobar below.
2030
2031 const int unresolved = DIALOG_MIGRATE_3D_MODELS::CountUnresolvedWrlReferences( this );
2032
2033 if( unresolved > 0 )
2034 {
2035 wxString msg = wxString::Format( wxPLURAL( "%d WRL 3D model could not be matched "
2036 "to an equivalent STEP model.",
2037 "%d WRL 3D models could not be matched "
2038 "to equivalent STEP models.",
2039 unresolved ),
2040 unresolved );
2041
2042 wxHyperlinkCtrl* link = new wxHyperlinkCtrl( m_loadNoticeInfoBar, wxID_ANY,
2043 _( "Show options" ), wxEmptyString );
2044
2045 link->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& )>(
2046 [this]( wxHyperlinkEvent& )
2047 {
2048 DIALOG_MIGRATE_3D_MODELS dlg( this );
2049 dlg.ShowModal();
2050
2051 // Dismiss the infobar if nothing remains to resolve;
2052 // otherwise leave it so the user can try again.
2054 m_loadNoticeInfoBar->Dismiss();
2055 } ) );
2056
2057 m_loadNoticeInfoBar->RemoveAllButtons();
2058 m_loadNoticeInfoBar->AddButton( link );
2059 m_loadNoticeInfoBar->AddCloseButton();
2060 m_loadNoticeInfoBar->ShowMessageFor( msg, 10000, wxICON_INFORMATION );
2061 }
2062 }
2063
2064 UpdateTitle();
2065
2066 // Display a warning that the file is read only
2067 if( fn.FileExists() && !fn.IsFileWritable() )
2068 {
2069 m_infoBar->RemoveAllButtons();
2070 m_infoBar->AddCloseButton();
2071 m_infoBar->ShowMessage( _( "Board file is read only." ),
2072 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
2073 }
2074
2076
2077 // Sync layer and item visibility
2079
2080 SetElementVisibility( LAYER_RATSNEST, GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest );
2081
2082 m_appearancePanel->OnBoardChanged();
2083
2084 // Apply saved display state to the appearance panel after it has been set up
2085 PROJECT_LOCAL_SETTINGS& localSettings = Prj().GetLocalSettings();
2086
2087 m_appearancePanel->ApplyLayerPreset( localSettings.m_ActiveLayerPreset );
2088
2089 if( GetBoard()->GetDesignSettings().IsLayerEnabled( localSettings.m_ActiveLayer ) )
2090 SetActiveLayer( localSettings.m_ActiveLayer, true );
2091 else
2092 SetActiveLayer( GetActiveLayer(), true ); // Make sure to repaint even if not switching
2093
2094 PROJECT_FILE& projectFile = Prj().GetProjectFile();
2095
2096 m_layerPairSettings->SetLayerPairs( projectFile.m_LayerPairInfos );
2097 m_layerPairSettings->SetCurrentLayerPair( LAYER_PAIR{ F_Cu, B_Cu } );
2098
2099 // Updates any auto dimensions and the auxiliary toolbar tracks/via sizes
2101
2102 // Sync the net inspector now we have connectivity calculated
2104 m_netInspectorPanel->OnBoardChanged();
2105
2106 // Display the loaded board:
2107 Zoom_Automatique( false );
2108
2109 // Invalidate painting as loading the DRC engine will cause clearances to become valid
2111
2112 Refresh();
2113
2114 SetMsgPanel( GetBoard() );
2115 SetStatusText( wxEmptyString );
2116
2117 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "PCB file changes are unsaved" ) );
2118}
2119
2120
2122{
2123 m_appearancePanel->UpdateDisplayOptions();
2124}
2125
2126
2128{
2129 return GetBoard()->IsElementVisible( aElement );
2130}
2131
2132
2134{
2135 // Force the RATSNEST visible
2136 if( aElement == LAYER_RATSNEST )
2137 GetCanvas()->GetView()->SetLayerVisible( aElement, true );
2138 else
2139 GetCanvas()->GetView()->SetLayerVisible( aElement , aNewState );
2140
2141 GetBoard()->SetElementVisibility( aElement, aNewState );
2142}
2143
2144
2146{
2147 // call my base class
2149
2150 m_auimgr.GetPane( m_appearancePanel ).Caption( _( "Appearance" ) );
2151 m_auimgr.GetPane( m_selectionFilterPanel ).Caption( _( "Selection Filter" ) );
2152 m_auimgr.GetPane( m_propertiesPanel ).Caption( _( "Properties" ) );
2153 m_auimgr.GetPane( m_netInspectorPanel ).Caption( _( "Net Inspector" ) );
2154 m_auimgr.Update();
2155
2156 UpdateTitle();
2157}
2158
2159
2161{
2163
2164 if( project.m_PcbLastPath[ aType ].IsEmpty() )
2165 return wxEmptyString;
2166
2167 wxFileName absoluteFileName = project.m_PcbLastPath[ aType ];
2168 wxFileName pcbFileName = GetBoard()->GetFileName();
2169
2170 absoluteFileName.MakeAbsolute( pcbFileName.GetPath() );
2171 return absoluteFileName.GetFullPath();
2172}
2173
2174
2175void PCB_EDIT_FRAME::SetLastPath( LAST_PATH_TYPE aType, const wxString& aLastPath )
2176{
2178
2179 wxFileName relativeFileName = aLastPath;
2180 wxFileName pcbFileName = GetBoard()->GetFileName();
2181
2182 relativeFileName.MakeRelativeTo( pcbFileName.GetPath() );
2183
2184 if( relativeFileName.GetFullPath() != project.m_PcbLastPath[ aType ] )
2185 {
2186 project.m_PcbLastPath[ aType ] = relativeFileName.GetFullPath();
2187 OnModify();
2188 }
2189}
2190
2191
2193{
2195 Kiway().LocalHistory().NoteFileChange( GetBoard()->GetFileName() );
2196 m_ZoneFillsDirty = true;
2197
2198 if( m_isClosing )
2199 return;
2200
2201 Update3DView( true, GetPcbNewSettings()->m_Display.m_Live3DRefresh );
2202
2203 if( !GetTitle().StartsWith( wxT( "*" ) ) )
2204 UpdateTitle();
2205
2206}
2207
2208
2210{
2211 Update3DView( true, true );
2212
2213 std::shared_ptr<CONNECTIVITY_DATA> connectivity = GetBoard()->GetConnectivity();
2214 connectivity->RecalculateRatsnest( nullptr );
2216
2217 std::vector<MSG_PANEL_ITEM> msg_list;
2218 GetBoard()->GetMsgPanelInfo( this, msg_list );
2219 SetMsgPanel( msg_list );
2220}
2221
2222
2224{
2225 wxFileName fn = GetBoard()->GetFileName();
2226 bool readOnly = false;
2227 bool unsaved = false;
2228
2229 if( fn.IsOk() && fn.FileExists() )
2230 readOnly = !fn.IsFileWritable();
2231 else
2232 unsaved = true;
2233
2234 wxString title;
2235
2236 if( IsContentModified() )
2237 title = wxT( "*" );
2238
2239 title += fn.GetName();
2240
2241 if( readOnly )
2242 title += wxS( " " ) + _( "[Read Only]" );
2243
2244 if( unsaved )
2245 title += wxS( " " ) + _( "[Unsaved]" );
2246
2247 title += wxT( " \u2014 " ) + _( "PCB Editor" );
2248
2249 SetTitle( title );
2250}
2251
2252
2254{
2255 // Update the layer manager and other widgets from the board setup
2256 // (layer and items visibility, colors ...)
2257
2258 // Rebuild list of nets (full ratsnest rebuild)
2260
2261 // Update info shown by the horizontal toolbars
2263
2264 LSET activeLayers = GetBoard()->GetEnabledLayers();
2265
2266 if( !activeLayers.test( GetActiveLayer() ) )
2267 SetActiveLayer( activeLayers.Seq().front() );
2268
2269 // The layer selector lives on the top auxiliary toolbar. Users can remove every
2270 // entry from that toolbar via Preferences, in which case the control is destroyed
2271 // and m_SelLayerBox is null. Avoid dereferencing it here.
2272 if( m_SelLayerBox )
2273 m_SelLayerBox->SetLayerSelection( GetActiveLayer() );
2274
2276
2277 layerEnum.Choices().Clear();
2278 layerEnum.Undefined( UNDEFINED_LAYER );
2279
2280 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
2281 {
2282 // Canonical name
2283 layerEnum.Map( layer, LSET::Name( layer ) );
2284
2285 // User name
2286 layerEnum.Map( layer, GetBoard()->GetLayerName( layer ) );
2287 }
2288
2290
2291 // Sync visibility with canvas
2292 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
2293 GetCanvas()->GetView()->SetLayerVisible( layer, GetBoard()->IsLayerVisible( layer ) );
2294
2295 // Stackup and/or color theme may have changed
2296 m_appearancePanel->OnBoardChanged();
2297 m_netInspectorPanel->OnParentSetupChanged();
2298}
2299
2300
2302{
2303 // switches currently used canvas (Cairo / OpenGL).
2304 PCB_BASE_FRAME::SwitchCanvas( aCanvasType );
2305}
2306
2307
2309{
2310 if( !m_findDialog )
2311 {
2312 m_findDialog = new DIALOG_FIND( this );
2313 m_findDialog->SetCallback( std::bind( &PCB_SELECTION_TOOL::FindItem,
2314 m_toolManager->GetTool<PCB_SELECTION_TOOL>(), _1 ) );
2315 }
2316
2317 wxString findString;
2318
2319 PCB_SELECTION& selection = m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
2320
2321 if( selection.Size() == 1 )
2322 {
2323 EDA_ITEM* front = selection.Front();
2324
2325 switch( front->Type() )
2326 {
2327 case PCB_FOOTPRINT_T:
2328 findString = UnescapeString( static_cast<FOOTPRINT*>( front )->GetValue() );
2329 break;
2330
2331 case PCB_FIELD_T:
2332 case PCB_TEXT_T:
2333 findString = UnescapeString( static_cast<PCB_TEXT*>( front )->GetText() );
2334
2335 if( findString.Contains( wxT( "\n" ) ) )
2336 findString = findString.Before( '\n' );
2337
2338 break;
2339
2340 default:
2341 break;
2342 }
2343 }
2344
2345 m_findDialog->Preload( findString );
2346
2347 m_findDialog->Show( true );
2348}
2349
2350
2359
2360
2366
2367
2373
2374
2375void PCB_EDIT_FRAME::FindNext( bool reverse )
2376{
2377 if( !m_findDialog )
2379
2380 m_findDialog->FindNext( reverse );
2381}
2382
2383
2385{
2386 if( Kiface().IsSingle() )
2387 return 0;
2388
2389 // Update PCB requires a netlist. Therefore the schematic editor must be running
2390 // If this is not the case, open the schematic editor
2391 KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH, true );
2392
2393 // If Kiway() cannot create the eeschema frame, it shows a error message, and
2394 // frame is null
2395 if( !frame )
2396 return -1;
2397
2398 if( !frame->IsShownOnScreen() )
2399 {
2400 wxEventBlocker blocker( this );
2401 wxFileName fn( Prj().GetProjectPath(), Prj().GetProjectName(),
2403
2404 // Maybe the file hasn't been converted to the new s-expression file format so
2405 // see if the legacy schematic file is still in play.
2406 if( !fn.FileExists() )
2407 {
2409
2410 if( !fn.FileExists() )
2411 {
2412 DisplayErrorMessage( this, _( "The schematic for this board cannot be found." ) );
2413 return -2;
2414 }
2415 }
2416
2417 frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
2418
2419 // we show the schematic editor frame, because do not show is seen as
2420 // a not yet opened schematic by Kicad manager, which is not the case
2421 frame->Show( true );
2422
2423 // bring ourselves back to the front
2424 Raise();
2425 }
2426
2427 return 1; //Success!
2428}
2429
2430
2432 const wxString& aAnnotateMessage )
2433{
2434 int standalone = TestStandalone();
2435
2436 if( standalone == 0 )
2437 {
2438 DisplayErrorMessage( this, _( "Cannot update the PCB because PCB editor is opened in "
2439 "stand-alone mode. In order to create or update PCBs from "
2440 "schematics, you must launch the KiCad project manager and "
2441 "create a project." ) );
2442 return false; // Not in standalone mode
2443 }
2444
2445 if( standalone < 0 ) // Problem with Eeschema or the schematic
2446 return false;
2447
2448 Raise(); // Show
2449
2450 std::string payload( aAnnotateMessage );
2451
2452 Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_GET_NETLIST, payload, this );
2453
2454 if( payload == aAnnotateMessage )
2455 {
2456 Raise();
2457 DisplayErrorMessage( this, aAnnotateMessage );
2458 return false;
2459 }
2460
2461 try
2462 {
2463 auto lineReader = new STRING_LINE_READER( payload, _( "Eeschema netlist" ) );
2464 KICAD_NETLIST_READER netlistReader( lineReader, &aNetlist );
2465 netlistReader.LoadNetlist();
2466 }
2467 catch( const IO_ERROR& e )
2468 {
2469 Raise();
2470
2471 // Do not translate extra_info strings. These are for developers
2472 wxString extra_info = e.Problem() + wxT( " : " ) + e.What() + wxT( " at " ) + e.Where();
2473
2474 DisplayErrorMessage( this, _( "Received an error while reading netlist. Please "
2475 "report this issue to the KiCad team using the menu "
2476 "Help->Report Bug."), extra_info );
2477 return false;
2478 }
2479
2480 return true;
2481}
2482
2483
2485{
2486 if( aFootprint == nullptr )
2487 return;
2488
2490
2491 /*
2492 * Make sure dlg is destroyed before GetCanvas->Refresh is called
2493 * later or the refresh will try to modify its properties since
2494 * they share a GL context.
2495 */
2496 {
2497 DIALOG_FOOTPRINT_PROPERTIES dlg( this, aFootprint );
2498
2499 dlg.ShowQuasiModal();
2500 retvalue = dlg.GetReturnValue();
2501 }
2502
2503 /*
2504 * retvalue =
2505 * FP_PROPS_UPDATE_FP to show Update Footprints dialog
2506 * FP_PROPS_CHANGE_FP to show Change Footprints dialog
2507 * FP_PROPS_OK for normal edit
2508 * FP_PROPS_CANCEL if aborted
2509 * FP_PROPS_EDIT_BOARD_FP to load board footprint into Footprint Editor
2510 * FP_PROPS_EDIT_LIBRARY_FP to load library footprint into Footprint Editor
2511 */
2512
2514 {
2515 // If something edited, push a refresh request
2516 GetCanvas()->Refresh();
2517 }
2519 {
2520 if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_EDITOR, true ) )
2521 {
2522 FOOTPRINT_EDIT_FRAME* fp_editor = static_cast<FOOTPRINT_EDIT_FRAME*>( frame );
2523
2524 fp_editor->LoadFootprintFromBoard( aFootprint );
2525 fp_editor->Show( true );
2526 fp_editor->Raise(); // Iconize( false );
2527 }
2528 }
2530 {
2531 if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_EDITOR, true ) )
2532 {
2533 FOOTPRINT_EDIT_FRAME* fp_editor = static_cast<FOOTPRINT_EDIT_FRAME*>( frame );
2534
2535 fp_editor->LoadFootprintFromLibrary( aFootprint->GetFPID() );
2536 fp_editor->Show( true );
2537 fp_editor->Raise(); // Iconize( false );
2538 }
2539 }
2541 {
2542 ShowExchangeFootprintsDialog( aFootprint, true, true );
2543 }
2545 {
2546 ShowExchangeFootprintsDialog( aFootprint, false, true );
2547 }
2548}
2549
2550
2552 bool aSelectedMode )
2553{
2554 DIALOG_EXCHANGE_FOOTPRINTS dialog( this, aFootprint, aUpdateMode, aSelectedMode );
2555
2556 return dialog.ShowQuasiModal();
2557}
2558
2559
2573static void processTextItem( const PCB_TEXT& aSrc, PCB_TEXT& aDest, const VECTOR2I& aPosShift,
2574 const EDA_ANGLE& aAngleShift, bool aResetText, bool aResetTextLayers,
2575 bool aResetTextEffects, bool aResetTextPositions, bool* aUpdated )
2576{
2577 if( aResetText )
2578 *aUpdated |= aSrc.GetText() != aDest.GetText();
2579 else
2580 aDest.SetText( aSrc.GetText() );
2581
2582 if( aResetTextLayers )
2583 {
2584 *aUpdated |= aSrc.GetLayer() != aDest.GetLayer();
2585 *aUpdated |= aSrc.IsVisible() != aDest.IsVisible();
2586 }
2587 else
2588 {
2589 aDest.SetLayer( aSrc.GetLayer() );
2590 aDest.SetVisible( aSrc.IsVisible() );
2591 }
2592
2593 VECTOR2I origPos = aDest.GetFPRelativePosition();
2594
2595 if( aResetTextEffects )
2596 {
2597 *aUpdated |= aSrc.GetHorizJustify() != aDest.GetHorizJustify();
2598 *aUpdated |= aSrc.GetVertJustify() != aDest.GetVertJustify();
2599 *aUpdated |= aSrc.GetTextSize() != aDest.GetTextSize();
2600 *aUpdated |= aSrc.GetTextThickness() != aDest.GetTextThickness();
2601 }
2602 else
2603 {
2604 EDA_ANGLE origAngle = aDest.GetTextAngle();
2605 aDest.SetAttributes( aSrc );
2606 aDest.SetTextAngle( origAngle ); // apply rotation as part of position shift
2607 }
2608
2609 if( aResetTextPositions )
2610 {
2611 *aUpdated |= aSrc.GetFPRelativePosition() != origPos;
2612 *aUpdated |= aSrc.GetTextAngle() != aDest.GetTextAngle();
2613
2614 aDest.SetFPRelativePosition( origPos );
2615 }
2616 else
2617 {
2618 VECTOR2I rotatedShift = GetRotated( aSrc.GetFPRelativePosition() - aPosShift, -aAngleShift );
2619
2620 aDest.SetFPRelativePosition( rotatedShift );
2621 aDest.SetTextAngle( aSrc.GetTextAngle() );
2622 }
2623
2624 aDest.SetLocked( aSrc.IsLocked() );
2625 aDest.SetUuid( aSrc.m_Uuid );
2626}
2627
2628
2629template<typename T>
2630static std::vector<std::pair<T*, T*>> matchItemsBySimilarity( const std::vector<T*>& aExisting,
2631 const std::vector<T*>& aNew )
2632{
2633 struct MATCH_CANDIDATE
2634 {
2635 T* existing;
2636 T* updated;
2637 double score;
2638 };
2639
2640 std::vector<MATCH_CANDIDATE> candidates;
2641
2642 for( T* existing : aExisting )
2643 {
2644 for( T* updated : aNew )
2645 {
2646 if( existing->Type() != updated->Type() )
2647 continue;
2648
2649 double similarity = existing->Similarity( *updated );
2650
2651 if constexpr( std::is_same_v<T, PAD> )
2652 {
2653 if( existing->GetNumber() == updated->GetNumber() )
2654 similarity += 2.0;
2655 }
2656
2657 if( similarity <= 0.0 )
2658 continue;
2659
2660 candidates.push_back( { existing, updated, similarity } );
2661 }
2662 }
2663
2664 std::sort( candidates.begin(), candidates.end(),
2665 []( const MATCH_CANDIDATE& a, const MATCH_CANDIDATE& b )
2666 {
2667 if( a.score != b.score )
2668 return a.score > b.score;
2669
2670 if( a.existing != b.existing )
2671 return a.existing < b.existing;
2672
2673 return a.updated < b.updated;
2674 } );
2675
2676 std::vector<std::pair<T*, T*>> matches;
2677 matches.reserve( candidates.size() );
2678
2679 std::unordered_set<T*> matchedExisting;
2680 std::unordered_set<T*> matchedNew;
2681
2682 for( const MATCH_CANDIDATE& candidate : candidates )
2683 {
2684 if( matchedExisting.find( candidate.existing ) != matchedExisting.end() )
2685 continue;
2686
2687 if( matchedNew.find( candidate.updated ) != matchedNew.end() )
2688 continue;
2689
2690 matchedExisting.insert( candidate.existing );
2691 matchedNew.insert( candidate.updated );
2692 matches.emplace_back( candidate.existing, candidate.updated );
2693 }
2694
2695 return matches;
2696}
2697
2698
2700 BOARD_COMMIT& aCommit,
2701 bool matchPadPositions,
2702 bool deleteExtraTexts,
2703 bool resetTextLayers,
2704 bool resetTextEffects,
2705 bool resetTextPositions,
2706 bool resetTextContent,
2707 bool resetFabricationAttrs,
2708 bool resetClearanceOverrides,
2709 bool reset3DModels,
2710 bool* aUpdated )
2711{
2712 EDA_GROUP* parentGroup = aExisting->GetParentGroup();
2713 bool dummyBool = false;
2714
2715 if( !aUpdated )
2716 aUpdated = &dummyBool;
2717
2718 if( parentGroup )
2719 {
2720 aCommit.Modify( parentGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
2721 parentGroup->RemoveItem( aExisting );
2722 parentGroup->AddItem( aNew );
2723 }
2724
2725 aNew->SetParent( GetBoard() );
2726
2727 // This is the position and angle shift to apply to the new footprint if the footprint
2728 // has a change anchor point or rotation compared to the existing footprint.
2729 VECTOR2I posShift( 0, 0 );
2730 EDA_ANGLE angleShift = ANGLE_0;
2731
2732 VECTOR2I position = aExisting->GetPosition();
2733 EDA_ANGLE orientation = aExisting->GetOrientation();
2734
2735 if( matchPadPositions )
2736 {
2737 if( ComputeFootprintShift( *aExisting, *aNew, posShift, angleShift ) )
2738 {
2739 position += posShift;
2740 orientation += angleShift;
2741 }
2742 }
2743
2744 PlaceFootprint( aNew, false, position );
2745
2746 if( aNew->GetLayer() != aExisting->GetLayer() )
2747 aNew->Flip( aNew->GetPosition(), GetPcbNewSettings()->m_FlipDirection );
2748
2749 if( aNew->GetOrientation() != orientation )
2750 aNew->SetOrientation( orientation );
2751
2752 aNew->SetLocked( aExisting->IsLocked() );
2753
2754 aNew->SetUuid( aExisting->m_Uuid );
2755 aNew->Reference().SetUuid( aExisting->Reference().m_Uuid );
2756 aNew->Value().SetUuid( aExisting->Value().m_Uuid );
2757
2758 std::vector<PAD*> oldPads;
2759 oldPads.reserve( aExisting->Pads().size() );
2760
2761 for( PAD* pad : aExisting->Pads() )
2762 oldPads.push_back( pad );
2763
2764 std::vector<PAD*> newPads;
2765 newPads.reserve( aNew->Pads().size() );
2766
2767 for( PAD* pad : aNew->Pads() )
2768 newPads.push_back( pad );
2769
2770 auto padMatches = matchItemsBySimilarity<PAD>( oldPads, newPads );
2771 std::unordered_set<PAD*> matchedNewPads;
2772
2773 for( const auto& match : padMatches )
2774 {
2775 PAD* oldPad = match.first;
2776 PAD* newPad = match.second;
2777
2778 matchedNewPads.insert( newPad );
2779 newPad->SetUuid( oldPad->m_Uuid );
2781 newPad->SetPinFunction( oldPad->GetPinFunction() );
2782 newPad->SetPinType( oldPad->GetPinType() );
2783
2784 if( newPad->IsOnCopperLayer() )
2785 newPad->SetNetCode( oldPad->GetNetCode() );
2786 else
2788 }
2789
2790 for( PAD* newPad : aNew->Pads() )
2791 {
2792 if( matchedNewPads.find( newPad ) != matchedNewPads.end() )
2793 continue;
2794
2795 newPad->ResetUuid();
2796 newPad->SetNetCode( NETINFO_LIST::UNCONNECTED );
2797 }
2798
2799 std::vector<BOARD_ITEM*> oldDrawings;
2800 oldDrawings.reserve( aExisting->GraphicalItems().size() );
2801
2802 for( BOARD_ITEM* item : aExisting->GraphicalItems() )
2803 oldDrawings.push_back( item );
2804
2805 std::vector<BOARD_ITEM*> newDrawings;
2806 newDrawings.reserve( aNew->GraphicalItems().size() );
2807
2808 for( BOARD_ITEM* item : aNew->GraphicalItems() )
2809 newDrawings.push_back( item );
2810
2811 auto drawingMatches = matchItemsBySimilarity<BOARD_ITEM>( oldDrawings, newDrawings );
2812 std::unordered_map<BOARD_ITEM*, BOARD_ITEM*> oldToNewDrawings;
2813 std::unordered_set<BOARD_ITEM*> matchedNewDrawings;
2814
2815 for( const auto& match : drawingMatches )
2816 {
2817 BOARD_ITEM* oldItem = match.first;
2818 BOARD_ITEM* newItem = match.second;
2819
2820 oldToNewDrawings[ oldItem ] = newItem;
2821 matchedNewDrawings.insert( newItem );
2822 newItem->SetUuid( oldItem->m_Uuid );
2823 }
2824
2825 for( BOARD_ITEM* newItem : newDrawings )
2826 {
2827 if( matchedNewDrawings.find( newItem ) == matchedNewDrawings.end() )
2828 newItem->ResetUuid();
2829 }
2830
2831 std::vector<ZONE*> oldZones;
2832 oldZones.reserve( aExisting->Zones().size() );
2833
2834 for( ZONE* zone : aExisting->Zones() )
2835 oldZones.push_back( zone );
2836
2837 std::vector<ZONE*> newZones;
2838 newZones.reserve( aNew->Zones().size() );
2839
2840 for( ZONE* zone : aNew->Zones() )
2841 newZones.push_back( zone );
2842
2843 auto zoneMatches = matchItemsBySimilarity<ZONE>( oldZones, newZones );
2844 std::unordered_set<ZONE*> matchedNewZones;
2845
2846 for( const auto& match : zoneMatches )
2847 {
2848 ZONE* oldZone = match.first;
2849 ZONE* newZone = match.second;
2850
2851 matchedNewZones.insert( newZone );
2852 newZone->SetUuid( oldZone->m_Uuid );
2853 }
2854
2855 for( ZONE* newZone : newZones )
2856 {
2857 if( matchedNewZones.find( newZone ) == matchedNewZones.end() )
2858 newZone->ResetUuid();
2859 }
2860
2861 std::vector<PCB_POINT*> oldPoints;
2862 oldPoints.reserve( aExisting->Points().size() );
2863
2864 for( PCB_POINT* point : aExisting->Points() )
2865 oldPoints.push_back( point );
2866
2867 std::vector<PCB_POINT*> newPoints;
2868 newPoints.reserve( aNew->Points().size() );
2869
2870 for( PCB_POINT* point : aNew->Points() )
2871 newPoints.push_back( point );
2872
2873 auto pointMatches = matchItemsBySimilarity<PCB_POINT>( oldPoints, newPoints );
2874 std::unordered_set<PCB_POINT*> matchedNewPoints;
2875
2876 for( const auto& match : pointMatches )
2877 {
2878 PCB_POINT* oldPoint = match.first;
2879 PCB_POINT* newPoint = match.second;
2880
2881 matchedNewPoints.insert( newPoint );
2882 newPoint->SetUuid( oldPoint->m_Uuid );
2883 }
2884
2885 for( PCB_POINT* newPoint : newPoints )
2886 {
2887 if( matchedNewPoints.find( newPoint ) == matchedNewPoints.end() )
2888 newPoint->ResetUuid();
2889 }
2890
2891 std::vector<PCB_GROUP*> oldGroups;
2892 oldGroups.reserve( aExisting->Groups().size() );
2893
2894 for( PCB_GROUP* group : aExisting->Groups() )
2895 oldGroups.push_back( group );
2896
2897 std::vector<PCB_GROUP*> newGroups;
2898 newGroups.reserve( aNew->Groups().size() );
2899
2900 for( PCB_GROUP* group : aNew->Groups() )
2901 newGroups.push_back( group );
2902
2903 auto groupMatches = matchItemsBySimilarity<PCB_GROUP>( oldGroups, newGroups );
2904 std::unordered_set<PCB_GROUP*> matchedNewGroups;
2905
2906 for( const auto& match : groupMatches )
2907 {
2908 PCB_GROUP* oldGroup = match.first;
2909 PCB_GROUP* newGroup = match.second;
2910
2911 matchedNewGroups.insert( newGroup );
2912 newGroup->SetUuid( oldGroup->m_Uuid );
2913 }
2914
2915 for( PCB_GROUP* newGroup : newGroups )
2916 {
2917 if( matchedNewGroups.find( newGroup ) == matchedNewGroups.end() )
2918 newGroup->ResetUuid();
2919 }
2920
2921 std::vector<PCB_FIELD*> oldFieldsVec;
2922 std::vector<PCB_FIELD*> newFieldsVec;
2923
2924 oldFieldsVec.reserve( aExisting->GetFields().size() );
2925
2926 for( PCB_FIELD* field : aExisting->GetFields() )
2927 {
2928 wxCHECK2( field, continue );
2929
2930 if( field->IsReference() || field->IsValue() )
2931 continue;
2932
2933 oldFieldsVec.push_back( field );
2934 }
2935
2936 newFieldsVec.reserve( aNew->GetFields().size() );
2937
2938 for( PCB_FIELD* field : aNew->GetFields() )
2939 {
2940 wxCHECK2( field, continue );
2941
2942 if( field->IsReference() || field->IsValue() )
2943 continue;
2944
2945 newFieldsVec.push_back( field );
2946 }
2947
2948 auto fieldMatches = matchItemsBySimilarity<PCB_FIELD>( oldFieldsVec, newFieldsVec );
2949 std::unordered_map<PCB_FIELD*, PCB_FIELD*> oldToNewFields;
2950 std::unordered_set<PCB_FIELD*> matchedNewFields;
2951
2952 for( const auto& match : fieldMatches )
2953 {
2954 PCB_FIELD* oldField = match.first;
2955 PCB_FIELD* newField = match.second;
2956
2957 oldToNewFields[ oldField ] = newField;
2958 matchedNewFields.insert( newField );
2959 newField->SetUuid( oldField->m_Uuid );
2960 }
2961
2962 for( PCB_FIELD* newField : newFieldsVec )
2963 {
2964 if( matchedNewFields.find( newField ) == matchedNewFields.end() )
2965 newField->ResetUuid();
2966 }
2967
2968 std::unordered_map<PCB_TEXT*, PCB_TEXT*> oldToNewTexts;
2969
2970 for( const auto& match : drawingMatches )
2971 {
2972 PCB_TEXT* oldText = dynamic_cast<PCB_TEXT*>( match.first );
2973 PCB_TEXT* newText = dynamic_cast<PCB_TEXT*>( match.second );
2974
2975 if( oldText && newText )
2976 oldToNewTexts[ oldText ] = newText;
2977 }
2978
2979 std::set<PCB_TEXT*> handledTextItems;
2980
2981 for( BOARD_ITEM* oldItem : aExisting->GraphicalItems() )
2982 {
2983 PCB_TEXT* oldTextItem = dynamic_cast<PCB_TEXT*>( oldItem );
2984
2985 if( oldTextItem )
2986 {
2987 // Dimensions have PCB_TEXT base but are not treated like texts in the updater
2988 if( dynamic_cast<PCB_DIMENSION_BASE*>( oldTextItem ) )
2989 continue;
2990
2991 PCB_TEXT* newTextItem = nullptr;
2992
2993 auto textMatchIt = oldToNewTexts.find( oldTextItem );
2994
2995 if( textMatchIt != oldToNewTexts.end() )
2996 newTextItem = textMatchIt->second;
2997
2998 if( newTextItem )
2999 {
3000 handledTextItems.insert( newTextItem );
3001 processTextItem( *oldTextItem, *newTextItem, posShift, angleShift, resetTextContent, resetTextLayers,
3002 resetTextEffects, resetTextPositions, aUpdated );
3003 }
3004 else if( deleteExtraTexts )
3005 {
3006 *aUpdated = true;
3007 }
3008 else
3009 {
3010 newTextItem = static_cast<PCB_TEXT*>( oldTextItem->Clone() );
3011 handledTextItems.insert( newTextItem );
3012 aNew->Add( newTextItem );
3013 }
3014 }
3015 }
3016
3017 // Check for any newly-added text items and set the update flag as appropriate
3018 for( BOARD_ITEM* newItem : aNew->GraphicalItems() )
3019 {
3020 PCB_TEXT* newTextItem = dynamic_cast<PCB_TEXT*>( newItem );
3021
3022 if( newTextItem )
3023 {
3024 // Dimensions have PCB_TEXT base but are not treated like texts in the updater
3025 if( dynamic_cast<PCB_DIMENSION_BASE*>( newTextItem ) )
3026 continue;
3027
3028 if( !handledTextItems.contains( newTextItem ) )
3029 {
3030 *aUpdated = true;
3031 break;
3032 }
3033 }
3034 }
3035
3036 // Copy reference. The initial text is always used, never resetted
3037 processTextItem( aExisting->Reference(), aNew->Reference(), posShift, angleShift, false, resetTextLayers,
3038 resetTextEffects, resetTextPositions, aUpdated );
3039
3040 // Copy value
3041 processTextItem( aExisting->Value(), aNew->Value(), posShift, angleShift,
3042 // reset value text only when it is a proxy for the footprint ID
3043 // (cf replacing value "MountingHole-2.5mm" with "MountingHole-4.0mm")
3044 aExisting->GetValue() == aExisting->GetFPID().GetLibItemName().wx_str(),
3045 resetTextLayers, resetTextEffects, resetTextPositions, aUpdated );
3046
3047 std::set<PCB_FIELD*> handledFields;
3048
3049 // Copy fields in accordance with the reset* flags
3050 for( PCB_FIELD* oldField : aExisting->GetFields() )
3051 {
3052 wxCHECK2( oldField, continue );
3053
3054 // Reference and value are already handled
3055 if( oldField->IsReference() || oldField->IsValue() )
3056 continue;
3057
3058 PCB_FIELD* newField = nullptr;
3059
3060 auto fieldMatchIt = oldToNewFields.find( oldField );
3061
3062 if( fieldMatchIt != oldToNewFields.end() )
3063 newField = fieldMatchIt->second;
3064
3065 if( newField )
3066 {
3067 handledFields.insert( newField );
3068 processTextItem( *oldField, *newField, posShift, angleShift, resetTextContent, resetTextLayers,
3069 resetTextEffects, resetTextPositions, aUpdated );
3070 }
3071 else if( deleteExtraTexts )
3072 {
3073 *aUpdated = true;
3074 }
3075 else
3076 {
3077 newField = new PCB_FIELD( *oldField );
3078 handledFields.insert( newField );
3079 aNew->Add( newField );
3080 }
3081 }
3082
3083 // Check for any newly-added fields and set the update flag as appropriate
3084 for( PCB_FIELD* newField : aNew->GetFields() )
3085 {
3086 wxCHECK2( newField, continue );
3087
3088 // Reference and value are already handled
3089 if( newField->IsReference() || newField->IsValue() )
3090 continue;
3091
3092 if( !handledFields.contains( newField ) )
3093 {
3094 *aUpdated = true;
3095 break;
3096 }
3097 }
3098
3099 if( resetFabricationAttrs )
3100 {
3101 // We've replaced the existing footprint with the library one, so the fabrication attrs
3102 // are already reset. Just set the aUpdated flag if appropriate.
3103 if( aNew->GetAttributes() != aExisting->GetAttributes() )
3104 *aUpdated = true;
3105 }
3106 else
3107 {
3108 aNew->SetAttributes( aExisting->GetAttributes() );
3109 }
3110
3111 if( resetClearanceOverrides )
3112 {
3113 if( aExisting->AllowSolderMaskBridges() != aNew->AllowSolderMaskBridges() )
3114 *aUpdated = true;
3115
3116 if( ( aExisting->GetLocalClearance() != aNew->GetLocalClearance() )
3117 || ( aExisting->GetLocalSolderMaskMargin() != aNew->GetLocalSolderMaskMargin() )
3118 || ( aExisting->GetLocalSolderPasteMargin() != aNew->GetLocalSolderPasteMargin() )
3120 || ( aExisting->GetLocalZoneConnection() != aNew->GetLocalZoneConnection() ) )
3121 {
3122 *aUpdated = true;
3123 }
3124 }
3125 else
3126 {
3127 aNew->SetLocalClearance( aExisting->GetLocalClearance() );
3131 aNew->SetLocalZoneConnection( aExisting->GetLocalZoneConnection() );
3133 }
3134
3135 if( reset3DModels )
3136 {
3137 // We've replaced the existing footprint with the library one, so the 3D models are
3138 // already reset. Just set the aUpdated flag if appropriate.
3139 if( aNew->Models().size() != aExisting->Models().size() )
3140 {
3141 *aUpdated = true;
3142 }
3143 else
3144 {
3145 for( size_t ii = 0; ii < aNew->Models().size(); ++ii )
3146 {
3147 if( aNew->Models()[ii] != aExisting->Models()[ii] )
3148 {
3149 *aUpdated = true;
3150 break;
3151 }
3152 }
3153 }
3154 }
3155 else
3156 {
3157 // Preserve model references and all embedded model data.
3158 aNew->Models() = aExisting->Models();
3159
3160 // Preserve extruded 3D body settings.
3161 if( aExisting->HasExtrudedBody() )
3162 aNew->SetExtrudedBody( std::make_unique<EXTRUDED_3D_BODY>( *aExisting->GetExtrudedBody() ) );
3163 else
3164 aNew->ClearExtrudedBody();
3165
3166 for( const auto& [name, file] : aExisting->GetEmbeddedFiles()->EmbeddedFileMap() )
3167 {
3169 continue;
3170
3171 aNew->GetEmbeddedFiles()->RemoveFile( name, true );
3173 }
3174 }
3175
3176 // Updating other parameters
3177 aNew->SetPath( aExisting->GetPath() );
3178 aNew->SetSheetfile( aExisting->GetSheetfile() );
3179 aNew->SetSheetname( aExisting->GetSheetname() );
3180 aNew->SetFilters( aExisting->GetFilters() );
3181 aNew->SetStaticComponentClass( aExisting->GetComponentClass() );
3182
3183 if( *aUpdated == false )
3184 {
3185 // Check pad shapes, graphics, zones, etc. for changes
3187 *aUpdated = true;
3188 }
3189
3190 aCommit.Remove( aExisting );
3191 aCommit.Add( aNew );
3192
3193 aNew->ClearFlags();
3194}
3195
3196
3198{
3200 m_appearancePanel->CommonSettingsChanged( aFlags );
3201
3203
3205
3206 SetElementVisibility( LAYER_RATSNEST, GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest );
3207
3209
3210 // Netclass definitions could have changed, either by us or by Eeschema, so we need to
3211 // recompile the implicit rules
3212 DRC_TOOL* drcTool = m_toolManager->GetTool<DRC_TOOL>();
3213 WX_INFOBAR* infobar = GetInfoBar();
3214
3215 try
3216 {
3218
3219 if( infobar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::DRC_RULES_ERROR )
3220 infobar->Dismiss();
3221 }
3222 catch( PARSE_ERROR& )
3223 {
3224 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _( "Edit design rules" ),
3225 wxEmptyString );
3226
3227 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
3228 [&]( wxHyperlinkEvent& aEvent )
3229 {
3230 ShowBoardSetupDialog( _( "Custom Rules" ) );
3231 } ) );
3232
3233 infobar->RemoveAllButtons();
3234 infobar->AddButton( button );
3235 infobar->AddCloseButton();
3236 infobar->ShowMessage( _( "Could not compile custom design rules." ), wxICON_ERROR,
3237 WX_INFOBAR::MESSAGE_TYPE::DRC_RULES_ERROR );
3238 }
3239
3242
3243 Layout();
3244 SendSizeEvent();
3245}
3246
3247
3252
3253
3255{
3256 // Register autosave history saver for the board.
3257 // Saver serializes the in-memory BOARD into HISTORY_FILE_DATA. Prettify and
3258 // file I/O happen on a background thread to avoid blocking the UI.
3259 if( GetBoard() )
3260 {
3262 GetBoard(),
3263 [this]( const wxString& aProjectPath, std::vector<HISTORY_FILE_DATA>& aFileData )
3264 {
3265 // See SCHEMATIC::SaveToHistory: the dirty check is only valid in ZIP
3266 // mode. In INCREMENTAL mode the manual-save flow clears the dirty
3267 // flag before the saver runs, so filtering would drop the snapshot.
3268 bool filterClean = Pgm().GetCommonSettings()->m_Backup.format == BACKUP_FORMAT::ZIP;
3269
3270 if( filterClean && !IsContentModified() )
3271 return;
3272
3273 GetBoard()->SaveToHistory( aProjectPath, aFileData );
3274 } );
3275 }
3276}
3277
3278
3280{
3281 TOOL_BASE* currentTool = GetToolManager()->GetCurrentTool();
3282
3283 // When a single item that can be point-edited is selected, the point editor
3284 // tool will be active instead of the selection tool. It blocks undo/redo
3285 // while the user is actually dragging points around, though, so we can use
3286 // this as an initial check to prevent API actions when points are being edited.
3287 if( UndoRedoBlocked() )
3288 return false;
3289
3290 // Don't allow any API use while the user is using a tool that could
3291 // modify the model in the middle of the message stream
3292 if( currentTool != GetToolManager()->GetTool<PCB_SELECTION_TOOL>() &&
3293 currentTool != GetToolManager()->GetTool<PCB_POINT_EDITOR>() )
3294 {
3295 return false;
3296 }
3297
3298 ZONE_FILLER_TOOL* zoneFillerTool = m_toolManager->GetTool<ZONE_FILLER_TOOL>();
3299
3300 if( zoneFillerTool->IsBusy() )
3301 return false;
3302
3303 ROUTER_TOOL* routerTool = m_toolManager->GetTool<ROUTER_TOOL>();
3304
3305 if( routerTool && routerTool->RoutingInProgress() )
3306 return false;
3307
3309}
3310
3311
3317
3318
3319bool PCB_EDIT_FRAME::GetPluginActionButtonVisible( const wxString& aPluginPath, bool aPluginDefault )
3320{
3321 if( PCBNEW_SETTINGS* cfg = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" ) )
3322 {
3323 for( const auto& [identifier, visible] : cfg->m_Plugins.actions )
3324 {
3325 if( identifier == aPluginPath )
3326 return visible;
3327 }
3328 }
3329
3330 // Plugin is not in settings, return default.
3331 return aPluginDefault;
3332}
3333
3334
3336{
3337 return GetBoard()->GetFileName();
3338}
3339
3340
3342{
3343 return m_auimgr.GetPane( wxS( "LayersManager" ) ).IsShown();
3344}
3345
3346
3348{
3349 return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
3350}
3351
3352
3354{
3355 return m_auimgr.GetPane( NetInspectorPanelName() ).IsShown();
3356}
3357
3358
3359void PCB_EDIT_FRAME::onSize( wxSizeEvent& aEvent )
3360{
3361 if( IsShownOnScreen() )
3362 {
3363 // We only need this until the frame is done resizing and the final client size is
3364 // established.
3365 Unbind( wxEVT_SIZE, &PCB_EDIT_FRAME::onSize, this );
3367 }
3368
3369 // Skip() is called in the base class.
3370 EDA_DRAW_FRAME::OnSize( aEvent );
3371}
3372
3373
3384
3385
3396
3397
3408
3409
3411{
3412 if( !m_footprintDiffDlg )
3413 {
3415 _( "Compare Footprint with Library" ) );
3416
3417 m_footprintDiffDlg->m_sdbSizerApply->SetLabel( _( "Update Footprint from Library..." ) );
3418 m_footprintDiffDlg->m_sdbSizerApply->PostSizeEventToParent();
3419 m_footprintDiffDlg->m_sdbSizerApply->Show();
3420 }
3421
3422 return m_footprintDiffDlg;
3423}
3424
3425
3427{
3428 if( m_inspectDrcErrorDlg && aEvent.GetString() == INSPECT_DRC_ERROR_DIALOG_NAME )
3429 {
3430 m_inspectDrcErrorDlg->Destroy();
3431 m_inspectDrcErrorDlg = nullptr;
3432 }
3433 else if( m_inspectClearanceDlg && aEvent.GetString() == INSPECT_CLEARANCE_DIALOG_NAME )
3434 {
3435 m_inspectClearanceDlg->Destroy();
3436 m_inspectClearanceDlg = nullptr;
3437 }
3438 else if( m_inspectConstraintsDlg && aEvent.GetString() == INSPECT_CONSTRAINTS_DIALOG_NAME )
3439 {
3440 m_inspectConstraintsDlg->Destroy();
3441 m_inspectConstraintsDlg = nullptr;
3442 }
3443 else if( m_footprintDiffDlg && aEvent.GetString() == FOOTPRINT_DIFF_DIALOG_NAME )
3444 {
3445 if( aEvent.GetId() == wxID_APPLY )
3446 {
3447 KIID fpUUID = m_footprintDiffDlg->GetUserItemID();
3448
3449 CallAfter(
3450 [this, fpUUID]()
3451 {
3452 BOARD_ITEM* item = m_pcb->ResolveItem( fpUUID );
3453
3454 if( FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( item ) )
3455 {
3456 m_toolManager->RunAction<EDA_ITEM*>( ACTIONS::selectItem, footprint );
3457
3458 DIALOG_EXCHANGE_FOOTPRINTS dialog( this, footprint, true, true );
3459 dialog.ShowQuasiModal();
3460 }
3461 } );
3462 }
3463
3464 m_footprintDiffDlg->Destroy();
3465 m_footprintDiffDlg = nullptr;
3466 }
3467}
3468
3469
3470#ifdef KICAD_IPC_API
3471void PCB_EDIT_FRAME::onPluginAvailabilityChanged( wxCommandEvent& aEvt )
3472{
3473 wxLogTrace( traceApi, "PCB frame: EDA_EVT_PLUGIN_AVAILABILITY_CHANGED" );
3475 aEvt.Skip();
3476}
3477#endif
3478
3479
3481{
3482 PCB_LAYER_ID curLayer = GetActiveLayer();
3483 const PCB_DISPLAY_OPTIONS& displ_opts = GetDisplayOptions();
3484
3485 // Check if the specified layer matches the present layer
3486 if( layer == curLayer )
3487 return;
3488
3489 // Copper layers cannot be selected unconditionally; how many of those layers are currently
3490 // enabled needs to be checked.
3491 if( IsCopperLayer( layer ) )
3492 {
3493 if( layer > GetBoard()->GetCopperLayerStackMaxId() )
3494 return;
3495 }
3496
3497 // Is yet more checking required? E.g. when the layer to be selected is a non-copper layer,
3498 // or when switching between a copper layer and a non-copper layer, or vice-versa?
3499
3500 SetActiveLayer( layer );
3501
3503 GetCanvas()->Refresh();
3504}
3505
3506
3508{
3509 switch( aItem->Type() )
3510 {
3513 break;
3514
3515 case PCB_BARCODE_T:
3516 ShowBarcodePropertiesDialog( static_cast<PCB_BARCODE*>( aItem ) );
3517 break;
3518
3519 case PCB_FIELD_T:
3520 case PCB_TEXT_T:
3521 ShowTextPropertiesDialog( static_cast<PCB_TEXT*>( aItem ) );
3522 break;
3523
3524 case PCB_TEXTBOX_T:
3525 ShowTextBoxPropertiesDialog( static_cast<PCB_TEXTBOX*>( aItem ) );
3526 break;
3527
3528 case PCB_TABLE_T:
3529 {
3530 DIALOG_TABLE_PROPERTIES dlg( this, static_cast<PCB_TABLE*>( aItem ) );
3531
3532 //QuasiModal required for Scintilla auto-complete
3533 dlg.ShowQuasiModal();
3534 break;
3535 }
3536
3537 case PCB_PAD_T:
3538 ShowPadPropertiesDialog( static_cast<PAD*>( aItem ) );
3539 break;
3540
3541 case PCB_FOOTPRINT_T:
3542 ShowFootprintPropertiesDialog( static_cast<FOOTPRINT*>( aItem ) );
3543 break;
3544
3545 case PCB_TARGET_T:
3546 ShowTargetOptionsDialog( static_cast<PCB_TARGET*>( aItem ) );
3547 break;
3548
3549 case PCB_DIM_ALIGNED_T:
3550 case PCB_DIM_CENTER_T:
3551 case PCB_DIM_RADIAL_T:
3553 case PCB_DIM_LEADER_T:
3554 {
3555 DIALOG_DIMENSION_PROPERTIES dlg( this, static_cast<PCB_DIMENSION_BASE*>( aItem ) );
3556
3557 dlg.ShowModal();
3558 break;
3559 }
3560
3561 case PCB_SHAPE_T:
3562 ShowGraphicItemPropertiesDialog( static_cast<PCB_SHAPE*>( aItem ) );
3563 break;
3564
3565 case PCB_ZONE_T:
3566 Edit_Zone_Params( static_cast<ZONE*>( aItem ) );
3567 break;
3568
3569 case PCB_GROUP_T:
3571 static_cast<EDA_GROUP*>( static_cast<PCB_GROUP*>( aItem ) ) );
3572 break;
3573
3574 case PCB_GENERATOR_T:
3575 static_cast<PCB_GENERATOR*>( aItem )->ShowPropertiesDialog( this );
3576 break;
3577
3578 case PCB_MARKER_T:
3579 m_toolManager->GetTool<DRC_TOOL>()->CrossProbe( static_cast<PCB_MARKER*>( aItem ) );
3580 break;
3581
3582 case PCB_POINT_T:
3583 break;
3584
3585 default:
3586 break;
3587 }
3588}
3589
3590
3592{
3593 // For now we just delegate to the base implementation which commits any pending
3594 // local history snapshots. If PCB-specific preconditions are later needed (e.g.
3595 // flushing zone fills or router state) they can be added here before calling the
3596 // base class method.
3598}
const char * name
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:125
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:198
static TOOL_ACTION paste
Definition actions.h:80
static TOOL_ACTION unselectAll
Definition actions.h:83
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition actions.h:227
static TOOL_ACTION togglePolarCoords
Definition actions.h:209
static TOOL_ACTION copy
Definition actions.h:78
static TOOL_ACTION pluginsReload
Definition actions.h:294
static TOOL_ACTION selectSetLasso
Definition actions.h:221
static TOOL_ACTION selectSetRect
Set lasso selection mode.
Definition actions.h:220
static TOOL_ACTION group
Definition actions.h:239
static TOOL_ACTION pasteSpecial
Definition actions.h:81
static TOOL_ACTION groupProperties
Definition actions.h:247
static TOOL_ACTION pointEditorArcKeepCenter
Definition actions.h:273
static TOOL_ACTION ungroup
Definition actions.h:240
static TOOL_ACTION toggleBoundingBoxes
Definition actions.h:157
static TOOL_ACTION pointEditorArcKeepRadius
Definition actions.h:275
static TOOL_ACTION showSearch
Definition actions.h:116
static TOOL_ACTION undo
Definition actions.h:75
static TOOL_ACTION duplicate
Definition actions.h:84
static TOOL_ACTION highContrastMode
Definition actions.h:155
static TOOL_ACTION embeddedFiles
Definition actions.h:297
static TOOL_ACTION measureTool
Definition actions.h:252
static TOOL_ACTION doDelete
Definition actions.h:85
static TOOL_ACTION selectionTool
Definition actions.h:251
static TOOL_ACTION save
Definition actions.h:58
static TOOL_ACTION zoomFitScreen
Definition actions.h:142
static TOOL_ACTION redo
Definition actions.h:76
static TOOL_ACTION deleteTool
Definition actions.h:86
static TOOL_ACTION zoomTool
Definition actions.h:146
static TOOL_ACTION showProperties
Definition actions.h:266
static TOOL_ACTION cut
Definition actions.h:77
static TOOL_ACTION gridSetOrigin
Definition actions.h:195
static TOOL_ACTION toggleGridOverrides
Definition actions.h:199
static TOOL_ACTION selectAll
Definition actions.h:82
static TOOL_ACTION pointEditorArcKeepEndpoint
Definition actions.h:274
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,...
virtual 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:84
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:268
void SetLocked(bool aLocked) override
Definition board_item.h:359
void SetUuid(const KIID &aUuid)
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:350
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:316
VECTOR2I GetFPRelativePosition() const
@ INSTANCE_TO_INSTANCE
Definition board_item.h:478
void SetFPRelativePosition(const VECTOR2I &aPos)
Bridges BOARD's listener stream into the generic TEXT_VAR_TRACKER.
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:323
void BuildListOfNets()
Definition board.h:967
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition board.cpp:1052
void RemoveAllListeners()
Remove all listeners.
Definition board.cpp:3513
const PAGE_INFO & GetPageSettings() const
Definition board.h:807
GAL_SET GetVisibleElements() const
Return a set of all the element categories that are visible.
Definition board.cpp:1046
void InitializeClearanceCache()
Initialize the clearance cache for all board items.
Definition board.cpp:1120
void SaveToHistory(const wxString &aProjectPath, std::vector< HISTORY_FILE_DATA > &aFileData)
Serialize board into HISTORY_FILE_DATA for non-blocking history commit.
Definition board.cpp:3967
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:203
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:2953
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:213
const wxString & GetFileName() const
Definition board.h:360
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Change the visibility of an element category.
Definition board.cpp:1058
void ClearProject()
Definition board.cpp:254
bool IsEmpty() const
Definition board.cpp:614
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:2417
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition board.cpp:986
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition board.cpp:315
void SynchronizeTuningProfileProperties()
Ensure that all time domain properties providers are in sync with current settings.
Definition board.cpp:2947
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition board.h:571
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.
AUTO_BACKUP m_Backup
Handles action that are shared between different applications.
enum FP_PROPS_RETVALUE GetReturnValue()
Dialog that offers to migrate obsolete WRL 3D model references on a loaded board to current STEP mode...
static int AutoMigrateByFilename(PCB_EDIT_FRAME *aFrame)
Silently rewrite unresolvable .wrl/.wrz references to STEP files whose filename stem matches in the s...
static int CountUnresolvedWrlReferences(PCB_EDIT_FRAME *aFrame)
Count of unique unresolvable .wrl/.wrz references on the board (deduplicated by filename).
int ShowModal() override
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:87
bool IsDRCRunning() const
Check to see if the DRC engine is running the tests.
Definition drc_tool.h:74
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 SetVariantName(const std::string &aVariant)
Set the current variant name and description to be shown on the drawing sheet.
void SetVariantDesc(const std::string &aVariantDesc)
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 AttachToTracker(TEXT_VAR_TRACKER *aTracker)
Register this proxy with aTracker as a dependent on every title-block source variable its current tem...
void SetFileName(const std::string &aFileName)
Set the file name displayed in the title block.
virtual bool doAutoSave()
This should be overridden by the derived class to handle the auto save feature.
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 RecreateToolbars()
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 std::vector< const PLUGIN_ACTION * > GetOrderedPluginActions(PLUGIN_ACTION_SCOPE aScope, APP_SETTINGS_BASE *aCfg)
Return ordered list of plugin actions for display in the toolbar.
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 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
virtual void UpdateProperties()
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:100
const KIID m_Uuid
Definition eda_item.h:528
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:118
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:112
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition eda_item.h:151
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:93
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:93
const EDA_ANGLE & GetTextAngle() const
Definition eda_text.h:172
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:114
virtual bool IsVisible() const
Definition eda_text.h:212
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:432
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:225
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:385
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:228
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:269
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:298
int GetTextThickness() const
Definition eda_text.h:153
VECTOR2I GetTextSize() const
Definition eda_text.h:286
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 CurrentTool(const TOOL_ACTION &aTool)
Create a functor testing if the specified tool is the current active tool in the 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.
The interactive edit tool.
Definition edit_tool.h:56
void RemoveFile(const wxString &name, bool aErase=true)
Remove a file from the collection and frees the memory.
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
const std::map< wxString, EMBEDDED_FILE * > & EmbeddedFileMap() const
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition property.h:727
static ENUM_MAP< T > & Instance()
Definition property.h:721
ENUM_MAP & Undefined(T aValue)
Definition property.h:734
wxPGChoices & Choices()
Definition property.h:770
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:501
ZONE_CONNECTION GetLocalZoneConnection() const
Definition footprint.h:477
void SetLocked(bool isLocked) override
Set the #MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition footprint.h:632
EDA_ANGLE GetOrientation() const
Definition footprint.h:408
ZONES & Zones()
Definition footprint.h:383
PCB_POINTS & Points()
Definition footprint.h:389
void SetOrientation(const EDA_ANGLE &aNewAngle)
void SetAllowSolderMaskBridges(bool aAllow)
Definition footprint.h:502
void SetLocalSolderPasteMarginRatio(std::optional< double > aRatio)
Definition footprint.h:474
wxString GetSheetname() const
Definition footprint.h:455
void SetPath(const KIID_PATH &aPath)
Definition footprint.h:453
void SetFilters(const wxString &aFilters)
Definition footprint.h:462
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.
const EXTRUDED_3D_BODY * GetExtrudedBody() const
Definition footprint.h:398
void SetAttributes(int aAttributes)
Definition footprint.h:496
void SetSheetfile(const wxString &aSheetfile)
Definition footprint.h:459
std::optional< int > GetLocalSolderPasteMargin() const
Definition footprint.h:470
PCB_FIELD & Value()
read/write accessors:
Definition footprint.h:865
bool HasExtrudedBody() const
Definition footprint.h:397
std::optional< int > GetLocalClearance() const
Definition footprint.h:464
void ClearExtrudedBody()
Definition footprint.h:402
std::deque< PAD * > & Pads()
Definition footprint.h:377
int GetAttributes() const
Definition footprint.h:495
const COMPONENT_CLASS * GetComponentClass() const
Returns the component class for this footprint.
void SetLocalZoneConnection(ZONE_CONNECTION aType)
Definition footprint.h:476
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition footprint.h:417
void SetExtrudedBody(std::unique_ptr< EXTRUDED_3D_BODY > aBody)
wxString GetSheetfile() const
Definition footprint.h:458
const LIB_ID & GetFPID() const
Definition footprint.h:429
bool IsLocked() const override
Definition footprint.h:622
PCB_FIELD & Reference()
Definition footprint.h:866
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:473
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
GROUPS & Groups()
Definition footprint.h:386
wxString GetFilters() const
Definition footprint.h:461
void SetSheetname(const wxString &aSheetname)
Definition footprint.h:456
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:394
const wxString & GetValue() const
Definition footprint.h:851
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition footprint.h:468
void SetLocalClearance(std::optional< int > aClearance)
Definition footprint.h:465
const KIID_PATH & GetPath() const
Definition footprint.h:452
std::optional< int > GetLocalSolderMaskMargin() const
Definition footprint.h:467
void SetLocalSolderPasteMargin(std::optional< int > aMargin)
Definition footprint.h:471
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition footprint.h:1293
VECTOR2I GetPosition() const override
Definition footprint.h:405
DRAWINGS & GraphicalItems()
Definition footprint.h:380
void ReadWindowSettings(WINDOW_SETTINGS &aCfg)
Read GAL config options from application-level config.
bool Contains(GAL_LAYER_ID aPos)
Definition layer_ids.h:439
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:105
void SetGridColor(const COLOR4D &aGridColor)
Set the grid color.
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
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:67
double GetScale() const
Definition view.h:285
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition view.cpp:601
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:1828
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition view.h:409
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:1685
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition view.h:661
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:1701
An implementation of class VIEW_CONTROLS for wxWidgets library.
std::unique_ptr< PROF_COUNTER > m_MotionEventCounter
Definition kiid.h:48
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)
void OnSockRequest(wxSocketEvent &evt)
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:315
void OnKiCadExit()
Definition kiway.cpp:800
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:402
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
Definition kiway.cpp:500
LOCAL_HISTORY & LocalHistory()
Return the LOCAL_HISTORY associated with this KIWAY.
Definition kiway.h:426
virtual void CommonSettingsChanged(int aFlags=0)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition kiway.cpp:594
PCB_LAYER_ID GetLayerA() const
PCB_LAYER_ID GetLayerB() const
const UTF8 & GetLibItemName() const
Definition lib_id.h:102
bool CommitDuplicateOfLastSave(const wxString &aProjectPath, const wxString &aFileType, const wxString &aMessage)
Create a new commit duplicating the tree pointed to by Last_Save_<fileType> and move the Last_Save_<f...
void RegisterSaver(const void *aSaverObject, const std::function< void(const wxString &, std::vector< HISTORY_FILE_DATA > &)> &aSaver)
Register a saver callback invoked during autosave history commits.
bool Init(const wxString &aProjectPath)
Initialize the local history repository for the given project path.
void NoteFileChange(const wxString &aFile)
Record that a file has been modified and should be included in the next snapshot.
void UnregisterSaver(const void *aSaverObject)
Unregister a previously registered saver callback.
void RemoveAutosaveFiles(const wxString &aProjectPath) const
Remove every autosave file under the project at aProjectPath regardless of which source it shadowed.
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:313
static const LSET & AllLayersMask()
Definition lset.cpp:641
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:259
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
Definition pad.h:55
void SetPinType(const wxString &aType)
Set the pad electrical type.
Definition pad.h:153
const wxString & GetPinType() const
Definition pad.h:154
const wxString & GetPinFunction() const
Definition pad.h:148
bool IsOnCopperLayer() const override
Definition pad.cpp:1591
void SetPinFunction(const wxString &aName)
Set the pad function (pin name in schematic)
Definition pad.h:147
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
AUI_PANELS m_AuiPanels
Gather all the actions that are shared by tools.
Definition pcb_actions.h:51
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 drawEllipseArc
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 angleSnapModeChanged
Notification event when angle mode changes.
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 drawEllipse
static TOOL_ACTION zoneDisplayTriangulated
static TOOL_ACTION placeDesignBlock
static TOOL_ACTION selectUnconnected
Select unconnected footprints from ratsnest of selection.
Definition pcb_actions.h:91
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.
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 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.
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 ...
bool UndoRedoBlocked() const
Check if the undo and redo operations are currently blocked.
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)
PANEL_SELECTION_FILTER * m_selectionFilterPanel
void ShowBarcodePropertiesDialog(PCB_BARCODE *aText)
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 void SetActiveLayer(PCB_LAYER_ID aLayer)
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 PCB_LAYER_ID GetActiveLayer() const
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, std::optional< VECTOR2I > aPosition=std::nullopt)
Place aFootprint at the current cursor position (or provided one) and updates footprint coordinates w...
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.
bool m_FlipBoardView
true if the board is flipped to show the mirrored view
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.
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
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 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
std::size_t m_textVarListenerHandle
Reactive text-var invalidation listener state.
static bool GetPluginActionButtonVisible(const wxString &aPluginPath, bool aPluginDefault)
Return true if button visibility action plugin setting was set to true or it is unset and plugin defa...
void OnEditItemRequest(BOARD_ITEM *aItem) override
Install the corresponding dialog editor for the given item.
Definition edit.cpp:99
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:72
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 UpdateVariantSelectionCtrl()
Update the variant selection dropdown with the current board's variant names.
bool DoAutoSave()
Perform auto save when the board has been modified and not saved within the auto save interval.
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.
void ShowFindByPropertiesDialog()
Show the Find by Properties dialog.
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
WX_INFOBAR * m_loadNoticeInfoBar
Secondary infobar that stacks above the main one; reserved for load-time notices (currently the WRL -...
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.
static std::vector< const PLUGIN_ACTION * > GetOrderedPluginActions()
Return ordered list of plugins in sequence in which they should appear on toolbar or in settings.
void detachTextVarTracker()
Drop every cached reference into the current BOARD's text-var tracker.
void PrepareLayerIndicator(bool aForceRebuild=false)
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)
void UpdateProperties() override
bool IsContentModified() const override
Get if the current board has been modified but not saved.
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.
DIALOG_BOOK_REPORTER * m_footprintDiffDlg
void ActivateGalCanvas() override
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
void onVariantSelected(wxCommandEvent &aEvent)
Event handler for variant selection changes in the toolbar.
SELECTION & GetCurrentSelection() override
Get the current selection from the canvas area.
void OnQuit(wxCommandEvent &event)
void NotifyFindByPropertiesDialog()
Notify the Find by Properties dialog that the selection has changed.
void onCloseModelessBookReporterDialogs(wxCommandEvent &aEvent)
PCB_DESIGN_BLOCK_PANE * m_designBlocksPane
bool canCloseWindow(wxCloseEvent &aCloseEvent) override
DIALOG_BOARD_SETUP * m_boardSetupDlg
DIALOG_BOOK_REPORTER * GetInspectClearanceDialog()
void ExchangeFootprint(FOOTPRINT *aExisting, FOOTPRINT *aNew, BOARD_COMMIT &aCommit, bool matchPadPositions, 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,...
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_FIND_BY_PROPERTIES * m_findByPropertiesDialog
DIALOG_BOOK_REPORTER * m_inspectClearanceDlg
void OnFileHistory(wxCommandEvent &event)
DIALOG_BOOK_REPORTER * GetInspectConstraintsDialog()
class TEXT_VAR_TRACKER * m_textVarListenerTracker
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:524
Tool useful for viewing footprints.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:541
virtual const wxString & GetExecutablePath() const
Definition pgm_base.cpp:867
The interactive edit tool.
void Show(std::ostream &aStream=std::cerr)
Definition profile.h:288
void Reset()
Definition profile.h:278
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 const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:187
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition project.h:210
void IncrementNetclassesTicker()
Definition project.h:118
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:204
void IncrementTextVarsTicker()
Definition project.h:115
Action handler for the Properties panel.
PNS::PNS_MODE GetRouterMode()
bool RoutingInProgress()
Returns whether routing is currently active.
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:226
Coordinates the dependency index with change notifications.
ListenerHandle AddInvalidateListener(InvalidateCallback aCallback)
Register a listener that fires for every invalidation.
static constexpr ListenerHandle INVALID_LISTENER
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.
TOOL_BASE * GetCurrentTool() const
Return the tool that is on the top of the active tools stack (was invoked the most recently).
wxString wx_str() const
Definition utf8.cpp:45
A modified version of the wxInfoBar class that allows us to:
Definition wx_infobar.h:77
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
@ ZIP
Zip archive snapshots; autosave uses recovery files.
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:150
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:221
int GetLastUnsavedChangesResponse()
Return the result code from the last call to HandleUnsavedChanges(): wxID_YES, wxID_NO or wxID_CANCEL...
Definition confirm.cpp:163
This file is part of the common library.
#define CHECK(x)
#define ENABLE(x)
#define DIALOG_DRC_WINDOW_NAME
Definition dialog_drc.h:44
#define DIALOG_DRC_RULE_EDITOR_WINDOW_NAME
#define _(s)
Declaration of the eda_3d_viewer class.
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
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:54
static const std::vector< KICAD_T > footprintTypes
static const std::vector< KICAD_T > groupTypes
static const std::vector< KICAD_T > trackTypes
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)
bool ComputeFootprintShift(const FOOTPRINT &aExisting, const FOOTPRINT &aNew, VECTOR2I &aShift, EDA_ANGLE &aAngleShift)
Compute position and angle shift between two footprints.
Collection of reusable/testable functions for footprint manipulation.
@ 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.
static const std::string LegacySchematicFileExtension
static const std::string LegacyPcbFileExtension
static const std::string KiCadSchematicFileExtension
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 traceCrossProbeFlash
Flag to enable debug output for cross-probe flash operations.
const wxChar *const traceApi
Flag to enable debug output related to the IPC API and its plugin system.
Definition api_utils.cpp:29
@ ID_ON_GRID_SELECT
Definition id.h:116
@ ID_FILE_LIST_CLEAR
Definition id.h:62
@ ID_EDA_SOCKET_EVENT
Definition id.h:136
@ ID_EDA_SOCKET_EVENT_SERV
Definition id.h:135
@ ID_ON_ZOOM_SELECT
Definition id.h:115
@ ID_FILEMAX
Definition id.h:60
@ ID_FILE1
Definition id.h:59
PROJECT & Prj()
Definition kicad.cpp:655
int GetNetnameLayer(int aLayer)
Return a netname layer corresponding to the given layer.
Definition layer_ids.h:856
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition layer_ids.h:679
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition layer_ids.h:228
@ LAYER_GRID
Definition layer_ids.h:254
@ LAYER_ZONES
Control for copper zone opacity/visibility (color ignored).
Definition layer_ids.h:295
@ LAYER_RATSNEST
Definition layer_ids.h:253
#define CLEARANCE_LAYER_FOR(boardLayer)
Definition layer_ids.h:373
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:102
bool SupportsShutdownBlockReason()
Whether or not the window supports setting a shutdown block reason.
Definition unix/app.cpp:91
@ RM_MarkObstacles
Ignore collisions, mark obstacles.
@ RM_Walkaround
Only walk around.
@ RM_Shove
Only shove.
#define _HKI(x)
Definition page_info.cpp:44
BARCODE class definition.
static std::vector< std::pair< T *, T * > > matchItemsBySimilarity(const std::vector< T * > &aExisting, const std::vector< T * > &aNew)
static void processTextItem(const PCB_TEXT &aSrc, PCB_TEXT &aDest, const VECTOR2I &aPosShift, const EDA_ANGLE &aAngleShift, bool aResetText, bool aResetTextLayers, bool aResetTextEffects, bool aResetTextPositions, bool *aUpdated)
copy text settings from aSrc to aDest
#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
@ ID_POPUP_PCB_SELECT_WIDTH_START_RANGE
Definition pcbnew_id.h:20
@ ID_POPUP_PCB_SELECT_WIDTH1
Definition pcbnew_id.h:24
@ ID_POPUP_PCB_SELECT_VIASIZE8
Definition pcbnew_id.h:47
@ ID_AUX_TOOLBAR_PCB_VARIANT_SELECT
Definition pcbnew_id.h:19
@ ID_AUX_TOOLBAR_PCB_VIA_SIZE
Definition pcbnew_id.h:17
@ ID_POPUP_PCB_SELECT_WIDTH_END_RANGE
Definition pcbnew_id.h:77
@ ID_POPUP_PCB_SELECT_VIASIZE1
Definition pcbnew_id.h:40
@ ID_AUX_TOOLBAR_PCB_TRACK_WIDTH
Definition pcbnew_id.h:18
@ SHOW_WITH_VIA_ALWAYS
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
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)
T * GetAppSettings(const char *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
BACKUP_FORMAT format
Backup format (incremental git history vs zip archives)
A filename or source description, a problem input line, a line number, a byte offset,...
TRACK_CLEARANCE_MODE m_TrackClearance
Identifies a single resolvable source that a text item's ${...} reference depends on.
@ 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
wxLogTrace helper definitions.
VECTOR2I GetRotated(const VECTOR2I &aVector, const EDA_ANGLE &aAngle)
Return a new VECTOR2I that is the result of rotating aVector by aAngle.
Definition trigo.h:77
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition typeinfo.h:85
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition typeinfo.h:103
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition typeinfo.h:100
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
Definition typeinfo.h:88
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:94
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition typeinfo.h:101
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:108
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:90
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition typeinfo.h:105
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:89
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
Definition typeinfo.h:86
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:87
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
Definition typeinfo.h:96
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
Definition typeinfo.h:98
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition typeinfo.h:104
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:83
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition typeinfo.h:99
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:84
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition typeinfo.h:95
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
Definition typeinfo.h:91
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
Definition typeinfo.h:110
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition typeinfo.h:93
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition typeinfo.h:102
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687
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.