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( IsSymbolTreeShown() )
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( IsSymbolTreeShown() )
536
537 UpdateTitle();
538}
539
540
542{
543 wxCHECK( !GetTargetLibId().GetLibNickname().empty(), /* void */ );
544
545 const wxString& libName = GetTargetLibId().GetLibNickname();
546
547 saveLibrary( libName, true );
549}
550
551
553{
555
557}
558
559
560static int ID_MAKE_NEW_LIBRARY = 4173;
561
562
564{
565public:
566 SAVE_AS_DIALOG( SYMBOL_EDIT_FRAME* aParent, const wxString& aSymbolName,
567 const wxString& aLibraryPreselect,
568 std::function<bool( wxString libName, wxString symbolName )> aValidator ) :
569 EDA_LIST_DIALOG( aParent, _( "Save Symbol As" ), false ),
570 m_validator( std::move( aValidator ) )
571 {
573 PROJECT_FILE& project = aParent->Prj().GetProjectFile();
575 std::vector<wxString> libNicknames = tbl->GetLogicalLibs();
576 wxArrayString headers;
577 std::vector<wxArrayString> itemsToDisplay;
578
579 headers.Add( _( "Nickname" ) );
580 headers.Add( _( "Description" ) );
581
582 for( const wxString& nickname : libNicknames )
583 {
584 if( alg::contains( project.m_PinnedSymbolLibs, nickname )
585 || alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
586 {
587 wxArrayString item;
588 item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
589 item.Add( tbl->GetDescription( nickname ) );
590 itemsToDisplay.push_back( item );
591 }
592 }
593
594 for( const wxString& nickname : libNicknames )
595 {
596 if( !alg::contains( project.m_PinnedSymbolLibs, nickname )
597 && !alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
598 {
599 wxArrayString item;
600 item.Add( nickname );
601 item.Add( tbl->GetDescription( nickname ) );
602 itemsToDisplay.push_back( item );
603 }
604 }
605
606 initDialog( headers, itemsToDisplay, aLibraryPreselect );
607
608 SetListLabel( _( "Save in library:" ) );
609 SetOKLabel( _( "Save" ) );
610
611 wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
612
613 wxStaticText* label = new wxStaticText( this, wxID_ANY, _( "Name:" ) );
614 bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
615
616 m_symbolNameCtrl = new wxTextCtrl( this, wxID_ANY, aSymbolName );
617 bNameSizer->Add( m_symbolNameCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
618
619 wxButton* newLibraryButton = new wxButton( this, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
620 m_ButtonsSizer->Prepend( 80, 20 );
621 m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
622
623 GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
624
625 Bind( wxEVT_BUTTON,
626 [this]( wxCommandEvent& )
627 {
628 EndModal( ID_MAKE_NEW_LIBRARY );
630
631 // Move nameTextCtrl to the head of the tab-order
632 if( GetChildren().DeleteObject( m_symbolNameCtrl ) )
633 GetChildren().Insert( m_symbolNameCtrl );
634
636
638
639 Layout();
640 GetSizer()->Fit( this );
641
642 Centre();
643 }
644
645 wxString GetSymbolName()
646 {
647 wxString symbolName = m_symbolNameCtrl->GetValue();
648 symbolName.Trim( true );
649 symbolName.Trim( false );
650 symbolName.Replace( " ", "_" );
651 return symbolName;
652 }
653
654protected:
656 {
658 }
659
660private:
661 wxTextCtrl* m_symbolNameCtrl;
662 std::function<bool( wxString libName, wxString symbolName )> m_validator;
663};
664
665
667{
668 LIB_SYMBOL* symbol = getTargetSymbol();
669
670 if( !symbol )
671 return;
672
673 LIB_ID old_lib_id = symbol->GetLibId();
674 wxString symbolName = old_lib_id.GetLibItemName();
675 wxString libraryName = old_lib_id.GetLibNickname();
676 bool valueFollowsName = symbol->GetValueField().GetText() == symbolName;
677 wxString msg;
678 bool done = false;
679
680 while( !done )
681 {
682 SAVE_AS_DIALOG dlg( this, symbolName, libraryName,
683 [&]( const wxString& newLib, const wxString& newName )
684 {
685 if( newLib.IsEmpty() )
686 {
687 wxMessageBox( _( "A library must be specified." ) );
688 return false;
689 }
690
691 if( newName.IsEmpty() )
692 {
693 wxMessageBox( _( "Symbol must have a name." ) );
694 return false;
695 }
696
697 if( m_libMgr->SymbolExists( newName, newLib ) )
698 {
699 msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
700 newName, newLib );
701
702 KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
703 wxOK | wxCANCEL | wxICON_WARNING );
704 errorDlg.SetOKLabel( _( "Overwrite" ) );
705
706 return errorDlg.ShowModal() == wxID_OK;
707 }
708
709 // @todo Either check the selecteced library to see if the parent symbol name
710 // is in the new library and/or copy the parent symbol as well. This is
711 // the lazy solution to ensure derived symbols do not get orphaned.
712 if( symbol->IsAlias() && newLib != old_lib_id.GetLibNickname().wx_str() )
713 {
714 DisplayError( this, _( "Derived symbols must be saved in the same library "
715 "as their parent symbol." ) );
716 return false;
717 }
718
719 return true;
720 } );
721
722 int ret = dlg.ShowModal();
723
724 if( ret == wxID_CANCEL )
725 {
726 return;
727 }
728 else if( ret == wxID_OK )
729 {
730 symbolName = dlg.GetSymbolName();
731 libraryName = dlg.GetTextSelection();
732 done = true;
733 }
734 else if( ret == ID_MAKE_NEW_LIBRARY )
735 {
736 wxFileName newLibrary( AddLibraryFile( true ) );
737 libraryName = newLibrary.GetName();
738 }
739 }
740
741 LIB_SYMBOL new_symbol( *symbol );
742 new_symbol.SetName( symbolName );
743
744 if( valueFollowsName )
745 new_symbol.GetValueField().SetText( symbolName );
746
747 m_libMgr->UpdateSymbol( &new_symbol, libraryName );
748 SyncLibraries( false );
749}
750
751
753{
754 wxCHECK( m_symbol, /* void */ );
755
756 wxString lib = GetCurLib();
757
758 if( !lib.IsEmpty() && aOldName && *aOldName != m_symbol->GetName() )
759 {
760 // Test the current library for name conflicts
761 if( m_libMgr->SymbolExists( m_symbol->GetName(), lib ) )
762 {
763 wxString msg = wxString::Format( _( "Symbol name '%s' already in use." ),
765
766 DisplayErrorMessage( this, msg );
767 m_symbol->SetName( *aOldName );
768 }
769 else
770 {
771 m_libMgr->UpdateSymbolAfterRename( m_symbol, *aOldName, lib );
772 }
773
774 // Reselect the renamed symbol
776 }
777
779 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasAlternateBodyStyle() );
780 UpdateTitle();
781
782 // N.B. The view needs to be rebuilt first as the Symbol Properties change may invalidate
783 // the view pointers by rebuilting the field table
784 RebuildView();
786
787 OnModify();
788}
789
790
792{
793 std::vector<LIB_ID> toDelete = GetSelectedLibIds();
794
795 if( toDelete.empty() )
796 toDelete.emplace_back( GetTargetLibId() );
797
798 for( LIB_ID& libId : toDelete )
799 {
800 if( m_libMgr->IsSymbolModified( libId.GetLibItemName(), libId.GetLibNickname() )
801 && !IsOK( this, wxString::Format( _( "The symbol '%s' has been modified.\n"
802 "Do you want to remove it from the library?" ),
803 libId.GetUniStringLibItemName() ) ) )
804 {
805 continue;
806 }
807
808 if( m_libMgr->HasDerivedSymbols( libId.GetLibItemName(), libId.GetLibNickname() ) )
809 {
810 wxString msg;
811
812 msg.Printf(
813 _( "The symbol %s is used to derive other symbols.\n"
814 "Deleting this symbol will delete all of the symbols derived from it.\n\n"
815 "Do you wish to delete this symbol and all of its derivatives?" ),
816 libId.GetLibItemName().wx_str() );
817
818 wxMessageDialog::ButtonLabel yesButtonLabel( _( "Delete Symbol" ) );
819 wxMessageDialog::ButtonLabel noButtonLabel( _( "Keep Symbol" ) );
820
821 wxMessageDialog dlg( this, msg, _( "Warning" ),
822 wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTER );
823 dlg.SetYesNoLabels( yesButtonLabel, noButtonLabel );
824
825 if( dlg.ShowModal() == wxID_NO )
826 continue;
827 }
828
829 if( IsCurrentSymbol( libId ) )
830 emptyScreen();
831
832 m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
833 }
834
836}
837
838
840{
841 std::vector<LIB_ID> symbols;
842
843 if( GetTreeLIBIDs( symbols ) == 0 )
844 return;
845
846 STRING_FORMATTER formatter;
847
848 for( LIB_ID& libId : symbols )
849 {
850 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(),
851 libId.GetLibNickname() );
852
853 if( !symbol )
854 continue;
855
856 std::unique_ptr<LIB_SYMBOL> tmp = symbol->Flatten();
857 SCH_IO_KICAD_SEXPR::FormatLibSymbol( tmp.get(), formatter );
858 }
859
860 wxLogNull doNotLog; // disable logging of failed clipboard actions
861
862 auto clipboard = wxTheClipboard;
863 wxClipboardLocker clipboardLock( clipboard );
864
865 if( !clipboardLock || !clipboard->IsOpened() )
866 return;
867
868 auto data = new wxTextDataObject( wxString( formatter.GetString().c_str(), wxConvUTF8 ) );
869 clipboard->SetData( data );
870
871 clipboard->Flush();
872}
873
874
875void SYMBOL_EDIT_FRAME::DuplicateSymbol( bool aFromClipboard )
876{
877 LIB_ID libId = GetTargetLibId();
878 wxString lib = libId.GetLibNickname();
879
880 if( !m_libMgr->LibraryExists( lib ) )
881 return;
882
883 std::vector<LIB_SYMBOL*> newSymbols;
884
885 if( aFromClipboard )
886 {
887 std::string clipboardData = m_toolManager->GetClipboardUTF8();
888
889 try
890 {
891 newSymbols = SCH_IO_KICAD_SEXPR::ParseLibSymbols( clipboardData, "Clipboard" );
892 }
893 catch( IO_ERROR& e )
894 {
895 wxLogMessage( wxS( "Can not paste: %s" ), e.Problem() );
896 }
897 }
898 else
899 {
900 LIB_SYMBOL* srcSymbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(), lib );
901
902 wxCHECK( srcSymbol, /* void */ );
903
904 newSymbols.emplace_back( new LIB_SYMBOL( *srcSymbol ) );
905
906 // Derive from same parent.
907 if( srcSymbol->IsAlias() )
908 {
909 std::shared_ptr< LIB_SYMBOL > srcParent = srcSymbol->GetParent().lock();
910
911 wxCHECK( srcParent, /* void */ );
912
913 newSymbols.back()->SetParent( srcParent.get() );
914 }
915 }
916
917 if( newSymbols.empty() )
918 return;
919
920 for( LIB_SYMBOL* symbol : newSymbols )
921 {
922 ensureUniqueName( symbol, lib );
923 m_libMgr->UpdateSymbol( symbol, lib );
924
925 LoadOneLibrarySymbolAux( symbol, lib, GetUnit(), GetBodyStyle() );
926 }
927
928 SyncLibraries( false );
929 m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, newSymbols[0]->GetName() ) );
930
931 for( LIB_SYMBOL* symbol : newSymbols )
932 delete symbol;
933}
934
935
936void SYMBOL_EDIT_FRAME::ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
937{
938 wxCHECK( aSymbol, /* void */ );
939
940 int i = 1;
941 wxString newName = aSymbol->GetName();
942
943 // Append a number to the name until the name is unique in the library.
944 while( m_libMgr->SymbolExists( newName, aLibrary ) )
945 newName.Printf( "%s_%d", aSymbol->GetName(), i++ );
946
947 aSymbol->SetName( newName );
948}
949
950
951void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
952{
953 LIB_ID libId = GetTargetLibId();
954 const wxString& libName = libId.GetLibNickname();
955
956 // Empty if this is the library itself that is selected.
957 const wxString& symbolName = libId.GetLibItemName();
958
959 wxString msg = wxString::Format( _( "Revert '%s' to last version saved?" ),
960 symbolName.IsEmpty() ? libName : symbolName );
961
962 if( aConfirm && !ConfirmRevertDialog( this, msg ) )
963 return;
964
965 bool reload_currentSymbol = false;
966 wxString curr_symbolName = symbolName;
967
968 if( GetCurSymbol() )
969 {
970 // the library itself is reverted: the current symbol will be reloaded only if it is
971 // owned by this library
972 if( symbolName.IsEmpty() )
973 {
974 LIB_ID curr_libId = GetCurSymbol()->GetLibId();
975 reload_currentSymbol = libName == curr_libId.GetLibNickname().wx_str();
976
977 if( reload_currentSymbol )
978 curr_symbolName = curr_libId.GetUniStringLibItemName();
979 }
980 else
981 {
982 reload_currentSymbol = IsCurrentSymbol( libId );
983 }
984 }
985
986 int unit = m_unit;
987
988 if( reload_currentSymbol )
989 emptyScreen();
990
991 if( symbolName.IsEmpty() )
992 {
993 m_libMgr->RevertLibrary( libName );
994 }
995 else
996 {
997 libId = m_libMgr->RevertSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
998
999 m_treePane->GetLibTree()->SelectLibId( libId );
1001 }
1002
1003 if( reload_currentSymbol && m_libMgr->SymbolExists( curr_symbolName, libName ) )
1004 LoadSymbol( curr_symbolName, libName, unit );
1005
1006 m_treePane->Refresh();
1007}
1008
1009
1011{
1012 wxCHECK_RET( m_libMgr, "Library manager object not created." );
1013
1014 Revert( false );
1016}
1017
1018
1019void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLibrary, int aUnit )
1020{
1022 {
1023 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
1024 [&]() -> bool
1025 {
1026 return saveCurrentSymbol();
1027 } ) )
1028 {
1029 return;
1030 }
1031 }
1032
1033 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aAlias, aLibrary );
1034
1035 if( !symbol )
1036 {
1037 DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
1038 aAlias,
1039 aLibrary ) );
1041 return;
1042 }
1043
1044 // Optimize default edit options for this symbol
1045 // Usually if units are locked, graphic items are specific to each unit
1046 // and if units are interchangeable, graphic items are common to units
1048 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
1049
1050 LoadOneLibrarySymbolAux( symbol, aLibrary, aUnit, 0 );
1051}
1052
1053
1054bool SYMBOL_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
1055{
1056 wxFileName fn;
1057 wxString msg;
1058 SYMBOL_SAVEAS_TYPE type = SYMBOL_SAVEAS_TYPE::NORMAL_SAVE_AS;
1059 SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
1060 PROJECT& prj = Prj();
1061
1063
1064 if( !aNewFile && ( aLibrary.empty() || !PROJECT_SCH::SchSymbolLibTable( &prj )->HasLibrary( aLibrary ) ) )
1065 {
1066 ShowInfoBarError( _( "No library specified." ) );
1067 return false;
1068 }
1069
1070 if( aNewFile )
1071 {
1072 SEARCH_STACK* search = PROJECT_SCH::SchSearchS( &prj );
1073
1074 // Get a new name for the library
1075 wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
1076
1077 if( !default_path )
1078 default_path = search->LastVisitedPath();
1079
1080 fn.SetName( aLibrary );
1082
1083 wxString wildcards = FILEEXT::KiCadSymbolLibFileWildcard();
1084
1085 wxFileDialog dlg( this, wxString::Format( _( "Save Library '%s' As..." ), aLibrary ),
1086 default_path, fn.GetFullName(), wildcards,
1087 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1088
1089 SYMBOL_FILEDLG_SAVE_AS saveAsHook( type );
1090 dlg.SetCustomizeHook( saveAsHook );
1091
1092 if( dlg.ShowModal() == wxID_CANCEL )
1093 return false;
1094
1095 fn = dlg.GetPath();
1096
1097 prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
1098
1099 if( fn.GetExt().IsEmpty() )
1101
1102 type = saveAsHook.GetOption();
1103 }
1104 else
1105 {
1106 fn = PROJECT_SCH::SchSymbolLibTable( &prj )->GetFullURI( aLibrary );
1108
1109 if( fileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
1110 fileType = SCH_IO_MGR::SCH_KICAD;
1111 }
1112
1113 // Verify the user has write privileges before attempting to save the library file.
1114 if( !aNewFile && m_libMgr->IsLibraryReadOnly( aLibrary ) )
1115 return false;
1116
1117 ClearMsgPanel();
1118
1119 // Copy .kicad_symb file to .bak.
1120 if( !backupFile( fn, "bak" ) )
1121 return false;
1122
1123 if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), fileType ) )
1124 {
1125 msg.Printf( _( "Failed to save changes to symbol library file '%s'." ),
1126 fn.GetFullPath() );
1127 DisplayErrorMessage( this, _( "Error Saving Library" ), msg );
1128 return false;
1129 }
1130
1131 if( !aNewFile )
1132 {
1133 m_libMgr->ClearLibraryModified( aLibrary );
1134
1135 // Update the library modification time so that we don't reload based on the watcher
1136 if( aLibrary == getTargetLib() )
1137 SetSymModificationTime( fn.GetModificationTime() );
1138 }
1139 else
1140 {
1141 bool resyncLibTree = false;
1142 wxString originalLibNickname = getTargetLib();
1143 wxString forceRefresh;
1144
1145 switch( type )
1146 {
1147 case SYMBOL_SAVEAS_TYPE::REPLACE_TABLE_ENTRY:
1148 resyncLibTree = replaceLibTableEntry( originalLibNickname, fn.GetFullPath() );
1149 forceRefresh = originalLibNickname;
1150 break;
1151
1152 case SYMBOL_SAVEAS_TYPE::ADD_GLOBAL_TABLE_ENTRY:
1153 resyncLibTree = addLibTableEntry( fn.GetFullPath() );
1154 break;
1155
1156 case SYMBOL_SAVEAS_TYPE::ADD_PROJECT_TABLE_ENTRY:
1157 resyncLibTree = addLibTableEntry( fn.GetFullPath(), PROJECT_LIB_TABLE );
1158 break;
1159
1160 default:
1161 break;
1162 }
1163
1164 if( resyncLibTree )
1165 {
1167 SyncLibraries( true, false, forceRefresh );
1169 }
1170 }
1171
1172 ClearMsgPanel();
1173 msg.Printf( _( "Symbol library file '%s' saved." ), fn.GetFullPath() );
1175
1176 return true;
1177}
1178
1179
1180bool SYMBOL_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
1181{
1182 wxString msg, msg2;
1183 bool doSave = true;
1184 int dirtyCount = 0;
1185 bool applyToAll = false;
1186 bool retv = true;
1187
1188 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1189 {
1190 if( m_libMgr->IsLibraryModified( libNickname ) )
1191 dirtyCount++;
1192 }
1193
1194 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1195 {
1196 if( m_libMgr->IsLibraryModified( libNickname ) )
1197 {
1198 if( aRequireConfirmation && !applyToAll )
1199 {
1200 msg.Printf( _( "Save changes to '%s' before closing?" ), libNickname );
1201
1202 switch( UnsavedChangesDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
1203 {
1204 case wxID_YES: doSave = true; break;
1205 case wxID_NO: doSave = false; break;
1206 default:
1207 case wxID_CANCEL: return false;
1208 }
1209 }
1210
1211 if( doSave )
1212 {
1213 // If saving under existing name fails then do a Save As..., and if that
1214 // fails then cancel close action.
1215 if( m_libMgr->IsLibraryReadOnly( libNickname ) )
1216 {
1217 msg.Printf( _( "Symbol library '%s' is not writable." ), libNickname );
1218 msg2 = _( "You must save to a different location." );
1219
1220 if( dirtyCount == 1 )
1221 {
1222 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) != wxID_OK )
1223 {
1224 retv = false;
1225 continue;
1226 }
1227 }
1228 else
1229 {
1230 m_infoBar->Dismiss();
1231 m_infoBar->ShowMessageFor( msg + wxS( " " ) + msg2,
1232 2000, wxICON_EXCLAMATION );
1233
1234 while( m_infoBar->IsShownOnScreen() )
1235 wxSafeYield();
1236
1237 retv = false;
1238 continue;
1239 }
1240 }
1241 else if( saveLibrary( libNickname, false ) )
1242 {
1243 continue;
1244 }
1245
1246 if( !saveLibrary( libNickname, true ) )
1247 retv = false;
1248 }
1249 }
1250 }
1251
1252 UpdateTitle();
1253 return retv;
1254}
1255
1256
1258{
1260
1261 if( !m_symbol )
1262 return;
1263
1264 wxString msg = m_symbol->GetName();
1265
1266 AppendMsgPanel( _( "Name" ), UnescapeString( msg ), 8 );
1267
1268 if( m_symbol->IsAlias() )
1269 {
1270 LIB_SYMBOL_SPTR parent = m_symbol->GetParent().lock();
1271
1272 msg = parent ? parent->GetName() : _( "Undefined!" );
1273 AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 );
1274 }
1275
1276 static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
1277 msg = UnitLetter[m_unit];
1278
1279 AppendMsgPanel( _( "Unit" ), msg, 8 );
1280
1281 if( m_bodyStyle == BODY_STYLE::DEMORGAN )
1282 msg = _( "Alternate" );
1283 else if( m_bodyStyle == BODY_STYLE::BASE )
1284 msg = _( "Standard" );
1285 else
1286 msg = wxT( "?" );
1287
1288 AppendMsgPanel( _( "Body" ), msg, 8 );
1289
1290 if( m_symbol->IsPower() )
1291 msg = _( "Power Symbol" );
1292 else
1293 msg = _( "Symbol" );
1294
1295 AppendMsgPanel( _( "Type" ), msg, 8 );
1296 AppendMsgPanel( _( "Description" ), m_symbol->GetDescription(), 8 );
1297 AppendMsgPanel( _( "Keywords" ), m_symbol->GetKeyWords() );
1298 AppendMsgPanel( _( "Datasheet" ), m_symbol->GetDatasheetField().GetText() );
1299}
const char * name
Definition: DXF_plotter.cpp:57
static TOOL_ACTION cancelInteractive
Definition: actions.h:63
static TOOL_ACTION zoomFitScreen
Definition: actions.h:124
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:103
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:98
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:1513
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:77
wxString GetDescription() const override
Definition: lib_symbol.h:157
const LIB_ID & GetLibId() const override
Definition: lib_symbol.h:142
wxString GetKeyWords() const override
Definition: lib_symbol.h:170
bool IsMulti() const override
Definition: lib_symbol.h:541
bool IsPower() const override
Definition: lib_symbol.cpp:663
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:263
SCH_FIELD & GetValueField() const
Return reference to the value field.
LIB_ID GetSourceLibId() const
Definition: lib_symbol.h:145
bool IsAlias() const
Definition: lib_symbol.h:194
void SetPower()
Definition: lib_symbol.cpp:679
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:257
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:570
wxString GetName() const override
Definition: lib_symbol.h:136
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:579
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:105
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:563
void SetNormal()
Definition: lib_symbol.cpp:707
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:438
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:361
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:1138
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.
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.
LIB_ID GetTargetLibId() const
Return either the symbol selected in the symbol tree (if context menu is active) or the symbol on the...
void Save()
Save the selected symbol or library.
void LoadSymbol(const wxString &aLibrary, const wxString &aSymbol, int Unit)
int GetBodyStyle() const
bool IsSymbolTreeShown() 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.
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:187
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:134
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:241
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:161
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:121
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:186
int UnsavedChangesDialog(wxWindow *parent, const wxString &aMessage, bool *aApplyToAll)
A specialized version of HandleUnsavedChanges which handles an apply-to-all checkbox.
Definition: confirm.cpp:58
bool ConfirmRevertDialog(wxWindow *parent, const wxString &aMessage)
Display a confirmation dialog for a revert action.
Definition: confirm.cpp:110
This file is part of the common library.
static bool empty(const wxTextEntryBase *aCtrl)
#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:45
@ 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.