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 <clipboard.h>
28#include <confirm.h>
29#include <kidialog.h>
30#include <kiway.h>
31#include <widgets/wx_infobar.h>
32#include <tools/ee_actions.h>
34#include <symbol_edit_frame.h>
35#include <symbol_library.h>
36#include <template_fieldnames.h>
38#include <symbol_lib_table.h>
40#include <symbol_tree_pane.h>
42#include <widgets/lib_tree.h>
46#include <eda_list_dialog.h>
47#include <wx/clipbrd.h>
48#include <wx/filedlg.h>
49#include <wx/log.h>
50#include <project_sch.h>
51#include <string_utils.h>
52#include "symbol_saveas_type.h"
53
56
57
59{
60 wxString title;
61
63 {
65 title = wxT( "*" );
66
67 title += m_reference;
68 title += wxS( " " ) + _( "[from schematic]" );
69 }
70 else if( GetCurSymbol() )
71 {
73 title = wxT( "*" );
74
75 title += UnescapeString( GetCurSymbol()->GetLibId().Format() );
76
78 title += wxS( " " ) + _( "[Read Only Library]" );
79 }
80 else
81 {
82 title = _( "[no symbol loaded]" );
83 }
84
85 title += wxT( " \u2014 " ) + _( "Symbol Editor" );
86 SetTitle( title );
87}
88
89
90void SYMBOL_EDIT_FRAME::SelectActiveLibrary( const wxString& aLibrary )
91{
92 wxString selectedLib = aLibrary;
93
94 if( selectedLib.empty() )
95 selectedLib = SelectLibraryFromList();
96
97 if( !selectedLib.empty() )
98 SetCurLib( selectedLib );
99
100 UpdateTitle();
101}
102
103
105{
106 if( GetCurSymbol() )
107 {
109 {
110 SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
111
112 if( !schframe ) // happens when the schematic editor has been closed
113 {
114 DisplayErrorMessage( this, _( "No schematic currently open." ) );
115 return false;
116 }
117 else
118 {
120 GetScreen()->SetContentModified( false );
121 return true;
122 }
123 }
124 else
125 {
126 const wxString& libName = GetCurSymbol()->GetLibId().GetLibNickname();
127
128 if( m_libMgr->IsLibraryReadOnly( libName ) )
129 {
130 wxString msg = wxString::Format( _( "Symbol library '%s' is not writable." ),
131 libName );
132 wxString msg2 = _( "You must save to a different location." );
133
134 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
135 return saveLibrary( libName, true );
136 }
137 else
138 {
139 return saveLibrary( libName, false );
140 }
141 }
142 }
143
144 return false;
145}
146
147
148bool SYMBOL_EDIT_FRAME::LoadSymbol( const LIB_ID& aLibId, int aUnit, int aBodyStyle )
149{
150 LIB_ID libId = aLibId;
151
152 // Some libraries can't be edited, so load the underlying chosen symbol
154 {
155 if( lib->SchLibType() == SCH_IO_MGR::SCH_DATABASE
156 || lib->SchLibType() == SCH_IO_MGR::SCH_CADSTAR_ARCHIVE
157 || lib->SchLibType() == SCH_IO_MGR::SCH_HTTP )
158
159 {
160 try
161 {
162 LIB_SYMBOL* readOnlySym = PROJECT_SCH::SchSymbolLibTable( &Prj() )->LoadSymbol( aLibId );
163
164 if( readOnlySym && readOnlySym->GetSourceLibId().IsValid() )
165 libId = readOnlySym->GetSourceLibId();
166 }
167 catch( const IO_ERROR& ioe )
168 {
169 wxString msg;
170
171 msg.Printf( _( "Error loading symbol %s from library '%s'." ),
172 aLibId.GetUniStringLibId(), aLibId.GetUniStringLibItemName() );
173 DisplayErrorMessage( this, msg, ioe.What() );
174 return false;
175 }
176 }
177 }
178
180 && GetCurSymbol()->GetLibId() == libId
181 && GetUnit() == aUnit
182 && GetBodyStyle() == aBodyStyle )
183 {
184 return true;
185 }
186
188 {
189 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
190 [&]() -> bool
191 {
192 return saveCurrentSymbol();
193 } ) )
194 {
195 return false;
196 }
197 }
198
200
201 if( LoadSymbolFromCurrentLib( libId.GetLibItemName(), aUnit, aBodyStyle ) )
202 {
203 m_treePane->GetLibTree()->SelectLibId( libId );
204 m_treePane->GetLibTree()->ExpandLibId( libId );
205
206 m_centerItemOnIdle = libId;
207 Bind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
208 setSymWatcher( &libId );
209
210 return true;
211 }
212
213 return false;
214}
215
216
218{
220 Unbind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
221}
222
223
224bool SYMBOL_EDIT_FRAME::LoadSymbolFromCurrentLib( const wxString& aAliasName, int aUnit,
225 int aBodyStyle )
226{
227 LIB_SYMBOL* alias = nullptr;
228
229 try
230 {
231 alias = PROJECT_SCH::SchSymbolLibTable( &Prj() )->LoadSymbol( GetCurLib(), aAliasName );
232 }
233 catch( const IO_ERROR& ioe )
234 {
235 wxString msg;
236
237 msg.Printf( _( "Error loading symbol %s from library '%s'." ),
238 aAliasName,
239 GetCurLib() );
240 DisplayErrorMessage( this, msg, ioe.What() );
241 return false;
242 }
243
244 if( !alias || !LoadOneLibrarySymbolAux( alias, GetCurLib(), aUnit, aBodyStyle ) )
245 return false;
246
247 // Enable synchronized pin edit mode for symbols with interchangeable units
249
252 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasAlternateBodyStyle() );
253
254 if( aUnit > 0 )
256
257 return true;
258}
259
260
261bool SYMBOL_EDIT_FRAME::LoadOneLibrarySymbolAux( LIB_SYMBOL* aEntry, const wxString& aLibrary,
262 int aUnit, int aBodyStyle )
263{
264 bool rebuildMenuAndToolbar = false;
265
266 if( !aEntry || aLibrary.empty() )
267 return false;
268
269 if( aEntry->GetName().IsEmpty() )
270 {
271 wxLogWarning( "Symbol in library '%s' has empty name field.", aLibrary );
272 return false;
273 }
274
276
277 // Symbols from the schematic are edited in place and not managed by the library manager.
279 {
280 delete m_symbol;
281 m_symbol = nullptr;
282
283 SCH_SCREEN* screen = GetScreen();
284 delete screen;
287 rebuildMenuAndToolbar = true;
288 }
289
290 LIB_SYMBOL* lib_symbol = m_libMgr->GetBufferedSymbol( aEntry->GetName(), aLibrary );
291 wxCHECK( lib_symbol, false );
292
293 m_unit = aUnit > 0 ? aUnit : 1;
294 m_bodyStyle = aBodyStyle > 0 ? aBodyStyle : 1;
295
296 // The buffered screen for the symbol
297 SCH_SCREEN* symbol_screen = m_libMgr->GetScreen( lib_symbol->GetName(), aLibrary );
298
299 SetScreen( symbol_screen );
300 SetCurSymbol( new LIB_SYMBOL( *lib_symbol ), true );
301 SetCurLib( aLibrary );
302
303 if( rebuildMenuAndToolbar )
304 {
307 GetInfoBar()->Dismiss();
308 }
309
310 UpdateTitle();
312 SetShowDeMorgan( GetCurSymbol()->HasAlternateBodyStyle() );
313
315
316 if( !IsSymbolFromSchematic() )
317 {
318 LIB_ID libId = GetCurSymbol()->GetLibId();
319 setSymWatcher( &libId );
320 }
321
322 // Let tools add things to the view if necessary
323 if( m_toolManager )
325
327
328 // Display the document information based on the entry selected just in
329 // case the entry is an alias.
331 Refresh();
332
333 return true;
334}
335
336
338{
339 saveAllLibraries( false );
341}
342
343
344void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& aInheritFrom )
345{
347
348 wxArrayString symbolNames;
349 wxString lib = getTargetLib();
350
351 if( !m_libMgr->LibraryExists( lib ) )
352 {
353 lib = SelectLibraryFromList();
354
355 if( !m_libMgr->LibraryExists( lib ) )
356 return;
357 }
358
359 m_libMgr->GetSymbolNames( lib, symbolNames );
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{
555 saveSymbolCopyAs( aOpenCopy );
556
558}
559
560
567static std::vector<LIB_SYMBOL_SPTR> GetParentChain( const LIB_SYMBOL& aSymbol )
568{
569 std::vector<LIB_SYMBOL_SPTR> chain( { aSymbol.SharedPtr() } );
570
571 while( chain.back()->IsAlias() )
572 {
573 LIB_SYMBOL_SPTR parent = chain.back()->GetParent().lock();
574 chain.push_back( parent );
575 }
576
577 return chain;
578}
579
580
590static std::pair<bool, bool> CheckSavingIntoOwnInheritance( LIB_SYMBOL_LIBRARY_MANAGER& aLibMgr,
591 LIB_SYMBOL& aSymbol,
592 const wxString& aNewSymbolName,
593 const wxString& aNewLibraryName )
594{
595 const wxString& oldLibraryName = aSymbol.GetLibId().GetLibNickname();
596
597 // Cannot be intersecting if in different libs
598 if( aNewLibraryName != oldLibraryName )
599 return { false, false };
600
601 // Or if the target symbol doesn't exist
602 if( !aLibMgr.SymbolExists( aNewSymbolName, aNewLibraryName ) )
603 return { false, false };
604
605 bool inAncestry = false;
606 bool inDescendents = false;
607
608 {
609 const std::vector<LIB_SYMBOL_SPTR> parentChainFromUs = GetParentChain( aSymbol );
610
611 // Ignore the leaf symbol (0) - that must match
612 for( size_t i = 1; i < parentChainFromUs.size(); ++i )
613 {
614 // Attempting to overwrite a symbol in the parental chain
615 if( parentChainFromUs[i]->GetName() == aNewSymbolName )
616 {
617 inAncestry = true;
618 break;
619 }
620 }
621 }
622
623 {
624 LIB_SYMBOL* targetSymbol = aLibMgr.GetAlias( aNewSymbolName, aNewLibraryName );
625 const std::vector<LIB_SYMBOL_SPTR> parentChainFromTarget = GetParentChain( *targetSymbol );
626 const wxString oldSymbolName = aSymbol.GetName();
627
628 // Ignore the leaf symbol - it'll match if we're saving the symbol
629 // to the same name, and that would be OK
630 for( size_t i = 1; i < parentChainFromTarget.size(); ++i )
631 {
632 if( parentChainFromTarget[i]->GetName() == oldSymbolName )
633 {
634 inDescendents = true;
635 break;
636 }
637 }
638 }
639
640 return { inAncestry, inDescendents };
641}
642
643
651static std::vector<wxString> CheckForParentalChainConflicts( LIB_SYMBOL_LIBRARY_MANAGER& aLibMgr,
652 LIB_SYMBOL& aSymbol,
653 const wxString& newSymbolName,
654 const wxString& newLibraryName )
655{
656 std::vector<wxString> conflicts;
657 const wxString& oldLibraryName = aSymbol.GetLibId().GetLibNickname();
658
659 if( newLibraryName == oldLibraryName )
660 {
661 // Saving into the same library - the only conflict could be the symbol itself
662 if( aLibMgr.SymbolExists( newSymbolName, newLibraryName ) )
663 {
664 conflicts.push_back( newSymbolName );
665 }
666 }
667 else
668 {
669 // In a different library, check the whole chain
670 const std::vector<LIB_SYMBOL_SPTR> parentChain = GetParentChain( aSymbol );
671
672 for( size_t i = 0; i < parentChain.size(); ++i )
673 {
674 if( i == 0 )
675 {
676 // This is the leaf symbol which the user actually named
677 if( aLibMgr.SymbolExists( newSymbolName, newLibraryName ) )
678 {
679 conflicts.push_back( newSymbolName );
680 }
681 }
682 else
683 {
684 LIB_SYMBOL_SPTR chainSymbol = parentChain[i];
685 if( aLibMgr.SymbolExists( chainSymbol->GetName(), newLibraryName ) )
686 {
687 conflicts.push_back( chainSymbol->GetName() );
688 }
689 }
690 }
691 }
692
693 return conflicts;
694}
695
696
704{
705public:
707 {
708 // Just overwrite any existing symbols in the target library
709 OVERWRITE,
710 // Add a suffix until we find a name that doesn't conflict
711 RENAME,
712 // Could have a mode that asks for every one, be then we'll need a fancier
713 // SAVE_AS_DIALOG subdialog with Overwrite/Rename/Prompt/Cancel
714 // PROMPT
715 };
716
718 bool aValueFollowsName ) :
719 m_libMgr( aLibMgr ), m_strategy( aStrategy ), m_valueFollowsName( aValueFollowsName )
720 {
721 }
722
723 bool DoSave( LIB_SYMBOL& symbol, const wxString& aNewSymName, const wxString& aNewLibName )
724 {
725 std::vector<LIB_SYMBOL_SPTR> parentChain;
726 // If we're saving into the same library, we don't need to check the parental chain
727 // because we can just keep the same parent symbol
728 if( aNewLibName == symbol.GetLibId().GetLibNickname().wx_str() )
729 parentChain.push_back( symbol.SharedPtr() );
730 else
731 parentChain = GetParentChain( symbol );
732
733 std::vector<wxString> newNames;
734
735 // Iterate backwards (i.e. from the root down)
736 for( int i = (int) parentChain.size() - 1; i >= 0; --i )
737 {
738 LIB_SYMBOL_SPTR& oldSymbol = parentChain[i];
739
740 LIB_SYMBOL new_symbol( *oldSymbol );
741
742 wxString newName;
743 if( i == 0 )
744 {
745 // This is the leaf symbol which the user actually named
746 newName = aNewSymName;
747 }
748 else
749 {
750 // Somewhere in the inheritance chain, use the conflict resolution strategy
751 newName = oldSymbol->GetName();
752 }
753
754 newName = resolveConflict( newName, aNewLibName );
755 new_symbol.SetName( newName );
756
758 new_symbol.GetValueField().SetText( newName );
759
760 if( i == (int) parentChain.size() - 1 )
761 {
762 // This is the root symbol
763 // Nothing extra to do, it's just a simple symbol with no parents
764 }
765 else
766 {
767 // Get the buffered new copy in the new library (with the name we gave it)
768 LIB_SYMBOL* newParent = m_libMgr.GetAlias( newNames.back(), aNewLibName );
769
770 // We should have stored this already, why didn't we get it back?
771 wxASSERT( newParent );
772 new_symbol.SetParent( newParent );
773 }
774
775 newNames.push_back( newName );
776 m_libMgr.UpdateSymbol( &new_symbol, aNewLibName );
777 }
778
779 return true;
780 }
781
782private:
783 wxString resolveConflict( const wxString& proposed, const wxString& aNewLibName ) const
784 {
785 switch( m_strategy )
786 {
788 {
789 // In an overwrite strategy, we don't care about conflicts
790 return proposed;
791 }
793 {
794 // In a rename strategy, we need to find a name that doesn't conflict
795 int suffix = 1;
796
797 while( true )
798 {
799 wxString newName = wxString::Format( "%s_%d", proposed, suffix );
800
801 if( !m_libMgr.SymbolExists( newName, aNewLibName ) )
802 return newName;
803
804 ++suffix;
805 }
806 break;
807 }
808 // No default
809 }
810
811 wxFAIL_MSG( "Invalid conflict strategy" );
812 return "";
813 }
814
818};
819
820
822{
823 ID_MAKE_NEW_LIBRARY = wxID_HIGHEST + 1,
826};
827
828
830{
831public:
833 std::function<int( const wxString& libName, const wxString& symbolName )>;
834
835 SAVE_AS_DIALOG( SYMBOL_EDIT_FRAME* aParent, const wxString& aSymbolName,
836 const wxString& aLibraryPreselect, SymLibNameValidator aValidator,
837 SYMBOL_SAVE_AS_HANDLER::CONFLICT_STRATEGY& aConflictStrategy ) :
838 EDA_LIST_DIALOG( aParent, _( "Save Symbol As" ), false ),
839 m_validator( std::move( aValidator ) ), m_conflictStrategy( aConflictStrategy )
840 {
842 PROJECT_FILE& project = aParent->Prj().GetProjectFile();
844 std::vector<wxString> libNicknames = tbl->GetLogicalLibs();
845 wxArrayString headers;
846 std::vector<wxArrayString> itemsToDisplay;
847
848 headers.Add( _( "Nickname" ) );
849 headers.Add( _( "Description" ) );
850
851 for( const wxString& nickname : libNicknames )
852 {
853 if( alg::contains( project.m_PinnedSymbolLibs, nickname )
854 || alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
855 {
856 wxArrayString item;
857 item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
858 item.Add( tbl->GetDescription( nickname ) );
859 itemsToDisplay.push_back( item );
860 }
861 }
862
863 for( const wxString& nickname : libNicknames )
864 {
865 if( !alg::contains( project.m_PinnedSymbolLibs, nickname )
866 && !alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
867 {
868 wxArrayString item;
869 item.Add( nickname );
870 item.Add( tbl->GetDescription( nickname ) );
871 itemsToDisplay.push_back( item );
872 }
873 }
874
875 initDialog( headers, itemsToDisplay, aLibraryPreselect );
876
877 SetListLabel( _( "Save in library:" ) );
878 SetOKLabel( _( "Save" ) );
879
880 wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
881
882 wxStaticText* label = new wxStaticText( this, wxID_ANY, _( "Name:" ) );
883 bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
884
885 m_symbolNameCtrl = new wxTextCtrl( this, wxID_ANY, aSymbolName );
886 bNameSizer->Add( m_symbolNameCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
887
888 wxButton* newLibraryButton = new wxButton( this, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
889 m_ButtonsSizer->Prepend( 80, 20 );
890 m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
891
892 GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
893
894 Bind( wxEVT_BUTTON,
895 [this]( wxCommandEvent& )
896 {
897 EndModal( ID_MAKE_NEW_LIBRARY );
899
900 // Move nameTextCtrl to the head of the tab-order
901 if( GetChildren().DeleteObject( m_symbolNameCtrl ) )
902 GetChildren().Insert( m_symbolNameCtrl );
903
905
907
908 Layout();
909 GetSizer()->Fit( this );
910
911 Centre();
912 }
913
914 wxString GetSymbolName()
915 {
916 wxString symbolName = m_symbolNameCtrl->GetValue();
917 symbolName.Trim( true );
918 symbolName.Trim( false );
919 symbolName.Replace( " ", "_" );
920 return symbolName;
921 }
922
923protected:
925 {
927
928 if( ret == wxID_CANCEL )
929 return false;
930
931 if( ret == ID_OVERWRITE_CONFLICTS )
933 else if( ret == ID_RENAME_CONFLICTS )
935
936 return true;
937 }
938
939private:
940 wxTextCtrl* m_symbolNameCtrl;
943};
944
945
947{
948 LIB_SYMBOL* symbol = getTargetSymbol();
949
950 if( !symbol )
951 return;
952
953 LIB_ID old_lib_id = symbol->GetLibId();
954 wxString symbolName = old_lib_id.GetLibItemName();
955 wxString libraryName = old_lib_id.GetLibNickname();
956 bool valueFollowsName = symbol->GetValueField().GetText() == symbolName;
957 wxString msg;
958 bool done = false;
959
960 // This is the function that will be called when the user clicks OK in the dialog
961 // and checks if the proposed name has problems, and asks for clarification.
962 const auto dialogValidatorFunc = [&]( const wxString& newLib, const wxString& newName ) -> int
963 {
964 if( newLib.IsEmpty() )
965 {
966 wxMessageBox( _( "A library must be specified." ) );
967 return wxID_CANCEL;
968 }
969
970 if( newName.IsEmpty() )
971 {
972 wxMessageBox( _( "Symbol must have a name." ) );
973 return wxID_CANCEL;
974 }
975
976 if( m_libMgr->IsLibraryReadOnly( newLib ) )
977 {
978 msg = wxString::Format( _( "Library '%s' is read-only. Choose a "
979 "different library to save the symbol '%s' to." ),
980 newLib, newName );
981 wxMessageBox( msg );
982 return wxID_CANCEL;
983 }
984
989 const auto& [inAncestry, inDescendents] =
990 CheckSavingIntoOwnInheritance( *m_libMgr, *symbol, newName, newLib );
991
992 if( inAncestry )
993 {
994 msg = wxString::Format( _( "Symbol '%s' cannot replace another symbol '%s' that it "
995 "descends from" ),
996 symbolName, newName );
997 wxMessageBox( msg );
998 return wxID_CANCEL;
999 }
1000
1001 if( inDescendents )
1002 {
1003 msg = wxString::Format( _( "Symbol '%s' cannot replace another symbol '%s' that is "
1004 "a descendent of it." ),
1005 symbolName, newName );
1006 wxMessageBox( msg );
1007 return wxID_CANCEL;
1008 }
1009
1010 const std::vector<wxString> conflicts =
1011 CheckForParentalChainConflicts( *m_libMgr, *symbol, newName, newLib );
1012
1013 if( conflicts.size() == 1 && conflicts.front() == newName )
1014 {
1015 // The simplest case is when the symbol itself has a conflict
1016 msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'."
1017 "Do you want to overwrite it?" ),
1018 newName, newLib );
1019
1020 KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
1021 errorDlg.SetOKLabel( _( "Overwrite" ) );
1022
1023 return errorDlg.ShowModal() == wxID_OK ? ID_OVERWRITE_CONFLICTS : (int) wxID_CANCEL;
1024 }
1025 else if( !conflicts.empty() )
1026 {
1027 // If there are conflicts in the parental chain, we need to ask the user
1028 // if they want to overwrite all of them.
1029 // A more complex UI might allow the user to re-parent the symbol to an existing
1030 // symbol in the target lib, or rename all the parents somehow.
1031 msg = wxString::Format( _( "The following symbols in the inheritance chain of '%s' "
1032 "already exist in library '%s':\n" ),
1033 symbolName, newLib );
1034
1035 for( const wxString& conflict : conflicts )
1036 msg += wxString::Format( " %s\n", conflict );
1037
1038 msg += _( "\nDo you want to overwrite all of them, or rename the new symbols?" );
1039
1040 KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
1041 wxYES_NO | wxCANCEL | wxICON_WARNING );
1042 errorDlg.SetYesNoCancelLabels( _( "Overwrite All" ), _( "Rename All" ), _( "Cancel" ) );
1043
1044 switch( errorDlg.ShowModal() )
1045 {
1046 case wxID_YES: return ID_OVERWRITE_CONFLICTS;
1047 case wxID_NO: return ID_RENAME_CONFLICTS;
1048 default: break;
1049 }
1050 return wxID_CANCEL;
1051 }
1052
1053 return wxID_OK;
1054 };
1055
1057
1058 // Keep asking the user for a new name until they give a valid one or cancel the operation
1059 while( !done )
1060 {
1061 SAVE_AS_DIALOG dlg( this, symbolName, libraryName, dialogValidatorFunc, strategy );
1062
1063 int ret = dlg.ShowModal();
1064
1065 switch( ret )
1066 {
1067 case wxID_CANCEL:
1068 {
1069 return;
1070 }
1071
1072 case wxID_OK: // No conflicts
1075 {
1076 symbolName = dlg.GetSymbolName();
1077 libraryName = dlg.GetTextSelection();
1078
1079 if( ret == ID_RENAME_CONFLICTS )
1081
1082 done = true;
1083 break;
1084 }
1085
1087 {
1088 wxFileName newLibrary( AddLibraryFile( true ) );
1089 libraryName = newLibrary.GetName();
1090 break;
1091 }
1092
1093 default:
1094 break;
1095 }
1096 }
1097
1098 SYMBOL_SAVE_AS_HANDLER saver( *m_libMgr, strategy, valueFollowsName );
1099
1100 saver.DoSave( *symbol, symbolName, libraryName );
1101
1102 SyncLibraries( false );
1103
1104 if( aOpenCopy )
1105 LoadSymbol( symbolName, libraryName, 1 );
1106}
1107
1108
1110{
1111 wxCHECK( m_symbol, /* void */ );
1112
1113 wxString lib = GetCurLib();
1114
1115 if( !lib.IsEmpty() && aOldName && *aOldName != m_symbol->GetName() )
1116 {
1117 // Test the current library for name conflicts
1118 if( m_libMgr->SymbolExists( m_symbol->GetName(), lib ) )
1119 {
1120 wxString msg = wxString::Format( _( "Symbol name '%s' already in use." ),
1122
1123 DisplayErrorMessage( this, msg );
1124 m_symbol->SetName( *aOldName );
1125 }
1126 else
1127 {
1128 m_libMgr->UpdateSymbolAfterRename( m_symbol, *aOldName, lib );
1129 }
1130
1131 // Reselect the renamed symbol
1133 }
1134
1136 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasAlternateBodyStyle() );
1137 UpdateTitle();
1138
1139 // N.B. The view needs to be rebuilt first as the Symbol Properties change may invalidate
1140 // the view pointers by rebuilting the field table
1141 RebuildView();
1143
1144 OnModify();
1145}
1146
1147
1149{
1150 std::vector<LIB_ID> toDelete = GetSelectedLibIds();
1151
1152 if( toDelete.empty() )
1153 toDelete.emplace_back( GetTargetLibId() );
1154
1155 for( LIB_ID& libId : toDelete )
1156 {
1157 if( m_libMgr->IsSymbolModified( libId.GetLibItemName(), libId.GetLibNickname() )
1158 && !IsOK( this, wxString::Format( _( "The symbol '%s' has been modified.\n"
1159 "Do you want to remove it from the library?" ),
1160 libId.GetUniStringLibItemName() ) ) )
1161 {
1162 continue;
1163 }
1164
1165 if( m_libMgr->HasDerivedSymbols( libId.GetLibItemName(), libId.GetLibNickname() ) )
1166 {
1167 wxString msg;
1168
1169 msg.Printf(
1170 _( "The symbol %s is used to derive other symbols.\n"
1171 "Deleting this symbol will delete all of the symbols derived from it.\n\n"
1172 "Do you wish to delete this symbol and all of its derivatives?" ),
1173 libId.GetLibItemName().wx_str() );
1174
1175 wxMessageDialog::ButtonLabel yesButtonLabel( _( "Delete Symbol" ) );
1176 wxMessageDialog::ButtonLabel noButtonLabel( _( "Keep Symbol" ) );
1177
1178 wxMessageDialog dlg( this, msg, _( "Warning" ),
1179 wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTER );
1180 dlg.SetYesNoLabels( yesButtonLabel, noButtonLabel );
1181
1182 if( dlg.ShowModal() == wxID_NO )
1183 continue;
1184 }
1185
1186 if( IsCurrentSymbol( libId ) )
1187 emptyScreen();
1188
1189 m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
1190 }
1191
1193}
1194
1195
1197{
1198 std::vector<LIB_ID> symbols;
1199
1200 if( GetTreeLIBIDs( symbols ) == 0 )
1201 return;
1202
1203 STRING_FORMATTER formatter;
1204
1205 for( LIB_ID& libId : symbols )
1206 {
1207 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(),
1208 libId.GetLibNickname() );
1209
1210 if( !symbol )
1211 continue;
1212
1213 std::unique_ptr<LIB_SYMBOL> tmp = symbol->Flatten();
1214 SCH_IO_KICAD_SEXPR::FormatLibSymbol( tmp.get(), formatter );
1215 }
1216
1217 std::string prettyData = formatter.GetString();
1218 KICAD_FORMAT::Prettify( prettyData, true );
1219
1220 wxLogNull doNotLog; // disable logging of failed clipboard actions
1221
1222 auto clipboard = wxTheClipboard;
1223 wxClipboardLocker clipboardLock( clipboard );
1224
1225 if( !clipboardLock || !clipboard->IsOpened() )
1226 return;
1227
1228 auto data = new wxTextDataObject( wxString( prettyData.c_str(), wxConvUTF8 ) );
1229 clipboard->SetData( data );
1230
1231 clipboard->Flush();
1232}
1233
1234
1235void SYMBOL_EDIT_FRAME::DuplicateSymbol( bool aFromClipboard )
1236{
1237 LIB_ID libId = GetTargetLibId();
1238 wxString lib = libId.GetLibNickname();
1239
1240 if( !m_libMgr->LibraryExists( lib ) )
1241 return;
1242
1243 std::vector<LIB_SYMBOL*> newSymbols;
1244
1245 if( aFromClipboard )
1246 {
1247 std::string clipboardData = GetClipboardUTF8();
1248
1249 try
1250 {
1251 newSymbols = SCH_IO_KICAD_SEXPR::ParseLibSymbols( clipboardData, "Clipboard" );
1252 }
1253 catch( IO_ERROR& e )
1254 {
1255 wxLogMessage( wxS( "Can not paste: %s" ), e.Problem() );
1256 }
1257 }
1258 else if( LIB_SYMBOL* srcSymbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(), lib ) )
1259 {
1260 newSymbols.emplace_back( new LIB_SYMBOL( *srcSymbol ) );
1261
1262 // Derive from same parent.
1263 if( srcSymbol->IsAlias() )
1264 {
1265 if( std::shared_ptr<LIB_SYMBOL> srcParent = srcSymbol->GetParent().lock() )
1266 newSymbols.back()->SetParent( srcParent.get() );
1267 }
1268 }
1269
1270 if( newSymbols.empty() )
1271 return;
1272
1273 for( LIB_SYMBOL* symbol : newSymbols )
1274 {
1275 ensureUniqueName( symbol, lib );
1276 m_libMgr->UpdateSymbol( symbol, lib );
1277
1278 LoadOneLibrarySymbolAux( symbol, lib, GetUnit(), GetBodyStyle() );
1279 }
1280
1281 SyncLibraries( false );
1282 m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, newSymbols[0]->GetName() ) );
1283
1284 for( LIB_SYMBOL* symbol : newSymbols )
1285 delete symbol;
1286}
1287
1288
1289void SYMBOL_EDIT_FRAME::ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
1290{
1291 if( aSymbol )
1292 {
1293 int i = 1;
1294 wxString newName = aSymbol->GetName();
1295
1296 // Append a number to the name until the name is unique in the library.
1297 while( m_libMgr->SymbolExists( newName, aLibrary ) )
1298 newName.Printf( "%s_%d", aSymbol->GetName(), i++ );
1299
1300 aSymbol->SetName( newName );
1301 }
1302}
1303
1304
1305void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
1306{
1307 LIB_ID libId = GetTargetLibId();
1308 const wxString& libName = libId.GetLibNickname();
1309
1310 // Empty if this is the library itself that is selected.
1311 const wxString& symbolName = libId.GetLibItemName();
1312
1313 wxString msg = wxString::Format( _( "Revert '%s' to last version saved?" ),
1314 symbolName.IsEmpty() ? libName : symbolName );
1315
1316 if( aConfirm && !ConfirmRevertDialog( this, msg ) )
1317 return;
1318
1319 bool reload_currentSymbol = false;
1320 wxString curr_symbolName = symbolName;
1321
1322 if( GetCurSymbol() )
1323 {
1324 // the library itself is reverted: the current symbol will be reloaded only if it is
1325 // owned by this library
1326 if( symbolName.IsEmpty() )
1327 {
1328 LIB_ID curr_libId = GetCurSymbol()->GetLibId();
1329 reload_currentSymbol = libName == curr_libId.GetLibNickname().wx_str();
1330
1331 if( reload_currentSymbol )
1332 curr_symbolName = curr_libId.GetUniStringLibItemName();
1333 }
1334 else
1335 {
1336 reload_currentSymbol = IsCurrentSymbol( libId );
1337 }
1338 }
1339
1340 int unit = m_unit;
1341
1342 if( reload_currentSymbol )
1343 emptyScreen();
1344
1345 if( symbolName.IsEmpty() )
1346 {
1347 m_libMgr->RevertLibrary( libName );
1348 }
1349 else
1350 {
1351 libId = m_libMgr->RevertSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
1352
1353 m_treePane->GetLibTree()->SelectLibId( libId );
1355 }
1356
1357 if( reload_currentSymbol && m_libMgr->SymbolExists( curr_symbolName, libName ) )
1358 LoadSymbol( curr_symbolName, libName, unit );
1359
1360 m_treePane->Refresh();
1361}
1362
1363
1365{
1366 wxCHECK_RET( m_libMgr, "Library manager object not created." );
1367
1368 Revert( false );
1370}
1371
1372
1373void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLibrary, int aUnit )
1374{
1376 {
1377 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
1378 [&]() -> bool
1379 {
1380 return saveCurrentSymbol();
1381 } ) )
1382 {
1383 return;
1384 }
1385 }
1386
1387 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aAlias, aLibrary );
1388
1389 if( !symbol )
1390 {
1391 DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
1392 aAlias,
1393 aLibrary ) );
1395 return;
1396 }
1397
1398 // Optimize default edit options for this symbol
1399 // Usually if units are locked, graphic items are specific to each unit
1400 // and if units are interchangeable, graphic items are common to units
1402 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
1403
1404 LoadOneLibrarySymbolAux( symbol, aLibrary, aUnit, 0 );
1405}
1406
1407
1408bool SYMBOL_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
1409{
1410 wxFileName fn;
1411 wxString msg;
1412 SYMBOL_SAVEAS_TYPE type = SYMBOL_SAVEAS_TYPE::NORMAL_SAVE_AS;
1413 SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
1414 PROJECT& prj = Prj();
1415
1417
1418 if( !aNewFile && ( aLibrary.empty() || !PROJECT_SCH::SchSymbolLibTable( &prj )->HasLibrary( aLibrary ) ) )
1419 {
1420 ShowInfoBarError( _( "No library specified." ) );
1421 return false;
1422 }
1423
1424 if( aNewFile )
1425 {
1426 SEARCH_STACK* search = PROJECT_SCH::SchSearchS( &prj );
1427
1428 // Get a new name for the library
1429 wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
1430
1431 if( !default_path )
1432 default_path = search->LastVisitedPath();
1433
1434 fn.SetName( aLibrary );
1436
1437 wxString wildcards = FILEEXT::KiCadSymbolLibFileWildcard();
1438
1439 wxFileDialog dlg( this, wxString::Format( _( "Save Library '%s' As..." ), aLibrary ),
1440 default_path, fn.GetFullName(), wildcards,
1441 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1442
1443 SYMBOL_FILEDLG_SAVE_AS saveAsHook( type );
1444 dlg.SetCustomizeHook( saveAsHook );
1445
1446 if( dlg.ShowModal() == wxID_CANCEL )
1447 return false;
1448
1449 fn = dlg.GetPath();
1450
1451 prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
1452
1453 if( fn.GetExt().IsEmpty() )
1455
1456 type = saveAsHook.GetOption();
1457 }
1458 else
1459 {
1460 fn = PROJECT_SCH::SchSymbolLibTable( &prj )->GetFullURI( aLibrary );
1462
1463 if( fileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
1464 fileType = SCH_IO_MGR::SCH_KICAD;
1465 }
1466
1467 // Verify the user has write privileges before attempting to save the library file.
1468 if( !aNewFile && m_libMgr->IsLibraryReadOnly( aLibrary ) )
1469 return false;
1470
1471 ClearMsgPanel();
1472
1473 // Copy .kicad_symb file to .bak.
1474 if( !backupFile( fn, "bak" ) )
1475 return false;
1476
1477 if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), fileType ) )
1478 {
1479 msg.Printf( _( "Failed to save changes to symbol library file '%s'." ),
1480 fn.GetFullPath() );
1481 DisplayErrorMessage( this, _( "Error Saving Library" ), msg );
1482 return false;
1483 }
1484
1485 if( !aNewFile )
1486 {
1487 m_libMgr->ClearLibraryModified( aLibrary );
1488
1489 // Update the library modification time so that we don't reload based on the watcher
1490 if( aLibrary == getTargetLib() )
1491 SetSymModificationTime( fn.GetModificationTime() );
1492 }
1493 else
1494 {
1495 bool resyncLibTree = false;
1496 wxString originalLibNickname = getTargetLib();
1497 wxString forceRefresh;
1498
1499 switch( type )
1500 {
1501 case SYMBOL_SAVEAS_TYPE::REPLACE_TABLE_ENTRY:
1502 resyncLibTree = replaceLibTableEntry( originalLibNickname, fn.GetFullPath() );
1503 forceRefresh = originalLibNickname;
1504 break;
1505
1506 case SYMBOL_SAVEAS_TYPE::ADD_GLOBAL_TABLE_ENTRY:
1507 resyncLibTree = addLibTableEntry( fn.GetFullPath() );
1508 break;
1509
1510 case SYMBOL_SAVEAS_TYPE::ADD_PROJECT_TABLE_ENTRY:
1511 resyncLibTree = addLibTableEntry( fn.GetFullPath(), PROJECT_LIB_TABLE );
1512 break;
1513
1514 default:
1515 break;
1516 }
1517
1518 if( resyncLibTree )
1519 {
1521 SyncLibraries( true, false, forceRefresh );
1523 }
1524 }
1525
1526 ClearMsgPanel();
1527 msg.Printf( _( "Symbol library file '%s' saved." ), fn.GetFullPath() );
1529
1530 return true;
1531}
1532
1533
1534bool SYMBOL_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
1535{
1536 wxString msg, msg2;
1537 bool doSave = true;
1538 int dirtyCount = 0;
1539 bool applyToAll = false;
1540 bool retv = true;
1541
1542 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1543 {
1544 if( m_libMgr->IsLibraryModified( libNickname ) )
1545 dirtyCount++;
1546 }
1547
1548 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1549 {
1550 if( m_libMgr->IsLibraryModified( libNickname ) )
1551 {
1552 if( aRequireConfirmation && !applyToAll )
1553 {
1554 msg.Printf( _( "Save changes to '%s' before closing?" ), libNickname );
1555
1556 switch( UnsavedChangesDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
1557 {
1558 case wxID_YES: doSave = true; break;
1559 case wxID_NO: doSave = false; break;
1560 default:
1561 case wxID_CANCEL: return false;
1562 }
1563 }
1564
1565 if( doSave )
1566 {
1567 // If saving under existing name fails then do a Save As..., and if that
1568 // fails then cancel close action.
1569 if( m_libMgr->IsLibraryReadOnly( libNickname ) )
1570 {
1571 msg.Printf( _( "Symbol library '%s' is not writable." ), libNickname );
1572 msg2 = _( "You must save to a different location." );
1573
1574 if( dirtyCount == 1 )
1575 {
1576 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) != wxID_OK )
1577 {
1578 retv = false;
1579 continue;
1580 }
1581 }
1582 else
1583 {
1584 m_infoBar->Dismiss();
1585 m_infoBar->ShowMessageFor( msg + wxS( " " ) + msg2,
1586 2000, wxICON_EXCLAMATION );
1587
1588 while( m_infoBar->IsShownOnScreen() )
1589 wxSafeYield();
1590
1591 retv = false;
1592 continue;
1593 }
1594 }
1595 else if( saveLibrary( libNickname, false ) )
1596 {
1597 continue;
1598 }
1599
1600 if( !saveLibrary( libNickname, true ) )
1601 retv = false;
1602 }
1603 }
1604 }
1605
1606 UpdateTitle();
1607 return retv;
1608}
1609
1610
1612{
1614
1615 if( !m_symbol )
1616 return;
1617
1618 wxString msg = m_symbol->GetName();
1619
1620 AppendMsgPanel( _( "Name" ), UnescapeString( msg ), 8 );
1621
1622 if( m_symbol->IsAlias() )
1623 {
1624 LIB_SYMBOL_SPTR parent = m_symbol->GetParent().lock();
1625
1626 msg = parent ? parent->GetName() : _( "Undefined!" );
1627 AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 );
1628 }
1629
1630 static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
1631 msg = UnitLetter[m_unit];
1632
1633 AppendMsgPanel( _( "Unit" ), msg, 8 );
1634
1635 if( m_bodyStyle == BODY_STYLE::DEMORGAN )
1636 msg = _( "Alternate" );
1637 else if( m_bodyStyle == BODY_STYLE::BASE )
1638 msg = _( "Standard" );
1639 else
1640 msg = wxT( "?" );
1641
1642 AppendMsgPanel( _( "Body" ), msg, 8 );
1643
1644 if( m_symbol->IsPower() )
1645 msg = _( "Power Symbol" );
1646 else
1647 msg = _( "Symbol" );
1648
1649 AppendMsgPanel( _( "Type" ), msg, 8 );
1650 AppendMsgPanel( _( "Description" ), m_symbol->GetDescription(), 8 );
1651 AppendMsgPanel( _( "Keywords" ), m_symbol->GetKeyWords() );
1652 AppendMsgPanel( _( "Datasheet" ), m_symbol->GetDatasheetField().GetText() );
1653}
const char * name
Definition: DXF_plotter.cpp:57
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
static TOOL_ACTION zoomFitScreen
Definition: actions.h:134
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={})
int ShowModal() override
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: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
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: kidialog.h:43
int ShowModal() override
Definition: kidialog.cpp:95
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition: view.cpp:1545
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
Symbol library management helper that is specific to the symbol library editor frame.
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.
LIB_SYMBOL_SPTR SharedPtr() const
Definition: lib_symbol.h:89
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:679
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:72
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:64
@ SCH_LIB_PATH
Definition: project.h:216
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:200
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:307
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:318
wxString GetSymbolName()
bool TransferDataFromWindow() override
wxTextCtrl * m_symbolNameCtrl
SymLibNameValidator m_validator
SYMBOL_SAVE_AS_HANDLER::CONFLICT_STRATEGY & m_conflictStrategy
SAVE_AS_DIALOG(SYMBOL_EDIT_FRAME *aParent, const wxString &aSymbolName, const wxString &aLibraryPreselect, SymLibNameValidator aValidator, SYMBOL_SAVE_AS_HANDLER::CONFLICT_STRATEGY &aConflictStrategy)
std::function< int(const wxString &libName, const wxString &symbolName)> SymLibNameValidator
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:1210
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:449
const std::string & GetString()
Definition: richio.h:472
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.
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 DuplicateSymbol(bool aFromClipboard)
Insert a duplicate symbol.
SCH_SCREEN * m_dummyScreen
< Helper screen used when no symbol is loaded
void saveSymbolCopyAs(bool aOpenCopy)
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.
void SaveSymbolCopyAs(bool aOpenCopy)
Save the currently selected symbol to a new name and/or location.
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.
This is a class that handles state involved in saving a symbol copy as a new symbol.
CONFLICT_STRATEGY m_strategy
wxString resolveConflict(const wxString &proposed, const wxString &aNewLibName) const
SYMBOL_SAVE_AS_HANDLER(LIB_SYMBOL_LIBRARY_MANAGER &aLibMgr, CONFLICT_STRATEGY aStrategy, bool aValueFollowsName)
LIB_SYMBOL_LIBRARY_MANAGER & m_libMgr
bool DoSave(LIB_SYMBOL &symbol, const wxString &aNewSymName, const wxString &aNewLibName)
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
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
std::string GetClipboardUTF8()
Return the information currently stored in the system clipboard.
Definition: clipboard.cpp:51
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:597
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
void Prettify(std::string &aSource, bool aCompactSave)
@ 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:1060
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 std::vector< LIB_SYMBOL_SPTR > GetParentChain(const LIB_SYMBOL &aSymbol)
Get a list of all the symbols in the parental chain of a symbol, with the "leaf" symbol at the start ...
SAVE_AS_IDS
@ ID_OVERWRITE_CONFLICTS
@ ID_RENAME_CONFLICTS
@ ID_MAKE_NEW_LIBRARY
static std::vector< wxString > CheckForParentalChainConflicts(LIB_SYMBOL_LIBRARY_MANAGER &aLibMgr, LIB_SYMBOL &aSymbol, const wxString &newSymbolName, const wxString &newLibraryName)
Get a list of all the symbols in the parental chain of a symbol that have conflicts when transposed t...
static std::pair< bool, bool > CheckSavingIntoOwnInheritance(LIB_SYMBOL_LIBRARY_MANAGER &aLibMgr, LIB_SYMBOL &aSymbol, const wxString &aNewSymbolName, const wxString &aNewLibraryName)
Check if a planned overwrite would put a symbol into it's own inheritance chain.
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.