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
350 m_acceptedExts.emplace( wxS( "jpeg" ), &PCB_ACTIONS::ddPlaceReferenceImage );
351 DragAcceptFiles( true );
352
354
355 // Apply saved visibility stuff at the end
356 wxAuiPaneInfo& treePane = m_auimgr.GetPane( "Footprints" );
357 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
358
359 if( libWidth > 0 )
360 SetAuiPaneSize( m_auimgr, treePane, libWidth, -1 );
361
362 if( aui_cfg.right_panel_width > 0 )
363 SetAuiPaneSize( m_auimgr, layersManager, aui_cfg.right_panel_width, -1 );
364
365 m_appearancePanel->SetTabIndex( aui_cfg.appearance_panel_tab );
366
368 {
369 m_appearancePanel->SetUserLayerPresets( cfg->m_LayerPresets );
370 m_appearancePanel->ApplyLayerPreset( cfg->m_ActiveLayerPreset );
371 }
372
373 // restore the last footprint from the project, if any, after the library has been init'ed
374 // N.B. This needs to happen after the AUI manager has been initialized so that we can
375 // properly call the WX_INFOBAR without crashing on some systems.
377
378 m_apiHandler = std::make_unique<API_HANDLER_FOOTPRINT>( this );
380
381 if( Kiface().IsSingle() )
382 {
383 m_apiHandlerCommon = std::make_unique<API_HANDLER_COMMON>();
385 m_apiHandlerFpLibs = std::make_unique<API_HANDLER_LIBRARIES>(
388 }
389
390 GetToolManager()->PostAction( ACTIONS::zoomFitScreen );
392
394
395 // This displays the last footprint loaded, if any, so it must be done after restoreLastFootprint()
397
398 // Default shutdown reason until a file is loaded
399 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "Footprint changes are unsaved" ) );
400
401 // Catch unhandled accelerator command characters that were no handled by the library tree
402 // panel.
404 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
405
406 // GTK rejects WXK_TAB as a menu accelerator, so handle Ctrl+Tab cycling from the CHAR_HOOK
407 // stream. Binding after the dispatcher runs this handler first so it can consume the event.
408 Bind( wxEVT_CHAR_HOOK, &FOOTPRINT_EDIT_FRAME::OnTabCharHook, this );
409
410 // Ensure the window is on top
411 Raise();
412 Show( true );
413
414 // Register a call to update the toolbar sizes. It can't be done immediately because
415 // it seems to require some sizes calculated that aren't yet (at least on GTK).
416 CallAfter(
417 [this]()
418 {
419 // Ensure the controls on the toolbars all are correctly sized
421 m_treePane->FocusSearchFieldIfExists();
422
423 // Update the angle snap mode toolbar button to reflect the current preference
425 } );
426}
427
428
430{
432
433 if( Kiface().IsSingle() )
434 {
437 }
438
439 // Hand the borrowed canvas back before the base destructor deletes it, or the later-destroyed
440 // panel would reparent already-freed memory. The canvas then frees exactly once.
441 m_tabsPanel->ReleaseSharedCanvas();
442
443 // Shutdown all running tools
444 if( m_toolManager )
445 m_toolManager->ShutdownAllTools();
446
447 // save the footprint in the PROJECT
449
450 // Clear the watched file
451 setFPWatcher( nullptr );
452
453 // When a tab context owns the active board, null the frame pointer so the base destructor does
454 // not double-free it. A frame-owned bootstrap board is left for the base class to delete.
456 m_pcb = nullptr;
457
458 // We passed ownership of these to wxAuiManager.
459 // delete m_selectionFilterPanel;
460 // delete m_appearancePanel;
461 // delete m_treePane;
462}
463
464
466{
468
469 FOOTPRINT* fp = static_cast<FOOTPRINT*>( GetModel() );
470
471 if( fp )
472 {
473 std::vector<MSG_PANEL_ITEM> msgItems;
474 fp->GetMsgPanelInfo( this, msgItems );
475 SetMsgPanel( msgItems );
476 }
477}
478
479
486
487
489{
490 return m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
491}
492
493
495{
496 // switches currently used canvas (Cairo / OpenGL).
497 PCB_BASE_FRAME::SwitchCanvas( aCanvasType );
498
499 GetCanvas()->GetGAL()->SetAxesEnabled( true );
500
501 // The base class method *does not reinit* the layers manager. We must update the layer
502 // widget to match board visibility states, both layers and render columns, and and some
503 // settings dependent on the canvas.
505}
506
507
513
514
516{
517 wxAuiPaneInfo& treePane = m_auimgr.GetPane( m_treePane );
518 treePane.Show( !IsLibraryTreeShown() );
519
520 if( IsLibraryTreeShown() )
521 {
522 // SetAuiPaneSize also updates m_auimgr
523 SetAuiPaneSize( m_auimgr, treePane, m_editorSettings->m_LibWidth, -1 );
524 }
525 else
526 {
527 m_editorSettings->m_LibWidth = m_treePane->GetSize().x;
528 m_auimgr.Update();
529 }
530}
531
532
534{
535 m_treePane->FocusSearchFieldIfExists();
536}
537
538
540{
542 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
543 wxAuiPaneInfo& selectionFilter = m_auimgr.GetPane( "SelectionFilter" );
544
545 // show auxiliary Vertical layers and visibility manager toolbar
547 layersManager.Show( m_show_layer_manager_tools );
548 selectionFilter.Show( m_show_layer_manager_tools );
549
551 {
552 SetAuiPaneSize( m_auimgr, layersManager, settings->m_AuiPanels.right_panel_width, -1 );
553 }
554 else
555 {
556 settings->m_AuiPanels.right_panel_width = m_appearancePanel->GetSize().x;
557 m_auimgr.Update();
558 }
559}
560
561
563{
564 return const_cast<wxAuiManager&>( m_auimgr ).GetPane( m_treePane ).IsShown();
565}
566
567
569{
570 // A tab close transiently leaves the frame with no board while UI repaints can still run.
571 if( !GetBoard() )
572 return nullptr;
573
574 return GetBoard()->GetFirstFootprint();
575}
576
577
579{
580 LIB_ID id;
581
582 if( IsLibraryTreeShown() )
584
585 if( id.GetLibNickname().empty() )
586 id = GetLoadedFPID();
587
588 return id;
589}
590
591
593{
594 // The board pointer is transiently null during a tab close while the library tree adapter can
595 // still repaint, so tolerate having no board.
596 if( !GetBoard() )
597 return LIB_ID();
598
599 FOOTPRINT* footprint = GetBoard()->GetFirstFootprint();
600
601 if( footprint )
602 return LIB_ID( footprint->GetFPID().GetLibNickname(), m_footprintNameWhenLoaded );
603 else
604 return LIB_ID();
605}
606
607
609{
610 if( GetBoard() && GetBoard()->GetFirstFootprint() )
611 {
614 }
615
616 GetScreen()->SetContentModified( false );
617
618 // OnModify() mirrors the dirty flag onto the active tab context and the panel model, so clear both
619 // here too. Tab rendering and close prompting read the context's flag, so a save that only cleared
620 // the shared screen would leave the tab starred and re-prompting to save.
621 if( m_activeTab )
622 {
623 m_activeTab->SetModified( false );
624
625 if( int idx = m_tabsPanel->FindTab( m_activeTab->GetTabKey() ); idx >= 0 )
626 m_tabsPanel->MarkModified( idx, false );
627 }
628}
629
630
632{
633 // If we've already vetted closing this window, then we have no FP anymore
634 if( m_isClosing || !GetBoard() )
635 return false;
636
637 FOOTPRINT* footprint = GetBoard()->GetFirstFootprint();
638
639 return ( footprint && footprint->GetLink() != niluuid );
640}
641
642
644{
645 LIB_ID id = GetLoadedFPID();
646
647 if( id.IsValid() )
648 {
650 Prj().SetRString( PROJECT::PCB_FOOTPRINT_EDITOR_FP_NAME, id.GetLibItemName() );
651 }
652}
653
654
656{
657 // Restore the persisted tab set first. The active tab is loaded last so it ends up focused, and
658 // tabs that no longer resolve are silently dropped.
659 if( FOOTPRINT_EDITOR_SETTINGS* cfg = GetSettings(); cfg && !cfg->m_OpenTabs.empty() )
660 {
661 const wxString activeKey = cfg->m_ActiveTab;
662
663 const auto loadTab =
664 [this]( const FOOTPRINT_EDITOR_SETTINGS::OPEN_TAB& aTab ) -> bool
665 {
666 LIB_ID id;
667 id.SetLibNickname( aTab.m_lib );
668 id.SetLibItemName( aTab.m_fpName );
669
670 if( FOOTPRINT* footprint = LoadFootprint( id ) )
671 {
672 AddFootprintToBoard( footprint );
673 findOrCreateFootprintTab( id, aTab.m_preview );
674
675 return true;
676 }
677
678 // LoadFootprint swallows the IO_ERROR when the library no longer resolves, so
679 // log the dropped tab to keep a failed restore diagnosable.
680 wxLogTrace( wxT( "KICAD_FP_TABS" ),
681 wxT( "Dropping persisted footprint tab '%s:%s' (failed to load)" ),
682 aTab.m_lib, aTab.m_fpName );
683
684 return false;
685 };
686
687 const FOOTPRINT_EDITOR_SETTINGS::OPEN_TAB* activeTab = nullptr;
688
689 for( const FOOTPRINT_EDITOR_SETTINGS::OPEN_TAB& tab : cfg->m_OpenTabs )
690 {
691 const wxString key = tab.m_lib + wxT( ":" ) + tab.m_fpName;
692
693 if( key == activeKey )
694 activeTab = &tab;
695 else
696 loadTab( tab );
697 }
698
699 if( activeTab )
700 loadTab( *activeTab );
701
702 if( !m_tabContexts.empty() )
703 return;
704 }
705
706 const wxString& footprintName = Prj().GetRString( PROJECT::PCB_FOOTPRINT_EDITOR_FP_NAME );
707 const wxString& libNickname = Prj().GetRString( PROJECT::PCB_FOOTPRINT_EDITOR_LIB_NICKNAME );
708
709 if( libNickname.Length() && footprintName.Length() )
710 {
711 LIB_ID id;
712 id.SetLibNickname( libNickname );
713 id.SetLibItemName( footprintName );
714
715 FOOTPRINT* footprint = LoadFootprint( id );
716
717 if( footprint )
718 {
719 AddFootprintToBoard( footprint );
720
721 // The last-session footprint is a real document, so promote its tab to permanent.
722 findOrCreateFootprintTab( id, false );
723 }
724 }
725}
726
727
729{
730 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( GetModel() );
731 BOARD& board = *GetBoard();
732
733 // All FPs have these layers enabled
734 LSET enabledLayers = LSET::AllTechMask() | LSET::UserMask();
735
736 const auto configureStackup =
737 [&]( FOOTPRINT_STACKUP aMode, const LSET& aLayerSet )
738 {
739 const LSET cuLayers = aLayerSet & LSET::AllCuMask();
740 board.SetCopperLayerCount( cuLayers.count() );
741
742 switch( aMode )
743 {
745 enabledLayers |= LSET{ F_Cu, In1_Cu, B_Cu };
746 board.SetLayerName( In1_Cu, _( "Inner layers" ) );
747 break;
748
750 // Nothing extra to add
751
752 // Clear layer name defaults
753 board.SetLayerName( In1_Cu, wxEmptyString );
754 break;
755 }
756
757 enabledLayers |= aLayerSet;
758 };
759
760 if( footprint )
761 {
762 configureStackup( footprint->GetStackupMode(), footprint->GetStackupLayers() );
763 }
764 else
765 {
766 // If no footprint is loaded, we assume the default stackup mode
767 configureStackup( FOOTPRINT_STACKUP::EXPAND_INNER_LAYERS, LSET{} );
768 }
769
771 {
772 m_originalFootprintCopy->RunOnChildren(
773 [&]( BOARD_ITEM* child )
774 {
775 LSET childLayers = child->GetLayerSet() & LSET::UserDefinedLayersMask();
776
777 for( PCB_LAYER_ID layer : childLayers )
778 enabledLayers.set( layer );
779 },
781 }
782
783 // Enable the user-configured number of user layers, plus any specifically named layers
785 {
786 int userLayerCount = cfg->m_DesignSettings.GetUserDefinedLayerCount();
787 enabledLayers |= LSET::UserDefinedLayersMask( userLayerCount );
788
789 for( const PCB_LAYER_ID& user : LSET::UserDefinedLayersMask() )
790 {
791 if( cfg->m_DesignSettings.m_UserLayerNames.contains( LSET::Name( user ).ToStdString() ) )
792 enabledLayers.set( user );
793 }
794 }
795
796 board.SetEnabledLayers( enabledLayers );
797
798 // Footprint Editor layer visibility is kept in the view, not the board (because the board
799 // just delegates to the project file, which we don't have).
800 for( const PCB_LAYER_ID& layer : GetBoard()->GetEnabledLayers() )
801 GetCanvas()->GetView()->SetLayerVisible( layer, true );
802}
803
804
806{
807 // Use CallAfter so that we update the canvas before waiting for the infobar animation
808 CallAfter(
809 [this]()
810 {
811 WX_INFOBAR& infobar = *GetInfoBar();
812 infobar.RemoveAllButtons();
813
814 wxArrayString msgs;
815 int infobarFlags = wxICON_INFORMATION;
816 FOOTPRINT* footprint = GetBoard() ? GetBoard()->GetFirstFootprint() : nullptr;
817 wxString lib = footprint ? footprint->GetFPID().GetLibNickname() : UTF8();
818
820 {
821 msgs.push_back( wxString::Format( _( "Editing %s from board. Saving will update the board only." ),
822 footprint->GetReference() ) );
823
824 infobar.AddLink( wxString::Format( _( "Open footprint from library %s" ), UnescapeString( lib ) ),
825 [this]( wxHyperlinkEvent& aEvent )
826 {
828 } );
829 }
830
831 if( footprint
833 && !PROJECT_PCB::FootprintLibAdapter( &Prj() )->IsFootprintLibWritable( lib ) )
834 {
835 msgs.push_back( _( "Library is read-only. Changes cannot be saved to this library." ) );
836
837 infobar.AddLink( _( "Save as editable copy" ),
838 [this]( wxHyperlinkEvent& aEvent )
839 {
840 SaveFootprintAs( GetBoard()->GetFirstFootprint() );
841 GetCanvas()->GetView()->Update( GetBoard()->GetFirstFootprint() );
842 ClearModify();
843
844 // Get rid of the save-will-update-board-only (or any other dismissable warning)
845 WX_INFOBAR* local_infobar = GetInfoBar();
846
847 if( local_infobar->IsShownOnScreen() && local_infobar->HasCloseButton() )
848 local_infobar->Dismiss();
849
851 SyncLibraryTree( true );
852 } );
853 }
854
855 if( msgs.empty() )
856 {
857 infobar.Dismiss();
858 }
859 else
860 {
861 wxString msg = wxJoin( msgs, '\n', '\0' );
862 infobar.AddCloseButton();
863 infobar.ShowMessage( msg, infobarFlags );
864 }
865 } );
866}
867
868
870{
871 // Cancel a mid-draw tool before the footprint it points into is freed (#24975).
872 if( GetToolManager() )
874
876
877 m_originalFootprintCopy.reset( static_cast<FOOTPRINT*>( aFootprint->Clone() ) );
878 m_originalFootprintCopy->SetParent( nullptr );
879
881
882 // Mirror the load baseline into the active tab context so it survives a tab switch (the frame
883 // members are only a borrowed view of the active context's baseline).
884 if( m_activeTab )
885 {
886 FOOTPRINT* fp_copy = nullptr;
887
889 fp_copy = static_cast<FOOTPRINT*>( m_originalFootprintCopy->Clone() );
890
891 m_activeTab->SetOriginalFootprintCopy( std::unique_ptr<FOOTPRINT>( fp_copy ) );
892 m_activeTab->SetFootprintNameWhenLoaded( m_footprintNameWhenLoaded );
893 m_activeTab->SetLibNickname( aFootprint->GetFPID().GetLibNickname() );
894 m_activeTab->SetFootprintName( aFootprint->GetFPID().GetLibItemName() );
895 }
896
898 // Ensure item UUIDs are valid
899 // ("old" footprints can have null uuids that create issues in fp editor)
900 aFootprint->FixUuids();
901
906}
907
908
910{
911 const bool fromBoard = aFootprint && aFootprint->GetLink() != niluuid;
912
913 if( !aHasTabs || !aFootprint || fromBoard || !aFootprint->GetFPID().IsValid() )
914 return false;
915
916 // A new footprint is parented to the board the tab switch is about to free, so drop the parent
917 // before the switch; ReloadFootprint reparents it to the incoming board
918 aFootprint->SetParent( nullptr );
919
920 return true;
921}
922
923
925{
926 // Opening from the library is a preview that the next library-open reuses; editing promotes it
927 // to a permanent tab.
928 if( prepareFootprintTabHandoff( aFootprint, m_tabsPanel != nullptr ) )
929 findOrCreateFootprintTab( aFootprint->GetFPID(), true );
930
931 ReloadFootprint( aFootprint );
932
934 setFPWatcher( nullptr );
935 else
936 setFPWatcher( aFootprint );
937}
938
939
941{
943 return true;
944
945 return std::any_of( m_tabContexts.begin(), m_tabContexts.end(),
946 [this]( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& aCtx )
947 {
948 return aCtx->GetBoard() == m_pcb;
949 } );
950}
951
952
954{
955 // Swap the board pointer without the SetBoard delete, since on a tab switch the outgoing board
956 // is owned by its tab context. Reproduce only the side effects SetBoard applies to the incoming
957 // board.
958 if( m_pcb == aBoard )
959 return;
960
961 // The only frame-owned board is the constructor's bootstrap board. Delete it when we first
962 // switch away so it does not leak; tab-owned boards are left to their contexts.
963 if( m_pcb && !activeBoardOwnedByTab() )
964 delete m_pcb;
965
966 m_pcb = aBoard;
967
968 if( GetBoard() )
970
971 if( GetBoard() && GetCanvas() )
972 {
973 if( KIGFX::RENDER_SETTINGS* rs = GetCanvas()->GetView()->GetPainter()->GetSettings() )
974 {
975 rs->SetDashLengthRatio( GetBoard()->GetPlotOptions().GetDashedLineDashRatio() );
976 rs->SetGapLengthRatio( GetBoard()->GetPlotOptions().GetDashedLineGapRatio() );
977 }
978
980 }
981
982 wxCommandEvent e( EDA_EVT_BOARD_CHANGED );
983 ProcessEventLocally( e );
984}
985
986
988{
989 if( !m_activeTab )
990 return;
991
992 KIGFX::VIEW* view = GetCanvas()->GetView();
993
994 EDITOR_TAB_CONTEXT::VIEW_SNAPSHOT& snap = m_activeTab->ViewSnapshot();
995 snap.scale = view->GetScale();
996 snap.center = view->GetCenter();
997 snap.valid = true;
998
999 std::vector<KIID>& sel = m_activeTab->SavedSelection();
1000 sel.clear();
1001
1002 for( EDA_ITEM* item : GetCurrentSelection() )
1003 sel.push_back( item->m_Uuid );
1004
1005 // Dirty state lives on the shared frame screen, so fold it into the context to survive the switch.
1006 if( GetScreen() )
1007 m_activeTab->SetModified( GetScreen()->IsContentModified() );
1008
1009 // Swap the raw vectors since UNDO_REDO_CONTAINER is non-copyable; ownership transfers intact.
1010 m_activeTab->UndoList().m_CommandsList.swap( m_undoList.m_CommandsList );
1011 m_activeTab->RedoList().m_CommandsList.swap( m_redoList.m_CommandsList );
1012
1013 m_activeTab = nullptr;
1014}
1015
1016
1018{
1019 if( !aCtx || aCtx == m_activeTab )
1020 return;
1021
1022 installFootprintTabBoard( aCtx, aCtx->GetBoard() );
1023}
1024
1025
1027{
1028 // Install the successor board and tool environment before the caller frees the outgoing context
1029 // so no tool Reset() or repaint ever sees a freed or null m_pcb. Never calls the base SetBoard,
1030 // which would delete m_pcb and reset tools while the model still aliases it.
1031
1033
1034 // Drop selection and unwind a mid-draw tool while the outgoing board is still valid (#24975).
1035 if( m_toolManager )
1036 {
1038 m_toolManager->DeactivateTool();
1039 }
1040
1041 m_activeTab = aCtx;
1042
1043 borrowBoardNonDestructive( aBoard );
1044
1045 if( aCtx )
1046 {
1047 m_undoList.m_CommandsList.swap( aCtx->UndoList().m_CommandsList );
1048 m_redoList.m_CommandsList.swap( aCtx->RedoList().m_CommandsList );
1049 }
1050 else
1051 {
1052 // Discard the swapped-in lists with their transient items so nothing references a freed board.
1054 }
1055
1057 ? static_cast<FOOTPRINT*>( aCtx->GetOriginalFootprintCopy()->Clone() )
1058 : nullptr );
1059 m_footprintNameWhenLoaded = aCtx ? aCtx->GetFootprintNameWhenLoaded() : wxString();
1060
1061 // Mirror the incoming tab's board-uuid remap onto the frame so SaveFootprintToBoard saves an
1062 // instance edit back to the originating board items. A library tab has an empty map.
1063 if( aCtx )
1065 else
1066 m_boardFootprintUuids.clear();
1067
1068 if( GetScreen() )
1069 GetScreen()->SetContentModified( aCtx ? aCtx->IsModified() : false );
1070
1071 // Point the tool environment at the incoming board before ResetTools so tools never dereference
1072 // a freed model.
1073 m_toolManager->SetEnvironment( GetBoard(), GetCanvas()->GetView(), GetCanvas()->GetViewControls(), config(),
1074 this );
1075
1078
1080
1081 FOOTPRINT* activeFootprint = GetBoard()->GetFirstFootprint();
1082
1083 if( IsCurrentFPFromBoard() )
1084 setFPWatcher( nullptr );
1085 else
1086 setFPWatcher( activeFootprint );
1087
1088 if( !aCtx )
1089 {
1091 updateInfoBar();
1095 return;
1096 }
1097
1098 const EDITOR_TAB_CONTEXT::VIEW_SNAPSHOT& snap = aCtx->ViewSnapshot();
1099
1100 if( snap.valid )
1101 {
1102 GetCanvas()->GetView()->SetScale( snap.scale );
1103 GetCanvas()->GetView()->SetCenter( snap.center );
1104 }
1105 else
1106 {
1107 // First time this tab is shown there is no saved view
1109 }
1110
1111 if( !aCtx->SavedSelection().empty() )
1112 {
1114
1115 if( selTool )
1116 {
1117 for( const KIID& id : aCtx->SavedSelection() )
1118 {
1119 if( BOARD_ITEM* item = GetBoard()->ResolveItem( id, true ) )
1120 selTool->select( item );
1121 }
1122 }
1123 }
1124
1125 if( m_appearancePanel )
1126 m_appearancePanel->OnBoardChanged();
1127
1128 if( m_propertiesPanel )
1129 m_propertiesPanel->UpdateData();
1130
1132 updateInfoBar();
1136}
1137
1138
1139static std::unique_ptr<BOARD> makeFpHolderBoard( FOOTPRINT_EDITOR_SETTINGS* aCfg )
1140{
1141 auto board = std::make_unique<BOARD>();
1142 board->SetBoardUse( BOARD_USE::FPHOLDER );
1143 board->GetDesignSettings().m_NetSettings->GetDefaultNetclass()->SetClearance( 0 );
1144 board->GetDesignSettings().m_SolderMaskExpansion = 0;
1145 board->SetVisibleAlls();
1146
1147 // Get our own settings; aCfg will be the PCBNEW_SETTINGS because we're part of the pcbnew
1148 // compile unit
1149 if( aCfg )
1150 {
1151 board->GetDesignSettings() = aCfg->m_DesignSettings;
1152
1153 for( auto& [source_name, dest_name] : aCfg->m_DesignSettings.m_UserLayerNames )
1154 {
1155 wxString wx_source_name = source_name;
1156 PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( LSET::NameToLayer( wx_source_name ) );
1157
1158 if( IsUserLayer( layer ) )
1159 board->SetLayerName( layer, dest_name );
1160 }
1161 }
1162
1163 return board;
1164}
1165
1166
1168{
1169 const wxString lib = aLibId.GetLibNickname();
1170 const wxString name = aLibId.GetLibItemName();
1171 const wxString key = lib + wxT( ":" ) + name;
1172
1173 if( int existing = m_tabsPanel->FindTab( key ); existing >= 0 )
1174 {
1175 m_tabsPanel->ActivateOrCreateTab( key, name, aAsPreview );
1176 return m_tabContexts[existing].get();
1177 }
1178
1179 auto ctx = std::make_unique<FOOTPRINT_EDITOR_TAB_CONTEXT>( lib, name, makeFpHolderBoard( GetSettings() ) );
1180 ctx->SetPreview( aAsPreview );
1181
1182 FOOTPRINT_EDITOR_TAB_CONTEXT* raw = ctx.get();
1183
1184 // Keep m_tabContexts index-aligned with the panel model. A previewed open reuses the preview
1185 // slot in place; otherwise the context is appended. It must be at its final index before AddTab
1186 // fires onActivateTab.
1187 const int reuseSlot = aAsPreview ? m_tabsPanel->Model().PreviewIndex() : -1;
1188
1189 if( reuseSlot >= 0 && reuseSlot < static_cast<int>( m_tabContexts.size() ) )
1190 {
1191 // Tear the active document down while the outgoing board is still alive, before it is
1192 // displaced and freed.
1193 if( m_tabContexts[reuseSlot].get() == m_activeTab )
1194 {
1195 if( m_toolManager )
1197
1199 m_activeTab = nullptr;
1200 }
1201
1202 return placeReusedTabContext( m_tabContexts, reuseSlot, std::move( ctx ),
1203 [&]( const FOOTPRINT_EDITOR_TAB_CONTEXT& aDisplaced )
1204 {
1205 SCOPED_SET_RESET<BOARD*> protectedBoard( m_protectedBorrowedBoard, aDisplaced.GetBoard() );
1206 m_tabsPanel->ActivateOrCreateTab( key, name, aAsPreview );
1207 } );
1208 }
1209
1210 m_tabContexts.push_back( std::move( ctx ) );
1211
1212 m_tabsPanel->ActivateOrCreateTab( key, name, aAsPreview );
1213
1214 return raw;
1215}
1216
1217
1219 std::vector<std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>>& aContexts, int aSlot,
1220 std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT> aNew,
1221 const std::function<void( const FOOTPRINT_EDITOR_TAB_CONTEXT& )>& aInstallSuccessor )
1222{
1223 // Hold the displaced context, and its still-displayed board, alive across aInstallSuccessor, which
1224 // repoints the canvas VIEW at the incoming board. Freeing the old board first would leave
1225 // VIEW::Clear() dereferencing items from a destroyed board.
1226 std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT> displaced = std::move( aContexts[aSlot] );
1227 aContexts[aSlot] = std::move( aNew );
1228
1229 FOOTPRINT_EDITOR_TAB_CONTEXT* raw = aContexts[aSlot].get();
1230
1231 aInstallSuccessor( *displaced );
1232
1233 return raw;
1234}
1235
1236
1238{
1239 if( !aBoardFootprint )
1240 return nullptr;
1241
1242 const KIID sourceUuid = aBoardFootprint->m_Uuid;
1243 const wxString key = FOOTPRINT_EDITOR_TAB_CONTEXT::MakeInstanceTabKey( sourceUuid );
1244 const wxString& reference = aBoardFootprint->GetReference();
1245
1246 // Re-editing the same placed footprint focuses the live tab rather than duplicating it.
1247 if( int existing = m_tabsPanel->FindTab( key ); existing >= 0 )
1248 {
1249 m_tabsPanel->ActivateOrCreateTab( key, m_tabContexts[existing]->GetDisplayName(), false );
1250 return m_tabContexts[existing].get();
1251 }
1252
1253 std::unique_ptr<BOARD> board = makeFpHolderBoard( GetSettings() );
1254 board->GetDesignSettings().m_DRCSeverities[DRCE_MISSING_COURTYARD] = RPT_SEVERITY_WARNING;
1255
1256 auto ctx = std::make_unique<FOOTPRINT_EDITOR_TAB_CONTEXT>( sourceUuid, reference, std::move( board ) );
1257 BOARD* ctxBoard = ctx->GetBoard();
1258 std::map<KIID, KIID>& uuidMap = ctx->BoardFootprintUuids();
1259 FOOTPRINT_EDITOR_TAB_CONTEXT* raw = ctx.get();
1260
1261 const auto recordAndUpdateUuid =
1262 [&]( BOARD_ITEM* aItem )
1263 {
1264 KIID newId;
1265 uuidMap[newId] = aItem->m_Uuid;
1266 aItem->SetUuid( newId );
1267 };
1268
1269 // Clone keeps the existing uuids, which the remap then swaps for fresh editor-local ones so
1270 // SaveFootprintToBoard can map them back to the original board items.
1271 FOOTPRINT* clone = static_cast<FOOTPRINT*>( aBoardFootprint->Clone() );
1272 clone->SetParent( ctxBoard );
1273 clone->SetParentGroup( nullptr );
1274 clone->SetLink( aBoardFootprint->m_Uuid );
1275 clone->ClearFlags();
1276 clone->SetLocked( false );
1277
1278 recordAndUpdateUuid( clone );
1279 clone->RunOnChildren(
1280 [&]( BOARD_ITEM* aItem )
1281 {
1282 if( aItem->Type() == PCB_PAD_T )
1283 aItem->SetLocked( false );
1284
1285 aItem->ClearFlags();
1286 recordAndUpdateUuid( aItem );
1287 },
1289
1290 ctxBoard->Add( clone );
1291
1292 // The editor knows nothing of the board's nets, so force the orphaned dummy net on every pad to
1293 // avoid saving a reference to an unknown net into the library cache.
1294 clone->ClearAllNets();
1295
1296 // Normalize placement to the footprint-editor defaults so the editor view matches a library load.
1297 clone->SetPosition( VECTOR2I( 0, 0 ) );
1298
1299 if( clone->GetLayer() != F_Cu )
1300 clone->Flip( clone->GetPosition(), GetPcbNewSettings()->m_FlipDirection );
1301
1302 clone->SetOrientation( ANGLE_0 );
1303 clone->RunOnChildren(
1304 [&]( BOARD_ITEM* aItem )
1305 {
1306 if( aItem->Type() == PCB_TEXT_T )
1307 static_cast<PCB_TEXT*>( aItem )->KeepUpright();
1308 },
1310
1311 m_tabContexts.push_back( std::move( ctx ) );
1312
1313 // Index-aligned with the panel model; the context is at its final index before AddTab fires
1314 // onActivateTab.
1315 m_tabsPanel->ActivateOrCreateTab( key, m_tabContexts.back()->GetDisplayName(), false );
1316
1317 return raw;
1318}
1319
1320
1322{
1323 std::unique_ptr<BOARD> board = makeFpHolderBoard( GetSettings() );
1324 std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT> ctx = FOOTPRINT_EDITOR_TAB_CONTEXT::MakeUnsaved( std::move( board ) );
1325
1326 const wxString key = ctx->GetTabKey();
1327 FOOTPRINT_EDITOR_TAB_CONTEXT* raw = ctx.get();
1328
1329 m_tabContexts.push_back( std::move( ctx ) );
1330
1331 // At its final index before AddTab fires onActivateTab, which makes the new tab active
1332 m_tabsPanel->ActivateOrCreateTab( key, m_tabContexts.back()->GetDisplayName(), false );
1333
1334 return raw;
1335}
1336
1337
1339{
1340 // Free the UR_TRANSIENT board items each command owns and the command wrappers. The frame's own
1341 // ClearUndoRedoList() and the bare container destructor delete only the wrappers and leak the
1342 // transient items, so a discarded tab history must come through here.
1343 for( UNDO_REDO_CONTAINER* list : { &aUndo, &aRedo } )
1344 {
1345 for( PICKED_ITEMS_LIST* cmd : list->m_CommandsList )
1346 {
1348 delete cmd;
1349 }
1350
1351 list->m_CommandsList.clear();
1352 }
1353}
1354
1355
1357{
1358 // The context is detached here, so the transient items in its lists are never the live objects.
1360}
1361
1362
1364{
1365 if( aIdx < 0 || aIdx >= static_cast<int>( m_tabContexts.size() ) )
1366 return false;
1367
1369
1370 // The active tab's live dirty state lives on the shared frame screen, so ctx->IsModified() is
1371 // stale for it. Fold the screen state back in so an unsaved active tab still prompts.
1372 if( ctx == m_activeTab && GetScreen() )
1374
1375 if( ctx->IsModified() && !m_silentFootprintTabClose )
1376 {
1377 // Prompt while the closing tab is still fully live so a save reads its real board.
1378 wxString msg = wxString::Format( _( "Save changes to '%s' before closing?" ), ctx->GetDisplayName( true ) );
1379
1380 KIDIALOG dlg( this, msg, _( "Confirmation" ), wxYES_NO | wxCANCEL | wxICON_WARNING );
1381 dlg.SetYesNoCancelLabels( _( "Save" ), _( "Discard Changes" ), _( "Cancel" ) );
1382
1383 switch( dlg.ShowModal() )
1384 {
1385 case wxID_YES:
1386 {
1387 // SaveFootprint reads the active tab's load baseline for rename detection, so an inactive
1388 // tab must be made active first or it saves against the wrong baseline. Restore the prior
1389 // active tab afterwards so closing an inactive tab stays an inactive close, keeping the
1390 // panel's suppressed fallback selection aligned with the live board. Veto the close if the
1391 // save did not complete so the edits and history are not silently dropped.
1392 FOOTPRINT_EDITOR_TAB_CONTEXT* activeBeforeSave = m_activeTab;
1393 const bool activatedForSave = ( ctx != m_activeTab );
1394
1395 if( activatedForSave )
1396 activateFootprintTab( ctx );
1397
1398 const bool saved = SaveFootprint( ctx->GetBoard()->GetFirstFootprint() );
1399
1400 if( activatedForSave && activeBeforeSave )
1401 activateFootprintTab( activeBeforeSave );
1402
1403 if( !saved )
1404 return false;
1405
1406 break;
1407 }
1408
1409 case wxID_NO:
1410 break;
1411
1412 default:
1413 case wxID_CANCEL:
1414 return false;
1415 }
1416 }
1417
1418 const bool closingActive = ( ctx == m_activeTab );
1419
1420 if( !closingActive )
1421 {
1422 // m_pcb aliases a different live tab's board, so freeing this context dangles nothing.
1424 m_tabContexts.erase( m_tabContexts.begin() + aIdx );
1425 return true;
1426 }
1427
1428 // The closing tab's lists are currently the frame's live lists. Free them now with their
1429 // transient items, so the install's detach swaps empty lists into the closing context.
1431
1432 const int newCount = static_cast<int>( m_tabContexts.size() ) - 1;
1433 const int successorIdx = newCount > 0 ? std::min( aIdx, newCount - 1 ) : -1;
1434
1435 if( successorIdx >= 0 )
1436 {
1437 // Map the successor's post-erase position back to a pre-erase index. Indices above the closed
1438 // one shift down by one after the erase.
1439 const int preEraseSuccessor = successorIdx < aIdx ? successorIdx : successorIdx + 1;
1440
1441 FOOTPRINT_EDITOR_TAB_CONTEXT* successor = m_tabContexts[preEraseSuccessor].get();
1442
1443 installFootprintTabBoard( successor, successor->GetBoard() );
1444 }
1445 else
1446 {
1447 // Last tab: the fresh empty board is frame-owned like the bootstrap board.
1448 installFootprintTabBoard( nullptr, makeFpHolderBoard( GetSettings() ).release() );
1449 }
1450
1451 // The install swapped m_pcb off the closing board, so erasing the context frees it safely.
1452 m_tabContexts.erase( m_tabContexts.begin() + aIdx );
1453
1454 return true;
1455}
1456
1457
1459{
1460 const wxString lib = aFPID.GetLibNickname();
1461 const wxString name = aFPID.GetLibItemName();
1462 const int idx = m_tabsPanel->FindTab( lib + wxT( ":" ) + name );
1463
1464 if( idx < 0 )
1465 return;
1466
1467 // The caller already confirmed the deletion, so close without re-prompting. The panel selects a
1468 // successor when the closed tab was active.
1470 m_tabsPanel->CloseTab( idx );
1472}
1473
1474
1475void FOOTPRINT_EDIT_FRAME::RenameFootprintTab( const LIB_ID& aOldId, const LIB_ID& aNewId )
1476{
1477 const wxString newLib = aNewId.GetLibNickname();
1478 const wxString newName = aNewId.GetLibItemName();
1479
1480 if( aOldId.GetLibNickname().empty() )
1481 {
1482 // This test precludes a tree-driven rename, so we can assume that the active tab is being
1483 // renamed.
1484
1485 // An unsaved import is keyed by a session id, not by aOldId, so the save-as that named it
1486 // promotes the active tab.
1487 if( m_activeTab && m_activeTab->IsUnsaved() && !newLib.IsEmpty() )
1488 {
1489 const wxString unsavedKey = m_activeTab->GetTabKey();
1490
1491 m_activeTab->PromoteToLibrary( newLib, newName );
1492 m_tabsPanel->RenameTab( unsavedKey, m_activeTab->GetTabKey(), m_activeTab->GetDisplayName() );
1493
1494 return;
1495 }
1496
1497 // A board footprint's tab is named from the board instance's reference, not any properties of
1498 // the edited copy.
1499 if( m_activeTab && m_activeTab->IsFromBoard() && aOldId.GetLibNickname().empty() )
1500 return;
1501 }
1502
1503 const wxString oldLib = aOldId.GetLibNickname();
1504 const wxString oldName = aOldId.GetLibItemName();
1505 const wxString oldKey = oldLib + wxT( ":" ) + oldName;
1506 const int idx = m_tabsPanel->FindTab( oldKey );
1507
1508 if( idx < 0 )
1509 return;
1510
1511 if( idx < static_cast<int>( m_tabContexts.size() ) )
1512 {
1513 // A tab switch restores the context's baseline onto the frame, so it must track the rename too
1514 // or the next save would delete the pre-renamed library entry
1515 m_tabContexts[idx]->SetLibNickname( newLib );
1516 m_tabContexts[idx]->SetFootprintName( newName );
1517 m_tabContexts[idx]->SetFootprintNameWhenLoaded( newName );
1518 }
1519
1520 m_tabsPanel->RenameTab( oldKey, newLib + wxT( ":" ) + newName, newName );
1521}
1522
1523
1525{
1526 for( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& ctx : m_tabContexts )
1527 {
1528 if( ctx.get() == m_activeTab )
1529 {
1530 if( GetScreen() && GetScreen()->IsContentModified() )
1531 return true;
1532 }
1533 else if( ctx->IsModified() )
1534 {
1535 return true;
1536 }
1537 }
1538
1539 return false;
1540}
1541
1542
1544{
1545 if( !m_tabsPanel )
1546 return;
1547
1548 const LIB_ID& footprintId = aFootprint.GetFPID();
1549 const wxString key = footprintId.GetLibNickname().wx_str() + wxT( ':' ) + footprintId.GetLibItemName().wx_str();
1550 const int idx = m_tabsPanel->FindTab( key );
1551
1552 if( idx < 0 || idx >= static_cast<int>( m_tabContexts.size() ) )
1553 return;
1554
1556 FOOTPRINT_EDITOR_TAB_CONTEXT* originalActive = m_activeTab;
1557
1558 // If we have our own unsaved changes, then leave it be.
1559 if( ctx->IsModified() )
1560 return;
1561
1562 // We have to activate this footprint to work on it. We'll switch back to the user-selected
1563 // tab afterwards.
1564 activateFootprintTab( ctx );
1565
1566 // The old history contains pointers into the footprint ReloadFootprint is about to delete.
1568 ctx->SavedSelection().clear();
1569
1570 FOOTPRINT* replacement = static_cast<FOOTPRINT*>( aFootprint.Clone() );
1571 replacement->SetParent( nullptr );
1572 ReloadFootprint( replacement );
1573 replacement->ClearFlags();
1574 ClearModify();
1575
1576 // Switch back to the user-selected tab.
1577 if( originalActive && originalActive != ctx )
1578 activateFootprintTab( originalActive );
1579
1580 UpdateView();
1582 Update3DView( true, true );
1583}
1584
1585
1587{
1588 for( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& ctx : m_tabContexts )
1589 {
1590 if( ctx.get() != m_activeTab && ctx->IsModified() )
1591 return true;
1592 }
1593
1594 return false;
1595}
1596
1597
1599{
1600 // Active tab always goes first
1601 for( int ii = 0; ii < (int) m_tabContexts.size(); ++ii )
1602 {
1603 if( aFromBoardOnly && !m_tabContexts[ii]->IsFromBoard() )
1604 continue;
1605
1606 if( m_tabContexts[ii].get() == m_activeTab )
1607 {
1608 wxSafeYield( this, true ); // Allow frame to come to front before showing "Save Changes?"
1609
1610 if( !m_tabsPanel->CloseTab( ii ) )
1611 return false;
1612 }
1613 }
1614
1615 // Go from back so we don't have to worry about deletions
1616 for( int ii = (int) m_tabContexts.size() - 1; ii >= 0; --ii )
1617 {
1618 if( aFromBoardOnly && !m_tabContexts[ii]->IsFromBoard() )
1619 continue;
1620
1622 wxSafeYield( this, true ); // Allow tab to come to front before showing "Save Changes?"
1623
1624 if( !m_tabsPanel->CloseTab( ii ) )
1625 return false;
1626 }
1627
1628 return true;
1629}
1630
1631
1633{
1634 m_tabsPanel->RefreshTabLabels();
1635}
1636
1637
1639{
1640 wxCHECK( aReplacement, /* void */ );
1641
1642 // Install the fresh frame-owned board and reset the tools against it before any tab board is
1643 // freed, so no ResetTools or repaint sees a freed or null m_pcb.
1644 installFootprintTabBoard( nullptr, aReplacement );
1645
1646 // Tear the strip down without re-prompting to save, since unsaved changes were already handled.
1647 // Suppress the host close callback and tab activation so CloseAll only does panel bookkeeping.
1648 std::function<bool( int )> savedCb = std::move( m_tabsPanel->onCloseTabRequested );
1649 m_tabsPanel->onCloseTabRequested =
1650 []( int )
1651 {
1652 return true;
1653 };
1654
1656 m_tabsPanel->CloseAll();
1658
1659 m_tabsPanel->onCloseTabRequested = std::move( savedCb );
1660
1661 wxASSERT_MSG( m_pcb == aReplacement,
1662 wxT( "m_pcb must alias the frame-owned replacement before contexts are freed" ) );
1663
1664 for( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& ctx : m_tabContexts )
1666
1667 m_tabContexts.clear();
1668}
1669
1670
1672{
1673 m_tabsPanel->AdvanceTab( aForward );
1674}
1675
1676
1678{
1679 m_tabsPanel->CloseTab( m_tabsPanel->GetActiveTab() );
1680}
1681
1682
1687
1688
1693
1694
1696{
1697 wxFAIL_MSG( wxT( "Plotting not supported in Footprint Editor" ) );
1698
1700}
1701
1702
1704{
1705 wxFAIL_MSG( wxT( "Plotting not supported in Footprint Editor" ) );
1706}
1707
1708
1716
1717
1725
1726
1728{
1729 // Get our own settings; aCfg will be the PCBNEW_SETTINGS because we're part of the pcbnew
1730 // compile unit
1732
1733 if( cfg )
1734 {
1736
1738
1741
1743 m_selectionFilterPanel->SetCheckboxesFromFilter( cfg->m_SelectionFilter );
1744
1746
1747 for( auto& [source_name, dest_name] : cfg->m_DesignSettings.m_UserLayerNames )
1748 {
1749 wxString wx_source_name = source_name;
1750 PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( LSET::NameToLayer( wx_source_name ) );
1751
1752 if( IsUserLayer( layer ) )
1753 GetBoard()->SetLayerName( layer, dest_name );
1754 }
1755
1756 }
1757}
1758
1759
1761{
1763
1764 // Get our own settings; aCfg will be the PCBNEW_SETTINGS because we're part of the pcbnew
1765 // compile unit
1767
1768 if( cfg )
1769 {
1771
1774 cfg->m_LibWidth = m_treePane->GetSize().x;
1775
1776 if( TOOL_MANAGER* toolMgr = GetToolManager() )
1777 {
1778 if( PCB_SELECTION_TOOL* selTool = toolMgr->GetTool<PCB_SELECTION_TOOL>() )
1779 cfg->m_SelectionFilter = selTool->GetFilter();
1780 }
1781
1783
1784 if( m_propertiesPanel )
1785 {
1786 cfg->m_AuiPanels.show_properties = m_propertiesPanel->IsShownOnScreen();
1788 cfg->m_AuiPanels.properties_splitter = m_propertiesPanel->SplitterProportion();
1789 }
1790
1792
1793 if( m_appearancePanel )
1794 {
1797 cfg->m_LayerPresets = m_appearancePanel->GetUserLayerPresets();
1798 cfg->m_ActiveLayerPreset = m_appearancePanel->GetActiveLayerPreset();
1799 }
1800
1801 cfg->m_OpenTabs.clear();
1802 cfg->m_ActiveTab.Clear();
1803
1804 const std::vector<EDITOR_TABS_MODEL::ENTRY>& entries = m_tabsPanel->Model().Entries();
1805
1806 for( size_t i = 0; i < m_tabContexts.size(); ++i )
1807 {
1808 const FOOTPRINT_EDITOR_TAB_CONTEXT* ctx = m_tabContexts[i].get();
1809
1810 // Instance and unsaved-import tabs are session-only and never persisted
1811 if( ctx->IsTransient() )
1812 continue;
1813
1814 const bool preview = i < entries.size() && entries[i].preview;
1815
1816 cfg->m_OpenTabs.push_back( { ctx->GetLibNickname(), ctx->GetFootprintName(), preview } );
1817
1818 if( ctx == m_activeTab )
1819 cfg->m_ActiveTab = ctx->GetTabKey();
1820 }
1821 }
1822}
1823
1824
1825
1827{
1828 FOOTPRINT_EDITOR_SETTINGS* cfg = const_cast<FOOTPRINT_EDIT_FRAME*>( this )->GetSettings();
1829
1830 return cfg ? cfg->m_RotationAngle : ANGLE_90;
1831}
1832
1833
1834
1836{
1838 return ::GetColorSettings( cfg ? cfg->m_ColorTheme : DEFAULT_THEME );
1839}
1840
1841
1843{
1844 static MAGNETIC_SETTINGS fallback;
1845
1847 return &cfg->m_MagneticItems;
1848
1849 return &fallback;
1850}
1851
1852
1853const BOX2I FOOTPRINT_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
1854{
1855 FOOTPRINT* footprint = GetBoard()->GetFirstFootprint();
1856
1857 if( footprint )
1858 {
1859 bool hasGraphicalItem = footprint->Pads().size() || footprint->Zones().size();
1860
1861 if( !hasGraphicalItem )
1862 {
1863 for( const BOARD_ITEM* item : footprint->GraphicalItems() )
1864 {
1865 if( item->Type() == PCB_TEXT_T || item->Type() == PCB_TEXTBOX_T )
1866 continue;
1867
1868 hasGraphicalItem = true;
1869 break;
1870 }
1871 }
1872
1873 if( hasGraphicalItem )
1874 {
1875 return footprint->GetBoundingBox( false );
1876 }
1877 else
1878 {
1879 BOX2I newFootprintBB( { 0, 0 }, { 0, 0 } );
1880 newFootprintBB.Inflate( pcbIUScale.mmToIU( 12 ) );
1881 return newFootprintBB;
1882 }
1883 }
1884
1885 return GetBoardBoundingBox( false );
1886}
1887
1888
1889bool FOOTPRINT_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
1890{
1891 // Shutdown blocks must be determined and vetoed as early as possible, before any modal prompt.
1892 // IsContentModified only sees the active tab, so also account for dirty inactive tabs.
1893 if( KIPLATFORM::APP::SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
1895 {
1896 aEvent.Veto();
1897 return false;
1898 }
1899
1900 if( !HandleUnsavedChanges( false ) )
1901 {
1902 aEvent.Veto();
1903 return false;
1904 }
1905
1906 PAD_TOOL* padTool = m_toolManager->GetTool<PAD_TOOL>();
1907
1908 if( padTool->InPadEditMode() )
1909 padTool->ExitPadEditMode();
1910
1911 // Save footprint tree column widths
1912 m_adapter->SaveSettings();
1913
1914 return PCB_BASE_EDIT_FRAME::canCloseWindow( aEvent );
1915}
1916
1917
1919{
1920 // No more vetos
1921 GetCanvas()->SetEventDispatcher( nullptr );
1923
1925 wxTheApp->Unbind( EDA_EVT_PLUGIN_AVAILABILITY_CHANGED,
1927
1928 if( GetLibTree() )
1930
1931 // Do not show the layer manager during closing to avoid flicker
1932 // on some platforms (Windows) that generate useless redraw of items in
1933 // the Layer Manager
1934 m_auimgr.GetPane( wxT( "LayersManager" ) ).Show( false );
1935 m_auimgr.GetPane( wxT( "SelectionFilter" ) ).Show( false );
1936
1937 Clear_Pcb();
1938}
1939
1940
1941void FOOTPRINT_EDIT_FRAME::OnExitKiCad( wxCommandEvent& event )
1942{
1943 Kiway().OnKiCadExit();
1944}
1945
1946
1948{
1949 Close();
1950}
1951
1952
1954{
1955 // call my base class
1957
1958 // We have 2 panes to update.
1959 // For some obscure reason, the AUI manager hides the first modified pane.
1960 // So force show panes
1961 wxAuiPaneInfo& tree_pane_info = m_auimgr.GetPane( m_treePane );
1962 bool tree_shown = tree_pane_info.IsShown();
1963 tree_pane_info.Caption( _( "Libraries" ) );
1964
1965 wxAuiPaneInfo& lm_pane_info = m_auimgr.GetPane( m_appearancePanel );
1966 bool lm_shown = lm_pane_info.IsShown();
1967 lm_pane_info.Caption( _( "Appearance" ) );
1968 wxAuiPaneInfo& sf_pane_info = m_auimgr.GetPane( m_selectionFilterPanel );
1969 sf_pane_info.Caption( _( "Selection Filter" ) );
1970
1971 // update the layer manager
1973
1974 // Now restore the visibility:
1975 lm_pane_info.Show( lm_shown );
1976 tree_pane_info.Show( tree_shown );
1977 m_auimgr.Update();
1978
1980
1981 UpdateTitle();
1982}
1983
1984
1986{
1988
1989 if( m_isClosing )
1990 return;
1991
1992 // An edit promotes the active tab from preview to permanent and flags it dirty. Reflect the
1993 // shared screen's dirty state onto the context and panel model so the tab shows bold + "*" and a
1994 // later library-open opens its own tab instead of replacing this one.
1995 if( m_activeTab )
1996 {
1997 m_activeTab->SetPreview( false );
1998 m_activeTab->SetModified( true );
1999
2000 if( int idx = m_tabsPanel->FindTab( m_activeTab->GetTabKey() ); idx >= 0 )
2001 m_tabsPanel->MarkModified( idx, true );
2002 }
2003
2004 Update3DView( true, true );
2006}
2007
2008
2010{
2011 SetTitle( _( "Footprint Editor" ) );
2012}
2013
2014
2016{
2017 m_appearancePanel->OnBoardChanged();
2018}
2019
2020
2022{
2026 m_propertiesPanel->UpdateData();
2027}
2028
2029
2031{
2033
2035 auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
2036
2037 adapter->AddLibraries( this );
2038}
2039
2040
2041void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( [[maybe_unused]] bool aProgress )
2042{
2043 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "FOOTPRINT_EDIT_FRAME::SyncLibraryTree enter" ) );
2044
2047 LIB_ID target = GetTargetFPID();
2048 bool targetSelected = ( target == GetLibTree()->GetSelectedLibId() );
2049 std::vector<LIB_ID> expanded = GetLibTree()->GetExpandedLibraries();
2050
2051 // Unselect before syncing to avoid null reference in the adapter
2052 // if a selected item is removed during the sync
2053 GetLibTree()->Unselect();
2054
2055 // Sync the LIB_TREE to the FOOTPRINT_INFO list
2056 adapter->Sync( footprints );
2057
2058 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "FOOTPRINT_EDIT_FRAME::SyncLibraryTree Regenerate" ) );
2059 GetLibTree()->Regenerate( true );
2060
2061 // Sync() collapsed the tree, so re-expand the libraries that were open before it.
2062 for( const LIB_ID& libId : expanded )
2063 GetLibTree()->ExpandLibId( libId );
2064
2065 if( target.IsValid() )
2066 {
2067 if( adapter->FindItem( target ) )
2068 {
2069 if( targetSelected )
2070 GetLibTree()->SelectLibId( target );
2071 else
2072 GetLibTree()->CenterLibId( target );
2073 }
2074 else
2075 {
2076 // Try to focus on parent
2077 target.SetLibItemName( wxEmptyString );
2078 GetLibTree()->CenterLibId( target );
2079 }
2080 }
2081
2082 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "FOOTPRINT_EDIT_FRAME::SyncLibraryTree exit" ) );
2083}
2084
2085
2090
2091
2093{
2094 GetLibTree()->SelectLibId( aLibID );
2095}
2096
2097
2099{
2100 m_appearancePanel->UpdateDisplayOptions();
2101}
2102
2103
2105{
2106 // Create the manager and dispatcher & route draw panel events to the dispatcher
2108 m_toolManager->SetEnvironment( GetBoard(), GetCanvas()->GetView(), GetCanvas()->GetViewControls(), config(), this );
2109 m_actions = new PCB_ACTIONS();
2111
2113
2114 m_toolManager->RegisterTool( new COMMON_CONTROL );
2115 m_toolManager->RegisterTool( new COMMON_TOOLS );
2116 m_toolManager->RegisterTool( new PCB_SELECTION_TOOL );
2117 m_toolManager->RegisterTool( new ZOOM_TOOL );
2118 m_toolManager->RegisterTool( new EDIT_TOOL );
2119 m_toolManager->RegisterTool( new PCB_EDIT_TABLE_TOOL );
2120 m_toolManager->RegisterTool( new PAD_TOOL );
2121 m_toolManager->RegisterTool( new DRAWING_TOOL );
2122 m_toolManager->RegisterTool( new PCB_POINT_EDITOR );
2123 m_toolManager->RegisterTool( new PCB_CONTROL ); // copy/paste
2124 m_toolManager->RegisterTool( new LIBRARY_EDITOR_CONTROL );
2125 m_toolManager->RegisterTool( new FOOTPRINT_EDITOR_CONTROL );
2126 m_toolManager->RegisterTool( new ALIGN_DISTRIBUTE_TOOL );
2127 m_toolManager->RegisterTool( new PCB_PICKER_TOOL );
2128 m_toolManager->RegisterTool( new POSITION_RELATIVE_TOOL );
2129 m_toolManager->RegisterTool( new ARRAY_TOOL );
2130 m_toolManager->RegisterTool( new PCB_VIEWER_TOOLS );
2131 m_toolManager->RegisterTool( new PCB_GROUP_TOOL );
2132 m_toolManager->RegisterTool( new CONSTRAINT_EDIT_TOOL );
2133 m_toolManager->RegisterTool( new CONVERT_TOOL );
2134 m_toolManager->RegisterTool( new PROPERTIES_TOOL );
2135 m_toolManager->RegisterTool( new MATCH_PROPERTIES_TOOL );
2136 m_toolManager->RegisterTool( new GRAPHIC_EDIT_TOOL );
2137 m_toolManager->RegisterTool( new EMBED_TOOL );
2138
2139 for( TOOL_BASE* tool : m_toolManager->Tools() )
2140 {
2141 if( PCB_TOOL_BASE* pcbTool = dynamic_cast<PCB_TOOL_BASE*>( tool ) )
2142 pcbTool->SetIsFootprintEditor( true );
2143 }
2144
2145 m_toolManager->GetTool<PCB_VIEWER_TOOLS>()->SetFootprintFrame( true );
2146 m_toolManager->InitTools();
2147
2148 m_toolManager->InvokeTool( "common.InteractiveSelection" );
2149
2150 // Load or reload wizard plugins in case they changed since the last time the frame opened
2151 // Because the board editor has also a plugin python menu,
2152 // call the PCB_EDIT_FRAME RunAction() if the board editor is running
2153 // Otherwise run the current RunAction().
2154 PCB_EDIT_FRAME* pcbframe = static_cast<PCB_EDIT_FRAME*>( Kiway().Player( FRAME_PCB_EDITOR, false ) );
2155
2156 if( pcbframe )
2158 else
2160}
2161
2162
2164{
2166
2167 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
2168 PCB_EDITOR_CONDITIONS cond( this );
2169
2170 wxASSERT( mgr );
2171
2172#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
2173#define CHECK( x ) ACTION_CONDITIONS().Check( x )
2174
2175 auto haveFootprintCond =
2176 [this]( const SELECTION& )
2177 {
2178 return GetBoard() && GetBoard()->GetFirstFootprint() != nullptr;
2179 };
2180
2181 auto footprintTargettedCond =
2182 [this]( const SELECTION& )
2183 {
2184 return !GetTargetFPID().GetLibItemName().empty();
2185 };
2186
2187 auto footprintSelectedInTreeCond =
2188 [this]( const SELECTION& )
2189 {
2191 return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
2192 };
2193
2194 const auto footprintFromBoardCond =
2195 [this]( const SELECTION& )
2196 {
2197 return IsCurrentFPFromBoard();
2198 };
2199
2200 auto pcbFrameExistsCond =
2201 [this]( const SELECTION& )
2202 {
2203 PCB_EDIT_FRAME* frame = dynamic_cast<PCB_EDIT_FRAME*>( Kiway().Player( FRAME_PCB_EDITOR, false ) );
2204
2205 return ( frame != nullptr );
2206 };
2207
2208 auto boardFootprintExistsCond =
2209 [this]( const SELECTION& )
2210 {
2211 PCB_EDIT_FRAME* frame = dynamic_cast<PCB_EDIT_FRAME*>( Kiway().Player( FRAME_PCB_EDITOR, false ) );
2212
2213 FOOTPRINT* editorFootprint = GetBoard()->GetFirstFootprint();
2214 bool canInsert = frame && editorFootprint && editorFootprint->GetLink() == niluuid;
2215
2216 // If the source was deleted, the footprint can inserted but not updated in the board.
2217 if( frame && editorFootprint && editorFootprint->GetLink() != niluuid )
2218 {
2219 BOARD* mainpcb = frame->GetBoard();
2220 canInsert = true;
2221
2222 // search if the source footprint was not deleted:
2223 for( FOOTPRINT* candidate : mainpcb->Footprints() )
2224 {
2225 if( editorFootprint->GetLink() == candidate->m_Uuid )
2226 {
2227 canInsert = false;
2228 break;
2229 }
2230 }
2231 }
2232
2233 return canInsert;
2234 };
2235
2236 // clang-format off
2237 mgr->SetConditions( ACTIONS::saveAs, ENABLE( footprintTargettedCond ) );
2240 mgr->SetConditions( PCB_ACTIONS::editLibFpInFpEditor,ENABLE( footprintFromBoardCond ) );
2241
2242 mgr->SetConditions( PCB_ACTIONS::saveFpToBoard, ENABLE( boardFootprintExistsCond ) );
2243 mgr->SetConditions( PCB_ACTIONS::loadFpFromBoard, ENABLE( pcbFrameExistsCond ) );
2244
2247
2250
2251 mgr->SetConditions( ACTIONS::cut, ENABLE( cond.HasItems() ) );
2252 mgr->SetConditions( ACTIONS::copy, ENABLE( cond.HasItems() ) );
2259
2266
2270
2275 // clang-format on
2276
2277 auto highContrastCond =
2278 [this]( const SELECTION& )
2279 {
2281 };
2282
2283 auto autoConstraintsCond = [this]( const SELECTION& )
2284 {
2286 return cfg && cfg->m_AutoConstraints;
2287 };
2288
2289 mgr->SetConditions( PCB_ACTIONS::toggleAutoConstraints, CHECK( autoConstraintsCond ) );
2290
2291 auto boardFlippedCond = [this]( const SELECTION& )
2292 {
2294 };
2295
2296 auto libraryTreeCond =
2297 [this](const SELECTION& )
2298 {
2299 return IsLibraryTreeShown();
2300 };
2301
2302 auto layerManagerCond =
2303 [this]( const SELECTION& )
2304 {
2305 return m_auimgr.GetPane( "LayersManager" ).IsShown();
2306 };
2307
2308 auto propertiesCond =
2309 [this] ( const SELECTION& )
2310 {
2311 return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
2312 };
2313
2314 mgr->SetConditions( ACTIONS::highContrastMode, CHECK( highContrastCond ) );
2315 mgr->SetConditions( PCB_ACTIONS::flipBoard, CHECK( boardFlippedCond ) );
2317
2318 mgr->SetConditions( ACTIONS::showLibraryTree, CHECK( libraryTreeCond ) );
2319 mgr->SetConditions( PCB_ACTIONS::showLayersManager, CHECK( layerManagerCond ) );
2320 mgr->SetConditions( ACTIONS::showProperties, CHECK( propertiesCond ) );
2321
2322 mgr->SetConditions( ACTIONS::print, ENABLE( haveFootprintCond ) );
2323 mgr->SetConditions( PCB_ACTIONS::exportFootprint, ENABLE( haveFootprintCond ) );
2324 mgr->SetConditions( PCB_ACTIONS::placeImportedGraphics, ENABLE( haveFootprintCond ) );
2325
2326 mgr->SetConditions( PCB_ACTIONS::footprintProperties, ENABLE( footprintSelectedInTreeCond || haveFootprintCond ) );
2327 mgr->SetConditions( PCB_ACTIONS::padTable, ENABLE( haveFootprintCond ) );
2328 mgr->SetConditions( PCB_ACTIONS::editTextAndGraphics, ENABLE( haveFootprintCond ) );
2329 mgr->SetConditions( PCB_ACTIONS::checkFootprint, ENABLE( haveFootprintCond ) );
2330 mgr->SetConditions( PCB_ACTIONS::repairFootprint, ENABLE( haveFootprintCond ) );
2331 mgr->SetConditions( PCB_ACTIONS::cleanupGraphics, ENABLE( haveFootprintCond ) );
2332 mgr->SetConditions( ACTIONS::showDatasheet, ENABLE( haveFootprintCond ) );
2333
2334 const auto isArcKeepCenterMode =
2335 [this]( const SELECTION& )
2336 {
2338 };
2339
2340 const auto isArcKeepEndpointMode =
2341 [this]( const SELECTION& )
2342 {
2344 };
2345
2346 const auto isArcKeepRadiusMode =
2347 [this]( const SELECTION& )
2348 {
2350 };
2351
2352 // clang-format off
2353 mgr->SetConditions( ACTIONS::pointEditorArcKeepCenter, CHECK( isArcKeepCenterMode ) );
2354 mgr->SetConditions( ACTIONS::pointEditorArcKeepEndpoint, CHECK( isArcKeepEndpointMode ) );
2355 mgr->SetConditions( ACTIONS::pointEditorArcKeepRadius, CHECK( isArcKeepRadiusMode ) );
2356 // clang-format on
2357
2358// Only enable a tool if the part is edtable
2359#define CURRENT_EDIT_TOOL( action ) mgr->SetConditions( action, ACTION_CONDITIONS() \
2360 .Enable( haveFootprintCond ) \
2361 .Check( cond.CurrentTool( action ) ) )
2362
2377 setArcModeConditions( PCB_ACTIONS::drawArc, haveFootprintCond );
2394
2413
2414#undef CURRENT_EDIT_TOOL
2415#undef ENABLE
2416#undef CHECK
2417}
2418
2419
2421{
2423
2424 // Be sure the axis are enabled
2425 GetCanvas()->GetGAL()->SetAxesEnabled( true );
2426
2427 UpdateView();
2428
2429 // Ensure the m_Layers settings are using the canvas type:
2431}
2432
2433
2435{
2437 m_appearancePanel->CommonSettingsChanged( aFlags );
2438
2440 {
2441 // This editor always shows the axes, whatever a settings file not yet saved by it says
2442 cfg->m_Window.grid.axes_enabled = true;
2443 GetGalDisplayOptions().ReadWindowSettings( cfg->m_Window );
2444
2445 GetBoard()->GetDesignSettings() = cfg->m_DesignSettings;
2447 }
2448
2452
2454
2455 if( aFlags & ENVVARS_CHANGED )
2456 SyncLibraryTree( true );
2457
2458 Layout();
2459 SendSizeEvent();
2460}
2461
2462
2463std::unique_ptr<GRID_HELPER> FOOTPRINT_EDIT_FRAME::MakeGridHelper()
2464{
2465 return std::make_unique<PCB_GRID_HELPER>( m_toolManager, GetMagneticItemsSettings() );
2466}
2467
2468
2470{
2471 LIB_ID id = GetLoadedFPID();
2472
2473 if( id.empty() )
2474 {
2475 DisplayErrorMessage( this, _( "No footprint selected." ) );
2476 return;
2477 }
2478
2479 wxFileName fn( id.GetLibItemName() );
2480 fn.SetExt( wxT( "png" ) );
2481
2482 wxString projectPath = wxPathOnly( Prj().GetProjectFullName() );
2483
2484 wxFileDialog dlg( this, _( "Export View as PNG" ), projectPath, fn.GetFullName(), FILEEXT::PngFileWildcard(),
2485 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
2486
2488
2489 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetPath().IsEmpty() )
2490 return;
2491
2492 // calling wxYield is mandatory under Linux, after closing the file selector dialog
2493 // to refresh the screen before creating the PNG or JPEG image from screen
2494 wxYield();
2495 this->SaveCanvasImageToFile( dlg.GetPath(), BITMAP_TYPE::PNG );
2496}
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
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:403
@ 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:294
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:264
static TOOL_ACTION pointEditorArcKeepCenter
Definition actions.h:273
static TOOL_ACTION ungroup
Definition actions.h:236
static TOOL_ACTION toggleBoundingBoxes
Definition actions.h:153
static TOOL_ACTION pointEditorArcKeepRadius
Definition actions.h:275
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:298
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:274
Manage TOOL_ACTION objects.
void SetConditions(const TOOL_ACTION &aAction, const ACTION_CONDITIONS &aConditions)
Set the conditions the UI elements for activating a specific tool action should use for determining t...
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:85
void SetLocked(bool aLocked) override
Definition board_item.h:427
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:355
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:411
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1520
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition board.cpp:950
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition board.h:713
const FOOTPRINTS & Footprints() const
Definition board.h:465
void DeleteAllFootprints()
Remove all footprints from the deque and free the memory associated with them.
Definition board.cpp:2103
BOARD_DESIGN_SETTINGS & GetDesignSettings()
Definition board.cpp:1290
void SetUserUnits(EDA_UNITS aUnits)
Definition board.h:1033
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.
virtual void resolveCanvasType()
Determine the canvas type to load (with prompt if required) and initializes m_canvasType.
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
void StopDrawing()
Prevent the GAL canvas from further drawing until it is recreated or StartDrawing() is called.
void ForceRefresh()
Force a redraw.
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 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.
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:1151
ZONES & Zones()
Definition footprint.h:361
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:355
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition footprint.h:393
const LIB_ID & GetFPID() const
Definition footprint.h:417
const LSET & GetStackupLayers() const
Definition footprint.h:507
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:1150
const wxString & GetReference() const
Definition footprint.h:793
FOOTPRINT_STACKUP GetStackupMode() const
Definition footprint.h:500
VECTOR2I GetPosition() const override
Definition footprint.h:379
DRAWINGS & GraphicalItems()
Definition footprint.h:358
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:68
double GetScale() const
Definition view.h:298
const VECTOR2D & GetCenter() const
Return the center point of this VIEW (in world space coordinates).
Definition view.h:377
virtual void SetScale(double aScale, VECTOR2D aAnchor={ 0, 0 })
Set the scaling factor, zooming around a given anchor point.
Definition view.cpp:901
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition view.cpp:1172
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition view.h:431
GAL * GetGAL() const
Return the GAL this view is using to draw graphical primitives.
Definition view.h:224
void SetCenter(const VECTOR2D &aCenter)
Set the center point of the VIEW (i.e.
Definition view.cpp:971
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition view.h:729
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:803
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:401
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()
bool InPadEditMode()
Definition pad_tool.h:63
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 placePasteAperturePad
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 placeNpthPad
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 placeThtPad
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 placeSmdPad
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 ddPlaceReferenceImage
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:244
@ PCB_FOOTPRINT_EDITOR_LIB_NICKNAME
Definition project.h:245
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:448
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:459
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.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
Definition cvpcb.cpp:165
#define CHECK(x)
#define ENABLE(x)
static bool empty(const wxTextEntryBase *aCtrl)
@ DRCE_MISSING_COURTYARD
Definition drc_item.h:80
#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:106
@ EXPAND_INNER_LAYERS
The 'normal' stackup handling, where there is a single inner layer (In1) and rule areas using it expa...
Definition footprint.h:111
@ CUSTOM_LAYERS
Stackup handling where the footprint can have any number of copper layers, and objects on those layer...
Definition footprint.h:116
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 JpegFileExtension
static const std::string PngFileExtension
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:737
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:823
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:108
bool SupportsShutdownBlockReason()
Whether or not the window supports setting a shutdown block reason.
Definition unix/app.cpp:97
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:640
#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.