KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 {
138 // Database libraries are hidden from the symbol editor at the moment
139 if( GetLibrary( libName )->SchLibType() == SCH_IO_MGR::SCH_DATABASE )
140 continue;
141
142 res.Add( libName );
143 }
144
145 return res;
146}
147
148
150{
151 SYMBOL_LIB_TABLE_ROW* row = nullptr;
152
153 try
154 {
155 row = symTable()->FindRow( aLibrary, true );
156 }
157 catch( const IO_ERROR& e )
158 {
159 wxLogMessage( _( "Library '%s' not found in the Symbol Library Table." ) + e.What(),
160 aLibrary );
161 }
162
163 return row;
164}
165
166
167bool SYMBOL_LIBRARY_MANAGER::SaveLibrary( const wxString& aLibrary, const wxString& aFileName,
168 SCH_IO_MGR::SCH_FILE_T aFileType )
169{
170 wxCHECK( aFileType != SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY && LibraryExists( aLibrary ), false );
171 wxFileName fn( aFileName );
172 wxCHECK( !fn.FileExists() || fn.IsFileWritable(), false );
173 SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( aFileType ) );
174 bool res = true; // assume all libraries are successfully saved
175
176 STRING_UTF8_MAP properties;
177 properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
178
179 auto it = m_libs.find( aLibrary );
180
181 if( it != m_libs.end() )
182 {
183 // Handle buffered library
184 LIB_BUFFER& libBuf = it->second;
185
186 const auto& symbolBuffers = libBuf.GetBuffers();
187
188 for( const auto& symbolBuf : symbolBuffers )
189 {
190 if( !libBuf.SaveBuffer( symbolBuf, aFileName, &*pi, true ) )
191 {
192 // Something went wrong, but try to save other libraries
193 res = false;
194 }
195 }
196
197 // clear the deleted symbols buffer only if data is saved to the original file
198 wxFileName original, destination( aFileName );
199 SYMBOL_LIB_TABLE_ROW* row = GetLibrary( aLibrary );
200
201 if( row )
202 {
203 original = row->GetFullURI();
204 original.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
205 }
206
207 destination.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
208
209 if( res && original == destination )
210 libBuf.ClearDeletedBuffer();
211 }
212 else
213 {
214 // Handle original library
215 for( LIB_SYMBOL* symbol : getOriginalSymbols( aLibrary ) )
216 {
217 LIB_SYMBOL* newSymbol;
218
219 try
220 {
221 if( symbol->IsAlias() )
222 {
223 std::shared_ptr< LIB_SYMBOL > oldParent = symbol->GetParent().lock();
224
225 wxCHECK_MSG( oldParent, false,
226 wxString::Format( wxT( "Derived symbol '%s' found with undefined parent." ),
227 symbol->GetName() ) );
228
229 LIB_SYMBOL* libParent = pi->LoadSymbol( aLibrary, oldParent->GetName(),
230 &properties );
231
232 if( !libParent )
233 {
234 libParent = new LIB_SYMBOL( *oldParent.get() );
235 pi->SaveSymbol( aLibrary, libParent, &properties );
236 }
237
238 newSymbol = new LIB_SYMBOL( *symbol );
239 newSymbol->SetParent( libParent );
240 pi->SaveSymbol( aLibrary, newSymbol, &properties );
241 }
242 else if( !pi->LoadSymbol( aLibrary, symbol->GetName(), &properties ) )
243 {
244 pi->SaveSymbol( aLibrary, new LIB_SYMBOL( *symbol ), &properties );
245 }
246 }
247 catch( ... )
248 {
249 res = false;
250 break;
251 }
252 }
253 }
254
255 try
256 {
257 pi->SaveLibrary( aFileName );
258 }
259 catch( ... )
260 {
261 // return false because something happens.
262 // The library is not successfully saved
263 res = false;
264 }
265
266 return res;
267}
268
269
270bool SYMBOL_LIBRARY_MANAGER::IsLibraryModified( const wxString& aLibrary ) const
271{
272 auto it = m_libs.find( aLibrary );
273 return it != m_libs.end() ? it->second.IsModified() : false;
274}
275
276
277bool SYMBOL_LIBRARY_MANAGER::IsSymbolModified( const wxString& aAlias,
278 const wxString& aLibrary ) const
279{
280 auto libIt = m_libs.find( aLibrary );
281
282 if( libIt == m_libs.end() )
283 return false;
284
285 const LIB_BUFFER& buf = libIt->second;
286 const std::shared_ptr<SYMBOL_LIBRARY_MANAGER::SYMBOL_BUFFER> symbolBuf = buf.GetBuffer( aAlias );
287 return symbolBuf ? symbolBuf->IsModified() : false;
288}
289
290
291void SYMBOL_LIBRARY_MANAGER::SetSymbolModified( const wxString& aAlias,
292 const wxString& aLibrary )
293{
294 auto libIt = m_libs.find( aLibrary );
295
296 if( libIt == m_libs.end() )
297 return;
298
299 const LIB_BUFFER& buf = libIt->second;
300 std::shared_ptr<SYMBOL_LIBRARY_MANAGER::SYMBOL_BUFFER> symbolBuf = buf.GetBuffer( aAlias );
301
302 wxCHECK( symbolBuf, /* void */ );
303
304 symbolBuf->GetScreen()->SetContentModified();
305}
306
307
308bool SYMBOL_LIBRARY_MANAGER::ClearLibraryModified( const wxString& aLibrary ) const
309{
310 auto libIt = m_libs.find( aLibrary );
311
312 if( libIt == m_libs.end() )
313 return false;
314
315 for( auto& symbolBuf : libIt->second.GetBuffers() )
316 {
317 SCH_SCREEN* screen = symbolBuf->GetScreen();
318
319 if( screen )
320 screen->SetContentModified( false );
321 }
322
323 return true;
324}
325
326
328 const wxString& aLibrary ) const
329{
330 auto libI = m_libs.find( aLibrary );
331
332 if( libI == m_libs.end() )
333 return false;
334
335 auto symbolBuf = libI->second.GetBuffer( aAlias );
336 wxCHECK( symbolBuf, false );
337
338 symbolBuf->GetScreen()->SetContentModified( false );
339 return true;
340}
341
342
343bool SYMBOL_LIBRARY_MANAGER::IsLibraryReadOnly( const wxString& aLibrary ) const
344{
345 wxCHECK( LibraryExists( aLibrary ), true );
346
347 return !symTable()->IsSymbolLibWritable( aLibrary );
348}
349
350
351bool SYMBOL_LIBRARY_MANAGER::IsLibraryLoaded( const wxString& aLibrary ) const
352{
353 wxCHECK( LibraryExists( aLibrary ), false );
354
355 return symTable()->IsSymbolLibLoaded( aLibrary );
356}
357
358
359std::list<LIB_SYMBOL*> SYMBOL_LIBRARY_MANAGER::GetAliases( const wxString& aLibrary ) const
360{
361 std::list<LIB_SYMBOL*> ret;
362 wxCHECK( LibraryExists( aLibrary ), ret );
363
364 auto libIt = m_libs.find( aLibrary );
365
366 if( libIt != m_libs.end() )
367 {
368 for( auto& symbolBuf : libIt->second.GetBuffers() )
369 {
370 ret.push_back( symbolBuf->GetSymbol() );
371 }
372 }
373 else
374 {
375 std::vector<LIB_SYMBOL*> aliases;
376
377 try
378 {
379 symTable()->LoadSymbolLib( aliases, aLibrary );
380 }
381 catch( const IO_ERROR& e )
382 {
383 wxLogWarning( e.Problem() );
384 }
385
386 std::copy( aliases.begin(), aliases.end(), std::back_inserter( ret ) );
387 }
388
389 return ret;
390}
391
392
394 const wxString& aLibrary )
395{
396 wxCHECK( LibraryExists( aLibrary ), nullptr );
397
398 // try the library buffers first
399 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
400 LIB_SYMBOL* bufferedSymbol = libBuf.GetSymbol( aAlias );
401
402 if( !bufferedSymbol ) // no buffer symbol found
403 {
404 // create a copy of the symbol
405 try
406 {
407 LIB_SYMBOL* symbol = symTable()->LoadSymbol( aLibrary, aAlias );
408
409 if( symbol == nullptr )
410 THROW_IO_ERROR( _( "Symbol not found." ) );
411
412 LIB_SYMBOL* bufferedParent = nullptr;
413
414 // Create parent symbols on demand so parent symbol can be set.
415 if( symbol->IsAlias() )
416 {
417 std::shared_ptr< LIB_SYMBOL > parent = symbol->GetParent().lock();
418 wxCHECK_MSG( parent, nullptr,
419 wxString::Format( "Derived symbol '%s' found with undefined parent.",
420 symbol->GetName() ) );
421
422 // Check if the parent symbol buffer has already be created.
423 bufferedParent = libBuf.GetSymbol( parent->GetName() );
424
425 if( !bufferedParent )
426 {
427 bufferedParent = new LIB_SYMBOL( *parent.get() );
428 libBuf.CreateBuffer( bufferedParent, new SCH_SCREEN );
429 }
430 }
431
432 bufferedSymbol = new LIB_SYMBOL( *symbol );
433
434 if( bufferedParent )
435 bufferedSymbol->SetParent( bufferedParent );
436
437 libBuf.CreateBuffer( bufferedSymbol, new SCH_SCREEN );
438 }
439 catch( const IO_ERROR& e )
440 {
441 wxLogMessage( _( "Error loading symbol %s from library '%s'. (%s)" ),
442 aAlias, aLibrary, e.What() );
443 bufferedSymbol = nullptr;
444 }
445 }
446
447 return bufferedSymbol;
448}
449
450
451SCH_SCREEN* SYMBOL_LIBRARY_MANAGER::GetScreen( const wxString& aAlias, const wxString& aLibrary )
452{
453 wxCHECK( LibraryExists( aLibrary ), nullptr );
454 wxCHECK( !aAlias.IsEmpty(), nullptr );
455 auto it = m_libs.find( aLibrary );
456 wxCHECK( it != m_libs.end(), nullptr );
457
458 LIB_BUFFER& buf = it->second;
459 auto symbolBuf = buf.GetBuffer( aAlias );
460 return symbolBuf ? symbolBuf->GetScreen() : nullptr;
461}
462
463
464bool SYMBOL_LIBRARY_MANAGER::UpdateSymbol( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
465{
466 wxCHECK( LibraryExists( aLibrary ), false );
467 wxCHECK( aSymbol, false );
468 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
469 auto symbolBuf = libBuf.GetBuffer( aSymbol->GetName() );
470
471 if( symbolBuf ) // Existing symbol.
472 {
473 LIB_SYMBOL* bufferedSymbol = const_cast< LIB_SYMBOL* >( symbolBuf->GetSymbol() );
474
475 wxCHECK( bufferedSymbol, false );
476
477 *bufferedSymbol = *aSymbol;
478 symbolBuf->GetScreen()->SetContentModified();
479 }
480 else // New symbol
481 {
482 LIB_SYMBOL* symbolCopy = new LIB_SYMBOL( *aSymbol, nullptr );
483
484 symbolCopy->SetLibId( LIB_ID( aLibrary, aSymbol->GetLibId().GetLibItemName() ) );
485
486 SCH_SCREEN* screen = new SCH_SCREEN;
487 libBuf.CreateBuffer( symbolCopy, screen );
488 screen->SetContentModified();
489 }
490
491 return true;
492}
493
494
495bool SYMBOL_LIBRARY_MANAGER::UpdateSymbolAfterRename( LIB_SYMBOL* aSymbol, const wxString& aOldName,
496 const wxString& aLibrary )
497{
498 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
499 auto symbolBuf = libBuf.GetBuffer( aOldName );
500
501 wxCHECK( symbolBuf, false );
502
503 libBuf.UpdateBuffer( symbolBuf, aSymbol );
505
506 return true;
507}
508
509
510bool SYMBOL_LIBRARY_MANAGER::FlushSymbol( const wxString& aAlias, const wxString& aLibrary )
511{
512 auto it = m_libs.find( aLibrary );
513
514 if( it == m_libs.end() ) // no items to flush
515 return true;
516
517 auto symbolBuf = it->second.GetBuffer( aAlias );
518 wxCHECK( symbolBuf, false );
519
520 return it->second.SaveBuffer( symbolBuf, symTable() );
521}
522
523
524LIB_ID SYMBOL_LIBRARY_MANAGER::RevertSymbol( const wxString& aAlias, const wxString& aLibrary )
525{
526 auto it = m_libs.find( aLibrary );
527
528 if( it == m_libs.end() ) // no items to flush
529 return LIB_ID( aLibrary, aAlias );
530
531 auto symbolBuf = it->second.GetBuffer( aAlias );
532 wxCHECK( symbolBuf, LIB_ID( aLibrary, aAlias ) );
533 LIB_SYMBOL original( *symbolBuf->GetOriginal() );
534
535 if( original.GetName() != aAlias )
536 {
537 UpdateSymbolAfterRename( &original, aAlias, aLibrary );
538 }
539 else
540 {
541 // copy the initial data to the current symbol to restore
542 *symbolBuf->GetSymbol() = original;
544 }
545
546 return LIB_ID( aLibrary, original.GetName() );
547}
548
549
550bool SYMBOL_LIBRARY_MANAGER::RevertLibrary( const wxString& aLibrary )
551{
552 auto it = m_libs.find( aLibrary );
553
554 if( it == m_libs.end() ) // nothing to reverse
555 return false;
556
557 m_libs.erase( it );
559
560 return true;
561}
562
563
565{
566 bool retv = true;
567
568 // Nothing to revert.
569 if( GetHash() == 0 )
570 return true;
571
572 for( const auto& lib : m_libs )
573 {
574 if( !lib.second.IsModified() )
575 continue;
576
577 for( const auto& buffer : lib.second.GetBuffers() )
578 {
579 if( !buffer->IsModified() )
580 continue;
581
582 RevertSymbol( lib.first, buffer->GetOriginal()->GetName() );
583 }
584 }
585
586 return retv;
587}
588
589
590bool SYMBOL_LIBRARY_MANAGER::RemoveSymbol( const wxString& aAlias, const wxString& aLibrary )
591{
592 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
593 auto symbolBuf = libBuf.GetBuffer( aAlias );
594 wxCHECK( symbolBuf, false );
595
596 bool retv = true;
597
598 retv &= libBuf.DeleteBuffer( symbolBuf );
600
601 return retv;
602}
603
604
606 const wxString& aLibrary ) const
607{
608 // Try the library buffers first
609 auto libIt = m_libs.find( aLibrary );
610
611 if( libIt != m_libs.end() )
612 {
613 LIB_SYMBOL* symbol = libIt->second.GetSymbol( aAlias );
614
615 if( symbol )
616 return symbol;
617 }
618
619 // Get the original symbol
620 LIB_SYMBOL* alias = nullptr;
621
622 try
623 {
624 alias = symTable()->LoadSymbol( aLibrary, aAlias );
625 }
626 catch( const IO_ERROR& e )
627 {
628 wxLogMessage( _( "Cannot load symbol '%s' from library '%s'." ) + e.What(),
629 aAlias,
630 aLibrary );
631 }
632
633 return alias;
634}
635
636
637bool SYMBOL_LIBRARY_MANAGER::SymbolExists( const wxString& aAlias, const wxString& aLibrary ) const
638{
639 auto libBufIt = m_libs.find( aLibrary );
640 LIB_SYMBOL* alias = nullptr;
641
642 if( libBufIt != m_libs.end() )
643 return !!libBufIt->second.GetBuffer( aAlias );
644
645 try
646 {
647 alias = symTable()->LoadSymbol( aLibrary, aAlias );
648 }
649 catch( IO_ERROR& )
650 {
651 // checking if certain symbol exists, so its absence is perfectly fine
652 }
653
654 return alias != nullptr;
655}
656
657
658bool SYMBOL_LIBRARY_MANAGER::LibraryExists( const wxString& aLibrary, bool aCheckEnabled ) const
659{
660 if( aLibrary.IsEmpty() )
661 return false;
662
663 if( m_libs.count( aLibrary ) > 0 )
664 return true;
665
666 return symTable()->HasLibrary( aLibrary, aCheckEnabled );
667}
668
669
671{
672 wxString name = "New_Library";
673
674 if( !LibraryExists( name ) )
675 return name;
676
677 name += "_";
678
679 for( unsigned int i = 0; i < std::numeric_limits<unsigned int>::max(); ++i )
680 {
681 if( !LibraryExists( name + wxString::Format( "%u", i ) ) )
682 return name + wxString::Format( "%u", i );
683 }
684
685 wxFAIL;
686 return wxEmptyString;
687}
688
689
690void SYMBOL_LIBRARY_MANAGER::GetRootSymbolNames( const wxString& aLibraryName,
691 wxArrayString& aRootSymbolNames )
692{
693 LIB_BUFFER& libBuf = getLibraryBuffer( aLibraryName );
694
695 libBuf.GetRootSymbolNames( aRootSymbolNames );
696}
697
698
699bool SYMBOL_LIBRARY_MANAGER:: HasDerivedSymbols( const wxString& aSymbolName,
700 const wxString& aLibraryName )
701{
702 LIB_BUFFER& libBuf = getLibraryBuffer( aLibraryName );
703
704 return libBuf.HasDerivedSymbols( aSymbolName );
705}
706
707
709{
710 return symTable()->GetLogicalLibs().size();
711}
712
713
714wxString SYMBOL_LIBRARY_MANAGER::getLibraryName( const wxString& aFilePath )
715{
716 wxFileName fn( aFilePath );
717 return fn.GetName();
718}
719
720
721bool SYMBOL_LIBRARY_MANAGER::addLibrary( const wxString& aFilePath, bool aCreate,
722 SYMBOL_LIB_TABLE* aTable )
723{
724 wxCHECK( aTable, false );
725 wxString libName = getLibraryName( aFilePath );
726 wxCHECK( !LibraryExists( libName ), false ); // either create or add an existing one
727
728 // try to use path normalized to an environmental variable or project path
729 wxString relPath = NormalizePath( aFilePath, &Pgm().GetLocalEnvVariables(), &m_frame.Prj() );
730
731 SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aFilePath );
732 wxString typeName = SCH_IO_MGR::ShowType( schFileType );
733 SYMBOL_LIB_TABLE_ROW* libRow = new SYMBOL_LIB_TABLE_ROW( libName, relPath, typeName );
734 aTable->InsertRow( libRow );
735
736 if( aCreate )
737 {
738 wxCHECK( schFileType != SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY, false );
739
740 try
741 {
742 aTable->CreateSymbolLib( libName );
743 }
744 catch( const IO_ERROR& )
745 {
746 aTable->RemoveRow( libRow );
747 return false;
748 }
749 }
750
752
753 return true;
754}
755
756
758{
759 return m_frame.Prj().SchSymbolLibTable();
760}
761
762
763std::set<LIB_SYMBOL*> SYMBOL_LIBRARY_MANAGER::getOriginalSymbols( const wxString& aLibrary )
764{
765 std::set<LIB_SYMBOL*> symbols;
766 wxCHECK( LibraryExists( aLibrary ), symbols );
767
768 try
769 {
770 wxArrayString aliases;
771 symTable()->EnumerateSymbolLib( aLibrary, aliases );
772
773 for( const auto& aliasName : aliases )
774 {
775 LIB_SYMBOL* alias = symTable()->LoadSymbol( aLibrary, aliasName );
776 symbols.insert( alias );
777 }
778 }
779 catch( const IO_ERROR& e )
780 {
781 wxLogMessage( _( "Cannot enumerate library '%s'." ) + e.What(), aLibrary );
782 }
783
784 return symbols;
785}
786
787
789 const wxString& aLibrary )
790{
791 auto it = m_libs.find( aLibrary );
792
793 if( it != m_libs.end() )
794 return it->second;
795
796 // The requested buffer does not exist yet, so create one
797 auto ret = m_libs.emplace( aLibrary, LIB_BUFFER( aLibrary ) );
798 LIB_BUFFER& buf = ret.first->second;
799
800 for( auto symbol : getOriginalSymbols( aLibrary ) )
801 {
802 LIB_SYMBOL* newSymbol;
803
804 if( symbol->IsAlias() )
805 {
806 std::shared_ptr< LIB_SYMBOL > oldParent = symbol->GetParent().lock();
807
808 wxCHECK_MSG( oldParent, buf,
809 wxString::Format( "Derived symbol '%s' found with undefined parent.",
810 symbol->GetName() ) );
811
812 LIB_SYMBOL* libParent = buf.GetSymbol( oldParent->GetName() );
813
814 if( !libParent )
815 {
816 libParent = new LIB_SYMBOL( *oldParent.get() );
817 buf.CreateBuffer( libParent, new SCH_SCREEN );
818 }
819
820 newSymbol = new LIB_SYMBOL( *symbol );
821 newSymbol->SetParent( libParent );
822 buf.CreateBuffer( newSymbol, new SCH_SCREEN );
823 }
824 else if( !buf.GetSymbol( symbol->GetName() ) )
825 {
826 buf.CreateBuffer( new LIB_SYMBOL( *symbol ), new SCH_SCREEN );
827 }
828 }
829
830 return buf;
831}
832
833
834bool SYMBOL_LIBRARY_MANAGER::UpdateLibraryBuffer( const wxString& aLibrary )
835{
836 try
837 {
838 m_libs.erase( aLibrary );
839 getLibraryBuffer( aLibrary );
840 }
841 catch(const std::exception& e)
842 {
843 wxLogError( _( "Error updating library buffer: %s" ), e.what() );
844 return false;
845 }
846 catch( const IO_ERROR& e )
847 {
848 wxLogError( _( "Error updating library buffer: %s" ), e.What() );
849 return false;
850 }
851 catch(...)
852 {
853 wxLogError( _( "Error updating library buffer." ) );
854 return false;
855 }
856
857 getLibraryBuffer( aLibrary );
858
859 return true;
860}
861
862
864 std::unique_ptr<SCH_SCREEN> aScreen ) :
865 m_screen( std::move( aScreen ) ),
866 m_symbol( aSymbol )
867{
868 m_original = new LIB_SYMBOL( *aSymbol );
869}
870
871
873{
874 delete m_symbol;
875 delete m_original;
876}
877
878
880{
881 wxCHECK( m_symbol != aSymbol, /* void */ );
882 wxASSERT( aSymbol );
883 delete m_symbol;
884 m_symbol = aSymbol;
885
886 // If the symbol moves libraries then the original moves with it
887 if( m_original->GetLibId().GetLibNickname() != m_symbol->GetLibId().GetLibNickname() )
888 {
889 m_original->SetLibId( LIB_ID( m_symbol->GetLibId().GetLibNickname(),
890 m_original->GetLibId().GetLibItemName() ) );
891 }
892}
893
894
896{
897 wxCHECK( m_original != aSymbol, /* void */ );
898 wxASSERT( aSymbol );
899 delete m_original;
900 m_original = aSymbol;
901
902 // The original is not allowed to have a different library than its symbol
903 if( m_original->GetLibId().GetLibNickname() != m_symbol->GetLibId().GetLibNickname() )
904 {
905 m_original->SetLibId( LIB_ID( m_symbol->GetLibId().GetLibNickname(),
906 m_original->GetLibId().GetLibItemName() ) );
907 }
908}
909
910
912{
913 return m_screen && m_screen->IsContentModified();
914}
915
916
918{
919 auto buf = GetBuffer( aAlias );
920
921 if( !buf )
922 return nullptr;
923
924 LIB_SYMBOL* symbol = buf->GetSymbol();
925
926 wxCHECK( symbol, nullptr );
927
928 return symbol;
929}
930
931
933{
934 wxASSERT( aCopy );
935 wxASSERT( aCopy->GetLib() == nullptr );
936 std::unique_ptr<SCH_SCREEN> screen( aScreen );
937 auto symbolBuf = std::make_shared<SYMBOL_BUFFER>( aCopy, std::move( screen ) );
938 m_symbols.push_back( symbolBuf );
939
940 // Set the parent library name,
941 // otherwise it is empty as no library has been given as the owner during object construction
942 LIB_ID libId = aCopy->GetLibId();
943 libId.SetLibNickname( m_libName );
944 aCopy->SetLibId( libId );
945 ++m_hash;
946
947 return true;
948}
949
950
951bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::UpdateBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf,
952 LIB_SYMBOL* aCopy )
953{
954 wxCHECK( aCopy && aSymbolBuf, false );
955
956 LIB_SYMBOL* bufferedSymbol = aSymbolBuf->GetSymbol();
957
958 wxCHECK( bufferedSymbol, false );
959
960 *bufferedSymbol = *aCopy;
961 ++m_hash;
962
963 return true;
964}
965
966
967bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::DeleteBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf )
968{
969 auto symbolBufIt = std::find( m_symbols.begin(), m_symbols.end(), aSymbolBuf );
970 wxCHECK( symbolBufIt != m_symbols.end(), false );
971
972 bool retv = true;
973
974 // Remove all derived symbols to prevent broken inheritance.
975 if( aSymbolBuf->GetSymbol()->IsRoot() && HasDerivedSymbols( aSymbolBuf->GetSymbol()->GetName() )
976 && removeChildSymbols( aSymbolBuf ) == 0 )
977 {
978 retv = false;
979 }
980
981 m_deleted.emplace_back( *symbolBufIt );
982 m_symbols.erase( symbolBufIt );
983 ++m_hash;
984
985 return retv;
986}
987
988
989bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf,
990 SYMBOL_LIB_TABLE* aLibTable )
991{
992 wxCHECK( aSymbolBuf, false );
993 LIB_SYMBOL* libSymbol = aSymbolBuf->GetSymbol();
994 LIB_SYMBOL* originalSymbol = aSymbolBuf->GetOriginal();
995 wxCHECK( libSymbol && originalSymbol, false );
997 STRING_UTF8_MAP properties;
998 properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
999
1000 wxString errorMsg = _( "Error saving symbol %s to library '%s'." ) + wxS( "\n%s" );
1001
1002 // Delete the original symbol if the symbol name has been changed.
1003 if( libSymbol->GetName() != originalSymbol->GetName() )
1004 {
1005 // DeleteSymbol may throw
1006 try
1007 {
1008 if( aLibTable->LoadSymbol( m_libName, originalSymbol->GetName() ) )
1009 aLibTable->DeleteSymbol( m_libName, originalSymbol->GetName() );
1010 }
1011 catch( const IO_ERROR& ioe )
1012 {
1013 wxLogError( errorMsg, UnescapeString( originalSymbol->GetName() ), m_libName,
1014 ioe.What() );
1015 return false;
1016 }
1017 }
1018
1019 if( libSymbol->IsAlias() )
1020 {
1021 LIB_SYMBOL* newCachedSymbol = new LIB_SYMBOL( *libSymbol );
1022 std::shared_ptr< LIB_SYMBOL > bufferedParent = libSymbol->GetParent().lock();
1023
1024 wxCHECK( bufferedParent, false );
1025
1026 LIB_SYMBOL* cachedParent = aLibTable->LoadSymbol( m_libName, bufferedParent->GetName() );
1027
1028 if( !cachedParent )
1029 {
1030 cachedParent = new LIB_SYMBOL( *bufferedParent.get() );
1031 newCachedSymbol->SetParent( cachedParent );
1032 result = aLibTable->SaveSymbol( m_libName, cachedParent );
1033 wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
1034 result = aLibTable->SaveSymbol( m_libName, newCachedSymbol );
1035 wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
1036
1037 LIB_SYMBOL* originalParent = new LIB_SYMBOL( *bufferedParent.get() );
1038 aSymbolBuf->SetOriginal( originalParent );
1039 originalSymbol = new LIB_SYMBOL( *libSymbol );
1040 originalSymbol->SetParent( originalParent );
1041 aSymbolBuf->SetOriginal( originalSymbol );
1042 }
1043 else
1044 {
1045 newCachedSymbol->SetParent( cachedParent );
1046 result = aLibTable->SaveSymbol( m_libName, newCachedSymbol );
1047 wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
1048
1049 auto originalBufferedParent = GetBuffer( bufferedParent->GetName() );
1050 wxCHECK( originalBufferedParent, false );
1051 originalSymbol = new LIB_SYMBOL( *libSymbol );
1052 originalSymbol->SetParent( originalBufferedParent->GetSymbol() );
1053 aSymbolBuf->SetOriginal( originalSymbol );
1054 }
1055 }
1056 else
1057 {
1058 wxArrayString derivedSymbols;
1059
1060 if( GetDerivedSymbolNames( libSymbol->GetName(), derivedSymbols ) == 0 )
1061 {
1062 result = aLibTable->SaveSymbol( m_libName, new LIB_SYMBOL( *libSymbol ) );
1063 wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
1064 aSymbolBuf->SetOriginal( new LIB_SYMBOL( *libSymbol ) );
1065 }
1066 else
1067 {
1068 LIB_SYMBOL* parentSymbol = new LIB_SYMBOL( *libSymbol );
1069
1070 aLibTable->SaveSymbol( m_libName, parentSymbol );
1071
1072 for( auto& entry : derivedSymbols )
1073 {
1074 std::shared_ptr<SYMBOL_BUFFER> symbol = GetBuffer( entry );
1075
1076 wxCHECK2( symbol, continue );
1077
1078 LIB_SYMBOL* derivedSymbol = new LIB_SYMBOL( *symbol->GetSymbol() );
1079 derivedSymbol->SetParent( parentSymbol );
1080 result = aLibTable->SaveSymbol( m_libName, derivedSymbol );
1081 wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
1082 }
1083 }
1084 }
1085
1086 ++m_hash;
1087 return true;
1088}
1089
1090
1091bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf,
1092 const wxString& aFileName,
1093 SCH_PLUGIN* aPlugin, bool aBuffer )
1094{
1095 wxCHECK( aSymbolBuf, false );
1096 LIB_SYMBOL* libSymbol = aSymbolBuf->GetSymbol();
1097 LIB_SYMBOL* originalSymbol = aSymbolBuf->GetOriginal();
1098 wxCHECK( libSymbol && originalSymbol, false );
1099 wxCHECK( !aFileName.IsEmpty(), false );
1100
1101 wxString errorMsg = _( "Error saving symbol %s to library '%s'." ) + wxS( "\n%s" );
1102
1103 // set properties to prevent save file on every symbol save
1104 STRING_UTF8_MAP properties;
1105 properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
1106
1107 // Delete the original symbol if the symbol name has been changed.
1108 if( libSymbol->GetName() != originalSymbol->GetName() )
1109 {
1110 try
1111 {
1112 if( aPlugin->LoadSymbol( aFileName, originalSymbol->GetName() ) )
1113 aPlugin->DeleteSymbol( aFileName, originalSymbol->GetName(), &properties );
1114 }
1115 catch( const IO_ERROR& ioe )
1116 {
1117 wxLogError( errorMsg, UnescapeString( originalSymbol->GetName() ), aFileName,
1118 ioe.What() );
1119 return false;
1120 }
1121 }
1122
1123 if( libSymbol->IsAlias() )
1124 {
1125 LIB_SYMBOL* newCachedSymbol = new LIB_SYMBOL( *libSymbol );
1126 std::shared_ptr< LIB_SYMBOL > bufferedParent = libSymbol->GetParent().lock();
1127
1128 wxCHECK( bufferedParent, false );
1129
1130 LIB_SYMBOL* cachedParent = nullptr;
1131
1132 try
1133 {
1134 cachedParent = aPlugin->LoadSymbol( aFileName, bufferedParent->GetName() );
1135 }
1136 catch( const IO_ERROR& )
1137 {
1138 return false;
1139 }
1140
1141 if( !cachedParent )
1142 {
1143 cachedParent = new LIB_SYMBOL( *bufferedParent.get() );
1144 newCachedSymbol->SetParent( cachedParent );
1145
1146 try
1147 {
1148 aPlugin->SaveSymbol( aFileName, cachedParent, aBuffer ? &properties : nullptr );
1149 }
1150 catch( const IO_ERROR& ioe )
1151 {
1152 wxLogError( errorMsg, UnescapeString( cachedParent->GetName() ), aFileName,
1153 ioe.What() );
1154 return false;
1155 }
1156
1157 try
1158 {
1159 aPlugin->SaveSymbol( aFileName, newCachedSymbol, aBuffer ? &properties : nullptr );
1160 }
1161 catch( const IO_ERROR& ioe )
1162 {
1163 wxLogError( errorMsg, UnescapeString( newCachedSymbol->GetName() ), aFileName,
1164 ioe.What() );
1165 return false;
1166 }
1167
1168 LIB_SYMBOL* originalParent = new LIB_SYMBOL( *bufferedParent.get() );
1169 aSymbolBuf->SetOriginal( originalParent );
1170 originalSymbol = new LIB_SYMBOL( *libSymbol );
1171 originalSymbol->SetParent( originalParent );
1172 aSymbolBuf->SetOriginal( originalSymbol );
1173 }
1174 else
1175 {
1176 newCachedSymbol->SetParent( cachedParent );
1177
1178 try
1179 {
1180 aPlugin->SaveSymbol( aFileName, newCachedSymbol, aBuffer ? &properties : nullptr );
1181 }
1182 catch( const IO_ERROR& ioe )
1183 {
1184 wxLogError( errorMsg, UnescapeString( newCachedSymbol->GetName() ), aFileName,
1185 ioe.What() );
1186 return false;
1187 }
1188
1189 auto originalBufferedParent = GetBuffer( bufferedParent->GetName() );
1190 wxCHECK( originalBufferedParent, false );
1191 originalSymbol = new LIB_SYMBOL( *libSymbol );
1192 originalSymbol->SetParent( originalBufferedParent->GetSymbol() );
1193 aSymbolBuf->SetOriginal( originalSymbol );
1194 }
1195 }
1196 else
1197 {
1198 wxArrayString derivedSymbols;
1199
1200 if( GetDerivedSymbolNames( libSymbol->GetName(), derivedSymbols ) == 0 )
1201 {
1202 try
1203 {
1204 aPlugin->SaveSymbol( aFileName, new LIB_SYMBOL( *libSymbol ),
1205 aBuffer ? &properties : nullptr );
1206 }
1207 catch( const IO_ERROR& ioe )
1208 {
1209 wxLogError( errorMsg, UnescapeString( libSymbol->GetName() ), aFileName,
1210 ioe.What() );
1211 return false;
1212 }
1213
1214 aSymbolBuf->SetOriginal( new LIB_SYMBOL( *libSymbol ) );
1215 }
1216 else
1217 {
1218 LIB_SYMBOL* parentSymbol = new LIB_SYMBOL( *libSymbol );
1219
1220 // Save the modified root symbol.
1221 try
1222 {
1223 aPlugin->SaveSymbol( aFileName, parentSymbol, aBuffer ? &properties : nullptr );
1224 }
1225 catch( const IO_ERROR& ioe )
1226 {
1227 wxLogError( errorMsg, UnescapeString( libSymbol->GetName() ), aFileName,
1228 ioe.What() );
1229 return false;
1230 }
1231
1232 aSymbolBuf->SetOriginal( new LIB_SYMBOL( *libSymbol ) );
1233
1234 // Save the derived symbols.
1235 for( const wxString& entry : derivedSymbols )
1236 {
1237 std::shared_ptr<SYMBOL_BUFFER> symbol = GetBuffer( entry );
1238
1239 wxCHECK2( symbol, continue );
1240
1241 LIB_SYMBOL* derivedSymbol = new LIB_SYMBOL( *symbol->GetSymbol() );
1242 derivedSymbol->SetParent( parentSymbol );
1243
1244 try
1245 {
1246 aPlugin->SaveSymbol( aFileName, new LIB_SYMBOL( *derivedSymbol ),
1247 aBuffer ? &properties : nullptr );
1248 }
1249 catch( const IO_ERROR& ioe )
1250 {
1251 wxLogError( errorMsg, UnescapeString( derivedSymbol->GetName() ), aFileName,
1252 ioe.What() );
1253 return false;
1254 }
1255 }
1256 }
1257 }
1258
1259 ++m_hash;
1260 return true;
1261}
1262
1263
1264std::shared_ptr<SYMBOL_LIBRARY_MANAGER::SYMBOL_BUFFER>
1266{
1267 for( std::shared_ptr<SYMBOL_LIBRARY_MANAGER::SYMBOL_BUFFER> entry : m_symbols )
1268 {
1269 if( entry->GetSymbol()->GetName() == aAlias )
1270 return entry;
1271 }
1272
1273 return std::shared_ptr<SYMBOL_BUFFER>( nullptr );
1274}
1275
1276
1277bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::HasDerivedSymbols( const wxString& aParentName ) const
1278{
1279 for( auto& entry : m_symbols )
1280 {
1281 if( entry->GetSymbol()->IsAlias() )
1282 {
1283 LIB_SYMBOL_SPTR parent = entry->GetSymbol()->GetParent().lock();
1284
1285 // Check for inherited symbol without a valid parent.
1286 wxCHECK( parent, false );
1287
1288 if( parent->GetName() == aParentName )
1289 return true;
1290 }
1291 }
1292
1293 return false;
1294}
1295
1296
1297void SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::GetRootSymbolNames( wxArrayString& aRootSymbolNames )
1298{
1299 for( auto& entry : m_symbols )
1300 {
1301 if( entry->GetSymbol()->IsAlias() )
1302 continue;
1303
1304 aRootSymbolNames.Add( UnescapeString( entry->GetSymbol()->GetName() ) );
1305 }
1306}
1307
1308
1310 wxArrayString& aList )
1311{
1312 wxCHECK( !aSymbolName.IsEmpty(), 0 );
1313
1314 for( auto& entry : m_symbols )
1315 {
1316 if( entry->GetSymbol()->IsAlias() )
1317 {
1318 LIB_SYMBOL_SPTR parent = entry->GetSymbol()->GetParent().lock();
1319
1320 // Check for inherited symbol without a valid parent.
1321 wxCHECK( parent, false );
1322
1323 if( parent->GetName() == aSymbolName )
1324 aList.Add( entry->GetSymbol()->GetName() );
1325 }
1326 }
1327
1328 return aList.GetCount();
1329}
1330
1331
1332int SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::removeChildSymbols( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf )
1333{
1334 wxCHECK( aSymbolBuf && aSymbolBuf->GetSymbol()->IsRoot(), 0 );
1335
1336 int cnt = 0;
1337 std::deque< std::shared_ptr<SYMBOL_BUFFER> >::iterator it = m_symbols.begin();
1338
1339 while( it != m_symbols.end() )
1340 {
1341
1342 if( (*it)->GetSymbol()->IsRoot() )
1343 {
1344 ++it;
1345 }
1346 else
1347 {
1348 LIB_SYMBOL_SPTR parent = (*it)->GetSymbol()->GetParent().lock();
1349
1350 wxCHECK2( parent, ++it; continue );
1351
1352 if( parent->GetName() == aSymbolBuf->GetSymbol()->GetName() )
1353 {
1354 wxCHECK2( parent == aSymbolBuf->GetSymbol()->SharedPtr(), ++it; continue );
1355
1356 m_deleted.emplace_back( *it );
1357 it = m_symbols.erase( it );
1358 cnt++;
1359 }
1360 else
1361 {
1362 ++it;
1363 }
1364 }
1365 }
1366
1367 return cnt;
1368}
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:102
Define a library symbol object.
Definition: lib_symbol.h:99
bool IsAlias() const
Definition: lib_symbol.h:193
LIB_ID GetLibId() const override
Definition: lib_symbol.h:146
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:579
wxString GetName() const override
Definition: lib_symbol.h:143
SYMBOL_LIB * GetLib() const
Definition: lib_symbol.h:197
void SetLibId(const LIB_ID &aLibId)
Definition: lib_symbol.h:147
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:127
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 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:84
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:160
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:536
Base class that schematic file and library loading and saving plugins should derive from.
Definition: sch_io_mgr.h:156
virtual void SaveSymbol(const wxString &aLibraryPath, const LIB_SYMBOL *aSymbol, const STRING_UTF8_MAP *aProperties=nullptr)
Write aSymbol to an existing library located at aLibraryPath.
Definition: sch_plugin.cpp:82
virtual void DeleteSymbol(const wxString &aLibraryPath, const wxString &aSymbolName, const STRING_UTF8_MAP *aProperties=nullptr)
Delete the entire LIB_SYMBOL associated with aAliasName from the library aLibraryPath.
Definition: sch_plugin.cpp:90
virtual void SaveLibrary(const wxString &aFileName, const STRING_UTF8_MAP *aProperties=nullptr)
Definition: sch_plugin.cpp:35
virtual LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aPartName, const STRING_UTF8_MAP *aProperties=nullptr)
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
Definition: sch_plugin.cpp:74
A name/value tuple with unique names and optional values.
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 UpdateLibraryBuffer(const wxString &aLibrary)
Update the library buffer with a new version of the library.
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:45
STL namespace.
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:115
wxString UnescapeString(const wxString &aSource)
Definition for symbol library class.
VECTOR3I res
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:38