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 along
20 * with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include "tool/embed_tool.h"
24#include "tools/convert_tool.h"
25#include "tools/drawing_tool.h"
26#include "tools/edit_tool.h"
29#include "tools/pad_tool.h"
30#include "tools/pcb_actions.h"
31#include "tools/pcb_control.h"
37#include <bitmaps.h>
38#include <board.h>
40#include <widgets/wx_infobar.h>
41#include <footprint.h>
42#include <confirm.h>
43#include <kidialog.h>
49#include <pcb_painter.h>
50#include <render_settings.h>
51#include <view/view.h>
52#include <kiface_base.h>
53#include <kiplatform/app.h>
54#include <kiplatform/ui.h>
55#include <kiway.h>
56#include <macros.h>
57#include <pcbnew_id.h>
58#include <pgm_base.h>
59#include <project.h>
60#include <project_pcb.h>
61#include <string_utils.h>
63#include <tool/action_toolbar.h>
64#include <tool/common_control.h>
65#include <tool/common_tools.h>
67#include <tool/selection.h>
70#include <tool/tool_manager.h>
71#include <tool/zoom_tool.h>
72#include <tools/array_tool.h>
80#include <widgets/lib_tree.h>
86
87#include <algorithm>
88
89#include <wx/filedlg.h>
90#include <wx/hyperlink.h>
91
92#ifdef KICAD_IPC_API
93#include <api/api_server.h>
96#endif
97
98BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
99 EVT_MENU( wxID_CLOSE, FOOTPRINT_EDIT_FRAME::CloseFootprintEditor )
100 EVT_MENU( wxID_EXIT, FOOTPRINT_EDIT_FRAME::OnExitKiCad )
101
103
106
108
109 // Drop files event
110 EVT_DROP_FILES( FOOTPRINT_EDIT_FRAME::OnDropFiles )
111
112END_EVENT_TABLE()
113
114
115FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
116 PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_FOOTPRINT_EDITOR, wxEmptyString,
117 wxDefaultPosition, wxDefaultSize,
120 m_tabsPanel( nullptr ),
121 m_activeTab( nullptr ),
123{
124 m_showBorderAndTitleBlock = false; // true to show the frame references
125 m_aboutTitle = _HKI( "KiCad Footprint Editor" );
126 m_editorSettings = nullptr;
127
128 // Give an icon
129 wxIcon icon;
130 wxIconBundle icon_bundle;
131
132 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit, 48 ) );
133 icon_bundle.AddIcon( icon );
134 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit, 128 ) );
135 icon_bundle.AddIcon( icon );
136 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit, 256 ) );
137 icon_bundle.AddIcon( icon );
138 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit_32 ) );
139 icon_bundle.AddIcon( icon );
140 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit_16 ) );
141 icon_bundle.AddIcon( icon );
142
143 SetIcons( icon_bundle );
144
145 // Create GAL canvas
147
148 PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_frameSize,
150 SetCanvas( drawPanel );
151
152 SetBoard( new BOARD() );
153
154 // This board will only be used to hold a footprint for editing
155 GetBoard()->SetBoardUse( BOARD_USE::FPHOLDER );
156
157 // In Footprint Editor, the default net clearance is not known (it depends on the actual
158 // board). So we do not show the default clearance, by setting it to 0. The footprint or
159 // pad specific clearance will be shown.
160 GetBoard()->GetDesignSettings().m_NetSettings->GetDefaultNetclass()->SetClearance( 0 );
161
162 // Don't show the default board solder mask expansion in the footprint editor. Only the
163 // footprint or pad mask expansions settings should be shown.
164 GetBoard()->GetDesignSettings().m_SolderMaskExpansion = 0;
165
166 // Ensure all layers and items are visible:
167 // In footprint editor, some layers have no meaning or cannot be used, but we show all of
168 // them, at least to be able to edit a bad layer
169 GetBoard()->SetVisibleAlls();
170
171 GetGalDisplayOptions().m_axesEnabled = true;
172
173 // In Footprint Editor, set the default paper size to A4 for plot/print
175 SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU( pcbIUScale.IU_PER_MILS ) ) );
176
177 // Create the manager and dispatcher & route draw panel events to the dispatcher
178 setupTools();
180
182 m_treePane = new FOOTPRINT_TREE_PANE( this );
183
187 ReCreateLayerBox( false );
188
190
192 m_appearancePanel = new APPEARANCE_CONTROLS( this, GetCanvas(), true );
193 m_propertiesPanel = new PCB_PROPERTIES_PANEL( this, this );
194
195 // LoadSettings() *after* creating m_LayersManager, because LoadSettings() initialize
196 // parameters in m_LayersManager
197 // NOTE: KifaceSettings() will return PCBNEW_SETTINGS if we started from pcbnew
199
201
202 float proportion = GetFootprintEditorSettings()->m_AuiPanels.properties_splitter;
203 m_propertiesPanel->SetSplitterProportion( proportion );
204
206
207 // Fetch a COPY of the config as a lot of these initializations are going to overwrite our
208 // data.
209 int libWidth = 0;
211
213 {
214 libWidth = cfg->m_LibWidth;
215 aui_cfg = cfg->m_AuiPanels;
216 }
217 else
218 {
219 // keep gcc quiet about uninitalized vars:
220 aui_cfg.appearance_panel_tab = 0;
221 aui_cfg.right_panel_width = -1;
222 }
223
224 m_auimgr.SetManagedWindow( this );
225
226 // Create the infobar pane only after the AUI manager owns this frame. Registering it before
227 // SetManagedWindow() leaves the Top/Layer-1 pane mispositioned once the tabbed center pane
228 // mounts and the perspective restores, so ShowMessage() never reveals it.
230
231 unsigned int auiFlags = wxAUI_MGR_DEFAULT;
232#if !defined( _WIN32 )
233 // Windows cannot redraw the UI fast enough during a live resize and may lead to all kinds
234 // of graphical glitches
235 auiFlags |= wxAUI_MGR_LIVE_RESIZE;
236#endif
237 m_auimgr.SetFlags( auiFlags );
238
239 // Rows; layers 4 - 6
240 m_auimgr.AddPane( m_tbTopMain, EDA_PANE().HToolbar().Name( "TopMainToolbar" )
241 .Top().Layer( 6 ) );
242
243 m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( "MsgPanel" )
244 .Bottom().Layer( 6 ) );
245
246 // Columns; layers 1 - 3
247 m_auimgr.AddPane( m_treePane, EDA_PANE().Palette().Name( "Footprints" )
248 .Left().Layer( 4 )
249 .Caption( _( "Libraries" ) )
250 // Don't use -1 for don't-change-height on a growable panel; it has side-effects.
251 .MinSize( FromDIP( 250 ), FromDIP( 80 ) )
252 .BestSize( FromDIP( 250 ), -1 ) );
254 .Left().Layer( 3 )
255 .Caption( _( "Properties" ) ).PaneBorder( false )
256 .MinSize( FromDIP( wxSize( 240, 60 ) ) ).BestSize( FromDIP( wxSize( 300, 200 ) ) ) );
257 m_auimgr.AddPane( m_tbLeft, EDA_PANE().VToolbar().Name( "LeftToolbar" )
258 .Left().Layer( 2 ) );
259
260 m_auimgr.AddPane( m_tbRight, EDA_PANE().VToolbar().Name( "RightToolbar" )
261 .Right().Layer(2) );
262 m_auimgr.AddPane( m_appearancePanel, EDA_PANE().Name( "LayersManager" )
263 .Right().Layer( 3 )
264 .Caption( _( "Appearance" ) ).PaneBorder( false )
265 // Don't use -1 for don't-change-height on a growable panel; it has side-effects.
266 .MinSize( FromDIP( 180 ), FromDIP( 80 ) )
267 .BestSize( FromDIP( 180 ), -1 ) );
268 m_auimgr.AddPane( m_selectionFilterPanel, EDA_PANE().Palette().Name( "SelectionFilter" )
269 .Right().Layer( 3 ).Position( 2 )
270 .Caption( _( "Selection Filter" ) ).PaneBorder( false )
271 // Fixed-size pane; -1 for MinSize height is required
272 .MinSize( FromDIP( 180 ), -1 )
273 .BestSize( FromDIP( 180 ), -1 ) );
274
275 // Center: the tabbed-document strip owns the tab bar above a single, never-reparented canvas.
276 // The panel borrows the canvas; the frame keeps ownership through GetCanvas().
277 m_tabsPanel = new EDITOR_TABS_PANEL( this, GetCanvas() );
278
279 m_tabsPanel->onActivateTab =
280 [this]( int aIdx )
281 {
282 // Ignore activation during a full clear, when each tab close re-selects a fallback
283 // that would re-borrow a tab-owned board into m_pcb just before it is freed.
285 return;
286
287 if( aIdx >= 0 && aIdx < static_cast<int>( m_tabContexts.size() ) )
288 activateFootprintTab( m_tabContexts[aIdx].get() );
289 };
290
291 m_tabsPanel->onCloseTabRequested =
292 [this]( int aIdx ) -> bool
293 {
294 return promptAndCloseFootprintTab( aIdx );
295 };
296
297 m_tabsPanel->onPinChanged =
298 [this]( int aIdx, bool aPinned )
299 {
300 // The context, not the panel model, persists the pin, so mirror every change there.
301 if( aIdx >= 0 && aIdx < static_cast<int>( m_tabContexts.size() ) )
302 m_tabContexts[aIdx]->SetPinned( aPinned );
303 };
304
305 // onCloseTabRequested installs the successor board atomically, so the panel must not re-activate
306 // the fallback after a close and re-borrow a just-installed or just-freed index.
307 m_tabsPanel->SetSuppressActivateOnClose( true );
308
309 m_tabsPanel->onQueryVisualState =
310 [this]( int aIdx ) -> TAB_VISUAL_STATE
311 {
312 // The panel model owns preview/pinned, but the live dirty flag lives on the shared
313 // frame screen folded into the context, so read modified from the context.
314 const std::vector<EDITOR_TABS_MODEL::ENTRY>& entries = m_tabsPanel->Model().Entries();
315
316 if( aIdx < 0 || aIdx >= static_cast<int>( entries.size() ) )
317 return TAB_VISUAL_STATE{};
318
320 aIdx < static_cast<int>( m_tabContexts.size() ) ? m_tabContexts[aIdx].get()
321 : nullptr;
322 const bool modified = ctx ? ctx->IsModified() : entries[aIdx].modified;
323
324 return ResolveTabVisualState( entries[aIdx].preview, modified,
325 entries[aIdx].pinned );
326 };
327
328 m_auimgr.AddPane( m_tabsPanel, EDA_PANE().Canvas().Name( "DrawFrame" )
329 .Center() );
330
332
333 m_auimgr.GetPane( "LayersManager" ).Show( m_show_layer_manager_tools );
334 m_auimgr.GetPane( "SelectionFilter" ).Show( m_show_layer_manager_tools );
335 m_auimgr.GetPane( PropertiesPaneName() ).Show( GetSettings()->m_AuiPanels.show_properties );
336
337 // The selection filter doesn't need to grow in the vertical direction when docked
338 m_auimgr.GetPane( "SelectionFilter" ).dock_proportion = 0;
339
342 DragAcceptFiles( true );
343
345
346 // Apply saved visibility stuff at the end
347 wxAuiPaneInfo& treePane = m_auimgr.GetPane( "Footprints" );
348 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
349
350 if( libWidth > 0 )
351 SetAuiPaneSize( m_auimgr, treePane, libWidth, -1 );
352
353 if( aui_cfg.right_panel_width > 0 )
354 SetAuiPaneSize( m_auimgr, layersManager, aui_cfg.right_panel_width, -1 );
355
356 m_appearancePanel->SetTabIndex( aui_cfg.appearance_panel_tab );
357
359 {
360 m_appearancePanel->SetUserLayerPresets( cfg->m_LayerPresets );
361 m_appearancePanel->ApplyLayerPreset( cfg->m_ActiveLayerPreset );
362 }
363
364 // restore the last footprint from the project, if any, after the library has been init'ed
365 // N.B. This needs to happen after the AUI manager has been initialized so that we can
366 // properly call the WX_INFOBAR without crashing on some systems.
368
369#ifdef KICAD_IPC_API
370 m_apiHandler = std::make_unique<API_HANDLER_FOOTPRINT>( this );
371 Pgm().GetApiServer().RegisterHandler( m_apiHandler.get() );
372
373 if( Kiface().IsSingle() )
374 {
375 m_apiHandlerCommon = std::make_unique<API_HANDLER_COMMON>();
376 Pgm().GetApiServer().RegisterHandler( m_apiHandlerCommon.get() );
377 }
378#endif
379
380 // This displays the last footprint loaded, if any, so it must be done after restoreLastFootprint()
382
383 GetToolManager()->PostAction( ACTIONS::zoomFitScreen );
384 UpdateTitle();
386
388
389 // Default shutdown reason until a file is loaded
390 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "Footprint changes are unsaved" ) );
391
392 // Catch unhandled accelerator command characters that were no handled by the library tree
393 // panel.
395 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
396
397 // GTK rejects WXK_TAB as a menu accelerator, so handle Ctrl+Tab cycling from the CHAR_HOOK
398 // stream. Binding after the dispatcher runs this handler first so it can consume the event.
399 Bind( wxEVT_CHAR_HOOK, &FOOTPRINT_EDIT_FRAME::OnTabCharHook, this );
400
401 // Ensure the window is on top
402 Raise();
403 Show( true );
404
405 // Register a call to update the toolbar sizes. It can't be done immediately because
406 // it seems to require some sizes calculated that aren't yet (at least on GTK).
407 CallAfter(
408 [this]()
409 {
410 // Ensure the controls on the toolbars all are correctly sized
412 m_treePane->FocusSearchFieldIfExists();
413
414 // Update the angle snap mode toolbar button to reflect the current preference
416 } );
417}
418
419
421{
422 // Hand the borrowed canvas back before the base destructor deletes it, or the later-destroyed
423 // panel would reparent already-freed memory. The canvas then frees exactly once.
424 if( m_tabsPanel )
425 m_tabsPanel->ReleaseSharedCanvas();
426
427 // Shutdown all running tools
428 if( m_toolManager )
429 m_toolManager->ShutdownAllTools();
430
431 // save the footprint in the PROJECT
433
434 // Clear the watched file
435 setFPWatcher( nullptr );
436
437 // When a tab context owns the active board, null the frame pointer so the base destructor does
438 // not double-free it. A frame-owned bootstrap board is left for the base class to delete.
440 m_pcb = nullptr;
441
442 // We passed ownership of these to wxAuiManager.
443 // delete m_selectionFilterPanel;
444 // delete m_appearancePanel;
445 // delete m_treePane;
446}
447
448
450{
452
453 FOOTPRINT* fp = static_cast<FOOTPRINT*>( GetModel() );
454
455 if( fp )
456 {
457 std::vector<MSG_PANEL_ITEM> msgItems;
458 fp->GetMsgPanelInfo( this, msgItems );
459 SetMsgPanel( msgItems );
460 }
461}
462
463
469
470
472{
473 return m_toolManager->GetTool<PCB_SELECTION_TOOL>()->GetSelection();
474}
475
476
478{
479 // switches currently used canvas (Cairo / OpenGL).
480 PCB_BASE_FRAME::SwitchCanvas( aCanvasType );
481
482 GetCanvas()->GetGAL()->SetAxesEnabled( true );
483
484 // The base class method *does not reinit* the layers manager. We must update the layer
485 // widget to match board visibility states, both layers and render columns, and and some
486 // settings dependent on the canvas.
488}
489
490
496
497
499{
500 wxAuiPaneInfo& treePane = m_auimgr.GetPane( m_treePane );
501 treePane.Show( !IsLibraryTreeShown() );
502
503 if( IsLibraryTreeShown() )
504 {
505 // SetAuiPaneSize also updates m_auimgr
506 SetAuiPaneSize( m_auimgr, treePane, m_editorSettings->m_LibWidth, -1 );
507 }
508 else
509 {
510 m_editorSettings->m_LibWidth = m_treePane->GetSize().x;
511 m_auimgr.Update();
512 }
513}
514
515
517{
518 m_treePane->FocusSearchFieldIfExists();
519}
520
521
523{
525 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
526 wxAuiPaneInfo& selectionFilter = m_auimgr.GetPane( "SelectionFilter" );
527
528 // show auxiliary Vertical layers and visibility manager toolbar
530 layersManager.Show( m_show_layer_manager_tools );
531 selectionFilter.Show( m_show_layer_manager_tools );
532
534 {
535 SetAuiPaneSize( m_auimgr, layersManager, settings->m_AuiPanels.right_panel_width, -1 );
536 }
537 else
538 {
539 settings->m_AuiPanels.right_panel_width = m_appearancePanel->GetSize().x;
540 m_auimgr.Update();
541 }
542}
543
544
546{
547 return const_cast<wxAuiManager&>( m_auimgr ).GetPane( m_treePane ).IsShown();
548}
549
550
552{
553 // A tab close transiently leaves the frame with no board while UI repaints can still run.
554 if( !GetBoard() )
555 return nullptr;
556
557 return GetBoard()->GetFirstFootprint();
558}
559
560
562{
563 LIB_ID id;
564
565 if( IsLibraryTreeShown() )
567
568 if( id.GetLibNickname().empty() )
569 id = GetLoadedFPID();
570
571 return id;
572}
573
574
576{
577 // The board pointer is transiently null during a tab close while the library tree adapter can
578 // still repaint, so tolerate having no board.
579 if( !GetBoard() )
580 return LIB_ID();
581
582 FOOTPRINT* footprint = GetBoard()->GetFirstFootprint();
583
584 if( footprint )
585 return LIB_ID( footprint->GetFPID().GetLibNickname(), m_footprintNameWhenLoaded );
586 else
587 return LIB_ID();
588}
589
590
592{
593 if( GetBoard() && GetBoard()->GetFirstFootprint() )
594 {
597 }
598
599 GetScreen()->SetContentModified( false );
600
601 // OnModify() mirrors the dirty flag onto the active tab context and the panel model, so clear both
602 // here too. Tab rendering and close prompting read the context's flag, so a save that only cleared
603 // the shared screen would leave the tab starred and re-prompting to save.
604 if( m_tabsPanel && m_activeTab )
605 {
606 m_activeTab->SetModified( false );
607
608 if( int idx = m_tabsPanel->FindTab( m_activeTab->GetTabKey() ); idx >= 0 )
609 m_tabsPanel->MarkModified( idx, false );
610 }
611}
612
613
615{
616 // If we've already vetted closing this window, then we have no FP anymore
617 if( m_isClosing || !GetBoard() )
618 return false;
619
620 FOOTPRINT* footprint = GetBoard()->GetFirstFootprint();
621
622 return ( footprint && footprint->GetLink() != niluuid );
623}
624
625
627{
628 LIB_ID id = GetLoadedFPID();
629
630 if( id.IsValid() )
631 {
633 Prj().SetRString( PROJECT::PCB_FOOTPRINT_EDITOR_FP_NAME, id.GetLibItemName() );
634 }
635}
636
637
639{
640 // Restore the persisted tab set first. The active tab is loaded last so it ends up focused, and
641 // tabs that no longer resolve are silently dropped.
642 if( FOOTPRINT_EDITOR_SETTINGS* cfg = GetSettings(); cfg && !cfg->m_OpenTabs.empty() )
643 {
644 const wxString activeKey = cfg->m_ActiveTab;
645
646 const auto loadTab =
647 [this]( const FOOTPRINT_EDITOR_SETTINGS::OPEN_TAB& aTab ) -> bool
648 {
649 LIB_ID id;
650 id.SetLibNickname( aTab.m_lib );
651 id.SetLibItemName( aTab.m_fpName );
652
653 if( FOOTPRINT* footprint = loadFootprint( id ) )
654 {
655 AddFootprintToBoard( footprint );
656
657 // A restored tab is a real document, so promote it from preview to permanent.
658 if( m_tabsPanel )
659 findOrCreateFootprintTab( id, false );
660
661 if( aTab.m_pinned && m_tabsPanel )
662 {
663 if( int idx = m_tabsPanel->FindTab( id.GetLibNickname()
664 + wxT( ":" ) + id.GetLibItemName() );
665 idx >= 0 )
666 {
667 // SetPinned mirrors into the context through onPinChanged, keeping
668 // the persisted IsPinned() flag in sync.
669 m_tabsPanel->SetPinned( idx, true );
670 }
671 }
672
673 return true;
674 }
675
676 // loadFootprint swallows the IO_ERROR when the library no longer resolves, so
677 // log the dropped tab to keep a failed restore diagnosable.
678 wxLogTrace( wxT( "KICAD_FP_TABS" ),
679 wxT( "Dropping persisted footprint tab '%s:%s' (failed to load)" ),
680 aTab.m_lib, aTab.m_fpName );
681
682 return false;
683 };
684
685 const FOOTPRINT_EDITOR_SETTINGS::OPEN_TAB* activeTab = nullptr;
686
687 for( const FOOTPRINT_EDITOR_SETTINGS::OPEN_TAB& tab : cfg->m_OpenTabs )
688 {
689 const wxString key = tab.m_lib + wxT( ":" ) + tab.m_fpName;
690
691 if( key == activeKey )
692 activeTab = &tab;
693 else
694 loadTab( tab );
695 }
696
697 if( activeTab )
698 loadTab( *activeTab );
699
700 if( !m_tabContexts.empty() )
701 return;
702 }
703
704 const wxString& footprintName = Prj().GetRString( PROJECT::PCB_FOOTPRINT_EDITOR_FP_NAME );
705 const wxString& libNickname = Prj().GetRString( PROJECT::PCB_FOOTPRINT_EDITOR_LIB_NICKNAME );
706
707 if( libNickname.Length() && footprintName.Length() )
708 {
709 LIB_ID id;
710 id.SetLibNickname( libNickname );
711 id.SetLibItemName( footprintName );
712
713 FOOTPRINT* footprint = loadFootprint( id );
714
715 if( footprint )
716 {
717 AddFootprintToBoard( footprint );
718
719 // The last-session footprint is a real document, so promote its tab to permanent.
720 if( m_tabsPanel )
721 findOrCreateFootprintTab( id, false );
722 }
723 }
724}
725
726
728{
729 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( GetModel() );
730 BOARD& board = *GetBoard();
731
732 // All FPs have these layers enabled
733 LSET enabledLayers = LSET::AllTechMask() | LSET::UserMask();
734
735 const auto configureStackup =
736 [&]( FOOTPRINT_STACKUP aMode, const LSET& aLayerSet )
737 {
738 const LSET cuLayers = aLayerSet & LSET::AllCuMask();
739 board.SetCopperLayerCount( cuLayers.count() );
740
741 switch( aMode )
742 {
744 {
745 enabledLayers |= LSET{ F_Cu, In1_Cu, B_Cu };
746 board.SetLayerName( In1_Cu, _( "Inner layers" ) );
747 break;
748 }
749
751 {
752 // Nothing extra to add
753
754 // Clear layer name defaults
755 board.SetLayerName( In1_Cu, wxEmptyString );
756 break;
757 }
758
759 }
760
761 enabledLayers |= aLayerSet;
762 };
763
764 if( footprint )
765 {
766 configureStackup( footprint->GetStackupMode(), footprint->GetStackupLayers() );
767 }
768 else
769 {
770 // If no footprint is loaded, we assume the default stackup mode
771 configureStackup( FOOTPRINT_STACKUP::EXPAND_INNER_LAYERS, LSET{} );
772 }
773
775 {
776 m_originalFootprintCopy->RunOnChildren(
777 [&]( BOARD_ITEM* child )
778 {
779 LSET childLayers = child->GetLayerSet() & LSET::UserDefinedLayersMask();
780
781 for( PCB_LAYER_ID layer : childLayers )
782 enabledLayers.set( layer );
783 },
785 }
786
787 // Enable the user-configured number of user layers, plus any specifically named layers
789 {
790 int userLayerCount = cfg->m_DesignSettings.GetUserDefinedLayerCount();
791 enabledLayers |= LSET::UserDefinedLayersMask( userLayerCount );
792
793 for( const PCB_LAYER_ID& user : LSET::UserDefinedLayersMask() )
794 {
795 if( cfg->m_DesignSettings.m_UserLayerNames.contains( LSET::Name( user ).ToStdString() ) )
796 enabledLayers.set( user );
797 }
798 }
799
800 board.SetEnabledLayers( enabledLayers );
801
802 // Footprint Editor layer visibility is kept in the view, not the board (because the board
803 // just delegates to the project file, which we don't have).
804 for( const PCB_LAYER_ID& layer : GetBoard()->GetEnabledLayers() )
805 GetCanvas()->GetView()->SetLayerVisible( layer, true );
806}
807
808
810{
812
813 m_originalFootprintCopy.reset( static_cast<FOOTPRINT*>( aFootprint->Clone() ) );
814 m_originalFootprintCopy->SetParent( nullptr );
815
817
818 // Mirror the load baseline into the active tab context so it survives a tab switch (the frame
819 // members are only a borrowed view of the active context's baseline).
820 if( m_activeTab )
821 {
822 m_activeTab->SetOriginalFootprintCopy(
823 std::unique_ptr<FOOTPRINT>( static_cast<FOOTPRINT*>( m_originalFootprintCopy
824 ? m_originalFootprintCopy->Clone()
825 : nullptr ) ) );
826 m_activeTab->SetFootprintNameWhenLoaded( m_footprintNameWhenLoaded );
827 m_activeTab->SetName( aFootprint->GetFPID().GetLibItemName() );
828 }
829
831 // Ensure item UUIDs are valid
832 // ("old" footprints can have null uuids that create issues in fp editor)
833 aFootprint->FixUuids();
834
836
837 // Use CallAfter so that we update the canvas before waiting for the infobar animation
838 CallAfter(
839 [this]()
840 {
842 wxString libName = fp->GetFPID().GetLibNickname();
843 wxString msg, link;
844
846 {
847 msg.Printf( _( "Editing %s from board. Saving will update the board only." ), fp->GetReference() );
848 link.Printf( _( "Open in library %s" ), UnescapeString( libName ) );
849
850 const auto openLibraryCopy =
851 [this]( wxHyperlinkEvent& aEvent )
852 {
854 };
855
856 if( WX_INFOBAR* infobar = GetInfoBar() )
857 {
858 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, link, wxEmptyString );
859 button->Bind( wxEVT_COMMAND_HYPERLINK, openLibraryCopy );
860
861 infobar->RemoveAllButtons();
862 infobar->AddButton( button );
863 infobar->AddCloseButton();
864 infobar->ShowMessage( msg, wxICON_INFORMATION );
865 }
866 }
867 // An empty libname is OK - you get that when creating a new footprint from the main menu
868 // In that case. treat is as editable, and the user will be prompted for save-as when saving.
869 else if( !libName.empty()
870 && !PROJECT_PCB::FootprintLibAdapter( &Prj() )->IsFootprintLibWritable( libName ) )
871 {
872 msg.Printf( _( "Editing footprint from read-only library %s." ), UnescapeString( libName ) );
873
874 if( WX_INFOBAR* infobar = GetInfoBar() )
875 {
876 link = _( "Save as editable copy" );
877
878 const auto saveAsEditableCopy =
879 [this]( wxHyperlinkEvent& aEvent )
880 {
881 SaveFootprintAs( GetBoard()->GetFirstFootprint() );
882 GetCanvas()->GetView()->Update( GetBoard()->GetFirstFootprint() );
883 ClearModify();
884
885 // Get rid of the save-will-update-board-only (or any other dismissable warning)
886 WX_INFOBAR* loc_infobar = GetInfoBar();
887
888 if( loc_infobar->IsShownOnScreen() && loc_infobar->HasCloseButton() )
889 loc_infobar->Dismiss();
890
892 SyncLibraryTree( true );
893 };
894
895 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, link, wxEmptyString );
896 button->Bind( wxEVT_COMMAND_HYPERLINK, saveAsEditableCopy );
897
898 infobar->RemoveAllButtons();
899 infobar->AddButton( button );
900 infobar->AddCloseButton();
901 infobar->ShowMessage( msg, wxICON_INFORMATION );
902 }
903 }
904 else
905 {
906 if( WX_INFOBAR* infobar = GetInfoBar() )
907 infobar->Dismiss();
908 }
909 } );
910
913}
914
915
917{
918 // Route the load through the tab strip so the footprint lands on its own tab. Tabs only apply to
919 // library footprints with a resolvable identity; board-sourced and new-footprint loads keep the
920 // legacy single-board behavior.
921 const bool fromBoard = aFootprint && aFootprint->GetLink() != niluuid;
922
923 // Opening from the library is a preview that the next library-open reuses; editing promotes it
924 // to a permanent tab.
925 if( m_tabsPanel && aFootprint && !fromBoard && aFootprint->GetFPID().IsValid() )
926 findOrCreateFootprintTab( aFootprint->GetFPID(), true );
927
928 ReloadFootprint( aFootprint );
929
931 setFPWatcher( nullptr );
932 else
933 setFPWatcher( aFootprint );
934}
935
936
938{
939 return std::any_of( m_tabContexts.begin(), m_tabContexts.end(),
940 [this]( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& aCtx )
941 {
942 return aCtx->GetBoard() == m_pcb;
943 } );
944}
945
946
948{
949 // Swap the board pointer without the SetBoard delete, since on a tab switch the outgoing board
950 // is owned by its tab context. Reproduce only the side effects SetBoard applies to the incoming
951 // board.
952 if( m_pcb == aBoard )
953 return;
954
955 // The only frame-owned board is the constructor's bootstrap board. Delete it when we first
956 // switch away so it does not leak; tab-owned boards are left to their contexts.
957 if( m_pcb && !activeBoardOwnedByTab() )
958 delete m_pcb;
959
960 m_pcb = aBoard;
961
962 if( GetBoard() )
964
965 if( GetBoard() && GetCanvas() )
966 {
967 if( KIGFX::RENDER_SETTINGS* rs = GetCanvas()->GetView()->GetPainter()->GetSettings() )
968 {
969 rs->SetDashLengthRatio( GetBoard()->GetPlotOptions().GetDashedLineDashRatio() );
970 rs->SetGapLengthRatio( GetBoard()->GetPlotOptions().GetDashedLineGapRatio() );
971 }
972 }
973
974 wxCommandEvent e( EDA_EVT_BOARD_CHANGED );
975 ProcessEventLocally( e );
976}
977
978
980{
981 if( !m_activeTab )
982 return;
983
984 KIGFX::VIEW* view = GetCanvas()->GetView();
985
986 EDITOR_TAB_CONTEXT::VIEW_SNAPSHOT& snap = m_activeTab->ViewSnapshot();
987 snap.scale = view->GetScale();
988 snap.center = view->GetCenter();
989 snap.valid = true;
990
991 std::vector<KIID>& sel = m_activeTab->SavedSelection();
992 sel.clear();
993
994 for( EDA_ITEM* item : GetCurrentSelection() )
995 sel.push_back( item->m_Uuid );
996
997 // Dirty state lives on the shared frame screen, so fold it into the context to survive the switch.
998 if( GetScreen() )
999 m_activeTab->SetModified( GetScreen()->IsContentModified() );
1000
1001 // Swap the raw vectors since UNDO_REDO_CONTAINER is non-copyable; ownership transfers intact.
1002 m_activeTab->UndoList().m_CommandsList.swap( m_undoList.m_CommandsList );
1003 m_activeTab->RedoList().m_CommandsList.swap( m_redoList.m_CommandsList );
1004
1005 m_activeTab = nullptr;
1006}
1007
1008
1010{
1011 if( !aCtx || aCtx == m_activeTab )
1012 return;
1013
1014 installFootprintTabBoard( aCtx, aCtx->GetBoard() );
1015}
1016
1017
1019 BOARD* aBoard )
1020{
1021 // Install the successor board and tool environment before the caller frees the outgoing context
1022 // so no tool Reset() or repaint ever sees a freed or null m_pcb. Never calls the base SetBoard,
1023 // which would delete m_pcb and reset tools while the model still aliases it.
1024
1026
1027 // Drop the live selection while the outgoing board is still valid.
1028 if( m_toolManager )
1030
1031 m_activeTab = aCtx;
1032
1033 borrowBoardNonDestructive( aBoard );
1034
1035 if( aCtx )
1036 {
1037 m_undoList.m_CommandsList.swap( aCtx->UndoList().m_CommandsList );
1038 m_redoList.m_CommandsList.swap( aCtx->RedoList().m_CommandsList );
1039 }
1040 else
1041 {
1042 // Discard the swapped-in lists with their transient items so nothing references a freed board.
1044 }
1045
1047 ? static_cast<FOOTPRINT*>(
1048 aCtx->GetOriginalFootprintCopy()->Clone() )
1049 : nullptr );
1050 m_footprintNameWhenLoaded = aCtx ? aCtx->GetFootprintNameWhenLoaded() : wxString();
1051
1052 if( GetScreen() )
1053 GetScreen()->SetContentModified( aCtx ? aCtx->IsModified() : false );
1054
1055 // Point the tool environment at the incoming board before ResetTools so tools never dereference
1056 // a freed model.
1057 m_toolManager->SetEnvironment( GetBoard(), GetCanvas()->GetView(),
1058 GetCanvas()->GetViewControls(), config(), this );
1059
1062
1064
1065 if( !aCtx )
1066 {
1071 return;
1072 }
1073
1074 const EDITOR_TAB_CONTEXT::VIEW_SNAPSHOT& snap = aCtx->ViewSnapshot();
1075
1076 if( snap.valid )
1077 {
1078 GetCanvas()->GetView()->SetScale( snap.scale );
1079 GetCanvas()->GetView()->SetCenter( snap.center );
1080 }
1081
1082 if( !aCtx->SavedSelection().empty() )
1083 {
1085
1086 if( selTool )
1087 {
1088 for( const KIID& id : aCtx->SavedSelection() )
1089 {
1090 if( BOARD_ITEM* item = GetBoard()->ResolveItem( id, true ) )
1091 selTool->select( item );
1092 }
1093 }
1094 }
1095
1096 if( m_appearancePanel )
1097 m_appearancePanel->OnBoardChanged();
1098
1099 if( m_propertiesPanel )
1100 m_propertiesPanel->UpdateData();
1101
1106}
1107
1108
1111{
1112 if( !m_tabsPanel )
1113 return nullptr;
1114
1115 const wxString lib = aLibId.GetLibNickname();
1116 const wxString name = aLibId.GetLibItemName();
1117 const wxString key = lib + wxT( ":" ) + name;
1118
1119 if( int existing = m_tabsPanel->FindTab( key ); existing >= 0 )
1120 {
1121 m_tabsPanel->AddTab( key, name, aAsPreview );
1122 return m_tabContexts[existing].get();
1123 }
1124
1125 auto board = std::make_unique<BOARD>();
1126 board->SetBoardUse( BOARD_USE::FPHOLDER );
1127 board->GetDesignSettings().m_NetSettings->GetDefaultNetclass()->SetClearance( 0 );
1128 board->GetDesignSettings().m_SolderMaskExpansion = 0;
1129 board->SetVisibleAlls();
1130
1131 auto ctx = std::make_unique<FOOTPRINT_EDITOR_TAB_CONTEXT>( lib, name, std::move( board ) );
1132 ctx->SetPreview( aAsPreview );
1133
1134 FOOTPRINT_EDITOR_TAB_CONTEXT* raw = ctx.get();
1135
1136 // Keep m_tabContexts index-aligned with the panel model. A previewed open reuses the preview
1137 // slot in place; otherwise the context is appended. It must be at its final index before AddTab
1138 // fires onActivateTab.
1139 const int reuseSlot = aAsPreview ? m_tabsPanel->Model().PreviewIndex() : -1;
1140
1141 if( reuseSlot >= 0 && reuseSlot < static_cast<int>( m_tabContexts.size() ) )
1142 {
1143 // The move-assign below destroys the reused slot's context and its board. If it is the active
1144 // tab, tear the document down while that board is still alive so the move-assign is safe.
1145 if( m_tabContexts[reuseSlot].get() == m_activeTab )
1146 {
1147 if( m_toolManager )
1149
1151 m_activeTab = nullptr;
1152 }
1153
1154 if( m_pcb == m_tabContexts[reuseSlot]->GetBoard() )
1155 m_pcb = nullptr;
1156
1157 m_tabContexts[reuseSlot] = std::move( ctx );
1158 }
1159 else
1160 {
1161 m_tabContexts.push_back( std::move( ctx ) );
1162 }
1163
1164 m_tabsPanel->AddTab( key, name, aAsPreview );
1165
1166 return raw;
1167}
1168
1169
1171 UNDO_REDO_CONTAINER& aRedo )
1172{
1173 // Free the UR_TRANSIENT board items each command owns and the command wrappers. The frame's own
1174 // ClearUndoRedoList() and the bare container destructor delete only the wrappers and leak the
1175 // transient items, so a discarded tab history must come through here.
1176 for( UNDO_REDO_CONTAINER* list : { &aUndo, &aRedo } )
1177 {
1178 for( PICKED_ITEMS_LIST* cmd : list->m_CommandsList )
1179 {
1181 delete cmd;
1182 }
1183
1184 list->m_CommandsList.clear();
1185 }
1186}
1187
1188
1190{
1191 // The context is detached here, so the transient items in its lists are never the live objects.
1193}
1194
1195
1197{
1198 if( aIdx < 0 || aIdx >= static_cast<int>( m_tabContexts.size() ) )
1199 return false;
1200
1202
1203 // The active tab's live dirty state lives on the shared frame screen, so ctx->IsModified() is
1204 // stale for it. Fold the screen state back in so an unsaved active tab still prompts.
1205 if( ctx == m_activeTab && GetScreen() )
1207
1208 if( ctx->IsModified() )
1209 {
1210 // Prompt while the closing tab is still fully live so a save reads its real board.
1211 wxString msg = wxString::Format( _( "Save changes to '%s' before closing?" ),
1212 ctx->GetName() );
1213
1214 KIDIALOG dlg( this, msg, _( "Confirmation" ), wxYES_NO | wxCANCEL | wxICON_WARNING );
1215 dlg.SetYesNoCancelLabels( _( "Save" ), _( "Discard Changes" ), _( "Cancel" ) );
1216
1217 switch( dlg.ShowModal() )
1218 {
1219 case wxID_YES:
1220 // SaveFootprint reads the active tab's load baseline for rename detection, so an inactive
1221 // tab must be made active first or it saves against the wrong baseline. Veto the close if
1222 // the save did not complete so the edits and history are not silently dropped.
1223 if( ctx != m_activeTab )
1224 activateFootprintTab( ctx );
1225
1226 if( !SaveFootprint( ctx->GetBoard()->GetFirstFootprint() ) )
1227 return false;
1228
1229 break;
1230
1231 case wxID_NO: break;
1232 default:
1233 case wxID_CANCEL: return false;
1234 }
1235 }
1236
1237 const bool closingActive = ( ctx == m_activeTab );
1238
1239 if( !closingActive )
1240 {
1241 // m_pcb aliases a different live tab's board, so freeing this context dangles nothing.
1243 m_tabContexts.erase( m_tabContexts.begin() + aIdx );
1244 return true;
1245 }
1246
1247 // The closing tab's lists are currently the frame's live lists. Free them now with their
1248 // transient items, so the install's detach swaps empty lists into the closing context.
1250
1251 const int newCount = static_cast<int>( m_tabContexts.size() ) - 1;
1252 const int successorIdx = newCount > 0 ? std::min( aIdx, newCount - 1 ) : -1;
1253
1254 if( successorIdx >= 0 )
1255 {
1256 // Map the successor's post-erase position back to a pre-erase index. Indices above the closed
1257 // one shift down by one after the erase.
1258 const int preEraseSuccessor = successorIdx < aIdx ? successorIdx : successorIdx + 1;
1259
1260 FOOTPRINT_EDITOR_TAB_CONTEXT* successor = m_tabContexts[preEraseSuccessor].get();
1261
1262 installFootprintTabBoard( successor, successor->GetBoard() );
1263 }
1264 else
1265 {
1266 // Last tab: the fresh empty board is frame-owned like the bootstrap board.
1267 BOARD* emptyBoard = new BOARD();
1268 emptyBoard->SetBoardUse( BOARD_USE::FPHOLDER );
1270 emptyBoard->GetDesignSettings().m_SolderMaskExpansion = 0;
1271 emptyBoard->SetVisibleAlls();
1272
1273 installFootprintTabBoard( nullptr, emptyBoard );
1274 }
1275
1276 // The install swapped m_pcb off the closing board, so erasing the context frees it safely.
1277 m_tabContexts.erase( m_tabContexts.begin() + aIdx );
1278
1279 return true;
1280}
1281
1282
1284{
1285 if( m_tabsPanel )
1286 m_tabsPanel->RefreshTabLabels();
1287}
1288
1289
1291{
1292 wxCHECK( aReplacement, /* void */ );
1293
1294 // Install the fresh frame-owned board and reset the tools against it before any tab board is
1295 // freed, so no ResetTools or repaint sees a freed or null m_pcb.
1296 installFootprintTabBoard( nullptr, aReplacement );
1297
1298 // Tear the strip down without re-prompting to save, since unsaved changes were already handled.
1299 // Suppress the host close callback and tab activation so CloseAll only does panel bookkeeping.
1300 if( m_tabsPanel )
1301 {
1302 std::function<bool( int )> savedCb = std::move( m_tabsPanel->onCloseTabRequested );
1303 m_tabsPanel->onCloseTabRequested = []( int ) { return true; };
1304
1306 m_tabsPanel->CloseAll();
1308
1309 m_tabsPanel->onCloseTabRequested = std::move( savedCb );
1310 }
1311
1312 wxASSERT_MSG( m_pcb == aReplacement,
1313 wxT( "m_pcb must alias the frame-owned replacement before contexts are freed" ) );
1314
1315 for( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& ctx : m_tabContexts )
1317
1318 m_tabContexts.clear();
1319}
1320
1321
1323{
1324 if( m_tabsPanel )
1325 m_tabsPanel->AdvanceTab( aForward );
1326}
1327
1328
1330{
1331 if( !m_tabsPanel )
1332 return;
1333
1334 const int active = m_tabsPanel->GetActiveTab();
1335
1336 if( active >= 0 && active < static_cast<int>( m_tabContexts.size() ) )
1337 {
1338 const bool pinned = !m_tabContexts[active]->IsPinned();
1339
1340 // SetPinned mirrors the change into the context through the panel's onPinChanged channel, so
1341 // this one call keeps the panel model and the persisted context flag in sync.
1342 m_tabsPanel->SetPinned( active, pinned );
1343 }
1344}
1345
1346
1348{
1349 if( m_tabsPanel )
1350 m_tabsPanel->CloseTab( m_tabsPanel->GetActiveTab() );
1351}
1352
1353
1358
1359
1364
1365
1367{
1368 wxFAIL_MSG( wxT( "Plotting not supported in Footprint Editor" ) );
1369
1371}
1372
1373
1375{
1376 wxFAIL_MSG( wxT( "Plotting not supported in Footprint Editor" ) );
1377}
1378
1379
1387
1388
1396
1397
1399{
1400 // Get our own settings; aCfg will be the PCBNEW_SETTINGS because we're part of the pcbnew
1401 // compile unit
1403
1404 if( cfg )
1405 {
1407
1409
1412
1414 m_selectionFilterPanel->SetCheckboxesFromFilter( cfg->m_SelectionFilter );
1415
1417
1418 for( auto& [source_name, dest_name] : cfg->m_DesignSettings.m_UserLayerNames )
1419 {
1420 wxString wx_source_name = source_name;
1421 PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( LSET::NameToLayer( wx_source_name ) );
1422
1423 if( IsUserLayer( layer ) )
1424 GetBoard()->SetLayerName( layer, dest_name );
1425 }
1426
1427 }
1428}
1429
1430
1432{
1433 // Load canvas type from the FOOTPRINT_EDITOR_SETTINGS:
1435
1436 // If we had an OpenGL failure this session, use the fallback GAL but don't update the
1437 // user preference silently:
1438
1441}
1442
1443
1445{
1447
1448 // Get our own settings; aCfg will be the PCBNEW_SETTINGS because we're part of the pcbnew
1449 // compile unit
1451
1452 if( cfg )
1453 {
1455
1458 cfg->m_LibWidth = m_treePane->GetSize().x;
1459
1460 if( TOOL_MANAGER* toolMgr = GetToolManager() )
1461 {
1462 if( PCB_SELECTION_TOOL* selTool = toolMgr->GetTool<PCB_SELECTION_TOOL>() )
1463 cfg->m_SelectionFilter = selTool->GetFilter();
1464 }
1465
1467
1468 if( m_propertiesPanel )
1469 {
1470 cfg->m_AuiPanels.show_properties = m_propertiesPanel->IsShownOnScreen();
1472 cfg->m_AuiPanels.properties_splitter = m_propertiesPanel->SplitterProportion();
1473 }
1474
1476
1477 if( m_appearancePanel )
1478 {
1481 cfg->m_LayerPresets = m_appearancePanel->GetUserLayerPresets();
1482 cfg->m_ActiveLayerPreset = m_appearancePanel->GetActiveLayerPreset();
1483 }
1484
1485 cfg->m_OpenTabs.clear();
1486 cfg->m_ActiveTab.Clear();
1487
1488 // Only library footprints are remembered. A footprint pulled from the board is edited on the
1489 // frame-owned board with no backing tab (LoadFootprintFromBoard clears every tab first), so it
1490 // must never be persisted as a tab.
1491 if( !IsCurrentFPFromBoard() )
1492 {
1493 for( const std::unique_ptr<FOOTPRINT_EDITOR_TAB_CONTEXT>& ctx : m_tabContexts )
1494 {
1495 cfg->m_OpenTabs.push_back( { ctx->GetLib(), ctx->GetName(), ctx->IsPinned() } );
1496
1497 if( ctx.get() == m_activeTab )
1498 cfg->m_ActiveTab = ctx->GetTabKey();
1499 }
1500 }
1501 }
1502}
1503
1504
1505
1507{
1508 FOOTPRINT_EDITOR_SETTINGS* cfg = const_cast<FOOTPRINT_EDIT_FRAME*>( this )->GetSettings();
1509
1510 return cfg ? cfg->m_RotationAngle : ANGLE_90;
1511}
1512
1513
1514
1516{
1518 return ::GetColorSettings( cfg ? cfg->m_ColorTheme : DEFAULT_THEME );
1519}
1520
1521
1523{
1524 static MAGNETIC_SETTINGS fallback;
1525
1527 return &cfg->m_MagneticItems;
1528
1529 return &fallback;
1530}
1531
1532
1533const BOX2I FOOTPRINT_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
1534{
1535 FOOTPRINT* footprint = GetBoard()->GetFirstFootprint();
1536
1537 if( footprint )
1538 {
1539 bool hasGraphicalItem = footprint->Pads().size() || footprint->Zones().size();
1540
1541 if( !hasGraphicalItem )
1542 {
1543 for( const BOARD_ITEM* item : footprint->GraphicalItems() )
1544 {
1545 if( item->Type() == PCB_TEXT_T || item->Type() == PCB_TEXTBOX_T )
1546 continue;
1547
1548 hasGraphicalItem = true;
1549 break;
1550 }
1551 }
1552
1553 if( hasGraphicalItem )
1554 {
1555 return footprint->GetBoundingBox( false );
1556 }
1557 else
1558 {
1559 BOX2I newFootprintBB( { 0, 0 }, { 0, 0 } );
1560 newFootprintBB.Inflate( pcbIUScale.mmToIU( 12 ) );
1561 return newFootprintBB;
1562 }
1563 }
1564
1565 return GetBoardBoundingBox( false );
1566}
1567
1568
1570{
1571 if( IsContentModified() )
1572 {
1573 wxString footprintName = GetBoard()->GetFirstFootprint()->GetReference();
1574 wxString msg = _( "Save changes to '%s' before closing?" );
1575
1576 if( !HandleUnsavedChanges( this, wxString::Format( msg, footprintName ),
1577 [&]() -> bool
1578 {
1579 return SaveFootprint( GetBoard()->GetFirstFootprint() );
1580 } ) )
1581 {
1582 return false;
1583 }
1584 }
1585
1586 if( doClose )
1587 {
1588 GetInfoBar()->ShowMessageFor( wxEmptyString, 1 );
1589 Clear_Pcb( false );
1590 UpdateTitle();
1591 }
1592
1593 return true;
1594}
1595
1596
1597bool FOOTPRINT_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
1598{
1599 if( IsContentModified() )
1600 {
1601 // Shutdown blocks must be determined and vetoed as early as possible
1603 aEvent.GetId() == wxEVT_QUERY_END_SESSION )
1604 {
1605 aEvent.Veto();
1606 return false;
1607 }
1608
1609 wxString footprintName = GetBoard()->GetFirstFootprint()->GetFPID().GetLibItemName();
1610
1611 if( IsCurrentFPFromBoard() )
1612 footprintName = GetBoard()->GetFirstFootprint()->GetReference();
1613
1614 wxString msg = _( "Save changes to '%s' before closing?" );
1615
1616 if( !HandleUnsavedChanges( this, wxString::Format( msg, footprintName ),
1617 [&]() -> bool
1618 {
1619 return SaveFootprint( GetBoard()->GetFirstFootprint() );
1620 } ) )
1621 {
1622 aEvent.Veto();
1623 return false;
1624 }
1625 }
1626
1627 PAD_TOOL* padTool = m_toolManager->GetTool<PAD_TOOL>();
1628
1629 if( padTool->InPadEditMode() )
1630 padTool->ExitPadEditMode();
1631
1632 // Save footprint tree column widths
1633 m_adapter->SaveSettings();
1634
1635 return PCB_BASE_EDIT_FRAME::canCloseWindow( aEvent );
1636}
1637
1638
1640{
1641 // No more vetos
1642 GetCanvas()->SetEventDispatcher( nullptr );
1644
1645#ifdef KICAD_IPC_API
1646 Pgm().GetApiServer().DeregisterHandler( m_apiHandler.get() );
1647#endif
1648
1649 if( GetLibTree() )
1651
1652 // Do not show the layer manager during closing to avoid flicker
1653 // on some platforms (Windows) that generate useless redraw of items in
1654 // the Layer Manager
1655 m_auimgr.GetPane( wxT( "LayersManager" ) ).Show( false );
1656 m_auimgr.GetPane( wxT( "SelectionFilter" ) ).Show( false );
1657
1658 Clear_Pcb( false );
1659}
1660
1661
1662void FOOTPRINT_EDIT_FRAME::OnExitKiCad( wxCommandEvent& event )
1663{
1664 Kiway().OnKiCadExit();
1665}
1666
1667
1669{
1670 Close();
1671}
1672
1673
1675{
1676 // call my base class
1678
1679 // We have 2 panes to update.
1680 // For some obscure reason, the AUI manager hides the first modified pane.
1681 // So force show panes
1682 wxAuiPaneInfo& tree_pane_info = m_auimgr.GetPane( m_treePane );
1683 bool tree_shown = tree_pane_info.IsShown();
1684 tree_pane_info.Caption( _( "Libraries" ) );
1685
1686 wxAuiPaneInfo& lm_pane_info = m_auimgr.GetPane( m_appearancePanel );
1687 bool lm_shown = lm_pane_info.IsShown();
1688 lm_pane_info.Caption( _( "Appearance" ) );
1689 wxAuiPaneInfo& sf_pane_info = m_auimgr.GetPane( m_selectionFilterPanel );
1690 sf_pane_info.Caption( _( "Selection Filter" ) );
1691
1692 // update the layer manager
1694
1695 // Now restore the visibility:
1696 lm_pane_info.Show( lm_shown );
1697 tree_pane_info.Show( tree_shown );
1698 m_auimgr.Update();
1699
1701
1702 UpdateTitle();
1703}
1704
1705
1707{
1709
1710 if( m_isClosing )
1711 return;
1712
1713 // An edit promotes the active tab from preview to permanent and flags it dirty. Reflect the
1714 // shared screen's dirty state onto the context and panel model so the tab shows bold + "*" and a
1715 // later library-open opens its own tab instead of replacing this one.
1716 if( m_tabsPanel && m_activeTab )
1717 {
1718 m_activeTab->SetPreview( false );
1719 m_activeTab->SetModified( true );
1720
1721 if( int idx = m_tabsPanel->FindTab( m_activeTab->GetTabKey() ); idx >= 0 )
1722 m_tabsPanel->MarkModified( idx, true );
1723 }
1724
1725 Update3DView( true, true );
1727
1728 if( !GetTitle().StartsWith( wxT( "*" ) ) )
1729 UpdateTitle();
1730}
1731
1732
1734{
1735 wxString title;
1736 LIB_ID fpid = GetLoadedFPID();
1737 FOOTPRINT* footprint = GetBoard() ? GetBoard()->GetFirstFootprint() : nullptr;
1738 bool writable = true;
1739
1740 if( IsCurrentFPFromBoard() )
1741 {
1742 if( IsContentModified() )
1743 title = wxT( "*" );
1744
1745 title += footprint->GetReference();
1746 title += wxS( " " ) + wxString::Format( _( "[from %s]" ), Prj().GetProjectName()
1747 + wxT( "." )
1748 + FILEEXT::PcbFileExtension );
1749 }
1750 else if( fpid.IsValid() )
1751 {
1752 try
1753 {
1755 }
1756 catch( const IO_ERROR& )
1757 {
1758 // best efforts...
1759 }
1760
1761 // Note: don't used GetLoadedFPID(); footprint name may have been edited
1762 if( IsContentModified() )
1763 title = wxT( "*" );
1764
1765 title += From_UTF8( footprint->GetFPID().Format().c_str() );
1766
1767 if( !writable )
1768 title += wxS( " " ) + _( "[Read Only]" );
1769 }
1770 else if( !fpid.GetLibItemName().empty() )
1771 {
1772 // Note: don't used GetLoadedFPID(); footprint name may have been edited
1773 if( IsContentModified() )
1774 title = wxT( "*" );
1775
1776 title += From_UTF8( footprint->GetFPID().GetLibItemName().c_str() );
1777 title += wxS( " " ) + _( "[Unsaved]" );
1778 }
1779 else
1780 {
1781 title = _( "[no footprint loaded]" );
1782 }
1783
1784 title += wxT( " \u2014 " ) + _( "Footprint Editor" );
1785
1786 SetTitle( title );
1787}
1788
1789
1791{
1792 m_appearancePanel->OnBoardChanged();
1793}
1794
1795
1797{
1801 m_propertiesPanel->UpdateData();
1802 UpdateTitle();
1803}
1804
1805
1807{
1809
1811 auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
1812
1813 adapter->AddLibraries( this );
1814}
1815
1816
1817void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( [[maybe_unused]] bool aProgress )
1818{
1819 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "FOOTPRINT_EDIT_FRAME::SyncLibraryTree enter" ) );
1820
1822 auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
1823 LIB_ID target = GetTargetFPID();
1824 bool targetSelected = ( target == GetLibTree()->GetSelectedLibId() );
1825
1826 // Unselect before syncing to avoid null reference in the adapter
1827 // if a selected item is removed during the sync
1828 GetLibTree()->Unselect();
1829
1830 // Sync the LIB_TREE to the FOOTPRINT_INFO list
1831 adapter->Sync( footprints );
1832
1833 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "FOOTPRINT_EDIT_FRAME::SyncLibraryTree Regenerate" ) );
1834 GetLibTree()->Regenerate( true );
1835
1836 if( target.IsValid() )
1837 {
1838 if( adapter->FindItem( target ) )
1839 {
1840 if( targetSelected )
1841 GetLibTree()->SelectLibId( target );
1842 else
1843 GetLibTree()->CenterLibId( target );
1844 }
1845 else
1846 {
1847 // Try to focus on parent
1848 target.SetLibItemName( wxEmptyString );
1849 GetLibTree()->CenterLibId( target );
1850 }
1851 }
1852
1853 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "FOOTPRINT_EDIT_FRAME::SyncLibraryTree exit" ) );
1854}
1855
1856
1861
1862
1864{
1865 GetLibTree()->SelectLibId( aLibID );
1866}
1867
1868
1870{
1871 m_appearancePanel->UpdateDisplayOptions();
1872}
1873
1874
1876{
1877 // Create the manager and dispatcher & route draw panel events to the dispatcher
1879 m_toolManager->SetEnvironment( GetBoard(), GetCanvas()->GetView(),
1880 GetCanvas()->GetViewControls(), config(), this );
1881 m_actions = new PCB_ACTIONS();
1883
1885
1886 m_toolManager->RegisterTool( new COMMON_CONTROL );
1887 m_toolManager->RegisterTool( new COMMON_TOOLS );
1888 m_toolManager->RegisterTool( new PCB_SELECTION_TOOL );
1889 m_toolManager->RegisterTool( new ZOOM_TOOL );
1890 m_toolManager->RegisterTool( new EDIT_TOOL );
1891 m_toolManager->RegisterTool( new PCB_EDIT_TABLE_TOOL );
1892 m_toolManager->RegisterTool( new PAD_TOOL );
1893 m_toolManager->RegisterTool( new DRAWING_TOOL );
1894 m_toolManager->RegisterTool( new PCB_POINT_EDITOR );
1895 m_toolManager->RegisterTool( new PCB_CONTROL ); // copy/paste
1896 m_toolManager->RegisterTool( new LIBRARY_EDITOR_CONTROL );
1897 m_toolManager->RegisterTool( new FOOTPRINT_EDITOR_CONTROL );
1898 m_toolManager->RegisterTool( new ALIGN_DISTRIBUTE_TOOL );
1899 m_toolManager->RegisterTool( new PCB_PICKER_TOOL );
1900 m_toolManager->RegisterTool( new POSITION_RELATIVE_TOOL );
1901 m_toolManager->RegisterTool( new ARRAY_TOOL );
1902 m_toolManager->RegisterTool( new PCB_VIEWER_TOOLS );
1903 m_toolManager->RegisterTool( new PCB_GROUP_TOOL );
1904 m_toolManager->RegisterTool( new CONVERT_TOOL );
1905 m_toolManager->RegisterTool( new PROPERTIES_TOOL );
1906 m_toolManager->RegisterTool( new EMBED_TOOL );
1907
1908 for( TOOL_BASE* tool : m_toolManager->Tools() )
1909 {
1910 if( PCB_TOOL_BASE* pcbTool = dynamic_cast<PCB_TOOL_BASE*>( tool ) )
1911 pcbTool->SetIsFootprintEditor( true );
1912 }
1913
1914 m_toolManager->GetTool<PCB_VIEWER_TOOLS>()->SetFootprintFrame( true );
1915 m_toolManager->InitTools();
1916
1917 m_toolManager->InvokeTool( "common.InteractiveSelection" );
1918
1919 // Load or reload wizard plugins in case they changed since the last time the frame opened
1920 // Because the board editor has also a plugin python menu,
1921 // call the PCB_EDIT_FRAME RunAction() if the board editor is running
1922 // Otherwise run the current RunAction().
1923 PCB_EDIT_FRAME* pcbframe = static_cast<PCB_EDIT_FRAME*>( Kiway().Player( FRAME_PCB_EDITOR, false ) );
1924
1925 if( pcbframe )
1927 else
1929}
1930
1931
1933{
1935
1936 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
1937 PCB_EDITOR_CONDITIONS cond( this );
1938
1939 wxASSERT( mgr );
1940
1941#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
1942#define CHECK( x ) ACTION_CONDITIONS().Check( x )
1943
1944 auto haveFootprintCond =
1945 [this]( const SELECTION& )
1946 {
1947 return GetBoard() && GetBoard()->GetFirstFootprint() != nullptr;
1948 };
1949
1950 auto footprintTargettedCond =
1951 [this]( const SELECTION& )
1952 {
1953 return !GetTargetFPID().GetLibItemName().empty();
1954 };
1955
1956 auto footprintSelectedInTreeCond =
1957 [this]( const SELECTION& )
1958 {
1960 return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
1961 };
1962
1963 const auto footprintFromBoardCond =
1964 [this]( const SELECTION& )
1965 {
1966 return IsCurrentFPFromBoard();
1967 };
1968
1969 auto pcbFrameExistsCond =
1970 [this]( const SELECTION& )
1971 {
1972 PCB_EDIT_FRAME* frame = dynamic_cast<PCB_EDIT_FRAME*>( Kiway().Player( FRAME_PCB_EDITOR, false ) );
1973
1974 return ( frame != nullptr );
1975 };
1976
1977 auto boardFootprintExistsCond =
1978 [this]( const SELECTION& )
1979 {
1980 PCB_EDIT_FRAME* frame = dynamic_cast<PCB_EDIT_FRAME*>( Kiway().Player( FRAME_PCB_EDITOR, false ) );
1981
1982 FOOTPRINT* editorFootprint = GetBoard()->GetFirstFootprint();
1983 bool canInsert = frame && editorFootprint && editorFootprint->GetLink() == niluuid;
1984
1985 // If the source was deleted, the footprint can inserted but not updated in the board.
1986 if( frame && editorFootprint && editorFootprint->GetLink() != niluuid )
1987 {
1988 BOARD* mainpcb = frame->GetBoard();
1989 canInsert = true;
1990
1991 // search if the source footprint was not deleted:
1992 for( FOOTPRINT* candidate : mainpcb->Footprints() )
1993 {
1994 if( editorFootprint->GetLink() == candidate->m_Uuid )
1995 {
1996 canInsert = false;
1997 break;
1998 }
1999 }
2000 }
2001
2002 return canInsert;
2003 };
2004
2005 // clang-format off
2006 mgr->SetConditions( ACTIONS::saveAs, ENABLE( footprintTargettedCond ) );
2009 mgr->SetConditions( PCB_ACTIONS::editLibFpInFpEditor,ENABLE( footprintFromBoardCond ) );
2010
2011 mgr->SetConditions( PCB_ACTIONS::saveFpToBoard, ENABLE( boardFootprintExistsCond ) );
2012 mgr->SetConditions( PCB_ACTIONS::loadFpFromBoard, ENABLE( pcbFrameExistsCond ) );
2013
2016
2019
2020 mgr->SetConditions( ACTIONS::cut, ENABLE( cond.HasItems() ) );
2021 mgr->SetConditions( ACTIONS::copy, ENABLE( cond.HasItems() ) );
2028
2035
2039
2044 // clang-format on
2045
2046 auto highContrastCond =
2047 [this]( const SELECTION& )
2048 {
2050 };
2051
2052 auto boardFlippedCond = [this]( const SELECTION& )
2053 {
2055 };
2056
2057 auto libraryTreeCond =
2058 [this](const SELECTION& )
2059 {
2060 return IsLibraryTreeShown();
2061 };
2062
2063 auto layerManagerCond =
2064 [this]( const SELECTION& )
2065 {
2066 return m_auimgr.GetPane( "LayersManager" ).IsShown();
2067 };
2068
2069 auto propertiesCond =
2070 [this] ( const SELECTION& )
2071 {
2072 return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
2073 };
2074
2075 mgr->SetConditions( ACTIONS::highContrastMode, CHECK( highContrastCond ) );
2076 mgr->SetConditions( PCB_ACTIONS::flipBoard, CHECK( boardFlippedCond ) );
2078
2079 mgr->SetConditions( ACTIONS::showLibraryTree, CHECK( libraryTreeCond ) );
2080 mgr->SetConditions( PCB_ACTIONS::showLayersManager, CHECK( layerManagerCond ) );
2081 mgr->SetConditions( ACTIONS::showProperties, CHECK( propertiesCond ) );
2082
2083 mgr->SetConditions( ACTIONS::print, ENABLE( haveFootprintCond ) );
2084 mgr->SetConditions( PCB_ACTIONS::exportFootprint, ENABLE( haveFootprintCond ) );
2085 mgr->SetConditions( PCB_ACTIONS::placeImportedGraphics, ENABLE( haveFootprintCond ) );
2086
2087 mgr->SetConditions( PCB_ACTIONS::footprintProperties, ENABLE( footprintSelectedInTreeCond || haveFootprintCond ) );
2088 mgr->SetConditions( PCB_ACTIONS::padTable, ENABLE( haveFootprintCond ) );
2089 mgr->SetConditions( PCB_ACTIONS::editTextAndGraphics, ENABLE( haveFootprintCond ) );
2090 mgr->SetConditions( PCB_ACTIONS::checkFootprint, ENABLE( haveFootprintCond ) );
2091 mgr->SetConditions( PCB_ACTIONS::repairFootprint, ENABLE( haveFootprintCond ) );
2092 mgr->SetConditions( PCB_ACTIONS::cleanupGraphics, ENABLE( haveFootprintCond ) );
2093 mgr->SetConditions( ACTIONS::showDatasheet, ENABLE( haveFootprintCond ) );
2094
2095 const auto isArcKeepCenterMode =
2096 [this]( const SELECTION& )
2097 {
2099 };
2100
2101 const auto isArcKeepEndpointMode =
2102 [this]( const SELECTION& )
2103 {
2105 };
2106
2107 const auto isArcKeepRadiusMode =
2108 [this]( const SELECTION& )
2109 {
2111 };
2112
2113 // clang-format off
2114 mgr->SetConditions( ACTIONS::pointEditorArcKeepCenter, CHECK( isArcKeepCenterMode ) );
2115 mgr->SetConditions( ACTIONS::pointEditorArcKeepEndpoint, CHECK( isArcKeepEndpointMode ) );
2116 mgr->SetConditions( ACTIONS::pointEditorArcKeepRadius, CHECK( isArcKeepRadiusMode ) );
2117 // clang-format on
2118
2119// Only enable a tool if the part is edtable
2120#define CURRENT_EDIT_TOOL( action ) \
2121 mgr->SetConditions( action, ACTION_CONDITIONS().Enable( haveFootprintCond ) \
2122 .Check( cond.CurrentTool( action ) ) )
2123
2150
2151#undef CURRENT_EDIT_TOOL
2152#undef ENABLE
2153#undef CHECK
2154}
2155
2156
2158{
2160
2161 // Be sure the axis are enabled
2162 GetCanvas()->GetGAL()->SetAxesEnabled( true );
2163
2164 UpdateView();
2165
2166 // Ensure the m_Layers settings are using the canvas type:
2168}
2169
2170
2172{
2174 m_appearancePanel->CommonSettingsChanged( aFlags );
2175
2177 {
2178 GetGalDisplayOptions().ReadWindowSettings( cfg->m_Window );
2179
2180 GetBoard()->GetDesignSettings() = cfg->m_DesignSettings;
2182 }
2183
2187
2189
2190 if( aFlags & ENVVARS_CHANGED )
2191 SyncLibraryTree( true );
2192
2193 Layout();
2194 SendSizeEvent();
2195}
2196
2197
2198std::unique_ptr<GRID_HELPER> FOOTPRINT_EDIT_FRAME::MakeGridHelper()
2199{
2200 return std::make_unique<PCB_GRID_HELPER>( m_toolManager, GetMagneticItemsSettings() );
2201}
2202
2203
2205{
2206 LIB_ID id = GetLoadedFPID();
2207
2208 if( id.empty() )
2209 {
2210 DisplayErrorMessage( this, _( "No footprint selected." ) );
2211 return;
2212 }
2213
2214 wxFileName fn( id.GetLibItemName() );
2215 fn.SetExt( wxT( "png" ) );
2216
2217 wxString projectPath = wxPathOnly( Prj().GetProjectFullName() );
2218
2219 wxFileDialog dlg( this, _( "Export View as PNG" ), projectPath, fn.GetFullName(),
2220 FILEEXT::PngFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
2221
2223
2224 if( dlg.ShowModal() == wxID_CANCEL || dlg.GetPath().IsEmpty() )
2225 return;
2226
2227 // calling wxYield is mandatory under Linux, after closing the file selector dialog
2228 // to refresh the screen before creating the PNG or JPEG image from screen
2229 wxYield();
2230 this->SaveCanvasImageToFile( dlg.GetPath(), BITMAP_TYPE::PNG );
2231}
const char * name
@ 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:125
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition bitmap.cpp:104
@ icon_modedit_32
@ icon_modedit_16
@ FPHOLDER
Definition board.h:315
@ NORMAL
Inactive layers are shown normally (no high-contrast mode)
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
static TOOL_ACTION toggleGrid
Definition actions.h:198
static TOOL_ACTION paste
Definition actions.h:80
static TOOL_ACTION unselectAll
Definition actions.h:83
static TOOL_ACTION revert
Definition actions.h:62
static TOOL_ACTION showLibraryTree
Definition actions.h:164
static TOOL_ACTION saveAs
Definition actions.h:59
static TOOL_ACTION copy
Definition actions.h:78
static TOOL_ACTION pluginsReload
Definition actions.h:294
static TOOL_ACTION selectSetLasso
Definition actions.h:221
static TOOL_ACTION selectSetRect
Set lasso selection mode.
Definition actions.h:220
static TOOL_ACTION group
Definition actions.h:239
static TOOL_ACTION pasteSpecial
Definition actions.h:81
static TOOL_ACTION showDatasheet
Definition actions.h:267
static TOOL_ACTION pointEditorArcKeepCenter
Definition actions.h:273
static TOOL_ACTION ungroup
Definition actions.h:240
static TOOL_ACTION toggleBoundingBoxes
Definition actions.h:157
static TOOL_ACTION pointEditorArcKeepRadius
Definition actions.h:275
static TOOL_ACTION undo
Definition actions.h:75
static TOOL_ACTION duplicate
Definition actions.h:84
static TOOL_ACTION highContrastMode
Definition actions.h:155
static TOOL_ACTION embeddedFiles
Definition actions.h:297
static TOOL_ACTION measureTool
Definition actions.h:252
static TOOL_ACTION doDelete
Definition actions.h:85
static TOOL_ACTION selectionTool
Definition actions.h:251
static TOOL_ACTION save
Definition actions.h:58
static TOOL_ACTION zoomFitScreen
Definition actions.h:142
static TOOL_ACTION redo
Definition actions.h:76
static TOOL_ACTION deleteTool
Definition actions.h:86
static TOOL_ACTION zoomTool
Definition actions.h:146
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:224
static TOOL_ACTION print
Definition actions.h:64
static TOOL_ACTION showProperties
Definition actions.h:266
static TOOL_ACTION cut
Definition actions.h:77
static TOOL_ACTION gridSetOrigin
Definition actions.h:195
static TOOL_ACTION ddAddLibrary
Definition actions.h:67
static TOOL_ACTION toggleGridOverrides
Definition actions.h:199
static TOOL_ACTION selectAll
Definition actions.h:82
static TOOL_ACTION pointEditorArcKeepEndpoint
Definition actions.h:274
Manage TOOL_ACTION objects.
void SetConditions(const TOOL_ACTION &aAction, const ACTION_CONDITIONS &aConditions)
Set the conditions the UI elements for activating a specific tool action should use for determining t...
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
wxString m_ColorTheme
Active color theme name.
The array tool.
Definition array_tool.h:48
bool IsContentModified() const
Definition base_screen.h:60
void SetContentModified(bool aModified=true)
Definition base_screen.h:59
BASE_SET & set(size_t pos)
Definition base_set.h:116
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
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
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition board_item.h:288
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:323
void SetBoardUse(BOARD_USE aUse)
Set what the board is going to be used for.
Definition board.h:335
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition board.cpp:763
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition board.h:524
void SetVisibleAlls()
Change the bit-mask of visible element categories and layers.
Definition board.cpp:1035
const FOOTPRINTS & Footprints() const
Definition board.h:364
void SetCopperLayerCount(int aCount)
Definition board.cpp:943
void DeleteAllFootprints()
Remove all footprints from the deque and free the memory associated with them.
Definition board.cpp:1774
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1101
void SetEnabledLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition board.cpp:1006
void SetUserUnits(EDA_UNITS aUnits)
Definition board.h:820
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.
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.
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:100
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()
Module editor specific tools.
BOARD_DESIGN_SETTINGS m_DesignSettings
Only some of these settings are actually used for footprint editing.
std::vector< OPEN_TAB > m_OpenTabs
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.
BOARD * GetBoard() const
The fp-holder board owned by this context.
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.
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 HardRedraw() override
Refresh the library tree and redraw the window.
static const wxChar * GetFootprintEditorFrameName()
void SyncLibraryTree(bool aProgress)
Synchronize the footprint library tree to the current state of the footprint library table.
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.
EDITOR_TABS_PANEL * m_tabsPanel
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 initLibraryTree()
Make sure the footprint info list is loaded (with a progress dialog) and then initialize the footprin...
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
void PinActiveFootprintTab()
Toggle the pinned state of the active tab.
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 Clear_Pcb(bool doAskAboutUnsavedChanges)
Delete all and reinitialize the current board.
Definition initpcb.cpp:108
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.
SELECTION & GetCurrentSelection() override
Get the current selection from the canvas area.
void AdvanceFootprintTab(bool aForward)
Advance the active tab forward or backward in MRU order.
bool CanCloseFPFromBoard(bool doClose)
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...
std::unique_ptr< FOOTPRINT > m_originalFootprintCopy
void ReloadFootprint(FOOTPRINT *aFootprint) override
Override from PCB_BASE_FRAME which reloads the footprint from the library without setting the footpri...
EDA_ANGLE GetRotationAngle() const override
Return the angle used for rotate operations.
void RefreshLibraryTree()
Redisplay the library tree.
void installFootprintTabBoard(FOOTPRINT_EDITOR_TAB_CONTEXT *aCtx, BOARD *aBoard)
Install aBoard as the active document non-destructively, wiring the tool environment and resetting th...
void OnExitKiCad(wxCommandEvent &aEvent)
bool promptAndCloseFootprintTab(int aIdx)
Prompt to save if needed, then drop the tab context at aIdx.
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
MAGNETIC_SETTINGS * GetMagneticItemsSettings() override
FOOTPRINT_EDITOR_SETTINGS * GetSettings()
FOOTPRINT_EDITOR_TAB_CONTEXT * findOrCreateFootprintTab(const LIB_ID &aLibId, bool aAsPreview)
Find or create the tab for aLibId over its own fp-holder board and make it the active tab.
void SwitchCanvas(EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType) override
Switch the currently used canvas (Cairo / OpenGL).
void freeUndoRedoCommandsWithItems(UNDO_REDO_CONTAINER &aUndo, UNDO_REDO_CONTAINER &aRedo)
Free both the transient board items and the command wrappers in the given lists.
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
An interface to the global shared library manager that is schematic-specific and linked to one projec...
bool IsFootprintLibWritable(const wxString &aNickname)
Return true if the library given by aNickname is writable.
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,...
ZONES & Zones()
Definition footprint.h:383
EDA_ITEM * Clone() const override
Invoke a function on all children.
std::deque< PAD * > & Pads()
Definition footprint.h:377
const LIB_ID & GetFPID() const
Definition footprint.h:429
const LSET & GetStackupLayers() const
Definition footprint.h:493
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.
KIID GetLink() const
Definition footprint.h:1163
const wxString & GetReference() const
Definition footprint.h:829
FOOTPRINT_STACKUP GetStackupMode() const
Definition footprint.h:486
DRAWINGS & GraphicalItems()
Definition footprint.h:380
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
void AddLibraries(EDA_BASE_FRAME *aParent)
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.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition kidialog.h:42
int ShowModal() override
Definition kidialog.cpp:93
bool m_axesEnabled
Crosshair drawing mode.
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:91
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:67
double GetScale() const
Definition view.h:285
const VECTOR2D & GetCenter() const
Return the center point of this VIEW (in world space coordinates).
Definition view.h:355
virtual void SetScale(double aScale, VECTOR2D aAnchor={ 0, 0 })
Set the scaling factor, zooming around a given anchor point.
Definition view.cpp:641
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition view.cpp:848
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition view.h:409
void SetCenter(const VECTOR2D &aCenter)
Set the center point of the VIEW (i.e.
Definition view.cpp:667
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition view.h:661
Definition kiid.h:48
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:315
void OnKiCadExit()
Definition kiway.cpp:800
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:402
Module editor specific tools.
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:49
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition lib_id.cpp:111
bool IsValid() const
Check if this LID_ID is valid.
Definition lib_id.h:172
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:100
UTF8 Format() const
Definition lib_id.cpp:119
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition lib_id.h:112
const UTF8 & GetLibItemName() const
Definition lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:87
void RefreshLibTree()
Refresh the tree (mainly to update highlighting and asterisking)
Definition lib_tree.cpp:472
void CenterLibId(const LIB_ID &aLibId)
Ensure that an item is visible (preferably centered).
Definition lib_tree.cpp:381
void ShutdownPreviews()
Definition lib_tree.cpp:287
void ShowChangedLanguage()
Definition lib_tree.cpp:304
void SelectLibId(const LIB_ID &aLibId)
Select an item in the tree widget.
Definition lib_tree.cpp:375
LIB_TREE_MODEL_ADAPTER::SORT_MODE GetSortMode() const
Definition lib_tree.h:156
void Unselect()
Unselect currently selected item in wxDataViewCtrl.
Definition lib_tree.cpp:387
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:314
void Regenerate(bool aKeepState)
Regenerate the tree.
Definition lib_tree.cpp:454
void SetSortMode(LIB_TREE_MODEL_ADAPTER::SORT_MODE aMode)
Save/restore the sorting mode.
Definition lib_tree.h:155
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition lset.cpp:608
static const LSET & UserMask()
Definition lset.cpp:690
static int NameToLayer(wxString &aName)
Return the layer number from a layer name.
Definition lset.cpp:117
static const LSET & AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition lset.cpp:676
static LSET UserDefinedLayersMask(int aUserDefinedLayerCount=MAX_USER_DEFINED_LAYERS)
Return a mask with the requested number of user defined layers.
Definition lset.cpp:704
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition lset.cpp:188
void SetClearance(int aClearance)
Definition netclass.h:116
std::shared_ptr< NETCLASS > GetDefaultNetclass()
Gets the default netclass for the project.
void ExitPadEditMode()
Definition pad_tool.cpp:804
bool InPadEditMode()
Definition pad_tool.h:63
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition page_info.h:79
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 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 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 angleSnapModeChanged
Notification event when angle mode changes.
static TOOL_ACTION drawEllipse
static TOOL_ACTION ddImportFootprint
static TOOL_ACTION placeImportedGraphics
static TOOL_ACTION drawArc
static TOOL_ACTION graphicsOutlines
Display footprint graphics as outlines.
static TOOL_ACTION loadFpFromBoard
static TOOL_ACTION drawCenterDimension
static TOOL_ACTION footprintProperties
static TOOL_ACTION flipBoard
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 mirrorV
static TOOL_ACTION repairFootprint
static TOOL_ACTION saveFpToBoard
static TOOL_ACTION drawLine
static TOOL_ACTION cleanupGraphics
static TOOL_ACTION rotateCw
Rotation of selected objects.
static TOOL_ACTION rotateCcw
static TOOL_ACTION drawAlignedDimension
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.
void configureToolbars() override
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
Set the #m_Pcb member in such as way as to ensure deleting any previous BOARD.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
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.
void OnModify() override
Must be called after a change in order to set the "modify" flag and update other data structures and ...
FOOTPRINT * loadFootprint(const LIB_ID &aFootprintId)
Attempt to load aFootprintId from the footprint library table.
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.
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 #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.
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:130
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:231
@ PCB_FOOTPRINT_EDITOR_LIB_NICKNAME
Definition project.h:232
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:359
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:370
Action handler for the Properties panel.
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 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:66
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition tool_base.h:80
virtual void DispatchWxEvent(wxEvent &aEvent)
Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those.
Master controller class:
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
A holder to handle a list of undo (or redo) commands.
std::vector< PICKED_ITEMS_LIST * > m_CommandsList
EDA_UNITS GetUserUnits() const
bool empty() const
Definition utf8.h:109
const char * c_str() const
Definition utf8.h:108
A modified version of the wxInfoBar class that allows us to:
Definition wx_infobar.h:77
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION, MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the infobar with the provided message and icon for a specific period of time.
bool HasCloseButton() const
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition confirm.cpp:150
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:221
This file is part of the common library.
#define CHECK(x)
#define ENABLE(x)
static bool empty(const wxTextEntryBase *aCtrl)
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
#define KICAD_DEFAULT_DRAWFRAME_STYLE
#define FOOTPRINT_EDIT_FRAME_NAME
@ RECURSE
Definition eda_item.h:53
FOOTPRINT_STACKUP
Definition footprint.h:145
@ EXPAND_INNER_LAYERS
The 'normal' stackup handling, where there is a single inner layer (In1) and rule areas using it expa...
Definition footprint.h:150
@ CUSTOM_LAYERS
Stackup handling where the footprint can have any number of copper layers, and objects on those layer...
Definition footprint.h:155
#define CURRENT_EDIT_TOOL(action)
@ FRAME_PCB_EDITOR
Definition frame_type.h:42
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:43
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:116
@ ID_ON_ZOOM_SELECT
Definition id.h:115
PROJECT & Prj()
Definition kicad.cpp:669
TAB_VISUAL_STATE ResolveTabVisualState(bool aPreview, bool aModified, bool aPinned)
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:761
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ B_Cu
Definition layer_ids.h:65
@ F_SilkS
Definition layer_ids.h:100
@ In1_Cu
Definition layer_ids.h:66
@ F_Cu
Definition layer_ids.h:64
This file contains miscellaneous commonly used macros and functions.
@ TARGET_NONCACHED
Auxiliary rendering target (noncached)
Definition definitions.h:38
void SetShutdownBlockReason(wxWindow *aWindow, const wxString &aReason)
Sets the block reason why the window/application is preventing OS shutdown.
Definition unix/app.cpp: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:448
#define _HKI(x)
Definition page_info.cpp:44
@ ID_FPEDIT_SAVE_PNG
Definition pcbnew_id.h:81
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
#define DEFAULT_THEME
T * GetToolbarSettings(const wxString &aFilename)
T * GetAppSettings(const char *aFilename)
KIWAY Kiway(KFCTL_STANDALONE)
wxString UnescapeString(const wxString &aSource)
wxString From_UTF8(const char *cstring)
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 EDIT_TOOL(tool)
#define ENVVARS_CHANGED
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:108
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:90
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:89
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.