KiCad PCB EDA Suite
Loading...
Searching...
No Matches
symbol_viewer_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) 2018 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 <wx/tokenzr.h>
23#include <bitmaps.h>
25#include <confirm.h>
27#include <eeschema_id.h>
28#include <eeschema_settings.h>
31#include <kiface_base.h>
32#include <kiway.h>
33#include <kiway_mail.h>
34#include <locale_io.h>
35#include <symbol_viewer_frame.h>
36#include <widgets/msgpanel.h>
37#include <widgets/wx_listbox.h>
40#include <sch_view.h>
41#include <sch_painter.h>
43#include <pgm_base.h>
45#include <project_sch.h>
47#include <tool/action_toolbar.h>
48#include <tool/common_control.h>
49#include <tool/common_tools.h>
51#include <tool/selection.h>
53#include <tool/tool_manager.h>
54#include <tool/zoom_tool.h>
55#include <tools/sch_actions.h>
58#include <view/view_controls.h>
59#include <wx/srchctrl.h>
60#include <wx/log.h>
61#include <wx/choice.h>
63#include <trace_helpers.h>
64
65#include <default_values.h>
66#include <string_utils.h>
68
69#include "eda_pattern_match.h"
70
71// Save previous symbol library viewer state.
73
76
77
78BEGIN_EVENT_TABLE( SYMBOL_VIEWER_FRAME, SCH_BASE_FRAME )
79 // Window events
82
83 // Toolbar events
88
89 // listbox events
95
96 // Menu (and/or hotkey) events
98
99END_EVENT_TABLE()
100
101
102SYMBOL_VIEWER_FRAME::SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
103 SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_VIEWER, _( "Symbol Library Browser" ), wxDefaultPosition,
105 m_unitChoice( nullptr ),
106 m_bodyStyleChoice( nullptr ),
107 m_libList( nullptr ),
108 m_symbolList( nullptr )
109{
110 m_aboutTitle = _HKI( "KiCad Symbol Library Browser" );
111
112 // Force the frame name used in config. the lib viewer frame has a name
113 // depending on aFrameType (needed to identify the frame by wxWidgets),
114 // but only one configuration is preferable.
116
117 // Give an icon
118 wxIcon icon;
119 icon.CopyFromBitmap( KiBitmap( BITMAPS::library_browser ) );
120 SetIcon( icon );
121
122 m_libListWidth = 200;
123 m_symbolListWidth = 300;
124 m_listPowerOnly = false;
125
126 SetScreen( new SCH_SCREEN );
127 GetScreen()->m_Center = true; // Axis origin centered on screen.
128 LoadSettings( config() );
129
130 // Ensure axis are always drawn (initial default display was not drawn)
132 gal_opts.m_axesEnabled = true;
133 gal_opts.m_gridMinSpacing = 10.0;
134 gal_opts.NotifyChanged();
135
136 GetRenderSettings()->LoadColors( GetColorSettings() );
137 GetCanvas()->GetGAL()->SetAxesColor( m_colorSettings->GetColor( LAYER_SCHEMATIC_GRID_AXES ) );
138
139 GetRenderSettings()->SetDefaultPenWidth( DEFAULT_LINE_WIDTH_MILS * schIUScale.IU_PER_MILS );
140
141 setupTools();
143
147
149
150 wxPanel* libPanel = new wxPanel( this );
151 wxSizer* libSizer = new wxBoxSizer( wxVERTICAL );
152
153 m_libFilter = new wxSearchCtrl( libPanel, ID_LIBVIEW_LIB_FILTER, wxEmptyString, wxDefaultPosition,
154 wxDefaultSize, wxTE_PROCESS_ENTER );
155 m_libFilter->SetDescriptiveText( _( "Filter" ) );
156 libSizer->Add( m_libFilter, 0, wxEXPAND, 5 );
157
158 m_libList = new WX_LISTBOX( libPanel, ID_LIBVIEW_LIB_LIST, wxDefaultPosition, wxDefaultSize, 0, nullptr,
159 wxLB_HSCROLL | wxNO_BORDER );
160 libSizer->Add( m_libList, 1, wxEXPAND, 5 );
161
162 libPanel->SetSizer( libSizer );
163 libPanel->Fit();
164
165 wxPanel* symbolPanel = new wxPanel( this );
166 wxSizer* symbolSizer = new wxBoxSizer( wxVERTICAL );
167
168 m_symbolFilter = new wxSearchCtrl( symbolPanel, ID_LIBVIEW_SYM_FILTER, wxEmptyString, wxDefaultPosition,
169 wxDefaultSize, wxTE_PROCESS_ENTER );
170 m_symbolFilter->SetDescriptiveText( _( "Filter" ) );
171 m_symbolFilter->SetToolTip( _( "Filter on symbol name, keywords, description and pin count.\n"
172 "Search terms are separated by spaces. All search terms must match.\n"
173 "A term which is a number will also match against the pin count." ) );
174 symbolSizer->Add( m_symbolFilter, 0, wxEXPAND, 5 );
175
176#ifdef __WXGTK__
177 // wxSearchCtrl vertical height is not calculated correctly on some GTK setups
178 // See https://gitlab.com/kicad/code/kicad/-/issues/9019
179 m_libFilter->SetMinSize( wxSize( -1, GetTextExtent( wxT( "qb" ) ).y + 10 ) );
180 m_symbolFilter->SetMinSize( wxSize( -1, GetTextExtent( wxT( "qb" ) ).y + 10 ) );
181#endif
182
183 m_symbolList = new WX_LISTBOX( symbolPanel, ID_LIBVIEW_SYM_LIST, wxDefaultPosition, wxDefaultSize, 0, nullptr,
184 wxLB_HSCROLL | wxNO_BORDER );
185 symbolSizer->Add( m_symbolList, 1, wxEXPAND, 5 );
186
187 symbolPanel->SetSizer( symbolSizer );
188 symbolPanel->Fit();
189
190 // Preload libraries
192
193 m_selection_changed = false;
194
196
197 m_auimgr.SetManagedWindow( this );
198
200
201 // Manage main toolbar
202 m_auimgr.AddPane( m_tbTopMain, EDA_PANE().HToolbar().Name( "TopMainToolbar" ).Top().Layer(6) );
203 m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( "MsgPanel" ) .Bottom().Layer(6) );
204
205 m_auimgr.AddPane( libPanel, EDA_PANE().Palette().Name( "Libraries" ).Left().Layer(2)
206 .CaptionVisible( false ).MinSize( 100, -1 ).BestSize( 200, -1 ) );
207 m_auimgr.AddPane( symbolPanel, EDA_PANE().Palette().Name( "Symbols" ).Left().Layer(1)
208 .CaptionVisible( false ).MinSize( 100, -1 ).BestSize( 300, -1 ) );
209
210 m_auimgr.AddPane( GetCanvas(), EDA_PANE().Canvas().Name( "DrawFrame" ).Center() );
211
213 m_auimgr.Update();
214
215 if( m_libListWidth > 0 )
216 SetAuiPaneSize( m_auimgr, m_auimgr.GetPane( "Libraries" ), m_libListWidth, -1 );
217
218 if( m_symbolListWidth > 0 )
219 SetAuiPaneSize( m_auimgr, m_auimgr.GetPane( "Symbols" ), m_symbolListWidth, -1 );
220
222
223 Raise();
224 Show( true );
225
226 SyncView();
227 GetCanvas()->SetCanFocus( false );
228
229 setupUnits( config() );
230
231 // Set the working/draw area size to display a symbol to a reasonable value:
232 // A 450mm x 450mm with a origin at the area center looks like a large working area
233 double max_size_x = schIUScale.mmToIU( 450 );
234 double max_size_y = schIUScale.mmToIU( 450 );
235 BOX2D bbox;
236 bbox.SetOrigin( -max_size_x / 2, -max_size_y / 2 );
237 bbox.SetSize( max_size_x, max_size_y );
238 GetCanvas()->GetView()->SetBoundary( bbox );
240
241 // If a symbol was previously selected in m_symbolList from a previous run, show it
242 wxString symbName = m_symbolList->GetStringSelection();
243
244 if( !symbName.IsEmpty() )
245 {
246 SetSelectedSymbol( symbName );
248 }
249}
250
251
253{
254 // Shutdown all running tools
255 if( m_toolManager )
256 m_toolManager->ShutdownAllTools();
257
258 if( m_previewItem )
259 {
260 GetCanvas()->GetView()->Remove( m_previewItem.get() );
261 m_previewItem = nullptr;
262 }
263}
264
265
267{
268 // Create the manager and dispatcher & route draw panel events to the dispatcher
270 m_toolManager->SetEnvironment( GetScreen(), GetCanvas()->GetView(), GetCanvas()->GetViewControls(), config(),
271 this );
272 m_actions = new SCH_ACTIONS();
274
275 // Register tools
276 m_toolManager->RegisterTool( new COMMON_TOOLS );
277 m_toolManager->RegisterTool( new COMMON_CONTROL );
278 m_toolManager->RegisterTool( new ZOOM_TOOL );
279 m_toolManager->RegisterTool( new SCH_INSPECTION_TOOL ); // manage show datasheet
280 m_toolManager->RegisterTool( new SCH_SELECTION_TOOL ); // manage context menu
281 m_toolManager->RegisterTool( new SYMBOL_EDITOR_CONTROL ); // manage render settings
282
283 m_toolManager->InitTools();
284
285 // Run the selection tool, it is supposed to be always active
286 // It also manages the mouse right click to show the context menu
287 m_toolManager->InvokeTool( "common.InteractiveSelection" );
288
290}
291
292
294{
296
297 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
298 EDITOR_CONDITIONS cond( this );
299
300 wxASSERT( mgr );
301
302#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
303#define CHECK( x ) ACTION_CONDITIONS().Check( x )
304
306
307 auto electricalTypesShownCondition =
308 [this]( const SELECTION& aSel )
309 {
311 };
312
313 auto pinNumbersShownCondition =
314 [this]( const SELECTION& )
315 {
317 };
318
319 auto haveDatasheetCond =
320 [this]( const SELECTION& )
321 {
322 LIB_SYMBOL* symbol = GetSelectedSymbol();
323 return symbol && !symbol->GetDatasheetField().GetText().IsEmpty();
324 };
325
326 mgr->SetConditions( ACTIONS::showDatasheet, ENABLE( haveDatasheetCond ) );
327 mgr->SetConditions( SCH_ACTIONS::showElectricalTypes, CHECK( electricalTypesShownCondition ) );
328 mgr->SetConditions( SCH_ACTIONS::showPinNumbers, CHECK( pinNumbersShownCondition ) );
329
330#undef CHECK
331#undef ENABLE
332}
333
334
335void SYMBOL_VIEWER_FRAME::SetUnitAndBodyStyle( int aUnit, int aBodyStyle )
336{
337 m_unit = aUnit > 0 ? aUnit : 1;
338 m_bodyStyle = aBodyStyle > 0 ? aBodyStyle : BODY_STYLE::BASE;
339 m_selection_changed = false;
340
342}
343
344
346{
347 LIB_SYMBOL* symbol = nullptr;
348
349 if( m_currentSymbol.IsValid() )
351
352 return symbol;
353}
354
355
357{
358 LIB_SYMBOL* symbol = GetSelectedSymbol();
359 KIGFX::SCH_VIEW* view = GetCanvas()->GetView();
360
361 if( m_previewItem )
362 {
363 view->Remove( m_previewItem.get() );
364 m_previewItem = nullptr;
365 }
366
368
369 if( symbol )
370 {
373
374 m_previewItem = symbol->Flatten();
375 view->Add( m_previewItem.get() );
376
377 wxString parentName;
378
379 if( std::shared_ptr<LIB_SYMBOL> parent = symbol->GetParent().lock() )
380 parentName = parent->GetName();
381
382 AppendMsgPanel( _( "Name" ), UnescapeString( m_previewItem->GetName() ) );
383 AppendMsgPanel( _( "Parent" ), UnescapeString( parentName ) );
384 AppendMsgPanel( _( "Description" ), m_previewItem->GetDescription() );
385 AppendMsgPanel( _( "Keywords" ), m_previewItem->GetKeyWords() );
386 }
387
389 GetCanvas()->Refresh();
390
393}
394
395
397{
399
400 delete m_toolManager;
401 m_toolManager = nullptr;
402
403 Destroy();
404}
405
406
407void SYMBOL_VIEWER_FRAME::OnSize( wxSizeEvent& SizeEv )
408{
409 if( m_auimgr.GetManagedWindow() )
410 m_auimgr.Update();
411
412 SizeEv.Skip();
413}
414
415
417{
418 LIB_SYMBOL* symbol = GetSelectedSymbol();
419
420 int unit_count = 1;
421
422 if( symbol )
423 unit_count = std::max( symbol->GetUnitCount(), 1 );
424
425 m_unitChoice->Enable( unit_count > 1 );
426 m_unitChoice->Clear();
427
428 if( unit_count > 1 )
429 {
430 // rebuild the unit list if it is not suitable (after a new selection for instance)
431 if( unit_count != (int) m_unitChoice->GetCount() )
432 {
433 for( int ii = 0; ii < unit_count; ii++ )
434 m_unitChoice->Append( symbol->GetUnitDisplayName( ii + 1, true ) );
435 }
436
437 if( m_unitChoice->GetSelection() != std::max( 0, m_unit - 1 ) )
438 m_unitChoice->SetSelection( std::max( 0, m_unit - 1 ) );
439 }
440}
441
442
444{
445 LIB_SYMBOL* symbol = GetSelectedSymbol();
446
447 int bodyStyle_count = 1;
448
449 if( symbol )
450 bodyStyle_count = std::max( symbol->GetBodyStyleCount(), 1 );
451
452 m_bodyStyleChoice->Enable( bodyStyle_count > 1 );
453 m_bodyStyleChoice->Clear();
454
455 if( bodyStyle_count > 1 )
456 {
457 if( symbol && symbol->HasDeMorganBodyStyles() )
458 {
459 m_bodyStyleChoice->Append( wxGetTranslation( DEMORGAN_STD ) );
460 m_bodyStyleChoice->Append( wxGetTranslation( DEMORGAN_ALT ) );
461 }
462 else if( symbol )
463 {
464 for( int i = 0; i < symbol->GetBodyStyleCount(); i++ )
465 m_bodyStyleChoice->Append( symbol->GetBodyStyleNames()[i] );
466 }
467
468 if( m_bodyStyleChoice->GetSelection() != std::max( 0, m_bodyStyle - 1 ) )
469 m_bodyStyleChoice->SetSelection( std::max( 0, m_bodyStyle - 1 ) );
470 }
471}
472
473
475{
476 if( !m_libList )
477 return false;
478
479 m_libList->Clear();
480
484 std::vector<wxString> libNicknames = adapter->GetLibraryNames();
485 std::vector<wxString> pinnedMatches;
486 std::vector<wxString> otherMatches;
487
488 auto doAddLib =
489 [&]( const wxString& aLib )
490 {
491 if( alg::contains( project.m_PinnedSymbolLibs, aLib )
493 {
494 pinnedMatches.push_back( aLib );
495 }
496 else
497 {
498 otherMatches.push_back( aLib );
499 }
500 };
501
502 auto process =
503 [&]( const wxString& aLib )
504 {
505 // Remove not allowed libs, if the allowed lib list is not empty
506 if( m_allowedLibs.GetCount() )
507 {
508 if( m_allowedLibs.Index( aLib ) == wxNOT_FOUND )
509 return;
510 }
511
512 // Remove libs which have no power symbols, if this filter is activated
513 if( m_listPowerOnly )
514 {
515 std::vector<wxString> symbolNames = adapter->GetSymbolNames(
517
518 if( symbolNames.empty() )
519 return;
520 }
521
522 LIBRARY_TABLE_ROW* row = adapter->GetRow( aLib ).value_or( nullptr );
523 wxCHECK( row, /* void */ );
524
525 if( row->Hidden() )
526 return;
527
528 if( adapter->SupportsSubLibraries( aLib ) )
529 {
530 for( const auto& [nickname, description] : adapter->GetSubLibraries( aLib ) )
531 {
532 wxString suffix = nickname.IsEmpty() ? wxString( wxT( "" ) )
533 : wxString::Format( wxT( " - %s" ), nickname );
534 wxString name = wxString::Format( wxT( "%s%s" ), aLib, suffix );
535
536 doAddLib( name );
537 }
538 }
539 else
540 {
541 doAddLib( aLib );
542 }
543 };
544
545 if( m_libFilter->GetValue().IsEmpty() )
546 {
547 for( const wxString& lib : libNicknames )
548 process( lib );
549 }
550 else
551 {
552 wxStringTokenizer tokenizer( m_libFilter->GetValue(), " \t\r\n", wxTOKEN_STRTOK );
553
554 while( tokenizer.HasMoreTokens() )
555 {
556 const wxString term = tokenizer.GetNextToken().Lower();
557 EDA_COMBINED_MATCHER matcher( term, CTX_LIBITEM );
558
559 for( const wxString& lib : libNicknames )
560 {
561 if( matcher.Find( lib.Lower() ) )
562 process( lib );
563 }
564 }
565 }
566
567 if( libNicknames.empty() )
568 return true;
569
570 for( const wxString& name : pinnedMatches )
572
573 for( const wxString& name : otherMatches )
574 m_libList->Append( UnescapeString( name ) );
575
576 // Search for a previous selection:
577 int index = m_libList->FindString( UnescapeString( m_currentSymbol.GetUniStringLibNickname() ) );
578
579 if( index != wxNOT_FOUND )
580 {
581 m_libList->SetSelection( index, true );
582 }
583 else
584 {
585 // If not found, clear current library selection because it can be deleted after a
586 // config change.
587 m_currentSymbol.SetLibNickname( m_libList->GetCount() > 0 ? m_libList->GetBaseString( 0 )
588 : wxString( wxEmptyString ) );
589 m_currentSymbol.SetLibItemName( wxEmptyString );
590 m_unit = 1;
592 }
593
594 bool cmp_changed = ReCreateSymbolList();
596 GetCanvas()->Refresh();
597
598 return cmp_changed;
599}
600
601
603{
604 if( m_symbolList == nullptr )
605 return false;
606
607 m_symbolList->Clear();
608
609 wxString libName = m_currentSymbol.GetUniStringLibNickname();
610
611 if( libName.IsEmpty() )
612 return false;
613
615 std::vector<LIB_SYMBOL*> symbols = adapter->GetSymbols( libName );
616
617 std::sort( symbols.begin(), symbols.end(),
618 []( LIB_SYMBOL* a, LIB_SYMBOL* b ) -> bool
619 {
620 return StrNumCmp( b->GetName(), a->GetName(), true ) > 0;
621 } );
622
623 std::set<wxString> excludes;
624
625 if( !m_symbolFilter->GetValue().IsEmpty() )
626 {
627 wxStringTokenizer tokenizer( m_symbolFilter->GetValue(), " \t\r\n", wxTOKEN_STRTOK );
628
629 while( tokenizer.HasMoreTokens() )
630 {
631 const wxString filterTerm = tokenizer.GetNextToken().Lower();
632 EDA_COMBINED_MATCHER matcher( filterTerm, CTX_LIBITEM );
633
634 for( LIB_SYMBOL* symbol : symbols )
635 {
636 int matched = matcher.ScoreTerms( symbol->GetSearchTerms() );
637
638 if( filterTerm.IsNumber() && wxAtoi( filterTerm ) == (int)symbol->GetPinCount() )
639 matched++;
640
641 if( !matched )
642 excludes.insert( symbol->GetName() );
643 }
644 }
645 }
646
647 wxString subLib = m_currentSymbol.GetSubLibraryName();
648
649 for( const LIB_SYMBOL* symbol : symbols )
650 {
651 if( adapter->SupportsSubLibraries( libName )
652 && !subLib.IsSameAs( symbol->GetLibId().GetSubLibraryName() ) )
653 {
654 continue;
655 }
656
657 if( !excludes.count( symbol->GetName() ) )
658 m_symbolList->Append( UnescapeString( symbol->GetName() ) );
659 }
660
661 if( m_symbolList->IsEmpty() )
662 {
663 SetSelectedSymbol( wxEmptyString );
665 m_unit = 1;
666 return true;
667 }
668
669 int index = m_symbolList->FindString( UnescapeString( m_currentSymbol.GetUniStringLibItemName() ) );
670 bool changed = false;
671
672 if( index == wxNOT_FOUND )
673 {
674 // Select the first library entry when the previous entry name does not exist in
675 // the current library.
677 m_unit = 1;
678 index = -1;
679 changed = true;
680 SetSelectedSymbol( wxEmptyString );
681 }
682
683 m_symbolList->SetSelection( index, true );
684
685 return changed;
686}
687
688
689void SYMBOL_VIEWER_FRAME::ClickOnLibList( wxCommandEvent& event )
690{
691 int ii = m_libList->GetSelection();
692
693 if( ii < 0 )
694 return;
695
696 m_selection_changed = true;
697
698 wxString selection = EscapeString( m_libList->GetBaseString( ii ), CTX_LIBID );
699
701
702 if( !adapter->HasLibrary( selection ) && selection.Find( '-' ) != wxNOT_FOUND )
703 {
704 // Probably a sub-library
705 wxString sublib;
706 selection = selection.BeforeLast( '-', &sublib ).Trim();
707 sublib.Trim( false );
708 SetSelectedLibrary( selection, sublib );
709 }
710 else
711 {
712 SetSelectedLibrary( selection );
713 }
714}
715
716
717void SYMBOL_VIEWER_FRAME::SetSelectedLibrary( const wxString& aLibraryName, const wxString& aSubLibName )
718{
719 if( m_currentSymbol.GetUniStringLibNickname() == aLibraryName
720 && wxString( m_currentSymbol.GetSubLibraryName().wx_str() ) == aSubLibName )
721 {
722 return;
723 }
724
725 m_currentSymbol.SetLibNickname( aLibraryName );
726 m_currentSymbol.SetSubLibraryName( aSubLibName );
728 GetCanvas()->Refresh();
730
731 // Ensure the corresponding line in m_libList is selected
732 // (which is not necessary the case if SetSelectedLibrary is called
733 // by another caller than ClickOnLibList.
734 m_libList->SetStringSelection( UnescapeString( m_currentSymbol.GetFullLibraryName() ), true );
735
736 // The m_libList has now the focus, in order to be able to use arrow keys
737 // to navigate inside the list.
738 // the gal canvas must not steal the focus to allow navigation
739 GetCanvas()->SetStealsFocus( false );
740 m_libList->SetFocus();
741}
742
743
744void SYMBOL_VIEWER_FRAME::ClickOnSymbolList( wxCommandEvent& event )
745{
746 int ii = m_symbolList->GetSelection();
747
748 if( ii < 0 )
749 return;
750
751 m_selection_changed = true;
752
753 SetSelectedSymbol( EscapeString( m_symbolList->GetBaseString( ii ), CTX_LIBID ) );
754
755 // The m_symbolList has now the focus, in order to be able to use arrow keys
756 // to navigate inside the list.
757 // the gal canvas must not steal the focus to allow navigation
758 GetCanvas()->SetStealsFocus( false );
759 m_symbolList->SetFocus();
760}
761
762
763void SYMBOL_VIEWER_FRAME::SetSelectedSymbol( const wxString& aSymbolName )
764{
765 if( m_currentSymbol.GetUniStringLibItemName() != aSymbolName )
766 {
767 m_currentSymbol.SetLibItemName( aSymbolName );
768
769 // Ensure the corresponding line in m_symbolList is selected
770 // (which is not necessarily the case if SetSelectedSymbol is called
771 // by another caller than ClickOnSymbolList.
772 m_symbolList->SetStringSelection( UnescapeString( aSymbolName ), true );
774
776 {
777 m_unit = 1;
779 m_selection_changed = false;
780 }
781
783 }
784}
785
786
787void SYMBOL_VIEWER_FRAME::DClickOnSymbolList( wxCommandEvent& event )
788{
790}
791
792
794{
796
798 {
799 // Grid shape, etc.
800 GetGalDisplayOptions().ReadWindowSettings( cfg->m_LibViewPanel.window );
801
802 m_libListWidth = cfg->m_LibViewPanel.lib_list_width;
803 m_symbolListWidth = cfg->m_LibViewPanel.cmp_list_width;
804
805 GetRenderSettings()->m_ShowPinsElectricalType = cfg->m_LibViewPanel.show_pin_electrical_type;
806 GetRenderSettings()->m_ShowPinNumbers = cfg->m_LibViewPanel.show_pin_numbers;
807
808 // Set parameters to a reasonable value.
809 int maxWidth = cfg->m_LibViewPanel.window.state.size_x - 80;
810
811 if( m_libListWidth + m_symbolListWidth > maxWidth )
812 {
815 }
816 }
817}
818
819
821{
823
825 m_libListWidth = m_libList->GetSize().x;
826
827 m_symbolListWidth = m_symbolList->GetSize().x;
828
830 {
831 cfg->m_LibViewPanel.lib_list_width = m_libListWidth;
832 cfg->m_LibViewPanel.cmp_list_width = m_symbolListWidth;
833
834 if( SCH_RENDER_SETTINGS* renderSettings = GetRenderSettings() )
835 {
836 cfg->m_LibViewPanel.show_pin_electrical_type = renderSettings->m_ShowPinsElectricalType;
837 cfg->m_LibViewPanel.show_pin_numbers = renderSettings->m_ShowPinNumbers;
838 }
839 }
840}
841
842
844{
845 if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( aCfg ) )
846 return &cfg->m_LibViewPanel.window;
847
848 wxFAIL_MSG( wxT( "SYMBOL_VIEWER not running with EESCHEMA_SETTINGS" ) );
849 return &aCfg->m_Window; // non-null fail-safe
850}
851
852
854{
856
858 GetGalDisplayOptions().ReadWindowSettings( cfg->m_LibViewPanel.window );
859
861 GetCanvas()->GetGAL()->DrawGrid();
863
864 if( aFlags && ENVVARS_CHANGED )
866}
867
868
869void SYMBOL_VIEWER_FRAME::OnActivate( wxActivateEvent& event )
870{
871 if( event.GetActive() )
872 {
873 bool changed = m_libList ? ReCreateLibList() : false;
874
875 if (changed)
876 m_selection_changed = true;
877
879
881 }
882
883 event.Skip(); // required under wxMAC
884}
885
886
887void SYMBOL_VIEWER_FRAME::CloseLibraryViewer( wxCommandEvent& event )
888{
889 Close();
890}
891
892
893const BOX2I SYMBOL_VIEWER_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
894{
895 if( LIB_SYMBOL* symbol = GetSelectedSymbol() )
896 return symbol->GetUnitBoundingBox( m_unit, m_bodyStyle );
897
898 return BOX2I( VECTOR2I( -200, -200 ), VECTOR2I( 400, 400 ) );
899}
900
901
902void SYMBOL_VIEWER_FRAME::OnLibFilter( wxCommandEvent& aEvent )
903{
905
906 // Required to avoid interaction with SetHint()
907 // See documentation for wxTextEntry::SetHint
908 aEvent.Skip();
909}
910
911
912void SYMBOL_VIEWER_FRAME::OnSymFilter( wxCommandEvent& aEvent )
913{
915
916 // Required to avoid interaction with SetHint()
917 // See documentation for wxTextEntry::SetHint
918 aEvent.Skip();
919}
920
921
922void SYMBOL_VIEWER_FRAME::OnCharHook( wxKeyEvent& aEvent )
923{
924 if( aEvent.GetKeyCode() == WXK_UP )
925 {
926 if( m_libFilter->HasFocus() || m_libList->HasFocus() )
927 {
928 int prev = m_libList->GetSelection() - 1;
929
930 if( prev >= 0 )
931 {
932 m_libList->SetSelection( prev );
933 m_libList->EnsureVisible( prev );
934
935 wxCommandEvent dummy;
937 }
938 }
939 else
940 {
942 }
943 }
944 else if( aEvent.GetKeyCode() == WXK_DOWN )
945 {
946 if( m_libFilter->HasFocus() || m_libList->HasFocus() )
947 {
948 int next = m_libList->GetSelection() + 1;
949
950 if( next < (int)m_libList->GetCount() )
951 {
952 m_libList->SetSelection( next );
953 m_libList->EnsureVisible( next );
954
955 wxCommandEvent dummy;
957 }
958 }
959 else
960 {
962 }
963 }
964 else if( aEvent.GetKeyCode() == WXK_TAB && m_libFilter->HasFocus() )
965 {
966 if( !aEvent.ShiftDown() )
967 m_symbolFilter->SetFocus();
968 else
969 aEvent.Skip();
970 }
971 else if( aEvent.GetKeyCode() == WXK_TAB && m_symbolFilter->HasFocus() )
972 {
973 if( aEvent.ShiftDown() )
974 m_libFilter->SetFocus();
975 else
976 aEvent.Skip();
977 }
978 else if( ( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER )
979 && m_symbolList->GetSelection() >= 0 )
980 {
981 wxCommandEvent dummy;
983 }
984 else
985 {
986 aEvent.Skip();
987 }
988}
989
990
992{
993 wxCommandEvent evt( wxEVT_COMMAND_LISTBOX_SELECTED, ID_LIBVIEW_SYM_LIST );
994 int ii = m_symbolList->GetSelection();
995
996 // Select the next symbol or stop at the end of the list.
997 if( ii != wxNOT_FOUND && ii < (int) ( m_symbolList->GetCount() - 1 ) )
998 ii += 1;
999
1000 m_symbolList->SetSelection( ii );
1001 ProcessEvent( evt );
1002}
1003
1004
1006{
1007 wxCommandEvent evt( wxEVT_COMMAND_LISTBOX_SELECTED, ID_LIBVIEW_SYM_LIST );
1008 int ii = m_symbolList->GetSelection();
1009
1010 // Select the previous symbol or stop at the beginning of list.
1011 if( ii != wxNOT_FOUND && ii != 0 )
1012 ii -= 1;
1013
1014 m_symbolList->SetSelection( ii );
1015 ProcessEvent( evt );
1016}
1017
1018
1019void SYMBOL_VIEWER_FRAME::onSelectSymbolUnit( wxCommandEvent& aEvent )
1020{
1021 int ii = m_unitChoice->GetSelection();
1022
1023 if( ii < 0 )
1024 return;
1025
1026 m_unit = ii + 1;
1027
1029}
1030
1031
1033{
1034 int ii = m_bodyStyleChoice->GetSelection();
1035
1036 if( ii < 0 )
1037 return;
1038
1039 m_bodyStyle = ii + 1;
1040
1042}
1043
1044
1046{
1047 wxString libName = m_currentSymbol.GetUniStringLibNickname();
1048
1049 if( m_libList && !m_libList->IsEmpty() && !libName.IsEmpty() )
1050 {
1052 LIBRARY_TABLE_ROW* row = adapter->GetRow( libName ).value_or( nullptr );
1053
1054 wxString title = row ? LIBRARY_MANAGER::GetFullURI( row, true )
1055 : _( "[no library selected]" );
1056
1057 title += wxT( " \u2014 " ) + _( "Symbol Library Browser" );
1058 SetTitle( title );
1059 }
1060}
1061
1062
1064{
1065 return m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
1066}
1067
1068
1070{
1071
1072 switch( mail.Command() )
1073 {
1074 case MAIL_RELOAD_LIB:
1076 break;
1077
1079 {
1080 LIB_SYMBOL* symbol = GetSelectedSymbol();
1081 wxCHECK2( symbol, break );
1082
1084 LIBRARY_TABLE_ROW* row = adapter->GetRow( symbol->GetLibId().GetLibNickname() ).value_or( nullptr );
1085
1086 if( !row )
1087 return;
1088
1089 wxString libfullname = LIBRARY_MANAGER::GetFullURI( row, true );
1090
1091 wxString lib( mail.GetPayload() );
1092 wxLogTrace( traceLibWatch, "Received refresh symbol request for %s, current symbols is %s", lib, libfullname );
1093
1094 if( lib == libfullname )
1095 {
1096 wxLogTrace( traceLibWatch, "Refreshing symbol %s", symbol->GetName() );
1099 }
1100
1101 break;
1102 }
1103 default:;
1104 }
1105}
int index
const char * name
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
@ library_browser
BOX2< VECTOR2I > BOX2I
Definition box2.h:927
BOX2< VECTOR2D > BOX2D
Definition box2.h:928
static TOOL_ACTION toggleGrid
Definition actions.h:194
static TOOL_ACTION showDatasheet
Definition actions.h:263
static TOOL_ACTION zoomFitScreen
Definition actions.h:138
Manage TOOL_ACTION objects.
void SetConditions(const TOOL_ACTION &aAction, const ACTION_CONDITIONS &aConditions)
Set the conditions the UI elements for activating a specific tool action should use for determining t...
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
WINDOW_SETTINGS m_Window
constexpr void SetOrigin(const Vec &pos)
Definition box2.h:234
constexpr void SetSize(const SizeVec &size)
Definition box2.h:245
Handle actions that are shared between different applications.
Handles action that are shared between different applications.
virtual APP_SETTINGS_BASE * config() const
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
virtual void setupUIConditions()
Setup the UI conditions for the various actions and their controls in this frame.
TOOLBAR_SETTINGS * m_toolbarSettings
wxString m_configName
wxAuiManager m_auimgr
virtual void RecreateToolbars()
bool ProcessEvent(wxEvent &aEvent) override
Override the default process event handler to implement the auto save feature.
ACTION_TOOLBAR * m_tbTopMain
wxString m_aboutTitle
void ReCreateMenuBar()
Recreate the menu bar.
int ScoreTerms(std::vector< SEARCH_TERM > &aWeightedTerms, bool *aExactMatch=nullptr)
bool Find(const wxString &aTerm, int &aMatchersTriggered, int &aPosition)
Look in all existing matchers, return the earliest match of any of the existing.
virtual void ClearMsgPanel()
Clear all messages from the message panel.
COLOR_SETTINGS * m_colorSettings
void OnSelectGrid(wxCommandEvent &event)
Command event handler for selecting grid sizes.
void setupUnits(APP_SETTINGS_BASE *aCfg)
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.
EDA_MSG_PANEL * m_messagePanel
virtual void SetScreen(BASE_SCREEN *aScreen)
void AppendMsgPanel(const wxString &aTextUpper, const wxString &aTextLower, int aPadding=6)
Append a message to the message panel.
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.
void SetStealsFocus(bool aStealsFocus)
Set whether focus is taken on certain events (mouseover, keys, etc).
Specialization of the wxAuiPaneInfo class for KiCad panels.
Class that groups generic conditions for editor states.
SELECTION_CONDITION GridVisible()
Create a functor testing if the grid is visible in a frame.
void ReadWindowSettings(WINDOW_SETTINGS &aCfg)
Read GAL config options from application-level config.
double m_gridMinSpacing
Whether or not to draw the coordinate system axes.
bool m_axesEnabled
Crosshair drawing mode.
void SetAxesColor(const COLOR4D &aAxesColor)
Set the axes color.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition view.cpp:301
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:416
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:1703
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition kiway_mail.h:34
std::string & GetPayload()
Return the payload, which can be any text but it typically self identifying s-expression.
Definition kiway_mail.h:52
MAIL_T Command()
Returns the MAIL_T associated with this mail.
Definition kiway_mail.h:44
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:340
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition kiway.cpp:201
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::vector< wxString > GetLibraryNames() const
Returns a list of library nicknames that are available (skips any that failed to load)
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...
bool Hidden() const
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:83
Define a library symbol object.
Definition lib_symbol.h:119
const LIB_ID & GetLibId() const override
Definition lib_symbol.h:188
std::weak_ptr< LIB_SYMBOL > & GetParent()
Definition lib_symbol.h:150
SCH_FIELD & GetDatasheetField()
Return reference to the datasheet field.
Definition lib_symbol.h:449
wxString GetName() const override
Definition lib_symbol.h:181
const std::vector< wxString > & GetBodyStyleNames() const
bool HasDeMorganBodyStyles() const override
int GetBodyStyleCount() const override
The body styles are a property of the drawings, which a derived symbol inherits from its root symbol ...
int GetUnitCount() const override
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
wxString GetUnitDisplayName(int aUnit, bool aLabel) const override
Return the user-defined display name for aUnit for symbols with units.
static const wxString GetPinningSymbol()
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:546
The backing store for a PROJECT, in JSON format.
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:201
Gather all the actions that are shared by tools.
Definition sch_actions.h:45
static TOOL_ACTION showElectricalTypes
static TOOL_ACTION showPinNumbers
static TOOL_ACTION addSymbolToSchematic
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.
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.
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:138
Handle actions for the various symbol editor and viewers.
An interface to the global shared library manager that is schematic-specific and linked to one projec...
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
std::vector< wxString > GetSymbolNames(const wxString &aNickname, SYMBOL_TYPE aType=SYMBOL_TYPE::ALL_SYMBOLS)
bool SupportsSubLibraries(const wxString &aNickname) const
std::vector< SUB_LIBRARY > GetSubLibraries(const wxString &aNickname) const
std::vector< LIB_SYMBOL * > GetSymbols(const wxString &aNickname, SYMBOL_TYPE aType=SYMBOL_TYPE::ALL_SYMBOLS)
Symbol library viewer main window.
void OnLibFilter(wxCommandEvent &aEvent)
std::unique_ptr< LIB_SYMBOL > m_previewItem
void CloseLibraryViewer(wxCommandEvent &event)
void SetSelectedLibrary(const wxString &aLibName, const wxString &aSubLibName=wxEmptyString)
Set the selected library in the library window.
void ClickOnLibList(wxCommandEvent &event)
SYMBOL_VIEWER_FRAME(KIWAY *aKiway, wxWindow *aParent)
void DClickOnSymbolList(wxCommandEvent &event)
void OnActivate(wxActivateEvent &event)
Called when the frame is activated to reload the libraries and symbol lists that can be changed by th...
void OnSymFilter(wxCommandEvent &aEvent)
void setupUIConditions() override
Setup the UI conditions for the various actions and their controls in this frame.
void SetSelectedSymbol(const wxString &aSymbolName)
Set the selected symbol.
bool ReCreateLibList()
Create o recreates a sorted list of currently loaded libraries.
SELECTION & GetCurrentSelection() override
Get the current selection from the canvas area.
void ClickOnSymbolList(wxCommandEvent &event)
const BOX2I GetDocumentExtents(bool aIncludeAllVisible=true) const override
Return bounding box of document with option to not include some items.
void SetUnitAndBodyStyle(int aUnit, int aBodyStyle)
Set unit and convert, and set flag preventing them from automatically resetting to 1.
wxSearchCtrl * m_symbolFilter
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
WINDOW_SETTINGS * GetWindowSettings(APP_SETTINGS_BASE *aCfg) override
Return a pointer to the window settings for this frame.
void OnCharHook(wxKeyEvent &aEvent) override
Capture the key event before it is sent to the GUI.
void KiwayMailIn(KIWAY_MAIL_EVENT &mail) override
Receive #KIWAY_ROUTED_EVENT messages from other players.
LIB_SYMBOL * GetSelectedSymbol() const
void onSelectSymbolUnit(wxCommandEvent &aEvent)
void OnSize(wxSizeEvent &event) override
Recalculate the size of toolbars and display panel when the frame size changes.
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
void onSelectSymbolBodyStyle(wxCommandEvent &aEvent)
bool m_selection_changed
Updated to true if a list rewrite on GUI activation resulted in the symbol selection changing,...
bool ReCreateSymbolList()
Create or recreate the list of symbols in the currently selected library.
void CommonSettingsChanged(int aFlags) override
Notification event that some of the common (suite-wide) settings have changed.
TOOL_MANAGER * m_toolManager
TOOL_DISPATCHER * m_toolDispatcher
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
ACTIONS * m_actions
Master controller class:
This file is part of the common library.
#define CHECK(x)
#define ENABLE(x)
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
#define _(s)
#define KICAD_DEFAULT_DRAWFRAME_STYLE
#define LIB_VIEW_FRAME_NAME
Abstract pattern-matching tool and implementations.
@ CTX_LIBITEM
@ ID_LIBVIEW_SELECT_UNIT_NUMBER
Definition eeschema_id.h:63
@ ID_LIBVIEW_SYM_LIST
Definition eeschema_id.h:68
@ ID_LIBVIEW_SELECT_BODY_STYLE
Definition eeschema_id.h:64
@ ID_LIBVIEW_LIB_FILTER
Definition eeschema_id.h:65
@ ID_LIBVIEW_LIB_LIST
Definition eeschema_id.h:66
@ ID_LIBVIEW_SYM_FILTER
Definition eeschema_id.h:67
@ FRAME_SCH_VIEWER
Definition frame_type.h:32
const wxChar *const traceLibWatch
Flag to enable debug output for library file watch refreshes.
@ ID_ON_GRID_SELECT
Definition id.h:113
@ ID_ON_ZOOM_SELECT
Definition id.h:112
PROJECT & Prj()
Definition kicad.cpp:727
EVT_MENU(ID_COMPARE_PROJECT_BRANCHES, KICAD_MANAGER_FRAME::OnCompareProjectBranches) KICAD_MANAGER_FRAME
@ LAYER_SCHEMATIC_GRID_AXES
Definition layer_ids.h:509
@ MAIL_REFRESH_SYMBOL
Definition mail_type.h:55
@ MAIL_RELOAD_LIB
Definition mail_type.h:53
Message panel definition file.
@ ALL
All except INITIAL_ADD.
Definition view_item.h:55
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
static PGM_BASE * process
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
CITER next(CITER it)
Definition ptree.cpp:120
@ BASE
Definition sch_item.h:59
COLOR_SETTINGS * GetColorSettings(const wxString &aName)
T * GetToolbarSettings(const wxString &aFilename)
T * GetAppSettings(const char *aFilename)
KIWAY Kiway(KFCTL_STANDALONE)
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_LIBID
std::vector< wxString > pinned_symbol_libs
Store the common settings that are saved and loaded for each window / frame.
#define DEMORGAN_ALT
#define DEMORGAN_STD
#define ENVVARS_CHANGED
wxLogTrace helper definitions.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
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.