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