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_itemName.clear();
|
||||
m_subLibraryName.clear();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ public:
|
|||
virtual void SetName( const wxString& aName );
|
||||
wxString GetName() const override { return m_name; }
|
||||
|
||||
LIB_ID& LibId() { return m_libId; }
|
||||
LIB_ID GetLibId() const override { return m_libId; }
|
||||
void SetLibId( const LIB_ID& aLibId ) { m_libId = aLibId; }
|
||||
|
||||
|
|
|
@ -443,6 +443,25 @@ public:
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
// 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 )
|
||||
{
|
||||
if( !m_settings )
|
||||
if( !m_settings && !aSettingsPath.IsEmpty() )
|
||||
{
|
||||
std::string path( aSettingsPath.ToUTF8() );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
else
|
||||
else if( !m_settings )
|
||||
{
|
||||
wxASSERT_MSG( aSettingsPath == m_settings->GetFilename(),
|
||||
"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->LibId().SetSubLibraryName( aTable.name );
|
||||
|
||||
if( aRow.count( aTable.footprints_col ) )
|
||||
{
|
||||
// TODO: Support multiple footprint choices
|
||||
|
|
|
@ -73,6 +73,10 @@ public:
|
|||
LIB_SYMBOL* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
|
||||
const PROPERTIES* aProperties = nullptr ) override;
|
||||
|
||||
bool SupportsSubLibraries() const override { return true; }
|
||||
|
||||
void GetSubLibraryNames( std::vector<wxString>& aNames ) override;
|
||||
|
||||
bool CheckHeader( const wxString& aFileName ) override;
|
||||
|
||||
// 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 ) :
|
||||
LIB_TABLE( aFallBackTable )
|
||||
{
|
||||
|
|
|
@ -80,6 +80,10 @@ public:
|
|||
*/
|
||||
bool Refresh();
|
||||
|
||||
bool SupportsSubLibraries() const { return plugin ? plugin->SupportsSubLibraries() : false; }
|
||||
|
||||
void GetSubLibraryNames( std::vector<wxString>& aNames ) const;
|
||||
|
||||
protected:
|
||||
SYMBOL_LIB_TABLE_ROW( const SYMBOL_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();
|
||||
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 )
|
||||
{
|
||||
if( !m_libs->FindRow( pair.first )->GetIsVisible() )
|
||||
SYMBOL_LIB_TABLE_ROW* row = m_libs->FindRow( pair.first );
|
||||
|
||||
if( !row->GetIsVisible() )
|
||||
continue;
|
||||
|
||||
std::vector<LIB_TREE_ITEM*> treeItems( pair.second.begin(), pair.second.end() );
|
||||
bool pinned = alg::contains( cfg->m_Session.pinned_symbol_libs, pair.first )
|
||||
|| alg::contains( project.m_PinnedSymbolLibs, pair.first );
|
||||
if( row->SupportsSubLibraries() )
|
||||
{
|
||||
std::vector<wxString> subLibraries;
|
||||
row->GetSubLibraryNames( subLibraries );
|
||||
|
||||
DoAddLibrary( pair.first, m_libs->GetDescription( pair.first ), treeItems, pinned,
|
||||
false );
|
||||
wxString parentDesc = m_libs->GetDescription( pair.first );
|
||||
|
||||
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 );
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
@ -253,6 +263,7 @@ protected:
|
|||
|
||||
UTF8 m_libraryName; ///< The nickname of the library or empty.
|
||||
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