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