Library Editor: enable part buffering for faster save, better 'save as' implementation
Previous 'save as' implementation simply copied the original file, so the buffered changes were not save.
This commit is contained in:
parent
9fcaa83b7d
commit
f6f1dff9d0
|
@ -136,6 +136,47 @@ bool LIB_MANAGER::FlushLibrary( const wxString& aLibrary )
|
|||
}
|
||||
|
||||
|
||||
bool LIB_MANAGER::SaveLibrary( const wxString& aLibrary, const wxString& aFileName )
|
||||
{
|
||||
wxCHECK( LibraryExists( aLibrary ), false );
|
||||
wxFileName fn( aFileName );
|
||||
wxCHECK( !fn.FileExists() || fn.IsFileWritable(), false );
|
||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
||||
bool res = true; // assume all libraries are successfully saved
|
||||
|
||||
auto it = m_libs.find( aLibrary );
|
||||
|
||||
if( it != m_libs.end() )
|
||||
{
|
||||
// Handle buffered library
|
||||
LIB_BUFFER& libBuf = it->second;
|
||||
|
||||
const auto& partBuffers = libBuf.GetBuffers();
|
||||
|
||||
for( const auto& partBuf : partBuffers )
|
||||
{
|
||||
if( !libBuf.SaveBuffer( partBuf, &*pi, true ) )
|
||||
{
|
||||
// Something went wrong, but try to save other libraries
|
||||
res = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle original library
|
||||
PROPERTIES properties;
|
||||
properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
|
||||
|
||||
for( auto part : getOriginalParts( aLibrary ) )
|
||||
pi->SaveSymbol( aLibrary, new LIB_PART( *part ), &properties );
|
||||
}
|
||||
|
||||
pi->SaveLibrary( aFileName );
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
bool LIB_MANAGER::IsLibraryModified( const wxString& aLibrary ) const
|
||||
{
|
||||
wxCHECK( LibraryExists( aLibrary ), false );
|
||||
|
@ -465,6 +506,22 @@ bool LIB_MANAGER::addLibrary( const wxString& aFilePath, bool aCreate )
|
|||
}
|
||||
|
||||
|
||||
std::set<LIB_PART*> LIB_MANAGER::getOriginalParts( const wxString& aLibrary )
|
||||
{
|
||||
wxArrayString aliases;
|
||||
std::set<LIB_PART*> parts;
|
||||
m_symbolTable->EnumerateSymbolLib( aLibrary, aliases );
|
||||
|
||||
for( const auto& aliasName : aliases )
|
||||
{
|
||||
LIB_ALIAS* alias = m_symbolTable->LoadSymbol( aLibrary, aliasName );
|
||||
parts.insert( alias->GetPart() );
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
|
||||
LIB_MANAGER::LIB_BUFFER& LIB_MANAGER::getLibraryBuffer( const wxString& aLibrary )
|
||||
{
|
||||
auto it = m_libs.find( aLibrary );
|
||||
|
@ -472,24 +529,11 @@ LIB_MANAGER::LIB_BUFFER& LIB_MANAGER::getLibraryBuffer( const wxString& aLibrary
|
|||
if( it != m_libs.end() )
|
||||
return it->second;
|
||||
|
||||
wxArrayString aliases;
|
||||
auto ret = m_libs.emplace( aLibrary, LIB_BUFFER( aLibrary ) );
|
||||
LIB_BUFFER& buf = ret.first->second;
|
||||
m_symbolTable->EnumerateSymbolLib( aLibrary, aliases );
|
||||
// set collecting the processed LIB_PARTs
|
||||
std::set<LIB_PART*> processed;
|
||||
|
||||
for( const auto& aliasName : aliases )
|
||||
{
|
||||
LIB_ALIAS* alias = m_symbolTable->LoadSymbol( aLibrary, aliasName );
|
||||
LIB_PART* part = alias->GetPart();
|
||||
|
||||
if( !processed.count( part ) )
|
||||
{
|
||||
buf.CreateBuffer( new LIB_PART( *part, nullptr ), new SCH_SCREEN( &m_frame.Kiway() ) );
|
||||
processed.insert( part );
|
||||
}
|
||||
}
|
||||
for( auto part : getOriginalParts( aLibrary ) )
|
||||
buf.CreateBuffer( new LIB_PART( *part, nullptr ), new SCH_SCREEN( &m_frame.Kiway() ) );
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
@ -555,7 +599,6 @@ bool LIB_MANAGER::LIB_BUFFER::CreateBuffer( LIB_PART* aCopy, SCH_SCREEN* aScreen
|
|||
|
||||
// Set the parent library name,
|
||||
// otherwise it is empty as no library has been given as the owner during object construction
|
||||
// TODO create a class derived from
|
||||
LIB_ID& libId = (LIB_ID&) aCopy->GetLibId();
|
||||
libId.SetLibNickname( m_libName );
|
||||
++m_hash;
|
||||
|
@ -593,23 +636,34 @@ bool LIB_MANAGER::LIB_BUFFER::SaveBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf
|
|||
SYMBOL_LIB_TABLE* aLibTable )
|
||||
{
|
||||
wxCHECK( aPartBuf, false );
|
||||
LIB_PART* part = aPartBuf->GetPart();
|
||||
wxCHECK( part, false );
|
||||
wxCHECK( aLibTable->SaveSymbol( m_libName, new LIB_PART( *part ) ) != SYMBOL_LIB_TABLE::SAVE_OK, false );
|
||||
|
||||
aPartBuf->GetScreen()->ClrModify();
|
||||
aPartBuf->SetOriginal( new LIB_PART( *part ) );
|
||||
++m_hash;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LIB_MANAGER::LIB_BUFFER::SaveBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf,
|
||||
SCH_PLUGIN* aPlugin, bool aBuffer )
|
||||
{
|
||||
wxCHECK( aPartBuf, false );
|
||||
LIB_PART* part = aPartBuf->GetPart();
|
||||
wxCHECK( part, false );
|
||||
|
||||
// TODO Enable buffering to avoid to disable too frequent file saves
|
||||
//PROPERTIES properties;
|
||||
//properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
|
||||
// set properties to prevent save file on every symbol save
|
||||
PROPERTIES properties;
|
||||
properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
|
||||
|
||||
if( aLibTable->SaveSymbol( m_libName, new LIB_PART( *part ) ) == SYMBOL_LIB_TABLE::SAVE_OK )
|
||||
{
|
||||
aPartBuf->GetScreen()->ClrModify();
|
||||
aPartBuf->SetOriginal( new LIB_PART( *part ) );
|
||||
++m_hash;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
// TODO there is no way to check if symbol has been successfully saved
|
||||
aPlugin->SaveSymbol( m_libName, new LIB_PART( *part ), aBuffer ? &properties : nullptr );
|
||||
aPartBuf->GetScreen()->ClrModify();
|
||||
aPartBuf->SetOriginal( new LIB_PART( *part ) );
|
||||
++m_hash;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ class LIB_PART;
|
|||
class LIB_BUFFER;
|
||||
class PART_LIB;
|
||||
class SCH_SCREEN;
|
||||
class SCH_PLUGIN;
|
||||
class LIB_EDIT_FRAME;
|
||||
class SYMBOL_LIB_TABLE;
|
||||
|
||||
|
@ -163,6 +164,14 @@ public:
|
|||
*/
|
||||
bool FlushLibrary( const wxString& aLibrary );
|
||||
|
||||
/**
|
||||
* Saves library to a file, including unsaved changes.
|
||||
* @param aLibrary is the library name.
|
||||
* @param aFileName is the target file name.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
bool SaveLibrary( const wxString& aLibrary, const wxString& aFileName );
|
||||
|
||||
/**
|
||||
* Saves all changes to libraries.
|
||||
* @return True if all changes have been flushed successfully, false otherwise.
|
||||
|
@ -328,9 +337,14 @@ private:
|
|||
m_deleted.clear();
|
||||
}
|
||||
|
||||
///> Saves stored modifications to a Symbol Library Table
|
||||
///> Saves stored modifications to Symbol Lib Table. It may result in saving the symbol
|
||||
///> to disk as well, depending on the row properties.
|
||||
bool SaveBuffer( PART_BUFFER::PTR aPartBuf, SYMBOL_LIB_TABLE* aLibTable );
|
||||
|
||||
///> Saves stored modificatiosn using a plugin. aBuffer decides whether the changes
|
||||
///> should be cached or stored directly to the disk (for SCH_LEGACY_PLUGIN).
|
||||
bool SaveBuffer( PART_BUFFER::PTR aPartBuf, SCH_PLUGIN* aPlugin, bool aBuffer );
|
||||
|
||||
///> Returns a part buffer with LIB_PART holding a particular alias
|
||||
PART_BUFFER::PTR GetBuffer( const wxString& aAlias ) const
|
||||
{
|
||||
|
@ -371,6 +385,9 @@ private:
|
|||
friend class PART_BUFFER;
|
||||
};
|
||||
|
||||
///> Returns a set of LIB_PART objects belonging to the original library
|
||||
std::set<LIB_PART*> getOriginalParts( const wxString& aLibrary );
|
||||
|
||||
///> Returns an existing library buffer or creates one to using
|
||||
///> Symbol Library Table to get the original data.
|
||||
LIB_BUFFER& getLibraryBuffer( const wxString& aLibrary );
|
||||
|
|
|
@ -535,10 +535,9 @@ bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
|
|||
}
|
||||
|
||||
wxFileName docFileName = libFileName;
|
||||
|
||||
docFileName.SetExt( DOC_EXT );
|
||||
|
||||
// Copy .dcm file to .bck.
|
||||
// Copy .dcm file to .bck. // handle
|
||||
if( docFileName.FileExists() )
|
||||
{
|
||||
backupFileName.SetExt( "bck" );
|
||||
|
@ -555,39 +554,12 @@ bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
|
|||
}
|
||||
}
|
||||
|
||||
// Copy the library and document files to the new destination library files.
|
||||
if( aNewFile )
|
||||
if( !m_libMgr->SaveLibrary( aLibrary, libFileName.GetFullPath() ) )
|
||||
{
|
||||
wxFileName src = prj.SchSymbolLibTable()->GetFullURI( GetCurLib() );
|
||||
|
||||
if( !wxCopyFile( src.GetFullPath(), libFileName.GetFullPath() ) )
|
||||
{
|
||||
msg.Printf( _( "Failed to copy symbol library file '%s'" ), libFileName.GetFullPath() );
|
||||
DisplayError( this, msg );
|
||||
return false;
|
||||
}
|
||||
|
||||
src.SetExt( DOC_EXT );
|
||||
|
||||
if( !wxCopyFile( src.GetFullPath(), docFileName.GetFullPath() ) )
|
||||
{
|
||||
msg.Printf( _( "Failed to copy symbol library document file '%s'" ),
|
||||
docFileName.GetFullPath() );
|
||||
DisplayError( this, msg );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Update symbol changes in library.
|
||||
if( GetScreen()->IsModify() )
|
||||
{
|
||||
if( !m_libMgr->FlushLibrary( aLibrary ) )
|
||||
{
|
||||
msg.Printf( _( "Failed to save changes to symbol library file '%s'" ),
|
||||
libFileName.GetFullPath() );
|
||||
DisplayErrorMessage( this, _( "Error saving library" ), msg );
|
||||
return false;
|
||||
}
|
||||
msg.Printf( _( "Failed to save changes to symbol library file '%s'" ),
|
||||
libFileName.GetFullPath() );
|
||||
DisplayErrorMessage( this, _( "Error saving library" ), msg );
|
||||
return false;
|
||||
}
|
||||
|
||||
msg.Printf( _( "Symbol library file '%s' saved" ), libFileName.GetFullPath() );
|
||||
|
|
Loading…
Reference in New Issue