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