From 3ae240ea4614d53591a3c192373f326eaaa3e807 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Sat, 17 Sep 2016 13:31:58 -0400 Subject: [PATCH] Eeschema: add save code to legacy symbol library plugin. Make LIB_PART copy constructor take a const LIB_PART reference. Add SaveSymbol to legacy symbol library plugin. Add removeAlias to legacy symbol library cache. Add AddSymbol to legacy symbol library cache. --- eeschema/class_libentry.cpp | 2 +- eeschema/class_libentry.h | 2 +- eeschema/class_library.cpp | 2 +- eeschema/sch_io_mgr.h | 26 ++++---- eeschema/sch_legacy_plugin.cpp | 114 ++++++++++++++++++++++++++++++++- eeschema/sch_legacy_plugin.h | 2 + eeschema/sch_plugin.cpp | 2 +- 7 files changed, 132 insertions(+), 18 deletions(-) diff --git a/eeschema/class_libentry.cpp b/eeschema/class_libentry.cpp index 9041ab9828..937bbb00af 100644 --- a/eeschema/class_libentry.cpp +++ b/eeschema/class_libentry.cpp @@ -206,7 +206,7 @@ LIB_PART::LIB_PART( const wxString& aName, PART_LIB* aLibrary ) : } -LIB_PART::LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary ) : +LIB_PART::LIB_PART( const LIB_PART& aPart, PART_LIB* aLibrary ) : EDA_ITEM( aPart ), m_me( this, null_deleter() ) { diff --git a/eeschema/class_libentry.h b/eeschema/class_libentry.h index e51788129a..dc1facea71 100644 --- a/eeschema/class_libentry.h +++ b/eeschema/class_libentry.h @@ -218,7 +218,7 @@ private: public: LIB_PART( const wxString& aName, PART_LIB* aLibrary = NULL ); - LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary = NULL ); + LIB_PART( const LIB_PART& aPart, PART_LIB* aLibrary = NULL ); virtual ~LIB_PART(); diff --git a/eeschema/class_library.cpp b/eeschema/class_library.cpp index f2721ba5c8..0fe4ac368b 100644 --- a/eeschema/class_library.cpp +++ b/eeschema/class_library.cpp @@ -242,7 +242,7 @@ bool PART_LIB::AddPart( LIB_PART* aPart ) } // add a clone, not the caller's copy - LIB_PART* my_part = new LIB_PART( *aPart, this ); + LIB_PART* my_part = new LIB_PART( *aPart ); for( size_t i = 0; i < my_part->m_aliases.size(); i++ ) { diff --git a/eeschema/sch_io_mgr.h b/eeschema/sch_io_mgr.h index 74017c7962..98b09b0394 100644 --- a/eeschema/sch_io_mgr.h +++ b/eeschema/sch_io_mgr.h @@ -303,25 +303,27 @@ public: const PROPERTIES* aProperties = NULL ); /** - * Function SymbolSave - * will write @a aModule to an existing library located at @a aLibraryPath. - * If a footprint by the same name already exists, it is replaced. + * Function SaveSymbol + * will write @a aSymbol to an existing library located at @a aLibraryPath. + * If a #LIB_PART by the same name already exists or there are any conflicting + * alias names, an exception is thrown. Symbol libraries cannot have duplicate + * alias names. * * @param aLibraryPath is a locator for the "library", usually a directory, file, - * or URL containing several footprints. + * or URL containing several footprints. * - * @param aSymbol is what to store in the library. The caller continues - * to own the footprint after this call. + * @param aSymbol is what to store in the library. The library is refreshed and the + * caller must update any #LIB_PART pointers that may have changed. * * @param aProperties is an associative array that can be used to tell the - * saver how to save the footprint, because it can take any number of - * additional named tuning arguments that the plugin is known to support. - * The caller continues to own this object (plugin may not delete it), and - * plugins should expect it to be optionally NULL. + * saver how to save the symbol, because it can take any number of + * additional named tuning arguments that the plugin is known to support. + * The caller continues to own this object (plugin may not delete it), and + * plugins should expect it to be optionally NULL. * - * @throw IO_ERROR if there is a problem saving. + * @throw IO_ERROR if there is a problem saving or duplicate alias names. */ - virtual void SymbolSave( const wxString& aLibraryPath, const LIB_PART* aSymbol, + virtual void SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol, const PROPERTIES* aProperties = NULL ); /** diff --git a/eeschema/sch_legacy_plugin.cpp b/eeschema/sch_legacy_plugin.cpp index 8fdb7b766b..1d9b71675f 100644 --- a/eeschema/sch_legacy_plugin.cpp +++ b/eeschema/sch_legacy_plugin.cpp @@ -1901,6 +1901,7 @@ class SCH_LEGACY_PLUGIN_CACHE wxDateTime m_fileModTime; LIB_ALIAS_MAP m_aliases; // Map of names of LIB_ALIAS pointers. bool m_isWritable; + bool m_isModified; int m_modHash; // Keep track of the modification status of the library. int m_versionMajor; int m_versionMinor; @@ -1926,6 +1927,7 @@ class SCH_LEGACY_PLUGIN_CACHE FILL_T parseFillMode( FILE_LINE_READER& aReader, const char* aLine, const char** aOutput ); bool checkForDuplicates( wxString& aAliasName ); + LIB_ALIAS* removeAlias( LIB_ALIAS* aAlias ); friend SCH_LEGACY_PLUGIN; @@ -1938,10 +1940,12 @@ public: // Catch these exceptions higher up please. /// Save the entire library to file m_libFileName; -// void Save(); + void Save(); void Load(); + void AddSymbol( const LIB_PART* aPart ); + wxDateTime GetLibModificationTime(); bool IsFile( const wxString& aFullPathAndFileName ) const; @@ -1954,7 +1958,8 @@ public: SCH_LEGACY_PLUGIN_CACHE::SCH_LEGACY_PLUGIN_CACHE( const wxString& aFullPathAndFileName ) : m_libFileName( aFullPathAndFileName ), - m_isWritable( true ) + m_isWritable( true ), + m_isModified( false ) { m_versionMajor = -1; m_versionMinor = -1; @@ -2004,6 +2009,76 @@ bool SCH_LEGACY_PLUGIN_CACHE::IsFileChanged() const } +LIB_ALIAS* SCH_LEGACY_PLUGIN_CACHE::removeAlias( LIB_ALIAS* aAlias ) +{ + wxCHECK_MSG( aAlias != NULL, NULL, "NULL pointer cannot be removed from library." ); + + LIB_ALIAS_MAP::iterator it = m_aliases.find( aAlias->GetName() ); + + if( it == m_aliases.end() ) + return NULL; + + // If the entry pointer doesn't match the name it is mapped to in the library, we + // have done something terribly wrong. + wxCHECK_MSG( *it->second == aAlias, NULL, + "Pointer mismatch while attempting to remove alias entry <" + aAlias->GetName() + + "> from library cache <" + m_libFileName.GetName() + ">." ); + + LIB_ALIAS* alias = aAlias; + LIB_PART* part = alias->GetPart(); + + alias = part->RemoveAlias( alias ); + + if( !alias ) + { + delete part; + + if( m_aliases.size() > 1 ) + { + LIB_ALIAS_MAP::iterator next = it; + next++; + + if( next == m_aliases.end() ) + next = m_aliases.begin(); + + alias = next->second; + } + } + + m_aliases.erase( it ); + m_isModified = true; + ++m_modHash; + return alias; +} + + +void SCH_LEGACY_PLUGIN_CACHE::AddSymbol( const LIB_PART* aPart ) +{ + // add a clone, not the caller's copy + LIB_PART* part = new LIB_PART( *aPart ); + + wxArrayString aliasNames = aPart->GetAliasNames(); + + for( size_t i = 0; i < aliasNames.size(); i++ ) + { + LIB_ALIAS_MAP::iterator it = m_aliases.find( aliasNames[i] ); + + if( it != m_aliases.end() ) + removeAlias( it->second ); + + LIB_ALIAS* alias = aPart->GetAlias( aliasNames[i] ); + + wxASSERT_MSG( alias != NULL, "No alias <" + aliasNames[i] + "> found in symbol <" + + aPart->GetName() +">." ); + + m_aliases[ aliasNames[i] ] = alias; + } + + m_isModified = true; + ++m_modHash; +} + + void SCH_LEGACY_PLUGIN_CACHE::Load() { FILE_LINE_READER reader( m_libFileName.GetFullPath() ); @@ -3100,6 +3175,29 @@ void SCH_LEGACY_PLUGIN_CACHE::loadFootprintFilters( std::unique_ptr< LIB_PART >& } +void SCH_LEGACY_PLUGIN_CACHE::Save() +{ + if( !m_isModified ) + return; + + FILE_OUTPUTFORMATTER formatter( m_libFileName.GetFullPath() ); + formatter.Print( 0, "%s %d.%d\n", LIBFILE_IDENT, LIB_VERSION_MAJOR, LIB_VERSION_MINOR ); + formatter.Print( 0, "#encoding utf-8\n"); + + for( LIB_ALIAS_MAP::iterator it = m_aliases.begin(); it != m_aliases.end(); it++ ) + { + if( !it->second->IsRoot() ) + continue; + + it->second->GetPart()->Save( formatter ); + } + + formatter.Print( 0, "#\n#End Library\n" ); + m_fileModTime = m_libFileName.GetModificationTime(); + m_isModified = false; +} + + void SCH_LEGACY_PLUGIN::cacheLib( const wxString& aLibraryFileName ) { if( !m_cache || !m_cache->IsFile( aLibraryFileName ) || m_cache->IsFileChanged() ) @@ -3163,3 +3261,15 @@ LIB_ALIAS* SCH_LEGACY_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wx return it->second; } + + +void SCH_LEGACY_PLUGIN::SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol, + const PROPERTIES* aProperties ) +{ + m_props = aProperties; + + cacheLib( aLibraryPath ); + + m_cache->AddSymbol( aSymbol ); + m_cache->Save(); +} diff --git a/eeschema/sch_legacy_plugin.h b/eeschema/sch_legacy_plugin.h index 1439c1fad2..78973b04b6 100644 --- a/eeschema/sch_legacy_plugin.h +++ b/eeschema/sch_legacy_plugin.h @@ -88,6 +88,8 @@ public: const PROPERTIES* aProperties = NULL ); LIB_ALIAS* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName, const PROPERTIES* aProperties = NULL ); + void SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol, + const PROPERTIES* aProperties = NULL ); // Temporary for testing using PART_LIB instead of SCH_PLUGIN. void TransferCache( PART_LIB& aTarget ); diff --git a/eeschema/sch_plugin.cpp b/eeschema/sch_plugin.cpp index 3df4e3530d..33b5140333 100644 --- a/eeschema/sch_plugin.cpp +++ b/eeschema/sch_plugin.cpp @@ -83,7 +83,7 @@ LIB_ALIAS* SCH_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wxString& } -void SCH_PLUGIN::SymbolSave( const wxString& aLibraryPath, const LIB_PART* aSymbol, +void SCH_PLUGIN::SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol, const PROPERTIES* aProperties ) { // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.