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
55
56
58{
59 wxString title;
60
62 {
64 title = wxT( "*" );
65
66 title += m_reference;
67 title += wxS( " " ) + _( "[from schematic]" );
68 }
69 else if( GetCurSymbol() )
70 {
72 title = wxT( "*" );
73
74 title += UnescapeString( GetCurSymbol()->GetLibId().Format() );
75
77 title += wxS( " " ) + _( "[Read Only Library]" );
78 }
79 else
80 {
81 title = _( "[no symbol loaded]" );
82 }
83
84 title += wxT( " \u2014 " ) + _( "Symbol Editor" );
85 SetTitle( title );
86}
87
88
89void SYMBOL_EDIT_FRAME::SelectActiveLibrary( const wxString& aLibrary )
90{
91 wxString selectedLib = aLibrary;
92
93 if( selectedLib.empty() )
94 selectedLib = SelectLibraryFromList();
95
96 if( !selectedLib.empty() )
97 SetCurLib( selectedLib );
98
100}
101
102
104{
105 if( GetCurSymbol() )
106 {
108 {
109 SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
110
111 if( !schframe ) // happens when the schematic editor has been closed
112 {
113 DisplayErrorMessage( this, _( "No schematic currently open." ) );
114 return false;
115 }
116 else
117 {
119 GetScreen()->SetContentModified( false );
120 return true;
121 }
122 }
123 else
124 {
125 const wxString& libName = GetCurSymbol()->GetLibId().GetLibNickname();
126
127 if( m_libMgr->IsLibraryReadOnly( libName ) )
128 {
129 wxString msg = wxString::Format( _( "Symbol library '%s' is not writable." ),
130 libName );
131 wxString msg2 = _( "You must save to a different location." );
132
133 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
134 return saveLibrary( libName, true );
135 }
136 else
137 {
138 return saveLibrary( libName, false );
139 }
140 }
141 }
142
143 return false;
144}
145
146
147bool SYMBOL_EDIT_FRAME::LoadSymbol( const LIB_ID& aLibId, int aUnit, int aBodyStyle )
148{
149 LIB_ID libId = aLibId;
150
151 // Some libraries can't be edited, so load the underlying chosen symbol
153 {
154 if( lib->SchLibType() == SCH_IO_MGR::SCH_DATABASE
155 || lib->SchLibType() == SCH_IO_MGR::SCH_CADSTAR_ARCHIVE
156 || lib->SchLibType() == SCH_IO_MGR::SCH_HTTP )
157
158 {
159 try
160 {
161 LIB_SYMBOL* readOnlySym = PROJECT_SCH::SchSymbolLibTable( &Prj() )->LoadSymbol( aLibId );
162
163 if( readOnlySym && readOnlySym->GetSourceLibId().IsValid() )
164 libId = readOnlySym->GetSourceLibId();
165 }
166 catch( const IO_ERROR& ioe )
167 {
168 wxString msg;
169
170 msg.Printf( _( "Error loading symbol %s from library '%s'." ),
171 aLibId.GetUniStringLibId(), aLibId.GetUniStringLibItemName() );
172 DisplayErrorMessage( this, msg, ioe.What() );
173 return false;
174 }
175 }
176 }
177
179 && GetCurSymbol()->GetLibId() == libId
180 && GetUnit() == aUnit
181 && GetBodyStyle() == aBodyStyle )
182 {
183 return true;
184 }
185
187 {
188 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
189 [&]() -> bool
190 {
191 return saveCurrentSymbol();
192 } ) )
193 {
194 return false;
195 }
196 }
197
199
200 if( LoadSymbolFromCurrentLib( libId.GetLibItemName(), aUnit, aBodyStyle ) )
201 {
202 m_treePane->GetLibTree()->SelectLibId( libId );
203 m_treePane->GetLibTree()->ExpandLibId( libId );
204
205 m_centerItemOnIdle = libId;
206 Bind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
207 setSymWatcher( &libId );
208
209 return true;
210 }
211
212 return false;
213}
214
215
217{
219 Unbind( wxEVT_IDLE, &SYMBOL_EDIT_FRAME::centerItemIdleHandler, this );
220}
221
222
223bool SYMBOL_EDIT_FRAME::LoadSymbolFromCurrentLib( const wxString& aAliasName, int aUnit,
224 int aBodyStyle )
225{
226 LIB_SYMBOL* alias = nullptr;
227
228 try
229 {
230 alias = PROJECT_SCH::SchSymbolLibTable( &Prj() )->LoadSymbol( GetCurLib(), aAliasName );
231 }
232 catch( const IO_ERROR& ioe )
233 {
234 wxString msg;
235
236 msg.Printf( _( "Error loading symbol %s from library '%s'." ),
237 aAliasName,
238 GetCurLib() );
239 DisplayErrorMessage( this, msg, ioe.What() );
240 return false;
241 }
242
243 if( !alias || !LoadOneLibrarySymbolAux( alias, GetCurLib(), aUnit, aBodyStyle ) )
244 return false;
245
246 // Enable synchronized pin edit mode for symbols with interchangeable units
248
251 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasAlternateBodyStyle() );
252
253 if( aUnit > 0 )
255
256 return true;
257}
258
259
260bool SYMBOL_EDIT_FRAME::LoadOneLibrarySymbolAux( LIB_SYMBOL* aEntry, const wxString& aLibrary,
261 int aUnit, int aBodyStyle )
262{
263 bool rebuildMenuAndToolbar = false;
264
265 if( !aEntry || aLibrary.empty() )
266 return false;
267
268 if( aEntry->GetName().IsEmpty() )
269 {
270 wxLogWarning( "Symbol in library '%s' has empty name field.", aLibrary );
271 return false;
272 }
273
275
276 // Symbols from the schematic are edited in place and not managed by the library manager.
278 {
279 delete m_symbol;
280 m_symbol = nullptr;
281
282 SCH_SCREEN* screen = GetScreen();
283 delete screen;
286 rebuildMenuAndToolbar = true;
287 }
288
289 LIB_SYMBOL* lib_symbol = m_libMgr->GetBufferedSymbol( aEntry->GetName(), aLibrary );
290 wxCHECK( lib_symbol, false );
291
292 m_unit = aUnit > 0 ? aUnit : 1;
293 m_bodyStyle = aBodyStyle > 0 ? aBodyStyle : 1;
294
295 // The buffered screen for the symbol
296 SCH_SCREEN* symbol_screen = m_libMgr->GetScreen( lib_symbol->GetName(), aLibrary );
297
298 SetScreen( symbol_screen );
299 SetCurSymbol( new LIB_SYMBOL( *lib_symbol ), true );
300 SetCurLib( aLibrary );
301
302 if( rebuildMenuAndToolbar )
303 {
306 GetInfoBar()->Dismiss();
307 }
308
309 UpdateTitle();
311 SetShowDeMorgan( GetCurSymbol()->HasAlternateBodyStyle() );
312
314
315 if( !IsSymbolFromSchematic() )
316 {
317 LIB_ID libId = GetCurSymbol()->GetLibId();
318 setSymWatcher( &libId );
319 }
320
321 // Let tools add things to the view if necessary
322 if( m_toolManager )
324
326
327 // Display the document information based on the entry selected just in
328 // case the entry is an alias.
330 Refresh();
331
332 return true;
333}
334
335
337{
338 saveAllLibraries( false );
340}
341
342
343void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& aInheritFrom )
344{
346
347 wxArrayString symbolNames;
348 wxString lib = getTargetLib();
349
350 if( !m_libMgr->LibraryExists( lib ) )
351 {
352 lib = SelectLibraryFromList();
353
354 if( !m_libMgr->LibraryExists( lib ) )
355 return;
356 }
357
358 m_libMgr->GetSymbolNames( lib, symbolNames );
359
360 wxString _inheritSymbolName;
361 wxString _infoMessage;
362 wxString msg;
363
364 // if the symbol being inherited from isn't a root symbol, find its root symbol
365 // and use that symbol instead
366 if( !aInheritFrom.IsEmpty() )
367 {
368 LIB_SYMBOL* inheritFromSymbol = m_libMgr->GetBufferedSymbol( aInheritFrom, lib );
369
370 if( inheritFromSymbol )
371 {
372 _inheritSymbolName = aInheritFrom;
373 _infoMessage = wxString::Format( _( "Deriving from symbol '%s'." ),
374 _inheritSymbolName );
375 }
376 else
377 {
378 _inheritSymbolName = aInheritFrom;
379 }
380 }
381
382 DIALOG_LIB_NEW_SYMBOL dlg( this, _infoMessage, &symbolNames, _inheritSymbolName,
383 [&]( wxString newName )
384 {
385 if( newName.IsEmpty() )
386 {
387 wxMessageBox( _( "Symbol must have a name." ) );
388 return false;
389 }
390
391 if( !lib.empty() && m_libMgr->SymbolExists( newName, lib ) )
392 {
393 msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
394 newName,
395 lib );
396
397 KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
398 wxOK | wxCANCEL | wxICON_WARNING );
399 errorDlg.SetOKLabel( _( "Overwrite" ) );
400
401 return errorDlg.ShowModal() == wxID_OK;
402 }
403
404 return true;
405 } );
406
407 dlg.SetMinSize( dlg.GetSize() );
408
409 if( dlg.ShowModal() == wxID_CANCEL )
410 return;
411
412 wxString name = dlg.GetName();
413
414 LIB_SYMBOL new_symbol( name ); // do not create symbol on the heap, it will be buffered soon
415
416 wxString parentSymbolName = dlg.GetParentSymbolName();
417
418 if( parentSymbolName.IsEmpty() )
419 {
420 new_symbol.GetReferenceField().SetText( dlg.GetReference() );
421 new_symbol.SetUnitCount( dlg.GetUnitCount() );
422
423 // Initialize new_symbol.m_TextInside member:
424 // if 0, pin text is outside the body (on the pin)
425 // if > 0, pin text is inside the body
426 if( dlg.GetPinNameInside() )
427 {
428 new_symbol.SetPinNameOffset( dlg.GetPinTextPosition() );
429
430 if( new_symbol.GetPinNameOffset() == 0 )
431 new_symbol.SetPinNameOffset( 1 );
432 }
433 else
434 {
435 new_symbol.SetPinNameOffset( 0 );
436 }
437
438 ( dlg.GetPowerSymbol() ) ? new_symbol.SetPower() : new_symbol.SetNormal();
439 new_symbol.SetShowPinNumbers( dlg.GetShowPinNumber() );
440 new_symbol.SetShowPinNames( dlg.GetShowPinName() );
441 new_symbol.LockUnits( !dlg.GetUnitsInterchangeable() );
442 new_symbol.SetExcludedFromBOM( !dlg.GetIncludeInBom() );
443 new_symbol.SetExcludedFromBoard( !dlg.GetIncludeOnBoard() );
444
445 if( dlg.GetUnitCount() < 2 )
446 new_symbol.LockUnits( false );
447
448 new_symbol.SetHasAlternateBodyStyle( dlg.GetAlternateBodyStyle() );
449 }
450 else
451 {
452 LIB_SYMBOL* parent = m_libMgr->GetAlias( parentSymbolName, lib );
453 wxCHECK( parent, /* void */ );
454 new_symbol.SetParent( parent );
455
456 // Inherit the parent mandatory field attributes.
457 for( int id = 0; id < MANDATORY_FIELDS; ++id )
458 {
459 SCH_FIELD* field = new_symbol.GetFieldById( id );
460
461 // the MANDATORY_FIELDS are exactly that in RAM.
462 wxCHECK( field, /* void */ );
463
464 SCH_FIELD* parentField = parent->GetFieldById( id );
465
466 wxCHECK( parentField, /* void */ );
467
468 *field = *parentField;
469
470 switch( id )
471 {
472 case REFERENCE_FIELD:
473 // parent's reference already copied
474 break;
475
476 case VALUE_FIELD:
477 if( parent->IsPower() )
478 field->SetText( name );
479 break;
480
481 case FOOTPRINT_FIELD:
482 case DATASHEET_FIELD:
483 // - footprint might be the same as parent, but might not
484 // - datasheet is most likely different
485 // - probably best to play it safe and copy neither
486 field->SetText( wxEmptyString );
487 break;
488 }
489
490 field->SetParent( &new_symbol );
491 }
492 }
493
494 m_libMgr->UpdateSymbol( &new_symbol, lib );
495 SyncLibraries( false );
496 LoadSymbol( name, lib, 1 );
497
498 // must be called after loadSymbol, that calls SetShowDeMorgan, but
499 // because the symbol is empty,it looks like it has no alternate body
500 // and a derived symbol inherits its parent body.
501 if( !new_symbol.GetParent().lock() )
502 SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
503 else
505}
506
507
509{
510 wxString libName;
511
512 if( IsLibraryTreeShown() )
514
515 if( libName.empty() )
516 {
518 }
519 else if( m_libMgr->IsLibraryReadOnly( libName ) )
520 {
521 wxString msg = wxString::Format( _( "Symbol library '%s' is not writable." ),
522 libName );
523 wxString msg2 = _( "You must save to a different location." );
524
525 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) == wxID_OK )
526 saveLibrary( libName, true );
527 }
528 else
529 {
530 saveLibrary( libName, false );
531 }
532
533 if( IsLibraryTreeShown() )
535
536 UpdateTitle();
537}
538
539
541{
542 const wxString& libName = GetTargetLibId().GetLibNickname();
543
544 if( !libName.IsEmpty() )
545 {
546 saveLibrary( libName, true );
548 }
549}
550
551
553{
554 saveSymbolCopyAs( aOpenCopy );
555
557}
558
559
566static std::vector<LIB_SYMBOL_SPTR> GetParentChain( const LIB_SYMBOL& aSymbol )
567{
568 std::vector<LIB_SYMBOL_SPTR> chain( { aSymbol.SharedPtr() } );
569
570 while( chain.back()->IsAlias() )
571 {
572 LIB_SYMBOL_SPTR parent = chain.back()->GetParent().lock();
573 chain.push_back( parent );
574 }
575
576 return chain;
577}
578
579
589static std::pair<bool, bool> CheckSavingIntoOwnInheritance( LIB_SYMBOL_LIBRARY_MANAGER& aLibMgr,
590 LIB_SYMBOL& aSymbol,
591 const wxString& aNewSymbolName,
592 const wxString& aNewLibraryName )
593{
594 const wxString& oldLibraryName = aSymbol.GetLibId().GetLibNickname();
595
596 // Cannot be intersecting if in different libs
597 if( aNewLibraryName != oldLibraryName )
598 return { false, false };
599
600 // Or if the target symbol doesn't exist
601 if( !aLibMgr.SymbolExists( aNewSymbolName, aNewLibraryName ) )
602 return { false, false };
603
604 bool inAncestry = false;
605 bool inDescendents = false;
606
607 {
608 const std::vector<LIB_SYMBOL_SPTR> parentChainFromUs = GetParentChain( aSymbol );
609
610 // Ignore the leaf symbol (0) - that must match
611 for( size_t i = 1; i < parentChainFromUs.size(); ++i )
612 {
613 // Attempting to overwrite a symbol in the parental chain
614 if( parentChainFromUs[i]->GetName() == aNewSymbolName )
615 {
616 inAncestry = true;
617 break;
618 }
619 }
620 }
621
622 {
623 LIB_SYMBOL* targetSymbol = aLibMgr.GetAlias( aNewSymbolName, aNewLibraryName );
624 const std::vector<LIB_SYMBOL_SPTR> parentChainFromTarget = GetParentChain( *targetSymbol );
625 const wxString oldSymbolName = aSymbol.GetName();
626
627 // Ignore the leaf symbol - it'll match if we're saving the symbol
628 // to the same name, and that would be OK
629 for( size_t i = 1; i < parentChainFromTarget.size(); ++i )
630 {
631 if( parentChainFromTarget[i]->GetName() == oldSymbolName )
632 {
633 inDescendents = true;
634 break;
635 }
636 }
637 }
638
639 return { inAncestry, inDescendents };
640}
641
642
650static std::vector<wxString> CheckForParentalChainConflicts( LIB_SYMBOL_LIBRARY_MANAGER& aLibMgr,
651 LIB_SYMBOL& aSymbol,
652 const wxString& newSymbolName,
653 const wxString& newLibraryName )
654{
655 std::vector<wxString> conflicts;
656 const wxString& oldLibraryName = aSymbol.GetLibId().GetLibNickname();
657
658 if( newLibraryName == oldLibraryName )
659 {
660 // Saving into the same library - the only conflict could be the symbol itself
661 if( aLibMgr.SymbolExists( newSymbolName, newLibraryName ) )
662 {
663 conflicts.push_back( newSymbolName );
664 }
665 }
666 else
667 {
668 // In a different library, check the whole chain
669 const std::vector<LIB_SYMBOL_SPTR> parentChain = GetParentChain( aSymbol );
670
671 for( size_t i = 0; i < parentChain.size(); ++i )
672 {
673 if( i == 0 )
674 {
675 // This is the leaf symbol which the user actually named
676 if( aLibMgr.SymbolExists( newSymbolName, newLibraryName ) )
677 {
678 conflicts.push_back( newSymbolName );
679 }
680 }
681 else
682 {
683 LIB_SYMBOL_SPTR chainSymbol = parentChain[i];
684 if( aLibMgr.SymbolExists( chainSymbol->GetName(), newLibraryName ) )
685 {
686 conflicts.push_back( chainSymbol->GetName() );
687 }
688 }
689 }
690 }
691
692 return conflicts;
693}
694
695
703{
704public:
706 {
707 // Just overwrite any existing symbols in the target library
708 OVERWRITE,
709 // Add a suffix until we find a name that doesn't conflict
710 RENAME,
711 // Could have a mode that asks for every one, be then we'll need a fancier
712 // SAVE_AS_DIALOG subdialog with Overwrite/Rename/Prompt/Cancel
713 // PROMPT
714 };
715
717 bool aValueFollowsName ) :
718 m_libMgr( aLibMgr ), m_strategy( aStrategy ), m_valueFollowsName( aValueFollowsName )
719 {
720 }
721
722 bool DoSave( LIB_SYMBOL& symbol, const wxString& aNewSymName, const wxString& aNewLibName )
723 {
724 std::vector<LIB_SYMBOL_SPTR> parentChain;
725 // If we're saving into the same library, we don't need to check the parental chain
726 // because we can just keep the same parent symbol
727 if( aNewLibName == symbol.GetLibId().GetLibNickname().wx_str() )
728 parentChain.push_back( symbol.SharedPtr() );
729 else
730 parentChain = GetParentChain( symbol );
731
732 std::vector<wxString> newNames;
733
734 // Iterate backwards (i.e. from the root down)
735 for( int i = (int) parentChain.size() - 1; i >= 0; --i )
736 {
737 LIB_SYMBOL_SPTR& oldSymbol = parentChain[i];
738
739 LIB_SYMBOL new_symbol( *oldSymbol );
740
741 wxString newName;
742 if( i == 0 )
743 {
744 // This is the leaf symbol which the user actually named
745 newName = aNewSymName;
746 }
747 else
748 {
749 // Somewhere in the inheritance chain, use the conflict resolution strategy
750 newName = oldSymbol->GetName();
751 }
752
753 newName = resolveConflict( newName, aNewLibName );
754 new_symbol.SetName( newName );
755
757 new_symbol.GetValueField().SetText( newName );
758
759 if( i == (int) parentChain.size() - 1 )
760 {
761 // This is the root symbol
762 // Nothing extra to do, it's just a simple symbol with no parents
763 }
764 else
765 {
766 // Get the buffered new copy in the new library (with the name we gave it)
767 LIB_SYMBOL* newParent = m_libMgr.GetAlias( newNames.back(), aNewLibName );
768
769 // We should have stored this already, why didn't we get it back?
770 wxASSERT( newParent );
771 new_symbol.SetParent( newParent );
772 }
773
774 newNames.push_back( newName );
775 m_libMgr.UpdateSymbol( &new_symbol, aNewLibName );
776 }
777
778 return true;
779 }
780
781private:
782 wxString resolveConflict( const wxString& proposed, const wxString& aNewLibName ) const
783 {
784 switch( m_strategy )
785 {
787 {
788 // In an overwrite strategy, we don't care about conflicts
789 return proposed;
790 }
792 {
793 // In a rename strategy, we need to find a name that doesn't conflict
794 int suffix = 1;
795
796 while( true )
797 {
798 wxString newName = wxString::Format( "%s_%d", proposed, suffix );
799
800 if( !m_libMgr.SymbolExists( newName, aNewLibName ) )
801 return newName;
802
803 ++suffix;
804 }
805 break;
806 }
807 // No default
808 }
809
810 wxFAIL_MSG( "Invalid conflict strategy" );
811 return "";
812 }
813
817};
818
819
821{
822 ID_MAKE_NEW_LIBRARY = wxID_HIGHEST + 1,
825};
826
827
829{
830public:
832 std::function<int( const wxString& libName, const wxString& symbolName )>;
833
834 SAVE_AS_DIALOG( SYMBOL_EDIT_FRAME* aParent, const wxString& aSymbolName,
835 const wxString& aLibraryPreselect, SymLibNameValidator aValidator,
836 SYMBOL_SAVE_AS_HANDLER::CONFLICT_STRATEGY& aConflictStrategy ) :
837 EDA_LIST_DIALOG( aParent, _( "Save Symbol As" ), false ),
838 m_validator( std::move( aValidator ) ), m_conflictStrategy( aConflictStrategy )
839 {
841 PROJECT_FILE& project = aParent->Prj().GetProjectFile();
843 std::vector<wxString> libNicknames = tbl->GetLogicalLibs();
844 wxArrayString headers;
845 std::vector<wxArrayString> itemsToDisplay;
846
847 headers.Add( _( "Nickname" ) );
848 headers.Add( _( "Description" ) );
849
850 for( const wxString& nickname : libNicknames )
851 {
852 if( alg::contains( project.m_PinnedSymbolLibs, nickname )
853 || alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
854 {
855 wxArrayString item;
856 item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
857 item.Add( tbl->GetDescription( nickname ) );
858 itemsToDisplay.push_back( item );
859 }
860 }
861
862 for( const wxString& nickname : libNicknames )
863 {
864 if( !alg::contains( project.m_PinnedSymbolLibs, nickname )
865 && !alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
866 {
867 wxArrayString item;
868 item.Add( nickname );
869 item.Add( tbl->GetDescription( nickname ) );
870 itemsToDisplay.push_back( item );
871 }
872 }
873
874 initDialog( headers, itemsToDisplay, aLibraryPreselect );
875
876 SetListLabel( _( "Save in library:" ) );
877 SetOKLabel( _( "Save" ) );
878
879 wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
880
881 wxStaticText* label = new wxStaticText( this, wxID_ANY, _( "Name:" ) );
882 bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
883
884 m_symbolNameCtrl = new wxTextCtrl( this, wxID_ANY, aSymbolName );
885 bNameSizer->Add( m_symbolNameCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
886
887 wxButton* newLibraryButton = new wxButton( this, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
888 m_ButtonsSizer->Prepend( 80, 20 );
889 m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
890
891 GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
892
893 Bind( wxEVT_BUTTON,
894 [this]( wxCommandEvent& )
895 {
896 EndModal( ID_MAKE_NEW_LIBRARY );
898
899 // Move nameTextCtrl to the head of the tab-order
900 if( GetChildren().DeleteObject( m_symbolNameCtrl ) )
901 GetChildren().Insert( m_symbolNameCtrl );
902
904
906
907 Layout();
908 GetSizer()->Fit( this );
909
910 Centre();
911 }
912
913 wxString GetSymbolName()
914 {
915 wxString symbolName = m_symbolNameCtrl->GetValue();
916 symbolName.Trim( true );
917 symbolName.Trim( false );
918 symbolName.Replace( " ", "_" );
919 return symbolName;
920 }
921
922protected:
924 {
926
927 if( ret == wxID_CANCEL )
928 return false;
929
930 if( ret == ID_OVERWRITE_CONFLICTS )
932 else if( ret == ID_RENAME_CONFLICTS )
934
935 return true;
936 }
937
938private:
939 wxTextCtrl* m_symbolNameCtrl;
942};
943
944
946{
947 LIB_SYMBOL* symbol = getTargetSymbol();
948
949 if( !symbol )
950 return;
951
952 LIB_ID old_lib_id = symbol->GetLibId();
953 wxString symbolName = old_lib_id.GetLibItemName();
954 wxString libraryName = old_lib_id.GetLibNickname();
955 bool valueFollowsName = symbol->GetValueField().GetText() == symbolName;
956 wxString msg;
957 bool done = false;
958
959 // This is the function that will be called when the user clicks OK in the dialog
960 // and checks if the proposed name has problems, and asks for clarification.
961 const auto dialogValidatorFunc = [&]( const wxString& newLib, const wxString& newName ) -> int
962 {
963 if( newLib.IsEmpty() )
964 {
965 wxMessageBox( _( "A library must be specified." ) );
966 return wxID_CANCEL;
967 }
968
969 if( newName.IsEmpty() )
970 {
971 wxMessageBox( _( "Symbol must have a name." ) );
972 return wxID_CANCEL;
973 }
974
975 if( m_libMgr->IsLibraryReadOnly( newLib ) )
976 {
977 msg = wxString::Format( _( "Library '%s' is read-only. Choose a "
978 "different library to save the symbol '%s' to." ),
979 newLib, newName );
980 wxMessageBox( msg );
981 return wxID_CANCEL;
982 }
983
988 const auto& [inAncestry, inDescendents] =
989 CheckSavingIntoOwnInheritance( *m_libMgr, *symbol, newName, newLib );
990
991 if( inAncestry )
992 {
993 msg = wxString::Format( _( "Symbol '%s' cannot replace another symbol '%s' that it "
994 "descends from" ),
995 symbolName, newName );
996 wxMessageBox( msg );
997 return wxID_CANCEL;
998 }
999
1000 if( inDescendents )
1001 {
1002 msg = wxString::Format( _( "Symbol '%s' cannot replace another symbol '%s' that is "
1003 "a descendent of it." ),
1004 symbolName, newName );
1005 wxMessageBox( msg );
1006 return wxID_CANCEL;
1007 }
1008
1009 const std::vector<wxString> conflicts =
1010 CheckForParentalChainConflicts( *m_libMgr, *symbol, newName, newLib );
1011
1012 if( conflicts.size() == 1 && conflicts.front() == newName )
1013 {
1014 // The simplest case is when the symbol itself has a conflict
1015 msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'."
1016 "Do you want to overwrite it?" ),
1017 newName, newLib );
1018
1019 KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
1020 errorDlg.SetOKLabel( _( "Overwrite" ) );
1021
1022 return errorDlg.ShowModal() == wxID_OK ? ID_OVERWRITE_CONFLICTS : (int) wxID_CANCEL;
1023 }
1024 else if( !conflicts.empty() )
1025 {
1026 // If there are conflicts in the parental chain, we need to ask the user
1027 // if they want to overwrite all of them.
1028 // A more complex UI might allow the user to re-parent the symbol to an existing
1029 // symbol in the target lib, or rename all the parents somehow.
1030 msg = wxString::Format( _( "The following symbols in the inheritance chain of '%s' "
1031 "already exist in library '%s':\n" ),
1032 symbolName, newLib );
1033
1034 for( const wxString& conflict : conflicts )
1035 msg += wxString::Format( " %s\n", conflict );
1036
1037 msg += _( "\nDo you want to overwrite all of them, or rename the new symbols?" );
1038
1039 KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
1040 wxYES_NO | wxCANCEL | wxICON_WARNING );
1041 errorDlg.SetYesNoCancelLabels( _( "Overwrite All" ), _( "Rename All" ), _( "Cancel" ) );
1042
1043 switch( errorDlg.ShowModal() )
1044 {
1045 case wxID_YES: return ID_OVERWRITE_CONFLICTS;
1046 case wxID_NO: return ID_RENAME_CONFLICTS;
1047 default: break;
1048 }
1049 return wxID_CANCEL;
1050 }
1051
1052 return wxID_OK;
1053 };
1054
1056
1057 // Keep asking the user for a new name until they give a valid one or cancel the operation
1058 while( !done )
1059 {
1060 SAVE_AS_DIALOG dlg( this, symbolName, libraryName, dialogValidatorFunc, strategy );
1061
1062 int ret = dlg.ShowModal();
1063
1064 switch( ret )
1065 {
1066 case wxID_CANCEL:
1067 {
1068 return;
1069 }
1070
1071 case wxID_OK: // No conflicts
1074 {
1075 symbolName = dlg.GetSymbolName();
1076 libraryName = dlg.GetTextSelection();
1077
1078 if( ret == ID_RENAME_CONFLICTS )
1080
1081 done = true;
1082 break;
1083 }
1084
1086 {
1087 wxFileName newLibrary( AddLibraryFile( true ) );
1088 libraryName = newLibrary.GetName();
1089 break;
1090 }
1091
1092 default:
1093 break;
1094 }
1095 }
1096
1097 SYMBOL_SAVE_AS_HANDLER saver( *m_libMgr, strategy, valueFollowsName );
1098
1099 saver.DoSave( *symbol, symbolName, libraryName );
1100
1101 SyncLibraries( false );
1102
1103 if( aOpenCopy )
1104 LoadSymbol( symbolName, libraryName, 1 );
1105}
1106
1107
1109{
1110 wxCHECK( m_symbol, /* void */ );
1111
1112 wxString lib = GetCurLib();
1113
1114 if( !lib.IsEmpty() && aOldName && *aOldName != m_symbol->GetName() )
1115 {
1116 // Test the current library for name conflicts
1117 if( m_libMgr->SymbolExists( m_symbol->GetName(), lib ) )
1118 {
1119 wxString msg = wxString::Format( _( "Symbol name '%s' already in use." ),
1121
1122 DisplayErrorMessage( this, msg );
1123 m_symbol->SetName( *aOldName );
1124 }
1125 else
1126 {
1127 m_libMgr->UpdateSymbolAfterRename( m_symbol, *aOldName, lib );
1128 }
1129
1130 // Reselect the renamed symbol
1132 }
1133
1135 SetShowDeMorgan( GetCurSymbol()->Flatten()->HasAlternateBodyStyle() );
1136 UpdateTitle();
1137
1138 // N.B. The view needs to be rebuilt first as the Symbol Properties change may invalidate
1139 // the view pointers by rebuilting the field table
1140 RebuildView();
1142
1143 OnModify();
1144}
1145
1146
1148{
1149 std::vector<LIB_ID> toDelete = GetSelectedLibIds();
1150
1151 if( toDelete.empty() )
1152 toDelete.emplace_back( GetTargetLibId() );
1153
1154 for( LIB_ID& libId : toDelete )
1155 {
1156 if( m_libMgr->IsSymbolModified( libId.GetLibItemName(), libId.GetLibNickname() )
1157 && !IsOK( this, wxString::Format( _( "The symbol '%s' has been modified.\n"
1158 "Do you want to remove it from the library?" ),
1159 libId.GetUniStringLibItemName() ) ) )
1160 {
1161 continue;
1162 }
1163
1164 if( m_libMgr->HasDerivedSymbols( libId.GetLibItemName(), libId.GetLibNickname() ) )
1165 {
1166 wxString msg;
1167
1168 msg.Printf(
1169 _( "The symbol %s is used to derive other symbols.\n"
1170 "Deleting this symbol will delete all of the symbols derived from it.\n\n"
1171 "Do you wish to delete this symbol and all of its derivatives?" ),
1172 libId.GetLibItemName().wx_str() );
1173
1174 wxMessageDialog::ButtonLabel yesButtonLabel( _( "Delete Symbol" ) );
1175 wxMessageDialog::ButtonLabel noButtonLabel( _( "Keep Symbol" ) );
1176
1177 wxMessageDialog dlg( this, msg, _( "Warning" ),
1178 wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTER );
1179 dlg.SetYesNoLabels( yesButtonLabel, noButtonLabel );
1180
1181 if( dlg.ShowModal() == wxID_NO )
1182 continue;
1183 }
1184
1185 if( IsCurrentSymbol( libId ) )
1186 emptyScreen();
1187
1188 m_libMgr->RemoveSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
1189 }
1190
1192}
1193
1194
1196{
1197 std::vector<LIB_ID> symbols;
1198
1199 if( GetTreeLIBIDs( symbols ) == 0 )
1200 return;
1201
1202 STRING_FORMATTER formatter;
1203
1204 for( LIB_ID& libId : symbols )
1205 {
1206 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(),
1207 libId.GetLibNickname() );
1208
1209 if( !symbol )
1210 continue;
1211
1212 std::unique_ptr<LIB_SYMBOL> tmp = symbol->Flatten();
1213 SCH_IO_KICAD_SEXPR::FormatLibSymbol( tmp.get(), formatter );
1214 }
1215
1216 wxLogNull doNotLog; // disable logging of failed clipboard actions
1217
1218 auto clipboard = wxTheClipboard;
1219 wxClipboardLocker clipboardLock( clipboard );
1220
1221 if( !clipboardLock || !clipboard->IsOpened() )
1222 return;
1223
1224 auto data = new wxTextDataObject( wxString( formatter.GetString().c_str(), wxConvUTF8 ) );
1225 clipboard->SetData( data );
1226
1227 clipboard->Flush();
1228}
1229
1230
1231void SYMBOL_EDIT_FRAME::DuplicateSymbol( bool aFromClipboard )
1232{
1233 LIB_ID libId = GetTargetLibId();
1234 wxString lib = libId.GetLibNickname();
1235
1236 if( !m_libMgr->LibraryExists( lib ) )
1237 return;
1238
1239 std::vector<LIB_SYMBOL*> newSymbols;
1240
1241 if( aFromClipboard )
1242 {
1243 std::string clipboardData = GetClipboardUTF8();
1244
1245 try
1246 {
1247 newSymbols = SCH_IO_KICAD_SEXPR::ParseLibSymbols( clipboardData, "Clipboard" );
1248 }
1249 catch( IO_ERROR& e )
1250 {
1251 wxLogMessage( wxS( "Can not paste: %s" ), e.Problem() );
1252 }
1253 }
1254 else if( LIB_SYMBOL* srcSymbol = m_libMgr->GetBufferedSymbol( libId.GetLibItemName(), lib ) )
1255 {
1256 newSymbols.emplace_back( new LIB_SYMBOL( *srcSymbol ) );
1257
1258 // Derive from same parent.
1259 if( srcSymbol->IsAlias() )
1260 {
1261 if( std::shared_ptr<LIB_SYMBOL> srcParent = srcSymbol->GetParent().lock() )
1262 newSymbols.back()->SetParent( srcParent.get() );
1263 }
1264 }
1265
1266 if( newSymbols.empty() )
1267 return;
1268
1269 for( LIB_SYMBOL* symbol : newSymbols )
1270 {
1271 ensureUniqueName( symbol, lib );
1272 m_libMgr->UpdateSymbol( symbol, lib );
1273
1274 LoadOneLibrarySymbolAux( symbol, lib, GetUnit(), GetBodyStyle() );
1275 }
1276
1277 SyncLibraries( false );
1278 m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, newSymbols[0]->GetName() ) );
1279
1280 for( LIB_SYMBOL* symbol : newSymbols )
1281 delete symbol;
1282}
1283
1284
1285void SYMBOL_EDIT_FRAME::ensureUniqueName( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
1286{
1287 if( aSymbol )
1288 {
1289 int i = 1;
1290 wxString newName = aSymbol->GetName();
1291
1292 // Append a number to the name until the name is unique in the library.
1293 while( m_libMgr->SymbolExists( newName, aLibrary ) )
1294 newName.Printf( "%s_%d", aSymbol->GetName(), i++ );
1295
1296 aSymbol->SetName( newName );
1297 }
1298}
1299
1300
1301void SYMBOL_EDIT_FRAME::Revert( bool aConfirm )
1302{
1303 LIB_ID libId = GetTargetLibId();
1304 const wxString& libName = libId.GetLibNickname();
1305
1306 // Empty if this is the library itself that is selected.
1307 const wxString& symbolName = libId.GetLibItemName();
1308
1309 wxString msg = wxString::Format( _( "Revert '%s' to last version saved?" ),
1310 symbolName.IsEmpty() ? libName : symbolName );
1311
1312 if( aConfirm && !ConfirmRevertDialog( this, msg ) )
1313 return;
1314
1315 bool reload_currentSymbol = false;
1316 wxString curr_symbolName = symbolName;
1317
1318 if( GetCurSymbol() )
1319 {
1320 // the library itself is reverted: the current symbol will be reloaded only if it is
1321 // owned by this library
1322 if( symbolName.IsEmpty() )
1323 {
1324 LIB_ID curr_libId = GetCurSymbol()->GetLibId();
1325 reload_currentSymbol = libName == curr_libId.GetLibNickname().wx_str();
1326
1327 if( reload_currentSymbol )
1328 curr_symbolName = curr_libId.GetUniStringLibItemName();
1329 }
1330 else
1331 {
1332 reload_currentSymbol = IsCurrentSymbol( libId );
1333 }
1334 }
1335
1336 int unit = m_unit;
1337
1338 if( reload_currentSymbol )
1339 emptyScreen();
1340
1341 if( symbolName.IsEmpty() )
1342 {
1343 m_libMgr->RevertLibrary( libName );
1344 }
1345 else
1346 {
1347 libId = m_libMgr->RevertSymbol( libId.GetLibItemName(), libId.GetLibNickname() );
1348
1349 m_treePane->GetLibTree()->SelectLibId( libId );
1351 }
1352
1353 if( reload_currentSymbol && m_libMgr->SymbolExists( curr_symbolName, libName ) )
1354 LoadSymbol( curr_symbolName, libName, unit );
1355
1356 m_treePane->Refresh();
1357}
1358
1359
1361{
1362 wxCHECK_RET( m_libMgr, "Library manager object not created." );
1363
1364 Revert( false );
1366}
1367
1368
1369void SYMBOL_EDIT_FRAME::LoadSymbol( const wxString& aAlias, const wxString& aLibrary, int aUnit )
1370{
1372 {
1373 if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
1374 [&]() -> bool
1375 {
1376 return saveCurrentSymbol();
1377 } ) )
1378 {
1379 return;
1380 }
1381 }
1382
1383 LIB_SYMBOL* symbol = m_libMgr->GetBufferedSymbol( aAlias, aLibrary );
1384
1385 if( !symbol )
1386 {
1387 DisplayError( this, wxString::Format( _( "Symbol %s not found in library '%s'." ),
1388 aAlias,
1389 aLibrary ) );
1391 return;
1392 }
1393
1394 // Optimize default edit options for this symbol
1395 // Usually if units are locked, graphic items are specific to each unit
1396 // and if units are interchangeable, graphic items are common to units
1398 tools->SetDrawSpecificUnit( symbol->UnitsLocked() );
1399
1400 LoadOneLibrarySymbolAux( symbol, aLibrary, aUnit, 0 );
1401}
1402
1403
1404bool SYMBOL_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
1405{
1406 wxFileName fn;
1407 wxString msg;
1408 SYMBOL_SAVEAS_TYPE type = SYMBOL_SAVEAS_TYPE::NORMAL_SAVE_AS;
1409 SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
1410 PROJECT& prj = Prj();
1411
1413
1414 if( !aNewFile && ( aLibrary.empty() || !PROJECT_SCH::SchSymbolLibTable( &prj )->HasLibrary( aLibrary ) ) )
1415 {
1416 ShowInfoBarError( _( "No library specified." ) );
1417 return false;
1418 }
1419
1420 if( aNewFile )
1421 {
1422 SEARCH_STACK* search = PROJECT_SCH::SchSearchS( &prj );
1423
1424 // Get a new name for the library
1425 wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
1426
1427 if( !default_path )
1428 default_path = search->LastVisitedPath();
1429
1430 fn.SetName( aLibrary );
1432
1433 wxString wildcards = FILEEXT::KiCadSymbolLibFileWildcard();
1434
1435 wxFileDialog dlg( this, wxString::Format( _( "Save Library '%s' As..." ), aLibrary ),
1436 default_path, fn.GetFullName(), wildcards,
1437 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1438
1439 SYMBOL_FILEDLG_SAVE_AS saveAsHook( type );
1440 dlg.SetCustomizeHook( saveAsHook );
1441
1442 if( dlg.ShowModal() == wxID_CANCEL )
1443 return false;
1444
1445 fn = dlg.GetPath();
1446
1447 prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
1448
1449 if( fn.GetExt().IsEmpty() )
1451
1452 type = saveAsHook.GetOption();
1453 }
1454 else
1455 {
1456 fn = PROJECT_SCH::SchSymbolLibTable( &prj )->GetFullURI( aLibrary );
1458
1459 if( fileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
1460 fileType = SCH_IO_MGR::SCH_KICAD;
1461 }
1462
1463 // Verify the user has write privileges before attempting to save the library file.
1464 if( !aNewFile && m_libMgr->IsLibraryReadOnly( aLibrary ) )
1465 return false;
1466
1467 ClearMsgPanel();
1468
1469 // Copy .kicad_symb file to .bak.
1470 if( !backupFile( fn, "bak" ) )
1471 return false;
1472
1473 if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), fileType ) )
1474 {
1475 msg.Printf( _( "Failed to save changes to symbol library file '%s'." ),
1476 fn.GetFullPath() );
1477 DisplayErrorMessage( this, _( "Error Saving Library" ), msg );
1478 return false;
1479 }
1480
1481 if( !aNewFile )
1482 {
1483 m_libMgr->ClearLibraryModified( aLibrary );
1484
1485 // Update the library modification time so that we don't reload based on the watcher
1486 if( aLibrary == getTargetLib() )
1487 SetSymModificationTime( fn.GetModificationTime() );
1488 }
1489 else
1490 {
1491 bool resyncLibTree = false;
1492 wxString originalLibNickname = getTargetLib();
1493 wxString forceRefresh;
1494
1495 switch( type )
1496 {
1497 case SYMBOL_SAVEAS_TYPE::REPLACE_TABLE_ENTRY:
1498 resyncLibTree = replaceLibTableEntry( originalLibNickname, fn.GetFullPath() );
1499 forceRefresh = originalLibNickname;
1500 break;
1501
1502 case SYMBOL_SAVEAS_TYPE::ADD_GLOBAL_TABLE_ENTRY:
1503 resyncLibTree = addLibTableEntry( fn.GetFullPath() );
1504 break;
1505
1506 case SYMBOL_SAVEAS_TYPE::ADD_PROJECT_TABLE_ENTRY:
1507 resyncLibTree = addLibTableEntry( fn.GetFullPath(), PROJECT_LIB_TABLE );
1508 break;
1509
1510 default:
1511 break;
1512 }
1513
1514 if( resyncLibTree )
1515 {
1517 SyncLibraries( true, false, forceRefresh );
1519 }
1520 }
1521
1522 ClearMsgPanel();
1523 msg.Printf( _( "Symbol library file '%s' saved." ), fn.GetFullPath() );
1525
1526 return true;
1527}
1528
1529
1530bool SYMBOL_EDIT_FRAME::saveAllLibraries( bool aRequireConfirmation )
1531{
1532 wxString msg, msg2;
1533 bool doSave = true;
1534 int dirtyCount = 0;
1535 bool applyToAll = false;
1536 bool retv = true;
1537
1538 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1539 {
1540 if( m_libMgr->IsLibraryModified( libNickname ) )
1541 dirtyCount++;
1542 }
1543
1544 for( const wxString& libNickname : m_libMgr->GetLibraryNames() )
1545 {
1546 if( m_libMgr->IsLibraryModified( libNickname ) )
1547 {
1548 if( aRequireConfirmation && !applyToAll )
1549 {
1550 msg.Printf( _( "Save changes to '%s' before closing?" ), libNickname );
1551
1552 switch( UnsavedChangesDialog( this, msg, dirtyCount > 1 ? &applyToAll : nullptr ) )
1553 {
1554 case wxID_YES: doSave = true; break;
1555 case wxID_NO: doSave = false; break;
1556 default:
1557 case wxID_CANCEL: return false;
1558 }
1559 }
1560
1561 if( doSave )
1562 {
1563 // If saving under existing name fails then do a Save As..., and if that
1564 // fails then cancel close action.
1565 if( m_libMgr->IsLibraryReadOnly( libNickname ) )
1566 {
1567 msg.Printf( _( "Symbol library '%s' is not writable." ), libNickname );
1568 msg2 = _( "You must save to a different location." );
1569
1570 if( dirtyCount == 1 )
1571 {
1572 if( OKOrCancelDialog( this, _( "Warning" ), msg, msg2 ) != wxID_OK )
1573 {
1574 retv = false;
1575 continue;
1576 }
1577 }
1578 else
1579 {
1580 m_infoBar->Dismiss();
1581 m_infoBar->ShowMessageFor( msg + wxS( " " ) + msg2,
1582 2000, wxICON_EXCLAMATION );
1583
1584 while( m_infoBar->IsShownOnScreen() )
1585 wxSafeYield();
1586
1587 retv = false;
1588 continue;
1589 }
1590 }
1591 else if( saveLibrary( libNickname, false ) )
1592 {
1593 continue;
1594 }
1595
1596 if( !saveLibrary( libNickname, true ) )
1597 retv = false;
1598 }
1599 }
1600 }
1601
1602 UpdateTitle();
1603 return retv;
1604}
1605
1606
1608{
1610
1611 if( !m_symbol )
1612 return;
1613
1614 wxString msg = m_symbol->GetName();
1615
1616 AppendMsgPanel( _( "Name" ), UnescapeString( msg ), 8 );
1617
1618 if( m_symbol->IsAlias() )
1619 {
1620 LIB_SYMBOL_SPTR parent = m_symbol->GetParent().lock();
1621
1622 msg = parent ? parent->GetName() : _( "Undefined!" );
1623 AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 );
1624 }
1625
1626 static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
1627 msg = UnitLetter[m_unit];
1628
1629 AppendMsgPanel( _( "Unit" ), msg, 8 );
1630
1631 if( m_bodyStyle == BODY_STYLE::DEMORGAN )
1632 msg = _( "Alternate" );
1633 else if( m_bodyStyle == BODY_STYLE::BASE )
1634 msg = _( "Standard" );
1635 else
1636 msg = wxT( "?" );
1637
1638 AppendMsgPanel( _( "Body" ), msg, 8 );
1639
1640 if( m_symbol->IsPower() )
1641 msg = _( "Power Symbol" );
1642 else
1643 msg = _( "Symbol" );
1644
1645 AppendMsgPanel( _( "Type" ), msg, 8 );
1646 AppendMsgPanel( _( "Description" ), m_symbol->GetDescription(), 8 );
1647 AppendMsgPanel( _( "Keywords" ), m_symbol->GetKeyWords() );
1648 AppendMsgPanel( _( "Datasheet" ), m_symbol->GetDatasheetField().GetText() );
1649}
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:94
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:46
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:1563
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:406
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
bool IsValid() const
Check if this LID_ID is valid.
Definition: lib_id.h:172
wxString GetUniStringLibId() const
Definition: lib_id.h:148
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition: lib_id.h:112
const wxString GetUniStringLibNickname() const
Definition: lib_id.h:88
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
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:1212
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:436
const std::string & GetString()
Definition: richio.h:459
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:595
This file is part of the common library.
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
Definition: lib_symbol.h:46
@ ALL
All except INITIAL_ADD.
Definition: view_item.h:58
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
STL namespace.
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp: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.