Add support for sub-libraries concept
Sub-libraries allow a single-level hierarchy inside a symbol library. This is useful for database libraries and for supporting other EDA library types where a single file can contain multiple logical groupings of symbols.
This commit is contained in:
parent
a76d1a791d
commit
49354e52a8
|
@ -43,6 +43,7 @@ void LIB_ID::clear()
|
||||||
{
|
{
|
||||||
m_libraryName.clear();
|
m_libraryName.clear();
|
||||||
m_itemName.clear();
|
m_itemName.clear();
|
||||||
|
m_subLibraryName.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,7 @@ public:
|
||||||
virtual void SetName( const wxString& aName );
|
virtual void SetName( const wxString& aName );
|
||||||
wxString GetName() const override { return m_name; }
|
wxString GetName() const override { return m_name; }
|
||||||
|
|
||||||
|
LIB_ID& LibId() { return m_libId; }
|
||||||
LIB_ID GetLibId() const override { return m_libId; }
|
LIB_ID GetLibId() const override { return m_libId; }
|
||||||
void SetLibId( const LIB_ID& aLibId ) { m_libId = aLibId; }
|
void SetLibId( const LIB_ID& aLibId ) { m_libId = aLibId; }
|
||||||
|
|
||||||
|
|
|
@ -443,6 +443,25 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void SymbolLibOptions( PROPERTIES* aListToAppendTo ) const;
|
virtual void SymbolLibOptions( PROPERTIES* aListToAppendTo ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this plugin supports libraries that contain sub-libraries.
|
||||||
|
*/
|
||||||
|
virtual bool SupportsSubLibraries() const { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a list of sub-libraries in this library.
|
||||||
|
*
|
||||||
|
* Some types of symbol library support sub-libraries, which are a single-level organizational
|
||||||
|
* hierarchy that is implementation-defined per plugin. Most of KiCad ignores sub-libraries and
|
||||||
|
* treats the hierarchy between library and symbol as flat, but the sub-libraries are used for
|
||||||
|
* sorting and grouping symbols in the symbol chooser.
|
||||||
|
*
|
||||||
|
* Has no effect if SupportsSubLibraries() returns false.
|
||||||
|
*
|
||||||
|
* @param aNames will be filled with a list of sub-libraries within this symbol library
|
||||||
|
*/
|
||||||
|
virtual void GetSubLibraryNames( std::vector<wxString>& aNames ) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the first line in @a aFileName begins with the expected header.
|
* Return true if the first line in @a aFileName begins with the expected header.
|
||||||
*
|
*
|
||||||
|
|
|
@ -142,6 +142,17 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::LoadSymbol( const wxString& aLibraryPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_DATABASE_PLUGIN::GetSubLibraryNames( std::vector<wxString>& aNames )
|
||||||
|
{
|
||||||
|
ensureSettings( wxEmptyString );
|
||||||
|
|
||||||
|
aNames.clear();
|
||||||
|
|
||||||
|
for( const DATABASE_LIB_TABLE& tableIter : m_settings->m_Tables )
|
||||||
|
aNames.emplace_back( tableIter.name );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_DATABASE_PLUGIN::CheckHeader( const wxString& aFileName )
|
bool SCH_DATABASE_PLUGIN::CheckHeader( const wxString& aFileName )
|
||||||
{
|
{
|
||||||
// TODO: Implement this sometime; but CheckHeader isn't even called...
|
// TODO: Implement this sometime; but CheckHeader isn't even called...
|
||||||
|
@ -151,7 +162,7 @@ bool SCH_DATABASE_PLUGIN::CheckHeader( const wxString& aFileName )
|
||||||
|
|
||||||
void SCH_DATABASE_PLUGIN::ensureSettings( const wxString& aSettingsPath )
|
void SCH_DATABASE_PLUGIN::ensureSettings( const wxString& aSettingsPath )
|
||||||
{
|
{
|
||||||
if( !m_settings )
|
if( !m_settings && !aSettingsPath.IsEmpty() )
|
||||||
{
|
{
|
||||||
std::string path( aSettingsPath.ToUTF8() );
|
std::string path( aSettingsPath.ToUTF8() );
|
||||||
m_settings = std::make_unique<DATABASE_LIB_SETTINGS>( path );
|
m_settings = std::make_unique<DATABASE_LIB_SETTINGS>( path );
|
||||||
|
@ -166,7 +177,7 @@ void SCH_DATABASE_PLUGIN::ensureSettings( const wxString& aSettingsPath )
|
||||||
THROW_IO_ERROR( msg );
|
THROW_IO_ERROR( msg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if( !m_settings )
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( aSettingsPath == m_settings->GetFilename(),
|
wxASSERT_MSG( aSettingsPath == m_settings->GetFilename(),
|
||||||
"Path changed for database library without re-initializing plugin!" );
|
"Path changed for database library without re-initializing plugin!" );
|
||||||
|
@ -251,6 +262,8 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
|
||||||
symbol->SetName( aSymbolName );
|
symbol->SetName( aSymbolName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
symbol->LibId().SetSubLibraryName( aTable.name );
|
||||||
|
|
||||||
if( aRow.count( aTable.footprints_col ) )
|
if( aRow.count( aTable.footprints_col ) )
|
||||||
{
|
{
|
||||||
// TODO: Support multiple footprint choices
|
// TODO: Support multiple footprint choices
|
||||||
|
|
|
@ -73,6 +73,10 @@ public:
|
||||||
LIB_SYMBOL* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
|
LIB_SYMBOL* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
|
||||||
const PROPERTIES* aProperties = nullptr ) override;
|
const PROPERTIES* aProperties = nullptr ) override;
|
||||||
|
|
||||||
|
bool SupportsSubLibraries() const override { return true; }
|
||||||
|
|
||||||
|
void GetSubLibraryNames( std::vector<wxString>& aNames ) override;
|
||||||
|
|
||||||
bool CheckHeader( const wxString& aFileName ) override;
|
bool CheckHeader( const wxString& aFileName ) override;
|
||||||
|
|
||||||
// Database libraries can never be written using the symbol editing API
|
// Database libraries can never be written using the symbol editing API
|
||||||
|
|
|
@ -86,6 +86,15 @@ bool SYMBOL_LIB_TABLE_ROW::Refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SYMBOL_LIB_TABLE_ROW::GetSubLibraryNames( std::vector<wxString>& aNames ) const
|
||||||
|
{
|
||||||
|
if( !plugin )
|
||||||
|
return;
|
||||||
|
|
||||||
|
plugin->GetSubLibraryNames( aNames );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SYMBOL_LIB_TABLE::SYMBOL_LIB_TABLE( SYMBOL_LIB_TABLE* aFallBackTable ) :
|
SYMBOL_LIB_TABLE::SYMBOL_LIB_TABLE( SYMBOL_LIB_TABLE* aFallBackTable ) :
|
||||||
LIB_TABLE( aFallBackTable )
|
LIB_TABLE( aFallBackTable )
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,10 @@ public:
|
||||||
*/
|
*/
|
||||||
bool Refresh();
|
bool Refresh();
|
||||||
|
|
||||||
|
bool SupportsSubLibraries() const { return plugin ? plugin->SupportsSubLibraries() : false; }
|
||||||
|
|
||||||
|
void GetSubLibraryNames( std::vector<wxString>& aNames ) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SYMBOL_LIB_TABLE_ROW( const SYMBOL_LIB_TABLE_ROW& aRow ) :
|
SYMBOL_LIB_TABLE_ROW( const SYMBOL_LIB_TABLE_ROW& aRow ) :
|
||||||
LIB_TABLE_ROW( aRow ),
|
LIB_TABLE_ROW( aRow ),
|
||||||
|
|
|
@ -118,17 +118,55 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
|
||||||
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
||||||
PROJECT_FILE& project = aFrame->Prj().GetProjectFile();
|
PROJECT_FILE& project = aFrame->Prj().GetProjectFile();
|
||||||
|
|
||||||
|
auto addFunc =
|
||||||
|
[&]( const wxString& aLibName, std::vector<LIB_SYMBOL*> aSymbolList,
|
||||||
|
const wxString& aDescription )
|
||||||
|
{
|
||||||
|
std::vector<LIB_TREE_ITEM*> treeItems( aSymbolList.begin(), aSymbolList.end() );
|
||||||
|
bool pinned = alg::contains( cfg->m_Session.pinned_symbol_libs, aLibName )
|
||||||
|
|| alg::contains( project.m_PinnedSymbolLibs, aLibName );
|
||||||
|
|
||||||
|
DoAddLibrary( aLibName, aDescription, treeItems, pinned, false );
|
||||||
|
};
|
||||||
|
|
||||||
for( const std::pair<const wxString, std::vector<LIB_SYMBOL*>>& pair : loadedSymbols )
|
for( const std::pair<const wxString, std::vector<LIB_SYMBOL*>>& pair : loadedSymbols )
|
||||||
{
|
{
|
||||||
if( !m_libs->FindRow( pair.first )->GetIsVisible() )
|
SYMBOL_LIB_TABLE_ROW* row = m_libs->FindRow( pair.first );
|
||||||
|
|
||||||
|
if( !row->GetIsVisible() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::vector<LIB_TREE_ITEM*> treeItems( pair.second.begin(), pair.second.end() );
|
if( row->SupportsSubLibraries() )
|
||||||
bool pinned = alg::contains( cfg->m_Session.pinned_symbol_libs, pair.first )
|
{
|
||||||
|| alg::contains( project.m_PinnedSymbolLibs, pair.first );
|
std::vector<wxString> subLibraries;
|
||||||
|
row->GetSubLibraryNames( subLibraries );
|
||||||
|
|
||||||
DoAddLibrary( pair.first, m_libs->GetDescription( pair.first ), treeItems, pinned,
|
wxString parentDesc = m_libs->GetDescription( pair.first );
|
||||||
false );
|
|
||||||
|
for( const wxString& lib : subLibraries )
|
||||||
|
{
|
||||||
|
wxString name = wxString::Format( wxT( "%s - %s" ), pair.first, lib );
|
||||||
|
wxString desc;
|
||||||
|
|
||||||
|
if( !parentDesc.IsEmpty() )
|
||||||
|
desc = wxString::Format( wxT( "%s (%s)" ), parentDesc, lib );
|
||||||
|
|
||||||
|
std::vector<LIB_SYMBOL*> symbols;
|
||||||
|
|
||||||
|
std::copy_if( pair.second.begin(), pair.second.end(),
|
||||||
|
std::back_inserter( symbols ),
|
||||||
|
[&lib]( LIB_SYMBOL* aSym )
|
||||||
|
{
|
||||||
|
return lib.IsSameAs( aSym->GetLibId().GetSubLibraryName() );
|
||||||
|
} );
|
||||||
|
|
||||||
|
addFunc( name, symbols, desc );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addFunc( pair.first, pair.second, m_libs->GetDescription( pair.first ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,16 @@ public:
|
||||||
*/
|
*/
|
||||||
int SetLibItemName( const UTF8& aLibItemName );
|
int SetLibItemName( const UTF8& aLibItemName );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some LIB_IDs can have a sub-library identifier in addition to a library nickname.
|
||||||
|
* This identifier is *not* part of the canonical LIB_ID and is not written out / parsed.
|
||||||
|
* It is only used for internal sorting/grouping, if present.
|
||||||
|
*
|
||||||
|
* @return the sub-library name for this LIB_ID, if one exists
|
||||||
|
*/
|
||||||
|
UTF8 GetSubLibraryName() const { return m_subLibraryName; }
|
||||||
|
void SetSubLibraryName( const UTF8& aName ) { m_subLibraryName = aName; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the fully formatted text of the LIB_ID in a UTF8 string.
|
* @return the fully formatted text of the LIB_ID in a UTF8 string.
|
||||||
*/
|
*/
|
||||||
|
@ -253,6 +263,7 @@ protected:
|
||||||
|
|
||||||
UTF8 m_libraryName; ///< The nickname of the library or empty.
|
UTF8 m_libraryName; ///< The nickname of the library or empty.
|
||||||
UTF8 m_itemName; ///< The name of the entry in the logical library.
|
UTF8 m_itemName; ///< The name of the entry in the logical library.
|
||||||
|
UTF8 m_subLibraryName; ///< Optional sub-library name used for grouping within a library
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue