KiCad PCB EDA Suite
Loading...
Searching...
No Matches
footprint_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) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright (C) 2015-2016 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
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
23#include "tool/embed_tool.h"
24#include "tools/convert_tool.h"
26#include "tools/drawing_tool.h"
27#include "tools/edit_tool.h"
30#include "tools/pad_tool.h"
31#include "tools/pcb_actions.h"
32#include "tools/pcb_control.h"
40#include <bitmaps.h>
45#include <api/api_server.h>
46#include <api/api_utils.h>
47#include <board.h>
49#include <widgets/wx_infobar.h>
50#include <footprint.h>
51#include <confirm.h>
52#include <drc/drc_item.h>
53#include <kidialog.h>
59#include <pcb_painter.h>
60#include <render_settings.h>
61#include <scoped_set_reset.h>
62#include <view/view.h>
63#include <kiface_base.h>
64#include <kiplatform/app.h>
65#include <kiplatform/ui.h>
66#include <kiway.h>
67#include <macros.h>
68#include <pcbnew_id.h>
69#include <pgm_base.h>
70#include <project.h>
71#include <project_pcb.h>
72#include <string_utils.h>
74#include <tool/action_toolbar.h>
75#include <tool/common_control.h>
76#include <tool/common_tools.h>
78#include <tool/selection.h>
81#include <tool/tool_manager.h>
82#include <tool/zoom_tool.h>
83#include <tools/array_tool.h>
91#include <widgets/lib_tree.h>
97#include <wx/app.h>
98
99#include <algorithm>
100
101#include <wx/filedlg.h>
102#include <wx/hyperlink.h>
103#include <wx/log.h>
104
105BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
108
110
113
115
116 // Drop files event
117 EVT_DROP_FILES( FOOTPRINT_EDIT_FRAME::OnDropFiles )
118
119END_EVENT_TABLE()
120
121
122FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
123 PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_FOOTPRINT_EDITOR, _( "Footprint Editor" ), wxDefaultPosition,
126 m_tabsPanel( nullptr ),
127 m_activeTab( nullptr ),
129 m_protectedBorrowedBoard( nullptr ),
131{
132 m_showBorderAndTitleBlock = false; // true to show the frame references
133 m_aboutTitle = _HKI( "KiCad Footprint Editor" );
134 m_editorSettings = nullptr;
135
136 // Give an icon
137 wxIcon icon;
138 wxIconBundle icon_bundle;
139
140 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit, 48 ) );
141 icon_bundle.AddIcon( icon );
142 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit, 128 ) );
143 icon_bundle.AddIcon( icon );
144 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit, 256 ) );
145 icon_bundle.AddIcon( icon );
146 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit_32 ) );
147 icon_bundle.AddIcon( icon );
148 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit_16 ) );
149 icon_bundle.AddIcon( icon );
150
151 SetIcons( icon_bundle );
152
153 // Create GAL canvas
155
156 PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_frameSize,
158 SetCanvas( drawPanel );
159
160 SetBoard( new BOARD() );
161
162 // This board will only be used to hold a footprint for editing
163 GetBoard()->SetBoardUse( BOARD_USE::FPHOLDER );
164
165 // In Footprint Editor, the default net clearance is not known (it depends on the actual
166 // board). So we do not show the default clearance, by setting it to 0. The footprint or
167 // pad specific clearance will be shown.
168 GetBoard()->GetDesignSettings().m_NetSettings->GetDefaultNetclass()->SetClearance( 0 );
169
170 // Don't show the default board solder mask expansion in the footprint editor. Only the
171 // footprint or pad mask expansions settings should be shown.
172 GetBoard()->GetDesignSettings().m_SolderMaskExpansion = 0;
173
174 // Ensure all layers and items are visible:
175 // In footprint editor, some layers have no meaning or cannot be used, but we show all of
176 // them, at least to be able to edit a bad layer
177 GetBoard()->SetVisibleAlls();
178
179 GetGalDisplayOptions().m_axesEnabled = true;
180
181 // In Footprint Editor, set the default paper size to A4 for plot/print
183 SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU( pcbIUScale.IU_PER_MILS ) ) );
184
185 // Create the manager and dispatcher & route draw panel events to the dispatcher
186 setupTools();
188
190 m_treePane = new FOOTPRINT_TREE_PANE( this );
191
195 ReCreateLayerBox( false );
196
198
201
203 m_appearancePanel = new APPEARANCE_CONTROLS( this, GetCanvas(), true );
204 m_propertiesPanel = new PCB_PROPERTIES_PANEL( this, this );
205
206 // LoadSettings() *after* creating m_LayersManager, because LoadSettings() initialize
207 // parameters in m_LayersManager
208 // NOTE: KifaceSettings() will return PCBNEW_SETTINGS if we started from pcbnew
210
212
213 float proportion = GetFootprintEditorSettings()->m_AuiPanels.properties_splitter;
214 m_propertiesPanel->SetSplitterProportion( proportion );
215
217
218 // Fetch a COPY of the config as a lot of these initializations are going to overwrite our data.
220 int libWidth = 0;
221
223 {
224 libWidth = cfg->m_LibWidth;
225 aui_cfg = cfg->m_AuiPanels;
226 }
227 else
228 {
229 // keep gcc quiet about uninitalized vars:
230 aui_cfg.appearance_panel_tab = 0;
231 aui_cfg.right_panel_width = -1;
232 }
233
234 m_auimgr.SetManagedWindow( this );
235
236 // Create the infobar pane only after the AUI manager owns this frame. Registering it before
237 // SetManagedWindow() leaves the Top/Layer-1 pane mispositioned once the tabbed center pane
238 // mounts and the perspective restores, so ShowMessage() never reveals it.
240
241 unsigned int auiFlags = wxAUI_MGR_DEFAULT;
242#if !defined( _WIN32 )
243 // Windows cannot redraw the UI fast enough during a live resize and may lead to all kinds
244 // of graphical glitches
245 auiFlags |= wxAUI_MGR_LIVE_RESIZE;
246#endif
247 m_auimgr.SetFlags( auiFlags );
248
249 // Rows; layers 4 - 6
250 m_auimgr.AddPane( m_tbTopMain, EDA_PANE().HToolbar().Name( "TopMainToolbar" )
251 .Top().Layer( 6 ) );
252
253 m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( "MsgPanel" )
254 .Bottom().Layer( 6 ) );
255
256 // Columns; layers 1 - 3
257 m_auimgr.AddPane( m_treePane, EDA_PANE().Palette().Name( "Footprints" )
258 .Left().Layer( 4 )
259 .Caption( _( "Libraries" ) )
260 // Don't use -1 for don't-change-height on a growable panel; it has side-effects.
261 .MinSize( FromDIP( 250 ), FromDIP( 80 ) )
262 .BestSize( FromDIP( 250 ), -1 ) );
264 .Left().Layer( 3 )
265 .Caption( _( "Properties" ) ).PaneBorder( false )
266 .MinSize( FromDIP( wxSize( 240, 60 ) ) ).BestSize( FromDIP( wxSize( 300, 200 ) ) ) );
267 m_auimgr.AddPane( m_tbLeft, EDA_PANE().VToolbar().Name( "LeftToolbar" )
268 .Left().Layer( 2 ) );
269
270 m_auimgr.AddPane( m_tbRight, EDA_PANE().VToolbar().Name( "RightToolbar" )
271 .Right().Layer(2) );
272 m_auimgr.AddPane( m_appearancePanel, EDA_PANE().Name( "LayersManager" )
273 .Right().Layer( 3 )
274 .Caption( _( "Appearance" ) ).PaneBorder( false )
275 // Don't use -1 for don't-change-height on a growable panel; it has side-effects.
276 .MinSize( FromDIP( 180 ), FromDIP( 80 ) )
277 .BestSize( FromDIP( 180 ), -1 ) );
278 m_auimgr.AddPane( m_selectionFilterPanel, EDA_PANE().Palette().Name( "SelectionFilter" )
279 .Right().Layer( 3 ).Position( 2 )
280 .Caption( _( "Selection Filter" ) ).PaneBorder( false )
281 // Fixed-size pane; -1 for MinSize height is required
282 .MinSize( FromDIP( 180 ), -1 )
283 .BestSize( FromDIP( 180 ), -1 ) );
284
285 // Center: the tabbed-document strip owns the tab bar above a single, never-reparented canvas.
286 // The panel borrows the canvas; the frame keeps ownership through GetCanvas().
287 m_tabsPanel = new EDITOR_TABS_PANEL( this, GetCanvas() );
288
289 m_tabsPanel->onActivateTab =
290 [this]( int aIdx )
291 {
292 // Ignore activation during a full clear, when each tab close re-selects a fallback
293 // that would re-borrow a tab-owned board into m_pcb just before it is freed.
295 return;
296
297 if( aIdx >= 0 && aIdx < static_cast<int>( m_tabContexts.size() ) )
298 activateFootprintTab( m_tabContexts[aIdx].get() );
299 };
300
301 m_tabsPanel->onCloseTabRequested =
302 [this]( int aIdx ) -> bool
303 {
304 return promptAndCloseFootprintTab( aIdx );
305 };
306
307 // onCloseTabRequested installs the successor board atomically, so the panel must not re-activate
308 // the fallback after a close and re-borrow a just-installed or just-freed index.
309 m_tabsPanel->SetSuppressActivateOnClose( true );
310
311 m_tabsPanel->onQueryVisualState =
312 [this]( int aIdx ) -> TAB_VISUAL_STATE
313 {
314 // The panel model owns preview, but the live dirty flag lives on the shared frame
315 // screen folded into the context, so read modified from the context.
316 const std::vector<EDITOR_TABS_MODEL::ENTRY>& entries = m_tabsPanel->Model().Entries();
317
318 if( aIdx < 0 || aIdx >= static_cast<int>( entries.size() ) )
319 return TAB_VISUAL_STATE{};
320
321 bool modified = entries[aIdx].modified;
322
323 if( aIdx < (int) m_tabContexts.size() && m_tabContexts[aIdx].get() )
324 modified = m_tabContexts[aIdx]->IsModified();
325
326 return ResolveTabVisualState( entries[aIdx].preview, modified );
327 };
328
329 m_auimgr.AddPane( m_tabsPanel, EDA_PANE().Canvas().Name( "DrawFrame" )
330 .Center() );
331
333
334 m_auimgr.GetPane( "LayersManager" ).Show( m_show_layer_manager_tools );
335 m_auimgr.GetPane( "SelectionFilter" ).Show( m_show_layer_manager_tools );
336 m_auimgr.GetPane( PropertiesPaneName() ).Show( GetSettings()->m_AuiPanels.show_properties );
337
338 wxAuiPaneInfo& selectionFilterPane = m_auimgr.GetPane( wxS( "SelectionFilter" ) );
339
340 // The selection filter doesn't need to grow in the vertical direction when docked
341 selectionFilterPane.dock_proportion = 0;
342
343 // wx 3.3.3 turns a -1 min height into 1, and a legacy perspective restores one
344 selectionFilterPane.min_size.y = m_selectionFilterPanel->GetBestSize().y;
345
348 DragAcceptFiles( true );
349
351
352 // Apply saved visibility stuff at the end
353 wxAuiPaneInfo& treePane = m_auimgr.GetPane( "Footprints" );
354 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
355
356 if( libWidth > 0 )
357 SetAuiPaneSize( m_auimgr, treePane, libWidth, -1 );
358
359 if( aui_cfg.right_panel_width > 0 )
360 SetAuiPaneSize( m_auimgr, layersManager, aui_cfg.right_panel_width, -1 );
361
362 m_appearancePanel->SetTabIndex( aui_cfg.appearance_panel_tab );
363
365 {
366 m_appearancePanel->SetUserLayerPresets( cfg->m_LayerPresets );
367 m_appearancePanel->ApplyLayerPreset( cfg->m_ActiveLayerPreset );
368 }
369
370 // restore the last footprint from the project, if any, after the library has been init'ed
371 // N.B. This needs to happen after the AUI manager has been initialized so that we can
372 // properly call the WX_INFOBAR without crashing on some systems.
374
375 m_apiHandler = std::make_unique<API_HANDLER_FOOTPRINT>( this );
377
378 if( Kiface().IsSingle() )
379 {
380 m_apiHandlerCommon = std::make_unique<API_HANDLER_COMMON>();
382 m_apiHandlerFpLibs = std::make_unique<API_HANDLER_LIBRARIES>(
385 }
386
387 GetToolManager()->PostAction( ACTIONS::zoomFitScreen );
389
391
392 // This displays the last footprint loaded, if any, so it must be done after restoreLastFootprint()
394
395 // Default shutdown reason until a file is loaded
396 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "Footprint changes are unsaved" ) );
397
398 // Catch unhandled accelerator command characters that were no handled by the library tree
399 // panel.
401 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
402
403 // GTK rejects WXK_TAB as a menu accelerator, so handle Ctrl+Tab cycling from the CHAR_HOOK
404 // stream. Binding after the dispatcher runs this handler first so it can consume the event.
405 Bind( wxEVT_CHAR_HOOK, &FOOTPRINT_EDIT_FRAME::OnTabCharHook, this );
406
407 // Ensure the window is on top
408 Raise();
409 Show( true );
410
411 // Register a call to update the toolbar sizes. It can't be done immediately because
412 // it seems to require some sizes calculated that aren't yet (at least on GTK).
413 CallAfter(
414 [this]()
415 {
416 // Ensure the controls on the toolbars all are correctly sized
418 m_treePane->FocusSearchFieldIfExists();
419
420 // Update the angle snap mode toolbar button to reflect the current preference
422 } );
423}
424
425
427{
429
430 if( Kiface().IsSingle() )
431 {
434 }
435
436 // Hand the borrowed canvas back before the base destructor deletes it, or the later-destroyed
437 // panel would reparent already-freed memory. The canvas then frees exactly once.
438 m_tabsPanel->ReleaseSharedCanvas();
439
440 // Shutdown all running tools
441 if( m_toolManager )
442 m_toolManager->ShutdownAllTools();
443
444 // save the footprint in the PROJECT
446
447 // Clear the watched file
448 setFPWatcher( nullptr );
449
450 // When a tab context owns the active board, null the frame pointer so the base destructor does
451 // not double-free it. A frame-owned bootstrap board is left for the base class to delete.
453 m_pcb = nullptr;
454
455 // We passed ownership of these to wxAuiManager.
456 // delete m_selectionFilterPanel;
457 // delete m_appearancePanel;
458 // delete m_treePane;
459}
460
461
463{
465
466 FOOTPRINT* fp = static_cast<FOOTPRINT*>( GetModel() );
467
468 if( fp )
469 {
470 std::vector<MSG_PANEL_ITEM> msgItems;
471 fp->GetMsgPanelInfo( this, msgItems );
472 SetMsgPanel( msgItems );
473 }
474}
475
476
483
484
486{
487 return m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
488}
489
490
492{
493 // switches currently used canvas (Cairo / OpenGL).
494 PCB_BASE_FRAME::SwitchCanvas( aCanvasType );
495
496 GetCanvas()->GetGAL()->SetAxesEnabled( true );
497
498 // The base class method *does not reinit* the layers manager. We must update the layer
499 // widget to match board visibility states, both layers and render columns, and and some
500 // settings dependent on the canvas.
502}
503
504
510
511
513{
514 wxAuiPaneInfo& treePane = m_auimgr.GetPane( m_treePane );
515 treePane.Show( !IsLibraryTreeShown() );
516
517 if( IsLibraryTreeShown() )
518 {
519 // SetAuiPaneSize also updates m_auimgr
520 SetAuiPaneSize( m_auimgr, treePane, m_editorSettings->m_LibWidth, -1 );
521 }
522 else
523 {
524 m_editorSettings->m_LibWidth = m_treePane->GetSize().x;
525 m_auimgr.Update();
526 }
527}
528
529
531{
532 m_treePane->FocusSearchFieldIfExists();
533}
534
535
537{
539 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
540 wxAuiPaneInfo& selectionFilter = m_auimgr.GetPane( "SelectionFilter" );
541
542 // show auxiliary Vertical layers and visibility manager toolbar
544 layersManager.Show( m_show_layer_manager_tools );
545 selectionFilter.Show( m_show_layer_manager_tools );
546
548 {
549 SetAuiPaneSize( m_auimgr, layersManager, settings->m_AuiPanels.right_panel_width, -1 );
550 }
551 else
552 {
553 settings->m_AuiPanels.right_panel_width = m_appearancePanel->GetSize().x;
554 m_auimgr.Update();
555 }
556}
557
558
560{
561 return const_cast<wxAuiManager&>( m_auimgr ).GetPane( m_treePane ).IsShown();
562}
563
564
566{
567 // A tab close transiently leaves the frame with no board while UI repaints can still run.
568 if( !GetBoard() )
569 return nullptr;
570
571 return GetBoard()->GetFirstFootprint();
572}
573
574
576{
577 LIB_ID id;
578
579 if( IsLibraryTreeShown() )
581
582 if( id.GetLibNickname().empty() )
583 id = GetLoadedFPID();
584
585 return id;
586}
587
588
590{
591 // The board pointer is transiently null during a tab close while the library tree adapter can
592 // still repaint, so tolerate having no board.
593 if( !GetBoard() )
594 return LIB_ID();
595
596 FOOTPRINT* footprint = GetBoard()->GetFirstFootprint();
597
598 if( footprint )
599 return LIB_ID( footprint->GetFPID().GetLibNickname(), m_footprintNameWhenLoaded );
600 else
601 return LIB_ID();
602}
603
604
606{
607 if( GetBoard() && GetBoard()->GetFirstFootprint() )
608 {
611 }
612
613 GetScreen()->SetContentModified( false );
614
615 // OnModify() mirrors the dirty flag onto the active tab context and the panel model, so clear both
616 // here too. Tab rendering and close prompting read the context's flag, so a save that only cleared
617 // the shared screen would leave the tab starred and re-prompting to save.
618 if( m_activeTab )
619 {
620 m_activeTab->SetModified( false );
621
622 if( int idx = m_tabsPanel->FindTab( m_activeTab->GetTabKey() ); idx >= 0 )
623 m_tabsPanel->MarkModified( idx, false );
624 }
625}
626
627
629{
630 // If we've already vetted closing this window, then we have no FP anymore
631 if( m_isClosing || !GetBoard() )
632 return false;
633
634 FOOTPRINT* footprint = GetBoard()->GetFirstFootprint();
635
636 return ( footprint && footprint->GetLink() != niluuid );
637}
638
639
641{
642 LIB_ID id = GetLoadedFPID();
643
644 if( id.IsValid() )
645 {
647 Prj().SetRString( PROJECT::PCB_FOOTPRINT_EDITOR_FP_NAME, id.GetLibItemName() );
648 }
649}
650
651
653{
654 // Restore the persisted tab set first. The active tab is loaded last so it ends up focused, and
655 // tabs that no longer resolve are silently dropped.
656 if( FOOTPRINT_EDITOR_SETTINGS* cfg = GetSettings(); cfg && !cfg->m_OpenTabs.empty() )
657 {
658 const wxString activeKey = cfg->m_ActiveTab;
659
660 const auto loadTab =
661 [this]( const FOOTPRINT_EDITOR_SETTINGS::OPEN_TAB& aTab ) -> bool
662 {
663 LIB_ID id;
664 id.SetLibNickname( aTab.m_lib );
665 id.SetLibItemName( aTab.m_fpName );
666
667 if( FOOTPRINT* footprint = LoadFootprint( id ) )
668 {
669 AddFootprintToBoard( footprint );
670 findOrCreateFootprintTab( id, aTab.m_preview );
671
672 return true;
673 }
674
675 // LoadFootprint swallows the IO_ERROR when the library no longer resolves, so
676 // log the dropped tab to keep a failed restore diagnosable.
677 wxLogTrace( wxT( "KICAD_FP_TABS" ),
678 wxT( "Dropping persisted footprint tab '%s:%s' (failed to load)" ),
679 aTab.m_lib, aTab.m_fpName );
680
681 return false;
682 };
683
684 const FOOTPRINT_EDITOR_SETTINGS::OPEN_TAB* activeTab = nullptr;
685
686 for( const FOOTPRINT_EDITOR_SETTINGS::OPEN_TAB& tab : cfg->m_OpenTabs )
687 {
688 const wxString key = tab.m_lib + wxT( ":" ) + tab.m_fpName;
689
690 if( key == activeKey )
691 activeTab = &tab;
692 else
693 loadTab( tab );
694 }
695
696 if( activeTab )
697 loadTab( *activeTab );
698
699 if( !m_tabContexts.empty() )
700 return;
701 }
702
703 const wxString& footprintName = Prj().GetRString( PROJECT::PCB_FOOTPRINT_EDITOR_FP_NAME );
704 const wxString& libNickname = Prj().GetRString( PROJECT::PCB_FOOTPRINT_EDITOR_LIB_NICKNAME );
705
706 if( libNickname.Length() && footprintName.Length() )
707 {
708 LIB_ID id;
709 id.SetLibNickname( libNickname );
710 id.SetLibItemName( footprintName );
711
712 FOOTPRINT* footprint = LoadFootprint( id );
713
714 if( footprint )
715 {
716 AddFootprintToBoard( footprint );
717
718 // The last-session footprint is a real document, so promote its tab to permanent.
719 findOrCreateFootprintTab( id, false );
720 }
721 }
722}
723
724
726{
727 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( GetModel() );
728 BOARD& board = *GetBoard();
729
730 // All FPs have these layers enabled
731 LSET enabledLayers = LSET::AllTechMask() | LSET::UserMask();
732
733 const auto configureStackup =
734 [&]( FOOTPRINT_STACKUP aMode, const LSET& aLayerSet )
735 {
736 const LSET cuLayers = aLayerSet & LSET::AllCuMask();
737 board.SetCopperLayerCount( cuLayers.count() );
738
739 switch( aMode )
740 {
742 enabledLayers |= LSET{ F_Cu, In1_Cu, B_Cu };
743 board.SetLayerName( In1_Cu, _( "Inner layers" ) );
744 break;
745
747 // Nothing extra to add
748
749 // Clear layer name defaults
750 board.SetLayerName( In1_Cu, wxEmptyString );
751 break;
752 }
753
754 enabledLayers |= aLayerSet;
755 };
756
757 if( footprint )
758 {
759 configureStackup( footprint->GetStackupMode(), footprint->GetStackupLayers() );
760 }
761 else
762 {
763 // If no footprint is loaded, we assume the default stackup mode
764 configureStackup( FOOTPRINT_STACKUP::EXPAND_INNER_LAYERS, LSET{} );
765 }
766
768 {
769 m_originalFootprintCopy->RunOnChildren(
770 [&]( BOARD_ITEM* child )
771 {
772 LSET childLayers = child->GetLayerSet() & LSET::UserDefinedLayersMask();
773
774 for( PCB_LAYER_ID layer : childLayers )
775 enabledLayers.set( layer );
776 },
778 }
779
780 // Enable the user-configured number of user layers, plus any specifically named layers
782 {
783 int userLayerCount = cfg->m_DesignSettings.GetUserDefinedLayerCount();
784 enabledLayers |= LSET::UserDefinedLayersMask( userLayerCount );
785
786 for( const PCB_LAYER_ID& user : LSET::UserDefinedLayersMask() )
787 {
788 if( cfg->m_DesignSettings.m_UserLayerNames.contains( LSET::Name( user ).ToStdString() ) )
789 enabledLayers.set( user );
790 }
791 }
792
793 board.SetEnabledLayers( enabledLayers );
794
795 // Footprint Editor layer visibility is kept in the view, not the board (because the board
796 // just delegates to the project file, which we don't have).
797 for( const PCB_LAYER_ID& layer : GetBoard()->GetEnabledLayers() )
798 GetCanvas()->GetView()->SetLayerVisible( layer, true );
799}
800
801
803{
804 // Use CallAfter so that we update the canvas before waiting for the infobar animation
805 CallAfter(
806 [this]()
807 {
808 WX_INFOBAR& infobar = *GetInfoBar();
809 infobar.RemoveAllButtons();
810
811 wxArrayString msgs;
812 int infobarFlags = wxICON_INFORMATION;
813 FOOTPRINT* footprint = GetBoard() ? GetBoard()->GetFirstFootprint() : nullptr;
814 wxString lib = footprint ? footprint->GetFPID().GetLibNickname() : UTF8();
815
817 {
818 msgs.push_back( wxString::Format( _( "Editing %s from board. Saving will update the board only." ),
819 footprint->GetReference() ) );
820
821 infobar.AddLink( wxString::Format( _( "Open footprint from library %s" ), UnescapeString( lib ) ),
822 [this]( wxHyperlinkEvent& aEvent )
823 {
825 } );
826 }
827
828 if( footprint
830 && !PROJECT_PCB::FootprintLibAdapter( &Prj() )->IsFootprintLibWritable( lib ) )
831 {
832 msgs.push_back( _( "Library is read-only. Changes cannot be saved to this library." ) );
833
834 infobar.AddLink( _( "Save as editable copy" ),
835 [this]( wxHyperlinkEvent& aEvent )
836 {
837 SaveFootprintAs( GetBoard()->GetFirstFootprint() );
838 GetCanvas()->GetView()->Update( GetBoard()->GetFirstFootprint() );
839 ClearModify();
840
841 // Get rid of the save-will-update-board-only (or any other dismissable warning)
842 WX_INFOBAR* local_infobar = GetInfoBar();
843
844 if( local_infobar->IsShownOnScreen() && local_infobar->HasCloseButton() )
845 local_infobar->Dismiss();
846
848 SyncLibraryTree( true );
849 } );
850 }
851
852 if( msgs.empty() )
853 {
854 infobar.Dismiss();
855 }
856 else
857 {
858 wxString msg = wxJoin( msgs, '\n', '\0' );
859 infobar.AddCloseButton();
860 infobar.ShowMessage( msg, infobarFlags );
861 }
862 } );
863}
864
865
867{
868 // Cancel a mid-draw tool before the footprint it points into is freed (#24975).
869 if( GetToolManager() )
871
873
874 m_originalFootprintCopy.reset( static_cast<FOOTPRINT*>( aFootprint->Clone() ) );
875 m_originalFootprintCopy->SetParent( nullptr );
876
878
879 // Mirror the load baseline into the active tab context so it survives a tab switch (the frame
880 // members are only a borrowed view of the active context's baseline).
881 if( m_activeTab )
882 {
883 FOOTPRINT* fp_copy = nullptr;
884
886 fp_copy = static_cast<FOOTPRINT*>( m_originalFootprintCopy->Clone() );
887
888 m_activeTab->SetOriginalFootprintCopy( std::unique_ptr<FOOTPRINT>( fp_copy ) );
889 m_activeTab->SetFootprintNameWhenLoaded( m_footprintNameWhenLoaded );
890 m_activeTab->SetLibNickname( aFootprint->GetFPID().GetLibNickname() );
891 m_activeTab->SetFootprintName( aFootprint->GetFPID().GetLibItemName() );
892 }
893
895 // Ensure item UUIDs are valid
896 // ("old" footprints can have null uuids that create issues in fp editor)
897 aFootprint->FixUuids();
898
903}
904
905
907{
908 const bool fromBoard = aFootprint && aFootprint->GetLink() != niluuid;
909
910 if( !aHasTabs || !aFootprint || fromBoard || !aFootprint->GetFPID().IsValid() )
911 return false;
912
913 // A new footprint is parented to the board the tab switch is about to free, so drop the parent
914 // before the switch; ReloadFootprint reparents it to the incoming board
915 aFootprint->SetParent( nullptr );
916
917 return true;
918}
919
920
922{
923 ReloadFootprint( aFootprint );
924
926 setFPWatcher( nullptr );
927 else
928 setFPWatcher( aFootprint );
929}
930
931
933{
934 // Opening from the library is a preview that the next library-open reuses; editing promotes it
935 // to a permanent tab.
936 if( prepareFootprintTabHandoff( aFootprint, m_tabsPanel != nullptr ) )
937 findOrCreateFootprintTab( aFootprint->GetFPID(), true );
938
939 installFootprintOnActiveBoard( aFootprint );
940}
941
942
944{
946 return true;
947
948 return std::any_of( m_tabContexts.begin(), m_tabContexts.end(),
949 [this]( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& aCtx )
950 {
951 return aCtx->GetBoard() == m_pcb;
952 } );
953}
954
955
957{
958 // Swap the board pointer without the SetBoard delete, since on a tab switch the outgoing board
959 // is owned by its tab context. Reproduce only the side effects SetBoard applies to the incoming
960 // board.
961 if( m_pcb == aBoard )
962 return;
963
964 // The only frame-owned board is the constructor's bootstrap board. Delete it when we first
965 // switch away so it does not leak; tab-owned boards are left to their contexts.
966 if( m_pcb && !activeBoardOwnedByTab() )
967 delete m_pcb;
968
969 m_pcb = aBoard;
970
971 if( GetBoard() )
973
974 if( GetBoard() && GetCanvas() )
975 {
976 if( KIGFX::RENDER_SETTINGS* rs = GetCanvas()->GetView()->GetPainter()->GetSettings() )
977 {
978 rs->SetDashLengthRatio( GetBoard()->GetPlotOptions().GetDashedLineDashRatio() );
979 rs->SetGapLengthRatio( GetBoard()->GetPlotOptions().GetDashedLineGapRatio() );
980 }
981
983 }
984
985 wxCommandEvent e( EDA_EVT_BOARD_CHANGED );
986 ProcessEventLocally( e );
987}
988
989
991{
992 if( !m_activeTab )
993 return;
994
995 KIGFX::VIEW* view = GetCanvas()->GetView();
996
997 EDITOR_TAB_CONTEXT::VIEW_SNAPSHOT& snap = m_activeTab->ViewSnapshot();
998 snap.scale = view->GetScale();
999 snap.center = view->GetCenter();
1000 snap.valid = true;
1001
1002 std::vector<KIID>& sel = m_activeTab->SavedSelection();
1003 sel.clear();
1004
1005 for( EDA_ITEM* item : GetCurrentSelection() )
1006 sel.push_back( item->m_Uuid );
1007
1008 // Dirty state lives on the shared frame screen, so fold it into the context to survive the switch.
1009 if( GetScreen() )
1010 m_activeTab->SetModified( GetScreen()->IsContentModified() );
1011
1012 // Swap the raw vectors since UNDO_REDO_CONTAINER is non-copyable; ownership transfers intact.
1013 m_activeTab->UndoList().m_CommandsList.swap( m_undoList.m_CommandsList );
1014 m_activeTab->RedoList().m_CommandsList.swap( m_redoList.m_CommandsList );
1015
1016 m_activeTab = nullptr;
1017}
1018
1019
1021{
1022 if( !aCtx || aCtx == m_activeTab )
1023 return;
1024
1025 installFootprintTabBoard( aCtx, aCtx->GetBoard() );
1026}
1027
1028
1030{
1031 // Install the successor board and tool environment before the caller frees the outgoing context
1032 // so no tool Reset() or repaint ever sees a freed or null m_pcb. Never calls the base SetBoard,
1033 // which would delete m_pcb and reset tools while the model still aliases it.
1034
1036
1037 // Drop selection and unwind a mid-draw tool while the outgoing board is still valid (#24975).
1038 if( m_toolManager )
1039 {
1041 m_toolManager->DeactivateTool();
1042 }
1043
1044 m_activeTab = aCtx;
1045
1046 borrowBoardNonDestructive( aBoard );
1047
1048 if( aCtx )
1049 {
1050 m_undoList.m_CommandsList.swap( aCtx->UndoList().m_CommandsList );
1051 m_redoList.m_CommandsList.swap( aCtx->RedoList().m_CommandsList );
1052 }
1053 else
1054 {
1055 // Discard the swapped-in lists with their transient items so nothing references a freed board.
1057 }
1058
1060 ? static_cast<FOOTPRINT*>( aCtx->GetOriginalFootprintCopy()->Clone() )
1061 : nullptr );
1062 m_footprintNameWhenLoaded = aCtx ? aCtx->GetFootprintNameWhenLoaded() : wxString();
1063
1064 // Mirror the incoming tab's board-uuid remap onto the frame so SaveFootprintToBoard saves an
1065 // instance edit back to the originating board items. A library tab has an empty map.
1066 if( aCtx )
1068 else
1069 m_boardFootprintUuids.clear();
1070
1071 if( GetScreen() )
1072 GetScreen()->SetContentModified( aCtx ? aCtx->IsModified() : false );
1073
1074 // Point the tool environment at the incoming board before ResetTools so tools never dereference
1075 // a freed model.
1076 m_toolManager->SetEnvironment( GetBoard(), GetCanvas()->GetView(), GetCanvas()->GetViewControls(), config(),
1077 this );
1078
1081
1083
1084 if( !aCtx )
1085 {
1087 updateInfoBar();
1091 return;
1092 }
1093
1094 const EDITOR_TAB_CONTEXT::VIEW_SNAPSHOT& snap = aCtx->ViewSnapshot();
1095
1096 if( snap.valid )
1097 {
1098 GetCanvas()->GetView()->SetScale( snap.scale );
1099 GetCanvas()->GetView()->SetCenter( snap.center );
1100 }
1101 else
1102 {
1103 // First time this tab is shown there is no saved view
1105 }
1106
1107 if( !aCtx->SavedSelection().empty() )
1108 {
1110
1111 if( selTool )
1112 {
1113 for( const KIID& id : aCtx->SavedSelection() )
1114 {
1115 if( BOARD_ITEM* item = GetBoard()->ResolveItem( id, true ) )
1116 selTool->select( item );
1117 }
1118 }
1119 }
1120
1121 if( m_appearancePanel )
1122 m_appearancePanel->OnBoardChanged();
1123
1124 if( m_propertiesPanel )
1125 m_propertiesPanel->UpdateData();
1126
1128 updateInfoBar();
1132}
1133
1134
1135static std::unique_ptr<BOARD> makeFpHolderBoard( FOOTPRINT_EDITOR_SETTINGS* aCfg )
1136{
1137 auto board = std::make_unique<BOARD>();
1138 board->SetBoardUse( BOARD_USE::FPHOLDER );
1139 board->GetDesignSettings().m_NetSettings->GetDefaultNetclass()->SetClearance( 0 );
1140 board->GetDesignSettings().m_SolderMaskExpansion = 0;
1141 board->SetVisibleAlls();
1142
1143 // Get our own settings; aCfg will be the PCBNEW_SETTINGS because we're part of the pcbnew
1144 // compile unit
1145 if( aCfg )
1146 {
1147 board->GetDesignSettings() = aCfg->m_DesignSettings;
1148
1149 for( auto& [source_name, dest_name] : aCfg->m_DesignSettings.m_UserLayerNames )
1150 {
1151 wxString wx_source_name = source_name;
1152 PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( LSET::NameToLayer( wx_source_name ) );
1153
1154 if( IsUserLayer( layer ) )
1155 board->SetLayerName( layer, dest_name );
1156 }
1157 }
1158
1159 return board;
1160}
1161
1162
1164{
1165 const wxString lib = aLibId.GetLibNickname();
1166 const wxString name = aLibId.GetLibItemName();
1167 const wxString key = lib + wxT( ":" ) + name;
1168
1169 if( int existing = m_tabsPanel->FindTab( key ); existing >= 0 )
1170 {
1171 m_tabsPanel->AddTab( key, name, aAsPreview );
1172 return m_tabContexts[existing].get();
1173 }
1174
1175 auto ctx = std::make_unique<FOOTPRINT_EDITOR_TAB_CONTEXT>( lib, name, makeFpHolderBoard( GetSettings() ) );
1176 ctx->SetPreview( aAsPreview );
1177
1178 FOOTPRINT_EDITOR_TAB_CONTEXT* raw = ctx.get();
1179
1180 // Keep m_tabContexts index-aligned with the panel model. A previewed open reuses the preview
1181 // slot in place; otherwise the context is appended. It must be at its final index before AddTab
1182 // fires onActivateTab.
1183 const int reuseSlot = aAsPreview ? m_tabsPanel->Model().PreviewIndex() : -1;
1184
1185 if( reuseSlot >= 0 && reuseSlot < static_cast<int>( m_tabContexts.size() ) )
1186 {
1187 // Tear the active document down while the outgoing board is still alive, before it is
1188 // displaced and freed.
1189 if( m_tabContexts[reuseSlot].get() == m_activeTab )
1190 {
1191 if( m_toolManager )
1193
1195 m_activeTab = nullptr;
1196 }
1197
1198 return placeReusedTabContext( m_tabContexts, reuseSlot, std::move( ctx ),
1199 [&]( const FOOTPRINT_EDITOR_TAB_CONTEXT& aDisplaced )
1200 {
1201 SCOPED_SET_RESET<BOARD*> protectedBoard( m_protectedBorrowedBoard, aDisplaced.GetBoard() );
1202 m_tabsPanel->AddTab( key, name, aAsPreview );
1203 } );
1204 }
1205
1206 m_tabContexts.push_back( std::move( ctx ) );
1207
1208 m_tabsPanel->AddTab( key, name, aAsPreview );
1209
1210 return raw;
1211}
1212
1213
1215 std::vector<std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>>& aContexts, int aSlot,
1216 std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT> aNew,
1217 const std::function<void( const FOOTPRINT_EDITOR_TAB_CONTEXT& )>& aInstallSuccessor )
1218{
1219 // Hold the displaced context, and its still-displayed board, alive across aInstallSuccessor, which
1220 // repoints the canvas VIEW at the incoming board. Freeing the old board first would leave
1221 // VIEW::Clear() dereferencing items from a destroyed board.
1222 std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT> displaced = std::move( aContexts[aSlot] );
1223 aContexts[aSlot] = std::move( aNew );
1224
1225 FOOTPRINT_EDITOR_TAB_CONTEXT* raw = aContexts[aSlot].get();
1226
1227 aInstallSuccessor( *displaced );
1228
1229 return raw;
1230}
1231
1232
1234{
1235 if( !aBoardFootprint )
1236 return nullptr;
1237
1238 const KIID sourceUuid = aBoardFootprint->m_Uuid;
1239 const wxString key = FOOTPRINT_EDITOR_TAB_CONTEXT::MakeInstanceTabKey( sourceUuid );
1240 const wxString reference = aBoardFootprint->GetReference();
1241
1242 // Re-editing the same placed footprint focuses the live tab rather than duplicating it.
1243 if( int existing = m_tabsPanel->FindTab( key ); existing >= 0 )
1244 return m_tabContexts[existing].get();
1245
1246 std::unique_ptr<BOARD> board = makeFpHolderBoard( GetSettings() );
1247 board->GetDesignSettings().m_DRCSeverities[DRCE_MISSING_COURTYARD] = RPT_SEVERITY_WARNING;
1248
1249 auto ctx = std::make_unique<FOOTPRINT_EDITOR_TAB_CONTEXT>( sourceUuid, reference, std::move( board ) );
1250 BOARD* ctxBoard = ctx->GetBoard();
1251 std::map<KIID, KIID>& uuidMap = ctx->BoardFootprintUuids();
1252 FOOTPRINT_EDITOR_TAB_CONTEXT* raw = ctx.get();
1253
1254 const auto recordAndUpdateUuid =
1255 [&]( BOARD_ITEM* aItem )
1256 {
1257 KIID newId;
1258 uuidMap[newId] = aItem->m_Uuid;
1259 aItem->SetUuid( newId );
1260 };
1261
1262 // Clone keeps the existing uuids, which the remap then swaps for fresh editor-local ones so
1263 // SaveFootprintToBoard can map them back to the original board items.
1264 FOOTPRINT* clone = static_cast<FOOTPRINT*>( aBoardFootprint->Clone() );
1265 clone->SetParent( ctxBoard );
1266 clone->SetParentGroup( nullptr );
1267 clone->SetLink( aBoardFootprint->m_Uuid );
1268 clone->ClearFlags();
1269 clone->SetLocked( false );
1270
1271 recordAndUpdateUuid( clone );
1272 clone->RunOnChildren(
1273 [&]( BOARD_ITEM* aItem )
1274 {
1275 if( aItem->Type() == PCB_PAD_T )
1276 aItem->SetLocked( false );
1277
1278 aItem->ClearFlags();
1279 recordAndUpdateUuid( aItem );
1280 },
1282
1283 ctxBoard->Add( clone );
1284
1285 // The editor knows nothing of the board's nets, so force the orphaned dummy net on every pad to
1286 // avoid saving a reference to an unknown net into the library cache.
1287 clone->ClearAllNets();
1288
1289 // Normalize placement to the footprint-editor defaults so the editor view matches a library load.
1290 clone->SetPosition( VECTOR2I( 0, 0 ) );
1291
1292 if( clone->GetLayer() != F_Cu )
1293 clone->Flip( clone->GetPosition(), GetPcbNewSettings()->m_FlipDirection );
1294
1295 clone->SetOrientation( ANGLE_0 );
1296 clone->RunOnChildren(
1297 [&]( BOARD_ITEM* aItem )
1298 {
1299 if( aItem->Type() == PCB_TEXT_T )
1300 static_cast<PCB_TEXT*>( aItem )->KeepUpright();
1301 },
1303
1304 m_tabContexts.push_back( std::move( ctx ) );
1305
1306 // Index-aligned with the panel model; the context is at its final index before AddTab fires
1307 // onActivateTab.
1308 m_tabsPanel->AddTab( key, m_tabContexts.back()->GetDisplayName(), false );
1309
1310 return raw;
1311}
1312
1313
1315{
1316 std::unique_ptr<BOARD> board = makeFpHolderBoard( GetSettings() );
1317 std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT> ctx = FOOTPRINT_EDITOR_TAB_CONTEXT::MakeUnsaved( std::move( board ) );
1318
1319 const wxString key = ctx->GetTabKey();
1320 FOOTPRINT_EDITOR_TAB_CONTEXT* raw = ctx.get();
1321
1322 m_tabContexts.push_back( std::move( ctx ) );
1323
1324 // At its final index before AddTab fires onActivateTab, which makes the new tab active
1325 m_tabsPanel->AddTab( key, m_tabContexts.back()->GetDisplayName(), false );
1326
1327 return raw;
1328}
1329
1330
1332{
1333 // Free the UR_TRANSIENT board items each command owns and the command wrappers. The frame's own
1334 // ClearUndoRedoList() and the bare container destructor delete only the wrappers and leak the
1335 // transient items, so a discarded tab history must come through here.
1336 for( UNDO_REDO_CONTAINER* list : { &aUndo, &aRedo } )
1337 {
1338 for( PICKED_ITEMS_LIST* cmd : list->m_CommandsList )
1339 {
1341 delete cmd;
1342 }
1343
1344 list->m_CommandsList.clear();
1345 }
1346}
1347
1348
1350{
1351 // The context is detached here, so the transient items in its lists are never the live objects.
1353}
1354
1355
1357{
1358 if( aIdx < 0 || aIdx >= static_cast<int>( m_tabContexts.size() ) )
1359 return false;
1360
1362
1363 // The active tab's live dirty state lives on the shared frame screen, so ctx->IsModified() is
1364 // stale for it. Fold the screen state back in so an unsaved active tab still prompts.
1365 if( ctx == m_activeTab && GetScreen() )
1367
1368 if( ctx->IsModified() && !m_silentFootprintTabClose )
1369 {
1370 // Prompt while the closing tab is still fully live so a save reads its real board.
1371 wxString msg = wxString::Format( _( "Save changes to '%s' before closing?" ), ctx->GetDisplayName( true ) );
1372
1373 KIDIALOG dlg( this, msg, _( "Confirmation" ), wxYES_NO | wxCANCEL | wxICON_WARNING );
1374 dlg.SetYesNoCancelLabels( _( "Save" ), _( "Discard Changes" ), _( "Cancel" ) );
1375
1376 switch( dlg.ShowModal() )
1377 {
1378 case wxID_YES:
1379 {
1380 // SaveFootprint reads the active tab's load baseline for rename detection, so an inactive
1381 // tab must be made active first or it saves against the wrong baseline. Restore the prior
1382 // active tab afterwards so closing an inactive tab stays an inactive close, keeping the
1383 // panel's suppressed fallback selection aligned with the live board. Veto the close if the
1384 // save did not complete so the edits and history are not silently dropped.
1385 FOOTPRINT_EDITOR_TAB_CONTEXT* activeBeforeSave = m_activeTab;
1386 const bool activatedForSave = ( ctx != m_activeTab );
1387
1388 if( activatedForSave )
1389 activateFootprintTab( ctx );
1390
1391 const bool saved = SaveFootprint( ctx->GetBoard()->GetFirstFootprint() );
1392
1393 if( activatedForSave && activeBeforeSave )
1394 activateFootprintTab( activeBeforeSave );
1395
1396 if( !saved )
1397 return false;
1398
1399 break;
1400 }
1401
1402 case wxID_NO:
1403 break;
1404
1405 default:
1406 case wxID_CANCEL:
1407 return false;
1408 }
1409 }
1410
1411 const bool closingActive = ( ctx == m_activeTab );
1412
1413 if( !closingActive )
1414 {
1415 // m_pcb aliases a different live tab's board, so freeing this context dangles nothing.
1417 m_tabContexts.erase( m_tabContexts.begin() + aIdx );
1418 return true;
1419 }
1420
1421 // The closing tab's lists are currently the frame's live lists. Free them now with their
1422 // transient items, so the install's detach swaps empty lists into the closing context.
1424
1425 const int newCount = static_cast<int>( m_tabContexts.size() ) - 1;
1426 const int successorIdx = newCount > 0 ? std::min( aIdx, newCount - 1 ) : -1;
1427
1428 if( successorIdx >= 0 )
1429 {
1430 // Map the successor's post-erase position back to a pre-erase index. Indices above the closed
1431 // one shift down by one after the erase.
1432 const int preEraseSuccessor = successorIdx < aIdx ? successorIdx : successorIdx + 1;
1433
1434 FOOTPRINT_EDITOR_TAB_CONTEXT* successor = m_tabContexts[preEraseSuccessor].get();
1435
1436 installFootprintTabBoard( successor, successor->GetBoard() );
1437 }
1438 else
1439 {
1440 // Last tab: the fresh empty board is frame-owned like the bootstrap board.
1441 installFootprintTabBoard( nullptr, makeFpHolderBoard( GetSettings() ).release() );
1442 }
1443
1444 // The install swapped m_pcb off the closing board, so erasing the context frees it safely.
1445 m_tabContexts.erase( m_tabContexts.begin() + aIdx );
1446
1447 return true;
1448}
1449
1450
1452{
1453 const wxString lib = aFPID.GetLibNickname();
1454 const wxString name = aFPID.GetLibItemName();
1455 const int idx = m_tabsPanel->FindTab( lib + wxT( ":" ) + name );
1456
1457 if( idx < 0 )
1458 return;
1459
1460 // The caller already confirmed the deletion, so close without re-prompting. The panel selects a
1461 // successor when the closed tab was active.
1463 m_tabsPanel->CloseTab( idx );
1465}
1466
1467
1468void FOOTPRINT_EDIT_FRAME::RenameFootprintTab( const LIB_ID& aOldId, const LIB_ID& aNewId )
1469{
1470 const wxString newLib = aNewId.GetLibNickname();
1471 const wxString newName = aNewId.GetLibItemName();
1472
1473 // An unsaved import is keyed by a session id, not by aOldId, so the save-as that named it promotes
1474 // the active tab instead. A tree-driven rename carries a nickname and never reaches this path
1475 if( m_activeTab && m_activeTab->IsUnsaved() && aOldId.GetLibNickname().empty()
1476 && !newLib.IsEmpty() )
1477 {
1478 const wxString unsavedKey = m_activeTab->GetTabKey();
1479
1480 m_activeTab->PromoteToLibrary( newLib, newName );
1481 m_tabsPanel->RenameTab( unsavedKey, m_activeTab->GetTabKey(), m_activeTab->GetDisplayName() );
1482
1483 return;
1484 }
1485
1486 // A board footprint's tab is named from the board instance's reference, not any properties of the
1487 // edited copy.
1488 if( m_activeTab && m_activeTab->IsFromBoard() )
1489 return;
1490
1491 const wxString oldLib = aOldId.GetLibNickname();
1492 const wxString oldName = aOldId.GetLibItemName();
1493 const wxString oldKey = oldLib + wxT( ":" ) + oldName;
1494 const int idx = m_tabsPanel->FindTab( oldKey );
1495
1496 if( idx < 0 )
1497 return;
1498
1499 if( idx < static_cast<int>( m_tabContexts.size() ) )
1500 {
1501 // A tab switch restores the context's baseline onto the frame, so it must track the rename too
1502 // or the next save would delete the pre-renamed library entry
1503 m_tabContexts[idx]->SetLibNickname( newLib );
1504 m_tabContexts[idx]->SetFootprintName( newName );
1505 m_tabContexts[idx]->SetFootprintNameWhenLoaded( newName );
1506 }
1507
1508 m_tabsPanel->RenameTab( oldKey, newLib + wxT( ":" ) + newName, newName );
1509}
1510
1511
1513{
1514 for( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& ctx : m_tabContexts )
1515 {
1516 if( ctx.get() == m_activeTab )
1517 {
1518 if( GetScreen() && GetScreen()->IsContentModified() )
1519 return true;
1520 }
1521 else if( ctx->IsModified() )
1522 {
1523 return true;
1524 }
1525 }
1526
1527 return false;
1528}
1529
1530
1532{
1533 if( !m_tabsPanel )
1534 return;
1535
1536 const LIB_ID& footprintId = aFootprint.GetFPID();
1537 const wxString key = footprintId.GetLibNickname().wx_str() + wxT( ':' ) + footprintId.GetLibItemName().wx_str();
1538 const int idx = m_tabsPanel->FindTab( key );
1539
1540 if( idx < 0 || idx >= static_cast<int>( m_tabContexts.size() ) )
1541 return;
1542
1544 FOOTPRINT_EDITOR_TAB_CONTEXT* originalActive = m_activeTab;
1545
1546 // If we have our own unsaved changes, then leave it be.
1547 if( ctx->IsModified() )
1548 return;
1549
1550 activateFootprintTab( ctx );
1551
1552 // The old history contains pointers into the footprint ReloadFootprint is about to delete.
1554 ctx->SavedSelection().clear();
1555
1556 FOOTPRINT* replacement = static_cast<FOOTPRINT*>( aFootprint.Clone() );
1557 replacement->SetParent( nullptr );
1558 installFootprintOnActiveBoard( replacement );
1559 replacement->ClearFlags();
1560 ClearModify();
1561
1562 if( originalActive && originalActive != ctx )
1563 activateFootprintTab( originalActive );
1564
1565 FOOTPRINT* activeFootprint = GetBoard()->GetFirstFootprint();
1566
1567 if( IsCurrentFPFromBoard() )
1568 setFPWatcher( nullptr );
1569 else
1570 setFPWatcher( activeFootprint );
1571
1572 UpdateView();
1574 Update3DView( true, true );
1575}
1576
1577
1579{
1580 for( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& ctx : m_tabContexts )
1581 {
1582 if( ctx.get() != m_activeTab && ctx->IsModified() )
1583 return true;
1584 }
1585
1586 return false;
1587}
1588
1589
1591{
1592 // Active tab always goes first
1593 for( int ii = 0; ii < (int) m_tabContexts.size(); ++ii )
1594 {
1595 if( aFromBoardOnly && !m_tabContexts[ii]->IsFromBoard() )
1596 continue;
1597
1598 if( m_tabContexts[ii].get() == m_activeTab )
1599 {
1600 wxSafeYield( this, true ); // Allow frame to come to front before showing "Save Changes?"
1601
1602 if( !m_tabsPanel->CloseTab( ii ) )
1603 return false;
1604 }
1605 }
1606
1607 // Go from back so we don't have to worry about deletions
1608 for( int ii = (int) m_tabContexts.size() - 1; ii >= 0; --ii )
1609 {
1610 if( aFromBoardOnly && !m_tabContexts[ii]->IsFromBoard() )
1611 continue;
1612
1614 wxSafeYield( this, true ); // Allow tab to come to front before showing "Save Changes?"
1615
1616 if( !m_tabsPanel->CloseTab( ii ) )
1617 return false;
1618 }
1619
1620 return true;
1621}
1622
1623
1625{
1626 m_tabsPanel->RefreshTabLabels();
1627}
1628
1629
1631{
1632 wxCHECK( aReplacement, /* void */ );
1633
1634 // Install the fresh frame-owned board and reset the tools against it before any tab board is
1635 // freed, so no ResetTools or repaint sees a freed or null m_pcb.
1636 installFootprintTabBoard( nullptr, aReplacement );
1637
1638 // Tear the strip down without re-prompting to save, since unsaved changes were already handled.
1639 // Suppress the host close callback and tab activation so CloseAll only does panel bookkeeping.
1640 std::function<bool( int )> savedCb = std::move( m_tabsPanel->onCloseTabRequested );
1641 m_tabsPanel->onCloseTabRequested =
1642 []( int )
1643 {
1644 return true;
1645 };
1646
1648 m_tabsPanel->CloseAll();
1650
1651 m_tabsPanel->onCloseTabRequested = std::move( savedCb );
1652
1653 wxASSERT_MSG( m_pcb == aReplacement,
1654 wxT( "m_pcb must alias the frame-owned replacement before contexts are freed" ) );
1655
1656 for( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& ctx : m_tabContexts )
1658
1659 m_tabContexts.clear();
1660}
1661
1662
1664{
1665 m_tabsPanel->AdvanceTab( aForward );
1666}
1667
1668
1670{
1671 m_tabsPanel->CloseTab( m_tabsPanel->GetActiveTab() );
1672}
1673
1674
1679
1680
1685
1686
1688{
1689 wxFAIL_MSG( wxT( "Plotting not supported in Footprint Editor" ) );
1690
1692}
1693
1694
1696{
1697 wxFAIL_MSG( wxT( "Plotting not supported in Footprint Editor" ) );
1698}
1699
1700
1708
1709
1717
1718
1720{
1721 // Get our own settings; aCfg will be the PCBNEW_SETTINGS because we're part of the pcbnew
1722 // compile unit
1724
1725 if( cfg )
1726 {
1728
1730
1733
1735 m_selectionFilterPanel->SetCheckboxesFromFilter( cfg->m_SelectionFilter );
1736
1738
1739 for( auto& [source_name, dest_name] : cfg->m_DesignSettings.m_UserLayerNames )
1740 {
1741 wxString wx_source_name = source_name;
1742 PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( LSET::NameToLayer( wx_source_name ) );
1743
1744 if( IsUserLayer( layer ) )
1745 GetBoard()->SetLayerName( layer, dest_name );
1746 }
1747
1748 }
1749}
1750
1751
1753{
1754 // Load canvas type from the FOOTPRINT_EDITOR_SETTINGS:
1756
1757 // If we had an OpenGL failure this session, use the fallback GAL but don't update the
1758 // user preference silently:
1759
1762}
1763
1764
1766{
1768
1769 // Get our own settings; aCfg will be the PCBNEW_SETTINGS because we're part of the pcbnew
1770 // compile unit
1772
1773 if( cfg )
1774 {
1776
1779 cfg->m_LibWidth = m_treePane->GetSize().x;
1780
1781 if( TOOL_MANAGER* toolMgr = GetToolManager() )
1782 {
1783 if( PCB_SELECTION_TOOL* selTool = toolMgr->GetTool<PCB_SELECTION_TOOL>() )
1784 cfg->m_SelectionFilter = selTool->GetFilter();
1785 }
1786
1788
1789 if( m_propertiesPanel )
1790 {
1791 cfg->m_AuiPanels.show_properties = m_propertiesPanel->IsShownOnScreen();
1793 cfg->m_AuiPanels.properties_splitter = m_propertiesPanel->SplitterProportion();
1794 }
1795
1797
1798 if( m_appearancePanel )
1799 {
1802 cfg->m_LayerPresets = m_appearancePanel->GetUserLayerPresets();
1803 cfg->m_ActiveLayerPreset = m_appearancePanel->GetActiveLayerPreset();
1804 }
1805
1806 cfg->m_OpenTabs.clear();
1807 cfg->m_ActiveTab.Clear();
1808
1809 const std::vector<EDITOR_TABS_MODEL::ENTRY>& entries = m_tabsPanel->Model().Entries();
1810
1811 for( size_t i = 0; i < m_tabContexts.size(); ++i )
1812 {
1813 const FOOTPRINT_EDITOR_TAB_CONTEXT* ctx = m_tabContexts[i].get();
1814
1815 // Instance and unsaved-import tabs are session-only and never persisted
1816 if( ctx->IsTransient() )
1817 continue;
1818
1819 const bool preview = i < entries.size() && entries[i].preview;
1820
1821 cfg->m_OpenTabs.push_back( { ctx->GetLibNickname(), ctx->GetFootprintName(), preview } );
1822
1823 if( ctx == m_activeTab )
1824 cfg->m_ActiveTab = ctx->GetTabKey();
1825 }
1826 }
1827}
1828
1829
1830
1832{
1833 FOOTPRINT_EDITOR_SETTINGS* cfg = const_cast<FOOTPRINT_EDIT_FRAME*>( this )->GetSettings();
1834
1835 return cfg ? cfg->m_RotationAngle : ANGLE_90;
1836}
1837
1838
1839
1841{
1843 return ::GetColorSettings( cfg ? cfg->m_ColorTheme : DEFAULT_THEME );
1844}
1845
1846
1848{
1849 static MAGNETIC_SETTINGS fallback;
1850
1852 return &cfg->m_MagneticItems;
1853
1854 return &fallback;
1855}
1856
1857
1858const BOX2I FOOTPRINT_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
1859{
1860 FOOTPRINT* footprint = GetBoard()->GetFirstFootprint();
1861
1862 if( footprint )
1863 {
1864 bool hasGraphicalItem = footprint->Pads().size() || footprint->Zones().size();
1865
1866 if( !hasGraphicalItem )
1867 {
1868 for( const BOARD_ITEM* item : footprint->GraphicalItems() )
1869 {
1870 if( item->Type() == PCB_TEXT_T || item->Type() == PCB_TEXTBOX_T )
1871 continue;
1872
1873 hasGraphicalItem = true;
1874 break;
1875 }
1876 }
1877
1878 if( hasGraphicalItem )
1879 {
1880 return footprint->GetBoundingBox( false );
1881 }
1882 else
1883 {
1884 BOX2I newFootprintBB( { 0, 0 }, { 0, 0 } );
1885 newFootprintBB.Inflate( pcbIUScale.mmToIU( 12 ) );
1886 return newFootprintBB;
1887 }
1888 }
1889
1890 return GetBoardBoundingBox( false );
1891}
1892
1893
1894bool FOOTPRINT_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
1895{
1896 // Shutdown blocks must be determined and vetoed as early as possible, before any modal prompt.
1897 // IsContentModified only sees the active tab, so also account for dirty inactive tabs.
1898 if( KIPLATFORM::APP::SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
1900 {
1901 aEvent.Veto();
1902 return false;
1903 }
1904
1905 if( !HandleUnsavedChanges( false ) )
1906 {
1907 aEvent.Veto();
1908 return false;
1909 }
1910
1911 PAD_TOOL* padTool = m_toolManager->GetTool<PAD_TOOL>();
1912
1913 if( padTool->InPadEditMode() )
1914 padTool->ExitPadEditMode();
1915
1916 // Save footprint tree column widths
1917 m_adapter->SaveSettings();
1918
1919 return PCB_BASE_EDIT_FRAME::canCloseWindow( aEvent );
1920}
1921
1922
1924{
1925 // No more vetos
1926 GetCanvas()->SetEventDispatcher( nullptr );
1928
1930 wxTheApp->Unbind( EDA_EVT_PLUGIN_AVAILABILITY_CHANGED,
1932
1933 if( GetLibTree() )
1935
1936 // Do not show the layer manager during closing to avoid flicker
1937 // on some platforms (Windows) that generate useless redraw of items in
1938 // the Layer Manager
1939 m_auimgr.GetPane( wxT( "LayersManager" ) ).Show( false );
1940 m_auimgr.GetPane( wxT( "SelectionFilter" ) ).Show( false );
1941
1942 Clear_Pcb();
1943}
1944
1945
1946void FOOTPRINT_EDIT_FRAME::OnExitKiCad( wxCommandEvent& event )
1947{
1948 Kiway().OnKiCadExit();
1949}
1950
1951
1953{
1954 Close();
1955}
1956
1957
1959{
1960 // call my base class
1962
1963 // We have 2 panes to update.
1964 // For some obscure reason, the AUI manager hides the first modified pane.
1965 // So force show panes
1966 wxAuiPaneInfo& tree_pane_info = m_auimgr.GetPane( m_treePane );
1967 bool tree_shown = tree_pane_info.IsShown();
1968 tree_pane_info.Caption( _( "Libraries" ) );
1969
1970 wxAuiPaneInfo& lm_pane_info = m_auimgr.GetPane( m_appearancePanel );
1971 bool lm_shown = lm_pane_info.IsShown();
1972 lm_pane_info.Caption( _( "Appearance" ) );
1973 wxAuiPaneInfo& sf_pane_info = m_auimgr.GetPane( m_selectionFilterPanel );
1974 sf_pane_info.Caption( _( "Selection Filter" ) );
1975
1976 // update the layer manager
1978
1979 // Now restore the visibility:
1980 lm_pane_info.Show( lm_shown );
1981 tree_pane_info.Show( tree_shown );
1982 m_auimgr.Update();
1983
1985
1986 UpdateTitle();
1987}
1988
1989
1991{
1993
1994 if( m_isClosing )
1995 return;
1996
1997 // An edit promotes the active tab from preview to permanent and flags it dirty. Reflect the
1998 // shared screen's dirty state onto the context and panel model so the tab shows bold + "*" and a
1999 // later library-open opens its own tab instead of replacing this one.
2000 if( m_activeTab )
2001 {
2002 m_activeTab->SetPreview( false );
2003 m_activeTab->SetModified( true );
2004
2005 if( int idx = m_tabsPanel->FindTab( m_activeTab->GetTabKey() ); idx >= 0 )
2006 m_tabsPanel->MarkModified( idx, true );
2007 }
2008
2009 Update3DView( true, true );
2011}
2012
2013
2015{
2016 SetTitle( _( "Footprint Editor" ) );
2017}
2018
2019
2021{
2022 m_appearancePanel->OnBoardChanged();
2023}
2024
2025
2027{
2031 m_propertiesPanel->UpdateData();
2032}
2033
2034
2036{
2038
2040 auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
2041
2042 adapter->AddLibraries( this );
2043}
2044
2045
2046void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( [[maybe_unused]] bool aProgress )
2047{
2048 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "FOOTPRINT_EDIT_FRAME::SyncLibraryTree enter" ) );
2049
2052 LIB_ID target = GetTargetFPID();
2053 bool targetSelected = ( target == GetLibTree()->GetSelectedLibId() );
2054 std::vector<LIB_ID> expanded = GetLibTree()->GetExpandedLibraries();
2055
2056 // Unselect before syncing to avoid null reference in the adapter
2057 // if a selected item is removed during the sync
2058 GetLibTree()->Unselect();
2059
2060 // Sync the LIB_TREE to the FOOTPRINT_INFO list
2061 adapter->Sync( footprints );
2062
2063 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "FOOTPRINT_EDIT_FRAME::SyncLibraryTree Regenerate" ) );
2064 GetLibTree()->Regenerate( true );
2065
2066 // Sync() collapsed the tree, so re-expand the libraries that were open before it.
2067 for( const LIB_ID& libId : expanded )
2068 GetLibTree()->ExpandLibId( libId );
2069
2070 if( target.IsValid() )
2071 {
2072 if( adapter->FindItem( target ) )
2073 {
2074 if( targetSelected )
2075 GetLibTree()->SelectLibId( target );
2076 else
2077 GetLibTree()->CenterLibId( target );
2078 }
2079 else
2080 {
2081 // Try to focus on parent
2082 target.SetLibItemName( wxEmptyString );
2083 GetLibTree()->CenterLibId( target );
2084 }
2085 }
2086
2087 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "FOOTPRINT_EDIT_FRAME::SyncLibraryTree exit" ) );
2088}
2089
2090
2095
2096
2098{
2099 GetLibTree()->SelectLibId( aLibID );
2100}
2101
2102
2104{
2105 m_appearancePanel->UpdateDisplayOptions();
2106}
2107
2108
2110{
2111 // Create the manager and dispatcher & route draw panel events to the dispatcher
2113 m_toolManager->SetEnvironment( GetBoard(), GetCanvas()->GetView(), GetCanvas()->GetViewControls(), config(), this );
2114 m_actions = new PCB_ACTIONS();
2116
2118
2119 m_toolManager->RegisterTool( new COMMON_CONTROL );
2120 m_toolManager->RegisterTool( new COMMON_TOOLS );
2121 m_toolManager->RegisterTool( new PCB_SELECTION_TOOL );
2122 m_toolManager->RegisterTool( new ZOOM_TOOL );
2123 m_toolManager->RegisterTool( new EDIT_TOOL );
2124 m_toolManager->RegisterTool( new PCB_EDIT_TABLE_TOOL );
2125 m_toolManager->RegisterTool( new PAD_TOOL );
2126 m_toolManager->RegisterTool( new DRAWING_TOOL );
2127 m_toolManager->RegisterTool( new PCB_POINT_EDITOR );
2128 m_toolManager->RegisterTool( new PCB_CONTROL ); // copy/paste
2129 m_toolManager->RegisterTool( new LIBRARY_EDITOR_CONTROL );
2130 m_toolManager->RegisterTool( new FOOTPRINT_EDITOR_CONTROL );
2131 m_toolManager->RegisterTool( new ALIGN_DISTRIBUTE_TOOL );
2132 m_toolManager->RegisterTool( new PCB_PICKER_TOOL );
2133 m_toolManager->RegisterTool( new POSITION_RELATIVE_TOOL );
2134 m_toolManager->RegisterTool( new ARRAY_TOOL );
2135 m_toolManager->RegisterTool( new PCB_VIEWER_TOOLS );
2136 m_toolManager->RegisterTool( new PCB_GROUP_TOOL );
2137 m_toolManager->RegisterTool( new CONSTRAINT_EDIT_TOOL );
2138 m_toolManager->RegisterTool( new CONVERT_TOOL );
2139 m_toolManager->RegisterTool( new PROPERTIES_TOOL );
2140 m_toolManager->RegisterTool( new MATCH_PROPERTIES_TOOL );
2141 m_toolManager->RegisterTool( new GRAPHIC_EDIT_TOOL );
2142 m_toolManager->RegisterTool( new EMBED_TOOL );
2143
2144 for( TOOL_BASE* tool : m_toolManager->Tools() )
2145 {
2146 if( PCB_TOOL_BASE* pcbTool = dynamic_cast<PCB_TOOL_BASE*>( tool ) )
2147 pcbTool->SetIsFootprintEditor( true );
2148 }
2149
2150 m_toolManager->GetTool<PCB_VIEWER_TOOLS>()->SetFootprintFrame( true );
2151 m_toolManager->InitTools();
2152
2153 m_toolManager->InvokeTool( "common.InteractiveSelection" );
2154
2155 // Load or reload wizard plugins in case they changed since the last time the frame opened
2156 // Because the board editor has also a plugin python menu,
2157 // call the PCB_EDIT_FRAME RunAction() if the board editor is running
2158 // Otherwise run the current RunAction().
2159 PCB_EDIT_FRAME* pcbframe = static_cast<PCB_EDIT_FRAME*>( Kiway().Player( FRAME_PCB_EDITOR, false ) );
2160
2161 if( pcbframe )
2163 else
2165}
2166
2167
2169{
2171
2172 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
2173 PCB_EDITOR_CONDITIONS cond( this );
2174
2175 wxASSERT( mgr );
2176
2177#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
2178#define CHECK( x ) ACTION_CONDITIONS().Check( x )
2179
2180 auto haveFootprintCond =
2181 [this]( const SELECTION& )
2182 {
2183 return GetBoard() && GetBoard()->GetFirstFootprint() != nullptr;
2184 };
2185
2186 auto footprintTargettedCond =
2187 [this]( const SELECTION& )
2188 {
2189 return !GetTargetFPID().GetLibItemName().empty();
2190 };
2191
2192 auto footprintSelectedInTreeCond =
2193 [this]( const SELECTION& )
2194 {
2196 return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
2197 };
2198
2199 const auto footprintFromBoardCond =
2200 [this]( const SELECTION& )
2201 {
2202 return IsCurrentFPFromBoard();
2203 };
2204
2205 auto pcbFrameExistsCond =
2206 [this]( const SELECTION& )
2207 {
2208 PCB_EDIT_FRAME* frame = dynamic_cast<PCB_EDIT_FRAME*>( Kiway().Player( FRAME_PCB_EDITOR, false ) );
2209
2210 return ( frame != nullptr );
2211 };
2212
2213 auto boardFootprintExistsCond =
2214 [this]( const SELECTION& )
2215 {
2216 PCB_EDIT_FRAME* frame = dynamic_cast<PCB_EDIT_FRAME*>( Kiway().Player( FRAME_PCB_EDITOR, false ) );
2217
2218 FOOTPRINT* editorFootprint = GetBoard()->GetFirstFootprint();
2219 bool canInsert = frame && editorFootprint && editorFootprint->GetLink() == niluuid;
2220
2221 // If the source was deleted, the footprint can inserted but not updated in the board.
2222 if( frame && editorFootprint && editorFootprint->GetLink() != niluuid )
2223 {
2224 BOARD* mainpcb = frame->GetBoard();
2225 canInsert = true;
2226
2227 // search if the source footprint was not deleted:
2228 for( FOOTPRINT* candidate : mainpcb->Footprints() )
2229 {
2230 if( editorFootprint->GetLink() == candidate->m_Uuid )
2231 {
2232 canInsert = false;
2233 break;
2234 }
2235 }
2236 }
2237
2238 return canInsert;
2239 };
2240
2241 // clang-format off
2242 mgr->SetConditions( ACTIONS::saveAs, ENABLE( footprintTargettedCond ) );
2245 mgr->SetConditions( PCB_ACTIONS::editLibFpInFpEditor,ENABLE( footprintFromBoardCond ) );
2246
2247 mgr->SetConditions( PCB_ACTIONS::saveFpToBoard, ENABLE( boardFootprintExistsCond ) );
2248 mgr->SetConditions( PCB_ACTIONS::loadFpFromBoard, ENABLE( pcbFrameExistsCond ) );
2249
2252
2255
2256 mgr->SetConditions( ACTIONS::cut, ENABLE( cond.HasItems() ) );
2257 mgr->SetConditions( ACTIONS::copy, ENABLE( cond.HasItems() ) );
2264
2271
2275
2280 // clang-format on
2281
2282 auto highContrastCond =
2283 [this]( const SELECTION& )
2284 {
2286 };
2287
2288 auto autoConstraintsCond = [this]( const SELECTION& )
2289 {
2291 return cfg && cfg->m_AutoConstraints;
2292 };
2293
2294 mgr->SetConditions( PCB_ACTIONS::toggleAutoConstraints, CHECK( autoConstraintsCond ) );
2295
2296 auto boardFlippedCond = [this]( const SELECTION& )
2297 {
2299 };
2300
2301 auto libraryTreeCond =
2302 [this](const SELECTION& )
2303 {
2304 return IsLibraryTreeShown();
2305 };
2306
2307 auto layerManagerCond =
2308 [this]( const SELECTION& )
2309 {
2310 return m_auimgr.GetPane( "LayersManager" ).IsShown();
2311 };
2312
2313 auto propertiesCond =
2314 [this] ( const SELECTION& )
2315 {
2316 return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
2317 };
2318
2319 mgr->SetConditions( ACTIONS::highContrastMode, CHECK( highContrastCond ) );
2320 mgr->SetConditions( PCB_ACTIONS::flipBoard, CHECK( boardFlippedCond ) );
2322
2323 mgr->SetConditions( ACTIONS::showLibraryTree, CHECK( libraryTreeCond ) );
2324 mgr->SetConditions( PCB_ACTIONS::showLayersManager, CHECK( layerManagerCond ) );
2325 mgr->SetConditions( ACTIONS::showProperties, CHECK( propertiesCond ) );
2326
2327 mgr->SetConditions( ACTIONS::print, ENABLE( haveFootprintCond ) );
2328 mgr->SetConditions( PCB_ACTIONS::exportFootprint, ENABLE( haveFootprintCond ) );
2329 mgr->SetConditions( PCB_ACTIONS::placeImportedGraphics, ENABLE( haveFootprintCond ) );
2330
2331 mgr->SetConditions( PCB_ACTIONS::footprintProperties, ENABLE( footprintSelectedInTreeCond || haveFootprintCond ) );
2332 mgr->SetConditions( PCB_ACTIONS::padTable, ENABLE( haveFootprintCond ) );
2333 mgr->SetConditions( PCB_ACTIONS::editTextAndGraphics, ENABLE( haveFootprintCond ) );
2334 mgr->SetConditions( PCB_ACTIONS::checkFootprint, ENABLE( haveFootprintCond ) );
2335 mgr->SetConditions( PCB_ACTIONS::repairFootprint, ENABLE( haveFootprintCond ) );
2336 mgr->SetConditions( PCB_ACTIONS::cleanupGraphics, ENABLE( haveFootprintCond ) );
2337 mgr->SetConditions( ACTIONS::showDatasheet, ENABLE( haveFootprintCond ) );
2338
2339 const auto isArcKeepCenterMode =
2340 [this]( const SELECTION& )
2341 {
2343 };
2344
2345 const auto isArcKeepEndpointMode =
2346 [this]( const SELECTION& )
2347 {
2349 };
2350
2351 const auto isArcKeepRadiusMode =
2352 [this]( const SELECTION& )
2353 {
2355 };
2356
2357 // clang-format off
2358 mgr->SetConditions( ACTIONS::pointEditorArcKeepCenter, CHECK( isArcKeepCenterMode ) );
2359 mgr->SetConditions( ACTIONS::pointEditorArcKeepEndpoint, CHECK( isArcKeepEndpointMode ) );
2360 mgr->SetConditions( ACTIONS::pointEditorArcKeepRadius, CHECK( isArcKeepRadiusMode ) );
2361 // clang-format on
2362
2363// Only enable a tool if the part is edtable
2364#define CURRENT_EDIT_TOOL( action ) mgr->SetConditions( action, ACTION_CONDITIONS() \
2365 .Enable( haveFootprintCond ) \
2366 .Check( cond.CurrentTool( action ) ) )
2367
2378 setArcModeConditions( PCB_ACTIONS::drawArc, haveFootprintCond );
2395
2414
2415#undef CURRENT_EDIT_TOOL
2416#undef ENABLE
2417#undef CHECK
2418}
2419
2420
2422{
2424
2425 // Be sure the axis are enabled
2426 GetCanvas()->GetGAL()->SetAxesEnabled( true );
2427
2428 UpdateView();
2429
2430 // Ensure the m_Layers settings are using the canvas type:
2432}
2433
2434
2436{
2438 m_appearancePanel->CommonSettingsChanged( aFlags );
2439
2441 {
2442 GetGalDisplayOptions().ReadWindowSettings( cfg->m_Window );
2443
2444 GetBoard()->GetDesignSettings() = cfg->m_DesignSettings;
2446 }
2447
2451
2453
2454 if( aFlags & ENVVARS_CHANGED )
2455 SyncLibraryTree( true );
2456
2457 Layout();
2458 SendSizeEvent();
2459}
2460
2461
2462std::unique_ptr<GRID_HELPER> FOOTPRINT_EDIT_FRAME::MakeGridHelper()
2463{
2464 return std::make_unique<PCB_GRID_HELPER>( m_toolManager, GetMagneticItemsSettings() );
2465}
2466
2467
2469{
2470 LIB_ID id = GetLoadedFPID();
2471
2472 if( id.empty() )
2473 {
2474 DisplayErrorMessage( this, _( "No footprint selected." ) );
2475 return;
2476 }
2477
2478 wxFileName fn( id.GetLibItemName() );
2479 fn.SetExt( wxT( "png" ) );
2480
2481 wxString projectPath = wxPathOnly( Prj().GetProjectFullName() );
2482
2483 wxFileDialog dlg( this, _( "Export View as PNG" ), projectPath, fn.GetFullName(), FILEEXT::PngFileWildcard(),
2484 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
2485
2487
2488 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetPath().IsEmpty() )
2489 return;
2490
2491 // calling wxYield is mandatory under Linux, after closing the file selector dialog
2492 // to refresh the screen before creating the PNG or JPEG image from screen
2493 wxYield();
2494 this->SaveCanvasImageToFile( dlg.GetPath(), BITMAP_TYPE::PNG );
2495}
const char * name
const KICOMMON_API wxEventTypeTag< wxCommandEvent > EDA_EVT_PLUGIN_AVAILABILITY_CHANGED
Notifies other parts of KiCad when plugin availability changes.
@ KEEP_ENDPOINTS_OR_START_DIRECTION
Whe editing endpoints, the other end remains in place.
@ KEEP_CENTER_ENDS_ADJUST_ANGLE
When editing endpoints, only the angle is adjusted.
@ KEEP_CENTER_ADJUST_ANGLE_RADIUS
When editing endpoints, the angle and radius are adjusted.
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:128
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:100
@ icon_modedit_32
@ icon_modedit_16
@ FPHOLDER
Definition board.h:402
@ NORMAL
Inactive layers are shown normally (no high-contrast mode)
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
static TOOL_ACTION toggleGrid
Definition actions.h:194
static TOOL_ACTION paste
Definition actions.h:76
static TOOL_ACTION unselectAll
Definition actions.h:79
static TOOL_ACTION revert
Definition actions.h:58
static TOOL_ACTION showLibraryTree
Definition actions.h:160
static TOOL_ACTION saveAs
Definition actions.h:55
static TOOL_ACTION copy
Definition actions.h:74
static TOOL_ACTION pluginsReload
Definition actions.h:293
static TOOL_ACTION selectSetLasso
Definition actions.h:217
static TOOL_ACTION selectSetRect
Set lasso selection mode.
Definition actions.h:216
static TOOL_ACTION group
Definition actions.h:235
static TOOL_ACTION pasteSpecial
Definition actions.h:77
static TOOL_ACTION showDatasheet
Definition actions.h:263
static TOOL_ACTION pointEditorArcKeepCenter
Definition actions.h:272
static TOOL_ACTION ungroup
Definition actions.h:236
static TOOL_ACTION toggleBoundingBoxes
Definition actions.h:153
static TOOL_ACTION pointEditorArcKeepRadius
Definition actions.h:274
static TOOL_ACTION undo
Definition actions.h:71
static TOOL_ACTION duplicate
Definition actions.h:80
static TOOL_ACTION highContrastMode
Definition actions.h:151
static TOOL_ACTION embeddedFiles
Definition actions.h:297
static TOOL_ACTION measureTool
Definition actions.h:248
static TOOL_ACTION doDelete
Definition actions.h:81
static TOOL_ACTION selectionTool
Definition actions.h:247
static TOOL_ACTION save
Definition actions.h:54
static TOOL_ACTION zoomFitScreen
Definition actions.h:138
static TOOL_ACTION redo
Definition actions.h:72
static TOOL_ACTION deleteTool
Definition actions.h:82
static TOOL_ACTION zoomTool
Definition actions.h:142
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:220
static TOOL_ACTION print
Definition actions.h:60
static TOOL_ACTION showProperties
Definition actions.h:262
static TOOL_ACTION cut
Definition actions.h:73
static TOOL_ACTION gridSetOrigin
Definition actions.h:191
static TOOL_ACTION ddAddLibrary
Definition actions.h:63
static TOOL_ACTION toggleGridOverrides
Definition actions.h:195
static TOOL_ACTION selectAll
Definition actions.h:78
static TOOL_ACTION pointEditorArcKeepEndpoint
Definition actions.h:273
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...
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
wxString m_ColorTheme
Active color theme name.
The array tool.
Definition array_tool.h:44
bool IsContentModified() const
Definition base_screen.h:56
void SetContentModified(bool aModified=true)
Definition base_screen.h:55
BASE_SET & set(size_t pos)
Definition base_set.h:126
Container for design settings for a BOARD object.
std::map< std::string, wxString > m_UserLayerNames
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
void SetLocked(bool aLocked) override
Definition board_item.h:426
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition board_item.h:354
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1521
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition board.cpp:958
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition board.h:712
const FOOTPRINTS & Footprints() const
Definition board.h:464
void DeleteAllFootprints()
Remove all footprints from the deque and free the memory associated with them.
Definition board.cpp:2101
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1298
void SetUserUnits(EDA_UNITS aUnits)
Definition board.h:1031
Color settings are a bit different than most of the settings objects in that there can be more than o...
Handle actions that are shared between different applications.
Handles action that are shared between different applications.
Interactive authoring of geometric constraints (issue #2329).
Tool responsible for drawing graphical elements like lines, arcs, circles, etc.
void CommonSettingsChanged(int aFlags) override
Notification event that some of the common (suite-wide) settings have changed.
UNDO_REDO_CONTAINER m_undoList
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 UpdateToolbarControlSizes()
Update the sizes of any controls in the toolbars of the frame.
ACTION_TOOLBAR * m_tbRight
TOOLBAR_SETTINGS * m_toolbarSettings
wxAuiManager m_auimgr
virtual void RecreateToolbars()
UNDO_REDO_CONTAINER m_redoList
ACTION_TOOLBAR * m_tbLeft
virtual void OnSize(wxSizeEvent &aEvent)
virtual bool canCloseWindow(wxCloseEvent &aCloseEvent)
virtual void OnDropFiles(wxDropFilesEvent &aEvent)
Handle event fired when a file is dropped to the window.
std::map< const wxString, TOOL_ACTION * > m_acceptedExts
Associate file extensions with action to execute.
ACTION_TOOLBAR * m_tbTopMain
wxString m_aboutTitle
bool m_isClosing
Set by the close window event handler after frames are asked if they can close.
void ReCreateMenuBar()
Recreate the menu bar.
WX_INFOBAR * GetInfoBar()
EDA_DRAW_PANEL_GAL::GAL_TYPE m_canvasType
The current canvas type.
void OnSelectGrid(wxCommandEvent &event)
Command event handler for selecting grid sizes.
void setupUnits(APP_SETTINGS_BASE *aCfg)
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void setArcModeConditions(const TOOL_ACTION &aDrawArc, const std::function< bool(const SELECTION &)> &aEnable)
Check each arc mode's tool action while the arc tool runs in that mode.
bool SaveCanvasImageToFile(const wxString &aFileName, BITMAP_TYPE aBitmapType)
Save the current view as an image file.
virtual void SwitchCanvas(EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType)
Change the current rendering backend.
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.
static bool m_openGLFailureOccured
Has any failure occurred when switching to OpenGL in any EDA_DRAW_FRAME?
static const wxString PropertiesPaneName()
EDA_MSG_PANEL * m_messagePanel
void SetCanvas(EDA_DRAW_PANEL_GAL *aPanel)
virtual void SetScreen(BASE_SCREEN *aScreen)
virtual void UpdateMsgPanel()
Redraw the message panel.
EDA_DRAW_PANEL_GAL::GAL_TYPE loadCanvasTypeSetting()
Return the canvas type stored in the application settings.
PROPERTIES_PANEL * m_propertiesPanel
bool m_showBorderAndTitleBlock
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.
@ GAL_TYPE_OPENGL
OpenGL implementation.
KIGFX::GAL * GetGAL() const
Return a pointer to the GAL instance used in the panel.
void SetEventDispatcher(TOOL_DISPATCHER *aEventDispatcher)
Set a dispatcher that processes events and forwards them to tools.
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:599
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:160
virtual void SetParentGroup(EDA_GROUP *aGroup)
Definition eda_item.h:115
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:153
Specialization of the wxAuiPaneInfo class for KiCad panels.
SELECTION_CONDITION NoActiveTool()
Create a functor testing if there are no tools active in the frame.
SELECTION_CONDITION BoundingBoxes()
SELECTION_CONDITION RedoAvailable()
Create a functor that tests if there are any items in the redo queue.
SELECTION_CONDITION CurrentTool(const TOOL_ACTION &aTool)
Create a functor testing if the specified tool is the current active tool in the frame.
virtual SELECTION_CONDITION UndoAvailable()
Create a functor that tests if there are any items in the undo queue.
SELECTION_CONDITION GridVisible()
Create a functor testing if the grid is visible in a frame.
SELECTION_CONDITION ContentModified()
Create a functor that tests if the content of the frame is modified.
SELECTION_CONDITION GridOverrides()
Create a functor testing if the grid overrides wires is enabled in a frame.
The tab strip plus the single shared GAL canvas.
VIEW_SNAPSHOT & ViewSnapshot()
std::vector< KIID > & SavedSelection()
Selection saved as resolved KIIDs, restored after the view is rebuilt.
UNDO_REDO_CONTAINER & RedoList()
UNDO_REDO_CONTAINER & UndoList()
The interactive edit tool.
Definition edit_tool.h:54
Module editor specific tools.
BOARD_DESIGN_SETTINGS m_DesignSettings
Only some of these settings are actually used for footprint editing.
wxString m_ActiveTab
Tab key ("lib:fpName") of the tab that was active when the editor last closed.
std::vector< LAYER_PRESET > m_LayerPresets
PCB_SELECTION_FILTER_OPTIONS m_SelectionFilter
One open footprint tab owning its fp-holder board, lent to the frame by raw pointer while active.
std::map< KIID, KIID > & BoardFootprintUuids()
Editor-to-board UUID remap captured at load, used by SaveFootprintToBoard to restore the original boa...
bool IsTransient() const
True for a tab that is session-only and not yet saved.
BOARD * GetBoard() const
The fp-holder board owned by this context.
wxString GetDisplayName(bool aShortForm=false) const override
Short label shown on the tab.
static wxString MakeInstanceTabKey(const KIID &aSourceUuid)
De-duplication key for a placed board footprint, in a namespace disjoint from library keys.
static std::unique_ptr< FOOTPRINT_EDITOR_TAB_CONTEXT > MakeUnsaved(std::unique_ptr< BOARD > aBoard)
Construct a tab for an imported footprint that has no library identity yet.
const wxString & GetFootprintNameWhenLoaded() const
bool IsModified() const override
True only when dirty and the board actually holds a footprint to edit.
FOOTPRINT * GetOriginalFootprintCopy() const
Baseline clone captured at load, used to detect edits and to revert.
wxString GetTabKey() const override
Stable identity for persistence and de-duplication.
void CloseFootprintEditor(wxCommandEvent &Event)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const override
Return the BOARD_DESIGN_SETTINGS for the open project.
void setupUIConditions() override
Setup the UI conditions for the various actions and their controls in this frame.
void ActivateGalCanvas() override
Use to start up the GAL drawing canvas.
void detachTabsForFullClear(BOARD *aReplacement)
Install aReplacement as the active document non-destructively, then drop every tab context and free t...
void onPluginAvailabilityChanged(wxCommandEvent &aEvt)
void Clear_Pcb()
Delete all and reinitialize the current board.
Definition initpcb.cpp:107
void HardRedraw() override
Refresh the library tree and redraw the window.
void updateInfoBar()
Update the infobar for the currently-active tab.
static const wxChar * GetFootprintEditorFrameName()
void SyncLibraryTree(bool aProgress)
Synchronize the footprint library tree to the current state of the footprint library table.
BOARD * m_protectedBorrowedBoard
Board still owned by a displaced preview context while AddTab() synchronously installs its successor.
FOOTPRINT_EDITOR_TAB_CONTEXT * CreateUnsavedFootprintTab()
Open a session-only tab over a fresh fp-holder board and make it the active tab.
FOOTPRINT_EDITOR_TAB_CONTEXT * m_activeTab
void OnSaveFootprintAsPng(wxCommandEvent &event)
bool SaveFootprintAs(FOOTPRINT *aFootprint)
void FocusLibraryTreeInput() override
BOARD_ITEM_CONTAINER * GetModel() const override
void ReCreateLayerBox(bool aForceResizeToolbar=true)
Re create the layer Box by clearing the old list, and building a new one from the new layers names an...
LIB_TREE * GetLibTree() const override
bool canCloseWindow(wxCloseEvent &Event) override
void UpdateMsgPanel() override
Redraw the message panel.
LIB_ID GetTargetFPID() const
Return the LIB_ID of the part selected in the footprint tree, or the loaded part if there is no selec...
LIB_ID GetLoadedFPID() const
Return the LIB_ID of the part being edited.
APP_SETTINGS_BASE * config() const override
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
void refreshFootprintTabState()
Re-query and re-render the tab labels from the active context's modified state.
std::unique_ptr< API_HANDLER_LIBRARIES > m_apiHandlerFpLibs
EDITOR_TABS_PANEL * m_tabsPanel
FOOTPRINT_EDITOR_TAB_CONTEXT * findOrCreateFootprintInstanceTab(FOOTPRINT *aBoardFootprint)
Find or create the instance tab for a placed board footprint and make it the active tab.
void detachActiveFootprintTab()
Snapshot the active tab's view/selection, fold the dirty state back into it, and clear m_activeTab.
void SetPlotSettings(const PCB_PLOT_PARAMS &aSettings) override
bool SaveFootprint(FOOTPRINT *aFootprint)
Save in an existing library a given footprint.
void OnTabCharHook(wxKeyEvent &aEvent)
Cycle footprint tabs from the CHAR_HOOK stream, since GTK cannot register WXK_TAB as a menu accelerat...
void CloseFootprintTab(const LIB_ID &aFPID)
Close the open tab for aFPID, if any, without prompting and leaving the other tabs open.
std::unique_ptr< API_HANDLER_FOOTPRINT > m_apiHandler
void initLibraryTree()
Make sure the footprint info list is loaded (with a progress dialog) and then initialize the footprin...
bool m_silentFootprintTabClose
While true, promptAndCloseFootprintTab() skips the unsaved-changes dialog.
std::map< KIID, KIID > m_boardFootprintUuids
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
std::unique_ptr< API_HANDLER_COMMON > m_apiHandlerCommon
void ShowChangedLanguage() override
Update visible items after a language change.
void resolveCanvasType() override
Determines the Canvas type to load (with prompt if required) and initializes m_canvasType.
void CommonSettingsChanged(int aFlags) override
Called after the preferences dialog is run.
bool IsContentModified() const override
Get if any footprints or libraries have been modified but not saved.
void UpdateUserInterface()
Update the layer manager and other widgets from the board setup (layer and items visibility,...
wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > m_adapter
bool IsLibraryTreeShown() const override
FOOTPRINT_EDITOR_SETTINGS * m_editorSettings
const BOX2I GetDocumentExtents(bool aIncludeAllVisible=true) const override
Return bounding box of document with option to not include some items.
bool HasModifiedFootprintTabs() const
Return true if any footprint editor tab has unsaved changes.
void RenameFootprintTab(const LIB_ID &aOldId, const LIB_ID &aNewId)
Update the open tab for aOldId, if any, to the renamed footprint aNewId so its label and key track th...
static FOOTPRINT_EDITOR_TAB_CONTEXT * placeReusedTabContext(std::vector< std::unique_ptr< FOOTPRINT_EDITOR_TAB_CONTEXT > > &aContexts, int aSlot, std::unique_ptr< FOOTPRINT_EDITOR_TAB_CONTEXT > aNew, const std::function< void(const FOOTPRINT_EDITOR_TAB_CONTEXT &)> &aInstallSuccessor)
Replace the tab context at aSlot with aNew, running aInstallSuccessor before the displaced context is...
bool HandleUnsavedChanges(bool aFromBoardOnly)
Prompt to save each dirty tab that meets the requirements.
void borrowBoardNonDestructive(BOARD *aBoard)
Swap the frame's borrowed board pointer to aBoard without deleting the previous board,...
FOOTPRINT_EDIT_FRAME(KIWAY *aKiway, wxWindow *aParent)
protected so only friend PCB::IFACE::CreateWindow() can act as sole factory.
bool hasDirtyInactiveTabs() const
True if any non-active tab has unsaved edits.
void RefreshLibraryFootprintTab(const FOOTPRINT &aFootprint)
Replace the clean open editor tab matching aFootprint, if any, with the saved footprint.
SELECTION & GetCurrentSelection() override
Get the current selection from the canvas area.
void UpdateView()
Reload displayed items and sets view.
void AdvanceFootprintTab(bool aForward)
Advance the active tab forward or backward in MRU order.
void activateFootprintTab(FOOTPRINT_EDITOR_TAB_CONTEXT *aCtx)
Make aCtx the active tab, borrowing its board without deleting the outgoing one.
void freeFootprintTabUndoRedo(FOOTPRINT_EDITOR_TAB_CONTEXT &aCtx)
Free the transient board items a detached context's lists own before it is destroyed,...
void SetActiveLayer(PCB_LAYER_ID aLayer) override
void AddFootprintToBoard(FOOTPRINT *aFootprint) override
Override from PCB_BASE_EDIT_FRAME which adds a footprint to the editor's dummy board,...
bool activeBoardOwnedByTab() const
True when a tab context owns the frame's borrowed board, so the frame must not delete it.
void OnModify() override
Must be called after a footprint change in order to set the "modify" flag of the current screen and p...
std::vector< std::unique_ptr< FOOTPRINT_EDITOR_TAB_CONTEXT > > m_tabContexts
void CloseActiveFootprintTab()
Request closing the active tab, prompting to save if it is modified.
FOOTPRINT_TREE_PANE * m_treePane
std::unique_ptr< GRID_HELPER > MakeGridHelper() override
void OnDisplayOptionsChanged() override
void FocusOnLibID(const LIB_ID &aLibID)
const PCB_PLOT_PARAMS & GetPlotSettings() const override
Return the PCB_PLOT_PARAMS for the BOARD owned by this frame.
bool m_suppressTabActivation
Set while a full clear tears the tab strip down so the panel's close-driven re-activation does not re...
static bool prepareFootprintTabHandoff(FOOTPRINT *aFootprint, bool aHasTabs)
Decide whether aFootprint opens in its own tab and, if so, detach it from the board it arrived parent...
std::unique_ptr< FOOTPRINT > m_originalFootprintCopy
void ReloadFootprint(FOOTPRINT *aFootprint) override
Override from PCB_BASE_FRAME which reloads the footprint from the library without setting the footpri...
EDA_ANGLE GetRotationAngle() const override
Return the angle used for rotate operations.
void RefreshLibraryTree()
Redisplay the library tree.
void installFootprintTabBoard(FOOTPRINT_EDITOR_TAB_CONTEXT *aCtx, BOARD *aBoard)
Install aBoard as the active document non-destructively, wiring the tool environment and resetting th...
void OnExitKiCad(wxCommandEvent &aEvent)
bool promptAndCloseFootprintTab(int aIdx)
Prompt to save if needed, then drop the tab context at aIdx.
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
MAGNETIC_SETTINGS * GetMagneticItemsSettings() override
FOOTPRINT_EDITOR_SETTINGS * GetSettings()
FOOTPRINT_EDITOR_TAB_CONTEXT * findOrCreateFootprintTab(const LIB_ID &aLibId, bool aAsPreview)
Find or create the tab for aLibId over its own fp-holder board and make it the active tab.
void SwitchCanvas(EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType) override
Switch the currently used canvas (Cairo / OpenGL).
void freeUndoRedoCommandsWithItems(UNDO_REDO_CONTAINER &aUndo, UNDO_REDO_CONTAINER &aRedo)
Free both the transient board items and the command wrappers in the given lists.
void installFootprintOnActiveBoard(FOOTPRINT *aFootprint)
Replace the active board's footprint with aFootprint and re-point the file watcher at it.
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
An interface to the global shared library manager that is schematic-specific and linked to one projec...
Footprint Editor pane with footprint library tree.
bool FixUuids()
Old footprints do not always have a valid UUID (some can be set to null uuid) However null UUIDs,...
void SetPosition(const VECTOR2I &aPos) override
void SetLink(const KIID &aLink)
Definition footprint.h:1267
void SetLocked(bool isLocked) override
Set the FP_is_LOCKED bit in the m_ModuleStatus.
Definition footprint.h:705
ZONES & Zones()
Definition footprint.h:411
void SetOrientation(const EDA_ANGLE &aNewAngle)
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const override
Invoke a function on all children.
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
std::deque< PAD * > & Pads()
Definition footprint.h:405
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition footprint.h:450
const LIB_ID & GetFPID() const
Definition footprint.h:474
const LSET & GetStackupLayers() const
Definition footprint.h:549
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.
void ClearAllNets()
Clear (i.e.
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
KIID GetLink() const
Definition footprint.h:1266
const wxString & GetReference() const
Definition footprint.h:909
FOOTPRINT_STACKUP GetStackupMode() const
Definition footprint.h:542
VECTOR2I GetPosition() const override
Definition footprint.h:436
DRAWINGS & GraphicalItems()
Definition footprint.h:408
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
void AddLibraries(EDA_BASE_FRAME *aParent)
void Sync(FOOTPRINT_LIBRARY_ADAPTER *aLibs)
static wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > Create(FOOTPRINT_EDIT_FRAME *aFrame, FOOTPRINT_LIBRARY_ADAPTER *aLibs)
void ReadWindowSettings(WINDOW_SETTINGS &aCfg)
Read GAL config options from application-level config.
void RegisterHandler(API_HANDLER *aHandler)
Adds a new request handler to the server.
void DeregisterHandler(API_HANDLER *aHandler)
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition kidialog.h:38
int ShowModal() override
Definition kidialog.cpp:89
bool m_axesEnabled
Whether or not to draw the coordinate system axes.
void SetAxesEnabled(bool aAxesEnabled)
Enable drawing the axes.
void SetGridOrigin(const VECTOR2D &aGridOrigin)
Set the origin point for the grid.
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:87
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:63
double GetScale() const
Definition view.h:283
const VECTOR2D & GetCenter() const
Return the center point of this VIEW (in world space coordinates).
Definition view.h:362
virtual void SetScale(double aScale, VECTOR2D aAnchor={ 0, 0 })
Set the scaling factor, zooming around a given anchor point.
Definition view.cpp:651
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition view.cpp:884
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition view.h:416
GAL * GetGAL() const
Return the GAL this view is using to draw graphical primitives.
Definition view.h:209
void SetCenter(const VECTOR2D &aCenter)
Set the center point of the VIEW (i.e.
Definition view.cpp:677
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition view.h:670
Definition kiid.h:46
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:348
void OnKiCadExit()
Definition kiway.cpp:790
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:388
Module editor specific tools.
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition lib_id.cpp:124
bool IsValid() const
Check if this LID_ID is valid.
Definition lib_id.h:168
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:113
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition lib_id.h:108
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:83
wxDataViewItem FindItem(const LIB_ID &aLibId)
Returns tree item corresponding to part.
void RefreshLibTree()
Refresh the tree (mainly to update highlighting and asterisking)
Definition lib_tree.cpp:492
void CenterLibId(const LIB_ID &aLibId)
Ensure that an item is visible (preferably centered).
Definition lib_tree.cpp:382
void ShutdownPreviews()
Definition lib_tree.cpp:282
void ShowChangedLanguage()
Definition lib_tree.cpp:299
std::vector< LIB_ID > GetExpandedLibraries() const
Definition lib_tree.cpp:402
void SelectLibId(const LIB_ID &aLibId)
Select an item in the tree widget.
Definition lib_tree.cpp:370
LIB_TREE_MODEL_ADAPTER::SORT_MODE GetSortMode() const
Definition lib_tree.h:151
void Unselect()
Unselect currently selected item in wxDataViewCtrl.
Definition lib_tree.cpp:388
LIB_ID GetSelectedLibId(int *aUnit=nullptr) const
For multi-unit symbols, if the user selects the symbol itself rather than picking an individual unit,...
Definition lib_tree.cpp:309
void ExpandLibId(const LIB_ID &aLibId)
Expand and item i the tree widget.
Definition lib_tree.cpp:396
void Regenerate(bool aKeepState)
Regenerate the tree.
Definition lib_tree.cpp:474
void SetSortMode(LIB_TREE_MODEL_ADAPTER::SORT_MODE aMode)
Save/restore the sorting mode.
Definition lib_tree.h:150
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition lset.cpp:604
static const LSET & UserMask()
Definition lset.cpp:686
static int NameToLayer(wxString &aName)
Return the layer number from a layer name.
Definition lset.cpp:113
static const LSET & AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition lset.cpp:672
static LSET UserDefinedLayersMask(int aUserDefinedLayerCount=MAX_USER_DEFINED_LAYERS)
Return a mask with the requested number of user defined layers.
Definition lset.cpp:700
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition lset.cpp:184
void ExitPadEditMode()
Definition pad_tool.cpp:814
bool InPadEditMode()
Definition pad_tool.h:58
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition page_info.h:75
Gather all the actions that are shared by tools.
Definition pcb_actions.h:51
static TOOL_ACTION drawRuleArea
static TOOL_ACTION drawBezier
static TOOL_ACTION placeText
static TOOL_ACTION drawOrthogonalDimension
static TOOL_ACTION drawRectangle
static TOOL_ACTION setAnchor
static TOOL_ACTION padDisplayMode
static TOOL_ACTION placeReferenceImage
static TOOL_ACTION showLayersManager
static TOOL_ACTION addConstraintVertical
static TOOL_ACTION drawCircle
static TOOL_ACTION mirrorH
Mirroring of selected items.
static TOOL_ACTION exportFootprint
static TOOL_ACTION drawEllipseArc
static TOOL_ACTION drawTable
static TOOL_ACTION drawTextBox
static TOOL_ACTION addConstraintPerpendicular
static TOOL_ACTION drawPolygon
static TOOL_ACTION placePad
Activation of the drawing tool (placing a PAD)
static TOOL_ACTION drawRadialDimension
static TOOL_ACTION padTable
static TOOL_ACTION editTextAndGraphics
static TOOL_ACTION drawLeader
static TOOL_ACTION addConstraintAngular
static TOOL_ACTION addConstraintArcAngle
static TOOL_ACTION angleSnapModeChanged
Notification event when angle mode changes.
static TOOL_ACTION addConstraintHorizontal
static TOOL_ACTION drawEllipse
static TOOL_ACTION ddImportFootprint
static TOOL_ACTION placeImportedGraphics
static TOOL_ACTION addConstraintCollinear
static TOOL_ACTION drawArc
static TOOL_ACTION graphicsOutlines
Display footprint graphics as outlines.
static TOOL_ACTION addConstraintEqualRadius
static TOOL_ACTION addConstraintTangent
static TOOL_ACTION loadFpFromBoard
static TOOL_ACTION drawCenterDimension
static TOOL_ACTION addConstraintFixedLength
static TOOL_ACTION footprintProperties
static TOOL_ACTION flipBoard
static TOOL_ACTION toggleAutoConstraints
Toggle authoring constraints automatically while drawing.
static TOOL_ACTION textOutlines
Display texts as lines.
static TOOL_ACTION checkFootprint
static TOOL_ACTION placeBarcode
static TOOL_ACTION placePoint
static TOOL_ACTION editLibFpInFpEditor
static TOOL_ACTION addConstraintSymmetric
static TOOL_ACTION addConstraintFixedPosition
Ground a point, and the cluster holding it.
static TOOL_ACTION mirrorV
static TOOL_ACTION addConstraintPointOnLine
static TOOL_ACTION repairFootprint
static TOOL_ACTION saveFpToBoard
static TOOL_ACTION addConstraintCoincident
static TOOL_ACTION drawLine
static TOOL_ACTION cleanupGraphics
static TOOL_ACTION rotateCw
Rotation of selected objects.
static TOOL_ACTION rotateCcw
static TOOL_ACTION addConstraintParallel
static TOOL_ACTION drawAlignedDimension
static TOOL_ACTION addConstraintFixedRadius
static TOOL_ACTION addConstraintEqualLength
static TOOL_ACTION addConstraintMidpoint
static TOOL_ACTION addConstraintConcentric
void ClearListAndDeleteItems(PICKED_ITEMS_LIST *aList)
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.
PCB_BASE_EDIT_FRAME(KIWAY *aKiway, wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName)
APPEARANCE_CONTROLS * m_appearancePanel
PANEL_SELECTION_FILTER * m_selectionFilterPanel
void ActivateGalCanvas() override
Use to start up the GAL drawing canvas.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
virtual const PCB_PLOT_PARAMS & GetPlotSettings() const
Return the PCB_PLOT_PARAMS for the BOARD owned by this frame.
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.
void setFPWatcher(FOOTPRINT *aFootprint)
Create or removes a watcher on the specified footprint.
PCBNEW_SETTINGS * GetPcbNewSettings() const
void OnModify() override
Must be called after a change in order to set the "modify" flag and update other data structures and ...
const VECTOR2I & GetGridOrigin() const override
Return the absolute coordinates of the origin of the snap grid.
const PAGE_INFO & GetPageSettings() const override
BOX2I GetBoardBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
EDA_ITEM * ResolveItem(const KIID &aId, bool aAllowNullptrReturn=false) const override
Fetch an item by KIID.
FOOTPRINT * LoadFootprint(const LIB_ID &aFootprintId)
Attempt to load aFootprintId from the footprint library table.
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 void AddFootprintToBoard(FOOTPRINT *aFootprint)
Add the given footprint to the board.
PCB_DISPLAY_OPTIONS m_displayOptions
FOOTPRINT_EDITOR_SETTINGS * GetFootprintEditorSettings() const
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
bool m_FlipBoardView
true if the board is flipped to show the mirrored view
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
void UpdateColors()
Update the color settings in the painter and GAL.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the KIGFX::VIEW instance used in the panel.
void DisplayBoard(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr)
Add all items from the current board to the VIEW, so they can be displayed by GAL.
Group generic conditions for PCB editor states.
SELECTION_CONDITION PadFillDisplay()
Create a functor that tests if the frame fills the pads.
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 TextFillDisplay()
Create a functor that tests if the frame fills text items.
The main frame for Pcbnew.
Generic tool for picking an item.
Parameters and options when plotting/printing a board.
Tool that displays edit points allowing to modify items by dragging the points.
The selection tool: currently supports:
void select(EDA_ITEM *aItem) override
Take necessary action mark an item as selected.
Tool useful for viewing footprints.
KICAD_API_SERVER & GetApiServer()
Definition pgm_base.h:141
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:123
A holder to handle information on schematic or board items.
The interactive edit tool.
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
@ PCB_FOOTPRINT_EDITOR_FP_NAME
Definition project.h:226
@ PCB_FOOTPRINT_EDITOR_LIB_NICKNAME
Definition project.h:227
virtual void SetRString(RSTRING_T aStringId, const wxString &aString)
Store a "retained string", which is any session and project specific string identified in enum RSTRIN...
Definition project.cpp:355
virtual const wxString & GetRString(RSTRING_T aStringId)
Return a "retained string", which is any session and project specific string identified in enum RSTRI...
Definition project.cpp:366
Action handler for the Properties panel.
RAII class that sets an value at construction and resets it to the original value at destruction.
static SELECTION_CONDITION HasType(KICAD_T aType)
Create a functor that tests if among the selected items there is at least one of a given type.
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 bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
T * GetAppSettings(const char *aFilename)
Return a handle to the a given settings by type.
TOOL_MANAGER * m_toolManager
TOOL_DISPATCHER * m_toolDispatcher
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
ACTIONS * m_actions
Base abstract interface for all kinds of tools.
Definition tool_base.h:62
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition tool_base.h:76
virtual void DispatchWxEvent(wxEvent &aEvent)
Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those.
Master controller class:
T * GetTool()
Return the tool of given type or nullptr if there is no such tool registered.
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
void ResetTools(TOOL_BASE::RESET_REASON aReason)
Reset all tools (i.e.
A holder to handle a list of undo (or redo) commands.
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
EDA_UNITS GetUserUnits() const
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition utf8.h:67
bool empty() const
Definition utf8.h:105
wxString wx_str() const
Definition utf8.cpp:41
A modified version of the wxInfoBar class that allows us to:
Definition wx_infobar.h:76
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
bool HasCloseButton() const
void AddLink(const wxString &aLinkText, const std::function< void(wxHyperlinkEvent &)> &aFn)
Add a hypertext link to the infobar.
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
This file is part of the common library.
#define CHECK(x)
#define ENABLE(x)
static bool empty(const wxTextEntryBase *aCtrl)
@ DRCE_MISSING_COURTYARD
Definition drc_item.h:69
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:448
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:450
#define KICAD_DEFAULT_DRAWFRAME_STYLE
#define FOOTPRINT_EDIT_FRAME_NAME
@ RECURSE
Definition eda_item.h:51
FOOTPRINT_STACKUP
Definition footprint.h:156
@ EXPAND_INNER_LAYERS
The 'normal' stackup handling, where there is a single inner layer (In1) and rule areas using it expa...
Definition footprint.h:161
@ CUSTOM_LAYERS
Stackup handling where the footprint can have any number of copper layers, and objects on those layer...
Definition footprint.h:166
static std::unique_ptr< BOARD > makeFpHolderBoard(FOOTPRINT_EDITOR_SETTINGS *aCfg)
#define CURRENT_EDIT_TOOL(action)
@ FRAME_PCB_EDITOR
Definition frame_type.h:38
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:39
a few functions useful in geometry calculations.
static const std::string KiCadFootprintLibPathExtension
static const std::string KiCadFootprintFileExtension
static wxString PngFileWildcard()
@ ID_ON_GRID_SELECT
Definition id.h:113
@ ID_ON_ZOOM_SELECT
Definition id.h:112
PROJECT & Prj()
Definition kicad.cpp:733
EVT_MENU(ID_COMPARE_PROJECT_BRANCHES, KICAD_MANAGER_FRAME::OnCompareProjectBranches) KICAD_MANAGER_FRAME
TAB_VISUAL_STATE ResolveTabVisualState(bool aPreview, bool aModified)
Resolve a tab's decorations from its document state flags.
KIID niluuid(0)
bool IsUserLayer(PCB_LAYER_ID aLayerId)
Test whether a layer is a non copper and a non tech layer.
Definition layer_ids.h:785
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ B_Cu
Definition layer_ids.h:61
@ F_SilkS
Definition layer_ids.h:96
@ In1_Cu
Definition layer_ids.h:62
@ F_Cu
Definition layer_ids.h:60
This file contains miscellaneous commonly used macros and functions.
@ TARGET_NONCACHED
Auxiliary rendering target (noncached)
Definition definitions.h:34
void SetShutdownBlockReason(wxWindow *aWindow, const wxString &aReason)
Sets the block reason why the window/application is preventing OS shutdown.
Definition unix/app.cpp:102
bool SupportsShutdownBlockReason()
Whether or not the window supports setting a shutdown block reason.
Definition unix/app.cpp:91
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:612
#define _HKI(x)
Definition page_info.cpp:40
@ ID_FPEDIT_SAVE_PNG
Definition pcbnew_id.h:82
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
@ RPT_SEVERITY_WARNING
#define DEFAULT_THEME
T * GetToolbarSettings(const wxString &aFilename)
T * GetAppSettings(const char *aFilename)
KIWAY Kiway(KFCTL_STANDALONE)
wxString UnescapeString(const wxString &aSource)
View snapshot captured on detach, restored on activate.
One open tab persisted across sessions.
Visual decorations derived from document state: preview is italic, modified is bold with a leading as...
#define ENVVARS_CHANGED
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:103
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:85
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:84
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:79
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
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.