From 2b94b7df77f6a237c7dcdda79c2a0bcf906ba7c2 Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Sat, 10 Dec 2022 16:35:11 -0500 Subject: [PATCH] DbLibs: Support empty virtual table names Fixes https://gitlab.com/kicad/code/kicad/-/issues/12902 --- .../database/sch_database_plugin.cpp | 75 +++++++++++++------ eeschema/symbol_tree_model_adapter.cpp | 4 +- 2 files changed, 57 insertions(+), 22 deletions(-) diff --git a/eeschema/sch_plugins/database/sch_database_plugin.cpp b/eeschema/sch_plugins/database/sch_database_plugin.cpp index 1e94f2aaba..0fbd519328 100644 --- a/eeschema/sch_plugins/database/sch_database_plugin.cpp +++ b/eeschema/sch_plugins/database/sch_database_plugin.cpp @@ -90,7 +90,8 @@ void SCH_DATABASE_PLUGIN::EnumerateSymbolLib( std::vector& aSymbolL if( !result.count( table.key_col ) ) continue; - wxString name( fmt::format( "{}/{}", table.name, + std::string prefix = table.name.empty() ? "" : fmt::format( "{}/", table.name ); + wxString name( fmt::format( "{}{}", prefix, std::any_cast( result[table.key_col] ) ) ); LIB_SYMBOL* symbol = loadSymbolFromRow( name, table, result ); @@ -110,36 +111,60 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::LoadSymbol( const wxString& aLibraryPath, ensureSettings( aLibraryPath ); ensureConnection(); - const DATABASE_LIB_TABLE* table = nullptr; + /* + * Table names are tricky, in order to allow maximum flexibility to the user. + * The slash character is used as a separator between a table name and symbol name, but symbol + * names may also contain slashes and table names may now also be empty (which results in the + * slash being dropped in the symbol name when placing a new symbol). So, if a slash is found, + * we check if the string before the slash is a valid table name. If not, we assume the table + * name is blank if our config has an entry for the null table. + */ - std::string tableName( aAliasName.BeforeFirst( '/' ).ToUTF8() ); - std::string symbolName( aAliasName.AfterFirst( '/' ).ToUTF8() ); + std::string tableName = ""; + std::string symbolName( aAliasName.ToUTF8() ); + + if( aAliasName.Contains( '/' ) ) + { + tableName = std::string( aAliasName.BeforeFirst( '/' ).ToUTF8() ); + symbolName = std::string( aAliasName.AfterFirst( '/' ).ToUTF8() ); + } + + std::vector tablesToTry; for( const DATABASE_LIB_TABLE& tableIter : m_settings->m_Tables ) { if( tableIter.name == tableName ) + tablesToTry.emplace_back( &tableIter ); + } + + if( tablesToTry.empty() ) + { + wxLogTrace( traceDatabase, wxT( "LoadSymbol: table '%s' not found in config" ), tableName ); + return nullptr; + } + + const DATABASE_LIB_TABLE* foundTable = nullptr; + DATABASE_CONNECTION::ROW result; + + for( const DATABASE_LIB_TABLE* table : tablesToTry ) + { + if( m_conn->SelectOne( table->table, std::make_pair( table->key_col, symbolName ), + result ) ) { - table = &tableIter; - break; + foundTable = table; + wxLogTrace( traceDatabase, wxT( "LoadSymbol: SelectOne (%s, %s) found in %s" ), + table->key_col, symbolName, table->table ); + } + else + { + wxLogTrace( traceDatabase, wxT( "LoadSymbol: SelectOne (%s, %s) failed for table %s" ), + table->key_col, symbolName, table->table ); } } - if( !table ) - { - wxLogTrace( traceDatabase, wxT( "LoadSymbol: table %s not found in config" ), tableName ); - return nullptr; - } + wxCHECK( foundTable, nullptr ); - DATABASE_CONNECTION::ROW result; - - if( !m_conn->SelectOne( table->table, std::make_pair( table->key_col, symbolName ), result ) ) - { - wxLogTrace( traceDatabase, wxT( "LoadSymbol: SelectOne (%s, %s) failed" ), table->key_col, - symbolName ); - return nullptr; - } - - return loadSymbolFromRow( aAliasName, *table, result ); + return loadSymbolFromRow( aAliasName, *foundTable, result ); } @@ -149,8 +174,16 @@ void SCH_DATABASE_PLUGIN::GetSubLibraryNames( std::vector& aNames ) aNames.clear(); + std::set tableNames; + for( const DATABASE_LIB_TABLE& tableIter : m_settings->m_Tables ) + { + if( tableNames.count( tableIter.name ) ) + continue; + aNames.emplace_back( tableIter.name ); + tableNames.insert( tableIter.name ); + } } diff --git a/eeschema/symbol_tree_model_adapter.cpp b/eeschema/symbol_tree_model_adapter.cpp index 5afdedffb7..00a98de0ae 100644 --- a/eeschema/symbol_tree_model_adapter.cpp +++ b/eeschema/symbol_tree_model_adapter.cpp @@ -153,7 +153,9 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector& aNick for( const wxString& lib : subLibraries ) { - wxString name = wxString::Format( wxT( "%s - %s" ), pair.first, lib ); + wxString suffix = lib.IsEmpty() ? wxT( "" ) + : wxString::Format( wxT( " - %s" ), lib ); + wxString name = wxString::Format( wxT( "%s%s" ), pair.first, suffix ); wxString desc; if( !parentDesc.IsEmpty() )