KiCad PCB EDA Suite
Loading...
Searching...
No Matches
symbol_editor.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) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2008 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 2004-2023 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 <pgm_base.h>
27#include <confirm.h>
28#include <kidialog.h>
29#include <kiway.h>
30#include <widgets/wx_infobar.h>
31#include <tools/ee_actions.h>
33#include <symbol_edit_frame.h>
34#include <symbol_library.h>
35#include <template_fieldnames.h>
37#include <symbol_lib_table.h>
39#include <symbol_tree_pane.h>
41#include <widgets/lib_tree.h>
45#include <eda_list_dialog.h>
46#include <wx/clipbrd.h>
47#include <wx/filedlg.h>
48#include <wx/log.h>
49#include <project_sch.h>
50#include <string_utils.h>
51#include "symbol_saveas_type.h"
52
54
55
57{
58 wxString title;
59
61 {
63 title = wxT( "*" );
64
65 title += m_reference;
66 title += wxS( " " ) + _( "[from schematic]" );
67 }
68 else if( GetCurSymbol() )
69 {
71 title = wxT( "*" );
72
73 title += UnescapeString( GetCurSymbol()->GetLibId().Format() );
74
76 title += wxS( " " ) + _( "[Read Only Library]" );
77 }
78 else
79 {
80 title = _( "[no symbol loaded]" );
81 }
82
83 title += wxT( " \u2014 " ) + _( "Symbol Editor" );
84 SetTitle( title );
85}
86
87
88void SYMBOL_EDIT_FRAME::SelectActiveLibrary( const wxString& aLibrary )
89{
90 wxString selectedLib = aLibrary;
91
92 if( selectedLib.empty() )
93 selectedLib = SelectLibraryFromList();
94
95 if( !selectedLib.empty() )
96 SetCurLib( selectedLib );
97
99}
100
101
103{
104 if( GetCurSymbol() )
105 {
107 {
108 SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
109
110 if( !schframe ) // happens when the schematic editor has been closed
111 {
112 DisplayErrorMessage( this, _( "No schematic currently open." ) );
113 return false;
114 }
115 else
116 {
118 GetScreen()->SetContentModified( false );
119 return true;
120 }
121 }
122 else
123 {
124 const wxString& libName = GetCurSymbol()->GetLibId().GetLibNickname();
125
126 if( m_libMgr->IsLibraryReadOnly( libName ) )
127 {
128 wxString msg = wxString::Format( _( "Symbol library '%s' is not writable." ),
129 libName );
130 wxString msg2 = _( "You must save to a different location." );
131
132 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
133 return saveLibrary( libName, true );
134 }
135 else
136 {
137 return saveLibrary( libName, false );
138 }
139 }
140 }
141
142 return false;
143}
144
145
146bool SYMBOL_EDIT_FRAME::LoadSymbol( const LIB_ID& aLibId, int aUnit, int aBodyStyle )
147{
148 LIB_ID libId = aLibId;
149
150 // Some libraries can't be edited, so load the underlying chosen symbol
152 {
153 if( lib->SchLibType() == SCH_IO_MGR::SCH_DATABASE
154 || lib->SchLibType() == SCH_IO_MGR::SCH_CADSTAR_ARCHIVE
155 || lib->SchLibType() == SCH_IO_MGR::SCH_HTTP )
156
157 {
158 try
159 {
160 LIB_SYMBOL* readOnlySym = PROJECT_SCH::SchSymbolLibTable( &Prj() )->LoadSymbol( aLibId );
161
162 if( readOnlySym && readOnlySym->GetSourceLibId().IsValid() )
163 libId = readOnlySym->GetSourceLibId();
164 }
165 catch( const IO_ERROR& ioe )
166 {
167 wxString msg;
168
169 msg.Printf( _( "Error loading symbol %s from library '%s'." ),
170 aLibId.GetUniStringLibId(), aLibId.GetUniStringLibItemName() );
171 DisplayErrorMessage( this, msg, ioe.What() );
172 return false;
173 }
174 }
175 }
176
178 && GetCurSymbol()->GetLibId() == libId
179 && GetUnit() == aUnit
180 && GetBodyStyle() == aBodyStyle )
181 {
182 return true;
183 }
184
186 {
187 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
188 [&]() -> bool
189 {
190 return saveCurrentSymbol();
191 } ) )
192 {
193 return false;
194 }
195 }
196
198
199 if( LoadSymbolFromCurrentLib( libId.GetLibItemName(), aUnit, aBodyStyle ) )
200 {
201 m_treePane->GetLibTree()->SelectLibId( libId );
202 m_treePane->GetLibTree()->ExpandLibId( libId );
203
204 m_centerItemOnIdle = libId;
205 Bind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
206 setSymWatcher( &libId );
207
208 return true;
209 }
210
211 return false;
212}
213
214
216{
218 Unbind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
219}
220
221
222bool SYMBOL_EDIT_FRAME::LoadSymbolFromCurrentLib( const wxString& aAliasName, int aUnit,
223 int aBodyStyle )
224{
225 LIB_SYMBOL* alias = nullptr;
226
227 try
228 {
229 alias = PROJECT_SCH::SchSymbolLibTable( &Prj() )->LoadSymbol( GetCurLib(), aAliasName );
230 }
231 catch( const IO_ERROR& ioe )
232 {
233 wxString msg;
234
235 msg.Printf( _( "Error loading symbol %s from library '%s'." ),
236 aAliasName,
237 GetCurLib() );
238 DisplayErrorMessage( this, msg, ioe.What() );
239 return false;
240 }
241
242 if( !alias || !LoadOneLibrarySymbolAux( alias, GetCurLib(), aUnit, aBodyStyle ) )
243 return false;
244
245 // Enable synchronized pin edit mode for symbols with interchangeable units
247
250 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasAlternateBodyStyle() );
251
252 if( aUnit > 0 )
254
255 return true;
256}
257
258
259bool SYMBOL_EDIT_FRAME::LoadOneLibrarySymbolAux( LIB_SYMBOL* aEntry, const wxString& aLibrary,
260 int aUnit, int aBodyStyle )
261{
262 bool rebuildMenuAndToolbar = false;
263
264 if( !aEntry || aLibrary.empty() )
265 return false;
266
267 if( aEntry->GetName().IsEmpty() )
268 {
269 wxLogWarning( "Symbol in library '%s' has empty name field.", aLibrary );
270 return false;
271 }
272
274
275 // Symbols from the schematic are edited in place and not managed by the library manager.
277 {
278 delete m_symbol;
279 m_symbol = nullptr;
280
281 SCH_SCREEN* screen = GetScreen();
282 delete screen;
285 rebuildMenuAndToolbar = true;
286 }
287
288 LIB_SYMBOL* lib_symbol = m_libMgr->GetBufferedSymbol( aEntry->GetName(), aLibrary );
289 wxCHECK( lib_symbol, false );
290
291 m_unit = aUnit > 0 ? aUnit : 1;
292 m_bodyStyle = aBodyStyle > 0 ? aBodyStyle : 1;
293
294 // The buffered screen for the symbol
295 SCH_SCREEN* symbol_screen = m_libMgr->GetScreen( lib_symbol->GetName(), aLibrary );
296
297 SetScreen( symbol_screen );
298 SetCurSymbol( new LIB_SYMBOL( *lib_symbol ), true );
299 SetCurLib( aLibrary );
300
301 if( rebuildMenuAndToolbar )
302 {
305 GetInfoBar()->Dismiss();
306 }
307
308 UpdateTitle();
310 SetShowDeMorgan( GetCurSymbol()->HasAlternateBodyStyle() );
311
313
314 if( !IsSymbolFromSchematic() )
315 {
316 LIB_ID libId = GetCurSymbol()->GetLibId();
317 setSymWatcher( &libId );
318 }
319
320 // Let tools add things to the view if necessary
321 if( m_toolManager )
323
325
326 // Display the document information based on the entry selected just in
327 // case the entry is an alias.
329 Refresh();
330
331 return true;
332}
333
334
336{
337 saveAllLibraries( false );
339}
340
341
342void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& aInheritFrom )
343{
345
346 wxArrayString symbolNames;
347 wxString lib = getTargetLib();
348
349 if( !m_libMgr->LibraryExists( lib ) )
350 {
351 lib = SelectLibraryFromList();
352
353 if( !m_libMgr->LibraryExists( lib ) )
354 return;
355 }
356
357 m_libMgr->GetSymbolNames( lib, symbolNames );
358
359 symbolNames.Sort();
360
361 wxString _inheritSymbolName;
362 wxString _infoMessage;
363 wxString msg;
364
365 // if the symbol being inherited from isn't a root symbol, find its root symbol
366 // and use that symbol instead
367 if( !aInheritFrom.IsEmpty() )
368 {
369 LIB_SYMBOL* inheritFromSymbol = m_libMgr->GetBufferedSymbol( aInheritFrom, lib );
370
371 if( inheritFromSymbol )
372 {
373 _inheritSymbolName = aInheritFrom;
374 _infoMessage = wxString::Format( _( "Deriving from symbol '%s'." ),
375 _inheritSymbolName );
376 }
377 else
378 {
379 _inheritSymbolName = aInheritFrom;
380 }
381 }
382
383 DIALOG_LIB_NEW_SYMBOL dlg( this, _infoMessage, &symbolNames, _inheritSymbolName,
384 [&]( wxString newName )
385 {
386 if( newName.IsEmpty() )
387 {
388 wxMessageBox( _( "Symbol must have a name." ) );
389 return false;
390 }
391
392 if( !lib.empty() && m_libMgr->SymbolExists( newName, lib ) )
393 {
394 msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
395 newName,
396 lib );
397
398 KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
399 wxOK | wxCANCEL | wxICON_WARNING );
400 errorDlg.SetOKLabel( _( "Overwrite" ) );
401
402 return errorDlg.ShowModal() == wxID_OK;
403 }
404
405 return true;
406 } );
407
408 dlg.SetMinSize( dlg.GetSize() );
409
410 if( dlg.ShowModal() == wxID_CANCEL )
411 return;
412
413 wxString name = dlg.GetName();
414
415 LIB_SYMBOL new_symbol( name ); // do not create symbol on the heap, it will be buffered soon
416
417 wxString parentSymbolName = dlg.GetParentSymbolName();
418
419 if( parentSymbolName.IsEmpty() )
420 {
421 new_symbol.GetReferenceField().SetText( dlg.GetReference() );
422 new_symbol.SetUnitCount( dlg.GetUnitCount() );
423
424 // Initialize new_symbol.m_TextInside member:
425 // if 0, pin text is outside the body (on the pin)
426 // if > 0, pin text is inside the body
427 if( dlg.GetPinNameInside() )
428 {
429 new_symbol.SetPinNameOffset( dlg.GetPinTextPosition() );
430
431 if( new_symbol.GetPinNameOffset() == 0 )
432 new_symbol.SetPinNameOffset( 1 );
433 }
434 else
435 {
436 new_symbol.SetPinNameOffset( 0 );
437 }
438
439 ( dlg.GetPowerSymbol() ) ? new_symbol.SetPower() : new_symbol.SetNormal();
440 new_symbol.SetShowPinNumbers( dlg.GetShowPinNumber() );
441 new_symbol.SetShowPinNames( dlg.GetShowPinName() );
442 new_symbol.LockUnits( !dlg.GetUnitsInterchangeable() );
443 new_symbol.SetExcludedFromBOM( !dlg.GetIncludeInBom() );
444 new_symbol.SetExcludedFromBoard( !dlg.GetIncludeOnBoard() );
445
446 if( dlg.GetUnitCount() < 2 )
447 new_symbol.LockUnits( false );
448
449 new_symbol.SetHasAlternateBodyStyle( dlg.GetAlternateBodyStyle() );
450 }
451 else
452 {
453 LIB_SYMBOL* parent = m_libMgr->GetAlias( parentSymbolName, lib );
454 wxCHECK( parent, /* void */ );
455 new_symbol.SetParent( parent );
456
457 // Inherit the parent mandatory field attributes.
458 for( int id = 0; id < MANDATORY_FIELDS; ++id )
459 {
460 SCH_FIELD* field = new_symbol.GetFieldById( id );
461
462 // the MANDATORY_FIELDS are exactly that in RAM.
463 wxCHECK( field, /* void */ );
464
465 SCH_FIELD* parentField = parent->GetFieldById( id );
466
467 wxCHECK( parentField, /* void */ );
468
469 *field = *parentField;
470
471 switch( id )
472 {
473 case REFERENCE_FIELD:
474 // parent's reference already copied
475 break;
476
477 case VALUE_FIELD:
478 if( parent->IsPower() )
479 field->SetText( name );
480 break;
481
482 case FOOTPRINT_FIELD:
483 case DATASHEET_FIELD:
484 // - footprint might be the same as parent, but might not
485 // - datasheet is most likely different
486 // - probably best to play it safe and copy neither
487 field->SetText( wxEmptyString );
488 break;
489 }
490
491 field->SetParent( &new_symbol );
492 }
493 }
494
495 m_libMgr->UpdateSymbol( &new_symbol, lib );
496 SyncLibraries( false );
497 LoadSymbol( name, lib, 1 );
498
499 // must be called after loadSymbol, that calls SetShowDeMorgan, but
500 // because the symbol is empty,it looks like it has no alternate body
501 // and a derived symbol inherits its parent body.
502 if( !new_symbol.GetParent().lock() )
503 SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
504 else
506}
507
508
510{
511 wxString libName;
512
513 if( IsLibraryTreeShown() )
515
516 if( libName.empty() )
517 {
519 }
520 else if( m_libMgr->IsLibraryReadOnly( libName ) )
521 {
522 wxString msg = wxString::Format( _( "Symbol library '%s' is not writable." ),
523 libName );
524 wxString msg2 = _( "You must save to a different location." );
525
526 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
527 saveLibrary( libName, true );
528 }
529 else
530 {
531 saveLibrary( libName, false );
532 }
533
534 if( IsLibraryTreeShown() )
536
537 UpdateTitle();
538}
539
540
542{
543 const wxString& libName = GetTargetLibId().GetLibNickname();
544
545 if( !libName.IsEmpty() )
546 {
547 saveLibrary( libName, true );
549 }
550}
551
552
554{
556
558}
559
560
561static int ID_MAKE_NEW_LIBRARY = 4173;
562
563
565{
566public:
567 SAVE_AS_DIALOG( SYMBOL_EDIT_FRAME* aParent, const wxString& aSymbolName,
568 const wxString& aLibraryPreselect,
569 std::function<bool( wxString libName, wxString symbolName )> aValidator ) :
570 EDA_LIST_DIALOG( aParent, _( "Save Symbol As" ), false ),
571 m_validator( std::move( aValidator ) )
572 {
574 PROJECT_FILE& project = aParent->Prj().GetProjectFile();
576 std::vector<wxString> libNicknames = tbl->GetLogicalLibs();
577 wxArrayString headers;
578 std::vector<wxArrayString> itemsToDisplay;
579
580 headers.Add( _( "Nickname" ) );
581 headers.Add( _( "Description" ) );
582
583 for( const wxString& nickname : libNicknames )
584 {
585 if( alg::contains( project.m_PinnedSymbolLibs, nickname )
586 || alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
587 {
588 wxArrayString item;
589 item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
590 item.Add( tbl->GetDescription( nickname ) );
591 itemsToDisplay.push_back( item );
592 }
593 }
594
595 for( const wxString& nickname : libNicknames )
596 {
597 if( !alg::contains( project.m_PinnedSymbolLibs, nickname )
598 && !alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
599 {
600 wxArrayString item;
601 item.Add( nickname );
602 item.Add( tbl->GetDescription( nickname ) );
603 itemsToDisplay.push_back( item );
604 }
605 }
606
607 initDialog( headers, itemsToDisplay, aLibraryPreselect );
608
609 SetListLabel( _( "Save in library:" ) );
610 SetOKLabel( _( "Save" ) );
611
612 wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
613
614 wxStaticText* label = new wxStaticText( this, wxID_ANY, _( "Name:" ) );
615 bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
616
617 m_symbolNameCtrl = new wxTextCtrl( this, wxID_ANY, aSymbolName );
618 bNameSizer->Add( m_symbolNameCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
619
620 wxButton* newLibraryButton = new wxButton( this, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
621 m_ButtonsSizer->Prepend( 80, 20 );
622 m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
623
624 GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
625
626 Bind( wxEVT_BUTTON,
627 [this]( wxCommandEvent& )
628 {
629 EndModal( ID_MAKE_NEW_LIBRARY );
631
632 // Move nameTextCtrl to the head of the tab-order
633 if( GetChildren().DeleteObject( m_symbolNameCtrl ) )
634 GetChildren().Insert( m_symbolNameCtrl );
635
637
639
640 Layout();
641 GetSizer()->Fit( this );
642
643 Centre();
644 }
645
646 wxString GetSymbolName()
647 {
648 wxString symbolName = m_symbolNameCtrl->GetValue();
649 symbolName.Trim( true );
650 symbolName.Trim( false );
651 symbolName.Replace( " ", "_" );
652 return symbolName;
653 }
654
655protected:
657 {
659 }
660
661private:
662 wxTextCtrl* m_symbolNameCtrl;
663 std::function<bool( wxString libName, wxString symbolName )> m_validator;
664};
665
666
668{
669 LIB_SYMBOL* symbol = getTargetSymbol();
670
671 if( !symbol )
672 return;
673
674 LIB_ID old_lib_id = symbol->GetLibId();
675 wxString symbolName = old_lib_id.GetLibItemName();
676 wxString libraryName = old_lib_id.GetLibNickname();
677 bool valueFollowsName = symbol->GetValueField().GetText() == symbolName;
678 wxString msg;
679 bool done = false;
680
681 while( !done )
682 {
683 SAVE_AS_DIALOG dlg( this, symbolName, libraryName,
684 [&]( const wxString& newLib, const wxString& newName )
685 {
686 if( newLib.IsEmpty() )
687 {
688 wxMessageBox( _( "A library must be specified." ) );
689 return false;
690 }
691
692 if( newName.IsEmpty() )
693 {
694 wxMessageBox( _( "Symbol must have a name." ) );
695 return false;
696 }
697
698 if( m_libMgr->SymbolExists( newName, newLib ) )
699 {
700 msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
701 newName, newLib );
702
703 KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
704 wxOK | wxCANCEL | wxICON_WARNING );
705 errorDlg.SetOKLabel( _( "Overwrite" ) );
706
707 return errorDlg.ShowModal() == wxID_OK;
708 }
709
710 // @todo Either check the selecteced library to see if the parent symbol name
711 // is in the new library and/or copy the parent symbol as well. This is
712 // the lazy solution to ensure derived symbols do not get orphaned.
713 if( symbol->IsAlias() && newLib != old_lib_id.GetLibNickname().wx_str() )
714 {
715 DisplayError( this, _( "Derived symbols must be saved in the same library "
716 "as their parent symbol." ) );
717 return false;
718 }
719
720 return true;
721 } );
722
723 int ret = dlg.ShowModal();
724
725 if( ret == wxID_CANCEL )
726 {
727 return;
728 }
729 else if( ret == wxID_OK )
730 {
731 symbolName = dlg.GetSymbolName();
732 libraryName = dlg.GetTextSelection();
733 done = true;
734 }
735 else if( ret == ID_MAKE_NEW_LIBRARY )
736 {
737 wxFileName newLibrary( AddLibraryFile( true ) );
738 libraryName = newLibrary.GetName();
739 }
740 }
741
742 LIB_SYMBOL new_symbol( *symbol );
743 new_symbol.SetName( symbolName );
744
745 if( valueFollowsName )
746 new_symbol.GetValueField().SetText( symbolName );
747
748 m_libMgr->UpdateSymbol( &new_symbol, libraryName );
749 SyncLibraries( false );
750}
751
752
754{
755 wxCHECK( m_symbol, /* void */ );
756
757 wxString lib = GetCurLib();
758
759 if( !lib.IsEmpty() && aOldName && *aOldName != m_symbol->GetName() )
760 {
761 // Test the current library for name conflicts
762 if( m_libMgr->SymbolExists( m_symbol->GetName(), lib ) )
763 {
764 wxString msg = wxString::Format( _( "Symbol name '%s' already in use." ),
766
767 DisplayErrorMessage( this, msg );
768 m_symbol->SetName( *aOldName );
769 }
770 else
771 {
772 m_libMgr->UpdateSymbolAfterRename( m_symbol, *aOldName, lib );
773 }
774
775 // Reselect the renamed symbol
777 }
778
780 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasAlternateBodyStyle() );
781 UpdateTitle();
782
783 // N.B. The view needs to be rebuilt first as the Symbol Properties change may invalidate
784 // the view pointers by rebuilting the field table
785 RebuildView();
787
788 OnModify();
789}
790
791
793{
794 std::vector<LIB_ID> toDelete = GetSelectedLibIds();
795
796 if( toDelete.empty() )
797 toDelete.emplace_back( GetTargetLibId() );
798
799 for( LIB_ID& libId : toDelete )
800 {
801 if( m_libMgr->IsSymbolModified( libId.GetLibItemName(), libId.GetLibNickname() )
802 && !IsOK( this, wxString::Format( _( "The symbol '%s' has been modified.\n"
803 "Do you want to remove it from the library?" ),
804 libId.GetUniStringLibItemName() ) ) )
805 {
806 continue;
807 }
808
809 if( m_libMgr->HasDerivedSymbols( libId.GetLibItemName(), libId.GetLibNickname() ) )
810 {
811 wxString msg;
812
813 msg.Printf(
814 _( "The symbol %s is used to derive other symbols.\n"
815 "Deleting this symbol will delete all of the symbols derived from it.\n\n"
816 "Do you wish to delete this symbol and all of its derivatives?" ),
817 libId.GetLibItemName().wx_str() );
818
819 wxMessageDialog::ButtonLabel yesButtonLabel( _( "Delete Symbol" ) );
820 wxMessageDialog::ButtonLabel noButtonLabel( _( "Keep Symbol" ) );
821
822 wxMessageDialog dlg( this, msg, _( "Warning" ),
823 wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTER );
824 dlg.SetYesNoLabels( yesButtonLabel, noButtonLabel );
825
826 if( dlg.ShowModal() == wxID_NO )
827 continue;
828 }
829
830 if( IsCurrentSymbol( libId ) )
831 emptyScreen();
832
833 m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
834 }
835
837}
838
839
841{
842 std::vector<LIB_ID> symbols;
843
844 if( GetTreeLIBIDs( symbols ) == 0 )
845 return;
846
847 STRING_FORMATTER formatter;
848
849 for( LIB_ID& libId : symbols )
850 {
851 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(),
852 libId.GetLibNickname() );
853
854 if( !symbol )
855 continue;
856
857 std::unique_ptr<LIB_SYMBOL> tmp = symbol->Flatten();
858 SCH_IO_KICAD_SEXPR::FormatLibSymbol( tmp.get(), formatter );
859 }
860
861 wxLogNull doNotLog; // disable logging of failed clipboard actions
862
863 auto clipboard = wxTheClipboard;
864 wxClipboardLocker clipboardLock( clipboard );
865
866 if( !clipboardLock || !clipboard->IsOpened() )
867 return;
868
869 auto data = new wxTextDataObject( wxString( formatter.GetString().c_str(), wxConvUTF8 ) );
870 clipboard->SetData( data );
871
872 clipboard->Flush();
873}
874
875
876void SYMBOL_EDIT_FRAME::DuplicateSymbol( bool aFromClipboard )
877{
878 LIB_ID libId = GetTargetLibId();
879 wxString lib = libId.GetLibNickname();
880
881 if( !m_libMgr->LibraryExists( lib ) )
882 return;
883
884 std::vector<LIB_SYMBOL*> newSymbols;
885
886 if( aFromClipboard )
887 {
888 std::string clipboardData = m_toolManager->GetClipboardUTF8();
889
890 try
891 {
892 newSymbols = SCH_IO_KICAD_SEXPR::ParseLibSymbols( clipboardData, "Clipboard" );
893 }
894 catch( IO_ERROR& e )
895 {
896 wxLogMessage( wxS( "Can not paste: %s" ), e.Problem() );
897 }
898 }
899 else if( LIB_SYMBOL* srcSymbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(), lib ) )
900 {
901 newSymbols.emplace_back( new LIB_SYMBOL( *srcSymbol ) );
902
903 // Derive from same parent.
904 if( srcSymbol->IsAlias() )
905 {
906 if( std::shared_ptr<LIB_SYMBOL> srcParent = srcSymbol->GetParent().lock() )
907 newSymbols.back()->SetParent( srcParent.get() );
908 }
909 }
910
911 if( newSymbols.empty() )
912 return;
913
914 for( LIB_SYMBOL* symbol : newSymbols )
915 {
916 ensureUniqueName( symbol, lib );
917 m_libMgr->UpdateSymbol( symbol, lib );
918
919 LoadOneLibrarySymbolAux( symbol, lib, GetUnit(), GetBodyStyle() );
920 }
921
922 SyncLibraries( false );
923 m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, newSymbols[0]->GetName() ) );
924
925 for( LIB_SYMBOL* symbol : newSymbols )
926 delete symbol;
927}
928
929
930void SYMBOL_EDIT_FRAME::ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
931{
932 if( aSymbol )
933 {
934 int i = 1;
935 wxString newName = aSymbol->GetName();
936
937 // Append a number to the name until the name is unique in the library.
938 while( m_libMgr->SymbolExists( newName, aLibrary ) )
939 newName.Printf( "%s_%d", aSymbol->GetName(), i++ );
940
941 aSymbol->SetName( newName );
942 }
943}
944
945
946void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
947{
948 LIB_ID libId = GetTargetLibId();
949 const wxString& libName = libId.GetLibNickname();
950
951 // Empty if this is the library itself that is selected.
952 const wxString& symbolName = libId.GetLibItemName();
953
954 wxString msg = wxString::Format( _( "Revert '%s' to last version saved?" ),
955 symbolName.IsEmpty() ? libName : symbolName );
956
957 if( aConfirm && !ConfirmRevertDialog( this, msg ) )
958 return;
959
960 bool reload_currentSymbol = false;
961 wxString curr_symbolName = symbolName;
962
963 if( GetCurSymbol() )
964 {
965 // the library itself is reverted: the current symbol will be reloaded only if it is
966 // owned by this library
967 if( symbolName.IsEmpty() )
968 {
969 LIB_ID curr_libId = GetCurSymbol()->GetLibId();
970 reload_currentSymbol = libName == curr_libId.GetLibNickname().wx_str();
971
972 if( reload_currentSymbol )
973 curr_symbolName = curr_libId.GetUniStringLibItemName();
974 }
975 else
976 {
977 reload_currentSymbol = IsCurrentSymbol( libId );
978 }
979 }
980
981 int unit = m_unit;
982
983 if( reload_currentSymbol )
984 emptyScreen();
985
986 if( symbolName.IsEmpty() )
987 {
988 m_libMgr->RevertLibrary( libName );
989 }
990 else
991 {
992 libId = m_libMgr->RevertSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
993
994 m_treePane->GetLibTree()->SelectLibId( libId );
996 }
997
998 if( reload_currentSymbol && m_libMgr->SymbolExists( curr_symbolName, libName ) )
999 LoadSymbol( curr_symbolName, libName, unit );
1000
1001 m_treePane->Refresh();
1002}
1003
1004
1006{
1007 wxCHECK_RET( m_libMgr, "Library manager object not created." );
1008
1009 Revert( false );
1011}
1012
1013
1014void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLibrary, int aUnit )
1015{
1017 {
1018 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
1019 [&]() -> bool
1020 {
1021 return saveCurrentSymbol();
1022 } ) )
1023 {
1024 return;
1025 }
1026 }
1027
1028 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aAlias, aLibrary );
1029
1030 if( !symbol )
1031 {
1032 DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
1033 aAlias,
1034 aLibrary ) );
1036 return;
1037 }
1038
1039 // Optimize default edit options for this symbol
1040 // Usually if units are locked, graphic items are specific to each unit
1041 // and if units are interchangeable, graphic items are common to units
1043 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
1044
1045 LoadOneLibrarySymbolAux( symbol, aLibrary, aUnit, 0 );
1046}
1047
1048
1049bool SYMBOL_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
1050{
1051 wxFileName fn;
1052 wxString msg;
1053 SYMBOL_SAVEAS_TYPE type = SYMBOL_SAVEAS_TYPE::NORMAL_SAVE_AS;
1054 SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
1055 PROJECT& prj = Prj();
1056
1058
1059 if( !aNewFile && ( aLibrary.empty() || !PROJECT_SCH::SchSymbolLibTable( &prj )->HasLibrary( aLibrary ) ) )
1060 {
1061 ShowInfoBarError( _( "No library specified." ) );
1062 return false;
1063 }
1064
1065 if( aNewFile )
1066 {
1067 SEARCH_STACK* search = PROJECT_SCH::SchSearchS( &prj );
1068
1069 // Get a new name for the library
1070 wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
1071
1072 if( !default_path )
1073 default_path = search->LastVisitedPath();
1074
1075 fn.SetName( aLibrary );
1077
1078 wxString wildcards = FILEEXT::KiCadSymbolLibFileWildcard();
1079
1080 wxFileDialog dlg( this, wxString::Format( _( "Save Library '%s' As..." ), aLibrary ),
1081 default_path, fn.GetFullName(), wildcards,
1082 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1083
1084 SYMBOL_FILEDLG_SAVE_AS saveAsHook( type );
1085 dlg.SetCustomizeHook( saveAsHook );
1086
1087 if( dlg.ShowModal() == wxID_CANCEL )
1088 return false;
1089
1090 fn = dlg.GetPath();
1091
1092 prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
1093
1094 if( fn.GetExt().IsEmpty() )
1096
1097 type = saveAsHook.GetOption();
1098 }
1099 else
1100 {
1101 fn = PROJECT_SCH::SchSymbolLibTable( &prj )->GetFullURI( aLibrary );
1103
1104 if( fileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
1105 fileType = SCH_IO_MGR::SCH_KICAD;
1106 }
1107
1108 // Verify the user has write privileges before attempting to save the library file.
1109 if( !aNewFile && m_libMgr->IsLibraryReadOnly( aLibrary ) )
1110 return false;
1111
1112 ClearMsgPanel();
1113
1114 // Copy .kicad_symb file to .bak.
1115 if( !backupFile( fn, "bak" ) )
1116 return false;
1117
1118 if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), fileType ) )
1119 {
1120 msg.Printf( _( "Failed to save changes to symbol library file '%s'." ),
1121 fn.GetFullPath() );
1122 DisplayErrorMessage( this, _( "Error Saving Library" ), msg );
1123 return false;
1124 }
1125
1126 if( !aNewFile )
1127 {
1128 m_libMgr->ClearLibraryModified( aLibrary );
1129
1130 // Update the library modification time so that we don't reload based on the watcher
1131 if( aLibrary == getTargetLib() )
1132 SetSymModificationTime( fn.GetModificationTime() );
1133 }
1134 else
1135 {
1136 bool resyncLibTree = false;
1137 wxString originalLibNickname = getTargetLib();
1138 wxString forceRefresh;
1139
1140 switch( type )
1141 {
1142 case SYMBOL_SAVEAS_TYPE::REPLACE_TABLE_ENTRY:
1143 resyncLibTree = replaceLibTableEntry( originalLibNickname, fn.GetFullPath() );
1144 forceRefresh = originalLibNickname;
1145 break;
1146
1147 case SYMBOL_SAVEAS_TYPE::ADD_GLOBAL_TABLE_ENTRY:
1148 resyncLibTree = addLibTableEntry( fn.GetFullPath() );
1149 break;
1150
1151 case SYMBOL_SAVEAS_TYPE::ADD_PROJECT_TABLE_ENTRY:
1152 resyncLibTree = addLibTableEntry( fn.GetFullPath(), PROJECT_LIB_TABLE );
1153 break;
1154
1155 default:
1156 break;
1157 }
1158
1159 if( resyncLibTree )
1160 {
1162 SyncLibraries( true, false, forceRefresh );
1164 }
1165 }
1166
1167 ClearMsgPanel();
1168 msg.Printf( _( "Symbol library file '%s' saved." ), fn.GetFullPath() );
1170
1171 return true;
1172}
1173
1174
1175bool SYMBOL_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
1176{
1177 wxString msg, msg2;
1178 bool doSave = true;
1179 int dirtyCount = 0;
1180 bool applyToAll = false;
1181 bool retv = true;
1182
1183 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1184 {
1185 if( m_libMgr->IsLibraryModified( libNickname ) )
1186 dirtyCount++;
1187 }
1188
1189 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1190 {
1191 if( m_libMgr->IsLibraryModified( libNickname ) )
1192 {
1193 if( aRequireConfirmation && !applyToAll )
1194 {
1195 msg.Printf( _( "Save changes to '%s' before closing?" ), libNickname );
1196
1197 switch( UnsavedChangesDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
1198 {
1199 case wxID_YES: doSave = true; break;
1200 case wxID_NO: doSave = false; break;
1201 default:
1202 case wxID_CANCEL: return false;
1203 }
1204 }
1205
1206 if( doSave )
1207 {
1208 // If saving under existing name fails then do a Save As..., and if that
1209 // fails then cancel close action.
1210 if( m_libMgr->IsLibraryReadOnly( libNickname ) )
1211 {
1212 msg.Printf( _( "Symbol library '%s' is not writable." ), libNickname );
1213 msg2 = _( "You must save to a different location." );
1214
1215 if( dirtyCount == 1 )
1216 {
1217 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) != wxID_OK )
1218 {
1219 retv = false;
1220 continue;
1221 }
1222 }
1223 else
1224 {
1225 m_infoBar->Dismiss();
1226 m_infoBar->ShowMessageFor( msg + wxS( " " ) + msg2,
1227 2000, wxICON_EXCLAMATION );
1228
1229 while( m_infoBar->IsShownOnScreen() )
1230 wxSafeYield();
1231
1232 retv = false;
1233 continue;
1234 }
1235 }
1236 else if( saveLibrary( libNickname, false ) )
1237 {
1238 continue;
1239 }
1240
1241 if( !saveLibrary( libNickname, true ) )
1242 retv = false;
1243 }
1244 }
1245 }
1246
1247 UpdateTitle();
1248 return retv;
1249}
1250
1251
1253{
1255
1256 if( !m_symbol )
1257 return;
1258
1259 wxString msg = m_symbol->GetName();
1260
1261 AppendMsgPanel( _( "Name" ), UnescapeString( msg ), 8 );
1262
1263 if( m_symbol->IsAlias() )
1264 {
1265 LIB_SYMBOL_SPTR parent = m_symbol->GetParent().lock();
1266
1267 msg = parent ? parent->GetName() : _( "Undefined!" );
1268 AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 );
1269 }
1270
1271 static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
1272 msg = UnitLetter[m_unit];
1273
1274 AppendMsgPanel( _( "Unit" ), msg, 8 );
1275
1276 if( m_bodyStyle == BODY_STYLE::DEMORGAN )
1277 msg = _( "Alternate" );
1278 else if( m_bodyStyle == BODY_STYLE::BASE )
1279 msg = _( "Standard" );
1280 else
1281 msg = wxT( "?" );
1282
1283 AppendMsgPanel( _( "Body" ), msg, 8 );
1284
1285 if( m_symbol->IsPower() )
1286 msg = _( "Power Symbol" );
1287 else
1288 msg = _( "Symbol" );
1289
1290 AppendMsgPanel( _( "Type" ), msg, 8 );
1291 AppendMsgPanel( _( "Description" ), m_symbol->GetDescription(), 8 );
1292 AppendMsgPanel( _( "Keywords" ), m_symbol->GetKeyWords() );
1293 AppendMsgPanel( _( "Datasheet" ), m_symbol->GetDatasheetField().GetText() );
1294}
const char * name
Definition: DXF_plotter.cpp:57
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
static TOOL_ACTION zoomFitScreen
Definition: actions.h:126
void SetContentModified(bool aModified=true)
Definition: base_screen.h:59
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:102
void SetupStandardButtons(std::map< int, wxString > aLabels={})
virtual void ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
WX_INFOBAR * m_infoBar
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false, WX_INFOBAR::MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
void ReCreateMenuBar()
Recreates the menu bar.
WX_INFOBAR * GetInfoBar()
virtual void ClearMsgPanel()
Clear all messages from the message panel.
void AppendMsgPanel(const wxString &aTextUpper, const wxString &aTextLower, int aPadding=6)
Append a message to the message panel.
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:104
A dialog which shows:
void SetOKLabel(const wxString &aLabel)
void initDialog(const wxArrayString &aItemHeaders, const std::vector< wxArrayString > &aItemList, const wxString &aPreselectText)
wxString GetTextSelection(int aColumn=0)
Return the selected text from aColumn in the wxListCtrl in the dialog.
void SetListLabel(const wxString &aLabel)
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:94
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:46
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition: view.cpp:1563
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:406
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
bool IsValid() const
Check if this LID_ID is valid.
Definition: lib_id.h:172
wxString GetUniStringLibId() const
Definition: lib_id.h:148
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition: lib_id.h:112
const wxString GetUniStringLibNickname() const
Definition: lib_id.h:88
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
Define a library symbol object.
Definition: lib_symbol.h:78
wxString GetDescription() const override
Definition: lib_symbol.h:158
const LIB_ID & GetLibId() const override
Definition: lib_symbol.h:143
wxString GetKeyWords() const override
Definition: lib_symbol.h:171
bool IsMulti() const override
Definition: lib_symbol.h:554
bool IsPower() const override
Definition: lib_symbol.cpp:389
void SetUnitCount(int aCount, bool aDuplicateDrawItems=true)
Set the units per symbol count.
bool UnitsLocked() const
Check whether symbol units are interchangeable.
Definition: lib_symbol.h:264
SCH_FIELD & GetValueField() const
Return reference to the value field.
LIB_ID GetSourceLibId() const
Definition: lib_symbol.h:146
bool IsAlias() const
Definition: lib_symbol.h:195
void SetPower()
Definition: lib_symbol.cpp:405
bool HasAlternateBodyStyle() const override
Test if symbol has more than one body conversion type (DeMorgan).
SCH_FIELD * GetFieldById(int aId) const
Return pointer to the requested field.
SCH_FIELD & GetDatasheetField() const
Return reference to the datasheet field.
void LockUnits(bool aLockUnits)
Set interchangeable the property for symbol units.
Definition: lib_symbol.h:258
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:295
wxString GetName() const override
Definition: lib_symbol.h:137
SCH_FIELD & GetReferenceField() const
Return reference to the reference designator field.
void SetHasAlternateBodyStyle(bool aHasAlternate, bool aDuplicatePins=true)
Set or clear the alternate body style (DeMorgan) for the symbol.
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:304
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:106
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:288
void SetNormal()
Definition: lib_symbol.cpp:433
const wxString GetDescription(const wxString &aNickname)
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
wxString GetFullURI(const wxString &aLibNickname, bool aExpandEnvVars=true) const
Return the full URI of the library mapped to aLibNickname.
static const wxString GetPinningSymbol()
void RefreshLibTree()
Refreshes the tree (mainly to update highlighting and asterisking)
Definition: lib_tree.cpp:440
void CenterLibId(const LIB_ID &aLibId)
Ensure that an item is visible (preferably centered).
Definition: lib_tree.cpp:349
void SelectLibId(const LIB_ID &aLibId)
Select an item in the tree widget.
Definition: lib_tree.cpp:343
void ExpandLibId(const LIB_ID &aLibId)
Expand and item i the tree widget.
Definition: lib_tree.cpp:363
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:678
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:70
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
static SEARCH_STACK * SchSearchS(PROJECT *aProject)
Accessor for Eeschema search stack.
Definition: project_sch.cpp:41
Container for project specific data.
Definition: project.h:62
@ SCH_LIB_PATH
Definition: project.h:182
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:166
virtual void SetRString(RSTRING_T aStringId, const wxString &aString)
Store a "retained string", which is any session and project specific string identified in enum RSTRIN...
Definition: project.cpp:269
virtual const wxString & GetRString(RSTRING_T aStringId)
Return a "retained string", which is any session and project specific string identified in enum RSTRI...
Definition: project.cpp:280
wxString GetSymbolName()
bool TransferDataFromWindow() override
wxTextCtrl * m_symbolNameCtrl
SAVE_AS_DIALOG(SYMBOL_EDIT_FRAME *aParent, const wxString &aSymbolName, const wxString &aLibraryPreselect, std::function< bool(wxString libName, wxString symbolName)> aValidator)
std::function< bool(wxString libName, wxString symbolName)> m_validator
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.
wxString SelectLibraryFromList()
Display a list of loaded libraries and allows the user to select a library.
void SetSymModificationTime(const wxDateTime &aTime)
Set the modification time of the symbol library table file.
void setSymWatcher(const LIB_ID *aSymbol)
Creates (or removes) a watcher on the specified symbol library.
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
Schematic editor (Eeschema) main window.
void SaveSymbolToSchematic(const LIB_SYMBOL &aSymbol, const KIID &aSchematicSymbolUUID)
Update a schematic symbol from a LIB_SYMBOL.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1205
static void FormatLibSymbol(LIB_SYMBOL *aPart, OUTPUTFORMATTER &aFormatter)
static std::vector< LIB_SYMBOL * > ParseLibSymbols(std::string &aSymbolText, std::string aSource, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a symbol library using the file extension of aLibPath.
Definition: sch_io_mgr.cpp:140
Look for files in a number of paths.
Definition: search_stack.h:43
const wxString LastVisitedPath(const wxString &aSubPathToSearch=wxEmptyString)
A quirky function inherited from old code that seems to serve particular needs in the UI.
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:433
const std::string & GetString()
Definition: richio.h:456
SYMBOL_EDITOR_DRAWING_TOOLS.
The symbol library editor main window.
void ClearMsgPanel() override
Clear all messages from the message panel.
void UpdateAfterSymbolProperties(wxString *aOldName=nullptr)
void SaveAll()
Save all modified symbols and libraries.
void DeleteSymbolFromLibrary()
bool addLibTableEntry(const wxString &aLibFile, TABLE_SCOPE aScope=GLOBAL_LIB_TABLE)
Add aLibFile to the symbol library table defined by aScope.
bool IsLibraryTreeShown() const override
wxString getTargetLib() const
bool IsCurrentSymbol(const LIB_ID &aLibId) const
Restore the empty editor screen, without any symbol or library selected.
bool backupFile(const wxFileName &aOriginalFile, const wxString &aBackupExt)
Return currently edited symbol.
int GetTreeLIBIDs(std::vector< LIB_ID > &aSelection) const
LIB_ID GetTreeLIBID(int *aUnit=nullptr) const
Return the LIB_ID of the library or symbol selected in the symbol tree.
LIB_SYMBOL_LIBRARY_MANAGER * m_libMgr
wxString GetCurLib() const
The nickname of the current library being edited and empty string if none.
void Save()
Save the selected symbol or library.
void LoadSymbol(const wxString &aLibrary, const wxString &aSymbol, int Unit)
int GetBodyStyle() const
bool m_SyncPinEdit
Set to true to synchronize pins at the same position when editing symbols with multiple units or mult...
void Revert(bool aConfirm=true)
Revert unsaved changes in a symbol, restoring to the last saved state.
void centerItemIdleHandler(wxIdleEvent &aEvent)
bool replaceLibTableEntry(const wxString &aLibNickname, const wxString &aLibFile)
Replace the file path of the symbol library table entry aLibNickname with aLibFile.
bool IsSymbolFromSchematic() const
void SetScreen(BASE_SCREEN *aScreen) override
void SaveSymbolCopyAs()
Save the currently selected symbol to a new name and/or location.
void DuplicateSymbol(bool aFromClipboard)
Insert a duplicate symbol.
SCH_SCREEN * m_dummyScreen
< Helper screen used when no symbol is loaded
void SetCurSymbol(LIB_SYMBOL *aSymbol, bool aUpdateZoom)
Take ownership of aSymbol and notes that it is the one currently being edited.
KIID m_schematicSymbolUUID
RefDes of the symbol (only valid if symbol was loaded from schematic)
std::vector< LIB_ID > GetSelectedLibIds() const
void SyncLibraries(bool aShowProgress, bool aPreloadCancelled=false, const wxString &aForceRefresh=wxEmptyString)
Synchronize the library manager to the symbol library table, and then the symbol tree to the library ...
LIB_SYMBOL * GetCurSymbol() const
Return the current symbol being edited or NULL if none selected.
void UpdateSymbolMsgPanelInfo()
Display the documentation of the selected symbol.
LIB_ID GetTargetLibId() const override
Return either the symbol selected in the symbol tree (if context menu is active) or the symbol on the...
bool saveLibrary(const wxString &aLibrary, bool aNewFile)
Save the changes to the current library.
void SelectActiveLibrary(const wxString &aLibrary=wxEmptyString)
Set the current active library to aLibrary.
int m_bodyStyle
Flag if the symbol being edited was loaded directly from a schematic.
bool saveAllLibraries(bool aRequireConfirmation)
Save the current symbol.
void UpdateMsgPanel() override
Redraw the message panel.
void CreateNewSymbol(const wxString &newName=wxEmptyString)
Create a new symbol in the selected library.
wxString SetCurLib(const wxString &aLibNickname)
Set the current library nickname and returns the old library nickname.
void UpdateTitle()
Update the main window title bar with the current library name and read only status of the library.
void ReCreateHToolbar() override
SYMBOL_TREE_PANE * m_treePane
bool LoadOneLibrarySymbolAux(LIB_SYMBOL *aLibEntry, const wxString &aLibrary, int aUnit, int aBodyStyle)
Create a copy of aLibEntry into memory.
bool LoadSymbolFromCurrentLib(const wxString &aAliasName, int aUnit=0, int aBodyStyle=0)
Load a symbol from the current active library, optionally setting the selected unit and convert.
bool saveCurrentSymbol()
Store the currently modified symbol in the library manager buffer.
wxString AddLibraryFile(bool aCreateNew)
Create or add an existing library to the symbol library table.
void ensureUniqueName(LIB_SYMBOL *aSymbol, const wxString &aLibrary)
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current symbol.
void SetShowDeMorgan(bool show)
void SaveLibraryAs()
Save the currently selected library to a new file.
bool IsContentModified() const override
Get if any symbols or libraries have been modified but not saved.
LIB_SYMBOL * getTargetSymbol() const
Return either the library selected in the symbol tree, if context menu is active or the library that ...
SYMBOL_SAVEAS_TYPE GetOption() const
LIB_SYMBOL * GetBufferedSymbol(const wxString &aAlias, const wxString &aLibrary)
Return the symbol copy from the buffer.
bool UpdateSymbolAfterRename(LIB_SYMBOL *aSymbol, const wxString &oldAlias, const wxString &aLibrary)
Update the symbol buffer with a new version of the symbol when the name has changed.
bool IsLibraryReadOnly(const wxString &aLibrary) const
Return true if the library is stored in a read-only file.
bool ClearSymbolModified(const wxString &aAlias, const wxString &aLibrary) const
Clear the modified flag for a symbol.
bool LibraryExists(const wxString &aLibrary, bool aCheckEnabled=false) const
Return true if library exists.
bool ClearLibraryModified(const wxString &aLibrary) const
Clear the modified flag for all symbols in a library.
LIB_SYMBOL * GetAlias(const wxString &aAlias, const wxString &aLibrary) const
Return either an alias of a working LIB_SYMBOL copy, or alias of the original symbol if there is no w...
SCH_SCREEN * GetScreen(const wxString &aAlias, const wxString &aLibrary)
Return the screen used to edit a specific symbol.
bool IsLibraryModified(const wxString &aLibrary) const
Return true if library has unsaved modifications.
wxArrayString GetLibraryNames() const
Return the array of library names.
bool SymbolExists(const wxString &aAlias, const wxString &aLibrary) const
Return true if symbol with a specific alias exists in library (either original one or buffered).
bool RemoveSymbol(const wxString &aName, const wxString &aLibrary)
Remove the symbol from the symbol buffer.
bool IsSymbolModified(const wxString &aAlias, const wxString &aLibrary) const
Return true if symbol has unsaved modifications.
bool RevertLibrary(const wxString &aLibrary)
Revert unsaved changes for a symbolicular library.
void GetSymbolNames(const wxString &aLibName, wxArrayString &aSymbolNames, SYMBOL_NAME_FILTER aFilter=SYMBOL_NAME_FILTER::ALL)
bool RevertAll()
Revert all pending changes.
LIB_ID RevertSymbol(const wxString &aAlias, const wxString &aLibrary)
Revert unsaved changes for a symbolicular symbol.
SYMBOL_LIB_TABLE_ROW * GetLibrary(const wxString &aLibrary) const
Find a single library within the (aggregate) library table.
bool UpdateSymbol(LIB_SYMBOL *aSymbol, const wxString &aLibrary)
Update the symbol buffer with a new version of the symbol.
bool SaveLibrary(const wxString &aLibrary, const wxString &aFileName, SCH_IO_MGR::SCH_FILE_T aFileType=SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY)
Save library to a file, including unsaved changes.
bool HasDerivedSymbols(const wxString &aSymbolName, const wxString &aLibraryName)
Check if symbol aSymbolName in library aLibraryName is a root symbol that has derived symbols.
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_IO object i...
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
LIB_TREE * GetLibTree() const
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: symbol.h:129
int GetPinNameOffset() const
Definition: symbol.h:118
virtual void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: symbol.h:123
void SetExcludedFromBOM(bool aExcludeFromBOM)
Set or clear the exclude from schematic bill of materials flag.
Definition: symbol.h:141
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
Definition: symbol.h:117
void SetExcludedFromBoard(bool aExcludeFromBoard)
Set or clear exclude from board netlist flag.
Definition: symbol.h:147
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:167
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition: tool_base.h:80
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:150
std::string GetClipboardUTF8() const
Return the information currently stored in the system clipboard.
void ResetTools(TOOL_BASE::RESET_REASON aReason)
Reset all tools (i.e.
wxString wx_str() const
Definition: utf8.cpp:45
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION, MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the infobar with the provided message and icon for a specific period of time.
Definition: wx_infobar.cpp:140
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: wx_infobar.cpp:190
int OKOrCancelDialog(wxWindow *aParent, const wxString &aWarning, const wxString &aMessage, const wxString &aDetailedMessage, const wxString &aOKLabel, const wxString &aCancelLabel, bool *aApplyToAll)
Display a warning dialog with aMessage and returns the user response.
Definition: confirm.cpp:143
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:250
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition: confirm.cpp:130
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:195
int UnsavedChangesDialog(wxWindow *parent, const wxString &aMessage, bool *aApplyToAll)
A specialized version of HandleUnsavedChanges which handles an apply-to-all checkbox.
Definition: confirm.cpp:66
bool ConfirmRevertDialog(wxWindow *parent, const wxString &aMessage)
Display a confirmation dialog for a revert action.
Definition: confirm.cpp:119
This file is part of the common library.
#define _(s)
static int ID_MAKE_NEW_LIBRARY
@ FRAME_SCH
Definition: frame_type.h:34
static const std::string KiCadSymbolLibFileExtension
static wxString KiCadSymbolLibFileWildcard()
PROJECT & Prj()
Definition: kicad.cpp:595
This file is part of the common library.
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
Definition: lib_symbol.h:46
@ ALL
All except INITIAL_ADD.
Definition: view_item.h:58
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
STL namespace.
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
see class PGM_BASE
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
KIWAY Kiway(KFCTL_STANDALONE)
MODEL3D_FORMAT_TYPE fileType(const char *aFileName)
wxString UnescapeString(const wxString &aSource)
std::vector< wxString > pinned_symbol_libs
static int ID_MAKE_NEW_LIBRARY
Definition for symbol library class.
SYMBOL_SAVEAS_TYPE
@ DATASHEET_FIELD
name of datasheet
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ MANDATORY_FIELDS
The first 5 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
Definition of file extensions used in Kicad.