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, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <bitmaps.h>
27#include <wx/hyperlink.h>
28#include <base_screen.h>
29#include <confirm.h>
30#include <core/kicad_algo.h>
31#include <eeschema_id.h>
32#include <eeschema_settings.h>
33#include <env_paths.h>
35#include <kidialog.h>
36#include <kiface_base.h>
37#include <kiplatform/app.h>
38#include <kiway_express.h>
39#include <symbol_edit_frame.h>
42#include <paths.h>
43#include <pgm_base.h>
44#include <project_sch.h>
45#include <sch_painter.h>
46#include <sch_view.h>
49#include <tool/action_manager.h>
50#include <tool/action_toolbar.h>
51#include <tool/common_control.h>
52#include <tool/common_tools.h>
54#include <tool/embed_tool.h>
56#include <tool/picker_tool.h>
58#include <tool/selection.h>
60#include <tool/tool_manager.h>
61#include <tool/zoom_tool.h>
62#include <tools/sch_actions.h>
73#include <view/view_controls.h>
75#include <widgets/wx_infobar.h>
83#include <panel_sym_lib_table.h>
84#include <string_utils.h>
86#include <wx/msgdlg.h>
87#include <wx/combobox.h>
88#include <wx/log.h>
89#include <trace_helpers.h>
90
91
93
94
95BEGIN_EVENT_TABLE( SYMBOL_EDIT_FRAME, SCH_BASE_FRAME )
98
99 // menubar commands
100 EVT_MENU( wxID_EXIT, SYMBOL_EDIT_FRAME::OnExitKiCad )
101 EVT_MENU( wxID_CLOSE, SYMBOL_EDIT_FRAME::CloseWindow )
102
103 // Update user interface elements.
106
107 // Drop files event
108 EVT_DROP_FILES( SYMBOL_EDIT_FRAME::OnDropFiles )
109
110END_EVENT_TABLE()
111
112
113SYMBOL_EDIT_FRAME::SYMBOL_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
114 SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_SYMBOL_EDITOR, _( "Library Editor" ),
115 wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE,
117 m_unitSelectBox( nullptr ),
118 m_bodyStyleSelectBox( nullptr ),
120{
121 m_SyncPinEdit = false;
122
123 m_symbol = nullptr;
124 m_treePane = nullptr;
125 m_libMgr = nullptr;
126 m_unit = 1;
127 m_bodyStyle = 1;
128 m_aboutTitle = _HKI( "KiCad Symbol Editor" );
129
130 wxIcon icon;
131 wxIconBundle icon_bundle;
132
133 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit, 48 ) );
134 icon_bundle.AddIcon( icon );
135 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit, 256 ) );
136 icon_bundle.AddIcon( icon );
137 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit, 128 ) );
138 icon_bundle.AddIcon( icon );
139 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit_32 ) );
140 icon_bundle.AddIcon( icon );
141 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_libedit_16 ) );
142 icon_bundle.AddIcon( icon );
143
144 SetIcons( icon_bundle );
145
148
150
151 m_treePane = new SYMBOL_TREE_PANE( this, m_libMgr );
152 m_treePane->GetLibTree()->SetSortMode( (LIB_TREE_MODEL_ADAPTER::SORT_MODE) m_settings->m_LibrarySortMode );
153
156
157 // Ensure axis are always drawn
159 gal_opts.m_axesEnabled = true;
160
163 GetScreen()->m_Center = true;
164
165 GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
166
167 GetRenderSettings()->LoadColors( GetColorSettings() );
168 GetRenderSettings()->m_IsSymbolEditor = true;
169 GetCanvas()->GetGAL()->SetAxesColor( m_colorSettings->GetColor( LAYER_SCHEMATIC_GRID_AXES ) );
170
171 setupTools();
173
175
179
180 UpdateTitle();
183
184 m_propertiesPanel = new SCH_PROPERTIES_PANEL( this, this );
185 m_propertiesPanel->SetSplitterProportion( m_settings->m_AuiPanels.properties_splitter );
186
188
189 m_auimgr.SetManagedWindow( this );
190
192
193 // Rows; layers 4 - 6
194 m_auimgr.AddPane( m_tbTopMain, EDA_PANE().HToolbar().Name( "TopMainToolbar" )
195 .Top().Layer( 6 ) );
196
197 m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( "MsgPanel" )
198 .Bottom().Layer( 6 ) );
199
200 m_auimgr.AddPane( m_tbLeft, EDA_PANE().VToolbar().Name( "LeftToolbar" )
201 .Left().Layer( 2 ) );
202
203 m_auimgr.AddPane( m_tbRight, EDA_PANE().VToolbar().Name( "RightToolbar" )
204 .Right().Layer( 2 ) );
205
206 // Center
207 m_auimgr.AddPane( GetCanvas(), wxAuiPaneInfo().Name( "DrawFrame" )
208 .CentrePane() );
209
210 // Columns; layers 1 - 3
211 m_auimgr.AddPane( m_treePane, EDA_PANE().Palette().Name( "LibraryTree" )
212 .Left().Layer( 3 )
213 .TopDockable( false ).BottomDockable( false )
214 .Caption( _( "Libraries" ) )
215 .MinSize( FromDIP( 250 ), -1 ).BestSize( FromDIP( 250 ), -1 ) );
216
219
220 // Can be called only when all panes are created, because (at least on Windows) when items
221 // managed by m_auimgr are not the same as those existing when saved by Perspective()
222 // in config, broken settings can happen.
224
225 // Protect against broken saved Perspective() due to bugs in previous version
226 // This is currently a workaround.
227 m_auimgr.GetPane( "TopMainToolbar" ).Top().Layer( 6 ).Position(0).Show( true );
228 m_auimgr.GetPane( "LeftToolbar" ).Position(0).Show( true );
229 m_auimgr.GetPane( "RightToolbar" ).Show( true );
230
231 // Show or hide m_propertiesPanel depending on current settings:
232 wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
233 wxAuiPaneInfo& selectionFilterPane = m_auimgr.GetPane( wxS( "SelectionFilter" ) );
234 // The selection filter doesn't need to grow in the vertical direction when docked
235 selectionFilterPane.dock_proportion = 0;
236
237 propertiesPaneInfo.Show( m_settings->m_AuiPanels.show_properties );
239
241
242 // Can't put this in LoadSettings, because it has to be called before setupTools :/
244 selTool->GetFilter() = GetSettings()->m_SelectionFilter;
245 m_selectionFilterPanel->SetCheckboxesFromFilter( selTool->GetFilter() );
246
247 if( m_settings->m_LibWidth > 0 )
248 SetAuiPaneSize( m_auimgr, m_auimgr.GetPane( "LibraryTree" ), m_settings->m_LibWidth, -1 );
249
250 Raise();
251 Show( true );
252
253 SyncView();
254 GetCanvas()->GetView()->UseDrawPriority( true );
255 GetCanvas()->GetGAL()->SetAxesEnabled( true );
256
258
259 // Set the working/draw area size to display a symbol to a reasonable value:
260 // A 600mm x 600mm with a origin at the area center looks like a large working area
261 double max_size_x = schIUScale.mmToIU( 600 );
262 double max_size_y = schIUScale.mmToIU( 600 );
263 BOX2D bbox;
264 bbox.SetOrigin( -max_size_x /2, -max_size_y/2 );
265 bbox.SetSize( max_size_x, max_size_y );
266 GetCanvas()->GetView()->SetBoundary( bbox );
267
269
271 DragAcceptFiles( true );
272
273 KIPLATFORM::APP::SetShutdownBlockReason( this, _( "Library changes are unsaved" ) );
274
275 // Catch unhandled accelerator command characters that were no handled by the library tree
276 // panel.
278 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
279
280 // Ensure the window is on top
281 Raise();
282
283 // run SyncLibraries with progress reporter enabled. The progress reporter is useful
284 // in debug mode because the loading time of ecah library can be really noticeable
285 SyncLibraries( true );
286}
287
288
290{
291 // Shutdown all running tools
292 if( m_toolManager )
293 m_toolManager->ShutdownAllTools();
294
295 setSymWatcher( nullptr );
296
298 {
299 delete m_symbol;
300 m_symbol = nullptr;
301
302 SCH_SCREEN* screen = GetScreen();
303 delete screen;
305 }
306
307 // current screen is destroyed in EDA_DRAW_FRAME
309
311 Pgm().GetSettingsManager().Save( cfg );
312
313 delete m_libMgr;
314}
315
316
318{
319 wxCHECK_RET( m_settings, "Call to SYMBOL_EDIT_FRAME::LoadSettings with null m_settings" );
320
322
323 GetRenderSettings()->m_ShowPinsElectricalType = m_settings->m_ShowPinElectricalType;
324 GetRenderSettings()->m_ShowHiddenPins = m_settings->m_ShowHiddenPins;
325 GetRenderSettings()->m_ShowHiddenFields = m_settings->m_ShowHiddenFields;
326 GetRenderSettings()->m_ShowPinAltIcons = m_settings->m_ShowPinAltIcons;
327 GetRenderSettings()->SetDefaultFont( wxEmptyString );
328}
329
330
332{
333 wxCHECK_RET( m_settings, "Call to SYMBOL_EDIT_FRAME:SaveSettings with null m_settings" );
334
336
338
339 m_settings->m_ShowPinElectricalType = GetRenderSettings()->m_ShowPinsElectricalType;
340 m_settings->m_ShowHiddenPins = GetRenderSettings()->m_ShowHiddenPins;
341 m_settings->m_ShowHiddenFields = GetRenderSettings()->m_ShowHiddenFields;
342 m_settings->m_ShowPinAltIcons = GetRenderSettings()->m_ShowPinAltIcons;
343
344 m_settings->m_LibWidth = m_treePane->GetSize().x;
345
346 m_settings->m_LibrarySortMode = GetLibTree()->GetSortMode();
347
348 m_settings->m_AuiPanels.properties_splitter = m_propertiesPanel->SplitterProportion();
349 bool prop_shown = m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
350 m_settings->m_AuiPanels.show_properties = prop_shown;
351
353 m_settings->m_SelectionFilter = selTool->GetFilter();
354}
355
356
358{
359 return static_cast<APP_SETTINGS_BASE*>( GetSettings() );
360}
361
362
364{
366
367 if( cfg && static_cast<SYMBOL_EDITOR_SETTINGS*>( cfg )->m_UseEeschemaColorSettings )
368 cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
369
370 return ::GetColorSettings( cfg ? cfg->m_ColorTheme : DEFAULT_THEME );
371}
372
373
375{
376 // Create the manager and dispatcher & route draw panel events to the dispatcher
378 m_toolManager->SetEnvironment( GetScreen(), GetCanvas()->GetView(),
379 GetCanvas()->GetViewControls(), GetSettings(), this );
380 m_actions = new SCH_ACTIONS();
382
383 // Register tools
384 m_toolManager->RegisterTool( new COMMON_CONTROL );
385 m_toolManager->RegisterTool( new COMMON_TOOLS );
386 m_toolManager->RegisterTool( new ZOOM_TOOL );
387 m_toolManager->RegisterTool( new SCH_SELECTION_TOOL );
388 m_toolManager->RegisterTool( new PICKER_TOOL );
389 m_toolManager->RegisterTool( new SCH_INSPECTION_TOOL );
390 m_toolManager->RegisterTool( new SYMBOL_EDITOR_PIN_TOOL );
391 m_toolManager->RegisterTool( new SYMBOL_EDITOR_DRAWING_TOOLS );
392 m_toolManager->RegisterTool( new SCH_POINT_EDITOR );
393 m_toolManager->RegisterTool( new SCH_FIND_REPLACE_TOOL );
394 m_toolManager->RegisterTool( new SYMBOL_EDITOR_MOVE_TOOL );
395 m_toolManager->RegisterTool( new SYMBOL_EDITOR_EDIT_TOOL );
396 m_toolManager->RegisterTool( new LIBRARY_EDITOR_CONTROL );
397 m_toolManager->RegisterTool( new SYMBOL_EDITOR_CONTROL );
398 m_toolManager->RegisterTool( new PROPERTIES_TOOL );
399 m_toolManager->RegisterTool( new EMBED_TOOL );
400 m_toolManager->InitTools();
401
402 // Run the selection tool, it is supposed to be always active
403 m_toolManager->InvokeTool( "common.InteractiveSelection" );
404
406}
407
408
410{
412
413 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
414 EDITOR_CONDITIONS cond( this );
415
416 wxASSERT( mgr );
417
418#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
419#define CHECK( x ) ACTION_CONDITIONS().Check( x )
420
421 auto haveSymbolCond =
422 [this]( const SELECTION& )
423 {
424 return m_symbol;
425 };
426
427 auto isEditableCond =
428 [this]( const SELECTION& )
429 {
430 // Only root symbols from the new s-expression libraries or the schematic
431 // are editable.
432 return IsSymbolEditable() && !IsSymbolAlias();
433 };
434
435 auto isEditableInAliasCond =
436 [this]( const SELECTION& )
437 {
438 // Less restrictive than isEditableCond
439 // Symbols fields (root symbols and aliases) from the new s-expression libraries
440 // or in the schematic are editable.
441 return IsSymbolEditable();
442 };
443
444 auto symbolModifiedCondition =
445 [this]( const SELECTION& sel )
446 {
447 return m_libMgr && m_libMgr->IsSymbolModified( GetTargetLibId().GetLibItemName(),
448 GetTargetLibId().GetLibNickname() );
449 };
450
451 auto libSelectedCondition =
452 [this]( const SELECTION& sel )
453 {
454 return !GetTargetLibId().GetLibNickname().empty();
455 };
456
457 auto canEditProperties =
458 [this]( const SELECTION& sel )
459 {
461 };
462
463 auto symbolSelectedInTreeCondition =
464 [this]( const SELECTION& sel )
465 {
466 LIB_ID targetLibId = GetTargetLibId();
467 return !targetLibId.GetLibNickname().empty() && !targetLibId.GetLibItemName().empty();
468 };
469
470 auto saveSymbolAsCondition =
471 [this]( const SELECTION& aSel )
472 {
473 return getTargetSymbol() != nullptr;
474 };
475
476 const auto isSymbolFromSchematicCond =
477 [this]( const SELECTION& )
478 {
479 return IsSymbolFromSchematic();
480 };
481
482 // clang-format off
485 mgr->SetConditions( SCH_ACTIONS::saveLibraryAs, ENABLE( libSelectedCondition ) );
486 mgr->SetConditions( SCH_ACTIONS::saveSymbolAs, ENABLE( saveSymbolAsCondition ) );
487 mgr->SetConditions( SCH_ACTIONS::saveSymbolCopyAs, ENABLE( saveSymbolAsCondition ) );
490 mgr->SetConditions( SCH_ACTIONS::editLibSymbolWithLibEdit, ENABLE( isSymbolFromSchematicCond ) );
491
492 mgr->SetConditions( ACTIONS::undo, ENABLE( haveSymbolCond && cond.UndoAvailable() ) );
493 mgr->SetConditions( ACTIONS::redo, ENABLE( haveSymbolCond && cond.RedoAvailable() ) );
494 mgr->SetConditions( ACTIONS::revert, ENABLE( symbolModifiedCondition ) );
495
498
499 mgr->SetConditions( ACTIONS::cut, ENABLE( isEditableCond ) );
500 mgr->SetConditions( ACTIONS::copy, ENABLE( haveSymbolCond ) );
501 mgr->SetConditions( ACTIONS::copyAsText, ENABLE( haveSymbolCond ) );
502 mgr->SetConditions( ACTIONS::paste, ENABLE( isEditableCond &&
504 mgr->SetConditions( ACTIONS::doDelete, ENABLE( isEditableCond ) );
505 mgr->SetConditions( ACTIONS::duplicate, ENABLE( isEditableCond ) );
506 mgr->SetConditions( ACTIONS::selectAll, ENABLE( haveSymbolCond ) );
507 mgr->SetConditions( ACTIONS::unselectAll, ENABLE( haveSymbolCond ) );
508
509 // These actions in symbol editor when editing alias field rotations are allowed.
510 mgr->SetConditions( SCH_ACTIONS::rotateCW, ENABLE( isEditableInAliasCond ) );
511 mgr->SetConditions( SCH_ACTIONS::rotateCCW, ENABLE( isEditableInAliasCond ) );
512
513 mgr->SetConditions( SCH_ACTIONS::mirrorH, ENABLE( isEditableCond ) );
514 mgr->SetConditions( SCH_ACTIONS::mirrorV, ENABLE( isEditableCond ) );
515
518 // clang-format on
519
520 auto pinTypeCond =
521 [this]( const SELECTION& )
522 {
524 };
525
526 auto hiddenPinCond =
527 [this]( const SELECTION& )
528 {
530 };
531
532 auto hiddenFieldCond =
533 [this]( const SELECTION& )
534 {
536 };
537
538 auto showPinAltIconsCond =
539 [this]( const SELECTION& )
540 {
542 };
543
544 auto showLibraryTreeCond =
545 [this]( const SELECTION& )
546 {
547 return IsLibraryTreeShown();
548 };
549
550 auto propertiesCond =
551 [this] ( const SELECTION& )
552 {
553 return m_auimgr.GetPane( PropertiesPaneName() ).IsShown();
554 };
555
558 mgr->SetConditions( ACTIONS::showLibraryTree, CHECK( showLibraryTreeCond ) );
559 mgr->SetConditions( ACTIONS::showProperties, CHECK( propertiesCond ) );
560 mgr->SetConditions( SCH_ACTIONS::showHiddenPins, CHECK( hiddenPinCond ) );
561 mgr->SetConditions( SCH_ACTIONS::showHiddenFields, CHECK( hiddenFieldCond ) );
562 mgr->SetConditions( SCH_ACTIONS::togglePinAltIcons, CHECK( showPinAltIconsCond ) );
563
564 auto multiUnitModeCond =
565 [this]( const SELECTION& )
566 {
567 return m_symbol && m_symbol->IsMultiUnit() && !m_symbol->UnitsLocked();
568 };
569
570 auto multiBodyStyleModeCond =
571 [this]( const SELECTION& )
572 {
573 return m_symbol && m_symbol->IsMultiBodyStyle();
574 };
575
576 auto syncedPinsModeCond =
577 [this]( const SELECTION& )
578 {
579 return m_SyncPinEdit;
580 };
581
582 auto haveDatasheetCond =
583 [this]( const SELECTION& )
584 {
585 return m_symbol && !m_symbol->GetDatasheetField().GetText().IsEmpty();
586 };
587
588 mgr->SetConditions( ACTIONS::showDatasheet, ENABLE( haveDatasheetCond ) );
589 mgr->SetConditions( SCH_ACTIONS::symbolProperties, ENABLE( symbolSelectedInTreeCondition || ( canEditProperties && haveSymbolCond ) ) );
590 mgr->SetConditions( SCH_ACTIONS::runERC, ENABLE( haveSymbolCond ) );
591 mgr->SetConditions( SCH_ACTIONS::pinTable, ENABLE( isEditableCond && haveSymbolCond ) );
592 mgr->SetConditions( SCH_ACTIONS::updateSymbolFields, ENABLE( isEditableCond && haveSymbolCond ) );
593 mgr->SetConditions( SCH_ACTIONS::cycleBodyStyle, ENABLE( multiBodyStyleModeCond ) );
594
595 mgr->SetConditions( SCH_ACTIONS::toggleSyncedPinsMode, ACTION_CONDITIONS().Enable( multiUnitModeCond ).Check( syncedPinsModeCond ) );
596
597// Only enable a tool if the symbol is edtable
598#define EDIT_TOOL( tool ) ACTION_CONDITIONS().Enable( isEditableCond ).Check( cond.CurrentTool( tool ) )
599
612
613#undef CHECK
614#undef ENABLE
615#undef EDIT_TOOL
616}
617
618
620{
621 if( IsContentModified() )
622 {
623 SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
624 wxString msg = _( "Save changes to '%s' before closing?" );
625
626 switch( UnsavedChangesDialog( this, wxString::Format( msg, m_reference ), nullptr ) )
627 {
628 case wxID_YES:
629 if( schframe && GetCurSymbol() ) // Should be always the case
631
632 break;
633
634 case wxID_NO:
635 break;
636
637 default:
638 case wxID_CANCEL:
639 return false;
640 }
641 }
642
643 if( doClose )
644 {
645 SetCurSymbol( nullptr, false );
646 UpdateTitle();
647 }
648
649 return true;
650}
651
652
653bool SYMBOL_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
654{
655 // Shutdown blocks must be determined and vetoed as early as possible
657 && aEvent.GetId() == wxEVT_QUERY_END_SESSION
658 && IsContentModified() )
659 {
660 return false;
661 }
662
664 return false;
665
666 if( !saveAllLibraries( true ) )
667 return false;
668
669 // Save symbol tree column widths
670 m_libMgr->GetAdapter()->SaveSettings();
671
672 return true;
673}
674
675
677{
679
680 if( GetLibTree() )
682
683 delete m_toolManager;
684 m_toolManager = nullptr;
685
686 Destroy();
687}
688
689
691{
692 if( m_unitSelectBox )
693 {
694 if( m_unitSelectBox->GetCount() != 0 )
695 m_unitSelectBox->Clear();
696
697 if( !m_symbol || m_symbol->GetUnitCount() <= 1 )
698 {
699 m_unit = 1;
700 m_unitSelectBox->Append( wxEmptyString );
701 }
702 else
703 {
704 for( int i = 0; i < m_symbol->GetUnitCount(); i++ )
705 m_unitSelectBox->Append( m_symbol->GetUnitDisplayName( i + 1, true ) );
706 }
707
708 // Ensure the selected unit is compatible with the number of units of the current symbol:
709 if( m_symbol && m_symbol->GetUnitCount() < m_unit )
710 m_unit = 1;
711
712 m_unitSelectBox->SetSelection( ( m_unit > 0 ) ? m_unit - 1 : 0 );
713 }
714
716 {
717 if( m_bodyStyleSelectBox->GetCount() != 0 )
718 m_bodyStyleSelectBox->Clear();
719
720 if( !m_symbol || !m_symbol->IsMultiBodyStyle() )
721 {
722 m_bodyStyle = 1;
723 m_bodyStyleSelectBox->Append( wxEmptyString );
724 }
725 else if( m_symbol && m_symbol->HasDeMorganBodyStyles() )
726 {
727 m_bodyStyleSelectBox->Append( wxGetTranslation( DEMORGAN_STD ) );
728 m_bodyStyleSelectBox->Append( wxGetTranslation( DEMORGAN_ALT ) );
729 }
730 else
731 {
732 for( int i = 0; i < m_symbol->GetBodyStyleCount(); i++ )
733 m_bodyStyleSelectBox->Append( m_symbol->GetBodyStyleNames()[i] );
734 }
735
736 // Ensure the selected body style is compatible with the number of body styles of the current symbol:
737 if( m_symbol && m_symbol->GetBodyStyleCount() < m_bodyStyle )
738 m_bodyStyle = 1;
739
740 m_bodyStyleSelectBox->SetSelection( ( m_bodyStyle > 0 ) ? m_bodyStyle - 1 : 0 );
741 }
742}
743
744
746{
747 if( !m_propertiesPanel )
748 return;
749
750 bool show = !m_propertiesPanel->IsShownOnScreen();
751
752 wxAuiPaneInfo& propertiesPaneInfo = m_auimgr.GetPane( PropertiesPaneName() );
753 propertiesPaneInfo.Show( show );
755
756 if( show )
757 {
758 SetAuiPaneSize( m_auimgr, propertiesPaneInfo,
759 m_settings->m_AuiPanels.properties_panel_width, -1 );
760 }
761 else
762 {
763 m_settings->m_AuiPanels.properties_panel_width = m_propertiesPanel->GetSize().x;
764 }
765
766 m_auimgr.Update();
767 Refresh();
768}
769
770
772{
773 wxAuiPaneInfo& treePane = m_auimgr.GetPane( m_treePane );
774 treePane.Show( !IsLibraryTreeShown() );
776 m_auimgr.Update();
777 Refresh();
778}
779
780
782{
783 return const_cast<wxAuiManager&>( m_auimgr ).GetPane( m_treePane ).IsShown();
784}
785
786
791
792
794{
795 m_treePane->Freeze();
796 m_libMgr->GetAdapter()->Freeze();
797}
798
799
801{
802 m_libMgr->GetAdapter()->Thaw();
803 m_treePane->Thaw();
804}
805
806
807void SYMBOL_EDIT_FRAME::OnExitKiCad( wxCommandEvent& event )
808{
809 Kiway().OnKiCadExit();
810}
811
812
813void SYMBOL_EDIT_FRAME::OnUpdateUnitNumber( wxUpdateUIEvent& event )
814{
815 event.Enable( m_symbol && m_symbol->GetUnitCount() > 1 );
816}
817
818
819void SYMBOL_EDIT_FRAME::OnSelectUnit( wxCommandEvent& event )
820{
821 if( event.GetSelection() == wxNOT_FOUND )
822 return;
823
824 SetUnit( event.GetSelection() + 1 );
825}
826
827
828void SYMBOL_EDIT_FRAME::OnUpdateBodyStyle( wxUpdateUIEvent& event )
829{
830 event.Enable( m_symbol && m_symbol->GetBodyStyleCount() > 1 );
831}
832
833
834void SYMBOL_EDIT_FRAME::OnSelectBodyStyle( wxCommandEvent& event )
835{
836 if( event.GetSelection() == wxNOT_FOUND )
837 return;
838
839 SetBodyStyle( event.GetSelection() + 1 );
840}
841
842
844{
845 if( m_symbol )
846 {
848
849 if( auto row = adapter->GetRow( m_symbol->GetLibNickname() ); row.has_value() )
850 {
851 if( ( *row )->Type() == SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) )
852 return true;
853 }
854 }
855
856 return false;
857}
858
859
861{
862 wxString libNickname = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_LIB );
863
864 if( !libNickname.empty() )
865 {
866 if( !PROJECT_SCH::SymbolLibAdapter( &Prj() )->HasLibrary( libNickname ) )
867 {
868 Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, wxEmptyString );
869 libNickname = wxEmptyString;
870 }
871 }
872
873 return libNickname;
874}
875
876
877wxString SYMBOL_EDIT_FRAME::SetCurLib( const wxString& aLibNickname )
878{
879 wxString old = GetCurLib();
880
881 if( aLibNickname.empty() || !PROJECT_SCH::SymbolLibAdapter( &Prj() )->HasLibrary( aLibNickname ) )
882 Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, wxEmptyString );
883 else
885
886 return old;
887}
888
889
890void SYMBOL_EDIT_FRAME::SetCurSymbol( LIB_SYMBOL* aSymbol, bool aUpdateZoom )
891{
892 wxCHECK( m_toolManager, /* void */ );
893
895 GetCanvas()->GetView()->Clear();
896 delete m_symbol;
897
898 m_symbol = aSymbol;
899
900 // select the current symbol in the tree widget
902 GetLibTree()->SelectLibId( m_symbol->GetLibId() );
903 else
904 GetLibTree()->Unselect();
905
906 wxString symbolName;
907 wxString libName;
908
909 if( m_symbol )
910 {
911 symbolName = m_symbol->GetName();
912 libName = UnescapeString( m_symbol->GetLibId().GetLibNickname() );
913 }
914
915 // retain in case this wxFrame is re-opened later on the same PROJECT
917
918 // Ensure synchronized pin edit can be enabled only symbols with interchangeable units
919 m_SyncPinEdit = aSymbol && aSymbol->IsRoot() && aSymbol->IsMultiUnit() && !aSymbol->UnitsLocked();
920
922
930
931 if( aUpdateZoom )
933
934 GetCanvas()->Refresh();
935 m_propertiesPanel->UpdateData();
936
937 WX_INFOBAR& infobar = *GetInfoBar();
938 infobar.RemoveAllButtons();
939
940 wxArrayString msgs;
941 int infobarFlags = wxICON_INFORMATION;
942
944 {
945 msgs.push_back( wxString::Format( _( "Editing symbol %s from schematic. Saving will "
946 "update the schematic only." ),
947 m_reference ) );
948
949 wxString link = wxString::Format( _( "Open symbol from library %s" ), libName );
950 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( &infobar, wxID_ANY, link, wxEmptyString );
951
952 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
953 [this, symbolName, libName]( wxHyperlinkEvent& aEvent )
954 {
956 } ) );
957
958 infobar.AddButton( button );
959 }
960 else if( IsSymbolFromLegacyLibrary() )
961 {
962 msgs.push_back( _( "Symbols in legacy libraries are not editable. Use Manage Symbol "
963 "Libraries to migrate to current format." ) );
964
965 wxString link = _( "Manage symbol libraries" );
966 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( &infobar, wxID_ANY, link, wxEmptyString );
967
968 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
969 [this]( wxHyperlinkEvent& aEvent )
970 {
972 } ) );
973
974 infobar.AddButton( button );
975 }
976 else if( IsSymbolAlias() )
977 {
978 msgs.push_back( wxString::Format( _( "Symbol %s is a derived symbol. Symbol graphics will "
979 "not be editable." ),
980 UnescapeString( symbolName ) ) );
981
982 // Don't assume the parent symbol shared pointer is still valid.
983 if( std::shared_ptr<LIB_SYMBOL> rootSymbol = m_symbol->GetRootSymbol() )
984 {
985 int unit = GetUnit();
986 int bodyStyle = GetBodyStyle();
987 wxString rootSymbolName = rootSymbol->GetName();
988 wxString link = wxString::Format( _( "Open %s" ), UnescapeString( rootSymbolName ) );
989
990 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( &infobar, wxID_ANY, link,
991 wxEmptyString );
992
993 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
994 [this, rootSymbolName, unit, bodyStyle]( wxHyperlinkEvent& aEvent )
995 {
996 LoadSymbolFromCurrentLib( rootSymbolName, unit, bodyStyle );
997 } ) );
998
999 infobar.AddButton( button );
1000 }
1001 }
1002
1003 if( m_symbol
1005 && m_libMgr->IsLibraryReadOnly( m_symbol->GetLibId().GetFullLibraryName() ) )
1006 {
1007 msgs.push_back( _( "Library is read-only. Changes cannot be saved to this library." ) );
1008
1009 wxString link = wxString::Format( _( "Create an editable copy" ) );
1010 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( &infobar, wxID_ANY, link, wxEmptyString );
1011
1012 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
1013 [this, symbolName, libName]( wxHyperlinkEvent& aEvent )
1014 {
1015 wxString msg = wxString::Format( _( "Create an editable copy of the symbol or "
1016 "the entire library (%s)?" ),
1017 libName );
1018
1019 KIDIALOG errorDlg( this, msg, _( "Select type of item to save" ),
1020 wxYES_NO | wxCANCEL | wxICON_QUESTION );
1021 // These buttons are in a weird order(?)
1022 errorDlg.SetYesNoCancelLabels( _( "Copy symbol" ), _( "Cancel" ),
1023 _( "Copy library" ) );
1024
1025 int choice = errorDlg.ShowModal();
1026
1027 switch( choice )
1028 {
1029 case wxID_YES:
1030 SaveSymbolCopyAs( true );
1031 break;
1032 case wxID_CANCEL:
1033 SaveLibraryAs();
1034 break;
1035 default:
1036 // Do nothing
1037 break;
1038 }
1039 } ) );
1040
1041 infobar.AddButton( button );
1042 }
1043
1044 if( msgs.empty() )
1045 {
1046 infobar.Dismiss();
1047 }
1048 else
1049 {
1050 wxString msg = wxJoin( msgs, '\n', '\0' );
1051 infobar.ShowMessage( msg, infobarFlags );
1052 }
1053}
1054
1055
1061
1062
1064{
1066
1068
1069 if( !IsSymbolFromSchematic() )
1071
1072 if( m_isClosing )
1073 return;
1074
1076
1077 if( !GetTitle().StartsWith( "*" ) )
1078 UpdateTitle();
1079}
1080
1081
1083{
1084 wxCHECK( aUnit > 0 && aUnit <= GetCurSymbol()->GetUnitCount(), /* void*/ );
1085
1086 if( m_unit == aUnit )
1087 return;
1088
1091
1092 m_unit = aUnit;
1093
1094 if( m_unitSelectBox->GetSelection() != ( m_unit - 1 ) )
1095 m_unitSelectBox->SetSelection( m_unit - 1 );
1096
1098 RebuildView();
1100}
1101
1102
1104{
1105 wxCHECK( aBodyStyle > 0 && aBodyStyle <= GetCurSymbol()->GetBodyStyleCount(), /* void */ );
1106
1107 if( m_bodyStyle == aBodyStyle )
1108 return;
1109
1112
1113 m_bodyStyle = aBodyStyle;
1114
1115 if( m_bodyStyleSelectBox->GetSelection() != ( m_bodyStyle - 1 ) )
1116 m_bodyStyleSelectBox->SetSelection( m_bodyStyle - 1 );
1117
1118
1120 RebuildView();
1122}
1123
1124
1126{
1127 return m_SyncPinEdit && m_symbol && m_symbol->IsMultiUnit() && !m_symbol->UnitsLocked();
1128}
1129
1130
1131wxString SYMBOL_EDIT_FRAME::AddLibraryFile( bool aCreateNew )
1132{
1133 wxFileName fn = m_libMgr->GetUniqueLibraryName();
1134 bool useGlobalTable = true;
1135 FILEDLG_HOOK_NEW_LIBRARY tableChooser( useGlobalTable );
1136
1137 if( !LibraryFileBrowser( aCreateNew ? _( "New Symbol Library" ) : _( "Add Symbol Library" ),
1138 !aCreateNew, fn, FILEEXT::KiCadSymbolLibFileWildcard(),
1140 Pgm().GetSettingsManager().IsProjectOpenNotDummy() ? &tableChooser : nullptr ) )
1141 {
1142 return wxEmptyString;
1143 }
1144
1147
1148 std::optional<LIBRARY_TABLE*> table = Pgm().GetLibraryManager().Table( LIBRARY_TABLE_TYPE::SYMBOL, scope );
1149 wxCHECK( table, wxEmptyString );
1150
1151 wxString libName = fn.GetName();
1152
1153 if( libName.IsEmpty() )
1154 return wxEmptyString;
1155
1157
1158 if( adapter->HasLibrary( libName ) )
1159 {
1160 DisplayError( this, wxString::Format( _( "Library '%s' already exists." ), libName ) );
1161 return wxEmptyString;
1162 }
1163
1164 if( aCreateNew )
1165 {
1166 if( !m_libMgr->CreateLibrary( fn.GetFullPath(), scope ) )
1167 {
1168 DisplayError( this, wxString::Format( _( "Could not create the library file '%s'.\n"
1169 "Make sure you have write permissions and try again." ),
1170 fn.GetFullPath() ) );
1171 return wxEmptyString;
1172 }
1173 }
1174 else
1175 {
1176 if( !m_libMgr->AddLibrary( fn.GetFullPath(), scope ) )
1177 {
1178 DisplayError( this, _( "Could not open the library file." ) );
1179 return wxEmptyString;
1180 }
1181 }
1182
1183 ( *table )->Save().map_error(
1184 []( const LIBRARY_ERROR& aError )
1185 {
1186 wxMessageBox( wxString::Format( _( "Error saving library table:\n\n%s" ), aError.message ),
1187 _( "File Save Error" ), wxOK | wxICON_ERROR );
1188 } );
1189
1190 adapter->LoadOne( fn.GetName() );
1191
1192 std::string packet = fn.GetFullPath().ToStdString();
1195
1196 return fn.GetFullPath();
1197}
1198
1199
1200void SYMBOL_EDIT_FRAME::DdAddLibrary( wxString aLibFile )
1201{
1202 wxFileName fn = wxFileName( aLibFile );
1203 wxString libName = fn.GetName();
1204
1205 if( libName.IsEmpty() )
1206 return;
1207
1209
1210 if( adapter->HasLibrary( libName ) )
1211 {
1212 DisplayError( this, wxString::Format( _( "Library '%s' already exists." ), libName ) );
1213 return;
1214 }
1215
1216 // TODO(JE) after Jeff's commit removing the select dialog; this is always project? is that correct?
1217 if( !m_libMgr->AddLibrary( fn.GetFullPath(), LIBRARY_TABLE_SCOPE::PROJECT ) )
1218 {
1219 DisplayError( this, _( "Could not open the library file." ) );
1220 return;
1221 }
1222
1223 std::optional<LIBRARY_TABLE*> table = Pgm().GetLibraryManager().Table( LIBRARY_TABLE_TYPE::SYMBOL,
1225 wxCHECK( table, /* void */ );
1226
1227 ( *table )->Save().map_error(
1228 []( const LIBRARY_ERROR& aError )
1229 {
1230 wxMessageBox( wxString::Format( _( "Error saving library table:\n\n%s" ), aError.message ),
1231 _( "File Save Error" ), wxOK | wxICON_ERROR );
1232 } );
1233
1234 std::string packet = fn.GetFullPath().ToStdString();
1237}
1238
1239
1241{
1242 return GetLibTree()->GetSelectedLibId( aUnit );
1243}
1244
1245
1250
1251int SYMBOL_EDIT_FRAME::GetTreeLIBIDs( std::vector<LIB_ID>& aSelection ) const
1252{
1253 return GetLibTree()->GetSelectedLibIds( aSelection );
1254}
1255
1256
1258{
1259 if( IsLibraryTreeShown() )
1260 {
1261 LIB_ID libId = GetTreeLIBID();
1262
1263 if( libId.IsValid() )
1264 return m_libMgr->GetSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
1265 }
1266
1267 return m_symbol;
1268}
1269
1270
1272{
1273 LIB_ID id;
1274
1275 if( IsLibraryTreeShown() )
1276 id = GetTreeLIBID();
1277
1278 if( id.GetLibNickname().empty() && m_symbol )
1279 id = m_symbol->GetLibId();
1280
1281 return id;
1282}
1283
1284
1285std::vector<LIB_ID> SYMBOL_EDIT_FRAME::GetSelectedLibIds() const
1286{
1287 std::vector<LIB_ID> ids;
1288 GetTreeLIBIDs( ids );
1289 return ids;
1290}
1291
1292
1294{
1295 return GetTargetLibId().GetLibNickname();
1296}
1297
1298
1299void SYMBOL_EDIT_FRAME::SyncLibraries( bool aShowProgress, bool aPreloadCancelled,
1300 const wxString& aForceRefresh )
1301{
1302 LIB_ID selected;
1303
1304 if( m_treePane )
1305 selected = GetLibTree()->GetSelectedLibId();
1306
1307 if( aShowProgress )
1308 {
1309 APP_PROGRESS_DIALOG progressDlg( _( "Loading Symbol Libraries" ), wxEmptyString,
1310 m_libMgr->GetAdapter()->GetLibrariesCount(), this );
1311
1312 m_libMgr->Sync( aForceRefresh,
1313 [&]( int progress, int max, const wxString& libName )
1314 {
1315 progressDlg.Update( progress, wxString::Format( _( "Loading library '%s'..." ),
1316 libName ) );
1317 } );
1318 }
1319 else if( !aPreloadCancelled )
1320 {
1321 m_libMgr->Sync( aForceRefresh,
1322 [&]( int progress, int max, const wxString& libName )
1323 {
1324 } );
1325 }
1326
1327 if( m_treePane )
1328 {
1329 wxDataViewItem found;
1330
1331 if( selected.IsValid() )
1332 {
1333 // Check if the previously selected item is still valid,
1334 // if not - it has to be unselected to prevent crash
1335 found = m_libMgr->GetAdapter()->FindItem( selected );
1336
1337 if( !found )
1338 GetLibTree()->Unselect();
1339 }
1340
1341 GetLibTree()->Regenerate( true );
1342
1343 // Try to select the parent library, in case the symbol is not found
1344 if( !found && selected.IsValid() )
1345 {
1346 selected.SetLibItemName( "" );
1347 found = m_libMgr->GetAdapter()->FindItem( selected );
1348
1349 if( found )
1350 GetLibTree()->SelectLibId( selected );
1351 }
1352
1353 // If no selection, see if there's a current symbol to centre
1354 if( !selected.IsValid() && m_symbol )
1355 {
1356 LIB_ID current( GetCurLib(), m_symbol->GetName() );
1357 GetLibTree()->CenterLibId( current );
1358 }
1359 }
1360}
1361
1362
1367
1368
1370{
1371 GetLibTree()->SelectLibId( aLibID );
1372}
1373
1374
1375void SYMBOL_EDIT_FRAME::UpdateLibraryTree( const wxDataViewItem& aTreeItem, LIB_SYMBOL* aSymbol )
1376{
1377 if( aTreeItem.IsOk() ) // Can be not found in tree if the current footprint is imported
1378 // from file therefore not yet in tree.
1379 {
1380 static_cast<LIB_TREE_NODE_ITEM*>( aTreeItem.GetID() )->Update( aSymbol );
1382 }
1383}
1384
1385
1386bool SYMBOL_EDIT_FRAME::backupFile( const wxFileName& aOriginalFile, const wxString& aBackupExt )
1387{
1388 if( aOriginalFile.FileExists() )
1389 {
1390 wxFileName backupFileName( aOriginalFile );
1391 backupFileName.SetExt( aBackupExt );
1392
1393 if( backupFileName.FileExists() )
1394 wxRemoveFile( backupFileName.GetFullPath() );
1395
1396 if( !wxCopyFile( aOriginalFile.GetFullPath(), backupFileName.GetFullPath() ) )
1397 {
1398 DisplayError( this, wxString::Format( _( "Failed to save backup to '%s'." ),
1399 backupFileName.GetFullPath() ) );
1400 return false;
1401 }
1402 }
1403
1404 return true;
1405}
1406
1407
1409{
1410 if( m_symbol && !GetCurLib().IsEmpty() && GetScreen()->IsContentModified() )
1411 m_libMgr->UpdateSymbol( m_symbol, GetCurLib() ); // UpdateSymbol() makes a copy
1412}
1413
1414
1416{
1417 // This will return the root symbol of any alias
1418 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aLibId.GetLibItemName(), aLibId.GetLibNickname() );
1419
1420 // Now we can compare the libId of the current symbol and the root symbol
1421 return ( symbol && m_symbol && symbol->GetLibId() == m_symbol->GetLibId() );
1422}
1423
1424
1426{
1427 GetLibTree()->Unselect();
1428 SetCurLib( wxEmptyString );
1429 SetCurSymbol( nullptr, false );
1433 Refresh();
1434}
1435
1436
1438{
1440
1442 {
1443 GetRenderSettings()->m_ShowPinsElectricalType = cfg->m_ShowPinElectricalType;
1444 GetRenderSettings()->m_ShowHiddenPins = cfg->m_ShowHiddenPins;
1445 GetRenderSettings()->m_ShowHiddenFields = cfg->m_ShowHiddenFields;
1446 GetRenderSettings()->m_ShowPinAltIcons = cfg->m_ShowPinAltIcons;
1447
1448 GetGalDisplayOptions().ReadWindowSettings( cfg->m_Window );
1449 }
1450
1451 if( m_symbol )
1452 m_symbol->ClearCaches();
1453
1455
1457 GetCanvas()->Refresh();
1458
1460
1461 if( aFlags & ENVVARS_CHANGED )
1462 SyncLibraries( true );
1463
1464 Layout();
1465 SendSizeEvent();
1466}
1467
1468
1470{
1471 // call my base class
1473
1474 // tooltips in toolbars
1476
1477 // For some obscure reason, the AUI manager hides the first modified pane.
1478 // So force show panes
1479 wxAuiPaneInfo& tree_pane_info = m_auimgr.GetPane( m_treePane );
1480 bool tree_shown = tree_pane_info.IsShown();
1481 tree_pane_info.Caption( _( "Libraries" ) );
1482 tree_pane_info.Show( tree_shown );
1483 m_auimgr.Update();
1484
1486
1487 // status bar
1489
1490 if( GetRenderSettings()->m_ShowPinsElectricalType )
1491 {
1493 GetCanvas()->Refresh();
1494 }
1495
1496 UpdateTitle();
1497}
1498
1499
1501{
1502 SCH_BASE_FRAME::SetScreen( aScreen );
1503
1504 // Let tools add things to the view if necessary
1505 if( m_toolManager )
1507}
1508
1509
1527
1528
1530{
1531 SyncLibraries( true );
1532
1533 if( m_symbol )
1534 {
1535 SCH_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<SCH_SELECTION_TOOL>();
1536 SCH_SELECTION& selection = selectionTool->GetSelection();
1537
1538 for( SCH_ITEM& item : m_symbol->GetDrawItems() )
1539 {
1540 if( !alg::contains( selection, &item ) )
1541 item.ClearSelected();
1542 else
1543 item.SetSelected();
1544 }
1545
1546 m_symbol->ClearCaches();
1547 }
1548
1549 RebuildView();
1550}
1551
1552
1553const BOX2I SYMBOL_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
1554{
1555 if( !m_symbol )
1556 {
1557 // Gives a reasonable drawing area size
1558 int width = schIUScale.mmToIU( 50 );
1559 int height = schIUScale.mmToIU( 30 );
1560
1561 return BOX2I( VECTOR2I( -width/2, -height/2 ), VECTOR2I( width, height ) );
1562 }
1563 else
1564 {
1565 return m_symbol->Flatten()->GetUnitBoundingBox( m_unit, m_bodyStyle );
1566 }
1567}
1568
1569
1570void SYMBOL_EDIT_FRAME::FocusOnItem( EDA_ITEM* aItem, bool aAllowScroll )
1571{
1572 static KIID lastBrightenedItemID( niluuid );
1573
1574 SCH_ITEM* lastItem = nullptr;
1575
1576 // nullptr will clear the current focus
1577 if( aItem != nullptr && !aItem->IsSCH_ITEM() )
1578 return;
1579
1580 if( m_symbol )
1581 {
1582 for( SCH_PIN* pin : m_symbol->GetPins() )
1583 {
1584 if( pin->m_Uuid == lastBrightenedItemID )
1585 lastItem = pin;
1586 }
1587
1588 std::vector<SCH_FIELD*> fields;
1589 m_symbol->GetFields( fields );
1590
1591 for( SCH_FIELD* field : fields )
1592 {
1593 if( field->m_Uuid == lastBrightenedItemID )
1594 lastItem = field;
1595 }
1596 }
1597
1598 if( lastItem && lastItem != aItem )
1599 {
1600 lastItem->ClearBrightened();
1601
1602 UpdateItem( lastItem );
1603 lastBrightenedItemID = niluuid;
1604 }
1605
1606 if( aItem )
1607 {
1608 if( !aItem->IsBrightened() )
1609 {
1610 aItem->SetBrightened();
1611
1612 UpdateItem( aItem );
1613 lastBrightenedItemID = aItem->m_Uuid;
1614 }
1615
1616 FocusOnLocation( VECTOR2I( aItem->GetFocusPosition().x, -aItem->GetFocusPosition().y ), aAllowScroll );
1617 }
1618}
1619
1620
1622{
1623 const std::string& payload = mail.GetPayload();
1624
1625 switch( mail.Command() )
1626 {
1627 case MAIL_LIB_EDIT:
1628 if( !payload.empty() )
1629 {
1630 wxString uri( payload );
1631 wxString libNickname;
1632 wxString msg;
1633
1635 std::optional<const LIBRARY_TABLE_ROW*> libTableRow = adapter->FindRowByURI( uri );
1636
1637 if( !libTableRow )
1638 {
1639 msg.Printf( _( "The current configuration does not include the symbol library '%s'." ),
1640 uri );
1641 msg += wxS( "\n" ) + _( "Use Manage Symbol Libraries to edit the configuration." );
1642 DisplayErrorMessage( this, _( "Library not found in symbol library table." ), msg );
1643 break;
1644 }
1645
1646 libNickname = ( *libTableRow )->Nickname();
1647
1648 if( !adapter->HasLibrary( libNickname, true ) )
1649 {
1650 msg.Printf( _( "The symbol library '%s' is not enabled in the current configuration." ),
1651 UnescapeString( libNickname ) );
1652 msg += wxS( "\n" ) + _( "Use Manage Symbol Libraries to edit the configuration." );
1653 DisplayErrorMessage( this, _( "Symbol library not enabled." ), msg );
1654 break;
1655 }
1656
1657 SetCurLib( libNickname );
1658
1659 if( m_treePane )
1660 {
1661 LIB_ID id( libNickname, wxEmptyString );
1662 GetLibTree()->SelectLibId( id );
1663 GetLibTree()->ExpandLibId( id );
1664 GetLibTree()->CenterLibId( id );
1665 }
1666 }
1667
1668 break;
1669
1670 case MAIL_RELOAD_LIB:
1671 {
1672 wxString currentLib = GetCurLib();
1673
1675
1676 // Check if the currently selected symbol library been removed or disabled.
1677 if( !currentLib.empty()
1678 && !PROJECT_SCH::SymbolLibAdapter( &Prj() )->HasLibrary( currentLib, true ) )
1679 {
1680 SetCurLib( wxEmptyString );
1681 emptyScreen();
1682 }
1683
1684 SyncLibraries( true );
1687
1688 break;
1689 }
1690
1692 {
1694 LIB_SYMBOL* symbol = GetCurSymbol();
1695
1696 wxLogTrace( traceLibWatch, "Received refresh symbol request for %s", payload );
1697
1698 if( !symbol )
1699 break;
1700
1701 wxString libName = symbol->GetLibId().GetLibNickname();
1702 std::optional<const LIBRARY_TABLE_ROW*> row = adapter->GetRow( libName );
1703
1704 if( !row )
1705 return;
1706
1707 wxFileName libfullname( LIBRARY_MANAGER::GetFullURI( *row, true ) );
1708
1709 wxFileName changedLib( mail.GetPayload() );
1710
1711 wxLogTrace( traceLibWatch, "Received refresh symbol request for %s, current symbols is %s",
1712 changedLib.GetFullPath(), libfullname.GetFullPath() );
1713
1714 if( changedLib == libfullname )
1715 {
1716 wxLogTrace( traceLibWatch, "Refreshing symbol %s", symbol->GetName() );
1717
1718 SetScreen( m_dummyScreen ); // UpdateLibraryBuffer will destroy the old screen
1719 m_libMgr->UpdateLibraryBuffer( libName );
1720
1721 if( LIB_SYMBOL* lib_symbol = m_libMgr->GetBufferedSymbol( symbol->GetName(), libName ) )
1722 {
1723 // The buffered screen for the symbol
1724 SCH_SCREEN* symbol_screen = m_libMgr->GetScreen( lib_symbol->GetName(), libName );
1725
1726 SetScreen( symbol_screen );
1727 SetCurSymbol( new LIB_SYMBOL( *lib_symbol ), false );
1729
1730 if( m_toolManager )
1732 }
1733 }
1734
1735 break;
1736 }
1737
1738 default:
1739 break;
1740 }
1741}
1742
1743
1744std::unique_ptr<GRID_HELPER> SYMBOL_EDIT_FRAME::MakeGridHelper()
1745{
1746 return std::make_unique<EE_GRID_HELPER>( m_toolManager );
1747}
1748
1749
1751{
1752 // switches currently used canvas ( Cairo / OpenGL):
1753 SCH_BASE_FRAME::SwitchCanvas( aCanvasType );
1754
1755 // Set options specific to symbol editor (axies are always enabled):
1756 GetCanvas()->GetGAL()->SetAxesEnabled( true );
1758}
1759
1760
1762{
1763 wxCHECK( m_libMgr, false );
1764
1765 return m_libMgr->HasModifications();
1766}
1767
1768
1770{
1771 wxCHECK( m_libMgr, false );
1772
1773 // Test if the currently edited symbol is modified
1775 return true;
1776
1777 // Test if any library has been modified
1778 for( const wxString& libName : m_libMgr->GetLibraryNames() )
1779 {
1780 if( m_libMgr->IsLibraryModified( libName ) && !m_libMgr->IsLibraryReadOnly( libName ) )
1781 return true;
1782 }
1783
1784 return false;
1785}
1786
1787
1789{
1790 if( aItemCount == 0 )
1791 return;
1792
1793 UNDO_REDO_CONTAINER& list = ( whichList == UNDO_LIST ) ? m_undoList : m_redoList;
1794
1795 if( aItemCount < 0 )
1796 {
1797 list.ClearCommandList();
1798 }
1799 else
1800 {
1801 for( int ii = 0; ii < aItemCount; ii++ )
1802 {
1803 if( list.m_CommandsList.size() == 0 )
1804 break;
1805
1806 PICKED_ITEMS_LIST* curr_cmd = list.m_CommandsList[0];
1807 list.m_CommandsList.erase( list.m_CommandsList.begin() );
1808
1809 curr_cmd->ClearListAndDeleteItems( []( EDA_ITEM* aItem )
1810 {
1811 delete aItem;
1812 } );
1813 delete curr_cmd; // Delete command
1814 }
1815 }
1816}
1817
1818
1820{
1821 return m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
1822}
1823
1824
1826{
1827 std::unique_ptr<LIB_SYMBOL> symbol = aSymbol->GetLibSymbolRef()->Flatten();
1828 wxCHECK( symbol, /* void */ );
1829
1830 symbol->SetLibId( aSymbol->GetLibId() );
1831
1832 // Take in account the symbol orientation and mirroring. to calculate the field
1833 // positions in symbol editor (i.e. no rotation, no mirroring)
1834 int orientation = aSymbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y );
1835 int mirror = aSymbol->GetOrientation() & ( SYM_MIRROR_X | SYM_MIRROR_Y );
1836
1837 std::vector<SCH_FIELD> fullSetOfFields;
1838
1839 for( const SCH_FIELD& field : aSymbol->GetFields() )
1840 {
1841 VECTOR2I pos = field.GetPosition() - aSymbol->GetPosition();
1842 SCH_FIELD libField( symbol.get(), field.GetId() );
1843
1844 libField = field;
1845
1846 // The inverse transform is mirroring before, rotate after
1847 switch( mirror )
1848 {
1849 case SYM_MIRROR_X: pos.y = -pos.y; break;
1850 case SYM_MIRROR_Y: pos.x = -pos.x; break;
1851 default: break;
1852 }
1853
1854 switch( orientation )
1855 {
1856 case SYM_ORIENT_90:
1857 std::swap( pos.x, pos.y );
1858 pos.x = - pos.x;
1859 break;
1860 case SYM_ORIENT_270:
1861 std::swap( pos.x, pos.y );
1862 pos.y = - pos.y;
1863 break;
1864 case SYM_ORIENT_180:
1865 pos.x = - pos.x;
1866 pos.y = - pos.y;
1867 break;
1868 default:
1869 break;
1870 }
1871
1872 libField.SetPosition( pos );
1873
1874 fullSetOfFields.emplace_back( std::move( libField ) );
1875 }
1876
1877 symbol->SetFields( fullSetOfFields );
1878
1879 if( m_symbol )
1880 SetCurSymbol( nullptr, false );
1881
1883 m_schematicSymbolUUID = aSymbol->m_Uuid;
1884 m_reference = symbol->GetReferenceField().GetText();
1885 m_unit = std::max( 1, aSymbol->GetUnit() );
1886 m_bodyStyle = std::max( 1, aSymbol->GetBodyStyle() );
1887
1888 // Optimize default edit options for this symbol
1889 // Usually if units are locked, graphic items are specific to each unit
1890 // and if units are interchangeable, graphic items are common to units
1892 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
1893
1894 // The buffered screen for the symbol
1895 SCH_SCREEN* tmpScreen = new SCH_SCREEN();
1896
1897 SetScreen( tmpScreen );
1898 SetCurSymbol( symbol.release(), true );
1899 setSymWatcher( nullptr );
1900
1903
1904 if( IsLibraryTreeShown() )
1906
1907 UpdateTitle();
1910
1911 // Let tools add things to the view if necessary
1912 if( m_toolManager )
1914
1916 GetCanvas()->Refresh();
1917}
1918
1919
1920bool SYMBOL_EDIT_FRAME::addLibTableEntry( const wxString& aLibFile, LIBRARY_TABLE_SCOPE aScope )
1921{
1922 wxFileName fn = aLibFile;
1923 wxFileName libTableFileName( Prj().GetProjectPath(), FILEEXT::SymbolLibraryTableFileName );
1924 wxString libNickname = fn.GetName();
1926 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
1927
1928 if( adapter->HasLibrary( libNickname ) )
1929 {
1930 wxString tmp;
1931 int suffix = 1;
1932
1933 while( adapter->HasLibrary( libNickname ) )
1934 {
1935 tmp.Printf( "%s%d", fn.GetName(), suffix );
1936 libNickname = tmp;
1937 suffix += 1;
1938 }
1939 }
1940
1941 std::optional<LIBRARY_TABLE*> optTable =
1943 wxCHECK( optTable, false );
1944 LIBRARY_TABLE* table = *optTable;
1945
1946 LIBRARY_TABLE_ROW* row = &table->InsertRow();
1947
1948 row->SetNickname( libNickname );
1949
1950 // We cannot normalize against the current project path when saving to global table.
1951 wxString normalizedPath = NormalizePath( aLibFile, &envVars,
1952 aScope == LIBRARY_TABLE_SCOPE::PROJECT ? Prj().GetProjectPath()
1953 : wxString( wxEmptyString ) );
1954
1955 row->SetURI( normalizedPath );
1957
1958 bool success = true;
1959
1960 table->Save().map_error(
1961 [&]( const LIBRARY_ERROR& aError )
1962 {
1963 wxString msg = aScope == LIBRARY_TABLE_SCOPE::GLOBAL ? _( "Error saving global library table." )
1964 : _( "Error saving project library table." );
1965
1966 wxMessageDialog dlg( this, msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
1967 dlg.SetExtendedMessage( aError.message );
1968 dlg.ShowModal();
1969
1970 success = false;
1971 } );
1972
1973 if( success )
1974 adapter->LoadOne( libNickname );
1975
1976 return success;
1977}
1978
1979
1980bool SYMBOL_EDIT_FRAME::replaceLibTableEntry( const wxString& aLibNickname, const wxString& aLibFile )
1981{
1983 LIBRARY_TABLE* table = nullptr;
1985
1986 // Check the global library table first because checking the project library table
1987 // checks the global library table as well due to library chaining.
1988 if( adapter->GetRow( aLibNickname, scope ) )
1989 {
1990 std::optional<LIBRARY_TABLE*> optTable = Pgm().GetLibraryManager().Table( LIBRARY_TABLE_TYPE::SYMBOL,
1991 scope );
1992 wxCHECK( optTable, false );
1993 table = *optTable;
1994 }
1995 else
1996 {
1998
1999 if( adapter->GetRow( aLibNickname, scope ) )
2000 {
2001 std::optional<LIBRARY_TABLE*> optTable = Pgm().GetLibraryManager().Table( LIBRARY_TABLE_TYPE::SYMBOL,
2002 scope );
2003
2004 if( optTable )
2005 table = *optTable;
2006 }
2007 }
2008
2009 wxCHECK( table, false );
2010
2011 auto optRow = adapter->GetRow( aLibNickname, scope );
2012 wxCHECK( optRow, false );
2013 LIBRARY_TABLE_ROW* row = *optRow;
2014
2015 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
2016
2017 wxString projectPath;
2018
2019 if( scope == LIBRARY_TABLE_SCOPE::PROJECT )
2020 projectPath = Prj().GetProjectPath();
2021
2022 wxString normalizedPath = NormalizePath( aLibFile, &envVars, projectPath );
2023
2024 row->SetURI( normalizedPath );
2025 row->SetType( "KiCad" );
2026
2027 bool success = true;
2028
2029 table->Save().map_error(
2030 [&]( const LIBRARY_ERROR& aError )
2031 {
2032 wxString msg = scope == LIBRARY_TABLE_SCOPE::GLOBAL ? _( "Error saving global library table." )
2033 : _( "Error saving project library table." );
2034
2035 wxMessageDialog dlg( this, msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
2036 dlg.SetExtendedMessage( aError.message );
2037 dlg.ShowModal();
2038
2039 success = false;
2040 } );
2041
2042 if( success )
2043 adapter->LoadOne( aLibNickname );
2044
2045 return success;
2046}
2047
2048
2050{
2051 return m_symbol && !m_symbol->IsRoot();
2052}
2053
2054
2059
2060
2061void SYMBOL_EDIT_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete, bool aUpdateRtree )
2062{
2063 SCH_BASE_FRAME::UpdateItem( aItem, isAddOrDelete, aUpdateRtree );
2064
2065 if( EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( aItem ) )
2066 {
2067 eda_text->ClearBoundingBoxCache();
2068 eda_text->ClearRenderCache();
2069 }
2070}
2071
2072
2074{
2075 wxAuiPaneInfo& treePane = m_auimgr.GetPane( m_treePane );
2076 wxAuiPaneInfo& propertiesPane = m_auimgr.GetPane( PropertiesPaneName() );
2077 wxAuiPaneInfo& selectionFilterPane = m_auimgr.GetPane( wxS( "SelectionFilter" ) );
2078
2079 // Don't give the selection filter its own visibility controls; instead show it if
2080 // anything else is visible
2081 bool showFilter = ( treePane.IsShown() && treePane.IsDocked() )
2082 || ( propertiesPane.IsShown() && propertiesPane.IsDocked() );
2083
2084 selectionFilterPane.Show( showFilter );
2085}
2086
2087
2089{
2090 // Returns the current render option for invisible fields
2092}
2093
2094
2096{
2097 // Returns the current render option for invisible pins
2099}
BASE_SCREEN class implementation.
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:114
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition bitmap.cpp:104
@ icon_libedit_32
@ icon_libedit_16
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
BOX2< VECTOR2D > BOX2D
Definition box2.h:923
static TOOL_ACTION toggleGrid
Definition actions.h:198
static TOOL_ACTION paste
Definition actions.h:80
static TOOL_ACTION cancelInteractive
Definition actions.h:72
static TOOL_ACTION unselectAll
Definition actions.h:83
static TOOL_ACTION revert
Definition actions.h:62
static TOOL_ACTION showLibraryTree
Definition actions.h:164
static TOOL_ACTION copy
Definition actions.h:78
static TOOL_ACTION showDatasheet
Definition actions.h:267
static TOOL_ACTION toggleBoundingBoxes
Definition actions.h:157
static TOOL_ACTION saveAll
Definition actions.h:61
static TOOL_ACTION undo
Definition actions.h:75
static TOOL_ACTION duplicate
Definition actions.h:84
static TOOL_ACTION doDelete
Definition actions.h:85
static TOOL_ACTION selectionTool
Definition actions.h:251
static TOOL_ACTION save
Definition actions.h:58
static TOOL_ACTION zoomFitScreen
Definition actions.h:142
static TOOL_ACTION redo
Definition actions.h:76
static TOOL_ACTION deleteTool
Definition actions.h:86
static TOOL_ACTION zoomTool
Definition actions.h:146
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:224
static TOOL_ACTION showProperties
Definition actions.h:266
static TOOL_ACTION cut
Definition actions.h:77
static TOOL_ACTION ddAddLibrary
Definition actions.h:67
static TOOL_ACTION copyAsText
Definition actions.h:79
static TOOL_ACTION toggleGridOverrides
Definition actions.h:199
static TOOL_ACTION selectAll
Definition actions.h:82
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:41
void SetContentModified(bool aModified=true)
Definition base_screen.h:59
constexpr void SetOrigin(const Vec &pos)
Definition box2.h:237
constexpr void SetSize(const SizeVec &size)
Definition box2.h:248
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 setupUnits(APP_SETTINGS_BASE *aCfg)
virtual void SwitchCanvas(EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType)
Change the current rendering backend.
GAL_DISPLAY_OPTIONS_IMPL & GetGalDisplayOptions()
Return a reference to the gal rendering options used by GAL for rendering.
virtual void resolveCanvasType()
Determine the canvas type to load (with prompt if required) and initializes m_canvasType.
static const wxString PropertiesPaneName()
EDA_MSG_PANEL * m_messagePanel
virtual void SetScreen(BASE_SCREEN *aScreen)
bool LibraryFileBrowser(const wxString &aTitle, bool doOpen, wxFileName &aFilename, const wxString &wildcard, const wxString &ext, bool isDirectory, FILEDLG_HOOK_NEW_LIBRARY *aFileDlgHook=nullptr)
void FocusOnLocation(const VECTOR2I &aPos, bool aAllowScroll=true)
Useful to focus on a particular location, in find functions.
PROPERTIES_PANEL * m_propertiesPanel
void ForceRefresh()
Force a redraw.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
KIGFX::GAL * GetGAL() const
Return a pointer to the GAL instance used in the panel.
void SetEventDispatcher(TOOL_DISPATCHER *aEventDispatcher)
Set a dispatcher that processes events and forwards them to tools.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
virtual const VECTOR2I GetFocusPosition() const
Similar to GetPosition() but allows items to return their visual center rather than their anchor.
Definition eda_item.h:279
const KIID m_Uuid
Definition eda_item.h:516
void ClearBrightened()
Definition eda_item.h:138
void SetBrightened()
Definition eda_item.h:135
bool IsBrightened() const
Definition eda_item.h:129
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:80
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.
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:42
int ShowModal() override
Definition kidialog.cpp:93
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:206
void ClearHiddenFlags()
Clear the hide flag of all items in the view.
Definition sch_view.cpp:194
bool IsSCH_ITEM() const
Definition view_item.h:101
void Clear()
Remove all items from the view.
Definition view.cpp:1143
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:1561
Definition kiid.h:49
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
std::string & GetPayload()
Return the payload, which can be any text but it typically self identifying s-expression.
MAIL_T Command()
Returns the MAIL_T associated with this mail.
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:292
void OnKiCadExit()
Definition kiway.cpp:756
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:403
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:507
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.
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) const
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:49
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition lib_id.cpp:111
bool IsValid() const
Check if this LID_ID is valid.
Definition lib_id.h:172
const UTF8 & GetLibItemName() const
Definition lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:87
Symbol library management helper that is specific to the symbol library editor frame.
Define a library symbol object.
Definition lib_symbol.h:83
const LIB_ID & GetLibId() const override
Definition lib_symbol.h:153
bool UnitsLocked() const
Check whether symbol units are interchangeable.
Definition lib_symbol.h:288
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition lib_symbol.h:203
wxString GetName() const override
Definition lib_symbol.h:146
bool IsMultiUnit() const override
Definition lib_symbol.h:742
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:472
void CenterLibId(const LIB_ID &aLibId)
Ensure that an item is visible (preferably centered).
Definition lib_tree.cpp:381
int GetSelectionCount() const
Definition lib_tree.h:90
void ShutdownPreviews()
Definition lib_tree.cpp:287
void ShowChangedLanguage()
Definition lib_tree.cpp:304
void FocusSearchFieldIfExists()
Focus the search widget if it exists.
Definition lib_tree.cpp:487
void SelectLibId(const LIB_ID &aLibId)
Select an item in the tree widget.
Definition lib_tree.cpp:375
LIB_TREE_MODEL_ADAPTER::SORT_MODE GetSortMode() const
Definition lib_tree.h: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:334
void Unselect()
Unselect currently selected item in wxDataViewCtrl.
Definition lib_tree.cpp:387
LIB_ID GetSelectedLibId(int *aUnit=nullptr) const
For multi-unit symbols, if the user selects the symbol itself rather than picking an individual unit,...
Definition lib_tree.cpp:314
void ExpandLibId(const LIB_ID &aLibId)
Expand and item i the tree widget.
Definition lib_tree.cpp:395
void Regenerate(bool aKeepState)
Regenerate the tree.
Definition lib_tree.cpp:454
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
Definition pgm_base.cpp:783
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:129
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:131
A holder to handle information on schematic or board items.
void ClearListAndDeleteItems(std::function< void(EDA_ITEM *)> aItemDeleter)
Delete the list of pickers AND the data pointed by #m_PickedItem or #m_PickedItemLink according to th...
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
@ SCH_LIBEDIT_CUR_LIB
Definition project.h:222
@ SCH_LIBEDIT_CUR_SYMBOL
Definition project.h:223
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:167
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:339
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:350
Action handler for the Properties panel.
Gather all the actions that are shared by tools.
Definition sch_actions.h:40
static TOOL_ACTION rotateCCW
static TOOL_ACTION importSymbol
static TOOL_ACTION newSymbol
static TOOL_ACTION saveLibraryAs
static TOOL_ACTION mirrorV
static TOOL_ACTION editLibSymbolWithLibEdit
static TOOL_ACTION drawArc
Definition sch_actions.h:97
static TOOL_ACTION pinTable
static TOOL_ACTION drawSymbolLines
static TOOL_ACTION placeSymbolPin
static TOOL_ACTION drawSymbolTextBox
static TOOL_ACTION drawRectangle
Definition sch_actions.h:95
static TOOL_ACTION drawCircle
Definition sch_actions.h:96
static TOOL_ACTION importGraphics
static TOOL_ACTION drawBezier
Definition sch_actions.h:98
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:167
int GetBodyStyle() const
Definition sch_item.h:247
int GetUnit() const
Definition sch_item.h:238
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:76
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:811
const LIB_ID & GetLibId() const override
Definition sch_symbol.h:165
int GetOrientation() const override
Get the display symbol orientation.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition sch_symbol.h:184
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.
The symbol library editor main window.
void OnExitKiCad(wxCommandEvent &event)
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
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 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.
void OnSelectBodyStyle(wxCommandEvent &event)
bool backupFile(const wxFileName &aOriginalFile, const wxString &aBackupExt)
Return currently edited symbol.
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
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
SYMBOL_EDITOR_SETTINGS * GetSettings() const
SCH_SCREEN * m_dummyScreen
< Helper screen used when no symbol is loaded
void KiwayMailIn(KIWAY_EXPRESS &mail) override
Receive KIWAY_EXPRESS messages from other players.
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)
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.
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
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 UpdateLibraryTree(const wxDataViewItem &aTreeItem, LIB_SYMBOL *aSymbol)
Update a symbol node in the library tree.
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.
TOOL_MANAGER * m_toolManager
TOOL_DISPATCHER * m_toolDispatcher
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
ACTIONS * m_actions
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition tool_base.h:80
virtual void DispatchWxEvent(wxEvent &aEvent)
Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those.
Master controller class:
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
A holder to handle a list of undo (or redo) commands.
bool empty() const
Definition utf8.h:110
A modified version of the wxInfoBar class that allows us to:
Definition wx_infobar.h:76
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
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:202
int UnsavedChangesDialog(wxWindow *parent, const wxString &aMessage, bool *aApplyToAll)
A specialized version of HandleUnsavedChanges which handles an apply-to-all checkbox.
Definition confirm.cpp:64
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:177
This file is part of the common library.
#define CHECK(x)
#define ENABLE(x)
static bool empty(const wxTextEntryBase *aCtrl)
#define _(s)
#define KICAD_DEFAULT_DRAWFRAME_STYLE
#define LIB_EDIT_FRAME_NAME
@ ID_LIBEDIT_SELECT_UNIT_NUMBER
Definition eeschema_id.h:65
@ ID_LIBEDIT_SELECT_BODY_STYLE
Definition eeschema_id.h:66
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:35
@ FRAME_SCH
Definition frame_type.h:34
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.
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
PROJECT & Prj()
Definition kicad.cpp:629
KIID niluuid(0)
@ LAYER_SCHEMATIC_GRID_AXES
Definition layer_ids.h:487
LIBRARY_TABLE_SCOPE
@ MAIL_LIB_EDIT
Definition mail_type.h:55
@ MAIL_REFRESH_SYMBOL
Definition mail_type.h:59
@ MAIL_RELOAD_LIB
Definition mail_type.h:57
@ ALL
All except INITIAL_ADD.
Definition view_item.h:59
void SetShutdownBlockReason(wxWindow *aWindow, const wxString &aReason)
Sets the block reason why the window/application is preventing OS shutdown.
Definition unix/app.cpp:90
bool SupportsShutdownBlockReason()
Whether or not the window supports setting a shutdown block reason.
Definition unix/app.cpp:79
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition kicad_algo.h:100
#define _HKI(x)
Definition page_info.cpp:44
void InvokeSchEditSymbolLibTable(KIWAY *aKiway, wxWindow *aParent)
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
PGM_BASE & Pgm()
The global program "get" accessor.
Definition pgm_base.cpp:946
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
@ SYM_ORIENT_270
Definition symbol.h:42
@ SYM_MIRROR_Y
Definition symbol.h:44
@ SYM_ORIENT_180
Definition symbol.h:41
@ SYM_MIRROR_X
Definition symbol.h:43
@ SYM_ORIENT_90
Definition symbol.h:40
#define EDIT_TOOL(tool)
#define DEMORGAN_ALT
#define DEMORGAN_STD
KIBIS_PIN * pin
#define ENVVARS_CHANGED
wxLogTrace helper definitions.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
VECTOR2< double > VECTOR2D
Definition vector2d.h:694
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.