KiCad PCB EDA Suite
symbol_library_manager.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) 2017 CERN
5 * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Maciej Suminski <[email protected]>
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 3
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 * https://www.gnu.org/licenses/gpl-3.0.html
21 * or you may search the http://www.gnu.org website for the version 3 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
27#include <symbol_library.h>
29#include <symbol_edit_frame.h>
30#include <env_paths.h>
31#include <pgm_base.h>
32#include <kiway.h>
33#include <profile.h>
34#include <wx_filename.h>
35#include <sch_io_mgr.h>
37#include <symbol_lib_table.h>
38#include <symbol_async_loader.h>
39#include <progress_reporter.h>
40#include <list>
41#include <locale_io.h>
42#include <wx/log.h>
43#include <string_utils.h>
44#include "lib_logger.h"
45
46
48 m_frame( aFrame )
49{
50 m_logger = new LIB_LOGGER();
51}
52
53
55{
56 delete m_logger;
57}
58
59
61{
62 SYMBOL_ASYNC_LOADER loader( symTable()->GetLogicalLibs(), symTable(), false, nullptr,
63 &aReporter );
64
65 LOCALE_IO toggle;
66
67 loader.Start();
68
69 while( !loader.Done() )
70 {
71 if( !aReporter.KeepRefreshing() )
72 break;
73
74 wxMilliSleep( 33 /* 30 FPS refresh rate */ );
75 }
76
77 loader.Join();
78
79 if( !loader.GetErrors().IsEmpty() )
80 {
81 HTML_MESSAGE_BOX dlg( &m_frame, _( "Load Error" ) );
82
83 dlg.MessageSet( _( "Errors loading symbols:" ) );
84
85 wxString msg = loader.GetErrors();
86 msg.Replace( "\n", "<BR>" );
87
88 dlg.AddHTML_Text( msg );
89 dlg.ShowModal();
90 }
91}
92
93
95{
96 for( const std::pair<const wxString, LIB_BUFFER>& lib : m_libs )
97 {
98 if( lib.second.IsModified() )
99 return true;
100 }
101
102 return false;
103}
104
105
107{
108 int hash = symTable()->GetModifyHash();
109
110 for( const std::pair<const wxString, LIB_BUFFER>& lib : m_libs )
111 hash += lib.second.GetHash();
112
113 return hash;
114}
115
116
117int SYMBOL_LIBRARY_MANAGER::GetLibraryHash( const wxString& aLibrary ) const
118{
119 const auto libBufIt = m_libs.find( aLibrary );
120
121 if( libBufIt != m_libs.end() )
122 return libBufIt->second.GetHash();
123
124 SYMBOL_LIB_TABLE_ROW* row = GetLibrary( aLibrary );
125
126 // return -1 if library does not exist or 0 if not modified
127 return row ? std::hash<std::string>{}( aLibrary.ToStdString() +
128 row->GetFullURI( true ).ToStdString() ) : -1;
129}
130
131
133{
134 wxArrayString res;
135
136 for( const wxString& libName : symTable()->GetLogicalLibs() )
137 res.Add( libName );
138
139 return res;
140}
141
142
144{
145 SYMBOL_LIB_TABLE_ROW* row = nullptr;
146
147 try
148 {
149 row = symTable()->FindRow( aLibrary, true );
150 }
151 catch( const IO_ERROR& e )
152 {
153 wxLogMessage( _( "Library '%s' not found in the Symbol Library Table." ) + e.What(),
154 aLibrary );
155 }
156
157 return row;
158}
159
160
161bool SYMBOL_LIBRARY_MANAGER::SaveLibrary( const wxString& aLibrary, const wxString& aFileName,
162 SCH_IO_MGR::SCH_FILE_T aFileType )
163{
164 wxCHECK( aFileType != SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY && LibraryExists( aLibrary ), false );
165 wxFileName fn( aFileName );
166 wxCHECK( !fn.FileExists() || fn.IsFileWritable(), false );
167 SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( aFileType ) );
168 bool res = true; // assume all libraries are successfully saved
169
170 PROPERTIES properties;
171 properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
172
173 auto it = m_libs.find( aLibrary );
174
175 if( it != m_libs.end() )
176 {
177 // Handle buffered library
178 LIB_BUFFER& libBuf = it->second;
179
180 const auto& symbolBuffers = libBuf.GetBuffers();
181
182 for( const auto& symbolBuf : symbolBuffers )
183 {
184 if( !libBuf.SaveBuffer( symbolBuf, aFileName, &*pi, true ) )
185 {
186 // Something went wrong, but try to save other libraries
187 res = false;
188 }
189 }
190
191 // clear the deleted symbols buffer only if data is saved to the original file
192 wxFileName original, destination( aFileName );
193 auto row = GetLibrary( aLibrary );
194
195 if( row )
196 {
197
198 }
199
200 destination.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
201
202 if( res && original == destination )
203 libBuf.ClearDeletedBuffer();
204 }
205 else
206 {
207 // Handle original library
208 for( LIB_SYMBOL* symbol : getOriginalSymbols( aLibrary ) )
209 {
210 LIB_SYMBOL* newSymbol;
211
212 try
213 {
214 if( symbol->IsAlias() )
215 {
216 std::shared_ptr< LIB_SYMBOL > oldParent = symbol->GetParent().lock();
217
218 wxCHECK_MSG( oldParent, false,
219 wxString::Format( wxT( "Derived symbol '%s' found with undefined parent." ),
220 symbol->GetName() ) );
221
222 LIB_SYMBOL* libParent = pi->LoadSymbol( aLibrary, oldParent->GetName(),
223 &properties );
224
225 if( !libParent )
226 {
227 libParent = new LIB_SYMBOL( *oldParent.get() );
228 pi->SaveSymbol( aLibrary, libParent, &properties );
229 }
230
231 newSymbol = new LIB_SYMBOL( *symbol );
232 newSymbol->SetParent( libParent );
233 pi->SaveSymbol( aLibrary, newSymbol, &properties );
234 }
235 else if( !pi->LoadSymbol( aLibrary, symbol->GetName(), &properties ) )
236 {
237 pi->SaveSymbol( aLibrary, new LIB_SYMBOL( *symbol ), &properties );
238 }
239 }
240 catch( ... )
241 {
242 res = false;
243 break;
244 }
245 }
246 }
247
248 try
249 {
250 pi->SaveLibrary( aFileName );
251 }
252 catch( ... )
253 {
254 // return false because something happens.
255 // The library is not successfully saved
256 res = false;
257 }
258
259 return res;
260}
261
262
263bool SYMBOL_LIBRARY_MANAGER::IsLibraryModified( const wxString& aLibrary ) const
264{
265 auto it = m_libs.find( aLibrary );
266 return it != m_libs.end() ? it->second.IsModified() : false;
267}
268
269
270bool SYMBOL_LIBRARY_MANAGER::IsSymbolModified( const wxString& aAlias,
271 const wxString& aLibrary ) const
272{
273 auto libIt = m_libs.find( aLibrary );
274
275 if( libIt == m_libs.end() )
276 return false;
277
278 const LIB_BUFFER& buf = libIt->second;
279 const std::shared_ptr<SYMBOL_LIBRARY_MANAGER::SYMBOL_BUFFER> symbolBuf = buf.GetBuffer( aAlias );
280 return symbolBuf ? symbolBuf->IsModified() : false;
281}
282
283
284void SYMBOL_LIBRARY_MANAGER::SetSymbolModified( const wxString& aAlias,
285 const wxString& aLibrary )
286{
287 auto libIt = m_libs.find( aLibrary );
288
289 if( libIt == m_libs.end() )
290 return;
291
292 const LIB_BUFFER& buf = libIt->second;
293 std::shared_ptr<SYMBOL_LIBRARY_MANAGER::SYMBOL_BUFFER> symbolBuf = buf.GetBuffer( aAlias );
294 symbolBuf->GetScreen()->SetContentModified();
295}
296
297
298bool SYMBOL_LIBRARY_MANAGER::ClearLibraryModified( const wxString& aLibrary ) const
299{
300 auto libIt = m_libs.find( aLibrary );
301
302 if( libIt == m_libs.end() )
303 return false;
304
305 for( auto& symbolBuf : libIt->second.GetBuffers() )
306 {
307 SCH_SCREEN* screen = symbolBuf->GetScreen();
308
309 if( screen )
310 screen->SetContentModified( false );
311 }
312
313 return true;
314}
315
316
318 const wxString& aLibrary ) const
319{
320 auto libI = m_libs.find( aLibrary );
321
322 if( libI == m_libs.end() )
323 return false;
324
325 auto symbolBuf = libI->second.GetBuffer( aAlias );
326 wxCHECK( symbolBuf, false );
327
328 symbolBuf->GetScreen()->SetContentModified( false );
329 return true;
330}
331
332
333bool SYMBOL_LIBRARY_MANAGER::IsLibraryReadOnly( const wxString& aLibrary ) const
334{
335 wxCHECK( LibraryExists( aLibrary ), true );
336
337 return !symTable()->IsSymbolLibWritable( aLibrary );
338}
339
340
341bool SYMBOL_LIBRARY_MANAGER::IsLibraryLoaded( const wxString& aLibrary ) const
342{
343 wxCHECK( LibraryExists( aLibrary ), false );
344
345 return symTable()->IsSymbolLibLoaded( aLibrary );
346}
347
348
349std::list<LIB_SYMBOL*> SYMBOL_LIBRARY_MANAGER::GetAliases( const wxString& aLibrary ) const
350{
351 std::list<LIB_SYMBOL*> ret;
352 wxCHECK( LibraryExists( aLibrary ), ret );
353
354 auto libIt = m_libs.find( aLibrary );
355
356 if( libIt != m_libs.end() )
357 {
358 for( auto& symbolBuf : libIt->second.GetBuffers() )
359 {
360 ret.push_back( symbolBuf->GetSymbol() );
361 }
362 }
363 else
364 {
365 std::vector<LIB_SYMBOL*> aliases;
366
367 try
368 {
369 symTable()->LoadSymbolLib( aliases, aLibrary );
370 }
371 catch( const IO_ERROR& e )
372 {
373 wxLogWarning( e.Problem() );
374 }
375
376 std::copy( aliases.begin(), aliases.end(), std::back_inserter( ret ) );
377 }
378
379 return ret;
380}
381
382
384 const wxString& aLibrary )
385{
386 wxCHECK( LibraryExists( aLibrary ), nullptr );
387
388 // try the library buffers first
389 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
390 LIB_SYMBOL* bufferedSymbol = libBuf.GetSymbol( aAlias );
391
392 if( !bufferedSymbol ) // no buffer symbol found
393 {
394 // create a copy of the symbol
395 try
396 {
397 LIB_SYMBOL* symbol = symTable()->LoadSymbol( aLibrary, aAlias );
398
399 if( symbol == nullptr )
400 THROW_IO_ERROR( _( "Symbol not found." ) );
401
402 LIB_SYMBOL* bufferedParent = nullptr;
403
404 // Create parent symbols on demand so parent symbol can be set.
405 if( symbol->IsAlias() )
406 {
407 std::shared_ptr< LIB_SYMBOL > parent = symbol->GetParent().lock();
408 wxCHECK_MSG( parent, nullptr,
409 wxString::Format( "Derived symbol '%s' found with undefined parent.",
410 symbol->GetName() ) );
411
412 // Check if the parent symbol buffer has already be created.
413 bufferedParent = libBuf.GetSymbol( parent->GetName() );
414
415 if( !bufferedParent )
416 {
417 bufferedParent = new LIB_SYMBOL( *parent.get() );
418 libBuf.CreateBuffer( bufferedParent, new SCH_SCREEN );
419 }
420 }
421
422 bufferedSymbol = new LIB_SYMBOL( *symbol );
423
424 if( bufferedParent )
425 bufferedSymbol->SetParent( bufferedParent );
426
427 libBuf.CreateBuffer( bufferedSymbol, new SCH_SCREEN );
428 }
429 catch( const IO_ERROR& e )
430 {
431 wxLogMessage( _( "Error loading symbol %s from library '%s'. (%s)" ),
432 aAlias, aLibrary, e.What() );
433 bufferedSymbol = nullptr;
434 }
435 }
436
437 return bufferedSymbol;
438}
439
440
441SCH_SCREEN* SYMBOL_LIBRARY_MANAGER::GetScreen( const wxString& aAlias, const wxString& aLibrary )
442{
443 wxCHECK( LibraryExists( aLibrary ), nullptr );
444 wxCHECK( !aAlias.IsEmpty(), nullptr );
445 auto it = m_libs.find( aLibrary );
446 wxCHECK( it != m_libs.end(), nullptr );
447
448 LIB_BUFFER& buf = it->second;
449 auto symbolBuf = buf.GetBuffer( aAlias );
450 return symbolBuf ? symbolBuf->GetScreen() : nullptr;
451}
452
453
454bool SYMBOL_LIBRARY_MANAGER::UpdateSymbol( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
455{
456 wxCHECK( LibraryExists( aLibrary ), false );
457 wxCHECK( aSymbol, false );
458 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
459 auto symbolBuf = libBuf.GetBuffer( aSymbol->GetName() );
460
461 if( symbolBuf ) // Existing symbol.
462 {
463 LIB_SYMBOL* bufferedSymbol = const_cast< LIB_SYMBOL* >( symbolBuf->GetSymbol() );
464
465 wxCHECK( bufferedSymbol, false );
466
467 *bufferedSymbol = *aSymbol;
468 symbolBuf->GetScreen()->SetContentModified();
469 }
470 else // New symbol
471 {
472 LIB_SYMBOL* symbolCopy = new LIB_SYMBOL( *aSymbol, nullptr );
473
474 symbolCopy->SetLibId( LIB_ID( aLibrary, aSymbol->GetLibId().GetLibItemName() ) );
475
476 SCH_SCREEN* screen = new SCH_SCREEN;
477 libBuf.CreateBuffer( symbolCopy, screen );
478 screen->SetContentModified();
479 }
480
481 return true;
482}
483
484
485bool SYMBOL_LIBRARY_MANAGER::UpdateSymbolAfterRename( LIB_SYMBOL* aSymbol, const wxString& aOldName,
486 const wxString& aLibrary )
487{
488 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
489 auto symbolBuf = libBuf.GetBuffer( aOldName );
490
491 wxCHECK( symbolBuf, false );
492
493 libBuf.UpdateBuffer( symbolBuf, aSymbol );
495
496 return true;
497}
498
499
500bool SYMBOL_LIBRARY_MANAGER::FlushSymbol( const wxString& aAlias, const wxString& aLibrary )
501{
502 auto it = m_libs.find( aLibrary );
503
504 if( it == m_libs.end() ) // no items to flush
505 return true;
506
507 auto symbolBuf = it->second.GetBuffer( aAlias );
508 wxCHECK( symbolBuf, false );
509
510 return it->second.SaveBuffer( symbolBuf, symTable() );
511}
512
513
514LIB_ID SYMBOL_LIBRARY_MANAGER::RevertSymbol( const wxString& aAlias, const wxString& aLibrary )
515{
516 auto it = m_libs.find( aLibrary );
517
518 if( it == m_libs.end() ) // no items to flush
519 return LIB_ID( aLibrary, aAlias );
520
521 auto symbolBuf = it->second.GetBuffer( aAlias );
522 wxCHECK( symbolBuf, LIB_ID( aLibrary, aAlias ) );
523 LIB_SYMBOL original( *symbolBuf->GetOriginal() );
524
525 if( original.GetName() != aAlias )
526 {
527 UpdateSymbolAfterRename( &original, aAlias, aLibrary );
528 }
529 else
530 {
531 symbolBuf->SetSymbol( new LIB_SYMBOL( original ) );
533 }
534
535 return LIB_ID( aLibrary, original.GetName() );
536}
537
538
539bool SYMBOL_LIBRARY_MANAGER::RevertLibrary( const wxString& aLibrary )
540{
541 auto it = m_libs.find( aLibrary );
542
543 if( it == m_libs.end() ) // nothing to reverse
544 return false;
545
546 m_libs.erase( it );
548
549 return true;
550}
551
552
554{
555 bool retv = true;
556
557 // Nothing to revert.
558 if( GetHash() == 0 )
559 return true;
560
561 for( const auto& lib : m_libs )
562 {
563 if( !lib.second.IsModified() )
564 continue;
565
566 for( const auto& buffer : lib.second.GetBuffers() )
567 {
568 if( !buffer->IsModified() )
569 continue;
570
571 RevertSymbol( lib.first, buffer->GetOriginal()->GetName() );
572 }
573 }
574
575 return retv;
576}
577
578
579bool SYMBOL_LIBRARY_MANAGER::RemoveSymbol( const wxString& aAlias, const wxString& aLibrary )
580{
581 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
582 auto symbolBuf = libBuf.GetBuffer( aAlias );
583 wxCHECK( symbolBuf, false );
584
585 bool retv = true;
586
587 retv &= libBuf.DeleteBuffer( symbolBuf );
589
590 return retv;
591}
592
593
595 const wxString& aLibrary ) const
596{
597 // Try the library buffers first
598 auto libIt = m_libs.find( aLibrary );
599
600 if( libIt != m_libs.end() )
601 {
602 LIB_SYMBOL* symbol = libIt->second.GetSymbol( aAlias );
603
604 if( symbol )
605 return symbol;
606 }
607
608 // Get the original symbol
609 LIB_SYMBOL* alias = nullptr;
610
611 try
612 {
613 alias = symTable()->LoadSymbol( aLibrary, aAlias );
614 }
615 catch( const IO_ERROR& e )
616 {
617 wxLogMessage( _( "Cannot load symbol '%s' from library '%s'." ) + e.What(),
618 aAlias,
619 aLibrary );
620 }
621
622 return alias;
623}
624
625
626bool SYMBOL_LIBRARY_MANAGER::SymbolExists( const wxString& aAlias, const wxString& aLibrary ) const
627{
628 auto libBufIt = m_libs.find( aLibrary );
629 LIB_SYMBOL* alias = nullptr;
630
631 if( libBufIt != m_libs.end() )
632 return !!libBufIt->second.GetBuffer( aAlias );
633
634 try
635 {
636 alias = symTable()->LoadSymbol( aLibrary, aAlias );
637 }
638 catch( IO_ERROR& )
639 {
640 // checking if certain symbol exists, so its absence is perfectly fine
641 }
642
643 return alias != nullptr;
644}
645
646
647bool SYMBOL_LIBRARY_MANAGER::LibraryExists( const wxString& aLibrary, bool aCheckEnabled ) const
648{
649 if( aLibrary.IsEmpty() )
650 return false;
651
652 if( m_libs.count( aLibrary ) > 0 )
653 return true;
654
655 return symTable()->HasLibrary( aLibrary, aCheckEnabled );
656}
657
658
660{
661 wxString name = "New_Library";
662
663 if( !LibraryExists( name ) )
664 return name;
665
666 name += "_";
667
668 for( unsigned int i = 0; i < std::numeric_limits<unsigned int>::max(); ++i )
669 {
670 if( !LibraryExists( name + wxString::Format( "%u", i ) ) )
671 return name + wxString::Format( "%u", i );
672 }
673
674 wxFAIL;
675 return wxEmptyString;
676}
677
678
679void SYMBOL_LIBRARY_MANAGER::GetRootSymbolNames( const wxString& aLibraryName,
680 wxArrayString& aRootSymbolNames )
681{
682 LIB_BUFFER& libBuf = getLibraryBuffer( aLibraryName );
683
684 libBuf.GetRootSymbolNames( aRootSymbolNames );
685}
686
687
688bool SYMBOL_LIBRARY_MANAGER:: HasDerivedSymbols( const wxString& aSymbolName,
689 const wxString& aLibraryName )
690{
691 LIB_BUFFER& libBuf = getLibraryBuffer( aLibraryName );
692
693 return libBuf.HasDerivedSymbols( aSymbolName );
694}
695
696
698{
699 return symTable()->GetLogicalLibs().size();
700}
701
702
703wxString SYMBOL_LIBRARY_MANAGER::getLibraryName( const wxString& aFilePath )
704{
705 wxFileName fn( aFilePath );
706 return fn.GetName();
707}
708
709
710bool SYMBOL_LIBRARY_MANAGER::addLibrary( const wxString& aFilePath, bool aCreate,
711 SYMBOL_LIB_TABLE* aTable )
712{
713 wxCHECK( aTable, false );
714 wxString libName = getLibraryName( aFilePath );
715 wxCHECK( !LibraryExists( libName ), false ); // either create or add an existing one
716
717 // try to use path normalized to an environmental variable or project path
718 wxString relPath = NormalizePath( aFilePath, &Pgm().GetLocalEnvVariables(), &m_frame.Prj() );
719
720 SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aFilePath );
721 wxString typeName = SCH_IO_MGR::ShowType( schFileType );
722 SYMBOL_LIB_TABLE_ROW* libRow = new SYMBOL_LIB_TABLE_ROW( libName, relPath, typeName );
723 aTable->InsertRow( libRow );
724
725 if( aCreate )
726 {
727 wxCHECK( schFileType != SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY, false );
728
729 try
730 {
731 aTable->CreateSymbolLib( libName );
732 }
733 catch( const IO_ERROR& )
734 {
735 aTable->RemoveRow( libRow );
736 return false;
737 }
738 }
739
741
742 return true;
743}
744
745
747{
748 return m_frame.Prj().SchSymbolLibTable();
749}
750
751
752std::set<LIB_SYMBOL*> SYMBOL_LIBRARY_MANAGER::getOriginalSymbols( const wxString& aLibrary )
753{
754 std::set<LIB_SYMBOL*> symbols;
755 wxCHECK( LibraryExists( aLibrary ), symbols );
756
757 try
758 {
759 wxArrayString aliases;
760 symTable()->EnumerateSymbolLib( aLibrary, aliases );
761
762 for( const auto& aliasName : aliases )
763 {
764 LIB_SYMBOL* alias = symTable()->LoadSymbol( aLibrary, aliasName );
765 symbols.insert( alias );
766 }
767 }
768 catch( const IO_ERROR& e )
769 {
770 wxLogMessage( _( "Cannot enumerate library '%s'." ) + e.What(), aLibrary );
771 }
772
773 return symbols;
774}
775
776
778 const wxString& aLibrary )
779{
780 auto it = m_libs.find( aLibrary );
781
782 if( it != m_libs.end() )
783 return it->second;
784
785 // The requested buffer does not exist yet, so create one
786 auto ret = m_libs.emplace( aLibrary, LIB_BUFFER( aLibrary ) );
787 LIB_BUFFER& buf = ret.first->second;
788
789 for( auto symbol : getOriginalSymbols( aLibrary ) )
790 {
791 LIB_SYMBOL* newSymbol;
792
793 if( symbol->IsAlias() )
794 {
795 std::shared_ptr< LIB_SYMBOL > oldParent = symbol->GetParent().lock();
796
797 wxCHECK_MSG( oldParent, buf,
798 wxString::Format( "Derived symbol '%s' found with undefined parent.",
799 symbol->GetName() ) );
800
801 LIB_SYMBOL* libParent = buf.GetSymbol( oldParent->GetName() );
802
803 if( !libParent )
804 {
805 libParent = new LIB_SYMBOL( *oldParent.get() );
806 buf.CreateBuffer( libParent, new SCH_SCREEN );
807 }
808
809 newSymbol = new LIB_SYMBOL( *symbol );
810 newSymbol->SetParent( libParent );
811 buf.CreateBuffer( newSymbol, new SCH_SCREEN );
812 }
813 else if( !buf.GetSymbol( symbol->GetName() ) )
814 {
815 buf.CreateBuffer( new LIB_SYMBOL( *symbol ), new SCH_SCREEN );
816 }
817 }
818
819 return buf;
820}
821
822
824 std::unique_ptr<SCH_SCREEN> aScreen ) :
825 m_screen( std::move( aScreen ) ),
826 m_symbol( aSymbol )
827{
828 m_original = new LIB_SYMBOL( *aSymbol );
829}
830
831
833{
834 delete m_symbol;
835 delete m_original;
836}
837
838
840{
841 wxCHECK( m_symbol != aSymbol, /* void */ );
842 wxASSERT( aSymbol );
843 delete m_symbol;
844 m_symbol = aSymbol;
845
846 // If the symbol moves libraries then the original moves with it
847 if( m_original->GetLibId().GetLibNickname() != m_symbol->GetLibId().GetLibNickname() )
848 {
849 m_original->SetLibId( LIB_ID( m_symbol->GetLibId().GetLibNickname(),
850 m_original->GetLibId().GetLibItemName() ) );
851 }
852}
853
854
856{
857 wxCHECK( m_original != aSymbol, /* void */ );
858 wxASSERT( aSymbol );
859 delete m_original;
860 m_original = aSymbol;
861
862 // The original is not allowed to have a different library than its symbol
863 if( m_original->GetLibId().GetLibNickname() != m_symbol->GetLibId().GetLibNickname() )
864 {
865 m_original->SetLibId( LIB_ID( m_symbol->GetLibId().GetLibNickname(),
866 m_original->GetLibId().GetLibItemName() ) );
867 }
868}
869
870
872{
873 return m_screen && m_screen->IsContentModified();
874}
875
876
878{
879 auto buf = GetBuffer( aAlias );
880
881 if( !buf )
882 return nullptr;
883
884 LIB_SYMBOL* symbol = buf->GetSymbol();
885
886 wxCHECK( symbol, nullptr );
887
888 return symbol;
889}
890
891
893{
894 wxASSERT( aCopy );
895 wxASSERT( aCopy->GetLib() == nullptr );
896 std::unique_ptr<SCH_SCREEN> screen( aScreen );
897 auto symbolBuf = std::make_shared<SYMBOL_BUFFER>( aCopy, std::move( screen ) );
898 m_symbols.push_back( symbolBuf );
899
900 // Set the parent library name,
901 // otherwise it is empty as no library has been given as the owner during object construction
902 LIB_ID libId = aCopy->GetLibId();
903 libId.SetLibNickname( m_libName );
904 aCopy->SetLibId( libId );
905 ++m_hash;
906
907 return true;
908}
909
910
911bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::UpdateBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf,
912 LIB_SYMBOL* aCopy )
913{
914 wxCHECK( aCopy && aSymbolBuf, false );
915
916 LIB_SYMBOL* bufferedSymbol = aSymbolBuf->GetSymbol();
917
918 wxCHECK( bufferedSymbol, false );
919
920 *bufferedSymbol = *aCopy;
921 ++m_hash;
922
923 return true;
924}
925
926
927bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::DeleteBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf )
928{
929 auto symbolBufIt = std::find( m_symbols.begin(), m_symbols.end(), aSymbolBuf );
930 wxCHECK( symbolBufIt != m_symbols.end(), false );
931
932 bool retv = true;
933
934 // Remove all derived symbols to prevent broken inheritance.
935 if( aSymbolBuf->GetSymbol()->IsRoot() && HasDerivedSymbols( aSymbolBuf->GetSymbol()->GetName() )
936 && removeChildSymbols( aSymbolBuf ) == 0 )
937 {
938 retv = false;
939 }
940
941 m_deleted.emplace_back( *symbolBufIt );
942 m_symbols.erase( symbolBufIt );
943 ++m_hash;
944
945 return retv;
946}
947
948
949bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf,
950 SYMBOL_LIB_TABLE* aLibTable )
951{
952 wxCHECK( aSymbolBuf, false );
953 LIB_SYMBOL* libSymbol = aSymbolBuf->GetSymbol();
954 LIB_SYMBOL* originalSymbol = aSymbolBuf->GetOriginal();
955 wxCHECK( libSymbol && originalSymbol, false );
957 PROPERTIES properties;
958 properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
959
960 wxString errorMsg = _( "Error saving symbol %s to library '%s'." ) + wxS( "\n%s" );
961
962 // Delete the original symbol if the symbol name has been changed.
963 if( libSymbol->GetName() != originalSymbol->GetName() )
964 {
965 // DeleteSymbol may throw
966 try
967 {
968 if( aLibTable->LoadSymbol( m_libName, originalSymbol->GetName() ) )
969 aLibTable->DeleteSymbol( m_libName, originalSymbol->GetName() );
970 }
971 catch( const IO_ERROR& ioe )
972 {
973 wxLogError( errorMsg, UnescapeString( originalSymbol->GetName() ), m_libName,
974 ioe.What() );
975 return false;
976 }
977 }
978
979 if( libSymbol->IsAlias() )
980 {
981 LIB_SYMBOL* newCachedSymbol = new LIB_SYMBOL( *libSymbol );
982 std::shared_ptr< LIB_SYMBOL > bufferedParent = libSymbol->GetParent().lock();
983
984 wxCHECK( bufferedParent, false );
985
986 LIB_SYMBOL* cachedParent = aLibTable->LoadSymbol( m_libName, bufferedParent->GetName() );
987
988 if( !cachedParent )
989 {
990 cachedParent = new LIB_SYMBOL( *bufferedParent.get() );
991 newCachedSymbol->SetParent( cachedParent );
992 result = aLibTable->SaveSymbol( m_libName, cachedParent );
993 wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
994 result = aLibTable->SaveSymbol( m_libName, newCachedSymbol );
995 wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
996
997 LIB_SYMBOL* originalParent = new LIB_SYMBOL( *bufferedParent.get() );
998 aSymbolBuf->SetOriginal( originalParent );
999 originalSymbol = new LIB_SYMBOL( *libSymbol );
1000 originalSymbol->SetParent( originalParent );
1001 aSymbolBuf->SetOriginal( originalSymbol );
1002 }
1003 else
1004 {
1005 newCachedSymbol->SetParent( cachedParent );
1006 result = aLibTable->SaveSymbol( m_libName, newCachedSymbol );
1007 wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
1008
1009 auto originalBufferedParent = GetBuffer( bufferedParent->GetName() );
1010 wxCHECK( originalBufferedParent, false );
1011 originalSymbol = new LIB_SYMBOL( *libSymbol );
1012 originalSymbol->SetParent( originalBufferedParent->GetSymbol() );
1013 aSymbolBuf->SetOriginal( originalSymbol );
1014 }
1015 }
1016 else
1017 {
1018 wxArrayString derivedSymbols;
1019
1020 if( GetDerivedSymbolNames( libSymbol->GetName(), derivedSymbols ) == 0 )
1021 {
1022 result = aLibTable->SaveSymbol( m_libName, new LIB_SYMBOL( *libSymbol ) );
1023 wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
1024 aSymbolBuf->SetOriginal( new LIB_SYMBOL( *libSymbol ) );
1025 }
1026 else
1027 {
1028 LIB_SYMBOL* parentSymbol = new LIB_SYMBOL( *libSymbol );
1029
1030 aLibTable->SaveSymbol( m_libName, parentSymbol );
1031
1032 for( auto& entry : derivedSymbols )
1033 {
1034 std::shared_ptr<SYMBOL_BUFFER> symbol = GetBuffer( entry );
1035
1036 wxCHECK2( symbol, continue );
1037
1038 LIB_SYMBOL* derivedSymbol = new LIB_SYMBOL( *symbol->GetSymbol() );
1039 derivedSymbol->SetParent( parentSymbol );
1040 result = aLibTable->SaveSymbol( m_libName, derivedSymbol );
1041 wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
1042 }
1043 }
1044 }
1045
1046 ++m_hash;
1047 return true;
1048}
1049
1050
1051bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf,
1052 const wxString& aFileName,
1053 SCH_PLUGIN* aPlugin, bool aBuffer )
1054{
1055 wxCHECK( aSymbolBuf, false );
1056 LIB_SYMBOL* libSymbol = aSymbolBuf->GetSymbol();
1057 LIB_SYMBOL* originalSymbol = aSymbolBuf->GetOriginal();
1058 wxCHECK( libSymbol && originalSymbol, false );
1059 wxCHECK( !aFileName.IsEmpty(), false );
1060
1061 wxString errorMsg = _( "Error saving symbol %s to library '%s'." ) + wxS( "\n%s" );
1062
1063 // set properties to prevent save file on every symbol save
1064 PROPERTIES properties;
1065 properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
1066
1067 // Delete the original symbol if the symbol name has been changed.
1068 if( libSymbol->GetName() != originalSymbol->GetName() )
1069 {
1070 try
1071 {
1072 if( aPlugin->LoadSymbol( aFileName, originalSymbol->GetName() ) )
1073 aPlugin->DeleteSymbol( aFileName, originalSymbol->GetName(), &properties );
1074 }
1075 catch( const IO_ERROR& ioe )
1076 {
1077 wxLogError( errorMsg, UnescapeString( originalSymbol->GetName() ), aFileName,
1078 ioe.What() );
1079 return false;
1080 }
1081 }
1082
1083 if( libSymbol->IsAlias() )
1084 {
1085 LIB_SYMBOL* newCachedSymbol = new LIB_SYMBOL( *libSymbol );
1086 std::shared_ptr< LIB_SYMBOL > bufferedParent = libSymbol->GetParent().lock();
1087
1088 wxCHECK( bufferedParent, false );
1089
1090 LIB_SYMBOL* cachedParent = nullptr;
1091
1092 try
1093 {
1094 cachedParent = aPlugin->LoadSymbol( aFileName, bufferedParent->GetName() );
1095 }
1096 catch( const IO_ERROR& )
1097 {
1098 return false;
1099 }
1100
1101 if( !cachedParent )
1102 {
1103 cachedParent = new LIB_SYMBOL( *bufferedParent.get() );
1104 newCachedSymbol->SetParent( cachedParent );
1105
1106 try
1107 {
1108 aPlugin->SaveSymbol( aFileName, cachedParent, aBuffer ? &properties : nullptr );
1109 }
1110 catch( const IO_ERROR& ioe )
1111 {
1112 wxLogError( errorMsg, UnescapeString( cachedParent->GetName() ), aFileName,
1113 ioe.What() );
1114 return false;
1115 }
1116
1117 try
1118 {
1119 aPlugin->SaveSymbol( aFileName, newCachedSymbol, aBuffer ? &properties : nullptr );
1120 }
1121 catch( const IO_ERROR& ioe )
1122 {
1123 wxLogError( errorMsg, UnescapeString( newCachedSymbol->GetName() ), aFileName,
1124 ioe.What() );
1125 return false;
1126 }
1127
1128 LIB_SYMBOL* originalParent = new LIB_SYMBOL( *bufferedParent.get() );
1129 aSymbolBuf->SetOriginal( originalParent );
1130 originalSymbol = new LIB_SYMBOL( *libSymbol );
1131 originalSymbol->SetParent( originalParent );
1132 aSymbolBuf->SetOriginal( originalSymbol );
1133 }
1134 else
1135 {
1136 newCachedSymbol->SetParent( cachedParent );
1137
1138 try
1139 {
1140 aPlugin->SaveSymbol( aFileName, newCachedSymbol, aBuffer ? &properties : nullptr );
1141 }
1142 catch( const IO_ERROR& ioe )
1143 {
1144 wxLogError( errorMsg, UnescapeString( newCachedSymbol->GetName() ), aFileName,
1145 ioe.What() );
1146 return false;
1147 }
1148
1149 auto originalBufferedParent = GetBuffer( bufferedParent->GetName() );
1150 wxCHECK( originalBufferedParent, false );
1151 originalSymbol = new LIB_SYMBOL( *libSymbol );
1152 originalSymbol->SetParent( originalBufferedParent->GetSymbol() );
1153 aSymbolBuf->SetOriginal( originalSymbol );
1154 }
1155 }
1156 else
1157 {
1158 wxArrayString derivedSymbols;
1159
1160 if( GetDerivedSymbolNames( libSymbol->GetName(), derivedSymbols ) == 0 )
1161 {
1162 try
1163 {
1164 aPlugin->SaveSymbol( aFileName, new LIB_SYMBOL( *libSymbol ),
1165 aBuffer ? &properties : nullptr );
1166 }
1167 catch( const IO_ERROR& ioe )
1168 {
1169 wxLogError( errorMsg, UnescapeString( libSymbol->GetName() ), aFileName,
1170 ioe.What() );
1171 return false;
1172 }
1173
1174 aSymbolBuf->SetOriginal( new LIB_SYMBOL( *libSymbol ) );
1175 }
1176 else
1177 {
1178 LIB_SYMBOL* parentSymbol = new LIB_SYMBOL( *libSymbol );
1179
1180 // Save the modified root symbol.
1181 try
1182 {
1183 aPlugin->SaveSymbol( aFileName, parentSymbol, aBuffer ? &properties : nullptr );
1184 }
1185 catch( const IO_ERROR& ioe )
1186 {
1187 wxLogError( errorMsg, UnescapeString( libSymbol->GetName() ), aFileName,
1188 ioe.What() );
1189 return false;
1190 }
1191
1192 aSymbolBuf->SetOriginal( new LIB_SYMBOL( *libSymbol ) );
1193
1194 // Save the derived symbols.
1195 for( const wxString& entry : derivedSymbols )
1196 {
1197 std::shared_ptr<SYMBOL_BUFFER> symbol = GetBuffer( entry );
1198
1199 wxCHECK2( symbol, continue );
1200
1201 LIB_SYMBOL* derivedSymbol = new LIB_SYMBOL( *symbol->GetSymbol() );
1202 derivedSymbol->SetParent( parentSymbol );
1203
1204 try
1205 {
1206 aPlugin->SaveSymbol( aFileName, new LIB_SYMBOL( *derivedSymbol ),
1207 aBuffer ? &properties : nullptr );
1208 }
1209 catch( const IO_ERROR& ioe )
1210 {
1211 wxLogError( errorMsg, UnescapeString( derivedSymbol->GetName() ), aFileName,
1212 ioe.What() );
1213 return false;
1214 }
1215 }
1216 }
1217 }
1218
1219 ++m_hash;
1220 return true;
1221}
1222
1223
1224std::shared_ptr<SYMBOL_LIBRARY_MANAGER::SYMBOL_BUFFER>
1226{
1227 for( std::shared_ptr<SYMBOL_LIBRARY_MANAGER::SYMBOL_BUFFER> entry : m_symbols )
1228 {
1229 if( entry->GetSymbol()->GetName() == aAlias )
1230 return entry;
1231 }
1232
1233 return std::shared_ptr<SYMBOL_BUFFER>( nullptr );
1234}
1235
1236
1237bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::HasDerivedSymbols( const wxString& aParentName ) const
1238{
1239 for( auto& entry : m_symbols )
1240 {
1241 if( entry->GetSymbol()->IsAlias() )
1242 {
1243 LIB_SYMBOL_SPTR parent = entry->GetSymbol()->GetParent().lock();
1244
1245 // Check for inherited symbol without a valid parent.
1246 wxCHECK( parent, false );
1247
1248 if( parent->GetName() == aParentName )
1249 return true;
1250 }
1251 }
1252
1253 return false;
1254}
1255
1256
1257void SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::GetRootSymbolNames( wxArrayString& aRootSymbolNames )
1258{
1259 for( auto& entry : m_symbols )
1260 {
1261 if( entry->GetSymbol()->IsAlias() )
1262 continue;
1263
1264 aRootSymbolNames.Add( UnescapeString( entry->GetSymbol()->GetName() ) );
1265 }
1266}
1267
1268
1270 wxArrayString& aList )
1271{
1272 wxCHECK( !aSymbolName.IsEmpty(), 0 );
1273
1274 for( auto& entry : m_symbols )
1275 {
1276 if( entry->GetSymbol()->IsAlias() )
1277 {
1278 LIB_SYMBOL_SPTR parent = entry->GetSymbol()->GetParent().lock();
1279
1280 // Check for inherited symbol without a valid parent.
1281 wxCHECK( parent, false );
1282
1283 if( parent->GetName() == aSymbolName )
1284 aList.Add( entry->GetSymbol()->GetName() );
1285 }
1286 }
1287
1288 return aList.GetCount();
1289}
1290
1291
1292int SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::removeChildSymbols( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf )
1293{
1294 wxCHECK( aSymbolBuf && aSymbolBuf->GetSymbol()->IsRoot(), 0 );
1295
1296 int cnt = 0;
1297 std::deque< std::shared_ptr<SYMBOL_BUFFER> >::iterator it = m_symbols.begin();
1298
1299 while( it != m_symbols.end() )
1300 {
1301
1302 if( (*it)->GetSymbol()->IsRoot() )
1303 {
1304 ++it;
1305 }
1306 else
1307 {
1308 LIB_SYMBOL_SPTR parent = (*it)->GetSymbol()->GetParent().lock();
1309
1310 wxCHECK2( parent, ++it; continue );
1311
1312 if( parent->GetName() == aSymbolBuf->GetSymbol()->GetName() )
1313 {
1314 wxCHECK2( parent == aSymbolBuf->GetSymbol()->SharedPtr(), ++it; continue );
1315
1316 m_deleted.emplace_back( *it );
1317 it = m_symbols.erase( it );
1318 cnt++;
1319 }
1320 else
1321 {
1322 ++it;
1323 }
1324 }
1325 }
1326
1327 return cnt;
1328}
const char * name
Definition: DXF_plotter.cpp:56
void SetContentModified(bool aModified=true)
Definition: base_screen.h:59
void MessageSet(const wxString &message)
Add a message (in bold) to message list.
void AddHTML_Text(const wxString &message)
Add HTML text (without any change) to message list.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
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
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:98
const UTF8 & GetLibItemName() const
Definition: lib_id.h:101
Define a library symbol object.
Definition: lib_symbol.h:98
bool IsAlias() const
Definition: lib_symbol.h:183
LIB_ID GetLibId() const override
Definition: lib_symbol.h:139
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:451
wxString GetName() const override
Definition: lib_symbol.h:136
SYMBOL_LIB * GetLib() const
Definition: lib_symbol.h:187
void SetLibId(const LIB_ID &aLibId)
Definition: lib_symbol.h:140
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:125
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
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.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
bool RemoveRow(const LIB_TABLE_ROW *aRow)
Removes a row from the table.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:41
A progress reporter interface for use in multi-threaded environments.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
A name/value tuple with unique names and optional values.
Definition: properties.h:34
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
static const wxString ShowType(SCH_FILE_T aFileType)
Return a brief name for a plugin, given aFileType enum.
Definition: sch_io_mgr.cpp:81
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath)
Return a plugin type given a symbol library using the file extension of aLibPath.
Definition: sch_io_mgr.cpp:156
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
Helper object to release a SCH_PLUGIN in the context of a potential thrown exception through its dest...
Definition: sch_io_mgr.h:535
Base class that schematic file and library loading and saving plugins should derive from.
Definition: sch_io_mgr.h:155
virtual void DeleteSymbol(const wxString &aLibraryPath, const wxString &aSymbolName, const PROPERTIES *aProperties=nullptr)
Delete the entire LIB_SYMBOL associated with aAliasName from the library aLibraryPath.
Definition: sch_plugin.cpp:102
virtual void SaveLibrary(const wxString &aFileName, const PROPERTIES *aProperties=nullptr)
Definition: sch_plugin.cpp:45
virtual LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aPartName, const PROPERTIES *aProperties=nullptr)
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
Definition: sch_plugin.cpp:85
virtual void SaveSymbol(const wxString &aLibraryPath, const LIB_SYMBOL *aSymbol, const PROPERTIES *aProperties=nullptr)
Write aSymbol to an existing library located at aLibraryPath.
Definition: sch_plugin.cpp:94
bool Done()
Returns a string containing any errors generated during the load.
const wxString & GetErrors() const
Represents a pair of <nickname, loaded parts list>
void Start()
Spins up threads to load all the libraries in m_nicknames.
bool Join()
Finalizes the threads and combines the output into the target output map.
LIB_SYMBOL * GetSymbol(const wxString &aAlias) const
Create a new buffer to store a symbol. LIB_BUFFER takes ownership of aCopy.
void ClearDeletedBuffer()
Save stored modifications to Symbol Lib Table.
bool HasDerivedSymbols(const wxString &aParentName) const
Check to see any symbols in the buffer are derived from a parent named aParentName.
bool SaveBuffer(std::shared_ptr< SYMBOL_BUFFER > aSymbolBuf, SYMBOL_LIB_TABLE *aLibTable)
Save stored modifications using a plugin.
void GetRootSymbolNames(wxArrayString &aRootSymbolNames)
Fetch a list of root symbols names from the library buffer.
const std::deque< std::shared_ptr< SYMBOL_BUFFER > > & GetBuffers() const
int removeChildSymbols(std::shared_ptr< SYMBOL_BUFFER > aSymbolBuf)
Remove all symbols derived from aParent from the library buffer.
std::shared_ptr< SYMBOL_BUFFER > GetBuffer(const wxString &aAlias) const
Return all buffered symbols.
bool UpdateBuffer(std::shared_ptr< SYMBOL_BUFFER > aSymbolBuf, LIB_SYMBOL *aCopy)
bool DeleteBuffer(std::shared_ptr< SYMBOL_BUFFER > aSymbolBuf)
bool CreateBuffer(LIB_SYMBOL *aCopy, SCH_SCREEN *aScreen)
Update the buffered symbol with the contents of aCopy.
size_t GetDerivedSymbolNames(const wxString &aSymbolName, wxArrayString &aList)
Fetch all of the symbols derived from a aSymbolName into aList.
SYMBOL_BUFFER(LIB_SYMBOL *aSymbol=nullptr, std::unique_ptr< SCH_SCREEN > aScreen=nullptr)
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 addLibrary(const wxString &aFilePath, bool aCreate, SYMBOL_LIB_TABLE *aTable)
Return the current Symbol Library Table.
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.
void SetSymbolModified(const wxString &aAlias, const wxString &aLibrary)
void GetRootSymbolNames(const wxString &aLibName, wxArrayString &aRootSymbolNames)
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).
wxString GetUniqueLibraryName() const
Return a library name that is not currently in use.
bool RemoveSymbol(const wxString &aName, const wxString &aLibrary)
Remove the symbol from the symbol buffer.
static wxString getLibraryName(const wxString &aFilePath)
Helper function to add either existing or create new library.
LIB_BUFFER & getLibraryBuffer(const wxString &aLibrary)
Return an existing library buffer or creates one to using Symbol Library Table to get the original da...
virtual void OnDataChanged() const
Extract library name basing on the file name.
bool IsSymbolModified(const wxString &aAlias, const wxString &aLibrary) const
Return true if symbol has unsaved modifications.
bool IsLibraryLoaded(const wxString &aLibrary) const
Return true if the library was successfully loaded.
SYMBOL_LIB_TABLE * symTable() const
Class to store a working copy of a LIB_SYMBOL object and editor context.
bool RevertLibrary(const wxString &aLibrary)
Revert unsaved changes for a symbolicular library.
std::set< LIB_SYMBOL * > getOriginalSymbols(const wxString &aLibrary)
Return a set of LIB_SYMBOL objects belonging to the original library.
int GetLibraryHash(const wxString &aLibrary) const
Return a library hash value to determine if it has changed.
void Preload(PROGRESS_REPORTER &aReporter)
Preloads all symbol libraries in the symbol library table using SYMBOL_ASYNC_LOADER.
bool RevertAll()
Revert all pending changes.
SYMBOL_LIBRARY_MANAGER(SCH_BASE_FRAME &aFrame)
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.
SCH_BASE_FRAME & m_frame
Parent frame.
std::list< LIB_SYMBOL * > GetAliases(const wxString &aLibrary) const
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.
std::map< wxString, LIB_BUFFER > m_libs
bool FlushSymbol(const wxString &aAlias, const wxString &aLibrary)
Save symbol changes to the library copy used by the schematic editor.
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_PLUGIN obje...
void LoadSymbolLib(std::vector< LIB_SYMBOL * > &aAliasList, const wxString &aNickname, bool aPowerSymbolsOnly=false)
void DeleteSymbol(const wxString &aNickname, const wxString &aSymbolName)
Deletes the aSymbolName from the library given by aNickname.
bool IsSymbolLibWritable(const wxString &aNickname)
Return true if the library given by aNickname is writable.
bool IsSymbolLibLoaded(const wxString &aNickname)
Return true if the library given by aNickname was successfully loaded.
void CreateSymbolLib(const wxString &aNickname)
void EnumerateSymbolLib(const wxString &aNickname, wxArrayString &aAliasNames, bool aPowerSymbolsOnly=false)
Return a list of symbol alias names contained within the library given by aNickname.
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
SAVE_T SaveSymbol(const wxString &aNickname, const LIB_SYMBOL *aSymbol, bool aOverwrite=true)
Write aSymbol to an existing library given by aNickname.
SAVE_T
The set of return values from SaveSymbol() below.
SYMBOL_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an SYMBOL_LIB_TABLE_ROW if aNickName is found in this table or in any chained fallBack table f...
#define _(s)
wxString NormalizePath(const wxFileName &aFilePath, const ENV_VAR_MAP *aEnvVars, const wxString &aProjectPath)
Normalize a file path to an environmental variable, if possible.
Definition: env_paths.cpp:71
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
Definition: lib_symbol.h:44
Definition: bitmap.cpp:64
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 & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
wxString UnescapeString(const wxString &aSource)
Definition for symbol library class.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:38