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 <wx/tokenzr.h>
27#include <bitmaps.h>
29#include <confirm.h>
31#include <eeschema_id.h>
32#include <eeschema_settings.h>
35#include <kiface_base.h>
36#include <kiway.h>
37#include <kiway_mail.h>
38#include <locale_io.h>
39#include <symbol_viewer_frame.h>
40#include <widgets/msgpanel.h>
41#include <widgets/wx_listbox.h>
44#include <sch_view.h>
45#include <sch_painter.h>
47#include <pgm_base.h>
49#include <project_sch.h>
51#include <tool/action_toolbar.h>
52#include <tool/common_control.h>
53#include <tool/common_tools.h>
55#include <tool/selection.h>
57#include <tool/tool_manager.h>
58#include <tool/zoom_tool.h>
59#include <tools/sch_actions.h>
62#include <view/view_controls.h>
63#include <wx/srchctrl.h>
64#include <wx/log.h>
65#include <wx/choice.h>
67#include <trace_helpers.h>
68
69#include <default_values.h>
70#include <string_utils.h>
72
73#include "eda_pattern_match.h"
74
75// Save previous symbol library viewer state.
77
80
81
82BEGIN_EVENT_TABLE( SYMBOL_VIEWER_FRAME, SCH_BASE_FRAME )
83 // Window events
86
87 // Toolbar events
92
93 // listbox events
99
100 // Menu (and/or hotkey) events
101 EVT_MENU( wxID_CLOSE, SYMBOL_VIEWER_FRAME::CloseLibraryViewer )
102
103END_EVENT_TABLE()
104
105
106SYMBOL_VIEWER_FRAME::SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
107 SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_VIEWER, _( "Symbol Library Browser" ), wxDefaultPosition,
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, wxDefaultPosition,
158 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, 0, nullptr,
163 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, wxDefaultPosition,
173 wxDefaultSize, wxTE_PROCESS_ENTER );
174 m_symbolFilter->SetDescriptiveText( _( "Filter" ) );
175 m_symbolFilter->SetToolTip( _( "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, wxDefaultSize, 0, nullptr,
188 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(), GetCanvas()->GetViewControls(), config(),
275 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() ? wxString( wxT( "" ) )
537 : wxString::Format( wxT( " - %s" ), nickname );
538 wxString name = wxString::Format( wxT( "%s%s" ), aLib, suffix );
539
540 doAddLib( name );
541 }
542 }
543 else
544 {
545 doAddLib( aLib );
546 }
547 };
548
549 if( m_libFilter->GetValue().IsEmpty() )
550 {
551 for( const wxString& lib : libNicknames )
552 process( lib );
553 }
554 else
555 {
556 wxStringTokenizer tokenizer( m_libFilter->GetValue(), " \t\r\n", wxTOKEN_STRTOK );
557
558 while( tokenizer.HasMoreTokens() )
559 {
560 const wxString term = tokenizer.GetNextToken().Lower();
561 EDA_COMBINED_MATCHER matcher( term, CTX_LIBITEM );
562
563 for( const wxString& lib : libNicknames )
564 {
565 if( matcher.Find( lib.Lower() ) )
566 process( lib );
567 }
568 }
569 }
570
571 if( libNicknames.empty() )
572 return true;
573
574 for( const wxString& name : pinnedMatches )
576
577 for( const wxString& name : otherMatches )
578 m_libList->Append( UnescapeString( name ) );
579
580 // Search for a previous selection:
581 int index = m_libList->FindString( UnescapeString( m_currentSymbol.GetUniStringLibNickname() ) );
582
583 if( index != wxNOT_FOUND )
584 {
585 m_libList->SetSelection( index, true );
586 }
587 else
588 {
589 // If not found, clear current library selection because it can be deleted after a
590 // config change.
591 m_currentSymbol.SetLibNickname( m_libList->GetCount() > 0 ? m_libList->GetBaseString( 0 )
592 : wxString( wxEmptyString ) );
593 m_currentSymbol.SetLibItemName( wxEmptyString );
594 m_unit = 1;
596 }
597
598 bool cmp_changed = ReCreateSymbolList();
600 GetCanvas()->Refresh();
601
602 return cmp_changed;
603}
604
605
607{
608 if( m_symbolList == nullptr )
609 return false;
610
611 m_symbolList->Clear();
612
613 wxString libName = m_currentSymbol.GetUniStringLibNickname();
614
615 if( libName.IsEmpty() )
616 return false;
617
619 std::vector<LIB_SYMBOL*> symbols = adapter->GetSymbols( libName );
620
621 std::set<wxString> excludes;
622
623 if( !m_symbolFilter->GetValue().IsEmpty() )
624 {
625 wxStringTokenizer tokenizer( m_symbolFilter->GetValue(), " \t\r\n", wxTOKEN_STRTOK );
626
627 while( tokenizer.HasMoreTokens() )
628 {
629 const wxString filterTerm = tokenizer.GetNextToken().Lower();
630 EDA_COMBINED_MATCHER matcher( filterTerm, CTX_LIBITEM );
631
632 for( LIB_SYMBOL* symbol : symbols )
633 {
634 int matched = matcher.ScoreTerms( symbol->GetSearchTerms() );
635
636 if( filterTerm.IsNumber() && wxAtoi( filterTerm ) == (int)symbol->GetPinCount() )
637 matched++;
638
639 if( !matched )
640 excludes.insert( symbol->GetName() );
641 }
642 }
643 }
644
645 wxString subLib = m_currentSymbol.GetSubLibraryName();
646
647 for( const LIB_SYMBOL* symbol : symbols )
648 {
649 if( adapter->SupportsSubLibraries( libName )
650 && !subLib.IsSameAs( symbol->GetLibId().GetSubLibraryName() ) )
651 {
652 continue;
653 }
654
655 if( !excludes.count( symbol->GetName() ) )
656 m_symbolList->Append( UnescapeString( symbol->GetName() ) );
657 }
658
659 if( m_symbolList->IsEmpty() )
660 {
661 SetSelectedSymbol( wxEmptyString );
663 m_unit = 1;
664 return true;
665 }
666
667 int index = m_symbolList->FindString( UnescapeString( m_currentSymbol.GetUniStringLibItemName() ) );
668 bool changed = false;
669
670 if( index == wxNOT_FOUND )
671 {
672 // Select the first library entry when the previous entry name does not exist in
673 // the current library.
675 m_unit = 1;
676 index = -1;
677 changed = true;
678 SetSelectedSymbol( wxEmptyString );
679 }
680
681 m_symbolList->SetSelection( index, true );
682
683 return changed;
684}
685
686
687void SYMBOL_VIEWER_FRAME::ClickOnLibList( wxCommandEvent& event )
688{
689 int ii = m_libList->GetSelection();
690
691 if( ii < 0 )
692 return;
693
694 m_selection_changed = true;
695
696 wxString selection = EscapeString( m_libList->GetBaseString( ii ), CTX_LIBID );
697
699
700 if( !adapter->HasLibrary( selection ) && selection.Find( '-' ) != wxNOT_FOUND )
701 {
702 // Probably a sub-library
703 wxString sublib;
704 selection = selection.BeforeLast( '-', &sublib ).Trim();
705 sublib.Trim( false );
706 SetSelectedLibrary( selection, sublib );
707 }
708 else
709 {
710 SetSelectedLibrary( selection );
711 }
712}
713
714
715void SYMBOL_VIEWER_FRAME::SetSelectedLibrary( const wxString& aLibraryName, const wxString& aSubLibName )
716{
717 if( m_currentSymbol.GetUniStringLibNickname() == aLibraryName
718 && wxString( m_currentSymbol.GetSubLibraryName().wx_str() ) == aSubLibName )
719 {
720 return;
721 }
722
723 m_currentSymbol.SetLibNickname( aLibraryName );
724 m_currentSymbol.SetSubLibraryName( aSubLibName );
726 GetCanvas()->Refresh();
728
729 // Ensure the corresponding line in m_libList is selected
730 // (which is not necessary the case if SetSelectedLibrary is called
731 // by another caller than ClickOnLibList.
732 m_libList->SetStringSelection( UnescapeString( m_currentSymbol.GetFullLibraryName() ), true );
733
734 // The m_libList has now the focus, in order to be able to use arrow keys
735 // to navigate inside the list.
736 // the gal canvas must not steal the focus to allow navigation
737 GetCanvas()->SetStealsFocus( false );
738 m_libList->SetFocus();
739}
740
741
742void SYMBOL_VIEWER_FRAME::ClickOnSymbolList( wxCommandEvent& event )
743{
744 int ii = m_symbolList->GetSelection();
745
746 if( ii < 0 )
747 return;
748
749 m_selection_changed = true;
750
751 SetSelectedSymbol( EscapeString( m_symbolList->GetBaseString( ii ), CTX_LIBID ) );
752
753 // The m_symbolList has now the focus, in order to be able to use arrow keys
754 // to navigate inside the list.
755 // the gal canvas must not steal the focus to allow navigation
756 GetCanvas()->SetStealsFocus( false );
757 m_symbolList->SetFocus();
758}
759
760
761void SYMBOL_VIEWER_FRAME::SetSelectedSymbol( const wxString& aSymbolName )
762{
763 if( m_currentSymbol.GetUniStringLibItemName() != aSymbolName )
764 {
765 m_currentSymbol.SetLibItemName( aSymbolName );
766
767 // Ensure the corresponding line in m_symbolList is selected
768 // (which is not necessarily the case if SetSelectedSymbol is called
769 // by another caller than ClickOnSymbolList.
770 m_symbolList->SetStringSelection( UnescapeString( aSymbolName ), true );
772
774 {
775 m_unit = 1;
777 m_selection_changed = false;
778 }
779
781 }
782}
783
784
785void SYMBOL_VIEWER_FRAME::DClickOnSymbolList( wxCommandEvent& event )
786{
788}
789
790
792{
794
796 {
797 // Grid shape, etc.
798 GetGalDisplayOptions().ReadWindowSettings( cfg->m_LibViewPanel.window );
799
800 m_libListWidth = cfg->m_LibViewPanel.lib_list_width;
801 m_symbolListWidth = cfg->m_LibViewPanel.cmp_list_width;
802
803 GetRenderSettings()->m_ShowPinsElectricalType = cfg->m_LibViewPanel.show_pin_electrical_type;
804 GetRenderSettings()->m_ShowPinNumbers = cfg->m_LibViewPanel.show_pin_numbers;
805
806 // Set parameters to a reasonable value.
807 int maxWidth = cfg->m_LibViewPanel.window.state.size_x - 80;
808
809 if( m_libListWidth + m_symbolListWidth > maxWidth )
810 {
813 }
814 }
815}
816
817
819{
821
823 m_libListWidth = m_libList->GetSize().x;
824
825 m_symbolListWidth = m_symbolList->GetSize().x;
826
828 {
829 cfg->m_LibViewPanel.lib_list_width = m_libListWidth;
830 cfg->m_LibViewPanel.cmp_list_width = m_symbolListWidth;
831
832 if( SCH_RENDER_SETTINGS* renderSettings = GetRenderSettings() )
833 {
834 cfg->m_LibViewPanel.show_pin_electrical_type = renderSettings->m_ShowPinsElectricalType;
835 cfg->m_LibViewPanel.show_pin_numbers = renderSettings->m_ShowPinNumbers;
836 }
837 }
838}
839
840
842{
843 if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( aCfg ) )
844 return &cfg->m_LibViewPanel.window;
845
846 wxFAIL_MSG( wxT( "SYMBOL_VIEWER not running with EESCHEMA_SETTINGS" ) );
847 return &aCfg->m_Window; // non-null fail-safe
848}
849
850
852{
854
856 GetGalDisplayOptions().ReadWindowSettings( cfg->m_LibViewPanel.window );
857
859 GetCanvas()->GetGAL()->DrawGrid();
861
862 if( aFlags && ENVVARS_CHANGED )
864}
865
866
867void SYMBOL_VIEWER_FRAME::OnActivate( wxActivateEvent& event )
868{
869 if( event.GetActive() )
870 {
871 bool changed = m_libList ? ReCreateLibList() : false;
872
873 if (changed)
874 m_selection_changed = true;
875
877
879 }
880
881 event.Skip(); // required under wxMAC
882}
883
884
885void SYMBOL_VIEWER_FRAME::CloseLibraryViewer( wxCommandEvent& event )
886{
887 Close();
888}
889
890
891const BOX2I SYMBOL_VIEWER_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
892{
893 if( LIB_SYMBOL* symbol = GetSelectedSymbol() )
894 return symbol->GetUnitBoundingBox( m_unit, m_bodyStyle );
895
896 return BOX2I( VECTOR2I( -200, -200 ), VECTOR2I( 400, 400 ) );
897}
898
899
900void SYMBOL_VIEWER_FRAME::OnLibFilter( wxCommandEvent& aEvent )
901{
903
904 // Required to avoid interaction with SetHint()
905 // See documentation for wxTextEntry::SetHint
906 aEvent.Skip();
907}
908
909
910void SYMBOL_VIEWER_FRAME::OnSymFilter( wxCommandEvent& aEvent )
911{
913
914 // Required to avoid interaction with SetHint()
915 // See documentation for wxTextEntry::SetHint
916 aEvent.Skip();
917}
918
919
920void SYMBOL_VIEWER_FRAME::OnCharHook( wxKeyEvent& aEvent )
921{
922 if( aEvent.GetKeyCode() == WXK_UP )
923 {
924 if( m_libFilter->HasFocus() || m_libList->HasFocus() )
925 {
926 int prev = m_libList->GetSelection() - 1;
927
928 if( prev >= 0 )
929 {
930 m_libList->SetSelection( prev );
931 m_libList->EnsureVisible( prev );
932
933 wxCommandEvent dummy;
935 }
936 }
937 else
938 {
940 }
941 }
942 else if( aEvent.GetKeyCode() == WXK_DOWN )
943 {
944 if( m_libFilter->HasFocus() || m_libList->HasFocus() )
945 {
946 int next = m_libList->GetSelection() + 1;
947
948 if( next < (int)m_libList->GetCount() )
949 {
950 m_libList->SetSelection( next );
951 m_libList->EnsureVisible( next );
952
953 wxCommandEvent dummy;
955 }
956 }
957 else
958 {
960 }
961 }
962 else if( aEvent.GetKeyCode() == WXK_TAB && m_libFilter->HasFocus() )
963 {
964 if( !aEvent.ShiftDown() )
965 m_symbolFilter->SetFocus();
966 else
967 aEvent.Skip();
968 }
969 else if( aEvent.GetKeyCode() == WXK_TAB && m_symbolFilter->HasFocus() )
970 {
971 if( aEvent.ShiftDown() )
972 m_libFilter->SetFocus();
973 else
974 aEvent.Skip();
975 }
976 else if( ( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER )
977 && m_symbolList->GetSelection() >= 0 )
978 {
979 wxCommandEvent dummy;
981 }
982 else
983 {
984 aEvent.Skip();
985 }
986}
987
988
990{
991 wxCommandEvent evt( wxEVT_COMMAND_LISTBOX_SELECTED, ID_LIBVIEW_SYM_LIST );
992 int ii = m_symbolList->GetSelection();
993
994 // Select the next symbol or stop at the end of the list.
995 if( ii != wxNOT_FOUND && ii < (int) ( m_symbolList->GetCount() - 1 ) )
996 ii += 1;
997
998 m_symbolList->SetSelection( ii );
999 ProcessEvent( evt );
1000}
1001
1002
1004{
1005 wxCommandEvent evt( wxEVT_COMMAND_LISTBOX_SELECTED, ID_LIBVIEW_SYM_LIST );
1006 int ii = m_symbolList->GetSelection();
1007
1008 // Select the previous symbol or stop at the beginning of list.
1009 if( ii != wxNOT_FOUND && ii != 0 )
1010 ii -= 1;
1011
1012 m_symbolList->SetSelection( ii );
1013 ProcessEvent( evt );
1014}
1015
1016
1017void SYMBOL_VIEWER_FRAME::onSelectSymbolUnit( wxCommandEvent& aEvent )
1018{
1019 int ii = m_unitChoice->GetSelection();
1020
1021 if( ii < 0 )
1022 return;
1023
1024 m_unit = ii + 1;
1025
1027}
1028
1029
1031{
1032 int ii = m_bodyStyleChoice->GetSelection();
1033
1034 if( ii < 0 )
1035 return;
1036
1037 m_bodyStyle = ii + 1;
1038
1040}
1041
1042
1044{
1045 wxString libName = m_currentSymbol.GetUniStringLibNickname();
1046
1047 if( m_libList && !m_libList->IsEmpty() && !libName.IsEmpty() )
1048 {
1050 LIBRARY_TABLE_ROW* row = adapter->GetRow( libName ).value_or( nullptr );
1051
1052 wxString title = row ? LIBRARY_MANAGER::GetFullURI( row, true )
1053 : _( "[no library selected]" );
1054
1055 title += wxT( " \u2014 " ) + _( "Symbol Library Browser" );
1056 SetTitle( title );
1057 }
1058}
1059
1060
1062{
1063 return m_toolManager->GetTool<SCH_SELECTION_TOOL>()->GetSelection();
1064}
1065
1066
1068{
1069
1070 switch( mail.Command() )
1071 {
1072 case MAIL_RELOAD_LIB:
1074 break;
1075
1077 {
1078 LIB_SYMBOL* symbol = GetSelectedSymbol();
1079 wxCHECK2( symbol, break );
1080
1082 LIBRARY_TABLE_ROW* row = adapter->GetRow( symbol->GetLibId().GetLibNickname() ).value_or( nullptr );
1083
1084 if( !row )
1085 return;
1086
1087 wxString libfullname = LIBRARY_MANAGER::GetFullURI( row, true );
1088
1089 wxString lib( mail.GetPayload() );
1090 wxLogTrace( traceLibWatch, "Received refresh symbol request for %s, current symbols is %s", lib, libfullname );
1091
1092 if( lib == libfullname )
1093 {
1094 wxLogTrace( traceLibWatch, "Refreshing symbol %s", symbol->GetName() );
1097 }
1098
1099 break;
1100 }
1101 default:;
1102 }
1103}
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 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:300
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:343
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:1584
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition kiway_mail.h:38
std::string & GetPayload()
Return the payload, which can be any text but it typically self identifying s-expression.
Definition kiway_mail.h:56
MAIL_T Command()
Returns the MAIL_T associated with this mail.
Definition kiway_mail.h:48
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:295
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition kiway.cpp:207
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: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:152
std::weak_ptr< LIB_SYMBOL > & GetParent()
Definition lib_symbol.h:114
SCH_FIELD & GetDatasheetField()
Return reference to the datasheet field.
Definition lib_symbol.h:344
wxString GetName() const override
Definition lib_symbol.h:145
const std::vector< wxString > & GetBodyStyleNames() const
Definition lib_symbol.h:787
bool HasDeMorganBodyStyles() const override
Definition lib_symbol.h:784
int GetBodyStyleCount() const override
Definition lib_symbol.h:776
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:547
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:203
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.
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:116
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:69
@ ID_LIBVIEW_SYM_LIST
Definition eeschema_id.h:74
@ ID_LIBVIEW_SELECT_BODY_STYLE
Definition eeschema_id.h:70
@ ID_LIBVIEW_LIB_FILTER
Definition eeschema_id.h:71
@ ID_LIBVIEW_LIB_LIST
Definition eeschema_id.h:72
@ ID_LIBVIEW_SYM_FILTER
Definition eeschema_id.h:73
@ FRAME_SCH_VIEWER
Definition frame_type.h:36
const wxChar *const traceLibWatch
Flag to enable debug output for library file watch refreshes.
@ ID_ON_GRID_SELECT
Definition id.h:116
@ ID_ON_ZOOM_SELECT
Definition id.h:115
PROJECT & Prj()
Definition kicad.cpp:642
@ 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
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
CITER next(CITER it)
Definition ptree.cpp:124
@ BASE
Definition sch_item.h:60
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.