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