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, 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>
28#include <confirm.h>
30#include <eeschema_id.h>
31#include <eeschema_settings.h>
33#include <kiface_base.h>
34#include <kiway.h>
35#include <kiway_express.h>
36#include <locale_io.h>
37#include <symbol_viewer_frame.h>
38#include <widgets/msgpanel.h>
39#include <widgets/wx_listbox.h>
42#include <sch_view.h>
43#include <sch_painter.h>
45#include <pgm_base.h>
47#include <project_sch.h>
49#include <tool/action_toolbar.h>
50#include <tool/common_control.h>
51#include <tool/common_tools.h>
53#include <tool/selection.h>
55#include <tool/tool_manager.h>
56#include <tool/zoom_tool.h>
57#include <tools/sch_actions.h>
60#include <view/view_controls.h>
61#include <wx/srchctrl.h>
62#include <wx/log.h>
63#include <wx/choice.h>
65#include <trace_helpers.h>
66
67#include <default_values.h>
68#include <string_utils.h>
70
71#include "eda_pattern_match.h"
72
73// Save previous symbol library viewer state.
75
79
80
81BEGIN_EVENT_TABLE( SYMBOL_VIEWER_FRAME, SCH_BASE_FRAME )
82 // Window events
85
86 // Toolbar events
91
92 // listbox events
98
99 // Menu (and/or hotkey) events
100 EVT_MENU( wxID_CLOSE, SYMBOL_VIEWER_FRAME::CloseLibraryViewer )
101
102END_EVENT_TABLE()
103
104
105SYMBOL_VIEWER_FRAME::SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
106 SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_VIEWER, _( "Symbol Library Browser" ),
107 wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE,
109 m_unitChoice( nullptr ),
110 m_bodyStyleChoice( nullptr ),
111 m_libList( nullptr ),
112 m_symbolList( nullptr )
113{
114 m_aboutTitle = _HKI( "KiCad Symbol Library Browser" );
115
116 // Force the frame name used in config. the lib viewer frame has a name
117 // depending on aFrameType (needed to identify the frame by wxWidgets),
118 // but only one configuration is preferable.
120
121 // Give an icon
122 wxIcon icon;
123 icon.CopyFromBitmap( KiBitmap( BITMAPS::library_browser ) );
124 SetIcon( icon );
125
126 m_libListWidth = 200;
127 m_symbolListWidth = 300;
128 m_listPowerOnly = false;
129
130 SetScreen( new SCH_SCREEN );
131 GetScreen()->m_Center = true; // Axis origin centered on screen.
132 LoadSettings( config() );
133
134 // Ensure axis are always drawn (initial default display was not drawn)
136 gal_opts.m_axesEnabled = true;
137 gal_opts.m_gridMinSpacing = 10.0;
138 gal_opts.NotifyChanged();
139
140 GetRenderSettings()->LoadColors( GetColorSettings() );
141 GetCanvas()->GetGAL()->SetAxesColor( m_colorSettings->GetColor( LAYER_SCHEMATIC_GRID_AXES ) );
142
143 GetRenderSettings()->SetDefaultPenWidth( DEFAULT_LINE_WIDTH_MILS * schIUScale.IU_PER_MILS );
144
145 setupTools();
147
151
153
154 wxPanel* libPanel = new wxPanel( this );
155 wxSizer* libSizer = new wxBoxSizer( wxVERTICAL );
156
157 m_libFilter = new wxSearchCtrl( libPanel, ID_LIBVIEW_LIB_FILTER, wxEmptyString,
158 wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
159 m_libFilter->SetDescriptiveText( _( "Filter" ) );
160 libSizer->Add( m_libFilter, 0, wxEXPAND, 5 );
161
162 m_libList = new WX_LISTBOX( libPanel, ID_LIBVIEW_LIB_LIST, wxDefaultPosition, wxDefaultSize,
163 0, nullptr, wxLB_HSCROLL | wxNO_BORDER );
164 libSizer->Add( m_libList, 1, wxEXPAND, 5 );
165
166 libPanel->SetSizer( libSizer );
167 libPanel->Fit();
168
169 wxPanel* symbolPanel = new wxPanel( this );
170 wxSizer* symbolSizer = new wxBoxSizer( wxVERTICAL );
171
172 m_symbolFilter = new wxSearchCtrl( symbolPanel, ID_LIBVIEW_SYM_FILTER, wxEmptyString,
173 wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
174 m_symbolFilter->SetDescriptiveText( _( "Filter" ) );
175 m_symbolFilter->SetToolTip(
176 _( "Filter on symbol name, keywords, description and pin count.\n"
177 "Search terms are separated by spaces. All search terms must match.\n"
178 "A term which is a number will also match against the pin count." ) );
179 symbolSizer->Add( m_symbolFilter, 0, wxEXPAND, 5 );
180
181#ifdef __WXGTK__
182 // wxSearchCtrl vertical height is not calculated correctly on some GTK setups
183 // See https://gitlab.com/kicad/code/kicad/-/issues/9019
184 m_libFilter->SetMinSize( wxSize( -1, GetTextExtent( wxT( "qb" ) ).y + 10 ) );
185 m_symbolFilter->SetMinSize( wxSize( -1, GetTextExtent( wxT( "qb" ) ).y + 10 ) );
186#endif
187
188 m_symbolList = new WX_LISTBOX( symbolPanel, ID_LIBVIEW_SYM_LIST, wxDefaultPosition,
189 wxDefaultSize, 0, nullptr, wxLB_HSCROLL | wxNO_BORDER );
190 symbolSizer->Add( m_symbolList, 1, wxEXPAND, 5 );
191
192 symbolPanel->SetSizer( symbolSizer );
193 symbolPanel->Fit();
194
195 // Preload libraries
197
198 m_selection_changed = false;
199
201
202 m_auimgr.SetManagedWindow( this );
203
205
206 // Manage main toolbar
207 m_auimgr.AddPane( m_tbTopMain, EDA_PANE().HToolbar().Name( "TopMainToolbar" ).Top().Layer(6) );
208 m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( "MsgPanel" ) .Bottom().Layer(6) );
209
210 m_auimgr.AddPane( libPanel, EDA_PANE().Palette().Name( "Libraries" ).Left().Layer(2)
211 .CaptionVisible( false ).MinSize( 100, -1 ).BestSize( 200, -1 ) );
212 m_auimgr.AddPane( symbolPanel, EDA_PANE().Palette().Name( "Symbols" ).Left().Layer(1)
213 .CaptionVisible( false ).MinSize( 100, -1 ).BestSize( 300, -1 ) );
214
215 m_auimgr.AddPane( GetCanvas(), EDA_PANE().Canvas().Name( "DrawFrame" ).Center() );
216
218 m_auimgr.Update();
219
220 if( m_libListWidth > 0 )
221 SetAuiPaneSize( m_auimgr, m_auimgr.GetPane( "Libraries" ), m_libListWidth, -1 );
222
223 if( m_symbolListWidth > 0 )
224 SetAuiPaneSize( m_auimgr, m_auimgr.GetPane( "Symbols" ), m_symbolListWidth, -1 );
225
227
228 Raise();
229 Show( true );
230
231 SyncView();
232 GetCanvas()->SetCanFocus( false );
233
234 setupUnits( config() );
235
236 // Set the working/draw area size to display a symbol to a reasonable value:
237 // A 450mm x 450mm with a origin at the area center looks like a large working area
238 double max_size_x = schIUScale.mmToIU( 450 );
239 double max_size_y = schIUScale.mmToIU( 450 );
240 BOX2D bbox;
241 bbox.SetOrigin( -max_size_x / 2, -max_size_y / 2 );
242 bbox.SetSize( max_size_x, max_size_y );
243 GetCanvas()->GetView()->SetBoundary( bbox );
245
246 // If a symbol was previously selected in m_symbolList from a previous run, show it
247 wxString symbName = m_symbolList->GetStringSelection();
248
249 if( !symbName.IsEmpty() )
250 {
251 SetSelectedSymbol( symbName );
253 }
254}
255
256
258{
259 // Shutdown all running tools
260 if( m_toolManager )
261 m_toolManager->ShutdownAllTools();
262
263 if( m_previewItem )
264 {
265 GetCanvas()->GetView()->Remove( m_previewItem.get() );
266 m_previewItem = nullptr;
267 }
268}
269
270
272{
273 // Create the manager and dispatcher & route draw panel events to the dispatcher
275 m_toolManager->SetEnvironment( GetScreen(), GetCanvas()->GetView(),
276 GetCanvas()->GetViewControls(), config(), this );
277 m_actions = new SCH_ACTIONS();
279
280 // Register tools
281 m_toolManager->RegisterTool( new COMMON_TOOLS );
282 m_toolManager->RegisterTool( new COMMON_CONTROL );
283 m_toolManager->RegisterTool( new ZOOM_TOOL );
284 m_toolManager->RegisterTool( new SCH_INSPECTION_TOOL ); // manage show datasheet
285 m_toolManager->RegisterTool( new SCH_SELECTION_TOOL ); // manage context menu
286 m_toolManager->RegisterTool( new SYMBOL_EDITOR_CONTROL ); // manage render settings
287
288 m_toolManager->InitTools();
289
290 // Run the selection tool, it is supposed to be always active
291 // It also manages the mouse right click to show the context menu
292 m_toolManager->InvokeTool( "common.InteractiveSelection" );
293
295}
296
297
299{
301
302 ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
303 EDITOR_CONDITIONS cond( this );
304
305 wxASSERT( mgr );
306
307#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
308#define CHECK( x ) ACTION_CONDITIONS().Check( x )
309
311
312 auto electricalTypesShownCondition =
313 [this]( const SELECTION& aSel )
314 {
316 };
317
318 auto pinNumbersShownCondition =
319 [this]( const SELECTION& )
320 {
322 };
323
324 auto haveDatasheetCond =
325 [this]( const SELECTION& )
326 {
327 LIB_SYMBOL* symbol = GetSelectedSymbol();
328 return symbol && !symbol->GetDatasheetField().GetText().IsEmpty();
329 };
330
331 mgr->SetConditions( ACTIONS::showDatasheet, ENABLE( haveDatasheetCond ) );
332 mgr->SetConditions( SCH_ACTIONS::showElectricalTypes, CHECK( electricalTypesShownCondition ) );
333 mgr->SetConditions( SCH_ACTIONS::showPinNumbers, CHECK( pinNumbersShownCondition ) );
334
335#undef CHECK
336#undef ENABLE
337}
338
339
340void SYMBOL_VIEWER_FRAME::SetUnitAndBodyStyle( int aUnit, int aBodyStyle )
341{
342 m_unit = aUnit > 0 ? aUnit : 1;
343 m_bodyStyle = aBodyStyle > 0 ? aBodyStyle : BODY_STYLE::BASE;
344 m_selection_changed = false;
345
347}
348
349
351{
352 LIB_SYMBOL* symbol = nullptr;
353
354 if( m_currentSymbol.IsValid() )
356
357 return symbol;
358}
359
360
362{
363 LIB_SYMBOL* symbol = GetSelectedSymbol();
364 KIGFX::SCH_VIEW* view = GetCanvas()->GetView();
365
366 if( m_previewItem )
367 {
368 view->Remove( m_previewItem.get() );
369 m_previewItem = nullptr;
370 }
371
373
374 if( symbol )
375 {
378
379 m_previewItem = symbol->Flatten();
380 view->Add( m_previewItem.get() );
381
382 wxString parentName;
383
384 if( std::shared_ptr<LIB_SYMBOL> parent = symbol->GetParent().lock() )
385 parentName = parent->GetName();
386
387 AppendMsgPanel( _( "Name" ), UnescapeString( m_previewItem->GetName() ) );
388 AppendMsgPanel( _( "Parent" ), UnescapeString( parentName ) );
389 AppendMsgPanel( _( "Description" ), m_previewItem->GetDescription() );
390 AppendMsgPanel( _( "Keywords" ), m_previewItem->GetKeyWords() );
391 }
392
394 GetCanvas()->Refresh();
395
398}
399
400
402{
404
405 delete m_toolManager;
406 m_toolManager = nullptr;
407
408 Destroy();
409}
410
411
412void SYMBOL_VIEWER_FRAME::OnSize( wxSizeEvent& SizeEv )
413{
414 if( m_auimgr.GetManagedWindow() )
415 m_auimgr.Update();
416
417 SizeEv.Skip();
418}
419
420
422{
423 LIB_SYMBOL* symbol = GetSelectedSymbol();
424
425 int unit_count = 1;
426
427 if( symbol )
428 unit_count = std::max( symbol->GetUnitCount(), 1 );
429
430 m_unitChoice->Enable( unit_count > 1 );
431 m_unitChoice->Clear();
432
433 if( unit_count > 1 )
434 {
435 // rebuild the unit list if it is not suitable (after a new selection for instance)
436 if( unit_count != (int) m_unitChoice->GetCount() )
437 {
438 for( int ii = 0; ii < unit_count; ii++ )
439 m_unitChoice->Append( symbol->GetUnitDisplayName( ii + 1, true ) );
440 }
441
442 if( m_unitChoice->GetSelection() != std::max( 0, m_unit - 1 ) )
443 m_unitChoice->SetSelection( std::max( 0, m_unit - 1 ) );
444 }
445}
446
447
449{
450 LIB_SYMBOL* symbol = GetSelectedSymbol();
451
452 int bodyStyle_count = 1;
453
454 if( symbol )
455 bodyStyle_count = std::max( symbol->GetBodyStyleCount(), 1 );
456
457 m_bodyStyleChoice->Enable( bodyStyle_count > 1 );
458 m_bodyStyleChoice->Clear();
459
460 if( bodyStyle_count > 1 )
461 {
462 if( symbol && symbol->HasDeMorganBodyStyles() )
463 {
464 m_bodyStyleChoice->Append( wxGetTranslation( DEMORGAN_STD ) );
465 m_bodyStyleChoice->Append( wxGetTranslation( DEMORGAN_ALT ) );
466 }
467 else if( symbol )
468 {
469 for( int i = 0; i < symbol->GetBodyStyleCount(); i++ )
470 m_bodyStyleChoice->Append( symbol->GetBodyStyleNames()[i] );
471 }
472
473 if( m_bodyStyleChoice->GetSelection() != std::max( 0, m_bodyStyle - 1 ) )
474 m_bodyStyleChoice->SetSelection( std::max( 0, m_bodyStyle - 1 ) );
475 }
476}
477
478
480{
481 if( !m_libList )
482 return false;
483
484 m_libList->Clear();
485
489 std::vector<wxString> libNicknames = adapter->GetLibraryNames();
490 std::vector<wxString> pinnedMatches;
491 std::vector<wxString> otherMatches;
492
493 auto doAddLib =
494 [&]( const wxString& aLib )
495 {
496 if( alg::contains( project.m_PinnedSymbolLibs, aLib )
498 {
499 pinnedMatches.push_back( aLib );
500 }
501 else
502 {
503 otherMatches.push_back( aLib );
504 }
505 };
506
507 auto process =
508 [&]( const wxString& aLib )
509 {
510 // Remove not allowed libs, if the allowed lib list is not empty
511 if( m_allowedLibs.GetCount() )
512 {
513 if( m_allowedLibs.Index( aLib ) == wxNOT_FOUND )
514 return;
515 }
516
517 // Remove libs which have no power symbols, if this filter is activated
518 if( m_listPowerOnly )
519 {
520 std::vector<wxString> symbolNames = adapter->GetSymbolNames(
522
523 if( symbolNames.empty() )
524 return;
525 }
526
527 LIBRARY_TABLE_ROW* row = adapter->GetRow( aLib ).value_or( nullptr );
528 wxCHECK( row, /* void */ );
529
530 if( row->Hidden() )
531 return;
532
533 if( adapter->SupportsSubLibraries( aLib ) )
534 {
535 for( const auto& [nickname, description] : adapter->GetSubLibraries( aLib ) )
536 {
537 wxString suffix = nickname.IsEmpty()
538 ? wxString( wxT( "" ) )
539 : wxString::Format( wxT( " - %s" ), nickname );
540 wxString name = wxString::Format( wxT( "%s%s" ), aLib, suffix );
541
542 doAddLib( name );
543 }
544 }
545 else
546 {
547 doAddLib( aLib );
548 }
549 };
550
551 if( m_libFilter->GetValue().IsEmpty() )
552 {
553 for( const wxString& lib : libNicknames )
554 process( lib );
555 }
556 else
557 {
558 wxStringTokenizer tokenizer( m_libFilter->GetValue(), " \t\r\n", wxTOKEN_STRTOK );
559
560 while( tokenizer.HasMoreTokens() )
561 {
562 const wxString term = tokenizer.GetNextToken().Lower();
563 EDA_COMBINED_MATCHER matcher( term, CTX_LIBITEM );
564
565 for( const wxString& lib : libNicknames )
566 {
567 if( matcher.Find( lib.Lower() ) )
568 process( lib );
569 }
570 }
571 }
572
573 if( libNicknames.empty() )
574 return true;
575
576 for( const wxString& name : pinnedMatches )
578
579 for( const wxString& name : otherMatches )
580 m_libList->Append( UnescapeString( name ) );
581
582 // Search for a previous selection:
583 int index =
584 m_libList->FindString( UnescapeString( m_currentSymbol.GetUniStringLibNickname() ) );
585
586 if( index != wxNOT_FOUND )
587 {
588 m_libList->SetSelection( index, true );
589 }
590 else
591 {
592 // If not found, clear current library selection because it can be deleted after a
593 // config change.
594 m_currentSymbol.SetLibNickname( m_libList->GetCount() > 0 ? m_libList->GetBaseString( 0 )
595 : wxString( wxEmptyString ) );
596 m_currentSymbol.SetLibItemName( wxEmptyString );
597 m_unit = 1;
599 }
600
601 bool cmp_changed = ReCreateSymbolList();
603 GetCanvas()->Refresh();
604
605 return cmp_changed;
606}
607
608
610{
611 if( m_symbolList == nullptr )
612 return false;
613
614 m_symbolList->Clear();
615
616 wxString libName = m_currentSymbol.GetUniStringLibNickname();
617
618 if( libName.IsEmpty() )
619 return false;
620
622 std::vector<LIB_SYMBOL*> symbols = adapter->GetSymbols( libName );
623
624 std::set<wxString> excludes;
625
626 if( !m_symbolFilter->GetValue().IsEmpty() )
627 {
628 wxStringTokenizer tokenizer( m_symbolFilter->GetValue(), " \t\r\n", wxTOKEN_STRTOK );
629
630 while( tokenizer.HasMoreTokens() )
631 {
632 const wxString filterTerm = tokenizer.GetNextToken().Lower();
633 EDA_COMBINED_MATCHER matcher( filterTerm, CTX_LIBITEM );
634
635 for( LIB_SYMBOL* symbol : symbols )
636 {
637 std::vector<SEARCH_TERM> searchTerms = symbol->GetSearchTerms();
638 int matched = matcher.ScoreTerms( searchTerms );
639
640 if( filterTerm.IsNumber() && wxAtoi( filterTerm ) == (int)symbol->GetPinCount() )
641 matched++;
642
643 if( !matched )
644 excludes.insert( symbol->GetName() );
645 }
646 }
647 }
648
649 wxString subLib = m_currentSymbol.GetSubLibraryName();
650
651 for( const LIB_SYMBOL* symbol : symbols )
652 {
653 if( adapter->SupportsSubLibraries( libName )
654 && !subLib.IsSameAs( symbol->GetLibId().GetSubLibraryName() ) )
655 {
656 continue;
657 }
658
659 if( !excludes.count( symbol->GetName() ) )
660 m_symbolList->Append( UnescapeString( symbol->GetName() ) );
661 }
662
663 if( m_symbolList->IsEmpty() )
664 {
665 SetSelectedSymbol( wxEmptyString );
667 m_unit = 1;
668 return true;
669 }
670
671 int index =
672 m_symbolList->FindString( UnescapeString( m_currentSymbol.GetUniStringLibItemName() ) );
673 bool changed = false;
674
675 if( index == wxNOT_FOUND )
676 {
677 // Select the first library entry when the previous entry name does not exist in
678 // the current library.
680 m_unit = 1;
681 index = -1;
682 changed = true;
683 SetSelectedSymbol( wxEmptyString );
684 }
685
686 m_symbolList->SetSelection( index, true );
687
688 return changed;
689}
690
691
692void SYMBOL_VIEWER_FRAME::ClickOnLibList( wxCommandEvent& event )
693{
694 int ii = m_libList->GetSelection();
695
696 if( ii < 0 )
697 return;
698
699 m_selection_changed = true;
700
701 wxString selection = EscapeString( m_libList->GetBaseString( ii ), CTX_LIBID );
702
704
705 if( !adapter->HasLibrary( selection ) && selection.Find( '-' ) != wxNOT_FOUND )
706 {
707 // Probably a sub-library
708 wxString sublib;
709 selection = selection.BeforeLast( '-', &sublib ).Trim();
710 sublib.Trim( false );
711 SetSelectedLibrary( selection, sublib );
712 }
713 else
714 {
715 SetSelectedLibrary( selection );
716 }
717}
718
719
720void SYMBOL_VIEWER_FRAME::SetSelectedLibrary( const wxString& aLibraryName,
721 const wxString& aSubLibName )
722{
723 if( m_currentSymbol.GetUniStringLibNickname() == aLibraryName
724 && wxString( m_currentSymbol.GetSubLibraryName().wx_str() ) == aSubLibName )
725 return;
726
727 m_currentSymbol.SetLibNickname( aLibraryName );
728 m_currentSymbol.SetSubLibraryName( aSubLibName );
730 GetCanvas()->Refresh();
732
733 // Ensure the corresponding line in m_libList is selected
734 // (which is not necessary the case if SetSelectedLibrary is called
735 // by another caller than ClickOnLibList.
736 m_libList->SetStringSelection( UnescapeString( m_currentSymbol.GetFullLibraryName() ), true );
737
738 // The m_libList has now the focus, in order to be able to use arrow keys
739 // to navigate inside the list.
740 // the gal canvas must not steal the focus to allow navigation
741 GetCanvas()->SetStealsFocus( false );
742 m_libList->SetFocus();
743}
744
745
746void SYMBOL_VIEWER_FRAME::ClickOnSymbolList( wxCommandEvent& event )
747{
748 int ii = m_symbolList->GetSelection();
749
750 if( ii < 0 )
751 return;
752
753 m_selection_changed = true;
754
755 SetSelectedSymbol( EscapeString( m_symbolList->GetBaseString( ii ), CTX_LIBID ) );
756
757 // The m_symbolList has now the focus, in order to be able to use arrow keys
758 // to navigate inside the list.
759 // the gal canvas must not steal the focus to allow navigation
760 GetCanvas()->SetStealsFocus( false );
761 m_symbolList->SetFocus();
762}
763
764
765void SYMBOL_VIEWER_FRAME::SetSelectedSymbol( const wxString& aSymbolName )
766{
767 if( m_currentSymbol.GetUniStringLibItemName() != aSymbolName )
768 {
769 m_currentSymbol.SetLibItemName( aSymbolName );
770
771 // Ensure the corresponding line in m_symbolList is selected
772 // (which is not necessarily the case if SetSelectedSymbol is called
773 // by another caller than ClickOnSymbolList.
774 m_symbolList->SetStringSelection( UnescapeString( aSymbolName ), true );
776
778 {
779 m_unit = 1;
781 m_selection_changed = false;
782 }
783
785 }
786}
787
788
789void SYMBOL_VIEWER_FRAME::DClickOnSymbolList( wxCommandEvent& event )
790{
792}
793
794
796{
798
800 {
801 // Grid shape, etc.
802 GetGalDisplayOptions().ReadWindowSettings( cfg->m_LibViewPanel.window );
803
804 m_libListWidth = cfg->m_LibViewPanel.lib_list_width;
805 m_symbolListWidth = cfg->m_LibViewPanel.cmp_list_width;
806
807 GetRenderSettings()->m_ShowPinsElectricalType = cfg->m_LibViewPanel.show_pin_electrical_type;
808 GetRenderSettings()->m_ShowPinNumbers = cfg->m_LibViewPanel.show_pin_numbers;
809
810 // Set parameters to a reasonable value.
811 int maxWidth = cfg->m_LibViewPanel.window.state.size_x - 80;
812
813 if( m_libListWidth + m_symbolListWidth > maxWidth )
814 {
817 }
818 }
819}
820
821
823{
825
827 m_libListWidth = m_libList->GetSize().x;
828
829 m_symbolListWidth = m_symbolList->GetSize().x;
830
832 {
833 cfg->m_LibViewPanel.lib_list_width = m_libListWidth;
834 cfg->m_LibViewPanel.cmp_list_width = m_symbolListWidth;
835
836 if( SCH_RENDER_SETTINGS* renderSettings = GetRenderSettings() )
837 {
838 cfg->m_LibViewPanel.show_pin_electrical_type = renderSettings->m_ShowPinsElectricalType;
839 cfg->m_LibViewPanel.show_pin_numbers = renderSettings->m_ShowPinNumbers;
840 }
841 }
842}
843
844
846{
847 if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( aCfg ) )
848 return &cfg->m_LibViewPanel.window;
849
850 wxFAIL_MSG( wxT( "SYMBOL_VIEWER not running with EESCHEMA_SETTINGS" ) );
851 return &aCfg->m_Window; // non-null fail-safe
852}
853
854
856{
858
860 GetGalDisplayOptions().ReadWindowSettings( cfg->m_LibViewPanel.window );
861
863 GetCanvas()->GetGAL()->DrawGrid();
865
866 if( aFlags && ENVVARS_CHANGED )
868}
869
870
871void SYMBOL_VIEWER_FRAME::OnActivate( wxActivateEvent& event )
872{
873 if( event.GetActive() )
874 {
875 bool changed = m_libList ? ReCreateLibList() : false;
876
877 if (changed)
878 m_selection_changed = true;
879
881
883 }
884
885 event.Skip(); // required under wxMAC
886}
887
888
889void SYMBOL_VIEWER_FRAME::CloseLibraryViewer( wxCommandEvent& event )
890{
891 Close();
892}
893
894
895const BOX2I SYMBOL_VIEWER_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
896{
897 if( LIB_SYMBOL* symbol = GetSelectedSymbol() )
898 return symbol->GetUnitBoundingBox( m_unit, m_bodyStyle );
899
900 return BOX2I( VECTOR2I( -200, -200 ), VECTOR2I( 400, 400 ) );
901}
902
903
904void SYMBOL_VIEWER_FRAME::OnLibFilter( wxCommandEvent& aEvent )
905{
907
908 // Required to avoid interaction with SetHint()
909 // See documentation for wxTextEntry::SetHint
910 aEvent.Skip();
911}
912
913
914void SYMBOL_VIEWER_FRAME::OnSymFilter( wxCommandEvent& aEvent )
915{
917
918 // Required to avoid interaction with SetHint()
919 // See documentation for wxTextEntry::SetHint
920 aEvent.Skip();
921}
922
923
924void SYMBOL_VIEWER_FRAME::OnCharHook( wxKeyEvent& aEvent )
925{
926 if( aEvent.GetKeyCode() == WXK_UP )
927 {
928 if( m_libFilter->HasFocus() || m_libList->HasFocus() )
929 {
930 int prev = m_libList->GetSelection() - 1;
931
932 if( prev >= 0 )
933 {
934 m_libList->SetSelection( prev );
935 m_libList->EnsureVisible( prev );
936
937 wxCommandEvent dummy;
939 }
940 }
941 else
942 {
943 wxCommandEvent dummy;
945 }
946 }
947 else if( aEvent.GetKeyCode() == WXK_DOWN )
948 {
949 if( m_libFilter->HasFocus() || m_libList->HasFocus() )
950 {
951 int next = m_libList->GetSelection() + 1;
952
953 if( next < (int)m_libList->GetCount() )
954 {
955 m_libList->SetSelection( next );
956 m_libList->EnsureVisible( next );
957
958 wxCommandEvent dummy;
960 }
961 }
962 else
963 {
964 wxCommandEvent dummy;
966 }
967 }
968 else if( aEvent.GetKeyCode() == WXK_TAB && m_libFilter->HasFocus() )
969 {
970 if( !aEvent.ShiftDown() )
971 m_symbolFilter->SetFocus();
972 else
973 aEvent.Skip();
974 }
975 else if( aEvent.GetKeyCode() == WXK_TAB && m_symbolFilter->HasFocus() )
976 {
977 if( aEvent.ShiftDown() )
978 m_libFilter->SetFocus();
979 else
980 aEvent.Skip();
981 }
982 else if( ( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER )
983 && m_symbolList->GetSelection() >= 0 )
984 {
985 wxCommandEvent dummy;
987 }
988 else
989 {
990 aEvent.Skip();
991 }
992}
993
994
995void SYMBOL_VIEWER_FRAME::onSelectNextSymbol( wxCommandEvent& aEvent )
996{
997 wxCommandEvent evt( wxEVT_COMMAND_LISTBOX_SELECTED, ID_LIBVIEW_SYM_LIST );
998 int ii = m_symbolList->GetSelection();
999
1000 // Select the next symbol or stop at the end of the list.
1001 if( ii != wxNOT_FOUND && ii < (int) ( m_symbolList->GetCount() - 1 ) )
1002 ii += 1;
1003
1004 m_symbolList->SetSelection( ii );
1005 ProcessEvent( evt );
1006}
1007
1008
1010{
1011 wxCommandEvent evt( wxEVT_COMMAND_LISTBOX_SELECTED, ID_LIBVIEW_SYM_LIST );
1012 int ii = m_symbolList->GetSelection();
1013
1014 // Select the previous symbol or stop at the beginning of list.
1015 if( ii != wxNOT_FOUND && ii != 0 )
1016 ii -= 1;
1017
1018 m_symbolList->SetSelection( ii );
1019 ProcessEvent( evt );
1020}
1021
1022
1023void SYMBOL_VIEWER_FRAME::onSelectSymbolUnit( wxCommandEvent& aEvent )
1024{
1025 int ii = m_unitChoice->GetSelection();
1026
1027 if( ii < 0 )
1028 return;
1029
1030 m_unit = ii + 1;
1031
1033}
1034
1035
1037{
1038 int ii = m_bodyStyleChoice->GetSelection();
1039
1040 if( ii < 0 )
1041 return;
1042
1043 m_bodyStyle = ii + 1;
1044
1046}
1047
1048
1050{
1051 wxString libName = m_currentSymbol.GetUniStringLibNickname();
1052
1053 if( m_libList && !m_libList->IsEmpty() && !libName.IsEmpty() )
1054 {
1056 LIBRARY_TABLE_ROW* row = adapter->GetRow( libName ).value_or( nullptr );
1057
1058 wxString title = row
1059 ? LIBRARY_MANAGER::GetFullURI( row, true )
1060 : _( "[no library selected]" );
1061
1062 title += wxT( " \u2014 " ) + _( "Symbol Library Browser" );
1063 SetTitle( title );
1064 }
1065}
1066
1067
1069{
1070 return m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
1071}
1072
1073
1075{
1076
1077 switch( mail.Command() )
1078 {
1079 case MAIL_RELOAD_LIB:
1080 {
1082 break;
1083 }
1085 {
1086 LIB_SYMBOL* symbol = GetSelectedSymbol();
1087 wxCHECK2( symbol, break );
1088
1090 LIBRARY_TABLE_ROW* row =
1091 adapter->GetRow( symbol->GetLibId().GetLibNickname() ).value_or( nullptr );
1092
1093 if( !row )
1094 return;
1095
1096 wxString libfullname = LIBRARY_MANAGER::GetFullURI( row, true );
1097
1098 wxString lib( mail.GetPayload() );
1099 wxLogTrace( traceLibWatch, "Received refresh symbol request for %s, current symbols "
1100 "is %s", lib, libfullname );
1101
1102 if( lib == libfullname )
1103 {
1104 wxLogTrace( traceLibWatch, "Refreshing symbol %s", symbol->GetName() );
1107 }
1108 break;
1109 }
1110 default:;
1111 }
1112}
const char * name
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
@ library_browser
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
BOX2< VECTOR2D > BOX2D
Definition box2.h:923
static TOOL_ACTION toggleGrid
Definition actions.h:197
static TOOL_ACTION showDatasheet
Definition actions.h:266
static TOOL_ACTION zoomFitScreen
Definition actions.h:141
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:237
constexpr void SetSize(const SizeVec &size)
Definition box2.h:248
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 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 setupUnits(APP_SETTINGS_BASE *aCfg)
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.
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:98
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:298
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:341
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:1561
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
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition kiway.cpp:200
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) const
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:49
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:87
Define a library symbol object.
Definition lib_symbol.h:85
const LIB_ID & GetLibId() const override
Definition lib_symbol.h:155
std::weak_ptr< LIB_SYMBOL > & GetParent()
Definition lib_symbol.h:117
SCH_FIELD & GetDatasheetField()
Return reference to the datasheet field.
Definition lib_symbol.h:348
wxString GetName() const override
Definition lib_symbol.h:148
const std::vector< wxString > & GetBodyStyleNames() const
Definition lib_symbol.h:763
bool HasDeMorganBodyStyles() const override
Definition lib_symbol.h:760
int GetBodyStyleCount() const override
Definition lib_symbol.h:752
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:537
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:205
Gather all the actions that are shared by tools.
Definition sch_actions.h:40
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.
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 onSelectNextSymbol(wxCommandEvent &aEvent)
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.
void KiwayMailIn(KIWAY_EXPRESS &mail) override
Receive KIWAY_EXPRESS messages from other players.
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.
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 onSelectPreviousSymbol(wxCommandEvent &aEvent)
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:71
@ ID_LIBVIEW_SYM_LIST
Definition eeschema_id.h:76
@ ID_LIBVIEW_NEXT
Definition eeschema_id.h:69
@ ID_LIBVIEW_SELECT_BODY_STYLE
Definition eeschema_id.h:72
@ ID_LIBVIEW_LIB_FILTER
Definition eeschema_id.h:73
@ ID_LIBVIEW_LIB_LIST
Definition eeschema_id.h:74
@ ID_LIBVIEW_SYM_FILTER
Definition eeschema_id.h:75
@ ID_LIBVIEW_PREVIOUS
Definition eeschema_id.h:70
@ FRAME_SCH_VIEWER
Definition frame_type.h:36
const wxChar *const traceLibWatch
Flag to enable debug output for library file watch refreshes.
PROJECT & Prj()
Definition kicad.cpp:623
@ LAYER_SCHEMATIC_GRID_AXES
Definition layer_ids.h:487
@ MAIL_REFRESH_SYMBOL
Definition mail_type.h:59
@ MAIL_RELOAD_LIB
Definition mail_type.h:57
Message panel definition file.
@ ALL
All except INITIAL_ADD.
Definition view_item.h:59
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
static PGM_BASE * process
Definition pgm_base.cpp:943
PGM_BASE & Pgm()
The global program "get" accessor.
Definition pgm_base.cpp:946
see class PGM_BASE
CITER next(CITER it)
Definition ptree.cpp:124
@ 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:695
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.