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