KiCad PCB EDA Suite
Loading...
Searching...
No Matches
symbol_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) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2008 Wayne Stambaugh <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <bitmaps.h>
23#include <wx/hyperlink.h>
24#include <base_screen.h>
25#include <confirm.h>
26#include <core/kicad_algo.h>
27#include <core/throttle.h>
28#include <eeschema_id.h>
29#include <eeschema_settings.h>
30#include <env_paths.h>
32#include <kidialog.h>
33#include <kiface_base.h>
34#include <kiplatform/app.h>
35#include <kiway_mail.h>
36#include <symbol_edit_frame.h>
40#include <paths.h>
41#include <pgm_base.h>
42#include <project_sch.h>
43#include <sch_painter.h>
44#include <sch_view.h>
48#include <tool/action_manager.h>
49#include <tool/action_toolbar.h>
50#include <tool/common_control.h>
51#include <tool/common_tools.h>
53#include <tool/embed_tool.h>
55#include <tool/picker_tool.h>
57#include <tool/selection.h>
59#include <tool/tool_manager.h>
60#include <tool/zoom_tool.h>
61#include <tools/sch_actions.h>
73#include <view/view_controls.h>
75#include <widgets/wx_infobar.h>
81#include <widgets/lib_tree.h>
86#include <panel_sym_lib_table.h>
87#include <string_utils.h>
89#include <wx/msgdlg.h>
90#include <wx/combobox.h>
91#include <wx/log.h>
92#include <trace_helpers.h>
93
94
96
97
98BEGIN_EVENT_TABLE( SYMBOL_EDIT_FRAME, SCH_BASE_FRAME )
101
102 // menubar commands
105
106 // Update user interface elements.
109
112
113 // Drop files event
114 EVT_DROP_FILES( SYMBOL_EDIT_FRAME::OnDropFiles )
115
116END_EVENT_TABLE()
117
118
119SYMBOL_EDIT_FRAME::SYMBOL_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
120 SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_SYMBOL_EDITOR, _( "Symbol Editor" ),
121 wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE,
123 m_unitSelectBox( nullptr ),
124 m_bodyStyleSelectBox( nullptr ),
125 m_drawSpecificUnit( false ),
129{
130 m_symbol = nullptr;
131 m_treePane = nullptr;
132 m_libMgr = nullptr;
133 m_unit = 1;
134 m_bodyStyle = 1;
136 m_aboutTitle = _HKI( "KiCad Symbol Editor" );
137
138 wxIcon icon;
139 wxIconBundle icon_bundle;
140
141 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit, 48 ) );
142 icon_bundle.AddIcon( icon );
143 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit, 256 ) );
144 icon_bundle.AddIcon( icon );
145 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit, 128 ) );
146 icon_bundle.AddIcon( icon );
147 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit_32 ) );
148 icon_bundle.AddIcon( icon );
149 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit_16 ) );
150 icon_bundle.AddIcon( icon );
151
152 SetIcons( icon_bundle );
153
156
158
159 m_treePane = new SYMBOL_TREE_PANE( this, m_libMgr );
160 m_treePane->GetLibTree()->SetSortMode( (LIB_TREE_MODEL_ADAPTER::SORT_MODE) m_settings->m_LibrarySortMode );
161
163
164 // Ensure axis are always drawn
166 gal_opts.m_axesEnabled = true;
167
170 GetScreen()->m_Center = true;
171
172 GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
173
174 GetRenderSettings()->LoadColors( GetColorSettings() );
175 GetRenderSettings()->m_IsSymbolEditor = true;
176 GetCanvas()->GetGAL()->SetAxesColor( m_colorSettings->GetColor( LAYER_SCHEMATIC_GRID_AXES ) );
177
178 setupTools();
180
182
186
189
190 m_propertiesPanel = new SCH_PROPERTIES_PANEL( this, this );
191 m_propertiesPanel->SetSplitterProportion( m_settings->m_AuiPanels.properties_splitter );
192
194
195 m_auimgr.SetManagedWindow( this );
196
198
199 // Rows; layers 4 - 6
200 m_auimgr.AddPane( m_tbTopMain, EDA_PANE().HToolbar().Name( "TopMainToolbar" )
201 .Top().Layer( 6 ) );
202
203 m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( "MsgPanel" )
204 .Bottom().Layer( 6 ) );
205
206 m_auimgr.AddPane( m_tbLeft, EDA_PANE().VToolbar().Name( "LeftToolbar" )
207 .Left().Layer( 2 ) );
208
209 m_auimgr.AddPane( m_tbRight, EDA_PANE().VToolbar().Name( "RightToolbar" )
210 .Right().Layer( 2 ) );
211
212 m_tabsPanel = new EDITOR_TABS_PANEL( this, GetCanvas() );
213
214 m_tabsPanel->onActivateTab =
215 [this]( int aIdx )
216 {
218 activateSymbolTab( ctx );
219 };
220
221 m_tabsPanel->onCloseTabRequested =
222 [this]( int aIdx ) -> bool
223 {
224 return promptAndCloseSymbolTab( aIdx );
225 };
226
227 m_tabsPanel->onQueryVisualState =
228 [this]( int aIdx ) -> TAB_VISUAL_STATE
229 {
230 // The panel model owns preview. Read modified from the live context.
231 const std::vector<EDITOR_TABS_MODEL::ENTRY>& entries = m_tabsPanel->Model().Entries();
232
233 if( aIdx < 0 || aIdx >= static_cast<int>( entries.size() ) )
234 return TAB_VISUAL_STATE{};
235
236 bool modified = entries[aIdx].modified;
237
239 modified = ctx->IsModified();
240
241 return ResolveTabVisualState( entries[aIdx].preview, modified );
242 };
243
244 m_auimgr.AddPane( m_tabsPanel, wxAuiPaneInfo().Name( "DrawFrame" )
245 .CentrePane() );
246
247 // Columns; layers 1 - 3
248 m_auimgr.AddPane( m_treePane, EDA_PANE().Palette().Name( "LibraryTree" )
249 .Left().Layer( 3 )
250 .TopDockable( false ).BottomDockable( false )
251 .Caption( _( "Libraries" ) )
252 // Don't use -1 for don't-change-height on a growable panel; it has side-effects.
253 .MinSize( FromDIP( 250 ), FromDIP( 80 ) )
254 .BestSize( FromDIP( 250 ), -1 ) );
255
258
259 // Can be called only when all panes are created, because (at least on Windows) when items
260 // managed by m_auimgr are not the same as those existing when saved by Perspective()
261 // in config, broken settings can happen.
263
264 // Protect against broken saved Perspective() due to bugs in previous version
265 // This is currently a workaround.
266 m_auimgr.GetPane( "TopMainToolbar" ).Top().Layer( 6 ).Position(0).Show( true );
267 m_auimgr.GetPane( "LeftToolbar" ).Position(0).Show( true );
268 m_auimgr.GetPane( "RightToolbar" ).Show( true );
269
270 // Show or hide m_propertiesPanel depending on current settings:
271 wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
272 wxAuiPaneInfo& selectionFilterPane = m_auimgr.GetPane( wxS( "SelectionFilter" ) );
273 // The selection filter doesn't need to grow in the vertical direction when docked
274 selectionFilterPane.dock_proportion = 0;
275
276 propertiesPaneInfo.Show( m_settings->m_AuiPanels.show_properties );
278
280
281 // Can't put this in LoadSettings, because it has to be called before setupTools :/
283 selTool->GetFilter() = GetSettings()->m_SelectionFilter;
284 m_selectionFilterPanel->SetCheckboxesFromFilter( selTool->GetFilter() );
285
286 if( m_settings->m_LibWidth > 0 )
287 SetAuiPaneSize( m_auimgr, m_auimgr.GetPane( "LibraryTree" ), m_settings->m_LibWidth, -1 );
288
289 Raise();
290 Show( true );
291
292 SyncView();
293 GetCanvas()->GetView()->UseDrawPriority( true );
294 GetCanvas()->GetGAL()->SetAxesEnabled( true );
295
297
298 // Set the working/draw area size to display a symbol to a reasonable value:
299 // A 600mm x 600mm with a origin at the area center looks like a large working area
300 double max_size_x = schIUScale.mmToIU( 600 );
301 double max_size_y = schIUScale.mmToIU( 600 );
302 BOX2D bbox;
303 bbox.SetOrigin( -max_size_x /2, -max_size_y/2 );
304 bbox.SetSize( max_size_x, max_size_y );
305 GetCanvas()->GetView()->SetBoundary( bbox );
306
308
310 m_acceptedExts.emplace( wxS( "dxf" ), &SCH_ACTIONS::ddImportGraphics );
312 DragAcceptFiles( true );
313
314 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "Library changes are unsaved" ) );
315
316 // Catch unhandled accelerator command characters that were no handled by the library tree
317 // panel.
319 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
320
321 // GTK rejects WXK_TAB as an accelerator so cycle tabs from the char hook ahead of the dispatcher.
322 Bind( wxEVT_CHAR_HOOK, &SYMBOL_EDIT_FRAME::OnTabCharHook, this );
323
324 // Ensure the window is on top
325 Raise();
326
327 // run SyncLibraries with progress reporter enabled. The progress reporter is useful
328 // in debug mode because the loading time of ecah library can be really noticeable
329 SyncLibraries( true );
330
331 // Must follow SyncLibraries so persisted tabs can resolve against the loaded libraries.
333}
334
335
337{
338 // Hand the borrowed canvas back before the base destructor frees it, else the panel reparents
339 // freed memory on its own teardown.
340 if( m_tabsPanel )
341 m_tabsPanel->ReleaseSharedCanvas();
342
343 // Shutdown all running tools
344 if( m_toolManager )
345 m_toolManager->ShutdownAllTools();
346
347 setSymWatcher( nullptr );
348
349 if( m_activeTab )
350 {
351 // Hand the working objects back so the context deletes them exactly once below; raw deleting
352 // here would double-free with the context dtor and leak the swapped-in undo list. Covers an
353 // active instance tab too, whose m_isSymbolFromSchematic mirror is only frame state.
355 m_activeTab->AdoptWorkingObjects( m_symbol, static_cast<SCH_SCREEN*>( GetScreen() ) );
356 m_activeTab = nullptr;
357 m_symbol = nullptr;
359 }
360 else
361 {
362 // No active tab owns the current screen, so let EDA_DRAW_FRAME free it.
364 }
365
366 // Free each detached context's undo/redo with the frame on the dummy screen to avoid double-frees.
367 for( const std::unique_ptr<SYMBOL_EDITOR_TAB_CONTEXT>& ctx : m_tabContexts )
369
370 m_tabContexts.clear();
371
373 Pgm().GetSettingsManager().Save( cfg );
374
375 delete m_libMgr;
376}
377
378
380{
381 wxCHECK_RET( m_settings, "Call to SYMBOL_EDIT_FRAME::LoadSettings with null m_settings" );
382
384
385 GetRenderSettings()->m_ShowPinsElectricalType = m_settings->m_ShowPinElectricalType;
386 GetRenderSettings()->m_ShowHiddenPins = m_settings->m_ShowHiddenPins;
387 GetRenderSettings()->m_ShowHiddenFields = m_settings->m_ShowHiddenFields;
388 GetRenderSettings()->m_ShowPinAltIcons = m_settings->m_ShowPinAltIcons;
389 GetRenderSettings()->SetDefaultFont( wxEmptyString );
390}
391
392
394{
395 wxCHECK_RET( m_settings, "Call to SYMBOL_EDIT_FRAME:SaveSettings with null m_settings" );
396
398
399 // The library tree is hidden while editing a symbol from the schematic. Force it visible in the
400 // serialized AUI layout so the user's preference survives a restart, but only touch the pane
401 // metadata (not ToggleLibraryTree) to avoid a mid-session repaint/flicker and a spurious tree
402 // width capture below.
403 wxAuiPaneInfo& treePane = m_auimgr.GetPane( m_treePane );
404 wxAuiPaneInfo& filterPane = m_auimgr.GetPane( wxS( "SelectionFilter" ) );
405
406 const bool treeShown = treePane.IsShown();
407 const bool filterShown = filterPane.IsShown();
408
409 // Gate on the pending-restore flag alone, not the active-tab schematic state, which is cleared
410 // when a schematic tab closes while the tree stays auto-hidden.
411 const bool forceTreeShown = m_libTreeAutoHiddenForSchematicEdit && !treeShown;
412
413 if( forceTreeShown )
414 {
415 treePane.Show( true );
417 }
418
420
421 if( forceTreeShown )
422 {
423 treePane.Show( treeShown );
424 filterPane.Show( filterShown );
425 }
426
427 m_settings->m_ShowPinElectricalType = GetRenderSettings()->m_ShowPinsElectricalType;
428 m_settings->m_ShowHiddenPins = GetRenderSettings()->m_ShowHiddenPins;
429 m_settings->m_ShowHiddenFields = GetRenderSettings()->m_ShowHiddenFields;
430 m_settings->m_ShowPinAltIcons = GetRenderSettings()->m_ShowPinAltIcons;
431
432 m_settings->m_LibWidth = m_treePane->GetSize().x;
433
434 m_settings->m_LibrarySortMode = GetLibTree()->GetSortMode();
435
436 m_settings->m_AuiPanels.properties_splitter = m_propertiesPanel->SplitterProportion();
437 bool prop_shown = m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
438 m_settings->m_AuiPanels.show_properties = prop_shown;
439
440 if( TOOL_MANAGER* toolMgr = GetToolManager() )
441 {
442 if( SCH_SELECTION_TOOL* selTool = toolMgr->GetTool<SCH_SELECTION_TOOL>() )
443 m_settings->m_SelectionFilter = selTool->GetFilter();
444 }
445
447}
448
449
454
455
457{
459
460 if( cfg && static_cast<SYMBOL_EDITOR_SETTINGS*>( cfg )->m_UseEeschemaColorSettings )
461 cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
462
463 return ::GetColorSettings( cfg ? cfg->m_ColorTheme : DEFAULT_THEME );
464}
465
466
468{
469 // Create the manager and dispatcher & route draw panel events to the dispatcher
471 m_toolManager->SetEnvironment( GetScreen(), GetCanvas()->GetView(), GetCanvas()->GetViewControls(), GetSettings(),
472 this );
473 m_actions = new SCH_ACTIONS();
475
476 // Register tools
477 m_toolManager->RegisterTool( new COMMON_CONTROL );
478 m_toolManager->RegisterTool( new COMMON_TOOLS );
479 m_toolManager->RegisterTool( new ZOOM_TOOL );
480 m_toolManager->RegisterTool( new SCH_SELECTION_TOOL );
481 m_toolManager->RegisterTool( new PICKER_TOOL );
482 m_toolManager->RegisterTool( new SCH_INSPECTION_TOOL );
483 m_toolManager->RegisterTool( new SYMBOL_EDITOR_PIN_TOOL );
484 m_toolManager->RegisterTool( new SYMBOL_EDITOR_DRAWING_TOOLS );
485 m_toolManager->RegisterTool( new EE_GRAPHIC_TOOL );
486 m_toolManager->RegisterTool( new SCH_POINT_EDITOR );
487 m_toolManager->RegisterTool( new SCH_FIND_REPLACE_TOOL );
488 m_toolManager->RegisterTool( new SYMBOL_EDITOR_MOVE_TOOL );
489 m_toolManager->RegisterTool( new SYMBOL_EDITOR_EDIT_TOOL );
490 m_toolManager->RegisterTool( new LIBRARY_EDITOR_CONTROL );
491 m_toolManager->RegisterTool( new SYMBOL_EDITOR_CONTROL );
492 m_toolManager->RegisterTool( new PROPERTIES_TOOL );
493 m_toolManager->RegisterTool( new EMBED_TOOL );
494 m_toolManager->InitTools();
495
496 // Run the selection tool, it is supposed to be always active
497 m_toolManager->InvokeTool( "common.InteractiveSelection" );
498
500}
501
502
504{
506
507 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
508 EDITOR_CONDITIONS cond( this );
509
510 wxASSERT( mgr );
511
512#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
513#define CHECK( x ) ACTION_CONDITIONS().Check( x )
514
515 auto haveSymbolCond =
516 [this]( const SELECTION& )
517 {
518 return m_symbol;
519 };
520
521 auto isGraphicallyEditableCond =
522 [this]( const SELECTION& )
523 {
525 };
526
527 auto isEditableInAliasCond =
528 [this]( const SELECTION& )
529 {
530 // Less restrictive than isGraphicallyEditableCond
531 // Symbols fields (root symbols and aliases) from the new s-expression libraries
532 // or in the schematic are editable.
533 return IsSymbolEditable();
534 };
535
536 auto canUpdateFieldsCond =
537 [this]( const SELECTION& )
538 {
539 return IsSymbolEditable() && m_symbol && m_symbol->CanUpdateFieldsFromParent();
540 };
541
542 auto symbolModifiedCondition =
543 [this]( const SELECTION& sel )
544 {
545 return m_libMgr && m_libMgr->IsSymbolModified( GetTargetLibId().GetLibItemName(),
546 GetTargetLibId().GetLibNickname() );
547 };
548
549 auto libSelectedCondition =
550 [this]( const SELECTION& sel )
551 {
552 return !GetTargetLibId().GetLibNickname().empty();
553 };
554
555 auto canEditProperties =
556 [this]( const SELECTION& sel )
557 {
559 };
560
561 auto symbolSelectedInTreeCondition =
562 [this]( const SELECTION& sel )
563 {
564 LIB_ID targetLibId = GetTargetLibId();
565 return !targetLibId.GetLibNickname().empty() && !targetLibId.GetLibItemName().empty();
566 };
567
568 auto saveSymbolAsCondition =
569 [this]( const SELECTION& aSel )
570 {
571 return getTargetSymbol() != nullptr;
572 };
573
574 const auto isSymbolFromSchematicCond =
575 [this]( const SELECTION& )
576 {
577 return IsSymbolFromSchematic();
578 };
579
580 // clang-format off
583 mgr->SetConditions( SCH_ACTIONS::saveLibraryAs, ENABLE( libSelectedCondition ) );
584 mgr->SetConditions( SCH_ACTIONS::saveSymbolAs, ENABLE( saveSymbolAsCondition ) );
585 mgr->SetConditions( SCH_ACTIONS::saveSymbolCopyAs, ENABLE( saveSymbolAsCondition ) );
588 mgr->SetConditions( SCH_ACTIONS::editLibSymbolWithLibEdit, ENABLE( isSymbolFromSchematicCond ) );
589
590 mgr->SetConditions( ACTIONS::undo, ENABLE( haveSymbolCond && cond.UndoAvailable() ) );
591 mgr->SetConditions( ACTIONS::redo, ENABLE( haveSymbolCond && cond.RedoAvailable() ) );
592 mgr->SetConditions( ACTIONS::revert, ENABLE( symbolModifiedCondition ) );
593
596
597 mgr->SetConditions( ACTIONS::cut, ENABLE( isGraphicallyEditableCond ) );
598 mgr->SetConditions( ACTIONS::copy, ENABLE( haveSymbolCond ) );
599 mgr->SetConditions( ACTIONS::copyAsText, ENABLE( haveSymbolCond ) );
600 mgr->SetConditions( ACTIONS::paste, ENABLE( isGraphicallyEditableCond && SELECTION_CONDITIONS::Idle && cond.NoActiveTool() ) );
601 mgr->SetConditions( ACTIONS::doDelete, ENABLE( isGraphicallyEditableCond ) );
602 mgr->SetConditions( ACTIONS::duplicate, ENABLE( isGraphicallyEditableCond ) );
603 mgr->SetConditions( ACTIONS::selectAll, ENABLE( haveSymbolCond ) );
604 mgr->SetConditions( ACTIONS::unselectAll, ENABLE( haveSymbolCond ) );
605
606 // These actions in symbol editor when editing alias field rotations are allowed.
608 .HotkeyEnable( isEditableInAliasCond ) );
610 .HotkeyEnable( isEditableInAliasCond ) );
611
612 mgr->SetConditions( SCH_ACTIONS::mirrorH, ENABLE( SELECTION_CONDITIONS::NotEmpty && isGraphicallyEditableCond )
613 .HotkeyEnable( isGraphicallyEditableCond ) );
614 mgr->SetConditions( SCH_ACTIONS::mirrorV, ENABLE( SELECTION_CONDITIONS::NotEmpty && isGraphicallyEditableCond )
615 .HotkeyEnable( isGraphicallyEditableCond ) );
616
619 // clang-format on
620
621 auto pinTypeCond =
622 [this]( const SELECTION& )
623 {
625 };
626
627 auto hiddenPinCond =
628 [this]( const SELECTION& )
629 {
631 };
632
633 auto hiddenFieldCond =
634 [this]( const SELECTION& )
635 {
637 };
638
639 auto showPinAltIconsCond =
640 [this]( const SELECTION& )
641 {
643 };
644
645 auto showLibraryTreeCond =
646 [this]( const SELECTION& )
647 {
648 return IsLibraryTreeShown();
649 };
650
651 auto propertiesCond =
652 [this] ( const SELECTION& )
653 {
654 return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
655 };
656
659 mgr->SetConditions( ACTIONS::showLibraryTree, CHECK( showLibraryTreeCond ) );
660 mgr->SetConditions( ACTIONS::showProperties, CHECK( propertiesCond ) );
661 mgr->SetConditions( SCH_ACTIONS::showHiddenPins, CHECK( hiddenPinCond ) );
662 mgr->SetConditions( SCH_ACTIONS::showHiddenFields, CHECK( hiddenFieldCond ) );
663 mgr->SetConditions( SCH_ACTIONS::togglePinAltIcons, CHECK( showPinAltIconsCond ) );
664
665 auto multiUnitModeCond =
666 [this]( const SELECTION& )
667 {
668 return m_symbol && m_symbol->IsMultiUnit() && !m_symbol->UnitsLocked();
669 };
670
671 auto multiBodyStyleModeCond =
672 [this]( const SELECTION& )
673 {
674 return m_symbol && m_symbol->IsMultiBodyStyle();
675 };
676
677 auto syncedPinsModeCond =
678 [this]( const SELECTION& )
679 {
680 return SynchronizePins();
681 };
682
683 auto haveDatasheetCond =
684 [this]( const SELECTION& )
685 {
686 return m_symbol && !m_symbol->GetDatasheetField().GetText().IsEmpty();
687 };
688
689 mgr->SetConditions( ACTIONS::showDatasheet, ENABLE( haveDatasheetCond ) );
690 mgr->SetConditions( SCH_ACTIONS::symbolProperties, ENABLE( symbolSelectedInTreeCondition || ( canEditProperties && haveSymbolCond ) ) );
691 mgr->SetConditions( SCH_ACTIONS::runERC, ENABLE( haveSymbolCond ) );
692 mgr->SetConditions( SCH_ACTIONS::pinTable, ENABLE( isGraphicallyEditableCond && haveSymbolCond ) );
693 mgr->SetConditions( SCH_ACTIONS::editSymbolPinMaps, ENABLE( isGraphicallyEditableCond && haveSymbolCond ) );
694 mgr->SetConditions( SCH_ACTIONS::updateSymbolFields, ENABLE( canUpdateFieldsCond ) );
695 mgr->SetConditions( SCH_ACTIONS::cycleBodyStyle, ENABLE( multiBodyStyleModeCond ) );
696
697 mgr->SetConditions( SCH_ACTIONS::toggleSyncedPinsMode, ACTION_CONDITIONS().Enable( multiUnitModeCond ).Check( syncedPinsModeCond ) );
698
699// Only enable a tool if the symbol is edtable
700#define EDIT_TOOL( tool ) ACTION_CONDITIONS().Enable( isGraphicallyEditableCond ).Check( cond.CurrentTool( tool ) )
701
716
717#undef CHECK
718#undef ENABLE
719#undef EDIT_TOOL
720}
721
722
724{
725 if( IsContentModified() )
726 {
727 wxString msg = _( "Save changes to '%s' before closing?" );
728
729 if( !HandleUnsavedChanges( this, wxString::Format( msg, m_reference ),
730 [&]() -> bool
731 {
732 SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
733 LIB_SYMBOL* symbol = GetCurSymbol();
734
735 if( schframe && symbol ) // Should be always the case
736 return schframe->SaveSymbolToSchematic( *symbol, m_schematicSymbolUUID );
737
738 return false;
739 } ) )
740 {
741 return false;
742 }
743 }
744
745 if( doClose )
746 SetCurSymbol( nullptr, false );
747
748 return true;
749}
750
751
752bool SYMBOL_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
753{
754 // Shutdown blocks must be determined and vetoed as early as possible, before any modal prompt.
755 // IsContentModified only sees the active tab, so also account for dirty inactive instance tabs.
757 && aEvent.GetId() == wxEVT_QUERY_END_SESSION
759 {
760 aEvent.Veto();
761 return false;
762 }
763
765 {
766 aEvent.Veto();
767 return false;
768 }
769
770 // Prompt for any dirty inactive instance (symbols from the schematic) tabs, which the active-tab
771 // checks above miss.
773 return false;
774
775 if( !saveAllLibraries( true ) )
776 return false;
777
778 // Save symbol tree column widths
779 m_libMgr->GetAdapter()->SaveSettings();
780
781 return true;
782}
783
784
786{
788
789 if( GetLibTree() )
791
792 delete m_toolManager;
793 m_toolManager = nullptr;
794
795 Destroy();
796}
797
798
800{
801 if( m_unitSelectBox )
802 {
803 if( m_unitSelectBox->GetCount() != 0 )
804 m_unitSelectBox->Clear();
805
806 if( !m_symbol || m_symbol->GetUnitCount() <= 1 )
807 {
808 m_unit = 1;
809 m_unitSelectBox->Append( wxEmptyString );
810 }
811 else
812 {
813 for( int i = 0; i < m_symbol->GetUnitCount(); i++ )
814 m_unitSelectBox->Append( m_symbol->GetUnitDisplayName( i + 1, true ) );
815 }
816
817 // Ensure the selected unit is compatible with the number of units of the current symbol:
818 if( m_symbol && m_symbol->GetUnitCount() < m_unit )
819 m_unit = 1;
820
821 m_unitSelectBox->SetSelection( ( m_unit > 0 ) ? m_unit - 1 : 0 );
822 }
823
825 {
826 if( m_bodyStyleSelectBox->GetCount() != 0 )
827 m_bodyStyleSelectBox->Clear();
828
829 if( !m_symbol || !m_symbol->IsMultiBodyStyle() )
830 {
831 m_bodyStyle = 1;
832 m_bodyStyleSelectBox->Append( wxEmptyString );
833 }
834 else if( m_symbol && m_symbol->HasDeMorganBodyStyles() )
835 {
836 m_bodyStyleSelectBox->Append( wxGetTranslation( DEMORGAN_STD ) );
837 m_bodyStyleSelectBox->Append( wxGetTranslation( DEMORGAN_ALT ) );
838 }
839 else
840 {
841 for( int i = 0; i < m_symbol->GetBodyStyleCount(); i++ )
842 m_bodyStyleSelectBox->Append( m_symbol->GetBodyStyleNames()[i] );
843 }
844
845 // Ensure the selected body style is compatible with the number of body styles of the current symbol:
846 if( m_symbol && m_symbol->GetBodyStyleCount() < m_bodyStyle )
847 m_bodyStyle = 1;
848
849 m_bodyStyleSelectBox->SetSelection( ( m_bodyStyle > 0 ) ? m_bodyStyle - 1 : 0 );
850 }
851}
852
853
855{
856 if( !m_propertiesPanel )
857 return;
858
859 bool show = !m_propertiesPanel->IsShownOnScreen();
860
861 wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
862 propertiesPaneInfo.Show( show );
864
865 if( show )
866 SetAuiPaneSize( m_auimgr, propertiesPaneInfo, m_settings->m_AuiPanels.properties_panel_width, -1 );
867 else
868 m_settings->m_AuiPanels.properties_panel_width = m_propertiesPanel->GetSize().x;
869
870 m_auimgr.Update();
871 Refresh();
872}
873
874
876{
877 // An explicit toggle makes the live visibility authoritative, so drop any pending restore that
878 // LoadSymbolFromSchematic's auto-hide left behind.
880
881 wxAuiPaneInfo& treePane = m_auimgr.GetPane( m_treePane );
882 treePane.Show( !IsLibraryTreeShown() );
884 m_auimgr.Update();
885 Refresh();
886}
887
888
890{
891 return const_cast<wxAuiManager&>( m_auimgr ).GetPane( m_treePane ).IsShown();
892}
893
894
899
900
902{
903 m_treePane->Freeze();
904 m_libMgr->GetAdapter()->Freeze();
905}
906
907
909{
910 m_libMgr->GetAdapter()->Thaw();
911 m_treePane->Thaw();
912}
913
914
915void SYMBOL_EDIT_FRAME::OnExitKiCad( wxCommandEvent& event )
916{
917 Kiway().OnKiCadExit();
918}
919
920
921void SYMBOL_EDIT_FRAME::OnUpdateUnitNumber( wxUpdateUIEvent& event )
922{
923 event.Enable( m_symbol && m_symbol->GetUnitCount() > 1 );
924}
925
926
927void SYMBOL_EDIT_FRAME::OnSelectUnit( wxCommandEvent& event )
928{
929 if( event.GetSelection() == wxNOT_FOUND )
930 return;
931
932 SetUnit( event.GetSelection() + 1 );
933}
934
935
936void SYMBOL_EDIT_FRAME::OnUpdateBodyStyle( wxUpdateUIEvent& event )
937{
938 event.Enable( m_symbol && m_symbol->GetBodyStyleCount() > 1 );
939}
940
941
942void SYMBOL_EDIT_FRAME::OnSelectBodyStyle( wxCommandEvent& event )
943{
944 if( event.GetSelection() == wxNOT_FOUND )
945 return;
946
947 SetBodyStyle( event.GetSelection() + 1 );
948}
949
950
952{
953 if( m_symbol )
954 {
956
957 if( std::optional<LIBRARY_TABLE_ROW*> row = adapter->GetRow( m_symbol->GetLibNickname() ); row.has_value() )
958 {
959 if( ( *row )->Type() == SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) )
960 return true;
961 }
962 }
963
964 return false;
965}
966
967
969{
970 // Use CallAfter so that we update the canvas before waiting for the infobar animation
971 CallAfter(
972 [this]()
973 {
974 WX_INFOBAR& infobar = *GetInfoBar();
975 infobar.RemoveAllButtons();
976
977 wxArrayString msgs;
978 int infobarFlags = wxICON_INFORMATION;
979 wxString symbolName;
980 wxString libName;
981
982 if( m_symbol )
983 {
984 symbolName = m_symbol->GetName();
985 libName = UnescapeString( m_symbol->GetLibId().GetLibNickname() );
986 }
987
989 {
990 msgs.push_back( wxString::Format( _( "Editing %s from schematic. Saving will update the "
991 "schematic only." ),
992 m_reference ) );
993
994 infobar.AddLink( wxString::Format( _( "Open symbol from library %s" ), UnescapeString( libName ) ),
995 [this]( wxHyperlinkEvent& aEvent )
996 {
998 } );
999 }
1000 else if( IsSymbolFromLegacyLibrary() )
1001 {
1002 msgs.push_back( _( "Symbols in legacy libraries are not editable. Use Manage Symbol "
1003 "Libraries to migrate to current format." ) );
1004
1005 infobar.AddLink( _( "Manage symbol libraries" ),
1006 [this]( wxHyperlinkEvent& aEvent )
1007 {
1009 } );
1010 }
1011 else if( IsSymbolAlias() )
1012 {
1013 msgs.push_back( wxString::Format( _( "Symbol %s is a derived symbol. Symbol graphics will "
1014 "not be editable." ),
1015 UnescapeString( symbolName ) ) );
1016
1017 // Don't assume the parent symbol shared pointer is still valid.
1018 if( std::shared_ptr<LIB_SYMBOL> rootSymbol = m_symbol->GetRootSymbol() )
1019 {
1020 int unit = GetUnit();
1021 int bodyStyle = GetBodyStyle();
1022 wxString rootSymbolName = rootSymbol->GetName();
1023
1024 infobar.AddLink( wxString::Format( _( "Open %s" ), UnescapeString( rootSymbolName ) ),
1025 [this, libName, rootSymbolName, unit, bodyStyle]( wxHyperlinkEvent& aEvent )
1026 {
1027 LoadSymbolFromLib( libName, rootSymbolName, unit, bodyStyle );
1028 } );
1029 }
1030 }
1031
1032 if( m_symbol
1034 && m_libMgr->IsLibraryReadOnly( m_symbol->GetLibId().GetFullLibraryName() ) )
1035 {
1036 msgs.push_back( _( "Library is read-only. Changes cannot be saved to this library." ) );
1037
1038 infobar.AddLink( _( "Create an editable copy" ),
1039 [this, libName]( wxHyperlinkEvent& aEvent )
1040 {
1041 wxString msg = wxString::Format( _( "Create an editable copy of the symbol or "
1042 "the entire library (%s)?" ),
1043 UnescapeString( libName ) );
1044
1045 KIDIALOG errorDlg( this, msg, _( "Select type of item to save" ),
1046 wxYES_NO | wxCANCEL | wxICON_QUESTION );
1047 // These buttons are in a weird order(?)
1048 errorDlg.SetYesNoCancelLabels( _( "Copy symbol" ), _( "Cancel" ), _( "Copy library" ) );
1049
1050 int choice = errorDlg.ShowModal();
1051
1052 switch( choice )
1053 {
1054 case wxID_YES: SaveSymbolCopyAs( true ); break;
1055 case wxID_CANCEL: SaveLibraryAs(); break;
1056 default: return;
1057 }
1058
1059 // Get rid of the save-will-update-schematic-only (or any other dismissable warning)
1060 WX_INFOBAR* local_infobar = GetInfoBar();
1061
1062 if( local_infobar->IsShownOnScreen() && local_infobar->HasCloseButton() )
1063 local_infobar->Dismiss();
1064
1066 } );
1067 }
1068
1069 if( msgs.empty() )
1070 {
1071 infobar.Dismiss();
1072 }
1073 else
1074 {
1075 wxString msg = wxJoin( msgs, '\n', '\0' );
1076 infobar.AddCloseButton();
1077 infobar.ShowMessage( msg, infobarFlags );
1078 }
1079 } );
1080}
1081
1082
1083void SYMBOL_EDIT_FRAME::SetCurSymbol( LIB_SYMBOL* aSymbol, bool aUpdateZoom )
1084{
1085 wxCHECK( m_toolManager, /* void */ );
1086
1088 GetCanvas()->GetView()->Clear();
1089
1090 // Install the replacement and refresh the active context before freeing the old symbol, so the
1091 // context never observes a freed pointer.
1092 LIB_SYMBOL* oldSymbol = m_symbol;
1093
1094 m_symbol = aSymbol;
1095
1096 if( m_activeTab )
1097 m_activeTab->RefreshFrameOwnedObjects( m_symbol, static_cast<SCH_SCREEN*>( GetScreen() ) );
1098
1099 delete oldSymbol;
1100
1101 // select the current symbol in the tree widget
1103 GetLibTree()->SelectLibId( m_symbol->GetLibId() );
1104 else
1105 GetLibTree()->Unselect();
1106
1108
1116
1117 if( aUpdateZoom )
1119
1120 GetCanvas()->Refresh();
1121 m_propertiesPanel->UpdateData();
1122 updateInfoBar();
1123}
1124
1125
1131
1132
1134{
1136
1138
1139 if( !IsSymbolFromSchematic() )
1140 {
1142 m_libMgr->UpdateSymbol( m_symbol, m_symbol->GetLibNickname() ); // UpdateSymbol() makes a copy
1143 }
1144
1145 if( m_isClosing )
1146 return;
1147
1148 // Clear preview so a later library-open gets its own tab instead of replacing this edited one.
1149 if( m_tabsPanel && m_activeTab )
1150 {
1151 m_activeTab->SetPreview( false );
1152
1153 if( int idx = m_tabsPanel->FindTab( m_activeTab->GetTabKey() ); idx >= 0 )
1154 m_tabsPanel->MarkModified( idx, true );
1155 }
1156
1158}
1159
1160
1162{
1163 wxCHECK( aUnit > 0 && aUnit <= GetCurSymbol()->GetUnitCount(), /* void*/ );
1164
1165 if( m_unit == aUnit )
1166 return;
1167
1170
1171 m_unit = aUnit;
1172
1173 if( m_unitSelectBox->GetSelection() != ( m_unit - 1 ) )
1174 m_unitSelectBox->SetSelection( m_unit - 1 );
1175
1177 RebuildView();
1179}
1180
1181
1183{
1184 wxCHECK( aBodyStyle > 0 && aBodyStyle <= GetCurSymbol()->GetBodyStyleCount(), /* void */ );
1185
1186 if( m_bodyStyle == aBodyStyle )
1187 return;
1188
1191
1192 m_bodyStyle = aBodyStyle;
1193
1194 if( m_bodyStyleSelectBox->GetSelection() != ( m_bodyStyle - 1 ) )
1195 m_bodyStyleSelectBox->SetSelection( m_bodyStyle - 1 );
1196
1197
1199 RebuildView();
1201}
1202
1203
1205{
1206 return m_settings && m_settings->m_SyncPinEdit && m_symbol && m_symbol->IsMultiUnit() && !m_symbol->UnitsLocked();
1207}
1208
1209
1210wxString SYMBOL_EDIT_FRAME::AddLibraryFile( bool aCreateNew )
1211{
1212 wxFileName fn = m_libMgr->GetUniqueLibraryName();
1213 bool useGlobalTable = true;
1214 FILEDLG_HOOK_NEW_LIBRARY tableChooser( useGlobalTable );
1215
1216 if( !LibraryFileBrowser( aCreateNew ? _( "New Symbol Library" ) : _( "Add Symbol Library" ),
1217 !aCreateNew, fn, FILEEXT::KiCadSymbolLibFileWildcard(),
1219 Pgm().GetSettingsManager().IsProjectOpenNotDummy() ? &tableChooser : nullptr ) )
1220 {
1221 return wxEmptyString;
1222 }
1223
1226
1227 LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
1228 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, scope );
1229
1230 wxCHECK( optTable.has_value(), wxEmptyString );
1231 LIBRARY_TABLE* table = optTable.value();
1232
1233 wxString libName = fn.GetName();
1234
1235 if( libName.IsEmpty() )
1236 return wxEmptyString;
1237
1239
1240 if( adapter->HasLibrary( libName ) )
1241 {
1242 DisplayError( this, wxString::Format( _( "Library '%s' already exists." ), libName ) );
1243 return wxEmptyString;
1244 }
1245
1246 if( aCreateNew )
1247 {
1248 // The file browser already asked to overwrite, so drop the old file here.
1249 // CreateLibrary fails on an existing path.
1250 if( fn.FileExists() && !wxRemoveFile( fn.GetFullPath() ) )
1251 {
1252 DisplayError( this, wxString::Format( _( "Could not overwrite the library file '%s'.\n"
1253 "Make sure you have write permissions and try again." ),
1254 fn.GetFullPath() ) );
1255 return wxEmptyString;
1256 }
1257
1258 if( !m_libMgr->CreateLibrary( fn.GetFullPath(), scope ) )
1259 {
1260 DisplayError( this, wxString::Format( _( "Could not create the library file '%s'.\n"
1261 "Make sure you have write permissions and try again." ),
1262 fn.GetFullPath() ) );
1263 return wxEmptyString;
1264 }
1265 }
1266 else
1267 {
1268 if( !m_libMgr->AddLibrary( fn.GetFullPath(), scope ) )
1269 {
1270 DisplayError( this, _( "Could not open the library file." ) );
1271 return wxEmptyString;
1272 }
1273 }
1274
1275 bool success = true;
1276
1277 // Tables are reinitialized by m_libMgr->AddLibrary(). So reinit table reference.
1278 optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, scope );
1279 wxCHECK( optTable.has_value(), wxEmptyString );
1280 table = optTable.value();
1281
1282 table->Save().map_error(
1283 [&]( const LIBRARY_ERROR& aError )
1284 {
1285 KICAD_MESSAGE_DIALOG dlg( this, _( "Error saving library table." ), _( "File Save Error" ),
1286 wxOK | wxICON_ERROR );
1287 dlg.SetExtendedMessage( aError.message );
1288 dlg.ShowModal();
1289
1290 success = false;
1291 } );
1292
1293 if( success )
1294 adapter->LoadOne( fn.GetName() );
1295
1296 SyncLibraries( false );
1297
1298 if( m_treePane )
1299 {
1300 LIB_ID libId( fn.GetName(), wxEmptyString );
1301 GetLibTree()->SelectLibId( libId );
1302 GetLibTree()->CenterLibId( libId );
1303 }
1304
1305 return fn.GetFullPath();
1306}
1307
1308
1309void SYMBOL_EDIT_FRAME::DdAddLibrary( wxString aLibFile )
1310{
1311 wxFileName fn = wxFileName( aLibFile );
1312 wxString libName = fn.GetName();
1313
1314 if( libName.IsEmpty() )
1315 return;
1316
1317 LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
1319
1320 if( adapter->HasLibrary( libName ) )
1321 {
1322 DisplayError( this, wxString::Format( _( "Library '%s' already exists." ), libName ) );
1323 return;
1324 }
1325
1326 if( !m_libMgr->AddLibrary( fn.GetFullPath(), LIBRARY_TABLE_SCOPE::PROJECT ) )
1327 {
1328 DisplayError( this, _( "Could not open the library file." ) );
1329 return;
1330 }
1331
1332 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, LIBRARY_TABLE_SCOPE::PROJECT );
1333 wxCHECK( optTable.has_value(), /* void */ );
1334 LIBRARY_TABLE* table = optTable.value();
1335 bool success = true;
1336
1337 table->Save().map_error(
1338 [&]( const LIBRARY_ERROR& aError )
1339 {
1340 KICAD_MESSAGE_DIALOG dlg( this, _( "Error saving library table." ), _( "File Save Error" ),
1341 wxOK | wxICON_ERROR );
1342 dlg.SetExtendedMessage( aError.message );
1343 dlg.ShowModal();
1344
1345 success = false;
1346 } );
1347
1348 if( success )
1349 adapter->LoadOne( libName );
1350
1351 std::string packet = fn.GetFullPath().ToStdString();
1354}
1355
1356
1358{
1359 return GetLibTree()->GetSelectedLibId( aUnit );
1360}
1361
1362
1367
1368int SYMBOL_EDIT_FRAME::GetTreeLIBIDs( std::vector<LIB_ID>& aSelection ) const
1369{
1370 return GetLibTree()->GetSelectedLibIds( aSelection );
1371}
1372
1373
1375{
1376 if( IsLibraryTreeShown() )
1377 {
1378 LIB_ID libId = GetTreeLIBID();
1379
1380 if( libId.IsValid() )
1381 return m_libMgr->GetSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
1382 }
1383
1384 return m_symbol;
1385}
1386
1387
1389{
1390 LIB_ID id;
1391
1392 if( IsLibraryTreeShown() )
1393 id = GetTreeLIBID();
1394
1395 if( id.GetLibNickname().empty() && m_symbol )
1396 id = m_symbol->GetLibId();
1397
1398 return id;
1399}
1400
1401
1402std::vector<LIB_ID> SYMBOL_EDIT_FRAME::GetSelectedLibIds() const
1403{
1404 std::vector<LIB_ID> ids;
1405 GetTreeLIBIDs( ids );
1406 return ids;
1407}
1408
1409
1411{
1412 return GetTargetLibId().GetLibNickname();
1413}
1414
1415
1416void SYMBOL_EDIT_FRAME::SyncLibraries( bool aShowProgress, bool aPreloadCancelled, const wxString& aForceRefresh )
1417{
1418 wxLogTrace( wxT( "KICAD_TABS_DBG" ),
1419 wxT( "SYMBOL_EDIT_FRAME::SyncLibraries enter (progress=%d, forceRefresh='%s')" ),
1420 aShowProgress, aForceRefresh );
1421
1422 // Prevent re-entrant calls. The progress dialog yields the event loop during Sync(),
1423 // which can dispatch queued UI events (e.g. menu clicks queued while the app was busy
1424 // loading libraries). A re-entrant call would corrupt the library tree mid-rebuild.
1426 {
1427 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "SYMBOL_EDIT_FRAME::SyncLibraries re-entrant; skipping" ) );
1428 return;
1429 }
1430
1432
1433 auto resetGuard =
1434 [this]( bool* )
1435 {
1437 };
1438
1439 std::unique_ptr<bool, decltype( resetGuard )> guard( &m_syncLibrariesInProgress, resetGuard );
1440
1441 LIB_ID selected;
1442 std::vector<LIB_ID> expanded;
1443
1444 if( m_treePane )
1445 {
1446 selected = GetLibTree()->GetSelectedLibId();
1447 expanded = GetLibTree()->GetExpandedLibraries();
1448 }
1449
1450 // Ensure any in-progress background library preloading is complete before syncing the
1451 // tree. Without this, libraries still in LOADING state get skipped by Sync(), resulting
1452 // in an incomplete tree that requires a manual refresh to fully populate.
1454 adapter->BlockUntilLoaded();
1455
1456 if( aShowProgress )
1457 {
1458 APP_PROGRESS_DIALOG progressDlg( _( "Loading Symbol Libraries" ), wxEmptyString,
1459 m_libMgr->GetAdapter()->GetLibrariesCount(), this );
1460
1461 THROTTLE progressThrottle( std::chrono::milliseconds( 350 ) );
1462 int pendingProgress = 0;
1463 bool callbackFired = false;
1464 wxString pendingLibName;
1465
1466 m_libMgr->Sync( aForceRefresh,
1467 [&]( int progress, int max, const wxString& libName )
1468 {
1469 pendingProgress = progress;
1470 pendingLibName = libName;
1471 callbackFired = true;
1472
1473 if( progressThrottle.Ready() )
1474 progressDlg.Update( progress, wxString::Format( _( "Loading library '%s'..." ), libName ) );
1475 } );
1476
1477 if( callbackFired )
1478 progressDlg.Update( pendingProgress, wxString::Format( _( "Loading library '%s'..." ), pendingLibName ) );
1479 }
1480 else if( !aPreloadCancelled )
1481 {
1482 m_libMgr->Sync( aForceRefresh, [&]( int progress, int max, const wxString& libName ) {} );
1483 }
1484
1485 if( m_treePane )
1486 {
1487 wxDataViewItem found;
1488
1489 if( selected.IsValid() )
1490 {
1491 // Check if the previously selected item is still valid,
1492 // if not - it has to be unselected to prevent crash
1493 found = m_libMgr->GetAdapter()->FindItem( selected );
1494
1495 if( !found )
1496 GetLibTree()->Unselect();
1497 }
1498
1499 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "SYMBOL_EDIT_FRAME::SyncLibraries Regenerate" ) );
1500 GetLibTree()->Regenerate( true );
1501
1502 // Sync() collapsed the tree, so re-expand the libraries that were open before it.
1503 for( const LIB_ID& libId : expanded )
1504 GetLibTree()->ExpandLibId( libId );
1505
1506 // Try to select the parent library, in case the symbol is not found
1507 if( !found && selected.IsValid() )
1508 {
1509 selected.SetLibItemName( "" );
1510 found = m_libMgr->GetAdapter()->FindItem( selected );
1511
1512 if( found )
1513 GetLibTree()->SelectLibId( selected );
1514 }
1515 }
1516
1517 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "SYMBOL_EDIT_FRAME::SyncLibraries exit" ) );
1518}
1519
1520
1525
1526
1528{
1529 GetLibTree()->SelectLibId( aLibID );
1530}
1531
1532
1533void SYMBOL_EDIT_FRAME::UpdateLibraryTree( const wxDataViewItem& aTreeItem, LIB_SYMBOL* aSymbol )
1534{
1535 if( aTreeItem.IsOk() ) // Can be not found in tree if the current footprint is imported
1536 // from file therefore not yet in tree.
1537 {
1538 static_cast<LIB_TREE_NODE_ITEM*>( aTreeItem.GetID() )->Update( aSymbol );
1540 }
1541}
1542
1543
1544bool SYMBOL_EDIT_FRAME::backupFile( const wxFileName& aOriginalFile, const wxString& aBackupExt )
1545{
1546 if( aOriginalFile.FileExists() )
1547 {
1548 wxFileName backupFileName( aOriginalFile );
1549 backupFileName.SetExt( aBackupExt );
1550
1551 if( backupFileName.FileExists() )
1552 wxRemoveFile( backupFileName.GetFullPath() );
1553
1554 if( !wxCopyFile( aOriginalFile.GetFullPath(), backupFileName.GetFullPath() ) )
1555 {
1556 DisplayError( this, wxString::Format( _( "Failed to save backup to '%s'." ),
1557 backupFileName.GetFullPath() ) );
1558 return false;
1559 }
1560 }
1561
1562 return true;
1563}
1564
1565
1567{
1568 // This will return the root symbol of any alias
1569 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aLibId.GetLibItemName(), aLibId.GetLibNickname() );
1570
1571 // Now we can compare the libId of the current symbol and the root symbol
1572 return ( symbol && m_symbol && symbol->GetLibId() == m_symbol->GetLibId() );
1573}
1574
1575
1577{
1578 GetLibTree()->Unselect();
1579
1580 // Tear down every tab first so no context observes the about-to-be-deleted working symbol.
1582
1583 SetCurSymbol( nullptr, false );
1587 Refresh();
1588}
1589
1590
1592{
1594
1596 {
1597 GetRenderSettings()->m_ShowPinsElectricalType = cfg->m_ShowPinElectricalType;
1598 GetRenderSettings()->m_ShowHiddenPins = cfg->m_ShowHiddenPins;
1599 GetRenderSettings()->m_ShowHiddenFields = cfg->m_ShowHiddenFields;
1600 GetRenderSettings()->m_ShowPinAltIcons = cfg->m_ShowPinAltIcons;
1601
1602 GetGalDisplayOptions().ReadWindowSettings( cfg->m_Window );
1603 }
1604
1605 if( m_symbol )
1606 m_symbol->ClearCaches();
1607
1609
1611 GetCanvas()->Refresh();
1612
1614
1615 if( aFlags & ENVVARS_CHANGED )
1616 SyncLibraries( true );
1617
1618 Layout();
1619 SendSizeEvent();
1620}
1621
1622
1624{
1625 // call my base class
1627
1628 // tooltips in toolbars
1630
1631 // For some obscure reason, the AUI manager hides the first modified pane.
1632 // So force show panes
1633 wxAuiPaneInfo& tree_pane_info = m_auimgr.GetPane( m_treePane );
1634 bool tree_shown = tree_pane_info.IsShown();
1635 tree_pane_info.Caption( _( "Libraries" ) );
1636 tree_pane_info.Show( tree_shown );
1637 m_auimgr.Update();
1638
1640
1641 // status bar
1643
1644 if( GetRenderSettings()->m_ShowPinsElectricalType )
1645 {
1647 GetCanvas()->Refresh();
1648 }
1649
1650 UpdateTitle();
1651}
1652
1653
1655{
1656 SCH_BASE_FRAME::SetScreen( aScreen );
1657
1658 if( m_toolManager )
1659 {
1660 m_toolManager->SetEnvironment( aScreen, GetCanvas()->GetView(), GetCanvas()->GetViewControls(), GetSettings(),
1661 this );
1663 }
1664}
1665
1666
1684
1685
1687{
1688 SyncLibraries( true );
1689
1690 if( m_symbol )
1691 {
1692 SCH_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<SCH_SELECTION_TOOL>();
1693 SCH_SELECTION& selection = selectionTool->GetSelection();
1694
1695 for( SCH_ITEM& item : m_symbol->GetDrawItems() )
1696 {
1697 if( !alg::contains( selection, &item ) )
1698 item.ClearSelected();
1699 else
1700 item.SetSelected();
1701 }
1702
1703 m_symbol->ClearCaches();
1704 }
1705
1706 RebuildView();
1707}
1708
1709
1710const BOX2I SYMBOL_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
1711{
1712 if( !m_symbol )
1713 {
1714 // Gives a reasonable drawing area size
1715 int width = schIUScale.mmToIU( 50 );
1716 int height = schIUScale.mmToIU( 30 );
1717
1718 return BOX2I( VECTOR2I( -width/2, -height/2 ), VECTOR2I( width, height ) );
1719 }
1720 else
1721 {
1722 return m_symbol->Flatten()->GetUnitBoundingBox( m_unit, m_bodyStyle );
1723 }
1724}
1725
1726
1727void SYMBOL_EDIT_FRAME::FocusOnItem( EDA_ITEM* aItem, bool aAllowScroll )
1728{
1729 static KIID lastBrightenedItemID( niluuid );
1730
1731 SCH_ITEM* lastItem = nullptr;
1732
1733 // nullptr will clear the current focus
1734 if( aItem != nullptr && !aItem->IsSCH_ITEM() )
1735 return;
1736
1737 if( m_symbol )
1738 {
1739 for( SCH_PIN* pin : m_symbol->GetGraphicalPins( 0, 0 ) )
1740 {
1741 if( pin->m_Uuid == lastBrightenedItemID )
1742 lastItem = pin;
1743 }
1744
1745 std::vector<SCH_FIELD*> fields;
1746 m_symbol->GetFields( fields );
1747
1748 for( SCH_FIELD* field : fields )
1749 {
1750 if( field->m_Uuid == lastBrightenedItemID )
1751 lastItem = field;
1752 }
1753 }
1754
1755 if( lastItem && lastItem != aItem )
1756 {
1757 lastItem->ClearBrightened();
1758
1759 UpdateItem( lastItem );
1760 lastBrightenedItemID = niluuid;
1761 }
1762
1763 if( aItem )
1764 {
1765 if( aItem->IsSCH_ITEM() )
1766 {
1767 SCH_ITEM* item = static_cast<SCH_ITEM*>( aItem );
1768
1769 if( int unit = item->GetUnit() )
1770 SetUnit( unit );
1771
1772 if( int bodyStyle = item->GetBodyStyle() )
1773 SetBodyStyle( bodyStyle );
1774 }
1775
1776 if( !aItem->IsBrightened() )
1777 {
1778 aItem->SetBrightened();
1779
1780 UpdateItem( aItem );
1781 lastBrightenedItemID = aItem->m_Uuid;
1782 }
1783
1784 FocusOnLocation( VECTOR2I( aItem->GetFocusPosition().x, aItem->GetFocusPosition().y ), aAllowScroll );
1785 }
1786}
1787
1788
1790{
1791 const std::string& payload = mail.GetPayload();
1792
1793 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "SYMBOL_EDIT_FRAME::KiwayMailIn cmd=%d" ), (int) mail.Command() );
1794
1795 switch( mail.Command() )
1796 {
1797 case MAIL_LIB_EDIT:
1798 if( !payload.empty() )
1799 {
1800 wxString uri( payload );
1801 wxString libNickname;
1802 wxString msg;
1803
1805 std::optional<const LIBRARY_TABLE_ROW*> libTableRow = adapter->FindRowByURI( uri );
1806
1807 if( !libTableRow )
1808 {
1809 msg.Printf( _( "The current configuration does not include the symbol library '%s'." ),
1810 uri );
1811 msg += wxS( "\n" ) + _( "Use Manage Symbol Libraries to edit the configuration." );
1812 DisplayErrorMessage( this, _( "Library not found in symbol library table." ), msg );
1813 break;
1814 }
1815
1816 libNickname = ( *libTableRow )->Nickname();
1817
1818 if( !adapter->HasLibrary( libNickname, true ) )
1819 {
1820 msg.Printf( _( "The symbol library '%s' is not enabled in the current configuration." ),
1821 UnescapeString( libNickname ) );
1822 msg += wxS( "\n" ) + _( "Use Manage Symbol Libraries to edit the configuration." );
1823 DisplayErrorMessage( this, _( "Symbol library not enabled." ), msg );
1824 break;
1825 }
1826
1827 if( m_treePane )
1828 {
1829 LIB_ID id( libNickname, wxEmptyString );
1830 GetLibTree()->SelectLibId( id );
1831 GetLibTree()->ExpandLibId( id );
1832 GetLibTree()->CenterLibId( id );
1833 }
1834 }
1835
1836 break;
1837
1838 case MAIL_RELOAD_LIB:
1839 {
1840 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "SYMBOL_EDIT_FRAME::KiwayMailIn MAIL_RELOAD_LIB -> SyncLibraries" ) );
1841
1843
1844 // Suppress the progress dialog for this background reload. It would steal focus from the
1845 // editor that broadcast the reload, and the tree is already frozen around the sync.
1846 SyncLibraries( false );
1849
1850 break;
1851 }
1852
1854 {
1856 LIB_SYMBOL* symbol = GetCurSymbol();
1857
1858 wxLogTrace( traceLibWatch, "Received refresh symbol request for %s", payload );
1859
1860 if( !symbol )
1861 break;
1862
1863 // Capture the name now. UpdateLibraryBuffer() recreates the buffer, so reading it from the
1864 // buffer copy afterwards would be a use-after-free.
1865 const wxString refreshSymbolName = symbol->GetName();
1866
1867 // A modal dialog may be registered before wxGTK disables the frame. Refreshing the
1868 // symbol in either state would delete the LIB_SYMBOL being edited by the dialog.
1869 if( !IsEnabled() || Kiway().HasBlockingDialog() )
1870 {
1871 wxLogTrace( traceLibWatch, "Deferring symbol refresh; dialog is open on the symbol editor." );
1872 break;
1873 }
1874 // Defensive backstop for refresh mail that did not originate from this frame's debounce
1875 // timer (which already defers while a tool is active). An interactive tool holds
1876 // references into the current symbol, so replacing it here would crash; drop this refresh
1877 // and let the originating watcher retry.
1878 else if( !ToolStackIsEmpty() )
1879 {
1880 wxLogTrace( traceLibWatch, "Deferring symbol refresh; an interactive tool is active." );
1881 break;
1882 }
1883
1884 wxString libName = symbol->GetLibId().GetLibNickname();
1885 std::optional<const LIBRARY_TABLE_ROW*> row = adapter->GetRow( libName );
1886
1887 if( !row )
1888 return;
1889
1890 wxFileName libfullname( LIBRARY_MANAGER::GetFullURI( *row, true ) );
1891
1892 wxFileName changedLib( mail.GetPayload() );
1893
1894 wxLogTrace( traceLibWatch, "Received refresh symbol request for %s, current symbols is %s",
1895 changedLib.GetFullPath(), libfullname.GetFullPath() );
1896
1897 if( changedLib == libfullname )
1898 {
1899 wxLogTrace( traceLibWatch, "Refreshing symbol %s", refreshSymbolName );
1900
1901 m_libMgr->UpdateLibraryBuffer( libName );
1902
1903 if( LIB_SYMBOL* lib_symbol = m_libMgr->GetBufferedSymbol( refreshSymbolName, libName ) )
1904 {
1905 SetCurSymbol( new LIB_SYMBOL( *lib_symbol ), false );
1907
1908 if( m_toolManager )
1910 }
1911 }
1912
1913 break;
1914 }
1915
1916 default:
1917 break;
1918 }
1919}
1920
1921
1922std::unique_ptr<GRID_HELPER> SYMBOL_EDIT_FRAME::MakeGridHelper()
1923{
1924 return std::make_unique<EE_GRID_HELPER>( m_toolManager );
1925}
1926
1927
1929{
1930 // switches currently used canvas ( Cairo / OpenGL):
1931 SCH_BASE_FRAME::SwitchCanvas( aCanvasType );
1932
1933 // Set options specific to symbol editor (axies are always enabled):
1934 GetCanvas()->GetGAL()->SetAxesEnabled( true );
1936}
1937
1938
1940{
1941 wxCHECK( m_libMgr, false );
1942
1943 return m_libMgr->HasModifications();
1944}
1945
1946
1948{
1949 wxCHECK( m_libMgr, false );
1950
1951 // Test if the currently edited symbol is modified
1953 return true;
1954
1955 // Test if any library has been modified
1956 for( const wxString& libName : m_libMgr->GetLibraryNames() )
1957 {
1958 if( m_libMgr->IsLibraryModified( libName ) && !m_libMgr->IsLibraryReadOnly( libName ) )
1959 return true;
1960 }
1961
1962 return false;
1963}
1964
1965
1967{
1968 if( aItemCount == 0 )
1969 return;
1970
1971 UNDO_REDO_CONTAINER& list = ( whichList == UNDO_LIST ) ? m_undoList : m_redoList;
1972
1973 // UR_TRANSIENT is flagged on the picked item, not the wrapper, so the shared deleters miss it.
1974 // Free the items carrying UR_TRANSIENT. m_symbol never carries it, so the live copy is safe.
1975 if( aItemCount < 0 )
1976 {
1978 }
1979 else
1980 {
1981 for( int ii = 0; ii < aItemCount; ii++ )
1982 {
1983 if( list.m_CommandsList.size() == 0 )
1984 break;
1985
1986 PICKED_ITEMS_LIST* curr_cmd = list.m_CommandsList[0];
1987 list.m_CommandsList.erase( list.m_CommandsList.begin() );
1988
1989 for( unsigned jj = 0; jj < curr_cmd->GetCount(); ++jj )
1990 {
1991 EDA_ITEM* item = curr_cmd->GetPickedItem( jj );
1992
1993 if( item && item->HasFlag( UR_TRANSIENT ) && item != m_symbol )
1994 delete item;
1995 }
1996
1997 curr_cmd->ClearItemsList();
1998 delete curr_cmd; // Delete command
1999 }
2000 }
2001}
2002
2003
2005{
2006 return m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
2007}
2008
2009
2011 bool aRestorePending, bool aTreeShownNow )
2012{
2013 // Auto-hiding a visible tree schedules its restore. A chained schematic edit finds the tree
2014 // already auto-hidden, so keep the pending restore rather than dropping it. An explicit user
2015 // toggle clears the flag elsewhere, so a tree hidden without a pending restore stays that way.
2016 if( aTreeShownNow )
2017 return true;
2018
2019 return aWasFromSchematic && aRestorePending;
2020}
2021
2022
2024{
2025 std::unique_ptr<LIB_SYMBOL> symbol = aSymbol->GetLibSymbolRef()->Flatten();
2026 wxCHECK( symbol, /* void */ );
2027
2028 symbol->SetLibId( aSymbol->GetLibId() );
2029
2030 // Take in account the symbol orientation and mirroring. to calculate the field
2031 // positions in symbol editor (i.e. no rotation, no mirroring)
2032 int orientation = aSymbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y );
2033 int mirror = aSymbol->GetOrientation() & ( SYM_MIRROR_X | SYM_MIRROR_Y );
2034
2035 std::vector<SCH_FIELD> fullSetOfFields;
2036
2037 for( const SCH_FIELD& field : aSymbol->GetFields() )
2038 {
2039 VECTOR2I pos = field.GetPosition() - aSymbol->GetPosition();
2040 SCH_FIELD libField( symbol.get(), field.GetId() );
2041
2042 libField = field;
2043
2044 // The inverse transform is mirroring before, rotate after
2045 switch( mirror )
2046 {
2047 case SYM_MIRROR_X: pos.y = -pos.y; break;
2048 case SYM_MIRROR_Y: pos.x = -pos.x; break;
2049 default: break;
2050 }
2051
2052 switch( orientation )
2053 {
2054 case SYM_ORIENT_90:
2055 std::swap( pos.x, pos.y );
2056 pos.x = - pos.x;
2057 break;
2058 case SYM_ORIENT_270:
2059 std::swap( pos.x, pos.y );
2060 pos.y = - pos.y;
2061 break;
2062 case SYM_ORIENT_180:
2063 pos.x = - pos.x;
2064 pos.y = - pos.y;
2065 break;
2066 default:
2067 break;
2068 }
2069
2070 libField.SetPosition( pos );
2071
2072 fullSetOfFields.emplace_back( std::move( libField ) );
2073 }
2074
2075 symbol->SetFields( fullSetOfFields );
2076
2077 const wxString reference = symbol->GetReferenceField().GetText();
2078 const int unit = std::max( 1, aSymbol->GetUnit() );
2079 const int bodyStyle = std::max( 1, aSymbol->GetBodyStyle() );
2080
2081 // Optimize default edit options for this symbol
2082 // Usually if units are locked, graphic items are specific to each unit
2083 // and if units are interchangeable, graphic items are common to units
2084 SetDrawSpecificUnit( symbol->UnitsLocked() );
2085
2086 // Hand the transient working symbol/screen to a session-only instance tab, whose activation
2087 // restores the frame's schematic-source state so the save path routes back to the schematic.
2088 SCH_SCREEN* tmpScreen = new SCH_SCREEN();
2089
2090 setSymWatcher( nullptr );
2091
2092 SYMBOL_EDITOR_TAB_CONTEXT* ctx = findOrCreateSymbolInstanceTab( symbol.release(), tmpScreen,
2093 aSymbol->m_Uuid, reference, unit,
2094 bodyStyle );
2095 wxCHECK( ctx, /* void */ );
2096
2099
2100 // Auto-hide the tree while editing a schematic symbol, remembering to restore it in SaveSettings
2101 // so the user's preference survives a restart. Hide via the pane directly, not ToggleLibraryTree,
2102 // which would treat this as a user toggle and drop the pending restore.
2105
2106 if( IsLibraryTreeShown() )
2107 {
2108 m_auimgr.GetPane( m_treePane ).Show( false );
2110 m_auimgr.Update();
2111 Refresh();
2112 }
2113
2116 updateInfoBar();
2117
2118 // Let tools add things to the view if necessary
2119 if( m_toolManager )
2121
2123 GetCanvas()->Refresh();
2124}
2125
2126
2127bool SYMBOL_EDIT_FRAME::addLibTableEntry( const wxString& aLibFile, LIBRARY_TABLE_SCOPE aScope )
2128{
2129 wxFileName fn = aLibFile;
2130 wxFileName libTableFileName( Prj().GetProjectPath(), FILEEXT::SymbolLibraryTableFileName );
2131 wxString libNickname = fn.GetName();
2133 LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
2134 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
2135
2136 if( adapter->HasLibrary( libNickname ) )
2137 {
2138 wxString tmp;
2139 int suffix = 1;
2140
2141 while( adapter->HasLibrary( libNickname ) )
2142 {
2143 tmp.Printf( "%s%d", fn.GetName(), suffix );
2144 libNickname = tmp;
2145 suffix += 1;
2146 }
2147 }
2148
2149 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, aScope );
2150 wxCHECK( optTable.has_value(), false );
2151 LIBRARY_TABLE* table = optTable.value();
2152
2153 LIBRARY_TABLE_ROW* row = &table->InsertRow();
2154
2155 row->SetNickname( libNickname );
2156
2157 // We cannot normalize against the current project path when saving to global table.
2158 wxString normalizedPath = NormalizePath( aLibFile, &envVars,
2159 aScope == LIBRARY_TABLE_SCOPE::PROJECT ? Prj().GetProjectPath()
2160 : wxString( wxEmptyString ) );
2161
2162 row->SetURI( normalizedPath );
2164
2165 bool success = true;
2166
2167 table->Save().map_error(
2168 [&]( const LIBRARY_ERROR& aError )
2169 {
2170 KICAD_MESSAGE_DIALOG dlg( this, _( "Error saving library table." ), _( "File Save Error" ),
2171 wxOK | wxICON_ERROR );
2172 dlg.SetExtendedMessage( aError.message );
2173 dlg.ShowModal();
2174
2175 success = false;
2176 } );
2177
2178 if( success )
2179 {
2180 manager.ReloadTables( aScope, { LIBRARY_TABLE_TYPE::SYMBOL } );
2181 adapter->LoadOne( libNickname );
2182 }
2183
2184 return success;
2185}
2186
2187
2188bool SYMBOL_EDIT_FRAME::replaceLibTableEntry( const wxString& aLibNickname, const wxString& aLibFile )
2189{
2191 LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
2192 LIBRARY_TABLE* table = nullptr;
2194
2195 // Check the global library table first because checking the project library table
2196 // checks the global library table as well due to library chaining.
2197 if( adapter->GetRow( aLibNickname, scope ) )
2198 {
2199 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, scope );
2200 wxCHECK( optTable.has_value(), false );
2201 table = optTable.value();
2202 }
2203 else
2204 {
2206
2207 if( adapter->GetRow( aLibNickname, scope ) )
2208 {
2209 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, scope );
2210
2211 if( optTable.has_value() )
2212 table = optTable.value();
2213 }
2214 }
2215
2216 wxCHECK( table, false );
2217
2218 std::optional<LIBRARY_TABLE_ROW*> optRow = adapter->GetRow( aLibNickname, scope );
2219 wxCHECK( optRow.has_value(), false );
2220 LIBRARY_TABLE_ROW* row = optRow.value();
2221
2222 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
2223
2224 wxString projectPath;
2225
2226 if( scope == LIBRARY_TABLE_SCOPE::PROJECT )
2227 projectPath = Prj().GetProjectPath();
2228
2229 wxString normalizedPath = NormalizePath( aLibFile, &envVars, projectPath );
2230
2231 row->SetURI( normalizedPath );
2232 row->SetType( "KiCad" );
2233
2234 bool success = true;
2235
2236 table->Save().map_error(
2237 [&]( const LIBRARY_ERROR& aError )
2238 {
2239 KICAD_MESSAGE_DIALOG dlg( this, _( "Error saving library table." ), _( "File Save Error" ),
2240 wxOK | wxICON_ERROR );
2241 dlg.SetExtendedMessage( aError.message );
2242 dlg.ShowModal();
2243
2244 success = false;
2245 } );
2246
2247 if( success )
2248 {
2249 manager.ReloadTables( scope, { LIBRARY_TABLE_TYPE::SYMBOL } );
2250 adapter->LoadOne( aLibNickname );
2251 }
2252
2253 return success;
2254}
2255
2256
2258{
2259 return m_symbol && !m_symbol->IsRoot();
2260}
2261
2262
2267
2268
2270{
2271 // Cannot edit graphics of symbols from legacy libraries, or of symbol aliases
2272 // unless the symbol is from a schematic (in which case it is a working copy of the symbol).
2274}
2275
2276
2277void SYMBOL_EDIT_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete, bool aUpdateRtree )
2278{
2279 SCH_BASE_FRAME::UpdateItem( aItem, isAddOrDelete, aUpdateRtree );
2280
2281 if( EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( aItem ) )
2282 {
2283 eda_text->ClearBoundingBoxCache();
2284 eda_text->ClearRenderCache();
2285 }
2286}
2287
2288
2290{
2291 wxAuiPaneInfo& treePane = m_auimgr.GetPane( m_treePane );
2292 wxAuiPaneInfo& propertiesPane = m_auimgr.GetPane( PropertiesPaneName() );
2293 wxAuiPaneInfo& selectionFilterPane = m_auimgr.GetPane( wxS( "SelectionFilter" ) );
2294
2295 // Don't give the selection filter its own visibility controls; instead show it if
2296 // anything else is visible
2297 bool showFilter = ( treePane.IsShown() && treePane.IsDocked() )
2298 || ( propertiesPane.IsShown() && propertiesPane.IsDocked() );
2299
2300 selectionFilterPane.Show( showFilter );
2301}
2302
2303
2305{
2306 // Returns the current render option for invisible fields
2308}
2309
2310
2312{
2313 // Returns the current render option for invisible pins
2315}
BASE_SCREEN class implementation.
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition bitmap.cpp:100
@ icon_libedit_32
@ icon_libedit_16
BOX2< VECTOR2I > BOX2I
Definition box2.h:927
BOX2< VECTOR2D > BOX2D
Definition box2.h:928
static TOOL_ACTION toggleGrid
Definition actions.h:194
static TOOL_ACTION paste
Definition actions.h:76
static TOOL_ACTION cancelInteractive
Definition actions.h:68
static TOOL_ACTION unselectAll
Definition actions.h:79
static TOOL_ACTION revert
Definition actions.h:58
static TOOL_ACTION showLibraryTree
Definition actions.h:160
static TOOL_ACTION copy
Definition actions.h:74
static TOOL_ACTION showDatasheet
Definition actions.h:263
static TOOL_ACTION toggleBoundingBoxes
Definition actions.h:153
static TOOL_ACTION saveAll
Definition actions.h:57
static TOOL_ACTION undo
Definition actions.h:71
static TOOL_ACTION duplicate
Definition actions.h:80
static TOOL_ACTION doDelete
Definition actions.h:81
static TOOL_ACTION selectionTool
Definition actions.h:247
static TOOL_ACTION save
Definition actions.h:54
static TOOL_ACTION zoomFitScreen
Definition actions.h:138
static TOOL_ACTION redo
Definition actions.h:72
static TOOL_ACTION deleteTool
Definition actions.h:82
static TOOL_ACTION zoomTool
Definition actions.h:142
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:220
static TOOL_ACTION showProperties
Definition actions.h:262
static TOOL_ACTION cut
Definition actions.h:73
static TOOL_ACTION ddAddLibrary
Definition actions.h:63
static TOOL_ACTION copyAsText
Definition actions.h:75
static TOOL_ACTION toggleGridOverrides
Definition actions.h:195
static TOOL_ACTION selectAll
Definition actions.h:78
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...
wxProgressDialog with the option to also update the application progress on the taskbar
virtual bool Update(int aValue, const wxString &aNewMsg=wxEmptyString, bool *aSkip=nullptr) override
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
wxString m_ColorTheme
Active color theme name.
Handles how to draw a screen (a board, a schematic ...)
Definition base_screen.h:37
void SetContentModified(bool aModified=true)
Definition base_screen.h:55
constexpr void SetOrigin(const Vec &pos)
Definition box2.h:234
constexpr void SetSize(const SizeVec &size)
Definition box2.h:245
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.
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 ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
SETTINGS_MANAGER * GetSettingsManager() const
UNDO_REDO_LIST
Specify whether we are interacting with the undo or redo stacks.
virtual void OnModify()
Must be called after a model change in order to set the "modify" flag and do other frame-specific pro...
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 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()
COLOR_SETTINGS * m_colorSettings
void OnSelectGrid(wxCommandEvent &event)
Command event handler for selecting grid sizes.
void setupUnits(APP_SETTINGS_BASE *aCfg)
virtual void SwitchCanvas(EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType)
Change the current rendering backend.
virtual void OnSelectZoom(wxCommandEvent &event)
Set the zoom factor when selected by the zoom list box in the main tool bar.
GAL_DISPLAY_OPTIONS_IMPL & GetGalDisplayOptions()
Return a reference to the gal rendering options used by GAL for rendering.
virtual void resolveCanvasType()
Determine the canvas type to load (with prompt if required) and initializes m_canvasType.
static const wxString PropertiesPaneName()
EDA_MSG_PANEL * m_messagePanel
virtual void SetScreen(BASE_SCREEN *aScreen)
bool LibraryFileBrowser(const wxString &aTitle, bool doOpen, wxFileName &aFilename, const wxString &wildcard, const wxString &ext, bool isDirectory, FILEDLG_HOOK_NEW_LIBRARY *aFileDlgHook=nullptr)
void FocusOnLocation(const VECTOR2I &aPos, bool aAllowScroll=true)
Useful to focus on a particular location, in find functions.
PROPERTIES_PANEL * m_propertiesPanel
void ForceRefresh()
Force a redraw.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
KIGFX::GAL * GetGAL() const
Return a pointer to the GAL instance used in the panel.
void SetEventDispatcher(TOOL_DISPATCHER *aEventDispatcher)
Set a dispatcher that processes events and forwards them to tools.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
virtual const VECTOR2I GetFocusPosition() const
Similar to GetPosition() but allows items to return their visual center rather than their anchor.
Definition eda_item.h:355
const KIID m_Uuid
Definition eda_item.h:597
void ClearBrightened()
Definition eda_item.h:154
void SetBrightened()
Definition eda_item.h:151
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition eda_item.h:168
bool IsBrightened() const
Definition eda_item.h:136
Specialization of the wxAuiPaneInfo class for KiCad panels.
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
Class that groups generic conditions for editor states.
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 GridOverrides()
Create a functor testing if the grid overrides wires is enabled in a frame.
The tab strip plus the single shared GAL canvas.
Tool responsible for drawing graphical shapes (rectangles, circles, arcs, beziers,...
void ReadWindowSettings(WINDOW_SETTINGS &aCfg)
Read GAL config options from application-level config.
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition kidialog.h:38
int ShowModal() override
Definition kidialog.cpp:89
bool m_axesEnabled
Crosshair drawing mode.
void SetAxesEnabled(bool aAxesEnabled)
Enable drawing the axes.
void SetAxesColor(const COLOR4D &aAxesColor)
Set the axes color.
void SetDefaultFont(const wxString &aFont)
void HideDrawingSheet()
Definition sch_view.cpp:306
void ClearHiddenFlags()
Clear the hide flag of all items in the view.
Definition sch_view.cpp:294
bool IsSCH_ITEM() const
Definition view_item.h:97
void Clear()
Remove all items from the view.
Definition view.cpp:1234
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:1703
Definition kiid.h:46
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition kiway_mail.h:34
std::string & GetPayload()
Return the payload, which can be any text but it typically self identifying s-expression.
Definition kiway_mail.h:52
MAIL_T Command()
Returns the MAIL_T associated with this mail.
Definition kiway_mail.h:44
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:340
void OnKiCadExit()
Definition kiway.cpp:790
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:388
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
Definition kiway.cpp:486
Module editor specific tools.
std::optional< LIBRARY_TABLE_ROW * > FindRowByURI(const wxString &aUri, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::FindRowByURI but filtered to the LIBRARY_TABLE_TYPE of this adapter.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library tables.
std::optional< LIBRARY_TABLE_ROW * > GetRow(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::GetRow but filtered to the LIBRARY_TABLE_TYPE of this adapter.
void ReloadTables(LIBRARY_TABLE_SCOPE aScope, std::initializer_list< LIBRARY_TABLE_TYPE > aTablesToLoad={})
std::optional< LIBRARY_TABLE * > Table(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope)
Retrieves a given table; creating a new empty project table if a valid project is loaded and the give...
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false)
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
void SetNickname(const wxString &aNickname)
void SetType(const wxString &aType)
void SetURI(const wxString &aUri)
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition lib_id.cpp:124
bool IsValid() const
Check if this LID_ID is valid.
Definition lib_id.h:168
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:83
Symbol library management helper that is specific to the symbol library editor frame.
Define a library symbol object.
Definition lib_symbol.h:119
const LIB_ID & GetLibId() const override
Definition lib_symbol.h:188
wxString GetName() const override
Definition lib_symbol.h:181
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Node type: LIB_ID.
void Update(LIB_TREE_ITEM *aItem)
Update the node using data from a LIB_ALIAS object.
void RefreshLibTree()
Refresh the tree (mainly to update highlighting and asterisking)
Definition lib_tree.cpp:493
void CenterLibId(const LIB_ID &aLibId)
Ensure that an item is visible (preferably centered).
Definition lib_tree.cpp:383
int GetSelectionCount() const
Definition lib_tree.h:88
void ShutdownPreviews()
Definition lib_tree.cpp:283
void ShowChangedLanguage()
Definition lib_tree.cpp:300
void FocusSearchFieldIfExists()
Focus the search widget if it exists.
Definition lib_tree.cpp:508
std::vector< LIB_ID > GetExpandedLibraries() const
Definition lib_tree.cpp:403
void SelectLibId(const LIB_ID &aLibId)
Select an item in the tree widget.
Definition lib_tree.cpp:371
LIB_TREE_MODEL_ADAPTER::SORT_MODE GetSortMode() const
Definition lib_tree.h:154
int GetSelectedLibIds(std::vector< LIB_ID > &aSelection, std::vector< int > *aUnit=nullptr) const
Retrieve a list of selections for trees that allow multi-selection.
Definition lib_tree.cpp:330
void Unselect()
Unselect currently selected item in wxDataViewCtrl.
Definition lib_tree.cpp:389
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:310
void ExpandLibId(const LIB_ID &aLibId)
Expand and item i the tree widget.
Definition lib_tree.cpp:397
void Regenerate(bool aKeepState)
Regenerate the tree.
Definition lib_tree.cpp:475
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
Definition pgm_base.cpp:792
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:123
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:125
A holder to handle information on schematic or board items.
unsigned GetCount() const
void ClearItemsList()
Delete only the list of pickers NOT the picked data itself.
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:183
Action handler for the Properties panel.
Gather all the actions that are shared by tools.
Definition sch_actions.h:45
static TOOL_ACTION rotateCCW
static TOOL_ACTION editSymbolPinMaps
static TOOL_ACTION importSymbol
static TOOL_ACTION newSymbol
static TOOL_ACTION saveLibraryAs
static TOOL_ACTION mirrorV
static TOOL_ACTION drawEllipseArc
static TOOL_ACTION editLibSymbolWithLibEdit
static TOOL_ACTION drawArc
static TOOL_ACTION pinTable
static TOOL_ACTION drawSymbolLines
static TOOL_ACTION placeSymbolPin
static TOOL_ACTION drawSymbolTextBox
static TOOL_ACTION ddImportGraphics
static TOOL_ACTION drawRectangle
static TOOL_ACTION drawEllipse
static TOOL_ACTION drawCircle
static TOOL_ACTION importGraphics
static TOOL_ACTION drawBezier
static TOOL_ACTION saveSymbolCopyAs
static TOOL_ACTION rotateCW
static TOOL_ACTION showElectricalTypes
static TOOL_ACTION drawSymbolPolygon
static TOOL_ACTION showHiddenFields
static TOOL_ACTION placeSymbolAnchor
static TOOL_ACTION showHiddenPins
static TOOL_ACTION cycleBodyStyle
static TOOL_ACTION mirrorH
static TOOL_ACTION runERC
Inspection and Editing.
static TOOL_ACTION symbolProperties
static TOOL_ACTION placeSymbolText
static TOOL_ACTION toggleSyncedPinsMode
static TOOL_ACTION togglePinAltIcons
static TOOL_ACTION updateSymbolFields
static TOOL_ACTION saveSymbolAs
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
SCH_BASE_FRAME(KIWAY *aKiway, wxWindow *aParent, FRAME_T aWindowType, const wxString &aTitle, const wxPoint &aPosition, const wxSize &aSize, long aStyle, const wxString &aFrameName)
SCH_RENDER_SETTINGS * GetRenderSettings()
void doCloseWindow() override
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SYMBOL_EDITOR_SETTINGS * libeditconfig() const
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void CommonSettingsChanged(int aFlags) override
Notification event that some of the common (suite-wide) settings have changed.
void SyncView()
Mark all items for refresh.
PANEL_SCH_SELECTION_FILTER * m_selectionFilterPanel
virtual void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false)
Mark an item for refresh.
void setSymWatcher(const LIB_ID *aSymbol)
Creates (or removes) a watcher on the specified symbol library.
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void DisplaySymbol(LIB_SYMBOL *aSymbol)
Schematic editor (Eeschema) main window.
bool SaveSymbolToSchematic(const LIB_SYMBOL &aSymbol, const KIID &aSchematicSymbolUUID)
Update a schematic symbol from a LIB_SYMBOL.
void SetPosition(const VECTOR2I &aPosition) override
Handle actions specific to the schematic editor.
static const wxString ShowType(SCH_FILE_T aFileType)
Return a brief name for a plugin, given aFileType enum.
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a symbol library using the file extension of aLibPath.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:165
int GetBodyStyle() const
Definition sch_item.h:247
int GetUnit() const
Definition sch_item.h:237
Tool that displays edit points allowing to modify items by dragging the points.
SCH_SELECTION & GetSelection()
SCH_SELECTION_FILTER_OPTIONS & GetFilter()
Schematic symbol object.
Definition sch_symbol.h:75
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
VECTOR2I GetPosition() const override
Definition sch_symbol.h:934
const LIB_ID & GetLibId() const override
Definition sch_symbol.h:164
int GetOrientation() const override
Get the display symbol orientation.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition sch_symbol.h:183
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
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).
Handle actions for the various symbol editor and viewers.
One open symbol tab owning a working LIB_SYMBOL and screen lent to the frame while active.
The symbol library editor main window.
std::vector< std::unique_ptr< SYMBOL_EDITOR_TAB_CONTEXT > > m_tabContexts
bool m_isSymbolFromSchematic
True while a schematic-edit auto-hide of the library tree still needs restoring on save.
void restoreSymbolTabsFromSettings()
Recreate tabs from the persisted open-tab list once the libraries have loaded.
void OnExitKiCad(wxCommandEvent &event)
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
bool promptToSaveInactiveInstanceTabs()
Prompt to save each dirty instance (symbol from schematic) tab that is not the active one,...
std::unique_ptr< GRID_HELPER > MakeGridHelper() override
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false) override
Mark an item for refresh.
void setupUIConditions() override
Setup the UI conditions for the various actions and their controls in this frame.
APP_SETTINGS_BASE * config() const override
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
bool hasDirtyInactiveInstanceTabs() const
True if any non-active instance (schematic) tab has unsaved edits.
bool IsLibraryTreeShown() const override
const BOX2I GetDocumentExtents(bool aIncludeAllVisible=true) const override
Return bounding box of document with option to not include some items.
SELECTION & GetCurrentSelection() override
Get the current selection from the canvas area.
wxString getTargetLib() const
bool LoadSymbolFromLib(const wxString &aLibName, const wxString &aSymbolName, int aUnit=0, int aBodyStyle=0)
Load a symbol from a library, optionally setting the selected unit and body style.
bool IsCurrentSymbol(const LIB_ID &aLibId) const
Restore the empty editor screen, without any symbol or library selected.
static void freeTransientUndoCommands(UNDO_REDO_CONTAINER &aList, const LIB_SYMBOL *aLiveSymbol)
Free every command in the list and the UR_TRANSIENT-flagged copies it owns, which the shared deleters...
void OnSelectBodyStyle(wxCommandEvent &event)
bool backupFile(const wxFileName &aOriginalFile, const wxString &aBackupExt)
Return currently edited symbol.
EDITOR_TABS_PANEL * m_tabsPanel
SYMBOL_EDITOR_TAB_CONTEXT * findOrCreateSymbolInstanceTab(LIB_SYMBOL *aSymbol, SCH_SCREEN *aScreen, const KIID &aSchematicSymbolUUID, const wxString &aReference, int aUnit, int aBodyStyle)
Find or create the instance tab for a placed schematic symbol and make it active.
void RefreshLibraryTree()
Redisplay the library tree.
void updateSelectionFilterVisbility() override
Selection filter panel doesn't have a dedicated visibility control, so show it if any other AUI panel...
void CommonSettingsChanged(int aFlags) override
Called after the preferences dialog is run.
void FocusLibraryTreeInput() override
wxComboBox * m_unitSelectBox
bool m_drawSpecificBodyStyle
Flag if the symbol being edited was loaded directly from a schematic.
void RebuildSymbolUnitAndBodyStyleLists()
int GetTreeLIBIDs(std::vector< LIB_ID > &aSelection) const
void OnTabCharHook(wxKeyEvent &aEvent)
Cycle symbol tabs from the char hook, since GTK cannot register WXK_TAB as an accelerator.
LIB_ID GetTreeLIBID(int *aUnit=nullptr) const
Return the LIB_ID of the library or symbol selected in the symbol tree.
LIB_SYMBOL_LIBRARY_MANAGER * m_libMgr
void FocusOnLibId(const LIB_ID &aLibID)
bool IsSymbolAlias() const
Return true if aLibId is an alias for the editor screen symbol.
void ToggleProperties() override
SYMBOL_EDITOR_SETTINGS * m_settings
void HardRedraw() override
Rebuild the GAL and redraw the screen.
int GetTreeSelectionCount() const
bool addLibTableEntry(const wxString &aLibFile, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::GLOBAL)
Add aLibFile to the symbol library table defined by aScope.
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
bool CanCloseSymbolFromSchematic(bool doClose)
bool IsSymbolFromLegacyLibrary() const
bool replaceLibTableEntry(const wxString &aLibNickname, const wxString &aLibFile)
Replace the file path of the symbol library table entry aLibNickname with aLibFile.
bool IsSymbolFromSchematic() const
void SetScreen(BASE_SCREEN *aScreen) override
void KiwayMailIn(KIWAY_MAIL_EVENT &mail) override
Receive #KIWAY_ROUTED_EVENT messages from other players.
SYMBOL_EDITOR_TAB_CONTEXT * m_activeTab
SYMBOL_EDITOR_SETTINGS * GetSettings() const
SCH_SCREEN * m_dummyScreen
< Helper screen used when no symbol is loaded
void SetCurSymbol(LIB_SYMBOL *aSymbol, bool aUpdateZoom)
Take ownership of aSymbol and notes that it is the one currently being edited.
KIID m_schematicSymbolUUID
RefDes of the symbol (only valid if symbol was loaded from schematic)
SYMBOL_EDIT_FRAME(KIWAY *aKiway, wxWindow *aParent)
static bool libTreeAutoHiddenForSchematicEdit(bool aWasFromSchematic, bool aRestorePending, bool aTreeShownNow)
Resolve whether the library tree's auto-hide for a schematic edit still needs restoring on save.
bool IsSymbolEditable() const
Test if a symbol is loaded and can be edited.
std::vector< LIB_ID > GetSelectedLibIds() const
void SyncLibraries(bool aShowProgress, bool aPreloadCancelled=false, const wxString &aForceRefresh=wxEmptyString)
Synchronize the library manager to the symbol library table, and then the symbol tree to the library ...
void OnSelectUnit(wxCommandEvent &event)
void storeSymbolTabsToSettings()
Write the current tab set into the editor settings for the next session.
LIB_SYMBOL * GetCurSymbol() const
Return the current symbol being edited or NULL if none selected.
void UpdateSymbolMsgPanelInfo()
Display the documentation of the selected symbol.
bool canCloseWindow(wxCloseEvent &aCloseEvent) override
LIB_ID GetTargetLibId() const override
Return either the symbol selected in the symbol tree (if context menu is active) or the symbol on the...
void SetBodyStyle(int aBodyStyle)
bool saveAllLibraries(bool aRequireConfirmation)
Save the current symbol.
void UpdateMsgPanel() override
Redraw the message panel.
void ClearUndoORRedoList(UNDO_REDO_LIST whichList, int aItemCount=-1) override
Free the undo or redo list from aList element.
LIB_TREE * GetLibTree() const override
void UpdateTitle()
Update the main window title bar with the current library name and read only status of the library.
bool HasLibModifications() const
Check if any pending libraries have been modified.
bool promptAndCloseSymbolTab(int aIdx)
Prompt for unsaved changes on the tab and drop its context.
SYMBOL_TREE_PANE * m_treePane
void SetDrawSpecificUnit(bool aSpecific)
void LoadSymbolFromSchematic(SCH_SYMBOL *aSymbol)
Load a symbol from the schematic to edit in place.
bool IsSymbolGraphicallyEditable() const
Test if a symbol is loaded and can be edited graphically.
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Returns a pointer to the active color theme settings.
LIB_SYMBOL_LIBRARY_MANAGER & GetLibManager()
void OnUpdateBodyStyle(wxUpdateUIEvent &event)
void SaveSymbolCopyAs(bool aOpenCopy)
Save the currently selected symbol to a new name and/or location.
void SwitchCanvas(EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType) override
Switch currently used canvas ( Cairo / OpenGL).
void doCloseWindow() override
SYMBOL_EDITOR_TAB_CONTEXT * symbolTabContextForIndex(int aIdx) const
Resolve the tab context for a panel tab index, or nullptr.
static void clearSymbolTabUndoRedo(SYMBOL_EDITOR_TAB_CONTEXT &aContext)
Free a detached context's undo/redo, which the frame's own teardown path never reaches.
void DdAddLibrary(wxString aLibFile)
Add a library dropped file to the symbol library table.
wxString AddLibraryFile(bool aCreateNew)
Create or add an existing library to the symbol library table.
void FocusOnItem(EDA_ITEM *aItem, bool aAllowScroll=true) override
Focus on a particular canvas item.
void configureToolbars() override
void CloseWindow(wxCommandEvent &event)
Trigger the wxCloseEvent, which is handled by the function given to EVT_CLOSE() macro:
wxComboBox * m_bodyStyleSelectBox
void activateSymbolTab(SYMBOL_EDITOR_TAB_CONTEXT *aContext)
Make aContext the active tab, borrowing its working symbol, undo/redo, view and selection,...
void UpdateLibraryTree(const wxDataViewItem &aTreeItem, LIB_SYMBOL *aSymbol)
Update a symbol node in the library tree.
void closeAllSymbolTabsSilently()
Close every tab without prompting and return the frame to the empty state.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current symbol.
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
void SaveLibraryAs()
Save the currently selected library to a new file.
bool IsContentModified() const override
Get if any symbols or libraries have been modified but not saved.
void ToggleLibraryTree() override
LIB_SYMBOL * getTargetSymbol() const
Return either the library selected in the symbol tree, if context menu is active or the library that ...
void OnUpdateUnitNumber(wxUpdateUIEvent &event)
An interface to the global shared library manager that is schematic-specific and linked to one projec...
std::optional< LIB_STATUS > LoadOne(LIB_DATA *aLib) override
Loads or reloads the given library, if it exists.
Library Editor pane with symbol tree and symbol library table selector.
Rate-limiter that fires at most once per interval.
Definition throttle.h:31
bool Ready()
Definition throttle.h:44
TOOL_MANAGER * m_toolManager
TOOL_DISPATCHER * m_toolDispatcher
bool ToolStackIsEmpty()
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
ACTIONS * m_actions
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition tool_base.h:76
virtual void DispatchWxEvent(wxEvent &aEvent)
Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those.
Master controller class:
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.
bool empty() const
Definition utf8.h:105
A modified version of the wxInfoBar class that allows us to:
Definition wx_infobar.h:76
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
bool HasCloseButton() const
void AddLink(const wxString &aLinkText, const std::function< void(wxHyperlinkEvent &)> &aFn)
Add a hypertext link to the infobar.
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
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:146
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:192
This file is part of the common library.
#define KICAD_MESSAGE_DIALOG
Definition confirm.h:48
#define CHECK(x)
#define ENABLE(x)
static bool empty(const wxTextEntryBase *aCtrl)
#define _(s)
#define KICAD_DEFAULT_DRAWFRAME_STYLE
#define LIB_EDIT_FRAME_NAME
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
@ ID_LIBEDIT_SELECT_UNIT_NUMBER
Definition eeschema_id.h:59
@ ID_LIBEDIT_SELECT_BODY_STYLE
Definition eeschema_id.h:60
const wxAuiPaneInfo & defaultSchSelectionFilterPaneInfo(wxWindow *aWindow)
const wxAuiPaneInfo & defaultPropertiesPaneInfo(wxWindow *aWindow)
wxString NormalizePath(const wxFileName &aFilePath, const ENV_VAR_MAP *aEnvVars, const wxString &aProjectPath)
Normalize a file path to an environmental variable, if possible.
Definition env_paths.cpp:73
Helper functions to substitute paths with environmental variables.
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:31
@ FRAME_SCH
Definition frame_type.h:30
static const std::string SymbolLibraryTableFileName
static const std::string KiCadSymbolLibFileExtension
static const std::string SVGFileExtension
static wxString KiCadSymbolLibFileWildcard()
const wxChar *const traceLibWatch
Flag to enable debug output for library file watch refreshes.
@ ID_ON_GRID_SELECT
Definition id.h:113
@ ID_ON_ZOOM_SELECT
Definition id.h:112
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
PROJECT & Prj()
Definition kicad.cpp:727
EVT_MENU(ID_COMPARE_PROJECT_BRANCHES, KICAD_MANAGER_FRAME::OnCompareProjectBranches) KICAD_MANAGER_FRAME
TAB_VISUAL_STATE ResolveTabVisualState(bool aPreview, bool aModified)
Resolve a tab's decorations from its document state flags.
KIID niluuid(0)
@ LAYER_SCHEMATIC_GRID_AXES
Definition layer_ids.h:509
LIBRARY_TABLE_SCOPE
@ MAIL_LIB_EDIT
Definition mail_type.h:51
@ MAIL_REFRESH_SYMBOL
Definition mail_type.h:55
@ MAIL_RELOAD_LIB
Definition mail_type.h:53
@ ALL
All except INITIAL_ADD.
Definition view_item.h:55
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
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition kicad_algo.h:96
static std::string normalizedPath(std::string aPath)
#define _HKI(x)
Definition page_info.cpp:40
void InvokeSchEditSymbolLibTable(KIWAY *aKiway, wxWindow *aParent)
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
#define DEFAULT_THEME
COLOR_SETTINGS * GetColorSettings(const wxString &aName)
T * GetToolbarSettings(const wxString &aFilename)
T * GetAppSettings(const char *aFilename)
KIWAY Kiway(KFCTL_STANDALONE)
wxString UnescapeString(const wxString &aSource)
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
wxString message
Visual decorations derived from document state: preview is italic, modified is bold with a leading as...
@ SYM_ORIENT_270
Definition symbol.h:38
@ SYM_MIRROR_Y
Definition symbol.h:40
@ SYM_ORIENT_180
Definition symbol.h:37
@ SYM_MIRROR_X
Definition symbol.h:39
@ SYM_ORIENT_90
Definition symbol.h:36
#define EDIT_TOOL(tool)
#define DEMORGAN_ALT
#define DEMORGAN_STD
KIBIS_PIN * pin
#define ENVVARS_CHANGED
wxLogTrace helper definitions.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682
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.