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>
89#include <tools/convert_tool.h>
90#include <tools/drawing_tool.h>
91#include <tools/pcb_control.h>
99#include <tools/pad_tool.h>
104#include <router/router_tool.h>
108#include <wx/socket.h>
109#include <wx/wupdlock.h>
110#include <dialog_drc.h> // for DIALOG_DRC_WINDOW_NAME definition
115#include <widgets/wx_infobar.h>
119#include <widgets/wx_aui_utils.h>
120#include <kiplatform/app.h>
121#include <kiplatform/ui.h>
122#include <core/profile.h>
123#include <math/box2_minmax.h>
127#include <toolbars_pcb_editor.h>
128#include <wx/log.h>
129
130#ifdef KICAD_IPC_API
131#include <api/api_server.h>
132#include <api/api_handler_pcb.h>
134#include <api/api_utils.h>
135#endif
136
137#include <action_plugin.h>
139#include <richio.h>
140
141#include "../scripting/python_scripting.h"
142
143#include <wx/filedlg.h>
144
145using namespace std::placeholders;
146
147
148#define INSPECT_DRC_ERROR_DIALOG_NAME wxT( "InspectDrcErrorDialog" )
149#define INSPECT_CLEARANCE_DIALOG_NAME wxT( "InspectClearanceDialog" )
150#define INSPECT_CONSTRAINTS_DIALOG_NAME wxT( "InspectConstraintsDialog" )
151#define FOOTPRINT_DIFF_DIALOG_NAME wxT( "FootprintDiffDialog" )
152
153
154BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
157
160
161 EVT_SIZE( PCB_EDIT_FRAME::OnSize )
162
163 // Menu Files:
166
167 EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit )
168 EVT_MENU( wxID_CLOSE, PCB_EDIT_FRAME::OnQuit )
169
170 // Horizontal toolbar
174
175 // Tracks and vias sizes general options
177 PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event )
178
179 // User interface update event handlers.
180 EVT_UPDATE_UI( ID_AUX_TOOLBAR_PCB_TRACK_WIDTH, PCB_EDIT_FRAME::OnUpdateSelectTrackWidth )
181 EVT_UPDATE_UI( ID_AUX_TOOLBAR_PCB_VIA_SIZE, PCB_EDIT_FRAME::OnUpdateSelectViaSize )
183 PCB_EDIT_FRAME::OnUpdateSelectTrackWidth )
185 PCB_EDIT_FRAME::OnUpdateSelectViaSize )
186 // Drop files event
187 EVT_DROP_FILES( PCB_EDIT_FRAME::OnDropFiles )
188END_EVENT_TABLE()
189
190
191PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
192 PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB_EDITOR, _( "PCB Editor" ),
193 wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE,
195 m_exportNetlistAction( nullptr ),
196 m_findDialog( nullptr ),
197 m_inspectDrcErrorDlg( nullptr ),
198 m_inspectClearanceDlg( nullptr ),
199 m_inspectConstraintsDlg( nullptr ),
200 m_footprintDiffDlg( nullptr ),
201 m_boardSetupDlg( nullptr ),
202 m_designBlocksPane( nullptr ),
203 m_importProperties( nullptr ),
204 m_eventCounterTimer( nullptr )
205{
206 m_maximizeByDefault = true;
207 m_showBorderAndTitleBlock = true; // true to display sheet references
208 m_SelTrackWidthBox = nullptr;
209 m_SelViaSizeBox = nullptr;
210 m_currentVariantCtrl = nullptr;
211 m_show_layer_manager_tools = true;
212 m_supportsAutoSave = true;
213 m_probingSchToPcb = false;
214 m_show_search = false;
215 m_show_net_inspector = false;
216 // Ensure timer has an owner before binding so it generates events.
217 m_crossProbeFlashTimer.SetOwner( this );
218 Bind( wxEVT_TIMER, &PCB_EDIT_FRAME::OnCrossProbeFlashTimer, this, m_crossProbeFlashTimer.GetId() );
219
220 // We don't know what state board was in when it was last saved, so we have to
221 // assume dirty
222 m_ZoneFillsDirty = true;
223
224 m_aboutTitle = _HKI( "KiCad PCB Editor" );
225
226 // Must be created before the menus are created.
227 if( ADVANCED_CFG::GetCfg().m_ShowPcbnewExportNetlist )
228 {
229 m_exportNetlistAction = new TOOL_ACTION( "pcbnew.EditorControl.exportNetlist",
230 AS_GLOBAL, 0, "", _( "Netlist..." ),
231 _( "Export netlist used to update schematics" ) );
232 }
233
234 // Create GAL canvas
235 auto canvas = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_frameSize,
236 GetGalDisplayOptions(),
238
239 SetCanvas( canvas );
240 SetBoard( new BOARD() );
241
242 wxIcon icon;
243 wxIconBundle icon_bundle;
244
245 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew, 48 ) );
246 icon_bundle.AddIcon( icon );
247 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew, 128 ) );
248 icon_bundle.AddIcon( icon );
249 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew, 256 ) );
250 icon_bundle.AddIcon( icon );
251 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew_32 ) );
252 icon_bundle.AddIcon( icon );
253 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_pcbnew_16 ) );
254 icon_bundle.AddIcon( icon );
255
256 SetIcons( icon_bundle );
257
258 // LoadSettings() *after* creating m_LayersManager, because LoadSettings()
259 // initialize parameters in m_LayersManager
260 LoadSettings( config() );
261
262 SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU( pcbIUScale.IU_PER_MILS ) ) );
263
264 // PCB drawings start in the upper left corner.
265 GetScreen()->m_Center = false;
266
267 setupTools();
268 setupUIConditions();
269
270 m_toolbarSettings = GetToolbarSettings<PCB_EDIT_TOOLBAR_SETTINGS>( "pcbnew-toolbars" );
271 configureToolbars();
272 RecreateToolbars();
273 PrepareLayerIndicator( true );
274
275 ReCreateMenuBar();
276
277#ifdef KICAD_IPC_API
279 &PCB_EDIT_FRAME::onPluginAvailabilityChanged, this );
280#endif
281
282 // Fetch a COPY of the config as a lot of these initializations are going to overwrite our
283 // data.
284 PCBNEW_SETTINGS::AUI_PANELS aui_cfg = GetPcbNewSettings()->m_AuiPanels;
285
286 m_propertiesPanel = new PCB_PROPERTIES_PANEL( this, this );
287 m_propertiesPanel->SetSplitterProportion( aui_cfg.properties_splitter );
288
289 m_selectionFilterPanel = new PANEL_SELECTION_FILTER( this );
290
291 m_appearancePanel = new APPEARANCE_CONTROLS( this, GetCanvas() );
292 m_searchPane = new PCB_SEARCH_PANE( this );
293 m_netInspectorPanel = new PCB_NET_INSPECTOR_PANEL( this, this );
294 m_designBlocksPane = new PCB_DESIGN_BLOCK_PANE( this, nullptr, m_designBlockHistoryList );
295
296 m_auimgr.SetManagedWindow( this );
297
298 CreateInfoBar();
299
300 unsigned int auiFlags = wxAUI_MGR_DEFAULT;
301#if !defined( _WIN32 )
302 // Windows cannot redraw the UI fast enough during a live resize and may lead to all kinds
303 // of graphical glitches.
304 auiFlags |= wxAUI_MGR_LIVE_RESIZE;
305#endif
306 m_auimgr.SetFlags( auiFlags );
307
308 // Rows; layers 4 - 6
309 m_auimgr.AddPane( m_tbTopMain, EDA_PANE().HToolbar().Name( wxS( "TopMainToolbar" ) )
310 .Top().Layer( 6 ) );
311 m_auimgr.AddPane( m_tbTopAux, EDA_PANE().HToolbar().Name( wxS( "TopAuxToolbar" ) )
312 .Top().Layer( 5 ) );
313 m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( wxS( "MsgPanel" ) )
314 .Bottom().Layer( 6 ) );
315
316 // Columns; layers 1 - 3
317 m_auimgr.AddPane( m_tbLeft, EDA_PANE().VToolbar().Name( wxS( "LeftToolbar" ) )
318 .Left().Layer( 3 ) );
319
320 m_auimgr.AddPane( m_tbRight, EDA_PANE().VToolbar().Name( wxS( "RightToolbar" ) )
321 .Right().Layer( 3 ) );
322
323 m_auimgr.AddPane( m_appearancePanel, EDA_PANE().Name( wxS( "LayersManager" ) )
324 .Right().Layer( 4 )
325 .Caption( _( "Appearance" ) ).PaneBorder( false )
326 .MinSize( m_appearancePanel->GetMinSize().x, -1 )
327#ifdef __WXMAC__
328 // Best size for this pane is calculated larger than necessary on wxMac
329 .BestSize( m_appearancePanel->GetMinSize().x, -1 )
330#else
331 .BestSize( m_appearancePanel->GetBestSize().x, -1 )
332#endif
333 .FloatingSize( m_appearancePanel->GetBestSize() )
334 .CloseButton( false ) );
335
336 m_auimgr.AddPane( m_selectionFilterPanel, EDA_PANE().Name( wxS( "SelectionFilter" ) )
337 .Right().Layer( 4 ).Position( 2 )
338 .Caption( _( "Selection Filter" ) ).PaneBorder( false )
339 .MinSize( m_selectionFilterPanel->GetMinSize().x, -1 )
340 .BestSize( m_selectionFilterPanel->GetBestSize().x, -1 )
341 .FloatingSize( m_selectionFilterPanel->GetBestSize() )
342 .CloseButton( false ) );
343
344 m_auimgr.AddPane( m_designBlocksPane, EDA_PANE().Name( DesignBlocksPaneName() )
345 .Right().Layer( 5 )
346 .Caption( _( "Design Blocks" ) )
347 .CaptionVisible( true )
348 .PaneBorder( true )
349 .TopDockable( false )
350 .BottomDockable( false )
351 .CloseButton( true )
352 .MinSize( FromDIP( wxSize( 240, 60 ) ) )
353 .BestSize( FromDIP( wxSize( 300, 200 ) ) )
354 .FloatingSize( FromDIP( wxSize( 800, 600 ) ) )
355 .FloatingPosition( FromDIP( wxPoint( 50, 200 ) ) )
356 .Show( true ) );
357
358 m_auimgr.AddPane( m_propertiesPanel, EDA_PANE().Name( PropertiesPaneName() )
359 .Left().Layer( 5 )
360 .Caption( _( "Properties" ) ).PaneBorder( false )
361 .MinSize( FromDIP( wxSize( 240, 60 ) ) )
362 .BestSize( FromDIP( wxSize( 300, 200 ) ) )
363 .FloatingSize( wxSize( 300, 200 ) )
364 .CloseButton( true ) );
365
366 // Center
367 m_auimgr.AddPane( GetCanvas(), EDA_PANE().Canvas().Name( wxS( "DrawFrame" ) )
368 .Center() );
369
370 m_auimgr.AddPane( m_netInspectorPanel, EDA_PANE().Name( NetInspectorPanelName() )
371 .Bottom()
372 .Caption( _( "Net Inspector" ) )
373 .PaneBorder( false )
374 .MinSize( FromDIP( wxSize( 240, 60 ) ) )
375 .BestSize( FromDIP( wxSize( 300, 200 ) ) )
376 .FloatingSize( wxSize( 300, 200 ) )
377 .CloseButton( true ) );
378
379 m_auimgr.AddPane( m_searchPane, EDA_PANE().Name( SearchPaneName() )
380 .Bottom()
381 .Caption( _( "Search" ) ).PaneBorder( false )
382 .MinSize( FromDIP( wxSize ( 180, 60 ) ) )
383 .BestSize( FromDIP( wxSize ( 180, 100 ) ) )
384 .FloatingSize( FromDIP( wxSize( 480, 200 ) ) )
385 .DestroyOnClose( false )
386 .CloseButton( true ) );
387
388 RestoreAuiLayout();
389
390 m_auimgr.GetPane( "LayersManager" ).Show( m_show_layer_manager_tools );
391 m_auimgr.GetPane( "SelectionFilter" ).Show( m_show_layer_manager_tools );
392 m_auimgr.GetPane( PropertiesPaneName() ).Show( GetPcbNewSettings()->m_AuiPanels.show_properties );
393 m_auimgr.GetPane( NetInspectorPanelName() ).Show( m_show_net_inspector );
394 m_auimgr.GetPane( SearchPaneName() ).Show( m_show_search );
395 m_auimgr.GetPane( DesignBlocksPaneName() ).Show( GetPcbNewSettings()->m_AuiPanels.design_blocks_show );
396
397 // The selection filter doesn't need to grow in the vertical direction when docked
398 m_auimgr.GetPane( "SelectionFilter" ).dock_proportion = 0;
399 FinishAUIInitialization();
400
401 if( aui_cfg.right_panel_width > 0 )
402 {
403 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( wxS( "LayersManager" ) );
404 SetAuiPaneSize( m_auimgr, layersManager, aui_cfg.right_panel_width, -1 );
405
406 wxAuiPaneInfo& designBlocksPane = m_auimgr.GetPane( DesignBlocksPaneName() );
407 SetAuiPaneSize( m_auimgr, designBlocksPane, aui_cfg.design_blocks_panel_docked_width, -1 );
408 }
409
410 if( aui_cfg.properties_panel_width > 0 && m_propertiesPanel )
411 {
412 wxAuiPaneInfo& propertiesPanel = m_auimgr.GetPane( PropertiesPaneName() );
413 SetAuiPaneSize( m_auimgr, propertiesPanel, aui_cfg.properties_panel_width, -1 );
414 }
415
416 if( aui_cfg.search_panel_height > 0
417 && ( aui_cfg.search_panel_dock_direction == wxAUI_DOCK_TOP
418 || aui_cfg.search_panel_dock_direction == wxAUI_DOCK_BOTTOM ) )
419 {
420 wxAuiPaneInfo& searchPane = m_auimgr.GetPane( SearchPaneName() );
421 searchPane.Direction( aui_cfg.search_panel_dock_direction );
422 SetAuiPaneSize( m_auimgr, searchPane, -1, aui_cfg.search_panel_height );
423 }
424 else if( aui_cfg.search_panel_width > 0
425 && ( aui_cfg.search_panel_dock_direction == wxAUI_DOCK_LEFT
426 || aui_cfg.search_panel_dock_direction == wxAUI_DOCK_RIGHT ) )
427 {
428 wxAuiPaneInfo& searchPane = m_auimgr.GetPane( SearchPaneName() );
429 searchPane.Direction( aui_cfg.search_panel_dock_direction );
430 SetAuiPaneSize( m_auimgr, searchPane, aui_cfg.search_panel_width, -1 );
431 }
432
433 m_appearancePanel->SetTabIndex( aui_cfg.appearance_panel_tab );
434
435 {
436 m_layerPairSettings = std::make_unique<LAYER_PAIR_SETTINGS>();
437
438 m_layerPairSettings->Bind( PCB_LAYER_PAIR_PRESETS_CHANGED, [&]( wxCommandEvent& aEvt )
439 {
440 // Update the project file list
441 std::span<const LAYER_PAIR_INFO> newPairInfos = m_layerPairSettings->GetLayerPairs();
443 std::vector<LAYER_PAIR_INFO>{ newPairInfos.begin(), newPairInfos.end() };
444 });
445
446 m_layerPairSettings->Bind( PCB_CURRENT_LAYER_PAIR_CHANGED, [&]( wxCommandEvent& aEvt )
447 {
448 const LAYER_PAIR& layerPair = m_layerPairSettings->GetCurrentLayerPair();
449 PCB_SCREEN& screen = *GetScreen();
450
451 screen.m_Route_Layer_TOP = layerPair.GetLayerA();
452 screen.m_Route_Layer_BOTTOM = layerPair.GetLayerB();
453
454 // Update the toolbar icon
455 PrepareLayerIndicator();
456 });
457 }
458
459 GetToolManager()->PostAction( ACTIONS::zoomFitScreen );
460
461 // This is used temporarily to fix a client size issue on GTK that causes zoom to fit
462 // to calculate the wrong zoom size. See PCB_EDIT_FRAME::onSize().
463 Bind( wxEVT_SIZE, &PCB_EDIT_FRAME::onSize, this );
464
465 Bind( wxEVT_IDLE,
466 [this]( wxIdleEvent& aEvent )
467 {
468 BOX2D viewport = GetCanvas()->GetView()->GetViewport();
469
470 if( viewport != m_lastNetnamesViewport )
471 {
472 redrawNetnames();
473 m_lastNetnamesViewport = viewport;
474 }
475
476 // Do not forget to pass the Idle event to other clients:
477 aEvent.Skip();
478 } );
479
480 resolveCanvasType();
481
482 setupUnits( config() );
483
484 // Ensure the DRC engine is initialized so that constraints can be resolved even before a
485 // board is loaded or saved
486 try
487 {
488 m_toolManager->GetTool<DRC_TOOL>()->GetDRCEngine()->InitEngine( wxFileName() );
489 }
490 catch( PARSE_ERROR& )
491 {
492 }
493
494 // Ensure the Python interpreter is up to date with its environment variables
495 PythonSyncEnvironmentVariables();
496 PythonSyncProjectName();
497
498 // Sync action plugins in case they changed since the last time the frame opened
499 GetToolManager()->RunAction( ACTIONS::pluginsReload );
500
501#ifdef KICAD_IPC_API
502 m_apiHandler = std::make_unique<API_HANDLER_PCB>( this );
503 Pgm().GetApiServer().RegisterHandler( m_apiHandler.get() );
504
505 if( Kiface().IsSingle() )
506 {
507 m_apiHandlerCommon = std::make_unique<API_HANDLER_COMMON>();
508 Pgm().GetApiServer().RegisterHandler( m_apiHandlerCommon.get() );
509 }
510#endif
511
512 GetCanvas()->SwitchBackend( m_canvasType );
513 ActivateGalCanvas();
514
515 // Default shutdown reason until a file is loaded
516 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "New PCB file is unsaved" ) );
517
518 // disable Export STEP item if kicad2step does not exist
519 wxString strK2S = Pgm().GetExecutablePath();
520
521#ifdef __WXMAC__
522 if( strK2S.Find( wxT( "pcbnew.app" ) ) != wxNOT_FOUND )
523 {
524 // On macOS, we have standalone applications inside the main bundle, so we handle that here:
525 strK2S += wxT( "../../" );
526 }
527
528 strK2S += wxT( "Contents/MacOS/" );
529#endif
530
531 wxFileName appK2S( strK2S, wxT( "kicad2step" ) );
532
533#ifdef _WIN32
534 appK2S.SetExt( wxT( "exe" ) );
535#endif
536
537 // Ensure the window is on top
538 Raise();
539
540// if( !appK2S.FileExists() )
541 // GetMenuBar()->FindItem( ID_GEN_EXPORT_FILE_STEP )->Enable( false );
542
543 // AUI doesn't refresh properly on wxMac after changes in eb7dc6dd, so force it to
544#ifdef __WXMAC__
545 if( Kiface().IsSingle() )
546 {
547 CallAfter( [this]()
548 {
549 m_appearancePanel->OnBoardChanged();
550 } );
551 }
552#endif
553
554 // Register a call to update the toolbar sizes. It can't be done immediately because
555 // it seems to require some sizes calculated that aren't yet (at least on GTK).
556 CallAfter( [this]()
557 {
558 // Ensure the controls on the toolbars all are correctly sized
559 UpdateToolbarControlSizes();
560
561 // Update the angle snap mode toolbar button to reflect the current preference
562 GetToolManager()->RunAction( PCB_ACTIONS::angleSnapModeChanged );
563 } );
564
565 if( ADVANCED_CFG::GetCfg().m_ShowEventCounters )
566 {
567 m_eventCounterTimer = new wxTimer( this );
568
569 Bind( wxEVT_TIMER,
570 [&]( wxTimerEvent& aEvent )
571 {
572 GetCanvas()->m_PaintEventCounter->Show();
573 GetCanvas()->m_PaintEventCounter->Reset();
574
576 static_cast<KIGFX::WX_VIEW_CONTROLS*>( GetCanvas()->GetViewControls() );
579
580 },
581 m_eventCounterTimer->GetId() );
582
583 m_eventCounterTimer->Start( 1000 );
584 }
585
588 m_acceptedExts.emplace( wxS( "dxf" ), &PCB_ACTIONS::ddImportGraphics );
590 DragAcceptFiles( true );
591
592 Bind( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, &PCB_EDIT_FRAME::onCloseModelessBookReporterDialogs, this );
593}
594
595
596void PCB_EDIT_FRAME::StartCrossProbeFlash( const std::vector<BOARD_ITEM*>& aItems )
597{
598 if( !GetPcbNewSettings()->m_CrossProbing.flash_selection )
599 {
600 wxLogTrace( traceCrossProbeFlash, "StartCrossProbeFlash(PCB): aborted (setting disabled) items=%zu",
601 aItems.size() );
602 return;
603 }
604
605 if( aItems.empty() )
606 {
607 wxLogTrace( traceCrossProbeFlash, "StartCrossProbeFlash(PCB): aborted (no items)" );
608 return;
609 }
610
612 {
613 wxLogTrace( traceCrossProbeFlash, "StartCrossProbeFlash(PCB): restarting existing flash (phase=%d)",
616 }
617
618 wxLogTrace( traceCrossProbeFlash, "StartCrossProbeFlash(PCB): starting with %zu items", aItems.size() );
619
620 // Store uuids
622 for( BOARD_ITEM* it : aItems )
623 m_crossProbeFlashItems.push_back( it->m_Uuid );
624
627
628 if( !m_crossProbeFlashTimer.GetOwner() )
629 m_crossProbeFlashTimer.SetOwner( this );
630
631 bool started = m_crossProbeFlashTimer.Start( 500, wxTIMER_CONTINUOUS ); // 0.5s intervals -> 3s total for 6 phases
632 wxLogTrace( traceCrossProbeFlash, "StartCrossProbeFlash(PCB): timer start=%d id=%d",
633 (int) started, m_crossProbeFlashTimer.GetId() );
634}
635
636
637void PCB_EDIT_FRAME::OnCrossProbeFlashTimer( wxTimerEvent& aEvent )
638{
639 wxLogTrace( traceCrossProbeFlash, "Timer(PCB) fired: phase=%d running=%d items=%zu",
641
643 {
644 wxLogTrace( traceCrossProbeFlash, "Timer(PCB) fired but not flashing (ignored)" );
645 return;
646 }
647
649
650 if( !selTool )
651 return;
652
653 // Prevent recursion / IPC during flashing
654 bool prevGuard = m_probingSchToPcb;
655 m_probingSchToPcb = true;
656
657 if( m_crossProbeFlashPhase % 2 == 0 )
658 {
659 // Hide selection
660 selTool->ClearSelection( true );
661 wxLogTrace( traceCrossProbeFlash, "Phase %d (PCB): cleared selection", m_crossProbeFlashPhase );
662 }
663 else
664 {
665 // Restore selection
666 for( const KIID& id : m_crossProbeFlashItems )
667 {
668 if( EDA_ITEM* item = GetBoard()->ResolveItem( id, true ) )
669 selTool->AddItemToSel( item, true );
670 }
671
672 wxLogTrace( traceCrossProbeFlash, "Phase %d (PCB): restored %zu items",
674 }
675
676 // Force a redraw even if the canvas / frame does not currently have focus (mouse elsewhere)
677 if( GetCanvas() )
678 {
680 wxLogTrace( traceCrossProbeFlash, "Phase %d (PCB): forced canvas refresh", m_crossProbeFlashPhase );
681 }
682
683 m_probingSchToPcb = prevGuard;
684
686
687 if( m_crossProbeFlashPhase > 6 )
688 {
689 // Ensure final state (selected)
690 for( const KIID& id : m_crossProbeFlashItems )
691 {
692 if( EDA_ITEM* item = GetBoard()->ResolveItem( id, true ) )
693 selTool->AddItemToSel( item, true );
694 }
695
696 m_crossProbeFlashing = false;
698
699 wxLogTrace( traceCrossProbeFlash, "Flashing complete (PCB). Final selection size=%zu",
700 m_crossProbeFlashItems.size() );
701 }
702}
703
704
706{
708
709 if( ADVANCED_CFG::GetCfg().m_ShowEventCounters )
710 {
711 // Stop the timer during destruction early to avoid potential event race conditions (that
712 // do happen on windows)
713 m_eventCounterTimer->Stop();
714 delete m_eventCounterTimer;
715 }
716
717 // Close modeless dialogs
718 wxWindow* open_dlg = wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME );
719
720 if( open_dlg )
721 open_dlg->Close( true );
722
723 // Shutdown all running tools
724 if( m_toolManager )
725 m_toolManager->ShutdownAllTools();
726
727 if( GetBoard() )
729
730 // We passed ownership of these to wxAuiManager.
731 // delete m_selectionFilterPanel;
732 // delete m_appearancePanel;
733 // delete m_propertiesPanel;
734 // delete m_netInspectorPanel;
735
737}
738
739
740void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard, bool aBuildConnectivity,
741 PROGRESS_REPORTER* aReporter )
742{
743 if( m_pcb )
744 m_pcb->ClearProject();
745
746 PCB_BASE_EDIT_FRAME::SetBoard( aBoard, aReporter );
747
748 aBoard->SetProject( &Prj() );
749
750 if( aBuildConnectivity )
751 aBoard->BuildConnectivity();
752
753 // reload the drawing-sheet
754 SetPageSettings( aBoard->GetPageSettings() );
755
757}
758
759
764
765
766std::unique_ptr<GRID_HELPER> PCB_EDIT_FRAME::MakeGridHelper()
767{
768 return std::make_unique<PCB_GRID_HELPER>( m_toolManager, GetMagneticItemsSettings() );
769}
770
771
773{
774 /*
775 * While new items being scrolled into the view will get painted, they will only get
776 * annotated with netname instances currently within the view. Subsequent panning will not
777 * draw newly-visible netname instances because the item has already been drawn.
778 *
779 * This routine, fired on idle if the viewport has changed, looks for visible items that
780 * might have multiple netname instances and redraws them. (It does not need to handle pads
781 * and vias because they only ever have a single netname instance drawn on them.)
782 */
783 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
784
785 if( !cfg || cfg->m_Display.m_NetNames < 2 )
786 return;
787
788 KIGFX::VIEW* view = GetCanvas()->GetView();
789 BOX2D viewport = view->GetViewport();
790
791 // Inflate to catch most of the track width
792 BOX2I_MINMAX clipbox( BOX2ISafe( viewport.Inflate( pcbIUScale.mmToIU( 2.0 ) ) ) );
793
794 for( PCB_TRACK* track : GetBoard()->Tracks() )
795 {
796 // Don't need to update vias
797 if( track->Type() == PCB_VIA_T )
798 continue;
799
800 // Don't update invisible tracks
801 if( !clipbox.Intersects( BOX2I_MINMAX( track->GetStart(), track->GetEnd() ) ) )
802 continue;
803
804 if( track->ViewGetLOD( GetNetnameLayer( track->GetLayer() ), view ) < view->GetScale() )
805 view->Update( track, KIGFX::REPAINT );
806 }
807}
808
809
810void PCB_EDIT_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
811{
812 PCB_BASE_FRAME::SetPageSettings( aPageSettings );
813
814 // Prepare drawing-sheet template
816 &m_pcb->GetPageSettings(),
817 m_pcb->GetProject(),
818 &m_pcb->GetTitleBlock(),
819 &m_pcb->GetProperties() );
820
821 drawingSheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) );
822 drawingSheet->SetSheetPath( std::string( GetFullScreenDesc().mb_str() ) );
823
824 // A board is not like a schematic having a main page and sub sheets.
825 // So for the drawing sheet, use only the first page option to display items
826 drawingSheet->SetIsFirstPage( true );
827
828 BASE_SCREEN* screen = GetScreen();
829
830 if( screen != nullptr )
831 {
832 drawingSheet->SetPageNumber(TO_UTF8( screen->GetPageNumber() ) );
833 drawingSheet->SetSheetCount( screen->GetPageCount() );
834 }
835
836 if( BOARD* board = GetBoard() )
837 drawingSheet->SetFileName( TO_UTF8( board->GetFileName() ) );
838
839 // PCB_DRAW_PANEL_GAL takes ownership of the drawing-sheet
840 GetCanvas()->SetDrawingSheet( drawingSheet );
841}
842
843
845{
846 return GetScreen() && GetScreen()->IsContentModified();
847}
848
849
851{
852 return m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
853}
854
855
857{
858 // Create the manager and dispatcher & route draw panel events to the dispatcher
860 m_toolManager->SetEnvironment( m_pcb, GetCanvas()->GetView(),
861 GetCanvas()->GetViewControls(), config(), this );
862 m_actions = new PCB_ACTIONS();
864
865 // Register tools
866 m_toolManager->RegisterTool( new COMMON_CONTROL );
867 m_toolManager->RegisterTool( new COMMON_TOOLS );
868 m_toolManager->RegisterTool( new PCB_SELECTION_TOOL );
869 m_toolManager->RegisterTool( new ZOOM_TOOL );
870 m_toolManager->RegisterTool( new PCB_PICKER_TOOL );
871 m_toolManager->RegisterTool( new ROUTER_TOOL );
872 m_toolManager->RegisterTool( new EDIT_TOOL );
873 m_toolManager->RegisterTool( new PCB_EDIT_TABLE_TOOL );
874 m_toolManager->RegisterTool( new GLOBAL_EDIT_TOOL );
875 m_toolManager->RegisterTool( new PAD_TOOL );
876 m_toolManager->RegisterTool( new DRAWING_TOOL );
877 m_toolManager->RegisterTool( new PCB_POINT_EDITOR );
878 m_toolManager->RegisterTool( new PCB_CONTROL );
879 m_toolManager->RegisterTool( new PCB_DESIGN_BLOCK_CONTROL );
880 m_toolManager->RegisterTool( new BOARD_EDITOR_CONTROL );
881 m_toolManager->RegisterTool( new BOARD_INSPECTION_TOOL );
882 m_toolManager->RegisterTool( new BOARD_REANNOTATE_TOOL );
883 m_toolManager->RegisterTool( new ALIGN_DISTRIBUTE_TOOL );
884 m_toolManager->RegisterTool( new MICROWAVE_TOOL );
885 m_toolManager->RegisterTool( new POSITION_RELATIVE_TOOL );
886 m_toolManager->RegisterTool( new ARRAY_TOOL );
887 m_toolManager->RegisterTool( new ZONE_FILLER_TOOL );
888 m_toolManager->RegisterTool( new AUTOPLACE_TOOL );
889 m_toolManager->RegisterTool( new DRC_TOOL );
890 m_toolManager->RegisterTool( new PCB_VIEWER_TOOLS );
891 m_toolManager->RegisterTool( new CONVERT_TOOL );
892 m_toolManager->RegisterTool( new PCB_GROUP_TOOL );
893 m_toolManager->RegisterTool( new GENERATOR_TOOL );
894 m_toolManager->RegisterTool( new SCRIPTING_TOOL );
895 m_toolManager->RegisterTool( new PROPERTIES_TOOL );
896 m_toolManager->RegisterTool( new MULTICHANNEL_TOOL );
897 m_toolManager->RegisterTool( new EMBED_TOOL );
898 m_toolManager->RegisterTool( new DRC_RULE_EDITOR_TOOL );
899 m_toolManager->InitTools();
900
901 for( TOOL_BASE* tool : m_toolManager->Tools() )
902 {
903 if( PCB_TOOL_BASE* pcbTool = dynamic_cast<PCB_TOOL_BASE*>( tool ) )
904 pcbTool->SetIsBoardEditor( true );
905 }
906
907 // Run the selection tool, it is supposed to be always active
908 m_toolManager->InvokeTool( "common.InteractiveSelection" );
909}
910
911
913{
915
916 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
917 PCB_EDITOR_CONDITIONS cond( this );
918
919 auto undoCond =
920 [ this ] (const SELECTION& aSel )
921 {
922 DRAWING_TOOL* drawingTool = m_toolManager->GetTool<DRAWING_TOOL>();
923
924 if( drawingTool && drawingTool->GetDrawingMode() != DRAWING_TOOL::MODE::NONE )
925 return true;
926
927 ROUTER_TOOL* routerTool = m_toolManager->GetTool<ROUTER_TOOL>();
928
929 if( routerTool && routerTool->RoutingInProgress() )
930 return true;
931
932 return GetUndoCommandCount() > 0;
933 };
934
935 auto groupWithDesignBlockLink =
936 [] ( const SELECTION& aSel )
937 {
938 if( aSel.Size() != 1 )
939 return false;
940
941 if( aSel[0]->Type() != PCB_GROUP_T )
942 return false;
943
944 PCB_GROUP* group = static_cast<PCB_GROUP*>( aSel.GetItem( 0 ) );
945
946 return group->HasDesignBlockLink();
947 };
948
949 wxASSERT( mgr );
950
951#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
952#define CHECK( x ) ACTION_CONDITIONS().Check( x )
953// clang-format off
954
956 mgr->SetConditions( ACTIONS::undo, ENABLE( undoCond ) );
958
962
963 mgr->SetConditions( ACTIONS::cut, ENABLE( cond.HasItems() ) );
964 mgr->SetConditions( ACTIONS::copy, ENABLE( cond.HasItems() ) );
971
972 static const std::vector<KICAD_T> groupTypes = { PCB_GROUP_T, PCB_GENERATOR_T };
973
978
979 mgr->SetConditions( PCB_ACTIONS::placeLinkedDesignBlock, ENABLE( groupWithDesignBlockLink) );
980 mgr->SetConditions( PCB_ACTIONS::saveToLinkedDesignBlock, ENABLE( groupWithDesignBlockLink) );
981
987
988 if( SCRIPTING::IsWxAvailable() )
990
991 auto enableZoneControlCondition =
992 [this] ( const SELECTION& )
993 {
996 };
997
999 ENABLE( enableZoneControlCondition )
1002 ENABLE( enableZoneControlCondition )
1005 ENABLE( enableZoneControlCondition )
1008 ENABLE( enableZoneControlCondition )
1010
1012
1013 auto hasElements =
1014 [ this ] ( const SELECTION& aSel )
1015 {
1016 return GetBoard() &&
1017 ( !GetBoard()->IsEmpty() || !SELECTION_CONDITIONS::Idle( aSel ) );
1018 };
1019
1020 auto boardFlippedCond =
1021 [this]( const SELECTION& )
1022 {
1023 return GetCanvas() && GetCanvas()->GetView()->IsMirroredX();
1024 };
1025
1026 auto layerManagerCond =
1027 [this] ( const SELECTION& )
1028 {
1029 return LayerManagerShown();
1030 };
1031
1032 auto propertiesCond =
1033 [this] ( const SELECTION& )
1034 {
1035 return PropertiesShown();
1036 };
1037
1038 auto netInspectorCond =
1039 [this] ( const SELECTION& )
1040 {
1041 return NetInspectorShown();
1042 };
1043
1044 auto searchPaneCond =
1045 [this] ( const SELECTION& )
1046 {
1047 return m_auimgr.GetPane( SearchPaneName() ).IsShown();
1048 };
1049
1050 auto designBlockCond =
1051 [ this ] (const SELECTION& aSel )
1052 {
1053 return m_auimgr.GetPane( DesignBlocksPaneName() ).IsShown();
1054 };
1055
1056 auto highContrastCond =
1057 [this] ( const SELECTION& )
1058 {
1060 };
1061
1062 auto globalRatsnestCond =
1063 [this] (const SELECTION& )
1064 {
1066 };
1067
1068 auto curvedRatsnestCond =
1069 [this] (const SELECTION& )
1070 {
1072 };
1073
1074 auto netHighlightCond =
1075 [this]( const SELECTION& )
1076 {
1078 return !settings->GetHighlightNetCodes().empty();
1079 };
1080
1081 auto enableNetHighlightCond =
1082 [this]( const SELECTION& )
1083 {
1085 return tool && tool->IsNetHighlightSet();
1086 };
1087
1088 mgr->SetConditions( ACTIONS::highContrastMode, CHECK( highContrastCond ) );
1089 mgr->SetConditions( PCB_ACTIONS::flipBoard, CHECK( boardFlippedCond ) );
1090 mgr->SetConditions( PCB_ACTIONS::showLayersManager, CHECK( layerManagerCond ) );
1091 mgr->SetConditions( PCB_ACTIONS::showRatsnest, CHECK( globalRatsnestCond ) );
1092 mgr->SetConditions( PCB_ACTIONS::ratsnestLineMode, CHECK( curvedRatsnestCond ) );
1093 mgr->SetConditions( PCB_ACTIONS::toggleNetHighlight, CHECK( netHighlightCond )
1094 .Enable( enableNetHighlightCond ) );
1095 mgr->SetConditions( ACTIONS::showProperties, CHECK( propertiesCond ) );
1096 mgr->SetConditions( PCB_ACTIONS::showNetInspector, CHECK( netInspectorCond ) );
1097 mgr->SetConditions( PCB_ACTIONS::showSearch, CHECK( searchPaneCond ) );
1098 mgr->SetConditions( PCB_ACTIONS::showDesignBlockPanel, CHECK( designBlockCond ) );
1099
1102
1103 const auto isArcKeepCenterMode =
1104 [this]( const SELECTION& )
1105 {
1107 };
1108
1109 const auto isArcKeepEndpointMode =
1110 [this]( const SELECTION& )
1111 {
1113 };
1114
1115 const auto isArcKeepRadiusMode =
1116 [this]( const SELECTION& )
1117 {
1119 };
1120
1121 mgr->SetConditions( ACTIONS::pointEditorArcKeepCenter, CHECK( isArcKeepCenterMode ) );
1122 mgr->SetConditions( ACTIONS::pointEditorArcKeepEndpoint, CHECK( isArcKeepEndpointMode ) );
1123 mgr->SetConditions( ACTIONS::pointEditorArcKeepRadius, CHECK( isArcKeepRadiusMode ) );
1124
1125 auto isHighlightMode =
1126 [this]( const SELECTION& )
1127 {
1128 ROUTER_TOOL* tool = m_toolManager->GetTool<ROUTER_TOOL>();
1129 return tool && tool->GetRouterMode() == PNS::RM_MarkObstacles;
1130 };
1131
1132 auto isShoveMode =
1133 [this]( const SELECTION& )
1134 {
1135 ROUTER_TOOL* tool = m_toolManager->GetTool<ROUTER_TOOL>();
1136 return tool && tool->GetRouterMode() == PNS::RM_Shove;
1137 };
1138
1139 auto isWalkaroundMode =
1140 [this]( const SELECTION& )
1141 {
1142 ROUTER_TOOL* tool = m_toolManager->GetTool<ROUTER_TOOL>();
1143 return tool && tool->GetRouterMode() == PNS::RM_Walkaround;
1144 };
1145
1146 mgr->SetConditions( PCB_ACTIONS::routerHighlightMode, CHECK( isHighlightMode ) );
1147 mgr->SetConditions( PCB_ACTIONS::routerShoveMode, CHECK( isShoveMode ) );
1148 mgr->SetConditions( PCB_ACTIONS::routerWalkaroundMode, CHECK( isWalkaroundMode ) );
1149
1150 auto isAutoTrackWidth =
1151 [this]( const SELECTION& )
1152 {
1154 };
1155
1156 mgr->SetConditions( PCB_ACTIONS::autoTrackWidth, CHECK( isAutoTrackWidth ) );
1157
1158 auto haveNetCond =
1159 [] ( const SELECTION& aSel )
1160 {
1161 for( EDA_ITEM* item : aSel )
1162 {
1163 if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
1164 {
1165 if( bci->GetNetCode() > 0 )
1166 return true;
1167 }
1168 }
1169
1170 return false;
1171 };
1172
1173 mgr->SetConditions( PCB_ACTIONS::showNetInRatsnest, ENABLE( haveNetCond ) );
1174 mgr->SetConditions( PCB_ACTIONS::hideNetInRatsnest, ENABLE( haveNetCond ) );
1177
1178 static const std::vector<KICAD_T> trackTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T };
1179 static const std::vector<KICAD_T> padOwnerTypes = { PCB_FOOTPRINT_T, PCB_PAD_T };
1180 static const std::vector<KICAD_T> footprintTypes = { PCB_FOOTPRINT_T };
1181 static const std::vector<KICAD_T> crossProbeTypes = { PCB_PAD_T, PCB_FOOTPRINT_T, PCB_GROUP_T };
1182 static const std::vector<KICAD_T> zoneTypes = { PCB_ZONE_T };
1183
1189
1190
1192 && SELECTION_CONDITIONS::OnlyTypes( zoneTypes );
1193
1195 && SELECTION_CONDITIONS::OnlyTypes( zoneTypes );
1196
1197 mgr->SetConditions( PCB_ACTIONS::zoneDuplicate, ENABLE( singleZoneCond ) );
1198 mgr->SetConditions( PCB_ACTIONS::drawZoneCutout, ENABLE( singleZoneCond ) );
1199 mgr->SetConditions( PCB_ACTIONS::drawSimilarZone, ENABLE( singleZoneCond ) );
1200 mgr->SetConditions( PCB_ACTIONS::zoneMerge, ENABLE( zoneMergeCond ) );
1201
1202#define CURRENT_TOOL( action ) mgr->SetConditions( action, CHECK( cond.CurrentTool( action ) ) )
1203
1204 // These tools can be used at any time to inspect the board
1209
1210 auto isDRCIdle =
1211 [this] ( const SELECTION& )
1212 {
1213 DRC_TOOL* tool = m_toolManager->GetTool<DRC_TOOL>();
1214 return !( tool && tool->IsDRCRunning() );
1215 };
1216
1217#define CURRENT_EDIT_TOOL( action ) \
1218 mgr->SetConditions( action, ACTION_CONDITIONS().Check( cond.CurrentTool( action ) ) \
1219 .Enable( isDRCIdle ) )
1220
1221 // These tools edit the board, so they must be disabled during some operations
1253
1259
1260#undef CURRENT_TOOL
1261#undef CURRENT_EDIT_TOOL
1262#undef ENABLE
1263#undef CHECK
1264// clang-format on
1265}
1266
1267
1268void PCB_EDIT_FRAME::OnQuit( wxCommandEvent& event )
1269{
1270 if( event.GetId() == wxID_EXIT )
1271 Kiway().OnKiCadExit();
1272
1273 if( event.GetId() == wxID_CLOSE || Kiface().IsSingle() )
1274 Close( false );
1275}
1276
1277
1278void PCB_EDIT_FRAME::ResolveDRCExclusions( bool aCreateMarkers )
1279{
1280 BOARD_COMMIT commit( this );
1281
1282 for( PCB_MARKER* marker : GetBoard()->ResolveDRCExclusions( aCreateMarkers ) )
1283 {
1284 if( marker->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
1285 marker->GetRCItem()->SetItems( GetCanvas()->GetDrawingSheet() );
1286
1287 commit.Add( marker );
1288 }
1289
1290 commit.Push( wxEmptyString, SKIP_UNDO | SKIP_SET_DIRTY );
1291
1292 for( PCB_MARKER* marker : GetBoard()->Markers() )
1293 {
1294 if( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION )
1295 GetCanvas()->GetView()->Update( marker );
1296 }
1297
1299}
1300
1301
1302bool PCB_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
1303{
1304 // Shutdown blocks must be determined and vetoed as early as possible
1305 if( KIPLATFORM::APP::SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
1306 && IsContentModified() )
1307 {
1308 return false;
1309 }
1310
1311 ZONE_FILLER_TOOL* zoneFillerTool = m_toolManager->GetTool<ZONE_FILLER_TOOL>();
1312
1313 if( zoneFillerTool->IsBusy() )
1314 {
1315 wxBell();
1316
1317 if( wxWindow* reporter = dynamic_cast<wxWindow*>( zoneFillerTool->GetProgressReporter() ) )
1318 reporter->ShowWithEffect( wxSHOW_EFFECT_EXPAND );
1319
1320 return false;
1321 }
1322
1323 // Don't allow closing while the modal footprint chooser is open
1324 auto* chooser = (FOOTPRINT_CHOOSER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_CHOOSER, false );
1325
1326 if( chooser && chooser->IsModal() ) // Can close footprint chooser?
1327 return false;
1328
1329 if( Kiface().IsSingle() )
1330 {
1331 auto* fpEditor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_FOOTPRINT_EDITOR, false );
1332
1333 if( fpEditor && !fpEditor->Close() ) // Can close footprint editor?
1334 return false;
1335
1336 auto* fpViewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_VIEWER, false );
1337
1338 if( fpViewer && !fpViewer->Close() ) // Can close footprint viewer?
1339 return false;
1340 }
1341 else
1342 {
1343 auto* fpEditor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_FOOTPRINT_EDITOR, false );
1344
1345 if( fpEditor && fpEditor->IsCurrentFPFromBoard() )
1346 {
1347 if( !fpEditor->CanCloseFPFromBoard( true ) )
1348 return false;
1349 }
1350 }
1351
1352 if( IsContentModified() )
1353 {
1354 wxFileName fileName = GetBoard()->GetFileName();
1355 wxString msg = _( "Save changes to '%s' before closing?" );
1356
1357 if( !HandleUnsavedChanges( this, wxString::Format( msg, fileName.GetFullName() ),
1358 [&]() -> bool
1359 {
1360 return SaveBoard();
1361 } ) )
1362 {
1363 return false;
1364 }
1365
1366 // If user discarded changes, create a duplicate commit of last saved PCB state and
1367 // advance Last_Save_pcb tag for explicit history event.
1368 if( GetLastUnsavedChangesResponse() == wxID_NO )
1369 {
1370 wxString projPath = Prj().GetProjectPath();
1371
1372 if( !projPath.IsEmpty() && Kiway().LocalHistory().HistoryExists( projPath ) )
1373 {
1374 Kiway().LocalHistory().CommitDuplicateOfLastSave( projPath, wxS("pcb"),
1375 wxS("Discard unsaved pcb changes") );
1376 }
1377 }
1378 }
1379
1380 return PCB_BASE_EDIT_FRAME::canCloseWindow( aEvent );
1381}
1382
1383
1385{
1386 // Unregister the autosave saver before any cleanup that might invalidate the board
1387 if( GetBoard() )
1389
1390 // On Windows 7 / 32 bits, on OpenGL mode only, Pcbnew crashes
1391 // when closing this frame if a footprint was selected, and the footprint editor called
1392 // to edit this footprint, and when closing pcbnew if this footprint is still selected
1393 // See https://bugs.launchpad.net/kicad/+bug/1655858
1394 // I think this is certainly a OpenGL event fired after frame deletion, so this workaround
1395 // avoid the crash (JPC)
1396 GetCanvas()->SetEvtHandlerEnabled( false );
1397
1399
1400#ifdef KICAD_IPC_API
1401 Pgm().GetApiServer().DeregisterHandler( m_apiHandler.get() );
1402 wxTheApp->Unbind( EDA_EVT_PLUGIN_AVAILABILITY_CHANGED,
1403 &PCB_EDIT_FRAME::onPluginAvailabilityChanged, this );
1404#endif
1405
1406 // Clean up mode-less dialogs.
1407 Unbind( EDA_EVT_CLOSE_DIALOG_BOOK_REPORTER, &PCB_EDIT_FRAME::onCloseModelessBookReporterDialogs,
1408 this );
1409
1410 wxWindow* open_dlg = wxWindow::FindWindowByName( DIALOG_DRC_WINDOW_NAME );
1411
1412 if( open_dlg )
1413 open_dlg->Close( true );
1414
1415 if( m_findDialog )
1416 {
1417 m_findDialog->Destroy();
1418 m_findDialog = nullptr;
1419 }
1420
1422 {
1423 m_inspectDrcErrorDlg->Destroy();
1424 m_inspectDrcErrorDlg = nullptr;
1425 }
1426
1428 {
1429 m_inspectClearanceDlg->Destroy();
1430 m_inspectClearanceDlg = nullptr;
1431 }
1432
1434 {
1435 m_inspectConstraintsDlg->Destroy();
1436 m_inspectConstraintsDlg = nullptr;
1437 }
1438
1439 if( m_footprintDiffDlg )
1440 {
1441 m_footprintDiffDlg->Destroy();
1442 m_footprintDiffDlg = nullptr;
1443 }
1444
1445 // Delete the auto save file if it exists.
1446 wxFileName fn = GetBoard()->GetFileName();
1447
1448 // Make sure local settings are persisted
1449 if( Prj().GetLocalSettings().ShouldAutoSave() )
1450 {
1451 m_netInspectorPanel->SaveSettings();
1453 }
1454 else
1455 {
1456 wxLogTrace( traceAutoSave, wxT( "Skipping auto-save of migrated local settings" ) );
1457 }
1458
1459 // Do not show the layer manager during closing to avoid flicker
1460 // on some platforms (Windows) that generate useless redraw of items in
1461 // the Layer Manager
1463 {
1464 m_auimgr.GetPane( wxS( "LayersManager" ) ).Show( false );
1465 m_auimgr.GetPane( wxS( "TabbedPanel" ) ).Show( false );
1466 }
1467
1468 // Unlink the old project if needed
1470
1471 // Delete board structs and undo/redo lists, to avoid crash on exit
1472 // when deleting some structs (mainly in undo/redo lists) too late
1473 Clear_Pcb( false, true );
1474
1475 // do not show the window because ScreenPcb will be deleted and we do not
1476 // want any paint event
1477 Show( false );
1478
1480}
1481
1482
1489
1490
1491void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage, wxWindow* aParent )
1492{
1493 static std::mutex dialogMutex; // Local static mutex
1494
1495 std::unique_lock<std::mutex> dialogLock( dialogMutex, std::try_to_lock );
1496
1497 // One dialog at a time.
1498 if( !dialogLock.owns_lock() )
1499 {
1500 if( m_boardSetupDlg && m_boardSetupDlg->IsShown() )
1501 {
1502 m_boardSetupDlg->Raise(); // Brings the existing dialog to the front
1503 }
1504
1505 return;
1506 }
1507
1508 // Make sure everything's up-to-date
1510
1511 DIALOG_BOARD_SETUP dlg( this, aParent );
1512
1513 if( !aInitialPage.IsEmpty() )
1514 dlg.SetInitialPage( aInitialPage, wxEmptyString );
1515
1516 // Assign dlg to the m_boardSetupDlg pointer to track its status.
1517 m_boardSetupDlg = &dlg;
1518
1519 // QuasiModal required for Scintilla auto-complete
1520 if( dlg.ShowQuasiModal() == wxID_OK )
1521 {
1522 // Note: We must synchronise time domain properties before nets and classes, otherwise the updates
1523 // called by the board listener events are using stale data
1526
1527 if( !GetBoard()->SynchronizeComponentClasses( std::unordered_set<wxString>() ) )
1528 {
1529 m_infoBar->RemoveAllButtons();
1530 m_infoBar->AddCloseButton();
1531 m_infoBar->ShowMessage( _( "Could not load component class assignment rules" ),
1532 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::GENERIC );
1533 }
1534
1535 // We don't know if anything was modified, so err on the side of requiring a save
1536 OnModify();
1537
1539
1542
1543 PCBNEW_SETTINGS* settings = GetPcbNewSettings();
1544 static LSET maskAndPasteLayers = LSET( { F_Mask, F_Paste, B_Mask, B_Paste } );
1545
1547 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
1548 {
1549 int flags = 0;
1550
1551 if( !aItem->IsBOARD_ITEM() )
1552 return flags;
1553
1554 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aItem );
1555
1556 if( item->Type() == PCB_VIA_T || item->Type() == PCB_PAD_T )
1557 {
1558 // Note: KIGFX::REPAINT isn't enough for things that go from invisible
1559 // to visible as they won't be found in the view layer's itemset for
1560 // re-painting.
1561 if( ( GetBoard()->GetVisibleLayers() & maskAndPasteLayers ).any() )
1562 flags |= KIGFX::ALL;
1563 }
1564
1565 if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T || item->Type() == PCB_VIA_T )
1566 {
1568 flags |= KIGFX::REPAINT;
1569 }
1570
1571 if( item->Type() == PCB_PAD_T )
1572 {
1573 if( settings->m_Display.m_PadClearance )
1574 flags |= KIGFX::REPAINT;
1575 }
1576
1577 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aItem ) )
1578 {
1579 if( text->HasTextVars() )
1580 {
1581 text->ClearRenderCache();
1582 text->ClearBoundingBoxCache();
1584 }
1585 }
1586
1587 return flags;
1588 } );
1589
1590 GetCanvas()->Refresh();
1591
1595
1596 //this event causes the routing tool to reload its design rules information
1598 toolEvent.SetHasPosition( false );
1599 m_toolManager->ProcessEvent( toolEvent );
1600 }
1601
1602 GetCanvas()->SetFocus();
1603
1604 // Reset m_boardSetupDlg after the dialog is closed
1605 m_boardSetupDlg = nullptr;
1606}
1607
1608
1610{
1611 m_searchPane->FocusSearch();
1612}
1613
1614
1616{
1618
1619 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( aCfg );
1620 wxASSERT( cfg );
1621
1622 if( cfg )
1623 {
1627 }
1628}
1629
1630
1632{
1634
1635 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( aCfg );
1636 wxASSERT( cfg );
1637
1638 if( cfg )
1639 {
1640 wxAuiPaneInfo& apperancePane = m_auimgr.GetPane( AppearancePanelName() );
1641 cfg->m_AuiPanels.show_layer_manager = apperancePane.IsShown();
1642
1643 if( m_propertiesPanel )
1644 {
1645 cfg->m_AuiPanels.show_properties = m_propertiesPanel->IsShownOnScreen();
1647 cfg->m_AuiPanels.properties_splitter = m_propertiesPanel->SplitterProportion();
1648 }
1649
1650 // ensure m_show_search is up to date (the pane can be closed)
1651 wxAuiPaneInfo& searchPaneInfo = m_auimgr.GetPane( SearchPaneName() );
1652 m_show_search = searchPaneInfo.IsShown();
1654 cfg->m_AuiPanels.search_panel_height = m_searchPane->GetSize().y;
1655 cfg->m_AuiPanels.search_panel_width = m_searchPane->GetSize().x;
1656 cfg->m_AuiPanels.search_panel_dock_direction = searchPaneInfo.dock_direction;
1657
1659 {
1660 wxAuiPaneInfo& netInspectorhPaneInfo = m_auimgr.GetPane( NetInspectorPanelName() );
1661 m_show_net_inspector = netInspectorhPaneInfo.IsShown();
1663 }
1664
1665 if( m_appearancePanel )
1666 {
1669 cfg->m_AuiPanels.appearance_expand_layer_display = m_appearancePanel->IsLayerOptionsExpanded();
1670 cfg->m_AuiPanels.appearance_expand_net_display = m_appearancePanel->IsNetOptionsExpanded();
1671 }
1672
1673 wxAuiPaneInfo& designBlocksPane = m_auimgr.GetPane( DesignBlocksPaneName() );
1674 cfg->m_AuiPanels.design_blocks_show = designBlocksPane.IsShown();
1675
1676 if( designBlocksPane.IsDocked() )
1678 else
1679 {
1680 cfg->m_AuiPanels.design_blocks_panel_float_height = designBlocksPane.floating_size.y;
1681 cfg->m_AuiPanels.design_blocks_panel_float_width = designBlocksPane.floating_size.x;
1682 }
1683
1684 m_designBlocksPane->SaveSettings();
1685 }
1686}
1687
1688
1690{
1691 PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( config() );
1692
1693 return cfg ? cfg->m_RotationAngle : ANGLE_90;
1694}
1695
1696
1701
1702
1704{
1705
1706 GetColorSettings()->SetColor( LAYER_GRID, aColor );
1707 GetCanvas()->GetGAL()->SetGridColor( aColor );
1708}
1709
1710
1711void PCB_EDIT_FRAME::SetActiveLayer( PCB_LAYER_ID aLayer, bool aForceRedraw )
1712{
1713 const PCB_LAYER_ID oldLayer = GetActiveLayer();
1714
1715 if( oldLayer == aLayer && !aForceRedraw )
1716 return;
1717
1719
1720 m_appearancePanel->OnLayerChanged();
1721
1722 m_toolManager->PostAction( PCB_ACTIONS::layerChanged ); // notify other tools
1723 GetCanvas()->SetFocus(); // allow capture of hotkeys
1724 GetCanvas()->SetHighContrastLayer( aLayer );
1725
1726 /*
1727 * Only show pad, via and track clearances when a copper layer is active
1728 * and then only show the clearance layer for that copper layer. For
1729 * front/back non-copper layers, show the clearance layer for the outer
1730 * layer on that side.
1731 *
1732 * For pads/vias, this is to avoid clutter when there are pad/via layers
1733 * that vary in flash (i.e. clearance from the hole or pad edge), padstack
1734 * shape on each layer or clearances on each layer.
1735 *
1736 * For tracks, this follows the same logic as pads/vias, but in theory could
1737 * have their own set of independent clearance layers to allow track clearance
1738 * to be shown for more layers.
1739 */
1740 const auto getClearanceLayerForActive = []( PCB_LAYER_ID aActiveLayer ) -> std::optional<int>
1741 {
1742 if( IsCopperLayer( aActiveLayer ) )
1743 return CLEARANCE_LAYER_FOR( aActiveLayer );
1744
1745 return std::nullopt;
1746 };
1747
1748 if( std::optional<int> oldClearanceLayer = getClearanceLayerForActive( oldLayer ) )
1749 GetCanvas()->GetView()->SetLayerVisible( *oldClearanceLayer, false );
1750
1751 if( std::optional<int> newClearanceLayer = getClearanceLayerForActive( aLayer ) )
1752 GetCanvas()->GetView()->SetLayerVisible( *newClearanceLayer, true );
1753
1755 [&]( KIGFX::VIEW_ITEM* aItem ) -> int
1756 {
1757 if( !aItem->IsBOARD_ITEM() )
1758 return 0;
1759
1760 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aItem );
1761
1762 // Note: KIGFX::REPAINT isn't enough for things that go from invisible to visible
1763 // as they won't be found in the view layer's itemset for re-painting.
1764 if( GetDisplayOptions().m_ContrastModeDisplay == HIGH_CONTRAST_MODE::HIDDEN )
1765 {
1766 if( item->IsOnLayer( oldLayer ) || item->IsOnLayer( aLayer ) )
1767 return KIGFX::ALL;
1768 }
1769
1770 if( item->Type() == PCB_VIA_T )
1771 {
1772 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1773
1774 // Vias on a restricted layer set must be redrawn when the active layer
1775 // is changed
1776 if( via->GetViaType() == VIATYPE::BLIND
1777 || via->GetViaType() == VIATYPE::BURIED
1778 || via->GetViaType() == VIATYPE::MICROVIA )
1779 {
1780 return KIGFX::REPAINT;
1781 }
1782
1783 if( via->GetRemoveUnconnected() )
1784 return KIGFX::ALL;
1785 }
1786 else if( item->Type() == PCB_PAD_T )
1787 {
1788 PAD* pad = static_cast<PAD*>( item );
1789
1790 if( pad->GetRemoveUnconnected() )
1791 return KIGFX::ALL;
1792 }
1793
1794 return 0;
1795 } );
1796
1797 GetCanvas()->Refresh();
1798}
1799
1800
1802{
1803 wxFileName fn( GetBoard()->GetFileName() );
1804 Kiway().LocalHistory().Init( fn.GetPath() );
1806
1807 layerEnum.Choices().Clear();
1808 layerEnum.Undefined( UNDEFINED_LAYER );
1809
1810 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
1811 {
1812 // Canonical name
1813 layerEnum.Map( layer, LSET::Name( layer ) );
1814
1815 // User name
1816 layerEnum.Map( layer, GetBoard()->GetLayerName( layer ) );
1817 }
1818
1819 DRC_TOOL* drcTool = m_toolManager->GetTool<DRC_TOOL>();
1820
1821 try
1822 {
1824 }
1825 catch( PARSE_ERROR& )
1826 {
1827 // Not sure this is the best place to tell the user their rules are buggy, so
1828 // we'll stay quiet for now. Feel free to revisit this decision....
1829 }
1830
1832
1833 UpdateTitle();
1834
1835 // Display a warning that the file is read only
1836 if( fn.FileExists() && !fn.IsFileWritable() )
1837 {
1838 m_infoBar->RemoveAllButtons();
1839 m_infoBar->AddCloseButton();
1840 m_infoBar->ShowMessage( _( "Board file is read only." ),
1842 }
1843
1845
1846 // Sync layer and item visibility
1848
1849 SetElementVisibility( LAYER_RATSNEST, GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest );
1850
1851 m_appearancePanel->OnBoardChanged();
1852
1853 // Apply saved display state to the appearance panel after it has been set up
1854 PROJECT_LOCAL_SETTINGS& localSettings = Prj().GetLocalSettings();
1855
1856 m_appearancePanel->ApplyLayerPreset( localSettings.m_ActiveLayerPreset );
1857
1858 if( GetBoard()->GetDesignSettings().IsLayerEnabled( localSettings.m_ActiveLayer ) )
1859 SetActiveLayer( localSettings.m_ActiveLayer, true );
1860 else
1861 SetActiveLayer( GetActiveLayer(), true ); // Make sure to repaint even if not switching
1862
1863 PROJECT_FILE& projectFile = Prj().GetProjectFile();
1864
1865 m_layerPairSettings->SetLayerPairs( projectFile.m_LayerPairInfos );
1866 m_layerPairSettings->SetCurrentLayerPair( LAYER_PAIR{ F_Cu, B_Cu } );
1867
1868 // Updates any auto dimensions and the auxiliary toolbar tracks/via sizes
1870
1871 // Sync the net inspector now we have connectivity calculated
1873 m_netInspectorPanel->OnBoardChanged();
1874
1875 // Display the loaded board:
1876 Zoom_Automatique( false );
1877
1878 // Invalidate painting as loading the DRC engine will cause clearances to become valid
1880
1881 Refresh();
1882
1883 SetMsgPanel( GetBoard() );
1884 SetStatusText( wxEmptyString );
1885
1886 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "PCB file changes are unsaved" ) );
1887}
1888
1889
1891{
1892 m_appearancePanel->UpdateDisplayOptions();
1893}
1894
1895
1897{
1898 return GetBoard()->IsElementVisible( aElement );
1899}
1900
1901
1903{
1904 // Force the RATSNEST visible
1905 if( aElement == LAYER_RATSNEST )
1906 GetCanvas()->GetView()->SetLayerVisible( aElement, true );
1907 else
1908 GetCanvas()->GetView()->SetLayerVisible( aElement , aNewState );
1909
1910 GetBoard()->SetElementVisibility( aElement, aNewState );
1911}
1912
1913
1915{
1916 // call my base class
1918
1919 m_auimgr.GetPane( m_appearancePanel ).Caption( _( "Appearance" ) );
1920 m_auimgr.GetPane( m_selectionFilterPanel ).Caption( _( "Selection Filter" ) );
1921 m_auimgr.GetPane( m_propertiesPanel ).Caption( _( "Properties" ) );
1922 m_auimgr.GetPane( m_netInspectorPanel ).Caption( _( "Net Inspector" ) );
1923 m_auimgr.Update();
1924
1925 UpdateTitle();
1926}
1927
1928
1930{
1932
1933 if( project.m_PcbLastPath[ aType ].IsEmpty() )
1934 return wxEmptyString;
1935
1936 wxFileName absoluteFileName = project.m_PcbLastPath[ aType ];
1937 wxFileName pcbFileName = GetBoard()->GetFileName();
1938
1939 absoluteFileName.MakeAbsolute( pcbFileName.GetPath() );
1940 return absoluteFileName.GetFullPath();
1941}
1942
1943
1944void PCB_EDIT_FRAME::SetLastPath( LAST_PATH_TYPE aType, const wxString& aLastPath )
1945{
1947
1948 wxFileName relativeFileName = aLastPath;
1949 wxFileName pcbFileName = GetBoard()->GetFileName();
1950
1951 relativeFileName.MakeRelativeTo( pcbFileName.GetPath() );
1952
1953 if( relativeFileName.GetFullPath() != project.m_PcbLastPath[ aType ] )
1954 {
1955 project.m_PcbLastPath[ aType ] = relativeFileName.GetFullPath();
1956 OnModify();
1957 }
1958}
1959
1960
1962{
1964 Kiway().LocalHistory().NoteFileChange( GetBoard()->GetFileName() );
1965 m_ZoneFillsDirty = true;
1966
1967 if( m_isClosing )
1968 return;
1969
1970 Update3DView( true, GetPcbNewSettings()->m_Display.m_Live3DRefresh );
1971
1972 if( !GetTitle().StartsWith( wxT( "*" ) ) )
1973 UpdateTitle();
1974
1975}
1976
1977
1979{
1980 Update3DView( true, true );
1981
1982 std::shared_ptr<CONNECTIVITY_DATA> connectivity = GetBoard()->GetConnectivity();
1983 connectivity->RecalculateRatsnest( nullptr );
1985
1986 std::vector<MSG_PANEL_ITEM> msg_list;
1987 GetBoard()->GetMsgPanelInfo( this, msg_list );
1988 SetMsgPanel( msg_list );
1989}
1990
1991
1993{
1994 wxFileName fn = GetBoard()->GetFileName();
1995 bool readOnly = false;
1996 bool unsaved = false;
1997
1998 if( fn.IsOk() && fn.FileExists() )
1999 readOnly = !fn.IsFileWritable();
2000 else
2001 unsaved = true;
2002
2003 wxString title;
2004
2005 if( IsContentModified() )
2006 title = wxT( "*" );
2007
2008 title += fn.GetName();
2009
2010 if( readOnly )
2011 title += wxS( " " ) + _( "[Read Only]" );
2012
2013 if( unsaved )
2014 title += wxS( " " ) + _( "[Unsaved]" );
2015
2016 title += wxT( " \u2014 " ) + _( "PCB Editor" );
2017
2018 SetTitle( title );
2019}
2020
2021
2023{
2024 // Update the layer manager and other widgets from the board setup
2025 // (layer and items visibility, colors ...)
2026
2027 // Rebuild list of nets (full ratsnest rebuild)
2029
2030 // Update info shown by the horizontal toolbars
2032
2033 LSET activeLayers = GetBoard()->GetEnabledLayers();
2034
2035 if( !activeLayers.test( GetActiveLayer() ) )
2036 SetActiveLayer( activeLayers.Seq().front() );
2037
2038 m_SelLayerBox->SetLayerSelection( GetActiveLayer() );
2039
2041
2042 layerEnum.Choices().Clear();
2043 layerEnum.Undefined( UNDEFINED_LAYER );
2044
2045 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
2046 {
2047 // Canonical name
2048 layerEnum.Map( layer, LSET::Name( layer ) );
2049
2050 // User name
2051 layerEnum.Map( layer, GetBoard()->GetLayerName( layer ) );
2052 }
2053
2055
2056 // Sync visibility with canvas
2057 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
2058 GetCanvas()->GetView()->SetLayerVisible( layer, GetBoard()->IsLayerVisible( layer ) );
2059
2060 // Stackup and/or color theme may have changed
2061 m_appearancePanel->OnBoardChanged();
2062 m_netInspectorPanel->OnParentSetupChanged();
2063}
2064
2065
2067{
2068 // switches currently used canvas (Cairo / OpenGL).
2069 PCB_BASE_FRAME::SwitchCanvas( aCanvasType );
2070}
2071
2072
2074{
2075 if( !m_findDialog )
2076 {
2077 m_findDialog = new DIALOG_FIND( this );
2078 m_findDialog->SetCallback( std::bind( &PCB_SELECTION_TOOL::FindItem,
2079 m_toolManager->GetTool<PCB_SELECTION_TOOL>(), _1 ) );
2080 }
2081
2082 wxString findString;
2083
2084 PCB_SELECTION& selection = m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
2085
2086 if( selection.Size() == 1 )
2087 {
2088 EDA_ITEM* front = selection.Front();
2089
2090 switch( front->Type() )
2091 {
2092 case PCB_FOOTPRINT_T:
2093 findString = UnescapeString( static_cast<FOOTPRINT*>( front )->GetValue() );
2094 break;
2095
2096 case PCB_FIELD_T:
2097 case PCB_TEXT_T:
2098 findString = UnescapeString( static_cast<PCB_TEXT*>( front )->GetText() );
2099
2100 if( findString.Contains( wxT( "\n" ) ) )
2101 findString = findString.Before( '\n' );
2102
2103 break;
2104
2105 default:
2106 break;
2107 }
2108 }
2109
2110 m_findDialog->Preload( findString );
2111
2112 m_findDialog->Show( true );
2113}
2114
2115
2116void PCB_EDIT_FRAME::FindNext( bool reverse )
2117{
2118 if( !m_findDialog )
2120
2121 m_findDialog->FindNext( reverse );
2122}
2123
2124
2126{
2127 if( Kiface().IsSingle() )
2128 return 0;
2129
2130 // Update PCB requires a netlist. Therefore the schematic editor must be running
2131 // If this is not the case, open the schematic editor
2132 KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH, true );
2133
2134 // If Kiway() cannot create the eeschema frame, it shows a error message, and
2135 // frame is null
2136 if( !frame )
2137 return -1;
2138
2139 if( !frame->IsShownOnScreen() )
2140 {
2141 wxEventBlocker blocker( this );
2142 wxFileName fn( Prj().GetProjectPath(), Prj().GetProjectName(),
2144
2145 // Maybe the file hasn't been converted to the new s-expression file format so
2146 // see if the legacy schematic file is still in play.
2147 if( !fn.FileExists() )
2148 {
2150
2151 if( !fn.FileExists() )
2152 {
2153 DisplayErrorMessage( this, _( "The schematic for this board cannot be found." ) );
2154 return -2;
2155 }
2156 }
2157
2158 frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
2159
2160 // we show the schematic editor frame, because do not show is seen as
2161 // a not yet opened schematic by Kicad manager, which is not the case
2162 frame->Show( true );
2163
2164 // bring ourselves back to the front
2165 Raise();
2166 }
2167
2168 return 1; //Success!
2169}
2170
2171
2173 const wxString& aAnnotateMessage )
2174{
2175 int standalone = TestStandalone();
2176
2177 if( standalone == 0 )
2178 {
2179 DisplayErrorMessage( this, _( "Cannot update the PCB because PCB editor is opened in "
2180 "stand-alone mode. In order to create or update PCBs from "
2181 "schematics, you must launch the KiCad project manager and "
2182 "create a project." ) );
2183 return false; // Not in standalone mode
2184 }
2185
2186 if( standalone < 0 ) // Problem with Eeschema or the schematic
2187 return false;
2188
2189 Raise(); // Show
2190
2191 std::string payload( aAnnotateMessage );
2192
2193 Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_GET_NETLIST, payload, this );
2194
2195 if( payload == aAnnotateMessage )
2196 {
2197 Raise();
2198 DisplayErrorMessage( this, aAnnotateMessage );
2199 return false;
2200 }
2201
2202 try
2203 {
2204 auto lineReader = new STRING_LINE_READER( payload, _( "Eeschema netlist" ) );
2205 KICAD_NETLIST_READER netlistReader( lineReader, &aNetlist );
2206 netlistReader.LoadNetlist();
2207 }
2208 catch( const IO_ERROR& e )
2209 {
2210 Raise();
2211
2212 // Do not translate extra_info strings. These are for developers
2213 wxString extra_info = e.Problem() + wxT( " : " ) + e.What() + wxT( " at " ) + e.Where();
2214
2215 DisplayErrorMessage( this, _( "Received an error while reading netlist. Please "
2216 "report this issue to the KiCad team using the menu "
2217 "Help->Report Bug."), extra_info );
2218 return false;
2219 }
2220
2221 return true;
2222}
2223
2224
2226{
2227 const ENV_VAR_MAP& vars = Pgm().GetLocalEnvVariables();
2228
2229 // Set the environment variables for python scripts
2230 // note: the string will be encoded UTF8 for python env
2231 for( const std::pair<const wxString, ENV_VAR_ITEM>& var : vars )
2232 UpdatePythonEnvVar( var.first, var.second.GetValue() );
2233
2234 // Because the env vars can be modified by the python scripts (rewritten in UTF8),
2235 // regenerate them (in Unicode) for our normal environment
2236 for( const std::pair<const wxString, ENV_VAR_ITEM>& var : vars )
2237 wxSetEnv( var.first, var.second.GetValue() );
2238}
2239
2240
2242{
2243 wxString evValue;
2244 wxGetEnv( PROJECT_VAR_NAME, &evValue );
2245 UpdatePythonEnvVar( wxString( PROJECT_VAR_NAME ).ToStdString(), evValue );
2246
2247 // Because PROJECT_VAR_NAME can be modified by the python scripts (rewritten in UTF8),
2248 // regenerate it (in Unicode) for our normal environment
2249 wxSetEnv( PROJECT_VAR_NAME, evValue );
2250}
2251
2252
2254{
2255 if( aFootprint == nullptr )
2256 return;
2257
2259
2260 /*
2261 * Make sure dlg is destroyed before GetCanvas->Refresh is called
2262 * later or the refresh will try to modify its properties since
2263 * they share a GL context.
2264 */
2265 {
2266 DIALOG_FOOTPRINT_PROPERTIES dlg( this, aFootprint );
2267
2268 dlg.ShowQuasiModal();
2269 retvalue = dlg.GetReturnValue();
2270 }
2271
2272 /*
2273 * retvalue =
2274 * FP_PROPS_UPDATE_FP to show Update Footprints dialog
2275 * FP_PROPS_CHANGE_FP to show Change Footprints dialog
2276 * FP_PROPS_OK for normal edit
2277 * FP_PROPS_CANCEL if aborted
2278 * FP_PROPS_EDIT_BOARD_FP to load board footprint into Footprint Editor
2279 * FP_PROPS_EDIT_LIBRARY_FP to load library footprint into Footprint Editor
2280 */
2281
2283 {
2284 // If something edited, push a refresh request
2285 GetCanvas()->Refresh();
2286 }
2288 {
2289 if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_EDITOR, true ) )
2290 {
2291 FOOTPRINT_EDIT_FRAME* fp_editor = static_cast<FOOTPRINT_EDIT_FRAME*>( frame );
2292
2293 fp_editor->LoadFootprintFromBoard( aFootprint );
2294 fp_editor->Show( true );
2295 fp_editor->Raise(); // Iconize( false );
2296 }
2297 }
2299 {
2300 if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_EDITOR, true ) )
2301 {
2302 FOOTPRINT_EDIT_FRAME* fp_editor = static_cast<FOOTPRINT_EDIT_FRAME*>( frame );
2303
2304 fp_editor->LoadFootprintFromLibrary( aFootprint->GetFPID() );
2305 fp_editor->Show( true );
2306 fp_editor->Raise(); // Iconize( false );
2307 }
2308 }
2310 {
2311 ShowExchangeFootprintsDialog( aFootprint, true, true );
2312 }
2314 {
2315 ShowExchangeFootprintsDialog( aFootprint, false, true );
2316 }
2317}
2318
2319
2321 bool aSelectedMode )
2322{
2323 DIALOG_EXCHANGE_FOOTPRINTS dialog( this, aFootprint, aUpdateMode, aSelectedMode );
2324
2325 return dialog.ShowQuasiModal();
2326}
2327
2328
2340static void processTextItem( const PCB_TEXT& aSrc, PCB_TEXT& aDest,
2341 bool aResetText, bool aResetTextLayers, bool aResetTextEffects,
2342 bool aResetTextPositions, bool* aUpdated )
2343{
2344 if( aResetText )
2345 *aUpdated |= aSrc.GetText() != aDest.GetText();
2346 else
2347 aDest.SetText( aSrc.GetText() );
2348
2349 if( aResetTextLayers )
2350 {
2351 *aUpdated |= aSrc.GetLayer() != aDest.GetLayer();
2352 *aUpdated |= aSrc.IsVisible() != aDest.IsVisible();
2353 }
2354 else
2355 {
2356 aDest.SetLayer( aSrc.GetLayer() );
2357 aDest.SetVisible( aSrc.IsVisible() );
2358 }
2359
2360 VECTOR2I origPos = aDest.GetFPRelativePosition();
2361
2362 if( aResetTextEffects )
2363 {
2364 *aUpdated |= aSrc.GetHorizJustify() != aDest.GetHorizJustify();
2365 *aUpdated |= aSrc.GetVertJustify() != aDest.GetVertJustify();
2366 *aUpdated |= aSrc.GetTextSize() != aDest.GetTextSize();
2367 *aUpdated |= aSrc.GetTextThickness() != aDest.GetTextThickness();
2368 *aUpdated |= aSrc.GetTextAngle() != aDest.GetTextAngle();
2369 }
2370 else
2371 {
2372 aDest.SetAttributes( aSrc );
2373 }
2374
2375 if( aResetTextPositions )
2376 {
2377 *aUpdated |= aSrc.GetFPRelativePosition() != origPos;
2378 aDest.SetFPRelativePosition( origPos );
2379 }
2380 else
2381 {
2383 }
2384
2385 aDest.SetLocked( aSrc.IsLocked() );
2386 const_cast<KIID&>( aDest.m_Uuid ) = aSrc.m_Uuid;
2387}
2388
2389
2390template<typename T>
2391static std::vector<std::pair<T*, T*>> matchItemsBySimilarity( const std::vector<T*>& aExisting,
2392 const std::vector<T*>& aNew )
2393{
2394 struct MATCH_CANDIDATE
2395 {
2396 T* existing;
2397 T* updated;
2398 double score;
2399 };
2400
2401 std::vector<MATCH_CANDIDATE> candidates;
2402
2403 for( T* existing : aExisting )
2404 {
2405 for( T* updated : aNew )
2406 {
2407 if( existing->Type() != updated->Type() )
2408 continue;
2409
2410 double similarity = existing->Similarity( *updated );
2411
2412 if constexpr( std::is_same_v<T, PAD> )
2413 {
2414 if( existing->GetNumber() == updated->GetNumber() )
2415 similarity += 2.0;
2416 }
2417
2418 if( similarity <= 0.0 )
2419 continue;
2420
2421 candidates.push_back( { existing, updated, similarity } );
2422 }
2423 }
2424
2425 std::sort( candidates.begin(), candidates.end(),
2426 []( const MATCH_CANDIDATE& a, const MATCH_CANDIDATE& b )
2427 {
2428 if( a.score != b.score )
2429 return a.score > b.score;
2430
2431 if( a.existing != b.existing )
2432 return a.existing < b.existing;
2433
2434 return a.updated < b.updated;
2435 } );
2436
2437 std::vector<std::pair<T*, T*>> matches;
2438 matches.reserve( candidates.size() );
2439
2440 std::unordered_set<T*> matchedExisting;
2441 std::unordered_set<T*> matchedNew;
2442
2443 for( const MATCH_CANDIDATE& candidate : candidates )
2444 {
2445 if( matchedExisting.find( candidate.existing ) != matchedExisting.end() )
2446 continue;
2447
2448 if( matchedNew.find( candidate.updated ) != matchedNew.end() )
2449 continue;
2450
2451 matchedExisting.insert( candidate.existing );
2452 matchedNew.insert( candidate.updated );
2453 matches.emplace_back( candidate.existing, candidate.updated );
2454 }
2455
2456 return matches;
2457}
2458
2459
2461 BOARD_COMMIT& aCommit,
2462 bool deleteExtraTexts,
2463 bool resetTextLayers,
2464 bool resetTextEffects,
2465 bool resetTextPositions,
2466 bool resetTextContent,
2467 bool resetFabricationAttrs,
2468 bool resetClearanceOverrides,
2469 bool reset3DModels,
2470 bool* aUpdated )
2471{
2472 EDA_GROUP* parentGroup = aExisting->GetParentGroup();
2473 bool dummyBool = false;
2474
2475 if( !aUpdated )
2476 aUpdated = &dummyBool;
2477
2478 if( parentGroup )
2479 {
2480 aCommit.Modify( parentGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
2481 parentGroup->RemoveItem( aExisting );
2482 parentGroup->AddItem( aNew );
2483 }
2484
2485 aNew->SetParent( GetBoard() );
2486
2487 PlaceFootprint( aNew, false, aExisting->GetPosition() );
2488
2489 if( aNew->GetLayer() != aExisting->GetLayer() )
2490 aNew->Flip( aNew->GetPosition(), GetPcbNewSettings()->m_FlipDirection );
2491
2492 if( aNew->GetOrientation() != aExisting->GetOrientation() )
2493 aNew->SetOrientation( aExisting->GetOrientation() );
2494
2495 aNew->SetLocked( aExisting->IsLocked() );
2496
2497 const_cast<KIID&>( aNew->m_Uuid ) = aExisting->m_Uuid;
2498 const_cast<KIID&>( aNew->Reference().m_Uuid ) = aExisting->Reference().m_Uuid;
2499 const_cast<KIID&>( aNew->Value().m_Uuid ) = aExisting->Value().m_Uuid;
2500
2501 std::vector<PAD*> oldPads;
2502 oldPads.reserve( aExisting->Pads().size() );
2503
2504 for( PAD* pad : aExisting->Pads() )
2505 oldPads.push_back( pad );
2506
2507 std::vector<PAD*> newPads;
2508 newPads.reserve( aNew->Pads().size() );
2509
2510 for( PAD* pad : aNew->Pads() )
2511 newPads.push_back( pad );
2512
2513 auto padMatches = matchItemsBySimilarity<PAD>( oldPads, newPads );
2514 std::unordered_set<PAD*> matchedNewPads;
2515
2516 for( const auto& match : padMatches )
2517 {
2518 PAD* oldPad = match.first;
2519 PAD* newPad = match.second;
2520
2521 matchedNewPads.insert( newPad );
2522 const_cast<KIID&>( newPad->m_Uuid ) = oldPad->m_Uuid;
2524 newPad->SetPinFunction( oldPad->GetPinFunction() );
2525 newPad->SetPinType( oldPad->GetPinType() );
2526
2527 if( newPad->IsOnCopperLayer() )
2528 newPad->SetNetCode( oldPad->GetNetCode() );
2529 else
2531 }
2532
2533 for( PAD* newPad : aNew->Pads() )
2534 {
2535 if( matchedNewPads.find( newPad ) != matchedNewPads.end() )
2536 continue;
2537
2538 const_cast<KIID&>( newPad->m_Uuid ) = KIID();
2539 newPad->SetNetCode( NETINFO_LIST::UNCONNECTED );
2540 }
2541
2542 std::vector<BOARD_ITEM*> oldDrawings;
2543 oldDrawings.reserve( aExisting->GraphicalItems().size() );
2544
2545 for( BOARD_ITEM* item : aExisting->GraphicalItems() )
2546 oldDrawings.push_back( item );
2547
2548 std::vector<BOARD_ITEM*> newDrawings;
2549 newDrawings.reserve( aNew->GraphicalItems().size() );
2550
2551 for( BOARD_ITEM* item : aNew->GraphicalItems() )
2552 newDrawings.push_back( item );
2553
2554 auto drawingMatches = matchItemsBySimilarity<BOARD_ITEM>( oldDrawings, newDrawings );
2555 std::unordered_map<BOARD_ITEM*, BOARD_ITEM*> oldToNewDrawings;
2556 std::unordered_set<BOARD_ITEM*> matchedNewDrawings;
2557
2558 for( const auto& match : drawingMatches )
2559 {
2560 BOARD_ITEM* oldItem = match.first;
2561 BOARD_ITEM* newItem = match.second;
2562
2563 oldToNewDrawings[ oldItem ] = newItem;
2564 matchedNewDrawings.insert( newItem );
2565 const_cast<KIID&>( newItem->m_Uuid ) = oldItem->m_Uuid;
2566 }
2567
2568 for( BOARD_ITEM* newItem : newDrawings )
2569 {
2570 if( matchedNewDrawings.find( newItem ) == matchedNewDrawings.end() )
2571 const_cast<KIID&>( newItem->m_Uuid ) = KIID();
2572 }
2573
2574 std::vector<ZONE*> oldZones;
2575 oldZones.reserve( aExisting->Zones().size() );
2576
2577 for( ZONE* zone : aExisting->Zones() )
2578 oldZones.push_back( zone );
2579
2580 std::vector<ZONE*> newZones;
2581 newZones.reserve( aNew->Zones().size() );
2582
2583 for( ZONE* zone : aNew->Zones() )
2584 newZones.push_back( zone );
2585
2586 auto zoneMatches = matchItemsBySimilarity<ZONE>( oldZones, newZones );
2587 std::unordered_set<ZONE*> matchedNewZones;
2588
2589 for( const auto& match : zoneMatches )
2590 {
2591 ZONE* oldZone = match.first;
2592 ZONE* newZone = match.second;
2593
2594 matchedNewZones.insert( newZone );
2595 const_cast<KIID&>( newZone->m_Uuid ) = oldZone->m_Uuid;
2596 }
2597
2598 for( ZONE* newZone : newZones )
2599 {
2600 if( matchedNewZones.find( newZone ) == matchedNewZones.end() )
2601 const_cast<KIID&>( newZone->m_Uuid ) = KIID();
2602 }
2603
2604 std::vector<PCB_POINT*> oldPoints;
2605 oldPoints.reserve( aExisting->Points().size() );
2606
2607 for( PCB_POINT* point : aExisting->Points() )
2608 oldPoints.push_back( point );
2609
2610 std::vector<PCB_POINT*> newPoints;
2611 newPoints.reserve( aNew->Points().size() );
2612
2613 for( PCB_POINT* point : aNew->Points() )
2614 newPoints.push_back( point );
2615
2616 auto pointMatches = matchItemsBySimilarity<PCB_POINT>( oldPoints, newPoints );
2617 std::unordered_set<PCB_POINT*> matchedNewPoints;
2618
2619 for( const auto& match : pointMatches )
2620 {
2621 PCB_POINT* oldPoint = match.first;
2622 PCB_POINT* newPoint = match.second;
2623
2624 matchedNewPoints.insert( newPoint );
2625 const_cast<KIID&>( newPoint->m_Uuid ) = oldPoint->m_Uuid;
2626 }
2627
2628 for( PCB_POINT* newPoint : newPoints )
2629 {
2630 if( matchedNewPoints.find( newPoint ) == matchedNewPoints.end() )
2631 const_cast<KIID&>( newPoint->m_Uuid ) = KIID();
2632 }
2633
2634 std::vector<PCB_GROUP*> oldGroups;
2635 oldGroups.reserve( aExisting->Groups().size() );
2636
2637 for( PCB_GROUP* group : aExisting->Groups() )
2638 oldGroups.push_back( group );
2639
2640 std::vector<PCB_GROUP*> newGroups;
2641 newGroups.reserve( aNew->Groups().size() );
2642
2643 for( PCB_GROUP* group : aNew->Groups() )
2644 newGroups.push_back( group );
2645
2646 auto groupMatches = matchItemsBySimilarity<PCB_GROUP>( oldGroups, newGroups );
2647 std::unordered_set<PCB_GROUP*> matchedNewGroups;
2648
2649 for( const auto& match : groupMatches )
2650 {
2651 PCB_GROUP* oldGroup = match.first;
2652 PCB_GROUP* newGroup = match.second;
2653
2654 matchedNewGroups.insert( newGroup );
2655 const_cast<KIID&>( newGroup->m_Uuid ) = oldGroup->m_Uuid;
2656 }
2657
2658 for( PCB_GROUP* newGroup : newGroups )
2659 {
2660 if( matchedNewGroups.find( newGroup ) == matchedNewGroups.end() )
2661 const_cast<KIID&>( newGroup->m_Uuid ) = KIID();
2662 }
2663
2664 std::vector<PCB_FIELD*> oldFieldsVec;
2665 std::vector<PCB_FIELD*> newFieldsVec;
2666
2667 oldFieldsVec.reserve( aExisting->GetFields().size() );
2668
2669 for( PCB_FIELD* field : aExisting->GetFields() )
2670 {
2671 wxCHECK2( field, continue );
2672
2673 if( field->IsReference() || field->IsValue() )
2674 continue;
2675
2676 oldFieldsVec.push_back( field );
2677 }
2678
2679 newFieldsVec.reserve( aNew->GetFields().size() );
2680
2681 for( PCB_FIELD* field : aNew->GetFields() )
2682 {
2683 wxCHECK2( field, continue );
2684
2685 if( field->IsReference() || field->IsValue() )
2686 continue;
2687
2688 newFieldsVec.push_back( field );
2689 }
2690
2691 auto fieldMatches = matchItemsBySimilarity<PCB_FIELD>( oldFieldsVec, newFieldsVec );
2692 std::unordered_map<PCB_FIELD*, PCB_FIELD*> oldToNewFields;
2693 std::unordered_set<PCB_FIELD*> matchedNewFields;
2694
2695 for( const auto& match : fieldMatches )
2696 {
2697 PCB_FIELD* oldField = match.first;
2698 PCB_FIELD* newField = match.second;
2699
2700 oldToNewFields[ oldField ] = newField;
2701 matchedNewFields.insert( newField );
2702 const_cast<KIID&>( newField->m_Uuid ) = oldField->m_Uuid;
2703 }
2704
2705 for( PCB_FIELD* newField : newFieldsVec )
2706 {
2707 if( matchedNewFields.find( newField ) == matchedNewFields.end() )
2708 const_cast<KIID&>( newField->m_Uuid ) = KIID();
2709 }
2710
2711 std::unordered_map<PCB_TEXT*, PCB_TEXT*> oldToNewTexts;
2712
2713 for( const auto& match : drawingMatches )
2714 {
2715 PCB_TEXT* oldText = dynamic_cast<PCB_TEXT*>( match.first );
2716 PCB_TEXT* newText = dynamic_cast<PCB_TEXT*>( match.second );
2717
2718 if( oldText && newText )
2719 oldToNewTexts[ oldText ] = newText;
2720 }
2721
2722 std::set<PCB_TEXT*> handledTextItems;
2723
2724 for( BOARD_ITEM* oldItem : aExisting->GraphicalItems() )
2725 {
2726 PCB_TEXT* oldTextItem = dynamic_cast<PCB_TEXT*>( oldItem );
2727
2728 if( oldTextItem )
2729 {
2730 // Dimensions have PCB_TEXT base but are not treated like texts in the updater
2731 if( dynamic_cast<PCB_DIMENSION_BASE*>( oldTextItem ) )
2732 continue;
2733
2734 PCB_TEXT* newTextItem = nullptr;
2735
2736 auto textMatchIt = oldToNewTexts.find( oldTextItem );
2737
2738 if( textMatchIt != oldToNewTexts.end() )
2739 newTextItem = textMatchIt->second;
2740
2741 if( newTextItem )
2742 {
2743 handledTextItems.insert( newTextItem );
2744 processTextItem( *oldTextItem, *newTextItem, resetTextContent, resetTextLayers,
2745 resetTextEffects, resetTextPositions, aUpdated );
2746 }
2747 else if( deleteExtraTexts )
2748 {
2749 *aUpdated = true;
2750 }
2751 else
2752 {
2753 newTextItem = static_cast<PCB_TEXT*>( oldTextItem->Clone() );
2754 handledTextItems.insert( newTextItem );
2755 aNew->Add( newTextItem );
2756 }
2757 }
2758 }
2759
2760 // Check for any newly-added text items and set the update flag as appropriate
2761 for( BOARD_ITEM* newItem : aNew->GraphicalItems() )
2762 {
2763 PCB_TEXT* newTextItem = dynamic_cast<PCB_TEXT*>( newItem );
2764
2765 if( newTextItem )
2766 {
2767 // Dimensions have PCB_TEXT base but are not treated like texts in the updater
2768 if( dynamic_cast<PCB_DIMENSION_BASE*>( newTextItem ) )
2769 continue;
2770
2771 if( !handledTextItems.contains( newTextItem ) )
2772 {
2773 *aUpdated = true;
2774 break;
2775 }
2776 }
2777 }
2778
2779 // Copy reference. The initial text is always used, never resetted
2780 processTextItem( aExisting->Reference(), aNew->Reference(), false, resetTextLayers,
2781 resetTextEffects, resetTextPositions, aUpdated );
2782
2783 // Copy value
2784 processTextItem( aExisting->Value(), aNew->Value(),
2785 // reset value text only when it is a proxy for the footprint ID
2786 // (cf replacing value "MountingHole-2.5mm" with "MountingHole-4.0mm")
2787 aExisting->GetValue() == aExisting->GetFPID().GetLibItemName().wx_str(),
2788 resetTextLayers, resetTextEffects, resetTextPositions, aUpdated );
2789
2790 std::set<PCB_FIELD*> handledFields;
2791
2792 // Copy fields in accordance with the reset* flags
2793 for( PCB_FIELD* oldField : aExisting->GetFields() )
2794 {
2795 wxCHECK2( oldField, continue );
2796
2797 // Reference and value are already handled
2798 if( oldField->IsReference() || oldField->IsValue() )
2799 continue;
2800
2801 PCB_FIELD* newField = nullptr;
2802
2803 auto fieldMatchIt = oldToNewFields.find( oldField );
2804
2805 if( fieldMatchIt != oldToNewFields.end() )
2806 newField = fieldMatchIt->second;
2807
2808 if( newField )
2809 {
2810 handledFields.insert( newField );
2811 processTextItem( *oldField, *newField, resetTextContent, resetTextLayers,
2812 resetTextEffects, resetTextPositions, aUpdated );
2813 }
2814 else if( deleteExtraTexts )
2815 {
2816 *aUpdated = true;
2817 }
2818 else
2819 {
2820 newField = new PCB_FIELD( *oldField );
2821 handledFields.insert( newField );
2822 aNew->Add( newField );
2823 }
2824 }
2825
2826 // Check for any newly-added fields and set the update flag as appropriate
2827 for( PCB_FIELD* newField : aNew->GetFields() )
2828 {
2829 wxCHECK2( newField, continue );
2830
2831 // Reference and value are already handled
2832 if( newField->IsReference() || newField->IsValue() )
2833 continue;
2834
2835 if( !handledFields.contains( newField ) )
2836 {
2837 *aUpdated = true;
2838 break;
2839 }
2840 }
2841
2842 if( resetFabricationAttrs )
2843 {
2844 // We've replaced the existing footprint with the library one, so the fabrication attrs
2845 // are already reset. Just set the aUpdated flag if appropriate.
2846 if( aNew->GetAttributes() != aExisting->GetAttributes() )
2847 *aUpdated = true;
2848 }
2849 else
2850 {
2851 aNew->SetAttributes( aExisting->GetAttributes() );
2852 }
2853
2854 if( resetClearanceOverrides )
2855 {
2856 if( aExisting->AllowSolderMaskBridges() != aNew->AllowSolderMaskBridges() )
2857 *aUpdated = true;
2858
2859 if( ( aExisting->GetLocalClearance() != aNew->GetLocalClearance() )
2860 || ( aExisting->GetLocalSolderMaskMargin() != aNew->GetLocalSolderMaskMargin() )
2861 || ( aExisting->GetLocalSolderPasteMargin() != aNew->GetLocalSolderPasteMargin() )
2863 || ( aExisting->GetLocalZoneConnection() != aNew->GetLocalZoneConnection() ) )
2864 {
2865 *aUpdated = true;
2866 }
2867 }
2868 else
2869 {
2870 aNew->SetLocalClearance( aExisting->GetLocalClearance() );
2874 aNew->SetLocalZoneConnection( aExisting->GetLocalZoneConnection() );
2876 }
2877
2878 if( reset3DModels )
2879 {
2880 // We've replaced the existing footprint with the library one, so the 3D models are
2881 // already reset. Just set the aUpdated flag if appropriate.
2882 if( aNew->Models().size() != aExisting->Models().size() )
2883 {
2884 *aUpdated = true;
2885 }
2886 else
2887 {
2888 for( size_t ii = 0; ii < aNew->Models().size(); ++ii )
2889 {
2890 if( aNew->Models()[ii] != aExisting->Models()[ii] )
2891 {
2892 *aUpdated = true;
2893 break;
2894 }
2895 }
2896 }
2897 }
2898 else
2899 {
2900 aNew->Models() = aExisting->Models(); // Linked list of 3D models.
2901 }
2902
2903 // Updating other parameters
2904 aNew->SetPath( aExisting->GetPath() );
2905 aNew->SetSheetfile( aExisting->GetSheetfile() );
2906 aNew->SetSheetname( aExisting->GetSheetname() );
2907 aNew->SetFilters( aExisting->GetFilters() );
2908 aNew->SetStaticComponentClass( aExisting->GetComponentClass() );
2909
2910 if( *aUpdated == false )
2911 {
2912 // Check pad shapes, graphics, zones, etc. for changes
2914 *aUpdated = true;
2915 }
2916
2917 aCommit.Remove( aExisting );
2918 aCommit.Add( aNew );
2919
2920 aNew->ClearFlags();
2921}
2922
2923
2925{
2927
2929
2931
2932 SetElementVisibility( LAYER_RATSNEST, GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest );
2933
2935
2936 // Netclass definitions could have changed, either by us or by Eeschema, so we need to
2937 // recompile the implicit rules
2938 DRC_TOOL* drcTool = m_toolManager->GetTool<DRC_TOOL>();
2939 WX_INFOBAR* infobar = GetInfoBar();
2940
2941 try
2942 {
2944
2945 if( infobar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::DRC_RULES_ERROR )
2946 infobar->Dismiss();
2947 }
2948 catch( PARSE_ERROR& )
2949 {
2950 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _( "Edit design rules" ),
2951 wxEmptyString );
2952
2953 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
2954 [&]( wxHyperlinkEvent& aEvent )
2955 {
2956 ShowBoardSetupDialog( _( "Custom Rules" ) );
2957 } ) );
2958
2959 infobar->RemoveAllButtons();
2960 infobar->AddButton( button );
2961 infobar->AddCloseButton();
2962 infobar->ShowMessage( _( "Could not compile custom design rules." ), wxICON_ERROR,
2964 }
2965
2968
2969 // Update the environment variables in the Python interpreter
2970 if( aFlags & ENVVARS_CHANGED )
2972
2973 Layout();
2974 SendSizeEvent();
2975}
2976
2977
2982
2983
2985{
2987
2988 // Register autosave history saver for the board.
2989 // Saver exports the in-memory BOARD into the history mirror preserving the original
2990 // relative path and file name (reparented under .history) without touching dirty flags.
2991 if( GetBoard() )
2992 {
2994 [this]( const wxString& aProjectPath, std::vector<wxString>& aFiles )
2995 {
2996 GetBoard()->SaveToHistory( aProjectPath, aFiles );
2997 } );
2998 }
2999}
3000
3001
3003{
3004 // For now, be conservative: Don't allow any API use while the user is changing things
3005 if( GetToolManager()->GetCurrentTool() != GetToolManager()->GetTool<PCB_SELECTION_TOOL>() )
3006 return false;
3007
3008 ZONE_FILLER_TOOL* zoneFillerTool = m_toolManager->GetTool<ZONE_FILLER_TOOL>();
3009
3010 if( zoneFillerTool->IsBusy() )
3011 return false;
3012
3013 ROUTER_TOOL* routerTool = m_toolManager->GetTool<ROUTER_TOOL>();
3014
3015 if( routerTool && routerTool->RoutingInProgress() )
3016 return false;
3017
3019}
3020
3021
3022
3024{
3025 return GetBoard()->GetFileName();
3026}
3027
3028
3030{
3031 return m_auimgr.GetPane( wxS( "LayersManager" ) ).IsShown();
3032}
3033
3034
3036{
3037 return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
3038}
3039
3040
3042{
3043 return m_auimgr.GetPane( NetInspectorPanelName() ).IsShown();
3044}
3045
3046
3047void PCB_EDIT_FRAME::onSize( wxSizeEvent& aEvent )
3048{
3049 if( IsShownOnScreen() )
3050 {
3051 // We only need this until the frame is done resizing and the final client size is
3052 // established.
3053 Unbind( wxEVT_SIZE, &PCB_EDIT_FRAME::onSize, this );
3055 }
3056
3057 // Skip() is called in the base class.
3058 EDA_DRAW_FRAME::OnSize( aEvent );
3059}
3060
3061
3072
3073
3084
3085
3096
3097
3099{
3100 if( !m_footprintDiffDlg )
3101 {
3103 _( "Compare Footprint with Library" ) );
3104
3105 m_footprintDiffDlg->m_sdbSizerApply->SetLabel( _( "Update Footprint from Library..." ) );
3106 m_footprintDiffDlg->m_sdbSizerApply->PostSizeEventToParent();
3107 m_footprintDiffDlg->m_sdbSizerApply->Show();
3108 }
3109
3110 return m_footprintDiffDlg;
3111}
3112
3113
3115{
3116 if( m_inspectDrcErrorDlg && aEvent.GetString() == INSPECT_DRC_ERROR_DIALOG_NAME )
3117 {
3118 m_inspectDrcErrorDlg->Destroy();
3119 m_inspectDrcErrorDlg = nullptr;
3120 }
3121 else if( m_inspectClearanceDlg && aEvent.GetString() == INSPECT_CLEARANCE_DIALOG_NAME )
3122 {
3123 m_inspectClearanceDlg->Destroy();
3124 m_inspectClearanceDlg = nullptr;
3125 }
3126 else if( m_inspectConstraintsDlg && aEvent.GetString() == INSPECT_CONSTRAINTS_DIALOG_NAME )
3127 {
3128 m_inspectConstraintsDlg->Destroy();
3129 m_inspectConstraintsDlg = nullptr;
3130 }
3131 else if( m_footprintDiffDlg && aEvent.GetString() == FOOTPRINT_DIFF_DIALOG_NAME )
3132 {
3133 if( aEvent.GetId() == wxID_APPLY )
3134 {
3135 KIID fpUUID = m_footprintDiffDlg->GetUserItemID();
3136
3137 CallAfter(
3138 [this, fpUUID]()
3139 {
3140 BOARD_ITEM* item = m_pcb->ResolveItem( fpUUID );
3141
3142 if( FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( item ) )
3143 {
3144 m_toolManager->RunAction<EDA_ITEM*>( ACTIONS::selectItem, footprint );
3145
3146 DIALOG_EXCHANGE_FOOTPRINTS dialog( this, footprint, true, true );
3147 dialog.ShowQuasiModal();
3148 }
3149 } );
3150 }
3151
3152 m_footprintDiffDlg->Destroy();
3153 m_footprintDiffDlg = nullptr;
3154 }
3155}
3156
3157
3158#ifdef KICAD_IPC_API
3159void PCB_EDIT_FRAME::onPluginAvailabilityChanged( wxCommandEvent& aEvt )
3160{
3161 wxLogTrace( traceApi, "PCB frame: EDA_EVT_PLUGIN_AVAILABILITY_CHANGED" );
3163 aEvt.Skip();
3164}
3165#endif
3166
3167
3169{
3170 PCB_LAYER_ID curLayer = GetActiveLayer();
3171 const PCB_DISPLAY_OPTIONS& displ_opts = GetDisplayOptions();
3172
3173 // Check if the specified layer matches the present layer
3174 if( layer == curLayer )
3175 return;
3176
3177 // Copper layers cannot be selected unconditionally; how many of those layers are currently
3178 // enabled needs to be checked.
3179 if( IsCopperLayer( layer ) )
3180 {
3181 if( layer > GetBoard()->GetCopperLayerStackMaxId() )
3182 return;
3183 }
3184
3185 // Is yet more checking required? E.g. when the layer to be selected is a non-copper layer,
3186 // or when switching between a copper layer and a non-copper layer, or vice-versa?
3187
3188 SetActiveLayer( layer );
3189
3191 GetCanvas()->Refresh();
3192}
3193
3194
3196{
3197 switch( aItem->Type() )
3198 {
3201 break;
3202
3203 case PCB_BARCODE_T:
3204 ShowBarcodePropertiesDialog( static_cast<PCB_BARCODE*>( aItem ) );
3205 break;
3206
3207 case PCB_FIELD_T:
3208 case PCB_TEXT_T:
3209 ShowTextPropertiesDialog( static_cast<PCB_TEXT*>( aItem ) );
3210 break;
3211
3212 case PCB_TEXTBOX_T:
3213 ShowTextBoxPropertiesDialog( static_cast<PCB_TEXTBOX*>( aItem ) );
3214 break;
3215
3216 case PCB_TABLE_T:
3217 {
3218 DIALOG_TABLE_PROPERTIES dlg( this, static_cast<PCB_TABLE*>( aItem ) );
3219
3220 //QuasiModal required for Scintilla auto-complete
3221 dlg.ShowQuasiModal();
3222 break;
3223 }
3224
3225 case PCB_PAD_T:
3226 ShowPadPropertiesDialog( static_cast<PAD*>( aItem ) );
3227 break;
3228
3229 case PCB_FOOTPRINT_T:
3230 ShowFootprintPropertiesDialog( static_cast<FOOTPRINT*>( aItem ) );
3231 break;
3232
3233 case PCB_TARGET_T:
3234 ShowTargetOptionsDialog( static_cast<PCB_TARGET*>( aItem ) );
3235 break;
3236
3237 case PCB_DIM_ALIGNED_T:
3238 case PCB_DIM_CENTER_T:
3239 case PCB_DIM_RADIAL_T:
3241 case PCB_DIM_LEADER_T:
3242 {
3243 DIALOG_DIMENSION_PROPERTIES dlg( this, static_cast<PCB_DIMENSION_BASE*>( aItem ) );
3244
3245 dlg.ShowModal();
3246 break;
3247 }
3248
3249 case PCB_SHAPE_T:
3250 ShowGraphicItemPropertiesDialog( static_cast<PCB_SHAPE*>( aItem ) );
3251 break;
3252
3253 case PCB_ZONE_T:
3254 Edit_Zone_Params( static_cast<ZONE*>( aItem ) );
3255 break;
3256
3257 case PCB_GROUP_T:
3259 static_cast<EDA_GROUP*>( static_cast<PCB_GROUP*>( aItem ) ) );
3260 break;
3261
3262 case PCB_GENERATOR_T:
3263 static_cast<PCB_GENERATOR*>( aItem )->ShowPropertiesDialog( this );
3264 break;
3265
3266 case PCB_MARKER_T:
3267 m_toolManager->GetTool<DRC_TOOL>()->CrossProbe( static_cast<PCB_MARKER*>( aItem ) );
3268 break;
3269
3270 case PCB_POINT_T:
3271 break;
3272
3273 default:
3274 break;
3275 }
3276}
3277
3278
3280{
3281 // For now we just delegate to the base implementation which commits any pending
3282 // local history snapshots. If PCB-specific preconditions are later needed (e.g.
3283 // flushing zone fills or router state) they can be added here before calling the
3284 // base class method.
3286}
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:959
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition board.cpp:1035
void RemoveAllListeners()
Remove all listeners.
Definition board.cpp:3219
const PAGE_INFO & GetPageSettings() const
Definition board.h:799
GAL_SET GetVisibleElements() const
Return a set of all the element categories that are visible.
Definition board.cpp:1029
void InitializeClearanceCache()
Initialize the clearance cache for all board items.
Definition board.cpp:1103
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:192
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:2668
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:202
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:1041
void ClearProject()
Definition board.cpp:240
bool IsEmpty() const
Definition board.cpp:599
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:2173
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition board.cpp:969
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition board.cpp:300
void SynchronizeTuningProfileProperties()
Ensure that all time domain properties providers are in sync with current settings.
Definition board.cpp:2662
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:3670
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:87
bool IsDRCRunning() const
Check to see if the DRC engine is running the tests.
Definition drc_tool.h:74
void SetSheetPath(const std::string &aSheetPath)
Set the sheet path displayed in the title block.
void SetSheetCount(int aSheetCount)
Change the sheet-count number displayed in the title block.
void 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:521
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:149
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:445
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:200
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:398
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:203
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:282
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:423
ZONE_CONNECTION GetLocalZoneConnection() const
Definition footprint.h:399
void SetLocked(bool isLocked) override
Set the #MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition footprint.h:554
EDA_ANGLE GetOrientation() const
Definition footprint.h:330
ZONES & Zones()
Definition footprint.h:312
PCB_POINTS & Points()
Definition footprint.h:318
void SetOrientation(const EDA_ANGLE &aNewAngle)
void SetAllowSolderMaskBridges(bool aAllow)
Definition footprint.h:424
void SetLocalSolderPasteMarginRatio(std::optional< double > aRatio)
Definition footprint.h:396
wxString GetSheetname() const
Definition footprint.h:377
void SetPath(const KIID_PATH &aPath)
Definition footprint.h:375
void SetFilters(const wxString &aFilters)
Definition footprint.h:384
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:418
void SetSheetfile(const wxString &aSheetfile)
Definition footprint.h:381
std::optional< int > GetLocalSolderPasteMargin() const
Definition footprint.h:392
PCB_FIELD & Value()
read/write accessors:
Definition footprint.h:787
std::optional< int > GetLocalClearance() const
Definition footprint.h:386
std::deque< PAD * > & Pads()
Definition footprint.h:306
int GetAttributes() const
Definition footprint.h:417
const COMPONENT_CLASS * GetComponentClass() const
Returns the component class for this footprint.
void SetLocalZoneConnection(ZONE_CONNECTION aType)
Definition footprint.h:398
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition footprint.h:339
wxString GetSheetfile() const
Definition footprint.h:380
const LIB_ID & GetFPID() const
Definition footprint.h:351
bool IsLocked() const override
Definition footprint.h:544
PCB_FIELD & Reference()
Definition footprint.h:788
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:395
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
GROUPS & Groups()
Definition footprint.h:315
wxString GetFilters() const
Definition footprint.h:383
void SetSheetname(const wxString &aSheetname)
Definition footprint.h:378
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:323
const wxString & GetValue() const
Definition footprint.h:773
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition footprint.h:390
void SetLocalClearance(std::optional< int > aClearance)
Definition footprint.h:387
const KIID_PATH & GetPath() const
Definition footprint.h:374
std::optional< int > GetLocalSolderMaskMargin() const
Definition footprint.h:389
void SetLocalSolderPasteMargin(std::optional< int > aMargin)
Definition footprint.h:393
VECTOR2I GetPosition() const override
Definition footprint.h:327
DRAWINGS & GraphicalItems()
Definition footprint.h:309
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:531
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:1696
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:1572
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:1582
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:313
static const LSET & AllLayersMask()
Definition lset.cpp:641
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition lset.cpp:188
@ MARKER_DRAWING_SHEET
Definition marker_base.h:56
Tool responsible for adding microwave features to PCBs.
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition netinfo.h: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:1517
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:781
virtual const wxString & GetExecutablePath() const
Definition pgm_base.cpp:861
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:168
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition project.h:209
void IncrementNetclassesTicker()
Definition project.h:117
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:203
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.