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>
72#include <view/view_controls.h>
74#include <widgets/wx_infobar.h>
80#include <widgets/lib_tree.h>
85#include <panel_sym_lib_table.h>
86#include <string_utils.h>
88#include <wx/msgdlg.h>
89#include <wx/combobox.h>
90#include <wx/log.h>
91#include <trace_helpers.h>
92
93
95
96
97BEGIN_EVENT_TABLE( SYMBOL_EDIT_FRAME, SCH_BASE_FRAME )
100
101 // menubar commands
104
105 // Update user interface elements.
108
111
112 // Drop files event
113 EVT_DROP_FILES( SYMBOL_EDIT_FRAME::OnDropFiles )
114
115END_EVENT_TABLE()
116
117
118SYMBOL_EDIT_FRAME::SYMBOL_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
119 SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_SYMBOL_EDITOR, _( "Library Editor" ),
120 wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE,
122 m_unitSelectBox( nullptr ),
123 m_bodyStyleSelectBox( nullptr ),
125{
126 m_SyncPinEdit = false;
127
128 m_symbol = nullptr;
129 m_treePane = nullptr;
130 m_libMgr = nullptr;
131 m_unit = 1;
132 m_bodyStyle = 1;
134 m_aboutTitle = _HKI( "KiCad Symbol Editor" );
135
136 wxIcon icon;
137 wxIconBundle icon_bundle;
138
139 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit, 48 ) );
140 icon_bundle.AddIcon( icon );
141 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit, 256 ) );
142 icon_bundle.AddIcon( icon );
143 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit, 128 ) );
144 icon_bundle.AddIcon( icon );
145 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit_32 ) );
146 icon_bundle.AddIcon( icon );
147 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit_16 ) );
148 icon_bundle.AddIcon( icon );
149
150 SetIcons( icon_bundle );
151
154
156
157 m_treePane = new SYMBOL_TREE_PANE( this, m_libMgr );
158 m_treePane->GetLibTree()->SetSortMode( (LIB_TREE_MODEL_ADAPTER::SORT_MODE) m_settings->m_LibrarySortMode );
159
162
163 // Ensure axis are always drawn
165 gal_opts.m_axesEnabled = true;
166
169 GetScreen()->m_Center = true;
170
171 GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
172
173 GetRenderSettings()->LoadColors( GetColorSettings() );
174 GetRenderSettings()->m_IsSymbolEditor = true;
175 GetCanvas()->GetGAL()->SetAxesColor( m_colorSettings->GetColor( LAYER_SCHEMATIC_GRID_AXES ) );
176
177 setupTools();
179
181
185
186 UpdateTitle();
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
237 const bool modified = ctx ? ctx->IsModified() : entries[aIdx].modified;
238
239 return ResolveTabVisualState( entries[aIdx].preview, modified );
240 };
241
242 m_auimgr.AddPane( m_tabsPanel, wxAuiPaneInfo().Name( "DrawFrame" )
243 .CentrePane() );
244
245 // Columns; layers 1 - 3
246 m_auimgr.AddPane( m_treePane, EDA_PANE().Palette().Name( "LibraryTree" )
247 .Left().Layer( 3 )
248 .TopDockable( false ).BottomDockable( false )
249 .Caption( _( "Libraries" ) )
250 // Don't use -1 for don't-change-height on a growable panel; it has side-effects.
251 .MinSize( FromDIP( 250 ), FromDIP( 80 ) )
252 .BestSize( FromDIP( 250 ), -1 ) );
253
256
257 // Can be called only when all panes are created, because (at least on Windows) when items
258 // managed by m_auimgr are not the same as those existing when saved by Perspective()
259 // in config, broken settings can happen.
261
262 // Protect against broken saved Perspective() due to bugs in previous version
263 // This is currently a workaround.
264 m_auimgr.GetPane( "TopMainToolbar" ).Top().Layer( 6 ).Position(0).Show( true );
265 m_auimgr.GetPane( "LeftToolbar" ).Position(0).Show( true );
266 m_auimgr.GetPane( "RightToolbar" ).Show( true );
267
268 // Show or hide m_propertiesPanel depending on current settings:
269 wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
270 wxAuiPaneInfo& selectionFilterPane = m_auimgr.GetPane( wxS( "SelectionFilter" ) );
271 // The selection filter doesn't need to grow in the vertical direction when docked
272 selectionFilterPane.dock_proportion = 0;
273
274 propertiesPaneInfo.Show( m_settings->m_AuiPanels.show_properties );
276
278
279 // Can't put this in LoadSettings, because it has to be called before setupTools :/
281 selTool->GetFilter() = GetSettings()->m_SelectionFilter;
282 m_selectionFilterPanel->SetCheckboxesFromFilter( selTool->GetFilter() );
283
284 if( m_settings->m_LibWidth > 0 )
285 SetAuiPaneSize( m_auimgr, m_auimgr.GetPane( "LibraryTree" ), m_settings->m_LibWidth, -1 );
286
287 Raise();
288 Show( true );
289
290 SyncView();
291 GetCanvas()->GetView()->UseDrawPriority( true );
292 GetCanvas()->GetGAL()->SetAxesEnabled( true );
293
295
296 // Set the working/draw area size to display a symbol to a reasonable value:
297 // A 600mm x 600mm with a origin at the area center looks like a large working area
298 double max_size_x = schIUScale.mmToIU( 600 );
299 double max_size_y = schIUScale.mmToIU( 600 );
300 BOX2D bbox;
301 bbox.SetOrigin( -max_size_x /2, -max_size_y/2 );
302 bbox.SetSize( max_size_x, max_size_y );
303 GetCanvas()->GetView()->SetBoundary( bbox );
304
306
308 DragAcceptFiles( true );
309
310 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "Library changes are unsaved" ) );
311
312 // Catch unhandled accelerator command characters that were no handled by the library tree
313 // panel.
315 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
316
317 // GTK rejects WXK_TAB as an accelerator so cycle tabs from the char hook ahead of the dispatcher.
318 Bind( wxEVT_CHAR_HOOK, &SYMBOL_EDIT_FRAME::OnTabCharHook, this );
319
320 // Ensure the window is on top
321 Raise();
322
323 // run SyncLibraries with progress reporter enabled. The progress reporter is useful
324 // in debug mode because the loading time of ecah library can be really noticeable
325 SyncLibraries( true );
326
327 // Must follow SyncLibraries so persisted tabs can resolve against the loaded libraries.
329}
330
331
333{
334 // Hand the borrowed canvas back before the base destructor frees it, else the panel reparents
335 // freed memory on its own teardown.
336 if( m_tabsPanel )
337 m_tabsPanel->ReleaseSharedCanvas();
338
339 // Shutdown all running tools
340 if( m_toolManager )
341 m_toolManager->ShutdownAllTools();
342
343 setSymWatcher( nullptr );
344
345 if( m_activeTab )
346 {
347 // Hand the working objects back so the context deletes them exactly once below; raw deleting
348 // here would double-free with the context dtor and leak the swapped-in undo list. Covers an
349 // active instance tab too, whose m_isSymbolFromSchematic mirror is only frame state.
351 m_activeTab->AdoptWorkingObjects( m_symbol, static_cast<SCH_SCREEN*>( GetScreen() ) );
352 m_activeTab = nullptr;
353 m_symbol = nullptr;
355 }
356 else
357 {
358 // No active tab owns the current screen, so let EDA_DRAW_FRAME free it.
360 }
361
362 // Free each detached context's undo/redo with the frame on the dummy screen to avoid double-frees.
363 for( const std::unique_ptr<SYMBOL_EDITOR_TAB_CONTEXT>& ctx : m_tabContexts )
365
366 m_tabContexts.clear();
367
369 Pgm().GetSettingsManager().Save( cfg );
370
371 delete m_libMgr;
372}
373
374
376{
377 wxCHECK_RET( m_settings, "Call to SYMBOL_EDIT_FRAME::LoadSettings with null m_settings" );
378
380
381 GetRenderSettings()->m_ShowPinsElectricalType = m_settings->m_ShowPinElectricalType;
382 GetRenderSettings()->m_ShowHiddenPins = m_settings->m_ShowHiddenPins;
383 GetRenderSettings()->m_ShowHiddenFields = m_settings->m_ShowHiddenFields;
384 GetRenderSettings()->m_ShowPinAltIcons = m_settings->m_ShowPinAltIcons;
385 GetRenderSettings()->SetDefaultFont( wxEmptyString );
386}
387
388
390{
391 wxCHECK_RET( m_settings, "Call to SYMBOL_EDIT_FRAME:SaveSettings with null m_settings" );
392
394
396
397 m_settings->m_ShowPinElectricalType = GetRenderSettings()->m_ShowPinsElectricalType;
398 m_settings->m_ShowHiddenPins = GetRenderSettings()->m_ShowHiddenPins;
399 m_settings->m_ShowHiddenFields = GetRenderSettings()->m_ShowHiddenFields;
400 m_settings->m_ShowPinAltIcons = GetRenderSettings()->m_ShowPinAltIcons;
401
402 m_settings->m_LibWidth = m_treePane->GetSize().x;
403
404 m_settings->m_LibrarySortMode = GetLibTree()->GetSortMode();
405
406 m_settings->m_AuiPanels.properties_splitter = m_propertiesPanel->SplitterProportion();
407 bool prop_shown = m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
408 m_settings->m_AuiPanels.show_properties = prop_shown;
409
410 if( TOOL_MANAGER* toolMgr = GetToolManager() )
411 {
412 if( SCH_SELECTION_TOOL* selTool = toolMgr->GetTool<SCH_SELECTION_TOOL>() )
413 m_settings->m_SelectionFilter = selTool->GetFilter();
414 }
415
417}
418
419
421{
422 return static_cast<APP_SETTINGS_BASE*>( GetSettings() );
423}
424
425
427{
429
430 if( cfg && static_cast<SYMBOL_EDITOR_SETTINGS*>( cfg )->m_UseEeschemaColorSettings )
431 cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
432
433 return ::GetColorSettings( cfg ? cfg->m_ColorTheme : DEFAULT_THEME );
434}
435
436
438{
439 // Create the manager and dispatcher & route draw panel events to the dispatcher
441 m_toolManager->SetEnvironment( GetScreen(), GetCanvas()->GetView(),
442 GetCanvas()->GetViewControls(), GetSettings(), this );
443 m_actions = new SCH_ACTIONS();
445
446 // Register tools
447 m_toolManager->RegisterTool( new COMMON_CONTROL );
448 m_toolManager->RegisterTool( new COMMON_TOOLS );
449 m_toolManager->RegisterTool( new ZOOM_TOOL );
450 m_toolManager->RegisterTool( new SCH_SELECTION_TOOL );
451 m_toolManager->RegisterTool( new PICKER_TOOL );
452 m_toolManager->RegisterTool( new SCH_INSPECTION_TOOL );
453 m_toolManager->RegisterTool( new SYMBOL_EDITOR_PIN_TOOL );
454 m_toolManager->RegisterTool( new SYMBOL_EDITOR_DRAWING_TOOLS );
455 m_toolManager->RegisterTool( new SCH_POINT_EDITOR );
456 m_toolManager->RegisterTool( new SCH_FIND_REPLACE_TOOL );
457 m_toolManager->RegisterTool( new SYMBOL_EDITOR_MOVE_TOOL );
458 m_toolManager->RegisterTool( new SYMBOL_EDITOR_EDIT_TOOL );
459 m_toolManager->RegisterTool( new LIBRARY_EDITOR_CONTROL );
460 m_toolManager->RegisterTool( new SYMBOL_EDITOR_CONTROL );
461 m_toolManager->RegisterTool( new PROPERTIES_TOOL );
462 m_toolManager->RegisterTool( new EMBED_TOOL );
463 m_toolManager->InitTools();
464
465 // Run the selection tool, it is supposed to be always active
466 m_toolManager->InvokeTool( "common.InteractiveSelection" );
467
469}
470
471
473{
475
476 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
477 EDITOR_CONDITIONS cond( this );
478
479 wxASSERT( mgr );
480
481#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
482#define CHECK( x ) ACTION_CONDITIONS().Check( x )
483
484 auto haveSymbolCond =
485 [this]( const SELECTION& )
486 {
487 return m_symbol;
488 };
489
490 auto isEditableCond =
491 [this]( const SELECTION& )
492 {
493 // Only root symbols from the new s-expression libraries or the schematic
494 // are editable.
495 return IsSymbolEditable() && !IsSymbolAlias();
496 };
497
498 auto isEditableInAliasCond =
499 [this]( const SELECTION& )
500 {
501 // Less restrictive than isEditableCond
502 // Symbols fields (root symbols and aliases) from the new s-expression libraries
503 // or in the schematic are editable.
504 return IsSymbolEditable();
505 };
506
507 auto symbolModifiedCondition =
508 [this]( const SELECTION& sel )
509 {
510 return m_libMgr && m_libMgr->IsSymbolModified( GetTargetLibId().GetLibItemName(),
511 GetTargetLibId().GetLibNickname() );
512 };
513
514 auto libSelectedCondition =
515 [this]( const SELECTION& sel )
516 {
517 return !GetTargetLibId().GetLibNickname().empty();
518 };
519
520 auto canEditProperties =
521 [this]( const SELECTION& sel )
522 {
524 };
525
526 auto symbolSelectedInTreeCondition =
527 [this]( const SELECTION& sel )
528 {
529 LIB_ID targetLibId = GetTargetLibId();
530 return !targetLibId.GetLibNickname().empty() && !targetLibId.GetLibItemName().empty();
531 };
532
533 auto saveSymbolAsCondition =
534 [this]( const SELECTION& aSel )
535 {
536 return getTargetSymbol() != nullptr;
537 };
538
539 const auto isSymbolFromSchematicCond =
540 [this]( const SELECTION& )
541 {
542 return IsSymbolFromSchematic();
543 };
544
545 // clang-format off
548 mgr->SetConditions( SCH_ACTIONS::saveLibraryAs, ENABLE( libSelectedCondition ) );
549 mgr->SetConditions( SCH_ACTIONS::saveSymbolAs, ENABLE( saveSymbolAsCondition ) );
550 mgr->SetConditions( SCH_ACTIONS::saveSymbolCopyAs, ENABLE( saveSymbolAsCondition ) );
553 mgr->SetConditions( SCH_ACTIONS::editLibSymbolWithLibEdit, ENABLE( isSymbolFromSchematicCond ) );
554
555 mgr->SetConditions( ACTIONS::undo, ENABLE( haveSymbolCond && cond.UndoAvailable() ) );
556 mgr->SetConditions( ACTIONS::redo, ENABLE( haveSymbolCond && cond.RedoAvailable() ) );
557 mgr->SetConditions( ACTIONS::revert, ENABLE( symbolModifiedCondition ) );
558
561
562 mgr->SetConditions( ACTIONS::cut, ENABLE( isEditableCond ) );
563 mgr->SetConditions( ACTIONS::copy, ENABLE( haveSymbolCond ) );
564 mgr->SetConditions( ACTIONS::copyAsText, ENABLE( haveSymbolCond ) );
565 mgr->SetConditions( ACTIONS::paste, ENABLE( isEditableCond &&
567 mgr->SetConditions( ACTIONS::doDelete, ENABLE( isEditableCond ) );
568 mgr->SetConditions( ACTIONS::duplicate, ENABLE( isEditableCond ) );
569 mgr->SetConditions( ACTIONS::selectAll, ENABLE( haveSymbolCond ) );
570 mgr->SetConditions( ACTIONS::unselectAll, ENABLE( haveSymbolCond ) );
571
572 // These actions in symbol editor when editing alias field rotations are allowed.
573 mgr->SetConditions( SCH_ACTIONS::rotateCW, ENABLE( isEditableInAliasCond ) );
574 mgr->SetConditions( SCH_ACTIONS::rotateCCW, ENABLE( isEditableInAliasCond ) );
575
576 mgr->SetConditions( SCH_ACTIONS::mirrorH, ENABLE( isEditableCond ) );
577 mgr->SetConditions( SCH_ACTIONS::mirrorV, ENABLE( isEditableCond ) );
578
581 // clang-format on
582
583 auto pinTypeCond =
584 [this]( const SELECTION& )
585 {
587 };
588
589 auto hiddenPinCond =
590 [this]( const SELECTION& )
591 {
593 };
594
595 auto hiddenFieldCond =
596 [this]( const SELECTION& )
597 {
599 };
600
601 auto showPinAltIconsCond =
602 [this]( const SELECTION& )
603 {
605 };
606
607 auto showLibraryTreeCond =
608 [this]( const SELECTION& )
609 {
610 return IsLibraryTreeShown();
611 };
612
613 auto propertiesCond =
614 [this] ( const SELECTION& )
615 {
616 return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
617 };
618
621 mgr->SetConditions( ACTIONS::showLibraryTree, CHECK( showLibraryTreeCond ) );
622 mgr->SetConditions( ACTIONS::showProperties, CHECK( propertiesCond ) );
623 mgr->SetConditions( SCH_ACTIONS::showHiddenPins, CHECK( hiddenPinCond ) );
624 mgr->SetConditions( SCH_ACTIONS::showHiddenFields, CHECK( hiddenFieldCond ) );
625 mgr->SetConditions( SCH_ACTIONS::togglePinAltIcons, CHECK( showPinAltIconsCond ) );
626
627 auto multiUnitModeCond =
628 [this]( const SELECTION& )
629 {
630 return m_symbol && m_symbol->IsMultiUnit() && !m_symbol->UnitsLocked();
631 };
632
633 auto multiBodyStyleModeCond =
634 [this]( const SELECTION& )
635 {
636 return m_symbol && m_symbol->IsMultiBodyStyle();
637 };
638
639 auto syncedPinsModeCond =
640 [this]( const SELECTION& )
641 {
642 return m_SyncPinEdit;
643 };
644
645 auto haveDatasheetCond =
646 [this]( const SELECTION& )
647 {
648 return m_symbol && !m_symbol->GetDatasheetField().GetText().IsEmpty();
649 };
650
651 mgr->SetConditions( ACTIONS::showDatasheet, ENABLE( haveDatasheetCond ) );
652 mgr->SetConditions( SCH_ACTIONS::symbolProperties, ENABLE( symbolSelectedInTreeCondition || ( canEditProperties && haveSymbolCond ) ) );
653 mgr->SetConditions( SCH_ACTIONS::runERC, ENABLE( haveSymbolCond ) );
654 mgr->SetConditions( SCH_ACTIONS::pinTable, ENABLE( isEditableCond && haveSymbolCond ) );
655 mgr->SetConditions( SCH_ACTIONS::updateSymbolFields, ENABLE( isEditableCond && haveSymbolCond ) );
656 mgr->SetConditions( SCH_ACTIONS::cycleBodyStyle, ENABLE( multiBodyStyleModeCond ) );
657
658 mgr->SetConditions( SCH_ACTIONS::toggleSyncedPinsMode, ACTION_CONDITIONS().Enable( multiUnitModeCond ).Check( syncedPinsModeCond ) );
659
660// Only enable a tool if the symbol is edtable
661#define EDIT_TOOL( tool ) ACTION_CONDITIONS().Enable( isEditableCond ).Check( cond.CurrentTool( tool ) )
662
677
678#undef CHECK
679#undef ENABLE
680#undef EDIT_TOOL
681}
682
683
685{
686 if( IsContentModified() )
687 {
688 SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
689 wxString msg = _( "Save changes to '%s' before closing?" );
690
691 switch( UnsavedChangesDialog( this, wxString::Format( msg, m_reference ), nullptr ) )
692 {
693 case wxID_YES:
694 if( schframe && GetCurSymbol() ) // Should be always the case
696
697 break;
698
699 case wxID_NO:
700 break;
701
702 default:
703 case wxID_CANCEL:
704 return false;
705 }
706 }
707
708 if( doClose )
709 {
710 SetCurSymbol( nullptr, false );
711 UpdateTitle();
712 }
713
714 return true;
715}
716
717
718bool SYMBOL_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
719{
720 // Shutdown blocks must be determined and vetoed as early as possible, before any modal prompt.
721 // IsContentModified only sees the active tab, so also account for dirty inactive instance tabs.
723 && aEvent.GetId() == wxEVT_QUERY_END_SESSION
725 {
726 return false;
727 }
728
730 return false;
731
732 // Prompt for any dirty inactive instance tabs, which the active-tab checks above miss.
734 return false;
735
736 if( !saveAllLibraries( true ) )
737 return false;
738
739 // Save symbol tree column widths
740 m_libMgr->GetAdapter()->SaveSettings();
741
742 return true;
743}
744
745
747{
749
750 if( GetLibTree() )
752
753 delete m_toolManager;
754 m_toolManager = nullptr;
755
756 Destroy();
757}
758
759
761{
762 if( m_unitSelectBox )
763 {
764 if( m_unitSelectBox->GetCount() != 0 )
765 m_unitSelectBox->Clear();
766
767 if( !m_symbol || m_symbol->GetUnitCount() <= 1 )
768 {
769 m_unit = 1;
770 m_unitSelectBox->Append( wxEmptyString );
771 }
772 else
773 {
774 for( int i = 0; i < m_symbol->GetUnitCount(); i++ )
775 m_unitSelectBox->Append( m_symbol->GetUnitDisplayName( i + 1, true ) );
776 }
777
778 // Ensure the selected unit is compatible with the number of units of the current symbol:
779 if( m_symbol && m_symbol->GetUnitCount() < m_unit )
780 m_unit = 1;
781
782 m_unitSelectBox->SetSelection( ( m_unit > 0 ) ? m_unit - 1 : 0 );
783 }
784
786 {
787 if( m_bodyStyleSelectBox->GetCount() != 0 )
788 m_bodyStyleSelectBox->Clear();
789
790 if( !m_symbol || !m_symbol->IsMultiBodyStyle() )
791 {
792 m_bodyStyle = 1;
793 m_bodyStyleSelectBox->Append( wxEmptyString );
794 }
795 else if( m_symbol && m_symbol->HasDeMorganBodyStyles() )
796 {
797 m_bodyStyleSelectBox->Append( wxGetTranslation( DEMORGAN_STD ) );
798 m_bodyStyleSelectBox->Append( wxGetTranslation( DEMORGAN_ALT ) );
799 }
800 else
801 {
802 for( int i = 0; i < m_symbol->GetBodyStyleCount(); i++ )
803 m_bodyStyleSelectBox->Append( m_symbol->GetBodyStyleNames()[i] );
804 }
805
806 // Ensure the selected body style is compatible with the number of body styles of the current symbol:
807 if( m_symbol && m_symbol->GetBodyStyleCount() < m_bodyStyle )
808 m_bodyStyle = 1;
809
810 m_bodyStyleSelectBox->SetSelection( ( m_bodyStyle > 0 ) ? m_bodyStyle - 1 : 0 );
811 }
812}
813
814
816{
817 if( !m_propertiesPanel )
818 return;
819
820 bool show = !m_propertiesPanel->IsShownOnScreen();
821
822 wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
823 propertiesPaneInfo.Show( show );
825
826 if( show )
827 {
828 SetAuiPaneSize( m_auimgr, propertiesPaneInfo,
829 m_settings->m_AuiPanels.properties_panel_width, -1 );
830 }
831 else
832 {
833 m_settings->m_AuiPanels.properties_panel_width = m_propertiesPanel->GetSize().x;
834 }
835
836 m_auimgr.Update();
837 Refresh();
838}
839
840
842{
843 wxAuiPaneInfo& treePane = m_auimgr.GetPane( m_treePane );
844 treePane.Show( !IsLibraryTreeShown() );
846 m_auimgr.Update();
847 Refresh();
848}
849
850
852{
853 return const_cast<wxAuiManager&>( m_auimgr ).GetPane( m_treePane ).IsShown();
854}
855
856
861
862
864{
865 m_treePane->Freeze();
866 m_libMgr->GetAdapter()->Freeze();
867}
868
869
871{
872 m_libMgr->GetAdapter()->Thaw();
873 m_treePane->Thaw();
874}
875
876
877void SYMBOL_EDIT_FRAME::OnExitKiCad( wxCommandEvent& event )
878{
879 Kiway().OnKiCadExit();
880}
881
882
883void SYMBOL_EDIT_FRAME::OnUpdateUnitNumber( wxUpdateUIEvent& event )
884{
885 event.Enable( m_symbol && m_symbol->GetUnitCount() > 1 );
886}
887
888
889void SYMBOL_EDIT_FRAME::OnSelectUnit( wxCommandEvent& event )
890{
891 if( event.GetSelection() == wxNOT_FOUND )
892 return;
893
894 SetUnit( event.GetSelection() + 1 );
895}
896
897
898void SYMBOL_EDIT_FRAME::OnUpdateBodyStyle( wxUpdateUIEvent& event )
899{
900 event.Enable( m_symbol && m_symbol->GetBodyStyleCount() > 1 );
901}
902
903
904void SYMBOL_EDIT_FRAME::OnSelectBodyStyle( wxCommandEvent& event )
905{
906 if( event.GetSelection() == wxNOT_FOUND )
907 return;
908
909 SetBodyStyle( event.GetSelection() + 1 );
910}
911
912
914{
915 if( m_symbol )
916 {
918
919 if( auto row = adapter->GetRow( m_symbol->GetLibNickname() ); row.has_value() )
920 {
921 if( ( *row )->Type() == SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) )
922 return true;
923 }
924 }
925
926 return false;
927}
928
929
931{
932 wxString libNickname = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_LIB );
933
934 if( !libNickname.empty() )
935 {
936 if( !PROJECT_SCH::SymbolLibAdapter( &Prj() )->HasLibrary( libNickname ) )
937 {
938 Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, wxEmptyString );
939 libNickname = wxEmptyString;
940 }
941 }
942
943 return libNickname;
944}
945
946
947wxString SYMBOL_EDIT_FRAME::SetCurLib( const wxString& aLibNickname )
948{
949 wxString old = GetCurLib();
950
951 if( aLibNickname.empty() || !PROJECT_SCH::SymbolLibAdapter( &Prj() )->HasLibrary( aLibNickname ) )
952 Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, wxEmptyString );
953 else
955
956 return old;
957}
958
959
960void SYMBOL_EDIT_FRAME::SetCurSymbol( LIB_SYMBOL* aSymbol, bool aUpdateZoom )
961{
962 wxCHECK( m_toolManager, /* void */ );
963
965 GetCanvas()->GetView()->Clear();
966
967 // Install the replacement and refresh the active context before freeing the old symbol, so the
968 // context never observes a freed pointer.
969 LIB_SYMBOL* oldSymbol = m_symbol;
970
971 m_symbol = aSymbol;
972
973 if( m_activeTab )
974 m_activeTab->RefreshFrameOwnedObjects( m_symbol, static_cast<SCH_SCREEN*>( GetScreen() ) );
975
976 delete oldSymbol;
977
978 // select the current symbol in the tree widget
980 GetLibTree()->SelectLibId( m_symbol->GetLibId() );
981 else
982 GetLibTree()->Unselect();
983
984 wxString symbolName;
985 wxString libName;
986
987 if( m_symbol )
988 {
989 symbolName = m_symbol->GetName();
990 libName = UnescapeString( m_symbol->GetLibId().GetLibNickname() );
991 }
992
993 // retain in case this wxFrame is re-opened later on the same PROJECT
995
996 // Ensure synchronized pin edit can be enabled only symbols with interchangeable units
997 m_SyncPinEdit = aSymbol && aSymbol->IsRoot() && aSymbol->IsMultiUnit() && !aSymbol->UnitsLocked();
998
1000
1008
1009 if( aUpdateZoom )
1011
1012 GetCanvas()->Refresh();
1013 m_propertiesPanel->UpdateData();
1014
1015 WX_INFOBAR& infobar = *GetInfoBar();
1016 infobar.RemoveAllButtons();
1017
1018 wxArrayString msgs;
1019 int infobarFlags = wxICON_INFORMATION;
1020
1021 if( IsSymbolFromSchematic() )
1022 {
1023 msgs.push_back( wxString::Format( _( "Editing symbol %s from schematic. Saving will "
1024 "update the schematic only." ),
1025 m_reference ) );
1026
1027 wxString link = wxString::Format( _( "Open symbol from library %s" ), libName );
1028 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( &infobar, wxID_ANY, link, wxEmptyString );
1029
1030 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
1031 [this, symbolName, libName]( wxHyperlinkEvent& aEvent )
1032 {
1034 } ) );
1035
1036 infobar.AddButton( button );
1037 }
1038 else if( IsSymbolFromLegacyLibrary() )
1039 {
1040 msgs.push_back( _( "Symbols in legacy libraries are not editable. Use Manage Symbol "
1041 "Libraries to migrate to current format." ) );
1042
1043 wxString link = _( "Manage symbol libraries" );
1044 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( &infobar, wxID_ANY, link, wxEmptyString );
1045
1046 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
1047 [this]( wxHyperlinkEvent& aEvent )
1048 {
1050 } ) );
1051
1052 infobar.AddButton( button );
1053 }
1054 else if( IsSymbolAlias() )
1055 {
1056 msgs.push_back( wxString::Format( _( "Symbol %s is a derived symbol. Symbol graphics will "
1057 "not be editable." ),
1058 UnescapeString( symbolName ) ) );
1059
1060 // Don't assume the parent symbol shared pointer is still valid.
1061 if( std::shared_ptr<LIB_SYMBOL> rootSymbol = m_symbol->GetRootSymbol() )
1062 {
1063 int unit = GetUnit();
1064 int bodyStyle = GetBodyStyle();
1065 wxString rootSymbolName = rootSymbol->GetName();
1066 wxString link = wxString::Format( _( "Open %s" ), UnescapeString( rootSymbolName ) );
1067
1068 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( &infobar, wxID_ANY, link,
1069 wxEmptyString );
1070
1071 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
1072 [this, rootSymbolName, unit, bodyStyle]( wxHyperlinkEvent& aEvent )
1073 {
1074 LoadSymbolFromCurrentLib( rootSymbolName, unit, bodyStyle );
1075 } ) );
1076
1077 infobar.AddButton( button );
1078 }
1079 }
1080
1081 if( m_symbol
1083 && m_libMgr->IsLibraryReadOnly( m_symbol->GetLibId().GetFullLibraryName() ) )
1084 {
1085 msgs.push_back( _( "Library is read-only. Changes cannot be saved to this library." ) );
1086
1087 wxString link = wxString::Format( _( "Create an editable copy" ) );
1088 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( &infobar, wxID_ANY, link, wxEmptyString );
1089
1090 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
1091 [this, symbolName, libName]( wxHyperlinkEvent& aEvent )
1092 {
1093 wxString msg = wxString::Format( _( "Create an editable copy of the symbol or "
1094 "the entire library (%s)?" ),
1095 libName );
1096
1097 KIDIALOG errorDlg( this, msg, _( "Select type of item to save" ),
1098 wxYES_NO | wxCANCEL | wxICON_QUESTION );
1099 // These buttons are in a weird order(?)
1100 errorDlg.SetYesNoCancelLabels( _( "Copy symbol" ), _( "Cancel" ),
1101 _( "Copy library" ) );
1102
1103 int choice = errorDlg.ShowModal();
1104
1105 switch( choice )
1106 {
1107 case wxID_YES:
1108 SaveSymbolCopyAs( true );
1109 break;
1110 case wxID_CANCEL:
1111 SaveLibraryAs();
1112 break;
1113 default:
1114 // Do nothing
1115 break;
1116 }
1117 } ) );
1118
1119 infobar.AddButton( button );
1120 }
1121
1122 if( msgs.empty() )
1123 {
1124 infobar.Dismiss();
1125 }
1126 else
1127 {
1128 wxString msg = wxJoin( msgs, '\n', '\0' );
1129 infobar.ShowMessage( msg, infobarFlags );
1130 }
1131}
1132
1133
1139
1140
1142{
1144
1146
1147 if( !IsSymbolFromSchematic() )
1149
1150 if( m_isClosing )
1151 return;
1152
1153 // Clear preview so a later library-open gets its own tab instead of replacing this edited one.
1154 if( m_tabsPanel && m_activeTab )
1155 {
1156 m_activeTab->SetPreview( false );
1157
1158 if( int idx = m_tabsPanel->FindTab( m_activeTab->GetTabKey() ); idx >= 0 )
1159 m_tabsPanel->MarkModified( idx, true );
1160 }
1161
1163
1164 if( !GetTitle().StartsWith( "*" ) )
1165 UpdateTitle();
1166}
1167
1168
1170{
1171 wxCHECK( aUnit > 0 && aUnit <= GetCurSymbol()->GetUnitCount(), /* void*/ );
1172
1173 if( m_unit == aUnit )
1174 return;
1175
1178
1179 m_unit = aUnit;
1180
1181 if( m_unitSelectBox->GetSelection() != ( m_unit - 1 ) )
1182 m_unitSelectBox->SetSelection( m_unit - 1 );
1183
1185 RebuildView();
1187}
1188
1189
1191{
1192 wxCHECK( aBodyStyle > 0 && aBodyStyle <= GetCurSymbol()->GetBodyStyleCount(), /* void */ );
1193
1194 if( m_bodyStyle == aBodyStyle )
1195 return;
1196
1199
1200 m_bodyStyle = aBodyStyle;
1201
1202 if( m_bodyStyleSelectBox->GetSelection() != ( m_bodyStyle - 1 ) )
1203 m_bodyStyleSelectBox->SetSelection( m_bodyStyle - 1 );
1204
1205
1207 RebuildView();
1209}
1210
1211
1213{
1214 return m_SyncPinEdit && m_symbol && m_symbol->IsMultiUnit() && !m_symbol->UnitsLocked();
1215}
1216
1217
1218wxString SYMBOL_EDIT_FRAME::AddLibraryFile( bool aCreateNew )
1219{
1220 wxFileName fn = m_libMgr->GetUniqueLibraryName();
1221 bool useGlobalTable = true;
1222 FILEDLG_HOOK_NEW_LIBRARY tableChooser( useGlobalTable );
1223
1224 if( !LibraryFileBrowser( aCreateNew ? _( "New Symbol Library" ) : _( "Add Symbol Library" ),
1225 !aCreateNew, fn, FILEEXT::KiCadSymbolLibFileWildcard(),
1227 Pgm().GetSettingsManager().IsProjectOpenNotDummy() ? &tableChooser : nullptr ) )
1228 {
1229 return wxEmptyString;
1230 }
1231
1234
1235 LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
1236 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, scope );
1237
1238 wxCHECK( optTable.has_value(), wxEmptyString );
1239 LIBRARY_TABLE* table = optTable.value();
1240
1241 wxString libName = fn.GetName();
1242
1243 if( libName.IsEmpty() )
1244 return wxEmptyString;
1245
1247
1248 if( adapter->HasLibrary( libName ) )
1249 {
1250 DisplayError( this, wxString::Format( _( "Library '%s' already exists." ), libName ) );
1251 return wxEmptyString;
1252 }
1253
1254 if( aCreateNew )
1255 {
1256 // The file browser already asked to overwrite, so drop the old file here.
1257 // CreateLibrary fails on an existing path.
1258 if( fn.FileExists() && !wxRemoveFile( fn.GetFullPath() ) )
1259 {
1260 DisplayError( this, wxString::Format( _( "Could not overwrite the library file '%s'.\n"
1261 "Make sure you have write permissions and try again." ),
1262 fn.GetFullPath() ) );
1263 return wxEmptyString;
1264 }
1265
1266 if( !m_libMgr->CreateLibrary( fn.GetFullPath(), scope ) )
1267 {
1268 DisplayError( this, wxString::Format( _( "Could not create the library file '%s'.\n"
1269 "Make sure you have write permissions and try again." ),
1270 fn.GetFullPath() ) );
1271 return wxEmptyString;
1272 }
1273 }
1274 else
1275 {
1276 if( !m_libMgr->AddLibrary( fn.GetFullPath(), scope ) )
1277 {
1278 DisplayError( this, _( "Could not open the library file." ) );
1279 return wxEmptyString;
1280 }
1281 }
1282
1283 bool success = true;
1284
1285 // Tables are reinitialized by m_libMgr->AddLibrary(). So reinit table reference.
1286 optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, scope );
1287 wxCHECK( optTable.has_value(), wxEmptyString );
1288 table = optTable.value();
1289
1290 table->Save().map_error(
1291 [&]( const LIBRARY_ERROR& aError )
1292 {
1293 KICAD_MESSAGE_DIALOG dlg( this, _( "Error saving library table." ), _( "File Save Error" ),
1294 wxOK | wxICON_ERROR );
1295 dlg.SetExtendedMessage( aError.message );
1296 dlg.ShowModal();
1297
1298 success = false;
1299 } );
1300
1301 if( success )
1302 adapter->LoadOne( fn.GetName() );
1303
1304 SyncLibraries( false );
1305 SetCurLib( fn.GetName() );
1306
1307 if( m_treePane )
1308 {
1309 LIB_ID libId( fn.GetName(), wxEmptyString );
1310 GetLibTree()->SelectLibId( libId );
1311 GetLibTree()->CenterLibId( libId );
1312 }
1313
1314 return fn.GetFullPath();
1315}
1316
1317
1318void SYMBOL_EDIT_FRAME::DdAddLibrary( wxString aLibFile )
1319{
1320 wxFileName fn = wxFileName( aLibFile );
1321 wxString libName = fn.GetName();
1322
1323 if( libName.IsEmpty() )
1324 return;
1325
1326 LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
1328
1329 if( adapter->HasLibrary( libName ) )
1330 {
1331 DisplayError( this, wxString::Format( _( "Library '%s' already exists." ), libName ) );
1332 return;
1333 }
1334
1335 if( !m_libMgr->AddLibrary( fn.GetFullPath(), LIBRARY_TABLE_SCOPE::PROJECT ) )
1336 {
1337 DisplayError( this, _( "Could not open the library file." ) );
1338 return;
1339 }
1340
1341 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, LIBRARY_TABLE_SCOPE::PROJECT );
1342 wxCHECK( optTable.has_value(), /* void */ );
1343 LIBRARY_TABLE* table = optTable.value();
1344 bool success = true;
1345
1346 table->Save().map_error(
1347 [&]( const LIBRARY_ERROR& aError )
1348 {
1349 KICAD_MESSAGE_DIALOG dlg( this, _( "Error saving library table." ), _( "File Save Error" ),
1350 wxOK | wxICON_ERROR );
1351 dlg.SetExtendedMessage( aError.message );
1352 dlg.ShowModal();
1353
1354 success = false;
1355 } );
1356
1357 if( success )
1358 adapter->LoadOne( libName );
1359
1360 std::string packet = fn.GetFullPath().ToStdString();
1363}
1364
1365
1367{
1368 return GetLibTree()->GetSelectedLibId( aUnit );
1369}
1370
1371
1376
1377int SYMBOL_EDIT_FRAME::GetTreeLIBIDs( std::vector<LIB_ID>& aSelection ) const
1378{
1379 return GetLibTree()->GetSelectedLibIds( aSelection );
1380}
1381
1382
1384{
1385 if( IsLibraryTreeShown() )
1386 {
1387 LIB_ID libId = GetTreeLIBID();
1388
1389 if( libId.IsValid() )
1390 return m_libMgr->GetSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
1391 }
1392
1393 return m_symbol;
1394}
1395
1396
1398{
1399 LIB_ID id;
1400
1401 if( IsLibraryTreeShown() )
1402 id = GetTreeLIBID();
1403
1404 if( id.GetLibNickname().empty() && m_symbol )
1405 id = m_symbol->GetLibId();
1406
1407 return id;
1408}
1409
1410
1411std::vector<LIB_ID> SYMBOL_EDIT_FRAME::GetSelectedLibIds() const
1412{
1413 std::vector<LIB_ID> ids;
1414 GetTreeLIBIDs( ids );
1415 return ids;
1416}
1417
1418
1420{
1421 return GetTargetLibId().GetLibNickname();
1422}
1423
1424
1425void SYMBOL_EDIT_FRAME::SyncLibraries( bool aShowProgress, bool aPreloadCancelled,
1426 const wxString& aForceRefresh )
1427{
1428 wxLogTrace( wxT( "KICAD_TABS_DBG" ),
1429 wxT( "SYMBOL_EDIT_FRAME::SyncLibraries enter (progress=%d, forceRefresh='%s')" ),
1430 aShowProgress, aForceRefresh );
1431
1432 // Prevent re-entrant calls. The progress dialog yields the event loop during Sync(),
1433 // which can dispatch queued UI events (e.g. menu clicks queued while the app was busy
1434 // loading libraries). A re-entrant call would corrupt the library tree mid-rebuild.
1436 {
1437 wxLogTrace( wxT( "KICAD_TABS_DBG" ),
1438 wxT( "SYMBOL_EDIT_FRAME::SyncLibraries re-entrant; skipping" ) );
1439 return;
1440 }
1441
1443
1444 auto resetGuard = [this]( bool* )
1445 {
1447 };
1448
1449 std::unique_ptr<bool, decltype( resetGuard )> guard( &m_syncLibrariesInProgress, resetGuard );
1450
1451 LIB_ID selected;
1452 std::vector<LIB_ID> expanded;
1453
1454 if( m_treePane )
1455 {
1456 selected = GetLibTree()->GetSelectedLibId();
1457 expanded = GetLibTree()->GetExpandedLibraries();
1458 }
1459
1460 // Ensure any in-progress background library preloading is complete before syncing the
1461 // tree. Without this, libraries still in LOADING state get skipped by Sync(), resulting
1462 // in an incomplete tree that requires a manual refresh to fully populate.
1464 adapter->BlockUntilLoaded();
1465
1466 if( aShowProgress )
1467 {
1468 APP_PROGRESS_DIALOG progressDlg( _( "Loading Symbol Libraries" ), wxEmptyString,
1469 m_libMgr->GetAdapter()->GetLibrariesCount(), this );
1470
1471 THROTTLE progressThrottle( std::chrono::milliseconds( 350 ) );
1472 int pendingProgress = 0;
1473 bool callbackFired = false;
1474 wxString pendingLibName;
1475
1476 m_libMgr->Sync( aForceRefresh,
1477 [&]( int progress, int max, const wxString& libName )
1478 {
1479 pendingProgress = progress;
1480 pendingLibName = libName;
1481 callbackFired = true;
1482
1483 if( progressThrottle.Ready() )
1484 progressDlg.Update( progress, wxString::Format( _( "Loading library '%s'..." ), libName ) );
1485 } );
1486
1487 if( callbackFired )
1488 progressDlg.Update( pendingProgress, wxString::Format( _( "Loading library '%s'..." ), pendingLibName ) );
1489 }
1490 else if( !aPreloadCancelled )
1491 {
1492 m_libMgr->Sync( aForceRefresh, [&]( int progress, int max, const wxString& libName ) {} );
1493 }
1494
1495 if( m_treePane )
1496 {
1497 wxDataViewItem found;
1498
1499 if( selected.IsValid() )
1500 {
1501 // Check if the previously selected item is still valid,
1502 // if not - it has to be unselected to prevent crash
1503 found = m_libMgr->GetAdapter()->FindItem( selected );
1504
1505 if( !found )
1506 GetLibTree()->Unselect();
1507 }
1508
1509 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "SYMBOL_EDIT_FRAME::SyncLibraries Regenerate" ) );
1510 GetLibTree()->Regenerate( true );
1511
1512 // Sync() collapsed the tree, so re-expand the libraries that were open before it.
1513 for( const LIB_ID& libId : expanded )
1514 GetLibTree()->ExpandLibId( libId );
1515
1516 // Try to select the parent library, in case the symbol is not found
1517 if( !found && selected.IsValid() )
1518 {
1519 selected.SetLibItemName( "" );
1520 found = m_libMgr->GetAdapter()->FindItem( selected );
1521
1522 if( found )
1523 GetLibTree()->SelectLibId( selected );
1524 }
1525
1526 // If no selection, see if there's a current symbol to centre
1527 if( !selected.IsValid() && m_symbol )
1528 {
1529 LIB_ID current( GetCurLib(), m_symbol->GetName() );
1530 GetLibTree()->CenterLibId( current );
1531 }
1532 }
1533
1534 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "SYMBOL_EDIT_FRAME::SyncLibraries exit" ) );
1535}
1536
1537
1542
1543
1545{
1546 GetLibTree()->SelectLibId( aLibID );
1547}
1548
1549
1550void SYMBOL_EDIT_FRAME::UpdateLibraryTree( const wxDataViewItem& aTreeItem, LIB_SYMBOL* aSymbol )
1551{
1552 if( aTreeItem.IsOk() ) // Can be not found in tree if the current footprint is imported
1553 // from file therefore not yet in tree.
1554 {
1555 static_cast<LIB_TREE_NODE_ITEM*>( aTreeItem.GetID() )->Update( aSymbol );
1557 }
1558}
1559
1560
1561bool SYMBOL_EDIT_FRAME::backupFile( const wxFileName& aOriginalFile, const wxString& aBackupExt )
1562{
1563 if( aOriginalFile.FileExists() )
1564 {
1565 wxFileName backupFileName( aOriginalFile );
1566 backupFileName.SetExt( aBackupExt );
1567
1568 if( backupFileName.FileExists() )
1569 wxRemoveFile( backupFileName.GetFullPath() );
1570
1571 if( !wxCopyFile( aOriginalFile.GetFullPath(), backupFileName.GetFullPath() ) )
1572 {
1573 DisplayError( this, wxString::Format( _( "Failed to save backup to '%s'." ),
1574 backupFileName.GetFullPath() ) );
1575 return false;
1576 }
1577 }
1578
1579 return true;
1580}
1581
1582
1584{
1585 if( m_symbol && !GetCurLib().IsEmpty() && GetScreen()->IsContentModified() )
1586 m_libMgr->UpdateSymbol( m_symbol, GetCurLib() ); // UpdateSymbol() makes a copy
1587}
1588
1589
1591{
1592 // This will return the root symbol of any alias
1593 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aLibId.GetLibItemName(), aLibId.GetLibNickname() );
1594
1595 // Now we can compare the libId of the current symbol and the root symbol
1596 return ( symbol && m_symbol && symbol->GetLibId() == m_symbol->GetLibId() );
1597}
1598
1599
1601{
1602 GetLibTree()->Unselect();
1603 SetCurLib( wxEmptyString );
1604
1605 // Tear down every tab first so no context observes the about-to-be-deleted working symbol.
1607
1608 SetCurSymbol( nullptr, false );
1612 Refresh();
1613}
1614
1615
1617{
1619
1621 {
1622 GetRenderSettings()->m_ShowPinsElectricalType = cfg->m_ShowPinElectricalType;
1623 GetRenderSettings()->m_ShowHiddenPins = cfg->m_ShowHiddenPins;
1624 GetRenderSettings()->m_ShowHiddenFields = cfg->m_ShowHiddenFields;
1625 GetRenderSettings()->m_ShowPinAltIcons = cfg->m_ShowPinAltIcons;
1626
1627 GetGalDisplayOptions().ReadWindowSettings( cfg->m_Window );
1628 }
1629
1630 if( m_symbol )
1631 m_symbol->ClearCaches();
1632
1634
1636 GetCanvas()->Refresh();
1637
1639
1640 if( aFlags & ENVVARS_CHANGED )
1641 SyncLibraries( true );
1642
1643 Layout();
1644 SendSizeEvent();
1645}
1646
1647
1649{
1650 // call my base class
1652
1653 // tooltips in toolbars
1655
1656 // For some obscure reason, the AUI manager hides the first modified pane.
1657 // So force show panes
1658 wxAuiPaneInfo& tree_pane_info = m_auimgr.GetPane( m_treePane );
1659 bool tree_shown = tree_pane_info.IsShown();
1660 tree_pane_info.Caption( _( "Libraries" ) );
1661 tree_pane_info.Show( tree_shown );
1662 m_auimgr.Update();
1663
1665
1666 // status bar
1668
1669 if( GetRenderSettings()->m_ShowPinsElectricalType )
1670 {
1672 GetCanvas()->Refresh();
1673 }
1674
1675 UpdateTitle();
1676}
1677
1678
1680{
1681 SCH_BASE_FRAME::SetScreen( aScreen );
1682
1683 if( m_toolManager )
1684 {
1685 m_toolManager->SetEnvironment( aScreen, GetCanvas()->GetView(), GetCanvas()->GetViewControls(), GetSettings(),
1686 this );
1688 }
1689}
1690
1691
1709
1710
1712{
1713 SyncLibraries( true );
1714
1715 if( m_symbol )
1716 {
1717 SCH_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<SCH_SELECTION_TOOL>();
1718 SCH_SELECTION& selection = selectionTool->GetSelection();
1719
1720 for( SCH_ITEM& item : m_symbol->GetDrawItems() )
1721 {
1722 if( !alg::contains( selection, &item ) )
1723 item.ClearSelected();
1724 else
1725 item.SetSelected();
1726 }
1727
1728 m_symbol->ClearCaches();
1729 }
1730
1731 RebuildView();
1732}
1733
1734
1735const BOX2I SYMBOL_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
1736{
1737 if( !m_symbol )
1738 {
1739 // Gives a reasonable drawing area size
1740 int width = schIUScale.mmToIU( 50 );
1741 int height = schIUScale.mmToIU( 30 );
1742
1743 return BOX2I( VECTOR2I( -width/2, -height/2 ), VECTOR2I( width, height ) );
1744 }
1745 else
1746 {
1747 return m_symbol->Flatten()->GetUnitBoundingBox( m_unit, m_bodyStyle );
1748 }
1749}
1750
1751
1752void SYMBOL_EDIT_FRAME::FocusOnItem( EDA_ITEM* aItem, bool aAllowScroll )
1753{
1754 static KIID lastBrightenedItemID( niluuid );
1755
1756 SCH_ITEM* lastItem = nullptr;
1757
1758 // nullptr will clear the current focus
1759 if( aItem != nullptr && !aItem->IsSCH_ITEM() )
1760 return;
1761
1762 if( m_symbol )
1763 {
1764 for( SCH_PIN* pin : m_symbol->GetGraphicalPins( 0, 0 ) )
1765 {
1766 if( pin->m_Uuid == lastBrightenedItemID )
1767 lastItem = pin;
1768 }
1769
1770 std::vector<SCH_FIELD*> fields;
1771 m_symbol->GetFields( fields );
1772
1773 for( SCH_FIELD* field : fields )
1774 {
1775 if( field->m_Uuid == lastBrightenedItemID )
1776 lastItem = field;
1777 }
1778 }
1779
1780 if( lastItem && lastItem != aItem )
1781 {
1782 lastItem->ClearBrightened();
1783
1784 UpdateItem( lastItem );
1785 lastBrightenedItemID = niluuid;
1786 }
1787
1788 if( aItem )
1789 {
1790 if( aItem->IsSCH_ITEM() )
1791 {
1792 SCH_ITEM* item = static_cast<SCH_ITEM*>( aItem );
1793
1794 if( int unit = item->GetUnit() )
1795 SetUnit( unit );
1796
1797 if( int bodyStyle = item->GetBodyStyle() )
1798 SetBodyStyle( bodyStyle );
1799 }
1800
1801 if( !aItem->IsBrightened() )
1802 {
1803 aItem->SetBrightened();
1804
1805 UpdateItem( aItem );
1806 lastBrightenedItemID = aItem->m_Uuid;
1807 }
1808
1809 FocusOnLocation( VECTOR2I( aItem->GetFocusPosition().x, aItem->GetFocusPosition().y ), aAllowScroll );
1810 }
1811}
1812
1813
1815{
1816 const std::string& payload = mail.GetPayload();
1817
1818 wxLogTrace( wxT( "KICAD_TABS_DBG" ), wxT( "SYMBOL_EDIT_FRAME::KiwayMailIn cmd=%d" ),
1819 (int) mail.Command() );
1820
1821 switch( mail.Command() )
1822 {
1823 case MAIL_LIB_EDIT:
1824 if( !payload.empty() )
1825 {
1826 wxString uri( payload );
1827 wxString libNickname;
1828 wxString msg;
1829
1831 std::optional<const LIBRARY_TABLE_ROW*> libTableRow = adapter->FindRowByURI( uri );
1832
1833 if( !libTableRow )
1834 {
1835 msg.Printf( _( "The current configuration does not include the symbol library '%s'." ),
1836 uri );
1837 msg += wxS( "\n" ) + _( "Use Manage Symbol Libraries to edit the configuration." );
1838 DisplayErrorMessage( this, _( "Library not found in symbol library table." ), msg );
1839 break;
1840 }
1841
1842 libNickname = ( *libTableRow )->Nickname();
1843
1844 if( !adapter->HasLibrary( libNickname, true ) )
1845 {
1846 msg.Printf( _( "The symbol library '%s' is not enabled in the current configuration." ),
1847 UnescapeString( libNickname ) );
1848 msg += wxS( "\n" ) + _( "Use Manage Symbol Libraries to edit the configuration." );
1849 DisplayErrorMessage( this, _( "Symbol library not enabled." ), msg );
1850 break;
1851 }
1852
1853 SetCurLib( libNickname );
1854
1855 if( m_treePane )
1856 {
1857 LIB_ID id( libNickname, wxEmptyString );
1858 GetLibTree()->SelectLibId( id );
1859 GetLibTree()->ExpandLibId( id );
1860 GetLibTree()->CenterLibId( id );
1861 }
1862 }
1863
1864 break;
1865
1866 case MAIL_RELOAD_LIB:
1867 {
1868 wxLogTrace( wxT( "KICAD_TABS_DBG" ),
1869 wxT( "SYMBOL_EDIT_FRAME::KiwayMailIn MAIL_RELOAD_LIB -> SyncLibraries" ) );
1870
1871 wxString currentLib = GetCurLib();
1872
1874
1875 // Check if the currently selected symbol library been removed or disabled.
1876 if( !currentLib.empty()
1877 && !PROJECT_SCH::SymbolLibAdapter( &Prj() )->HasLibrary( currentLib, true ) )
1878 {
1879 SetCurLib( wxEmptyString );
1880 emptyScreen();
1881 }
1882
1883 // Suppress the progress dialog for this background reload. It would steal focus from the
1884 // editor that broadcast the reload, and the tree is already frozen around the sync.
1885 SyncLibraries( false );
1888
1889 break;
1890 }
1891
1893 {
1895 LIB_SYMBOL* symbol = GetCurSymbol();
1896
1897 wxLogTrace( traceLibWatch, "Received refresh symbol request for %s", payload );
1898
1899 if( !symbol )
1900 break;
1901
1902 // Capture the name now. UpdateLibraryBuffer() recreates the buffer, so reading it from the
1903 // buffer copy afterwards would be a use-after-free.
1904 const wxString refreshSymbolName = symbol->GetName();
1905
1906 // If the frame is disabled then a modal/quasi-modal dialog (such as the symbol properties dialog) is
1907 // editing the current LIB_SYMBOL. Refreshing it here would delete the symbol out from under the dialog
1908 // and crash on dismissal. The file watcher timer will retry the reload once the dialog has closed.
1909 if( !IsEnabled() )
1910 {
1911 wxLogTrace( traceLibWatch, "Deferring symbol refresh; dialog is open on the symbol editor." );
1912 break;
1913 }
1914 // Defensive backstop for refresh mail that did not originate from this frame's debounce
1915 // timer (which already defers while a tool is active). An interactive tool holds
1916 // references into the current symbol, so replacing it here would crash; drop this refresh
1917 // and let the originating watcher retry.
1918 else if( !ToolStackIsEmpty() )
1919 {
1920 wxLogTrace( traceLibWatch, "Deferring symbol refresh; an interactive tool is active." );
1921 break;
1922 }
1923
1924 wxString libName = symbol->GetLibId().GetLibNickname();
1925 std::optional<const LIBRARY_TABLE_ROW*> row = adapter->GetRow( libName );
1926
1927 if( !row )
1928 return;
1929
1930 wxFileName libfullname( LIBRARY_MANAGER::GetFullURI( *row, true ) );
1931
1932 wxFileName changedLib( mail.GetPayload() );
1933
1934 wxLogTrace( traceLibWatch, "Received refresh symbol request for %s, current symbols is %s",
1935 changedLib.GetFullPath(), libfullname.GetFullPath() );
1936
1937 if( changedLib == libfullname )
1938 {
1939 wxLogTrace( traceLibWatch, "Refreshing symbol %s", refreshSymbolName );
1940
1941 m_libMgr->UpdateLibraryBuffer( libName );
1942
1943 if( LIB_SYMBOL* lib_symbol = m_libMgr->GetBufferedSymbol( refreshSymbolName, libName ) )
1944 {
1945 SetCurSymbol( new LIB_SYMBOL( *lib_symbol ), false );
1947
1948 if( m_toolManager )
1950 }
1951 }
1952
1953 break;
1954 }
1955
1956 default:
1957 break;
1958 }
1959}
1960
1961
1962std::unique_ptr<GRID_HELPER> SYMBOL_EDIT_FRAME::MakeGridHelper()
1963{
1964 return std::make_unique<EE_GRID_HELPER>( m_toolManager );
1965}
1966
1967
1969{
1970 // switches currently used canvas ( Cairo / OpenGL):
1971 SCH_BASE_FRAME::SwitchCanvas( aCanvasType );
1972
1973 // Set options specific to symbol editor (axies are always enabled):
1974 GetCanvas()->GetGAL()->SetAxesEnabled( true );
1976}
1977
1978
1980{
1981 wxCHECK( m_libMgr, false );
1982
1983 return m_libMgr->HasModifications();
1984}
1985
1986
1988{
1989 wxCHECK( m_libMgr, false );
1990
1991 // Test if the currently edited symbol is modified
1993 return true;
1994
1995 // Test if any library has been modified
1996 for( const wxString& libName : m_libMgr->GetLibraryNames() )
1997 {
1998 if( m_libMgr->IsLibraryModified( libName ) && !m_libMgr->IsLibraryReadOnly( libName ) )
1999 return true;
2000 }
2001
2002 return false;
2003}
2004
2005
2007{
2008 if( aItemCount == 0 )
2009 return;
2010
2011 UNDO_REDO_CONTAINER& list = ( whichList == UNDO_LIST ) ? m_undoList : m_redoList;
2012
2013 // UR_TRANSIENT is flagged on the picked item, not the wrapper, so the shared deleters miss it.
2014 // Free the items carrying UR_TRANSIENT. m_symbol never carries it, so the live copy is safe.
2015 if( aItemCount < 0 )
2016 {
2018 }
2019 else
2020 {
2021 for( int ii = 0; ii < aItemCount; ii++ )
2022 {
2023 if( list.m_CommandsList.size() == 0 )
2024 break;
2025
2026 PICKED_ITEMS_LIST* curr_cmd = list.m_CommandsList[0];
2027 list.m_CommandsList.erase( list.m_CommandsList.begin() );
2028
2029 for( unsigned jj = 0; jj < curr_cmd->GetCount(); ++jj )
2030 {
2031 EDA_ITEM* item = curr_cmd->GetPickedItem( jj );
2032
2033 if( item && item->HasFlag( UR_TRANSIENT ) && item != m_symbol )
2034 delete item;
2035 }
2036
2037 curr_cmd->ClearItemsList();
2038 delete curr_cmd; // Delete command
2039 }
2040 }
2041}
2042
2043
2045{
2046 return m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
2047}
2048
2049
2051{
2052 std::unique_ptr<LIB_SYMBOL> symbol = aSymbol->GetLibSymbolRef()->Flatten();
2053 wxCHECK( symbol, /* void */ );
2054
2055 symbol->SetLibId( aSymbol->GetLibId() );
2056
2057 // Take in account the symbol orientation and mirroring. to calculate the field
2058 // positions in symbol editor (i.e. no rotation, no mirroring)
2059 int orientation = aSymbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y );
2060 int mirror = aSymbol->GetOrientation() & ( SYM_MIRROR_X | SYM_MIRROR_Y );
2061
2062 std::vector<SCH_FIELD> fullSetOfFields;
2063
2064 for( const SCH_FIELD& field : aSymbol->GetFields() )
2065 {
2066 VECTOR2I pos = field.GetPosition() - aSymbol->GetPosition();
2067 SCH_FIELD libField( symbol.get(), field.GetId() );
2068
2069 libField = field;
2070
2071 // The inverse transform is mirroring before, rotate after
2072 switch( mirror )
2073 {
2074 case SYM_MIRROR_X: pos.y = -pos.y; break;
2075 case SYM_MIRROR_Y: pos.x = -pos.x; break;
2076 default: break;
2077 }
2078
2079 switch( orientation )
2080 {
2081 case SYM_ORIENT_90:
2082 std::swap( pos.x, pos.y );
2083 pos.x = - pos.x;
2084 break;
2085 case SYM_ORIENT_270:
2086 std::swap( pos.x, pos.y );
2087 pos.y = - pos.y;
2088 break;
2089 case SYM_ORIENT_180:
2090 pos.x = - pos.x;
2091 pos.y = - pos.y;
2092 break;
2093 default:
2094 break;
2095 }
2096
2097 libField.SetPosition( pos );
2098
2099 fullSetOfFields.emplace_back( std::move( libField ) );
2100 }
2101
2102 symbol->SetFields( fullSetOfFields );
2103
2104 const wxString reference = symbol->GetReferenceField().GetText();
2105 const int unit = std::max( 1, aSymbol->GetUnit() );
2106 const int bodyStyle = std::max( 1, aSymbol->GetBodyStyle() );
2107
2108 // Optimize default edit options for this symbol
2109 // Usually if units are locked, graphic items are specific to each unit
2110 // and if units are interchangeable, graphic items are common to units
2112 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
2113
2114 // Hand the transient working symbol/screen to a session-only instance tab, whose activation
2115 // restores the frame's schematic-source state so the save path routes back to the schematic.
2116 SCH_SCREEN* tmpScreen = new SCH_SCREEN();
2117
2118 setSymWatcher( nullptr );
2119
2120 SYMBOL_EDITOR_TAB_CONTEXT* ctx = findOrCreateSymbolInstanceTab( symbol.release(), tmpScreen,
2121 aSymbol->m_Uuid, reference, unit,
2122 bodyStyle );
2123 wxCHECK( ctx, /* void */ );
2124
2127
2128 if( IsLibraryTreeShown() )
2130
2131 UpdateTitle();
2134
2135 // Let tools add things to the view if necessary
2136 if( m_toolManager )
2138
2140 GetCanvas()->Refresh();
2141}
2142
2143
2144bool SYMBOL_EDIT_FRAME::addLibTableEntry( const wxString& aLibFile, LIBRARY_TABLE_SCOPE aScope )
2145{
2146 wxFileName fn = aLibFile;
2147 wxFileName libTableFileName( Prj().GetProjectPath(), FILEEXT::SymbolLibraryTableFileName );
2148 wxString libNickname = fn.GetName();
2150 LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
2151 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
2152
2153 if( adapter->HasLibrary( libNickname ) )
2154 {
2155 wxString tmp;
2156 int suffix = 1;
2157
2158 while( adapter->HasLibrary( libNickname ) )
2159 {
2160 tmp.Printf( "%s%d", fn.GetName(), suffix );
2161 libNickname = tmp;
2162 suffix += 1;
2163 }
2164 }
2165
2166 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, aScope );
2167 wxCHECK( optTable.has_value(), false );
2168 LIBRARY_TABLE* table = optTable.value();
2169
2170 LIBRARY_TABLE_ROW* row = &table->InsertRow();
2171
2172 row->SetNickname( libNickname );
2173
2174 // We cannot normalize against the current project path when saving to global table.
2175 wxString normalizedPath = NormalizePath( aLibFile, &envVars,
2176 aScope == LIBRARY_TABLE_SCOPE::PROJECT ? Prj().GetProjectPath()
2177 : wxString( wxEmptyString ) );
2178
2179 row->SetURI( normalizedPath );
2181
2182 bool success = true;
2183
2184 table->Save().map_error(
2185 [&]( const LIBRARY_ERROR& aError )
2186 {
2187 KICAD_MESSAGE_DIALOG dlg( this, _( "Error saving library table." ), _( "File Save Error" ),
2188 wxOK | wxICON_ERROR );
2189 dlg.SetExtendedMessage( aError.message );
2190 dlg.ShowModal();
2191
2192 success = false;
2193 } );
2194
2195 if( success )
2196 {
2197 manager.ReloadTables( aScope, { LIBRARY_TABLE_TYPE::SYMBOL } );
2198 adapter->LoadOne( libNickname );
2199 }
2200
2201 return success;
2202}
2203
2204
2205bool SYMBOL_EDIT_FRAME::replaceLibTableEntry( const wxString& aLibNickname, const wxString& aLibFile )
2206{
2208 LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
2209 LIBRARY_TABLE* table = nullptr;
2211
2212 // Check the global library table first because checking the project library table
2213 // checks the global library table as well due to library chaining.
2214 if( adapter->GetRow( aLibNickname, scope ) )
2215 {
2216 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, scope );
2217 wxCHECK( optTable.has_value(), false );
2218 table = optTable.value();
2219 }
2220 else
2221 {
2223
2224 if( adapter->GetRow( aLibNickname, scope ) )
2225 {
2226 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL, scope );
2227
2228 if( optTable.has_value() )
2229 table = optTable.value();
2230 }
2231 }
2232
2233 wxCHECK( table, false );
2234
2235 std::optional<LIBRARY_TABLE_ROW*> optRow = adapter->GetRow( aLibNickname, scope );
2236 wxCHECK( optRow.has_value(), false );
2237 LIBRARY_TABLE_ROW* row = optRow.value();
2238
2239 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
2240
2241 wxString projectPath;
2242
2243 if( scope == LIBRARY_TABLE_SCOPE::PROJECT )
2244 projectPath = Prj().GetProjectPath();
2245
2246 wxString normalizedPath = NormalizePath( aLibFile, &envVars, projectPath );
2247
2248 row->SetURI( normalizedPath );
2249 row->SetType( "KiCad" );
2250
2251 bool success = true;
2252
2253 table->Save().map_error(
2254 [&]( const LIBRARY_ERROR& aError )
2255 {
2256 KICAD_MESSAGE_DIALOG dlg( this, _( "Error saving library table." ), _( "File Save Error" ),
2257 wxOK | wxICON_ERROR );
2258 dlg.SetExtendedMessage( aError.message );
2259 dlg.ShowModal();
2260
2261 success = false;
2262 } );
2263
2264 if( success )
2265 {
2266 manager.ReloadTables( scope, { LIBRARY_TABLE_TYPE::SYMBOL } );
2267 adapter->LoadOne( aLibNickname );
2268 }
2269
2270 return success;
2271}
2272
2273
2275{
2276 return m_symbol && !m_symbol->IsRoot();
2277}
2278
2279
2284
2285
2286void SYMBOL_EDIT_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete, bool aUpdateRtree )
2287{
2288 SCH_BASE_FRAME::UpdateItem( aItem, isAddOrDelete, aUpdateRtree );
2289
2290 if( EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( aItem ) )
2291 {
2292 eda_text->ClearBoundingBoxCache();
2293 eda_text->ClearRenderCache();
2294 }
2295}
2296
2297
2299{
2300 wxAuiPaneInfo& treePane = m_auimgr.GetPane( m_treePane );
2301 wxAuiPaneInfo& propertiesPane = m_auimgr.GetPane( PropertiesPaneName() );
2302 wxAuiPaneInfo& selectionFilterPane = m_auimgr.GetPane( wxS( "SelectionFilter" ) );
2303
2304 // Don't give the selection filter its own visibility controls; instead show it if
2305 // anything else is visible
2306 bool showFilter = ( treePane.IsShown() && treePane.IsDocked() )
2307 || ( propertiesPane.IsShown() && propertiesPane.IsDocked() );
2308
2309 selectionFilterPane.Show( showFilter );
2310}
2311
2312
2314{
2315 // Returns the current render option for invisible fields
2317}
2318
2319
2321{
2322 // Returns the current render option for invisible pins
2324}
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:918
BOX2< VECTOR2D > BOX2D
Definition box2.h:919
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:233
constexpr void SetSize(const SizeVec &size)
Definition box2.h:244
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
EDA_DRAW_PANEL_GAL::GAL_TYPE m_canvasType
The current canvas type.
void OnSelectGrid(wxCommandEvent &event)
Command event handler for selecting grid sizes.
void setupUnits(APP_SETTINGS_BASE *aCfg)
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:96
virtual const VECTOR2I GetFocusPosition() const
Similar to GetPosition() but allows items to return their visual center rather than their anchor.
Definition eda_item.h:289
const KIID m_Uuid
Definition eda_item.h:531
void ClearBrightened()
Definition eda_item.h:148
void SetBrightened()
Definition eda_item.h:145
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition eda_item.h:156
bool IsBrightened() const
Definition eda_item.h:134
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:89
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.
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:266
void ClearHiddenFlags()
Clear the hide flag of all items in the view.
Definition sch_view.cpp:254
bool IsSCH_ITEM() const
Definition view_item.h:97
void Clear()
Remove all items from the view.
Definition view.cpp:1218
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:1686
Definition kiid.h:44
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:311
void OnKiCadExit()
Definition kiway.cpp:796
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:398
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:496
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:107
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:79
const LIB_ID & GetLibId() const override
Definition lib_symbol.h:148
bool UnitsLocked() const
Check whether symbol units are interchangeable.
Definition lib_symbol.h:283
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition lib_symbol.h:195
wxString GetName() const override
Definition lib_symbol.h:141
bool IsMultiUnit() const override
Definition lib_symbol.h:767
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:774
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:124
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:126
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.
@ SCH_LIBEDIT_CUR_LIB
Definition project.h:218
@ SCH_LIBEDIT_CUR_SYMBOL
Definition project.h:219
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:183
virtual void SetRString(RSTRING_T aStringId, const wxString &aString)
Store a "retained string", which is any session and project specific string identified in enum RSTRIN...
Definition project.cpp:355
virtual const wxString & GetRString(RSTRING_T aStringId)
Return a "retained string", which is any session and project specific string identified in enum RSTRI...
Definition project.cpp:366
Action handler for the Properties panel.
Gather all the actions that are shared by tools.
Definition sch_actions.h:36
static TOOL_ACTION rotateCCW
static TOOL_ACTION importSymbol
static TOOL_ACTION newSymbol
static TOOL_ACTION saveLibraryAs
static TOOL_ACTION mirrorV
static TOOL_ACTION drawEllipseArc
Definition sch_actions.h:94
static TOOL_ACTION editLibSymbolWithLibEdit
static TOOL_ACTION drawArc
Definition sch_actions.h:95
static TOOL_ACTION pinTable
static TOOL_ACTION drawSymbolLines
static TOOL_ACTION placeSymbolPin
static TOOL_ACTION drawSymbolTextBox
static TOOL_ACTION drawRectangle
Definition sch_actions.h:91
static TOOL_ACTION drawEllipse
Definition sch_actions.h:93
static TOOL_ACTION drawCircle
Definition sch_actions.h:92
static TOOL_ACTION importGraphics
static TOOL_ACTION drawBezier
Definition sch_actions.h:96
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.
void 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:162
int GetBodyStyle() const
Definition sch_item.h:242
int GetUnit() const
Definition sch_item.h:233
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:69
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:885
const LIB_ID & GetLibId() const override
Definition sch_symbol.h:158
int GetOrientation() const override
Get the display symbol orientation.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition sch_symbol.h:177
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.
bool m_ShowPinAltIcons
When true, dragging an outline edge will drag pins rooted on it.
One open symbol tab owning a working LIB_SYMBOL and screen lent to the frame while active.
bool IsModified() const override
True when the working screen carries unsaved edits.
The symbol library editor main window.
std::vector< std::unique_ptr< SYMBOL_EDITOR_TAB_CONTEXT > > m_tabContexts
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 (schematic) tab that is not the active one, since the active tab's...
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.
void storeCurrentSymbol()
Rename LIB_SYMBOL aliases to avoid conflicts before adding a symbol to a library.
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 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
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
wxString GetCurLib() const
The nickname of the current library being edited and empty string if none.
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.
bool m_SyncPinEdit
Set to true to synchronize pins at the same position when editing symbols with multiple units or mult...
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)
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)
int m_bodyStyle
Flag if the symbol being edited was loaded directly from a schematic.
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
wxString SetCurLib(const wxString &aLibNickname)
Set the current library nickname and returns the old library nickname.
void UpdateTitle()
Update the main window title bar with the current library name and read only status of the library.
bool LoadSymbolFromCurrentLib(const wxString &aSymbolName, int aUnit=0, int aBodyStyle=0)
Load a symbol from the current active library, optionally setting the selected unit and convert.
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 LoadSymbolFromSchematic(SCH_SYMBOL *aSymbol)
Load a symbol from the schematic to edit in place.
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:77
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
void AddButton(wxButton *aButton)
Add an already created button to the infobar.
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
int UnsavedChangesDialog(wxWindow *parent, const wxString &aMessage, bool *aApplyToAll)
A specialized version of HandleUnsavedChanges which handles an apply-to-all checkbox.
Definition confirm.cpp:60
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 wxString KiCadSymbolLibFileWildcard()
const wxChar *const traceLibWatch
Flag to enable debug output for library file watch refreshes.
@ ID_ON_GRID_SELECT
Definition id.h:112
@ ID_ON_ZOOM_SELECT
Definition id.h:111
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
PROJECT & Prj()
Definition kicad.cpp:730
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:485
LIBRARY_TABLE_SCOPE
@ MAIL_LIB_EDIT
Definition mail_type.h:52
@ MAIL_REFRESH_SYMBOL
Definition mail_type.h:56
@ MAIL_RELOAD_LIB
Definition mail_type.h:54
@ 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
#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
std::vector< std::vector< std::string > > table
#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.