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-2023 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 <project_sch.h>
33#include <kiway.h>
34#include <core/profile.h>
35#include <wx_filename.h>
36#include <sch_io/sch_io_mgr.h>
38#include <symbol_lib_table.h>
39#include <symbol_async_loader.h>
40#include <progress_reporter.h>
41#include <list>
42#include <locale_io.h>
43#include <confirm.h>
44#include <string_utils.h>
45#include "lib_logger.h"
46
47
49 m_frame( aFrame )
50{
51 m_logger = new LIB_LOGGER();
52}
53
54
56{
57 delete m_logger;
58}
59
60
62{
63 SYMBOL_ASYNC_LOADER loader( symTable()->GetLogicalLibs(), symTable(), false, nullptr,
64 &aReporter );
65
66 LOCALE_IO toggle;
67
68 loader.Start();
69
70 while( !loader.Done() )
71 {
72 if( !aReporter.KeepRefreshing() )
73 break;
74
75 wxMilliSleep( 33 /* 30 FPS refresh rate */ );
76 }
77
78 loader.Join();
79
80 if( !loader.GetErrors().IsEmpty() )
81 {
82 HTML_MESSAGE_BOX dlg( &m_frame, _( "Load Error" ) );
83
84 dlg.MessageSet( _( "Errors loading symbols:" ) );
85
86 wxString msg = loader.GetErrors();
87 msg.Replace( "\n", "<BR>" );
88
89 dlg.AddHTML_Text( msg );
90 dlg.ShowModal();
91 }
92}
93
94
96{
97 for( const std::pair<const wxString, LIB_BUFFER>& lib : m_libs )
98 {
99 if( lib.second.IsModified() )
100 return true;
101 }
102
103 return false;
104}
105
106
108{
109 int hash = symTable()->GetModifyHash();
110
111 for( const std::pair<const wxString, LIB_BUFFER>& lib : m_libs )
112 hash += lib.second.GetHash();
113
114 return hash;
115}
116
117
118int SYMBOL_LIBRARY_MANAGER::GetLibraryHash( const wxString& aLibrary ) const
119{
120 const auto libBufIt = m_libs.find( aLibrary );
121
122 if( libBufIt != m_libs.end() )
123 return libBufIt->second.GetHash();
124
125 SYMBOL_LIB_TABLE_ROW* row = GetLibrary( aLibrary );
126
127 // return -1 if library does not exist or 0 if not modified
128 return row ? std::hash<std::string>{}( aLibrary.ToStdString() +
129 row->GetFullURI( true ).ToStdString() ) : -1;
130}
131
132
134{
135 wxArrayString res;
136
137 for( const wxString& libName : symTable()->GetLogicalLibs() )
138 {
139 // Database libraries are hidden from the symbol editor at the moment
140 if( GetLibrary( libName )->SchLibType() == SCH_IO_MGR::SCH_DATABASE )
141 continue;
142
143 res.Add( libName );
144 }
145
146 return res;
147}
148
149
151{
152 SYMBOL_LIB_TABLE_ROW* row = nullptr;
153
154 try
155 {
156 row = symTable()->FindRow( aLibrary, true );
157 }
158 catch( const IO_ERROR& e )
159 {
160 wxString msg;
161
162 msg.Printf( _( "Library '%s' not found in the Symbol Library Table." ), aLibrary );
163 DisplayErrorMessage( &m_frame, msg, e.What() );
164 }
165
166 return row;
167}
168
169
170bool SYMBOL_LIBRARY_MANAGER::SaveLibrary( const wxString& aLibrary, const wxString& aFileName,
171 SCH_IO_MGR::SCH_FILE_T aFileType )
172{
173 wxCHECK( aFileType != SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY && LibraryExists( aLibrary ), false );
174 wxFileName fn( aFileName );
175 wxCHECK( !fn.FileExists() || fn.IsFileWritable(), false );
176
177 IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( aFileType ) );
178 bool res = true; // assume all libraries are successfully saved
179
180 STRING_UTF8_MAP properties;
181 properties.emplace( SCH_IO_KICAD_LEGACY::PropBuffering, "" );
182
183 auto it = m_libs.find( aLibrary );
184
185 if( it != m_libs.end() )
186 {
187 // Handle buffered library
188 LIB_BUFFER& libBuf = it->second;
189
190 const auto& symbolBuffers = libBuf.GetBuffers();
191
192 for( const std::shared_ptr<SYMBOL_BUFFER>& symbolBuf : symbolBuffers )
193 {
194 if( !libBuf.SaveBuffer( symbolBuf, aFileName, &*pi, true ) )
195 {
196 // Something went wrong, but try to save other libraries
197 res = false;
198 }
199 }
200
201 // clear the deleted symbols buffer only if data is saved to the original file
202 wxFileName original, destination( aFileName );
203 SYMBOL_LIB_TABLE_ROW* row = GetLibrary( aLibrary );
204
205 if( row )
206 {
207 original = row->GetFullURI();
208 original.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
209 }
210
211 destination.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
212
213 if( res && original == destination )
214 libBuf.ClearDeletedBuffer();
215 }
216 else
217 {
218 // Handle original library
219 for( LIB_SYMBOL* symbol : getOriginalSymbols( aLibrary ) )
220 {
221 LIB_SYMBOL* newSymbol;
222
223 try
224 {
225 if( symbol->IsAlias() )
226 {
227 std::shared_ptr< LIB_SYMBOL > oldParent = symbol->GetParent().lock();
228
229 wxCHECK_MSG( oldParent, false,
230 wxString::Format( wxT( "Derived symbol '%s' found with "
231 "undefined parent." ),
232 symbol->GetName() ) );
233
234 LIB_SYMBOL* libParent = pi->LoadSymbol( aLibrary, oldParent->GetName(),
235 &properties );
236
237 if( !libParent )
238 {
239 libParent = new LIB_SYMBOL( *oldParent.get() );
240 pi->SaveSymbol( aLibrary, libParent, &properties );
241 }
242
243 newSymbol = new LIB_SYMBOL( *symbol );
244 newSymbol->SetParent( libParent );
245 pi->SaveSymbol( aLibrary, newSymbol, &properties );
246 }
247 else if( !pi->LoadSymbol( aLibrary, symbol->GetName(), &properties ) )
248 {
249 pi->SaveSymbol( aLibrary, new LIB_SYMBOL( *symbol ), &properties );
250 }
251 }
252 catch( ... )
253 {
254 res = false;
255 break;
256 }
257 }
258 }
259
260 try
261 {
262 pi->SaveLibrary( aFileName );
263 }
264 catch( ... )
265 {
266 // return false because something happens.
267 // The library is not successfully saved
268 res = false;
269 }
270
271 return res;
272}
273
274
275bool SYMBOL_LIBRARY_MANAGER::IsLibraryModified( const wxString& aLibrary ) const
276{
277 auto it = m_libs.find( aLibrary );
278 return it != m_libs.end() ? it->second.IsModified() : false;
279}
280
281
282bool SYMBOL_LIBRARY_MANAGER::IsSymbolModified( const wxString& aAlias,
283 const wxString& aLibrary ) const
284{
285 auto libIt = m_libs.find( aLibrary );
286
287 if( libIt == m_libs.end() )
288 return false;
289
290 const LIB_BUFFER& buf = libIt->second;
291 const std::shared_ptr<SYMBOL_BUFFER> symbolBuf = buf.GetBuffer( aAlias );
292 return symbolBuf ? symbolBuf->IsModified() : false;
293}
294
295
296void SYMBOL_LIBRARY_MANAGER::SetSymbolModified( const wxString& aAlias, const wxString& aLibrary )
297{
298 auto libIt = m_libs.find( aLibrary );
299
300 if( libIt == m_libs.end() )
301 return;
302
303 const LIB_BUFFER& buf = libIt->second;
304 std::shared_ptr<SYMBOL_BUFFER> symbolBuf = buf.GetBuffer( aAlias );
305
306 wxCHECK( symbolBuf, /* void */ );
307
308 symbolBuf->GetScreen()->SetContentModified();
309}
310
311
312bool SYMBOL_LIBRARY_MANAGER::ClearLibraryModified( const wxString& aLibrary ) const
313{
314 auto libIt = m_libs.find( aLibrary );
315
316 if( libIt == m_libs.end() )
317 return false;
318
319 for( auto& symbolBuf : libIt->second.GetBuffers() )
320 {
321 SCH_SCREEN* screen = symbolBuf->GetScreen();
322
323 if( screen )
324 screen->SetContentModified( false );
325 }
326
327 return true;
328}
329
330
332 const wxString& aLibrary ) const
333{
334 auto libI = m_libs.find( aLibrary );
335
336 if( libI == m_libs.end() )
337 return false;
338
339 auto symbolBuf = libI->second.GetBuffer( aAlias );
340 wxCHECK( symbolBuf, false );
341
342 symbolBuf->GetScreen()->SetContentModified( false );
343 return true;
344}
345
346
347bool SYMBOL_LIBRARY_MANAGER::IsLibraryReadOnly( const wxString& aLibrary ) const
348{
349 wxCHECK( LibraryExists( aLibrary ), true );
350
351 return !symTable()->IsSymbolLibWritable( aLibrary );
352}
353
354
355bool SYMBOL_LIBRARY_MANAGER::IsLibraryLoaded( const wxString& aLibrary ) const
356{
357 wxCHECK( LibraryExists( aLibrary ), false );
358
359 return symTable()->IsSymbolLibLoaded( aLibrary );
360}
361
362
363std::list<LIB_SYMBOL*> SYMBOL_LIBRARY_MANAGER::GetAliases( const wxString& aLibrary ) const
364{
365 std::list<LIB_SYMBOL*> ret;
366 wxCHECK( LibraryExists( aLibrary ), ret );
367
368 auto libIt = m_libs.find( aLibrary );
369
370 if( libIt != m_libs.end() )
371 {
372 for( auto& symbolBuf : libIt->second.GetBuffers() )
373 {
374 ret.push_back( symbolBuf->GetSymbol() );
375 }
376 }
377 else
378 {
379 std::vector<LIB_SYMBOL*> aliases;
380
381 try
382 {
383 symTable()->LoadSymbolLib( aliases, aLibrary );
384 }
385 catch( const IO_ERROR& e )
386 {
387 wxLogWarning( e.Problem() );
388 }
389
390 std::copy( aliases.begin(), aliases.end(), std::back_inserter( ret ) );
391 }
392
393 return ret;
394}
395
396
398 const wxString& aLibrary )
399{
400 wxCHECK( LibraryExists( aLibrary ), nullptr );
401
402 // try the library buffers first
403 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
404 LIB_SYMBOL* bufferedSymbol = libBuf.GetSymbol( aAlias );
405
406 if( !bufferedSymbol ) // no buffer symbol found
407 {
408 // create a copy of the symbol
409 try
410 {
411 LIB_SYMBOL* symbol = symTable()->LoadSymbol( aLibrary, aAlias );
412
413 if( symbol == nullptr )
414 THROW_IO_ERROR( _( "Symbol not found." ) );
415
416 LIB_SYMBOL* bufferedParent = nullptr;
417
418 // Create parent symbols on demand so parent symbol can be set.
419 if( symbol->IsAlias() )
420 {
421 std::shared_ptr< LIB_SYMBOL > parent = symbol->GetParent().lock();
422 wxCHECK_MSG( parent, nullptr,
423 wxString::Format( "Derived symbol '%s' found with undefined parent.",
424 symbol->GetName() ) );
425
426 // Check if the parent symbol buffer has already be created.
427 bufferedParent = libBuf.GetSymbol( parent->GetName() );
428
429 if( !bufferedParent )
430 {
431 bufferedParent = new LIB_SYMBOL( *parent.get() );
432 libBuf.CreateBuffer( bufferedParent, new SCH_SCREEN );
433 }
434 }
435
436 bufferedSymbol = new LIB_SYMBOL( *symbol );
437
438 if( bufferedParent )
439 bufferedSymbol->SetParent( bufferedParent );
440
441 libBuf.CreateBuffer( bufferedSymbol, new SCH_SCREEN );
442 }
443 catch( const IO_ERROR& e )
444 {
445 wxString msg;
446
447 msg.Printf( _( "Error loading symbol %s from library '%s'." ), aAlias, aLibrary );
448 DisplayErrorMessage( &m_frame, msg, e.What() );
449 bufferedSymbol = nullptr;
450 }
451 }
452
453 return bufferedSymbol;
454}
455
456
457SCH_SCREEN* SYMBOL_LIBRARY_MANAGER::GetScreen( const wxString& aAlias, const wxString& aLibrary )
458{
459 wxCHECK( LibraryExists( aLibrary ), nullptr );
460 wxCHECK( !aAlias.IsEmpty(), nullptr );
461 auto it = m_libs.find( aLibrary );
462 wxCHECK( it != m_libs.end(), nullptr );
463
464 LIB_BUFFER& buf = it->second;
465 auto symbolBuf = buf.GetBuffer( aAlias );
466 return symbolBuf ? symbolBuf->GetScreen() : nullptr;
467}
468
469
470bool SYMBOL_LIBRARY_MANAGER::UpdateSymbol( LIB_SYMBOL* aSymbol, const wxString& aLibrary )
471{
472 wxCHECK( LibraryExists( aLibrary ), false );
473 wxCHECK( aSymbol, false );
474 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
475 auto symbolBuf = libBuf.GetBuffer( aSymbol->GetName() );
476
477 if( symbolBuf ) // Existing symbol.
478 {
479 LIB_SYMBOL* bufferedSymbol = const_cast< LIB_SYMBOL* >( symbolBuf->GetSymbol() );
480
481 wxCHECK( bufferedSymbol, false );
482
483 *bufferedSymbol = *aSymbol;
484 symbolBuf->GetScreen()->SetContentModified();
485 }
486 else // New symbol
487 {
488 LIB_SYMBOL* symbolCopy = new LIB_SYMBOL( *aSymbol, nullptr );
489
490 symbolCopy->SetLibId( LIB_ID( aLibrary, aSymbol->GetLibId().GetLibItemName() ) );
491
492 SCH_SCREEN* screen = new SCH_SCREEN;
493 libBuf.CreateBuffer( symbolCopy, screen );
494 screen->SetContentModified();
495 }
496
497 return true;
498}
499
500
501bool SYMBOL_LIBRARY_MANAGER::UpdateSymbolAfterRename( LIB_SYMBOL* aSymbol, const wxString& aOldName,
502 const wxString& aLibrary )
503{
504 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
505 auto symbolBuf = libBuf.GetBuffer( aOldName );
506
507 wxCHECK( symbolBuf, false );
508
509 libBuf.UpdateBuffer( symbolBuf, aSymbol );
511
512 return true;
513}
514
515
516LIB_ID SYMBOL_LIBRARY_MANAGER::RevertSymbol( const wxString& aAlias, const wxString& aLibrary )
517{
518 auto it = m_libs.find( aLibrary );
519
520 if( it == m_libs.end() ) // no items to flush
521 return LIB_ID( aLibrary, aAlias );
522
523 auto symbolBuf = it->second.GetBuffer( aAlias );
524 wxCHECK( symbolBuf, LIB_ID( aLibrary, aAlias ) );
525 LIB_SYMBOL original( *symbolBuf->GetOriginal() );
526
527 if( original.GetName() != aAlias )
528 {
529 UpdateSymbolAfterRename( &original, aAlias, aLibrary );
530 }
531 else
532 {
533 // copy the initial data to the current symbol to restore
534 *symbolBuf->GetSymbol() = original;
536 }
537
538 return LIB_ID( aLibrary, original.GetName() );
539}
540
541
542bool SYMBOL_LIBRARY_MANAGER::RevertLibrary( const wxString& aLibrary )
543{
544 auto it = m_libs.find( aLibrary );
545
546 if( it == m_libs.end() ) // nothing to reverse
547 return false;
548
549 m_libs.erase( it );
551
552 return true;
553}
554
555
557{
558 bool retv = true;
559
560 // Nothing to revert.
561 if( GetHash() == 0 )
562 return true;
563
564 for( const auto& lib : m_libs )
565 {
566 if( !lib.second.IsModified() )
567 continue;
568
569 for( const auto& buffer : lib.second.GetBuffers() )
570 {
571 if( !buffer->IsModified() )
572 continue;
573
574 RevertSymbol( lib.first, buffer->GetOriginal()->GetName() );
575 }
576 }
577
578 return retv;
579}
580
581
582bool SYMBOL_LIBRARY_MANAGER::RemoveSymbol( const wxString& aAlias, const wxString& aLibrary )
583{
584 LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
585 auto symbolBuf = libBuf.GetBuffer( aAlias );
586 wxCHECK( symbolBuf, false );
587
588 bool retv = true;
589
590 retv &= libBuf.DeleteBuffer( symbolBuf );
592
593 return retv;
594}
595
596
598 const wxString& aLibrary ) const
599{
600 // Try the library buffers first
601 auto libIt = m_libs.find( aLibrary );
602
603 if( libIt != m_libs.end() )
604 {
605 LIB_SYMBOL* symbol = libIt->second.GetSymbol( aAlias );
606
607 if( symbol )
608 return symbol;
609 }
610
611 // Get the original symbol
612 LIB_SYMBOL* alias = nullptr;
613
614 try
615 {
616 alias = symTable()->LoadSymbol( aLibrary, aAlias );
617 }
618 catch( const IO_ERROR& e )
619 {
620 wxString msg;
621
622 msg.Printf( _( "Cannot load symbol '%s' from library '%s'." ), aAlias, aLibrary );
623 DisplayErrorMessage( &m_frame, msg, e.What() );
624 }
625
626 return alias;
627}
628
629
630bool SYMBOL_LIBRARY_MANAGER::SymbolExists( const wxString& aAlias, const wxString& aLibrary ) const
631{
632 auto libBufIt = m_libs.find( aLibrary );
633 LIB_SYMBOL* alias = nullptr;
634
635 if( libBufIt != m_libs.end() )
636 return !!libBufIt->second.GetBuffer( aAlias );
637
638 try
639 {
640 alias = symTable()->LoadSymbol( aLibrary, aAlias );
641 }
642 catch( IO_ERROR& )
643 {
644 // checking if certain symbol exists, so its absence is perfectly fine
645 }
646
647 return alias != nullptr;
648}
649
650
651bool SYMBOL_LIBRARY_MANAGER::LibraryExists( const wxString& aLibrary, bool aCheckEnabled ) const
652{
653 if( aLibrary.IsEmpty() )
654 return false;
655
656 if( m_libs.count( aLibrary ) > 0 )
657 return true;
658
659 return symTable()->HasLibrary( aLibrary, aCheckEnabled );
660}
661
662
664{
665 wxString name = "New_Library";
666
667 if( !LibraryExists( name ) )
668 return name;
669
670 name += "_";
671
672 for( unsigned int i = 0; i < std::numeric_limits<unsigned int>::max(); ++i )
673 {
674 if( !LibraryExists( name + wxString::Format( "%u", i ) ) )
675 return name + wxString::Format( "%u", i );
676 }
677
678 wxFAIL;
679 return wxEmptyString;
680}
681
682
683void SYMBOL_LIBRARY_MANAGER::GetSymbolNames( const wxString& aLibraryName,
684 wxArrayString& aSymbolNames,
685 SYMBOL_NAME_FILTER aFilter )
686{
687 LIB_BUFFER& libBuf = getLibraryBuffer( aLibraryName );
688
689 libBuf.GetSymbolNames( aSymbolNames, aFilter );
690}
691
692
693bool SYMBOL_LIBRARY_MANAGER:: HasDerivedSymbols( const wxString& aSymbolName,
694 const wxString& aLibraryName )
695{
696 LIB_BUFFER& libBuf = getLibraryBuffer( aLibraryName );
697
698 return libBuf.HasDerivedSymbols( aSymbolName );
699}
700
701
703{
704 return symTable()->GetLogicalLibs().size();
705}
706
707
708wxString SYMBOL_LIBRARY_MANAGER::getLibraryName( const wxString& aFilePath )
709{
710 wxFileName fn( aFilePath );
711 return fn.GetName();
712}
713
714
715bool SYMBOL_LIBRARY_MANAGER::addLibrary( const wxString& aFilePath, bool aCreate,
716 SYMBOL_LIB_TABLE* aTable )
717{
718 wxCHECK( aTable, false );
719 wxString libName = getLibraryName( aFilePath );
720 wxCHECK( !LibraryExists( libName ), false ); // either create or add an existing one
721
722 // try to use path normalized to an environmental variable or project path
723 wxString relPath = NormalizePath( aFilePath, &Pgm().GetLocalEnvVariables(), &m_frame.Prj() );
724
725 SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aFilePath );
726
727 if( schFileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
728 schFileType = SCH_IO_MGR::SCH_LEGACY;
729
730 wxString typeName = SCH_IO_MGR::ShowType( schFileType );
731 SYMBOL_LIB_TABLE_ROW* libRow = new SYMBOL_LIB_TABLE_ROW( libName, relPath, typeName );
732 aTable->InsertRow( libRow );
733
734 if( aCreate )
735 {
736 wxCHECK( schFileType != SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY, false );
737
738 try
739 {
740 aTable->CreateSymbolLib( libName );
741 }
742 catch( const IO_ERROR& )
743 {
744 aTable->RemoveRow( libRow );
745 return false;
746 }
747 }
748
750
751 return true;
752}
753
754
756{
758}
759
760
761std::set<LIB_SYMBOL*> SYMBOL_LIBRARY_MANAGER::getOriginalSymbols( const wxString& aLibrary )
762{
763 std::set<LIB_SYMBOL*> symbols;
764 wxCHECK( LibraryExists( aLibrary ), symbols );
765
766 try
767 {
768 wxArrayString aliases;
769 symTable()->EnumerateSymbolLib( aLibrary, aliases );
770
771 for( const auto& aliasName : aliases )
772 {
773 LIB_SYMBOL* alias = symTable()->LoadSymbol( aLibrary, aliasName );
774 symbols.insert( alias );
775 }
776 }
777 catch( const IO_ERROR& e )
778 {
779 wxString msg;
780
781 msg.Printf( _( "Cannot enumerate library '%s'." ), aLibrary );
782 DisplayErrorMessage( &m_frame, msg, e.What() );
783 }
784
785 return symbols;
786}
787
788
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
863SYMBOL_BUFFER::SYMBOL_BUFFER( LIB_SYMBOL* aSymbol, std::unique_ptr<SCH_SCREEN> aScreen ) :
864 m_screen( std::move( aScreen ) ),
865 m_symbol( aSymbol )
866{
867 m_original = new LIB_SYMBOL( *aSymbol );
868}
869
870
872{
873 delete m_symbol;
874 delete m_original;
875}
876
877
879{
880 wxCHECK( m_symbol != aSymbol, /* void */ );
881 wxASSERT( aSymbol );
882 delete m_symbol;
883 m_symbol = aSymbol;
884
885 // If the symbol moves libraries then the original moves with it
887 {
890 }
891}
892
893
895{
896 wxCHECK( m_original != aSymbol, /* void */ );
897 wxASSERT( aSymbol );
898 delete m_original;
899 m_original = aSymbol;
900
901 // The original is not allowed to have a different library than its symbol
903 {
906 }
907}
908
909
911{
912 return m_screen && m_screen->IsContentModified();
913}
914
915
916LIB_SYMBOL* LIB_BUFFER::GetSymbol( const wxString& aAlias ) const
917{
918 auto buf = GetBuffer( aAlias );
919
920 if( !buf )
921 return nullptr;
922
923 LIB_SYMBOL* symbol = buf->GetSymbol();
924
925 wxCHECK( symbol, nullptr );
926
927 return symbol;
928}
929
930
932{
933 wxASSERT( aCopy );
934 wxASSERT( aCopy->GetLib() == nullptr );
935 std::unique_ptr<SCH_SCREEN> screen( aScreen );
936 auto symbolBuf = std::make_shared<SYMBOL_BUFFER>( aCopy, std::move( screen ) );
937 m_symbols.push_back( symbolBuf );
938
939 // Set the parent library name,
940 // otherwise it is empty as no library has been given as the owner during object construction
941 LIB_ID libId = aCopy->GetLibId();
942 libId.SetLibNickname( m_libName );
943 aCopy->SetLibId( libId );
944 ++m_hash;
945
946 return true;
947}
948
949
950bool LIB_BUFFER::UpdateBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf, LIB_SYMBOL* aCopy )
951{
952 wxCHECK( aCopy && aSymbolBuf, false );
953
954 LIB_SYMBOL* bufferedSymbol = aSymbolBuf->GetSymbol();
955
956 wxCHECK( bufferedSymbol, false );
957
958 *bufferedSymbol = *aCopy;
959 ++m_hash;
960
961 return true;
962}
963
964
965bool LIB_BUFFER::DeleteBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf )
966{
967 auto symbolBufIt = std::find( m_symbols.begin(), m_symbols.end(), aSymbolBuf );
968 wxCHECK( symbolBufIt != m_symbols.end(), false );
969
970 bool retv = true;
971
972 // Remove all derived symbols to prevent broken inheritance.
973 if( HasDerivedSymbols( aSymbolBuf->GetSymbol()->GetName() )
974 && ( removeChildSymbols( aSymbolBuf ) == 0 ) )
975 {
976 retv = false;
977 }
978
979 m_deleted.emplace_back( *symbolBufIt );
980 m_symbols.erase( symbolBufIt );
981 ++m_hash;
982
983 return retv;
984}
985
986
987bool LIB_BUFFER::SaveBuffer( std::shared_ptr<SYMBOL_BUFFER> aSymbolBuf,
988 const wxString& aFileName, SCH_IO* aPlugin, bool aBuffer )
989{
990 wxCHECK( aSymbolBuf, false );
991 wxCHECK( !aFileName.IsEmpty(), false );
992
993 wxString errorMsg = _( "Error saving symbol %s to library '%s'." ) + wxS( "\n%s" );
994
995 // Set properties to prevent saving the file on every symbol save.
996 STRING_UTF8_MAP properties;
997 properties.emplace( SCH_IO_KICAD_LEGACY::PropBuffering, "" );
998
999 std::shared_ptr<SYMBOL_BUFFER>& symbolBuf = aSymbolBuf;
1000 LIB_SYMBOL* libSymbol = symbolBuf->GetSymbol();
1001 LIB_SYMBOL* originalSymbol = symbolBuf->GetOriginal();
1002
1003 wxCHECK( libSymbol && originalSymbol, false );
1004
1005 // Delete the original symbol if the symbol name has been changed.
1006 if( libSymbol->GetName() != originalSymbol->GetName() )
1007 {
1008 try
1009 {
1010 if( aPlugin->LoadSymbol( aFileName, originalSymbol->GetName() ) )
1011 aPlugin->DeleteSymbol( aFileName, originalSymbol->GetName(), &properties );
1012 }
1013 catch( const IO_ERROR& ioe )
1014 {
1015 wxLogError( errorMsg, UnescapeString( originalSymbol->GetName() ), aFileName,
1016 ioe.What() );
1017 return false;
1018 }
1019 }
1020
1021 LIB_SYMBOL* parentSymbol = nullptr;
1022
1023 if( libSymbol->IsAlias() )
1024 {
1025 LIB_SYMBOL* newCachedSymbol = new LIB_SYMBOL( *libSymbol );
1026 std::shared_ptr< LIB_SYMBOL > bufferedParent = libSymbol->GetParent().lock();
1027 parentSymbol = newCachedSymbol;
1028
1029 wxCHECK( bufferedParent, false );
1030
1031 LIB_SYMBOL* cachedParent = nullptr;
1032
1033 try
1034 {
1035 cachedParent = aPlugin->LoadSymbol( aFileName, bufferedParent->GetName() );
1036 }
1037 catch( const IO_ERROR& )
1038 {
1039 return false;
1040 }
1041
1042 if( !cachedParent )
1043 {
1044 cachedParent = new LIB_SYMBOL( *bufferedParent.get() );
1045 newCachedSymbol->SetParent( cachedParent );
1046
1047 try
1048 {
1049 aPlugin->SaveSymbol( aFileName, cachedParent, aBuffer ? &properties : nullptr );
1050 }
1051 catch( const IO_ERROR& ioe )
1052 {
1053 wxLogError( errorMsg, UnescapeString( cachedParent->GetName() ), aFileName,
1054 ioe.What() );
1055 return false;
1056 }
1057
1058 try
1059 {
1060 aPlugin->SaveSymbol( aFileName, newCachedSymbol, aBuffer ? &properties : nullptr );
1061 }
1062 catch( const IO_ERROR& ioe )
1063 {
1064 wxLogError( errorMsg, UnescapeString( newCachedSymbol->GetName() ), aFileName,
1065 ioe.What() );
1066 return false;
1067 }
1068
1069 LIB_SYMBOL* originalParent = new LIB_SYMBOL( *bufferedParent.get() );
1070 aSymbolBuf->SetOriginal( originalParent );
1071 originalSymbol = new LIB_SYMBOL( *libSymbol );
1072 originalSymbol->SetParent( originalParent );
1073 aSymbolBuf->SetOriginal( originalSymbol );
1074 }
1075 else
1076 {
1077 newCachedSymbol->SetParent( cachedParent );
1078
1079 try
1080 {
1081 aPlugin->SaveSymbol( aFileName, newCachedSymbol, aBuffer ? &properties : nullptr );
1082 }
1083 catch( const IO_ERROR& ioe )
1084 {
1085 wxLogError( errorMsg, UnescapeString( newCachedSymbol->GetName() ), aFileName,
1086 ioe.What() );
1087 return false;
1088 }
1089
1090 auto originalBufferedParent = GetBuffer( bufferedParent->GetName() );
1091 wxCHECK( originalBufferedParent, false );
1092 originalSymbol = new LIB_SYMBOL( *libSymbol );
1093 originalSymbol->SetParent( originalBufferedParent->GetSymbol() );
1094 aSymbolBuf->SetOriginal( originalSymbol );
1095 }
1096 }
1097 else
1098 {
1099 parentSymbol = new LIB_SYMBOL( *libSymbol );
1100
1101 try
1102 {
1103 aPlugin->SaveSymbol( aFileName, parentSymbol, aBuffer ? &properties : nullptr );
1104 }
1105 catch( const IO_ERROR& ioe )
1106 {
1107 wxLogError( errorMsg, UnescapeString( libSymbol->GetName() ), aFileName,
1108 ioe.What() );
1109 return false;
1110 }
1111
1112 aSymbolBuf->SetOriginal( new LIB_SYMBOL( *libSymbol ) );
1113 }
1114
1115 wxArrayString derivedSymbols;
1116
1117 // Reparent all symbols derived from the saved symbol.
1118 if( GetDerivedSymbolNames( libSymbol->GetName(), derivedSymbols ) != 0 )
1119 {
1120 // Save the derived symbols.
1121 for( const wxString& entry : derivedSymbols )
1122 {
1123 std::shared_ptr<SYMBOL_BUFFER> symbol = GetBuffer( entry );
1124
1125 wxCHECK2( symbol, continue );
1126
1127 LIB_SYMBOL* derivedSymbol = new LIB_SYMBOL( *symbol->GetSymbol() );
1128 derivedSymbol->SetParent( parentSymbol );
1129
1130 try
1131 {
1132 aPlugin->SaveSymbol( aFileName, new LIB_SYMBOL( *derivedSymbol ),
1133 aBuffer ? &properties : nullptr );
1134 }
1135 catch( const IO_ERROR& ioe )
1136 {
1137 wxLogError( errorMsg, UnescapeString( derivedSymbol->GetName() ), aFileName,
1138 ioe.What() );
1139 return false;
1140 }
1141 }
1142 }
1143
1144 ++m_hash;
1145 return true;
1146}
1147
1148
1149std::shared_ptr<SYMBOL_BUFFER> LIB_BUFFER::GetBuffer( const wxString& aAlias ) const
1150{
1151 for( std::shared_ptr<SYMBOL_BUFFER> entry : m_symbols )
1152 {
1153 if( entry->GetSymbol()->GetName() == aAlias )
1154 return entry;
1155 }
1156
1157 return std::shared_ptr<SYMBOL_BUFFER>( nullptr );
1158}
1159
1160
1161bool LIB_BUFFER::HasDerivedSymbols( const wxString& aParentName ) const
1162{
1163 for( const std::shared_ptr<SYMBOL_BUFFER>& entry : m_symbols )
1164 {
1165 if( entry->GetSymbol()->IsAlias() )
1166 {
1167 LIB_SYMBOL_SPTR parent = entry->GetSymbol()->GetParent().lock();
1168
1169 // Check for inherited symbol without a valid parent.
1170 wxCHECK( parent, false );
1171
1172 if( parent->GetName() == aParentName )
1173 return true;
1174 }
1175 }
1176
1177 return false;
1178}
1179
1180
1181void LIB_BUFFER::GetSymbolNames( wxArrayString& aSymbolNames, SYMBOL_NAME_FILTER aFilter )
1182{
1183 for( std::shared_ptr<SYMBOL_BUFFER>& entry : m_symbols )
1184 {
1185 if( ( entry->GetSymbol()->IsAlias() && ( aFilter == SYMBOL_NAME_FILTER::ROOT_ONLY ) )
1186 || ( entry->GetSymbol()->IsRoot() && ( aFilter == SYMBOL_NAME_FILTER::DERIVED_ONLY ) ) )
1187 continue;
1188
1189 aSymbolNames.Add( UnescapeString( entry->GetSymbol()->GetName() ) );
1190 }
1191}
1192
1193
1194size_t LIB_BUFFER::GetDerivedSymbolNames( const wxString& aSymbolName, wxArrayString& aList )
1195{
1196 wxCHECK( !aSymbolName.IsEmpty(), 0 );
1197
1198 for( std::shared_ptr<SYMBOL_BUFFER>& entry : m_symbols )
1199 {
1200 if( entry->GetSymbol()->IsAlias() )
1201 {
1202 LIB_SYMBOL_SPTR parent = entry->GetSymbol()->GetParent().lock();
1203
1204 // Check for inherited symbol without a valid parent.
1205 wxCHECK2( parent, continue );
1206
1207 if( parent->GetName() == aSymbolName )
1208 {
1209 aList.Add( entry->GetSymbol()->GetName() );
1210
1211 GetDerivedSymbolNames( entry->GetSymbol()->GetName(), aList );
1212 }
1213 }
1214 }
1215
1216 return aList.GetCount();
1217}
1218
1219
1220int LIB_BUFFER::removeChildSymbols( std::shared_ptr<SYMBOL_BUFFER>& aSymbolBuf )
1221{
1222 wxCHECK( aSymbolBuf, 0 );
1223
1224 int cnt = 0;
1225 wxArrayString derivedSymbolNames;
1226 std::deque< std::shared_ptr<SYMBOL_BUFFER> >::iterator it;
1227
1228 if( GetDerivedSymbolNames( aSymbolBuf->GetSymbol()->GetName(), derivedSymbolNames ) )
1229 {
1230 for( const wxString& symbolName : derivedSymbolNames )
1231 {
1232 it = std::find_if( m_symbols.begin(), m_symbols.end(),
1233 [symbolName]( std::shared_ptr<SYMBOL_BUFFER>& buf )
1234 {
1235 return buf->GetSymbol()->GetName() == symbolName;
1236 } );
1237
1238 wxCHECK2( it != m_symbols.end(), continue );
1239
1240 m_deleted.emplace_back( *it );
1241 m_symbols.erase( it );
1242 cnt += 1;
1243 }
1244 }
1245
1246 return cnt;
1247}
const char * name
Definition: DXF_plotter.cpp:57
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:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:46
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
size_t GetDerivedSymbolNames(const wxString &aSymbolName, wxArrayString &aList)
Fetch all of the symbols derived from a aSymbolName into aList.
int removeChildSymbols(std::shared_ptr< SYMBOL_BUFFER > &aSymbolBuf)
Remove all symbols derived from aParent from the library buffer.
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.
void ClearDeletedBuffer()
Save stored modifications using a plugin.
void GetSymbolNames(wxArrayString &aSymbolNames, SYMBOL_NAME_FILTER aFilter=SYMBOL_NAME_FILTER::ALL)
Fetch a list of root symbols names from the library buffer.
bool UpdateBuffer(std::shared_ptr< SYMBOL_BUFFER > aSymbolBuf, LIB_SYMBOL *aCopy)
std::deque< std::shared_ptr< SYMBOL_BUFFER > > m_symbols
Buffer for deleted symbols until library is saved.
std::deque< std::shared_ptr< SYMBOL_BUFFER > > m_deleted
const std::deque< std::shared_ptr< SYMBOL_BUFFER > > & GetBuffers() const
std::shared_ptr< SYMBOL_BUFFER > GetBuffer(const wxString &aAlias) const
Return all buffered symbols.
LIB_SYMBOL * GetSymbol(const wxString &aAlias) const
Create a new buffer to store a symbol. LIB_BUFFER takes ownership of aCopy.
bool HasDerivedSymbols(const wxString &aParentName) const
Check to see any symbols in the buffer are derived from a parent named aParentName.
const wxString m_libName
bool SaveBuffer(std::shared_ptr< SYMBOL_BUFFER > aSymbolBuf, const wxString &aFileName, SCH_IO *aPlugin, bool aBuffer)
Return a symbol buffer with LIB_SYMBOL holding a symbolicular alias.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition: lib_id.cpp:99
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
Define a library symbol object.
Definition: lib_symbol.h:77
const LIB_ID & GetLibId() const override
Definition: lib_symbol.h:146
bool IsAlias() const
Definition: lib_symbol.h:198
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:331
wxString GetName() const override
Definition: lib_symbol.h:140
SYMBOL_LIB * GetLib() const
Definition: lib_symbol.h:202
void SetLibId(const LIB_ID &aLibId)
Definition: lib_symbol.h:147
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:109
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 and frees the pointer.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:49
A progress reporter interface for use in multi-threaded environments.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
static const wxString ShowType(SCH_FILE_T aFileType)
Return a brief name for a plugin, given aFileType enum.
Definition: sch_io_mgr.cpp:83
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a symbol library using the file extension of aLibPath.
Definition: sch_io_mgr.cpp:140
Base class that schematic file and library loading and saving plugins should derive from.
Definition: sch_io.h:57
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_io.cpp:101
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_io.cpp:117
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_io.cpp:109
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.
std::unique_ptr< SCH_SCREEN > m_screen
void SetOriginal(LIB_SYMBOL *aSymbol)
void SetSymbol(LIB_SYMBOL *aSymbol)
SYMBOL_BUFFER(LIB_SYMBOL *aSymbol=nullptr, std::unique_ptr< SCH_SCREEN > aScreen=nullptr)
LIB_SYMBOL * m_original
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)
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).
LIB_BUFFER & getLibraryBuffer(const wxString &aLibrary)
Return an existing library buffer or creates one to using Symbol Library Table to get the original da...
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.
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.
void GetSymbolNames(const wxString &aLibName, wxArrayString &aSymbolNames, SYMBOL_NAME_FILTER aFilter=SYMBOL_NAME_FILTER::ALL)
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.
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_IO object i...
void LoadSymbolLib(std::vector< LIB_SYMBOL * > &aAliasList, const wxString &aNickname, bool aPowerSymbolsOnly=false)
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.
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...
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:195
This file is part of the common library.
#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
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition: io_mgr.h:33
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:39
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
Definition: lib_symbol.h:45
STL namespace.
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
see class PGM_BASE
wxString UnescapeString(const wxString &aSource)
Definition for symbol library class.
SYMBOL_NAME_FILTER
VECTOR3I res
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:39