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 const auto validator = [&]( wxString newName ) -> bool
360 {
361 if( newName.IsEmpty() )
362 {
363 wxMessageBox( _( "Symbol must have a name." ) );
364 return false;
365 }
366
367 if( !lib.empty() && m_libMgr->SymbolExists( newName, lib ) )
368 {
369 wxString msg = wxString::Format(
370 _( "Symbol '%s' already exists in library '%s'." ), newName, lib );
371
372 KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
373 errorDlg.SetOKLabel( _( "Overwrite" ) );
374
375 return errorDlg.ShowModal() == wxID_OK;
376 }
377
378 return true;
379 };
380
381 wxArrayString symbolNamesInLib;
382 m_libMgr->GetSymbolNames( lib, symbolNamesInLib );
383
384 DIALOG_LIB_NEW_SYMBOL dlg( this, symbolNamesInLib, aInheritFrom, validator );
385
386 dlg.SetMinSize( dlg.GetSize() );
387
388 if( dlg.ShowModal() == wxID_CANCEL )
389 return;
390
391 wxString name = dlg.GetName();
392
393 LIB_SYMBOL new_symbol( name ); // do not create symbol on the heap, it will be buffered soon
394
395 wxString parentSymbolName = dlg.GetParentSymbolName();
396
397 if( parentSymbolName.IsEmpty() )
398 {
399 new_symbol.GetReferenceField().SetText( dlg.GetReference() );
400 new_symbol.SetUnitCount( dlg.GetUnitCount() );
401
402 // Initialize new_symbol.m_TextInside member:
403 // if 0, pin text is outside the body (on the pin)
404 // if > 0, pin text is inside the body
405 if( dlg.GetPinNameInside() )
406 {
407 new_symbol.SetPinNameOffset( dlg.GetPinTextPosition() );
408
409 if( new_symbol.GetPinNameOffset() == 0 )
410 new_symbol.SetPinNameOffset( 1 );
411 }
412 else
413 {
414 new_symbol.SetPinNameOffset( 0 );
415 }
416
417 ( dlg.GetPowerSymbol() ) ? new_symbol.SetPower() : new_symbol.SetNormal();
418 new_symbol.SetShowPinNumbers( dlg.GetShowPinNumber() );
419 new_symbol.SetShowPinNames( dlg.GetShowPinName() );
420 new_symbol.LockUnits( !dlg.GetUnitsInterchangeable() );
421 new_symbol.SetExcludedFromBOM( !dlg.GetIncludeInBom() );
422 new_symbol.SetExcludedFromBoard( !dlg.GetIncludeOnBoard() );
423
424 if( dlg.GetUnitCount() < 2 )
425 new_symbol.LockUnits( false );
426
428 }
429 else
430 {
431 LIB_SYMBOL* parent = m_libMgr->GetAlias( parentSymbolName, lib );
432 wxCHECK( parent, /* void */ );
433 new_symbol.SetParent( parent );
434
435 // Inherit the parent mandatory field attributes.
436 for( int id = 0; id < MANDATORY_FIELDS; ++id )
437 {
438 SCH_FIELD* field = new_symbol.GetFieldById( id );
439
440 // the MANDATORY_FIELDS are exactly that in RAM.
441 wxCHECK( field, /* void */ );
442
443 SCH_FIELD* parentField = parent->GetFieldById( id );
444
445 wxCHECK( parentField, /* void */ );
446
447 *field = *parentField;
448
449 switch( id )
450 {
451 case REFERENCE_FIELD:
452 // parent's reference already copied
453 break;
454
455 case VALUE_FIELD:
456 if( parent->IsPower() )
457 field->SetText( name );
458 break;
459
460 case FOOTPRINT_FIELD:
461 case DATASHEET_FIELD:
462 // - footprint might be the same as parent, but might not
463 // - datasheet is most likely different
464 // - probably best to play it safe and copy neither
465 field->SetText( wxEmptyString );
466 break;
467 }
468
469 field->SetParent( &new_symbol );
470 }
471 }
472
473 m_libMgr->UpdateSymbol( &new_symbol, lib );
474 SyncLibraries( false );
475 LoadSymbol( name, lib, 1 );
476
477 // must be called after loadSymbol, that calls SetShowDeMorgan, but
478 // because the symbol is empty,it looks like it has no alternate body
479 // and a derived symbol inherits its parent body.
480 if( !new_symbol.GetParent().lock() )
482 else
484}
485
486
488{
489 wxString libName;
490
491 if( IsLibraryTreeShown() )
493
494 if( libName.empty() )
495 {
497 }
498 else if( m_libMgr->IsLibraryReadOnly( libName ) )
499 {
500 wxString msg = wxString::Format( _( "Symbol library '%s' is not writable." ),
501 libName );
502 wxString msg2 = _( "You must save to a different location." );
503
504 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
505 saveLibrary( libName, true );
506 }
507 else
508 {
509 saveLibrary( libName, false );
510 }
511
512 if( IsLibraryTreeShown() )
514
515 UpdateTitle();
516}
517
518
520{
521 const wxString& libName = GetTargetLibId().GetLibNickname();
522
523 if( !libName.IsEmpty() )
524 {
525 saveLibrary( libName, true );
527 }
528}
529
530
532{
533 saveSymbolCopyAs( aOpenCopy );
534
536}
537
538
545static std::vector<LIB_SYMBOL_SPTR> GetParentChain( const LIB_SYMBOL& aSymbol )
546{
547 std::vector<LIB_SYMBOL_SPTR> chain( { aSymbol.SharedPtr() } );
548
549 while( chain.back()->IsAlias() )
550 {
551 LIB_SYMBOL_SPTR parent = chain.back()->GetParent().lock();
552 chain.push_back( parent );
553 }
554
555 return chain;
556}
557
558
568static std::pair<bool, bool> CheckSavingIntoOwnInheritance( LIB_SYMBOL_LIBRARY_MANAGER& aLibMgr,
569 LIB_SYMBOL& aSymbol,
570 const wxString& aNewSymbolName,
571 const wxString& aNewLibraryName )
572{
573 const wxString& oldLibraryName = aSymbol.GetLibId().GetLibNickname();
574
575 // Cannot be intersecting if in different libs
576 if( aNewLibraryName != oldLibraryName )
577 return { false, false };
578
579 // Or if the target symbol doesn't exist
580 if( !aLibMgr.SymbolExists( aNewSymbolName, aNewLibraryName ) )
581 return { false, false };
582
583 bool inAncestry = false;
584 bool inDescendents = false;
585
586 {
587 const std::vector<LIB_SYMBOL_SPTR> parentChainFromUs = GetParentChain( aSymbol );
588
589 // Ignore the leaf symbol (0) - that must match
590 for( size_t i = 1; i < parentChainFromUs.size(); ++i )
591 {
592 // Attempting to overwrite a symbol in the parental chain
593 if( parentChainFromUs[i]->GetName() == aNewSymbolName )
594 {
595 inAncestry = true;
596 break;
597 }
598 }
599 }
600
601 {
602 LIB_SYMBOL* targetSymbol = aLibMgr.GetAlias( aNewSymbolName, aNewLibraryName );
603 const std::vector<LIB_SYMBOL_SPTR> parentChainFromTarget = GetParentChain( *targetSymbol );
604 const wxString oldSymbolName = aSymbol.GetName();
605
606 // Ignore the leaf symbol - it'll match if we're saving the symbol
607 // to the same name, and that would be OK
608 for( size_t i = 1; i < parentChainFromTarget.size(); ++i )
609 {
610 if( parentChainFromTarget[i]->GetName() == oldSymbolName )
611 {
612 inDescendents = true;
613 break;
614 }
615 }
616 }
617
618 return { inAncestry, inDescendents };
619}
620
621
629static std::vector<wxString> CheckForParentalChainConflicts( LIB_SYMBOL_LIBRARY_MANAGER& aLibMgr,
630 LIB_SYMBOL& aSymbol,
631 const wxString& newSymbolName,
632 const wxString& newLibraryName )
633{
634 std::vector<wxString> conflicts;
635 const wxString& oldLibraryName = aSymbol.GetLibId().GetLibNickname();
636
637 if( newLibraryName == oldLibraryName )
638 {
639 // Saving into the same library - the only conflict could be the symbol itself
640 if( aLibMgr.SymbolExists( newSymbolName, newLibraryName ) )
641 {
642 conflicts.push_back( newSymbolName );
643 }
644 }
645 else
646 {
647 // In a different library, check the whole chain
648 const std::vector<LIB_SYMBOL_SPTR> parentChain = GetParentChain( aSymbol );
649
650 for( size_t i = 0; i < parentChain.size(); ++i )
651 {
652 if( i == 0 )
653 {
654 // This is the leaf symbol which the user actually named
655 if( aLibMgr.SymbolExists( newSymbolName, newLibraryName ) )
656 {
657 conflicts.push_back( newSymbolName );
658 }
659 }
660 else
661 {
662 LIB_SYMBOL_SPTR chainSymbol = parentChain[i];
663 if( aLibMgr.SymbolExists( chainSymbol->GetName(), newLibraryName ) )
664 {
665 conflicts.push_back( chainSymbol->GetName() );
666 }
667 }
668 }
669 }
670
671 return conflicts;
672}
673
674
682{
683public:
685 {
686 // Just overwrite any existing symbols in the target library
687 OVERWRITE,
688 // Add a suffix until we find a name that doesn't conflict
689 RENAME,
690 // Could have a mode that asks for every one, be then we'll need a fancier
691 // SAVE_AS_DIALOG subdialog with Overwrite/Rename/Prompt/Cancel
692 // PROMPT
693 };
694
696 bool aValueFollowsName ) :
697 m_libMgr( aLibMgr ), m_strategy( aStrategy ), m_valueFollowsName( aValueFollowsName )
698 {
699 }
700
701 bool DoSave( LIB_SYMBOL& symbol, const wxString& aNewSymName, const wxString& aNewLibName )
702 {
703 std::vector<LIB_SYMBOL_SPTR> parentChain;
704 // If we're saving into the same library, we don't need to check the parental chain
705 // because we can just keep the same parent symbol
706 if( aNewLibName == symbol.GetLibId().GetLibNickname().wx_str() )
707 parentChain.push_back( symbol.SharedPtr() );
708 else
709 parentChain = GetParentChain( symbol );
710
711 std::vector<wxString> newNames;
712
713 // Iterate backwards (i.e. from the root down)
714 for( int i = (int) parentChain.size() - 1; i >= 0; --i )
715 {
716 LIB_SYMBOL_SPTR& oldSymbol = parentChain[i];
717
718 LIB_SYMBOL new_symbol( *oldSymbol );
719
720 wxString newName;
721 if( i == 0 )
722 {
723 // This is the leaf symbol which the user actually named
724 newName = aNewSymName;
725 }
726 else
727 {
728 // Somewhere in the inheritance chain, use the conflict resolution strategy
729 newName = oldSymbol->GetName();
730 }
731
732 newName = resolveConflict( newName, aNewLibName );
733 new_symbol.SetName( newName );
734
736 new_symbol.GetValueField().SetText( newName );
737
738 if( i == (int) parentChain.size() - 1 )
739 {
740 // This is the root symbol
741 // Nothing extra to do, it's just a simple symbol with no parents
742 }
743 else
744 {
745 // Get the buffered new copy in the new library (with the name we gave it)
746 LIB_SYMBOL* newParent = m_libMgr.GetAlias( newNames.back(), aNewLibName );
747
748 // We should have stored this already, why didn't we get it back?
749 wxASSERT( newParent );
750 new_symbol.SetParent( newParent );
751 }
752
753 newNames.push_back( newName );
754 m_libMgr.UpdateSymbol( &new_symbol, aNewLibName );
755 }
756
757 return true;
758 }
759
760private:
761 wxString resolveConflict( const wxString& proposed, const wxString& aNewLibName ) const
762 {
763 switch( m_strategy )
764 {
766 {
767 // In an overwrite strategy, we don't care about conflicts
768 return proposed;
769 }
771 {
772 // In a rename strategy, we need to find a name that doesn't conflict
773 int suffix = 1;
774
775 while( true )
776 {
777 wxString newName = wxString::Format( "%s_%d", proposed, suffix );
778
779 if( !m_libMgr.SymbolExists( newName, aNewLibName ) )
780 return newName;
781
782 ++suffix;
783 }
784 break;
785 }
786 // No default
787 }
788
789 wxFAIL_MSG( "Invalid conflict strategy" );
790 return "";
791 }
792
796};
797
798
800{
801 ID_MAKE_NEW_LIBRARY = wxID_HIGHEST + 1,
804};
805
806
808{
809public:
811 std::function<int( const wxString& libName, const wxString& symbolName )>;
812
813 SAVE_AS_DIALOG( SYMBOL_EDIT_FRAME* aParent, const wxString& aSymbolName,
814 const wxString& aLibraryPreselect, SymLibNameValidator aValidator,
815 SYMBOL_SAVE_AS_HANDLER::CONFLICT_STRATEGY& aConflictStrategy ) :
816 EDA_LIST_DIALOG( aParent, _( "Save Symbol As" ), false ),
817 m_validator( std::move( aValidator ) ), m_conflictStrategy( aConflictStrategy )
818 {
820 PROJECT_FILE& project = aParent->Prj().GetProjectFile();
822 std::vector<wxString> libNicknames = tbl->GetLogicalLibs();
823 wxArrayString headers;
824 std::vector<wxArrayString> itemsToDisplay;
825
826 headers.Add( _( "Nickname" ) );
827 headers.Add( _( "Description" ) );
828
829 for( const wxString& nickname : libNicknames )
830 {
831 if( alg::contains( project.m_PinnedSymbolLibs, nickname )
832 || alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
833 {
834 wxArrayString item;
835 item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
836 item.Add( tbl->GetDescription( nickname ) );
837 itemsToDisplay.push_back( item );
838 }
839 }
840
841 for( const wxString& nickname : libNicknames )
842 {
843 if( !alg::contains( project.m_PinnedSymbolLibs, nickname )
844 && !alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
845 {
846 wxArrayString item;
847 item.Add( nickname );
848 item.Add( tbl->GetDescription( nickname ) );
849 itemsToDisplay.push_back( item );
850 }
851 }
852
853 initDialog( headers, itemsToDisplay, aLibraryPreselect );
854
855 SetListLabel( _( "Save in library:" ) );
856 SetOKLabel( _( "Save" ) );
857
858 wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
859
860 wxStaticText* label = new wxStaticText( this, wxID_ANY, _( "Name:" ) );
861 bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
862
863 m_symbolNameCtrl = new wxTextCtrl( this, wxID_ANY, aSymbolName );
864 bNameSizer->Add( m_symbolNameCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
865
866 wxButton* newLibraryButton = new wxButton( this, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
867 m_ButtonsSizer->Prepend( 80, 20 );
868 m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
869
870 GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
871
872 Bind( wxEVT_BUTTON,
873 [this]( wxCommandEvent& )
874 {
875 EndModal( ID_MAKE_NEW_LIBRARY );
877
878 // Move nameTextCtrl to the head of the tab-order
879 if( GetChildren().DeleteObject( m_symbolNameCtrl ) )
880 GetChildren().Insert( m_symbolNameCtrl );
881
883
885
886 Layout();
887 GetSizer()->Fit( this );
888
889 Centre();
890 }
891
892 wxString GetSymbolName()
893 {
894 wxString symbolName = m_symbolNameCtrl->GetValue();
895 symbolName.Trim( true );
896 symbolName.Trim( false );
897 symbolName.Replace( " ", "_" );
898 return symbolName;
899 }
900
901protected:
903 {
905
906 if( ret == wxID_CANCEL )
907 return false;
908
909 if( ret == ID_OVERWRITE_CONFLICTS )
911 else if( ret == ID_RENAME_CONFLICTS )
913
914 return true;
915 }
916
917private:
918 wxTextCtrl* m_symbolNameCtrl;
921};
922
923
925{
926 LIB_SYMBOL* symbol = getTargetSymbol();
927
928 if( !symbol )
929 return;
930
931 LIB_ID old_lib_id = symbol->GetLibId();
932 wxString symbolName = old_lib_id.GetLibItemName();
933 wxString libraryName = old_lib_id.GetLibNickname();
934 bool valueFollowsName = symbol->GetValueField().GetText() == symbolName;
935 wxString msg;
936 bool done = false;
937
938 // This is the function that will be called when the user clicks OK in the dialog
939 // and checks if the proposed name has problems, and asks for clarification.
940 const auto dialogValidatorFunc = [&]( const wxString& newLib, const wxString& newName ) -> int
941 {
942 if( newLib.IsEmpty() )
943 {
944 wxMessageBox( _( "A library must be specified." ) );
945 return wxID_CANCEL;
946 }
947
948 if( newName.IsEmpty() )
949 {
950 wxMessageBox( _( "Symbol must have a name." ) );
951 return wxID_CANCEL;
952 }
953
954 if( m_libMgr->IsLibraryReadOnly( newLib ) )
955 {
956 msg = wxString::Format( _( "Library '%s' is read-only. Choose a "
957 "different library to save the symbol '%s' to." ),
958 newLib, newName );
959 wxMessageBox( msg );
960 return wxID_CANCEL;
961 }
962
967 const auto& [inAncestry, inDescendents] =
968 CheckSavingIntoOwnInheritance( *m_libMgr, *symbol, newName, newLib );
969
970 if( inAncestry )
971 {
972 msg = wxString::Format( _( "Symbol '%s' cannot replace another symbol '%s' that it "
973 "descends from" ),
974 symbolName, newName );
975 wxMessageBox( msg );
976 return wxID_CANCEL;
977 }
978
979 if( inDescendents )
980 {
981 msg = wxString::Format( _( "Symbol '%s' cannot replace another symbol '%s' that is "
982 "a descendent of it." ),
983 symbolName, newName );
984 wxMessageBox( msg );
985 return wxID_CANCEL;
986 }
987
988 const std::vector<wxString> conflicts =
989 CheckForParentalChainConflicts( *m_libMgr, *symbol, newName, newLib );
990
991 if( conflicts.size() == 1 && conflicts.front() == newName )
992 {
993 // The simplest case is when the symbol itself has a conflict
994 msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'."
995 "Do you want to overwrite it?" ),
996 newName, newLib );
997
998 KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
999 errorDlg.SetOKLabel( _( "Overwrite" ) );
1000
1001 return errorDlg.ShowModal() == wxID_OK ? ID_OVERWRITE_CONFLICTS : (int) wxID_CANCEL;
1002 }
1003 else if( !conflicts.empty() )
1004 {
1005 // If there are conflicts in the parental chain, we need to ask the user
1006 // if they want to overwrite all of them.
1007 // A more complex UI might allow the user to re-parent the symbol to an existing
1008 // symbol in the target lib, or rename all the parents somehow.
1009 msg = wxString::Format( _( "The following symbols in the inheritance chain of '%s' "
1010 "already exist in library '%s':\n" ),
1011 symbolName, newLib );
1012
1013 for( const wxString& conflict : conflicts )
1014 msg += wxString::Format( " %s\n", conflict );
1015
1016 msg += _( "\nDo you want to overwrite all of them, or rename the new symbols?" );
1017
1018 KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
1019 wxYES_NO | wxCANCEL | wxICON_WARNING );
1020 errorDlg.SetYesNoCancelLabels( _( "Overwrite All" ), _( "Rename All" ), _( "Cancel" ) );
1021
1022 switch( errorDlg.ShowModal() )
1023 {
1024 case wxID_YES: return ID_OVERWRITE_CONFLICTS;
1025 case wxID_NO: return ID_RENAME_CONFLICTS;
1026 default: break;
1027 }
1028 return wxID_CANCEL;
1029 }
1030
1031 return wxID_OK;
1032 };
1033
1035
1036 // Keep asking the user for a new name until they give a valid one or cancel the operation
1037 while( !done )
1038 {
1039 SAVE_AS_DIALOG dlg( this, symbolName, libraryName, dialogValidatorFunc, strategy );
1040
1041 int ret = dlg.ShowModal();
1042
1043 switch( ret )
1044 {
1045 case wxID_CANCEL:
1046 {
1047 return;
1048 }
1049
1050 case wxID_OK: // No conflicts
1053 {
1054 symbolName = dlg.GetSymbolName();
1055 libraryName = dlg.GetTextSelection();
1056
1057 if( ret == ID_RENAME_CONFLICTS )
1059
1060 done = true;
1061 break;
1062 }
1063
1065 {
1066 wxFileName newLibrary( AddLibraryFile( true ) );
1067 libraryName = newLibrary.GetName();
1068 break;
1069 }
1070
1071 default:
1072 break;
1073 }
1074 }
1075
1076 SYMBOL_SAVE_AS_HANDLER saver( *m_libMgr, strategy, valueFollowsName );
1077
1078 saver.DoSave( *symbol, symbolName, libraryName );
1079
1080 SyncLibraries( false );
1081
1082 if( aOpenCopy )
1083 LoadSymbol( symbolName, libraryName, 1 );
1084}
1085
1086
1088{
1089 wxCHECK( m_symbol, /* void */ );
1090
1091 wxString lib = GetCurLib();
1092
1093 if( !lib.IsEmpty() && aOldName && *aOldName != m_symbol->GetName() )
1094 {
1095 // Test the current library for name conflicts
1096 if( m_libMgr->SymbolExists( m_symbol->GetName(), lib ) )
1097 {
1098 wxString msg = wxString::Format( _( "Symbol name '%s' already in use." ),
1100
1101 DisplayErrorMessage( this, msg );
1102 m_symbol->SetName( *aOldName );
1103 }
1104 else
1105 {
1106 m_libMgr->UpdateSymbolAfterRename( m_symbol, *aOldName, lib );
1107 }
1108
1109 // Reselect the renamed symbol
1111 }
1112
1114 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasAlternateBodyStyle() );
1115 UpdateTitle();
1116
1117 // N.B. The view needs to be rebuilt first as the Symbol Properties change may invalidate
1118 // the view pointers by rebuilting the field table
1119 RebuildView();
1121
1122 OnModify();
1123}
1124
1125
1127{
1128 std::vector<LIB_ID> toDelete = GetSelectedLibIds();
1129
1130 if( toDelete.empty() )
1131 toDelete.emplace_back( GetTargetLibId() );
1132
1133 for( LIB_ID& libId : toDelete )
1134 {
1135 if( m_libMgr->IsSymbolModified( libId.GetLibItemName(), libId.GetLibNickname() )
1136 && !IsOK( this, wxString::Format( _( "The symbol '%s' has been modified.\n"
1137 "Do you want to remove it from the library?" ),
1138 libId.GetUniStringLibItemName() ) ) )
1139 {
1140 continue;
1141 }
1142
1143 if( m_libMgr->HasDerivedSymbols( libId.GetLibItemName(), libId.GetLibNickname() ) )
1144 {
1145 wxString msg;
1146
1147 msg.Printf(
1148 _( "The symbol %s is used to derive other symbols.\n"
1149 "Deleting this symbol will delete all of the symbols derived from it.\n\n"
1150 "Do you wish to delete this symbol and all of its derivatives?" ),
1151 libId.GetLibItemName().wx_str() );
1152
1153 wxMessageDialog::ButtonLabel yesButtonLabel( _( "Delete Symbol" ) );
1154 wxMessageDialog::ButtonLabel noButtonLabel( _( "Keep Symbol" ) );
1155
1156 wxMessageDialog dlg( this, msg, _( "Warning" ),
1157 wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTER );
1158 dlg.SetYesNoLabels( yesButtonLabel, noButtonLabel );
1159
1160 if( dlg.ShowModal() == wxID_NO )
1161 continue;
1162 }
1163
1164 if( IsCurrentSymbol( libId ) )
1165 emptyScreen();
1166
1167 m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
1168 }
1169
1171}
1172
1173
1175{
1176 std::vector<LIB_ID> symbols;
1177
1178 if( GetTreeLIBIDs( symbols ) == 0 )
1179 return;
1180
1181 STRING_FORMATTER formatter;
1182
1183 for( LIB_ID& libId : symbols )
1184 {
1185 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(),
1186 libId.GetLibNickname() );
1187
1188 if( !symbol )
1189 continue;
1190
1191 std::unique_ptr<LIB_SYMBOL> tmp = symbol->Flatten();
1192 SCH_IO_KICAD_SEXPR::FormatLibSymbol( tmp.get(), formatter );
1193 }
1194
1195 std::string prettyData = formatter.GetString();
1196 KICAD_FORMAT::Prettify( prettyData, true );
1197
1198 wxLogNull doNotLog; // disable logging of failed clipboard actions
1199
1200 auto clipboard = wxTheClipboard;
1201 wxClipboardLocker clipboardLock( clipboard );
1202
1203 if( !clipboardLock || !clipboard->IsOpened() )
1204 return;
1205
1206 auto data = new wxTextDataObject( wxString( prettyData.c_str(), wxConvUTF8 ) );
1207 clipboard->SetData( data );
1208
1209 clipboard->Flush();
1210}
1211
1212
1213void SYMBOL_EDIT_FRAME::DuplicateSymbol( bool aFromClipboard )
1214{
1215 LIB_ID libId = GetTargetLibId();
1216 wxString lib = libId.GetLibNickname();
1217
1218 if( !m_libMgr->LibraryExists( lib ) )
1219 return;
1220
1221 std::vector<LIB_SYMBOL*> newSymbols;
1222
1223 if( aFromClipboard )
1224 {
1225 std::string clipboardData = GetClipboardUTF8();
1226
1227 try
1228 {
1229 newSymbols = SCH_IO_KICAD_SEXPR::ParseLibSymbols( clipboardData, "Clipboard" );
1230 }
1231 catch( IO_ERROR& e )
1232 {
1233 wxLogMessage( wxS( "Can not paste: %s" ), e.Problem() );
1234 }
1235 }
1236 else if( LIB_SYMBOL* srcSymbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(), lib ) )
1237 {
1238 newSymbols.emplace_back( new LIB_SYMBOL( *srcSymbol ) );
1239
1240 // Derive from same parent.
1241 if( srcSymbol->IsAlias() )
1242 {
1243 if( std::shared_ptr<LIB_SYMBOL> srcParent = srcSymbol->GetParent().lock() )
1244 newSymbols.back()->SetParent( srcParent.get() );
1245 }
1246 }
1247
1248 if( newSymbols.empty() )
1249 return;
1250
1251 for( LIB_SYMBOL* symbol : newSymbols )
1252 {
1253 ensureUniqueName( symbol, lib );
1254 m_libMgr->UpdateSymbol( symbol, lib );
1255
1256 LoadOneLibrarySymbolAux( symbol, lib, GetUnit(), GetBodyStyle() );
1257 }
1258
1259 SyncLibraries( false );
1260 m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, newSymbols[0]->GetName() ) );
1261
1262 for( LIB_SYMBOL* symbol : newSymbols )
1263 delete symbol;
1264}
1265
1266
1267void SYMBOL_EDIT_FRAME::ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
1268{
1269 if( aSymbol )
1270 {
1271 int i = 1;
1272 wxString newName = aSymbol->GetName();
1273
1274 // Append a number to the name until the name is unique in the library.
1275 while( m_libMgr->SymbolExists( newName, aLibrary ) )
1276 newName.Printf( "%s_%d", aSymbol->GetName(), i++ );
1277
1278 aSymbol->SetName( newName );
1279 }
1280}
1281
1282
1283void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
1284{
1285 LIB_ID libId = GetTargetLibId();
1286 const wxString& libName = libId.GetLibNickname();
1287
1288 // Empty if this is the library itself that is selected.
1289 const wxString& symbolName = libId.GetLibItemName();
1290
1291 wxString msg = wxString::Format( _( "Revert '%s' to last version saved?" ),
1292 symbolName.IsEmpty() ? libName : symbolName );
1293
1294 if( aConfirm && !ConfirmRevertDialog( this, msg ) )
1295 return;
1296
1297 bool reload_currentSymbol = false;
1298 wxString curr_symbolName = symbolName;
1299
1300 if( GetCurSymbol() )
1301 {
1302 // the library itself is reverted: the current symbol will be reloaded only if it is
1303 // owned by this library
1304 if( symbolName.IsEmpty() )
1305 {
1306 LIB_ID curr_libId = GetCurSymbol()->GetLibId();
1307 reload_currentSymbol = libName == curr_libId.GetLibNickname().wx_str();
1308
1309 if( reload_currentSymbol )
1310 curr_symbolName = curr_libId.GetUniStringLibItemName();
1311 }
1312 else
1313 {
1314 reload_currentSymbol = IsCurrentSymbol( libId );
1315 }
1316 }
1317
1318 int unit = m_unit;
1319
1320 if( reload_currentSymbol )
1321 emptyScreen();
1322
1323 if( symbolName.IsEmpty() )
1324 {
1325 m_libMgr->RevertLibrary( libName );
1326 }
1327 else
1328 {
1329 libId = m_libMgr->RevertSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
1330
1331 m_treePane->GetLibTree()->SelectLibId( libId );
1333 }
1334
1335 if( reload_currentSymbol && m_libMgr->SymbolExists( curr_symbolName, libName ) )
1336 LoadSymbol( curr_symbolName, libName, unit );
1337
1338 m_treePane->Refresh();
1339}
1340
1341
1343{
1344 wxCHECK_RET( m_libMgr, "Library manager object not created." );
1345
1346 Revert( false );
1348}
1349
1350
1351void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLibrary, int aUnit )
1352{
1354 {
1355 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
1356 [&]() -> bool
1357 {
1358 return saveCurrentSymbol();
1359 } ) )
1360 {
1361 return;
1362 }
1363 }
1364
1365 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aAlias, aLibrary );
1366
1367 if( !symbol )
1368 {
1369 DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
1370 aAlias,
1371 aLibrary ) );
1373 return;
1374 }
1375
1376 // Optimize default edit options for this symbol
1377 // Usually if units are locked, graphic items are specific to each unit
1378 // and if units are interchangeable, graphic items are common to units
1380 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
1381
1382 LoadOneLibrarySymbolAux( symbol, aLibrary, aUnit, 0 );
1383}
1384
1385
1386bool SYMBOL_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
1387{
1388 wxFileName fn;
1389 wxString msg;
1390 SYMBOL_SAVEAS_TYPE type = SYMBOL_SAVEAS_TYPE::NORMAL_SAVE_AS;
1391 SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
1392 PROJECT& prj = Prj();
1393
1395
1396 if( !aNewFile && ( aLibrary.empty() || !PROJECT_SCH::SchSymbolLibTable( &prj )->HasLibrary( aLibrary ) ) )
1397 {
1398 ShowInfoBarError( _( "No library specified." ) );
1399 return false;
1400 }
1401
1402 if( aNewFile )
1403 {
1404 SEARCH_STACK* search = PROJECT_SCH::SchSearchS( &prj );
1405
1406 // Get a new name for the library
1407 wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
1408
1409 if( !default_path )
1410 default_path = search->LastVisitedPath();
1411
1412 fn.SetName( aLibrary );
1414
1415 wxString wildcards = FILEEXT::KiCadSymbolLibFileWildcard();
1416
1417 wxFileDialog dlg( this, wxString::Format( _( "Save Library '%s' As..." ), aLibrary ),
1418 default_path, fn.GetFullName(), wildcards,
1419 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1420
1421 SYMBOL_FILEDLG_SAVE_AS saveAsHook( type );
1422 dlg.SetCustomizeHook( saveAsHook );
1423
1424 if( dlg.ShowModal() == wxID_CANCEL )
1425 return false;
1426
1427 fn = dlg.GetPath();
1428
1429 prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
1430
1431 if( fn.GetExt().IsEmpty() )
1433
1434 type = saveAsHook.GetOption();
1435 }
1436 else
1437 {
1438 fn = PROJECT_SCH::SchSymbolLibTable( &prj )->GetFullURI( aLibrary );
1440
1441 if( fileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
1442 fileType = SCH_IO_MGR::SCH_KICAD;
1443 }
1444
1445 // Verify the user has write privileges before attempting to save the library file.
1446 if( !aNewFile && m_libMgr->IsLibraryReadOnly( aLibrary ) )
1447 return false;
1448
1449 ClearMsgPanel();
1450
1451 // Copy .kicad_symb file to .bak.
1452 if( !backupFile( fn, "bak" ) )
1453 return false;
1454
1455 if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), fileType ) )
1456 {
1457 msg.Printf( _( "Failed to save changes to symbol library file '%s'." ),
1458 fn.GetFullPath() );
1459 DisplayErrorMessage( this, _( "Error Saving Library" ), msg );
1460 return false;
1461 }
1462
1463 if( !aNewFile )
1464 {
1465 m_libMgr->ClearLibraryModified( aLibrary );
1466
1467 // Update the library modification time so that we don't reload based on the watcher
1468 if( aLibrary == getTargetLib() )
1469 SetSymModificationTime( fn.GetModificationTime() );
1470 }
1471 else
1472 {
1473 bool resyncLibTree = false;
1474 wxString originalLibNickname = getTargetLib();
1475 wxString forceRefresh;
1476
1477 switch( type )
1478 {
1479 case SYMBOL_SAVEAS_TYPE::REPLACE_TABLE_ENTRY:
1480 resyncLibTree = replaceLibTableEntry( originalLibNickname, fn.GetFullPath() );
1481 forceRefresh = originalLibNickname;
1482 break;
1483
1484 case SYMBOL_SAVEAS_TYPE::ADD_GLOBAL_TABLE_ENTRY:
1485 resyncLibTree = addLibTableEntry( fn.GetFullPath() );
1486 break;
1487
1488 case SYMBOL_SAVEAS_TYPE::ADD_PROJECT_TABLE_ENTRY:
1489 resyncLibTree = addLibTableEntry( fn.GetFullPath(), PROJECT_LIB_TABLE );
1490 break;
1491
1492 default:
1493 break;
1494 }
1495
1496 if( resyncLibTree )
1497 {
1499 SyncLibraries( true, false, forceRefresh );
1501 }
1502 }
1503
1504 ClearMsgPanel();
1505 msg.Printf( _( "Symbol library file '%s' saved." ), fn.GetFullPath() );
1507
1508 return true;
1509}
1510
1511
1512bool SYMBOL_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
1513{
1514 wxString msg, msg2;
1515 bool doSave = true;
1516 int dirtyCount = 0;
1517 bool applyToAll = false;
1518 bool retv = true;
1519
1520 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1521 {
1522 if( m_libMgr->IsLibraryModified( libNickname ) )
1523 dirtyCount++;
1524 }
1525
1526 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1527 {
1528 if( m_libMgr->IsLibraryModified( libNickname ) )
1529 {
1530 if( aRequireConfirmation && !applyToAll )
1531 {
1532 msg.Printf( _( "Save changes to '%s' before closing?" ), libNickname );
1533
1534 switch( UnsavedChangesDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
1535 {
1536 case wxID_YES: doSave = true; break;
1537 case wxID_NO: doSave = false; break;
1538 default:
1539 case wxID_CANCEL: return false;
1540 }
1541 }
1542
1543 if( doSave )
1544 {
1545 // If saving under existing name fails then do a Save As..., and if that
1546 // fails then cancel close action.
1547 if( m_libMgr->IsLibraryReadOnly( libNickname ) )
1548 {
1549 msg.Printf( _( "Symbol library '%s' is not writable." ), libNickname );
1550 msg2 = _( "You must save to a different location." );
1551
1552 if( dirtyCount == 1 )
1553 {
1554 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) != wxID_OK )
1555 {
1556 retv = false;
1557 continue;
1558 }
1559 }
1560 else
1561 {
1562 m_infoBar->Dismiss();
1563 m_infoBar->ShowMessageFor( msg + wxS( " " ) + msg2,
1564 2000, wxICON_EXCLAMATION );
1565
1566 while( m_infoBar->IsShownOnScreen() )
1567 wxSafeYield();
1568
1569 retv = false;
1570 continue;
1571 }
1572 }
1573 else if( saveLibrary( libNickname, false ) )
1574 {
1575 continue;
1576 }
1577
1578 if( !saveLibrary( libNickname, true ) )
1579 retv = false;
1580 }
1581 }
1582 }
1583
1584 UpdateTitle();
1585 return retv;
1586}
1587
1588
1590{
1592
1593 if( !m_symbol )
1594 return;
1595
1596 wxString msg = m_symbol->GetName();
1597
1598 AppendMsgPanel( _( "Name" ), UnescapeString( msg ), 8 );
1599
1600 if( m_symbol->IsAlias() )
1601 {
1602 LIB_SYMBOL_SPTR parent = m_symbol->GetParent().lock();
1603
1604 msg = parent ? parent->GetName() : _( "Undefined!" );
1605 AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 );
1606 }
1607
1608 static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
1609 msg = UnitLetter[m_unit];
1610
1611 AppendMsgPanel( _( "Unit" ), msg, 8 );
1612
1613 if( m_bodyStyle == BODY_STYLE::DEMORGAN )
1614 msg = _( "Alternate" );
1615 else if( m_bodyStyle == BODY_STYLE::BASE )
1616 msg = _( "Standard" );
1617 else
1618 msg = wxT( "?" );
1619
1620 AppendMsgPanel( _( "Body" ), msg, 8 );
1621
1622 if( m_symbol->IsPower() )
1623 msg = _( "Power Symbol" );
1624 else
1625 msg = _( "Symbol" );
1626
1627 AppendMsgPanel( _( "Type" ), msg, 8 );
1628 AppendMsgPanel( _( "Description" ), m_symbol->GetDescription(), 8 );
1629 AppendMsgPanel( _( "Keywords" ), m_symbol->GetKeyWords() );
1630 AppendMsgPanel( _( "Datasheet" ), m_symbol->GetDatasheetField().GetText() );
1631}
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
wxString GetParentSymbolName() const
wxString GetName() const override
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:1213
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.