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