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.
This commit is contained in:
Wayne Stambaugh 2016-09-17 13:31:58 -04:00
parent 6117713f33
commit 3ae240ea46
7 changed files with 132 additions and 18 deletions

View File

@ -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() )
{

View File

@ -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();

View File

@ -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++ )
{

View File

@ -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 );
/**

View File

@ -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();
}

View File

@ -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 );

View File

@ -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.