diff --git a/common/design_block_io.cpp b/common/design_block_io.cpp index d38d9ee288..88f81ca989 100644 --- a/common/design_block_io.cpp +++ b/common/design_block_io.cpp @@ -39,13 +39,16 @@ #include #include #include +#include +#include const wxString DESIGN_BLOCK_IO_MGR::ShowType( DESIGN_BLOCK_FILE_T aFileType ) { switch( aFileType ) { - case KICAD_SEXP: return _( "KiCad" ); - default: return wxString::Format( _( "UNKNOWN (%d)" ), aFileType ); + case KICAD_SEXP: return _( "KiCad" ); + case NESTED_TABLE: return LIBRARY_TABLE_ROW::TABLE_TYPE_NAME; + default: return wxString::Format( _( "UNKNOWN (%d)" ), aFileType ); } } @@ -54,7 +57,9 @@ DESIGN_BLOCK_IO_MGR::DESIGN_BLOCK_FILE_T DESIGN_BLOCK_IO_MGR::EnumFromStr( const wxString& aFileType ) { if( aFileType == _( "KiCad" ) ) - return DESIGN_BLOCK_FILE_T( KICAD_SEXP ); + return DESIGN_BLOCK_FILE_T::KICAD_SEXP; + else if( aFileType == LIBRARY_TABLE_ROW::TABLE_TYPE_NAME ) + return DESIGN_BLOCK_FILE_T::NESTED_TABLE; return DESIGN_BLOCK_FILE_T( DESIGN_BLOCK_FILE_UNKNOWN ); } @@ -64,8 +69,8 @@ DESIGN_BLOCK_IO* DESIGN_BLOCK_IO_MGR::FindPlugin( DESIGN_BLOCK_FILE_T aFileType { switch( aFileType ) { - case KICAD_SEXP: return new DESIGN_BLOCK_IO(); - default: return nullptr; + case KICAD_SEXP: return new DESIGN_BLOCK_IO(); + default: return nullptr; } } @@ -73,6 +78,11 @@ DESIGN_BLOCK_IO* DESIGN_BLOCK_IO_MGR::FindPlugin( DESIGN_BLOCK_FILE_T aFileType DESIGN_BLOCK_IO_MGR::DESIGN_BLOCK_FILE_T DESIGN_BLOCK_IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath, int aCtl ) { + LIBRARY_TABLE_PARSER parser; + + if( parser.Parse( aLibPath.ToStdString() ).has_value() ) + return NESTED_TABLE; + if( IO_RELEASER( FindPlugin( KICAD_SEXP ) )->CanReadLibrary( aLibPath ) && aCtl != KICTL_NONKICAD_ONLY ) { @@ -95,8 +105,7 @@ bool DESIGN_BLOCK_IO_MGR::ConvertLibrary( std::map* aOldFileP IO_RELEASER oldFilePI( DESIGN_BLOCK_IO_MGR::FindPlugin( oldFileType ) ); - IO_RELEASER kicadPI( - DESIGN_BLOCK_IO_MGR::FindPlugin( DESIGN_BLOCK_IO_MGR::KICAD_SEXP ) ); + IO_RELEASER kicadPI( DESIGN_BLOCK_IO_MGR::FindPlugin( DESIGN_BLOCK_IO_MGR::KICAD_SEXP ) ); wxArrayString dbNames; wxFileName newFileName( aNewFilePath ); @@ -118,8 +127,8 @@ bool DESIGN_BLOCK_IO_MGR::ConvertLibrary( std::map* aOldFileP for( const wxString& dbName : dbNames ) { - std::unique_ptr db( - oldFilePI->GetEnumeratedDesignBlock( aOldFilePath, dbName, aOldFileProps ) ); + std::unique_ptr db( oldFilePI->GetEnumeratedDesignBlock( aOldFilePath, dbName, + aOldFileProps ) ); kicadPI->DesignBlockSave( aNewFilePath, db.get() ); } } @@ -227,8 +236,7 @@ bool DESIGN_BLOCK_IO::DeleteLibrary( const wxString& aLibrary if( tmp.GetExt() != FILEEXT::KiCadDesignBlockLibPathExtension ) { - THROW_IO_ERROR( wxString::Format( _( "Unexpected folder '%s' found in library " - "path '%s'." ), + THROW_IO_ERROR( wxString::Format( _( "Unexpected folder '%s' found in library path '%s'." ), dirs[i].GetData(), aLibraryPath.GetData() ) ); } } @@ -340,8 +348,8 @@ DESIGN_BLOCK* DESIGN_BLOCK_IO::DesignBlockLoad( const wxString& aLibraryPath, catch( ... ) { delete newDB; - THROW_IO_ERROR( wxString::Format( - _( "Design block metadata file '%s' could not be read." ), dbMetadataPath ) ); + THROW_IO_ERROR( wxString::Format( _( "Design block metadata file '%s' could not be read." ), + dbMetadataPath ) ); } } diff --git a/common/design_block_io.h b/common/design_block_io.h index aa1598651b..45c70ca0e0 100644 --- a/common/design_block_io.h +++ b/common/design_block_io.h @@ -40,7 +40,8 @@ public: DESIGN_BLOCK_FILE_UNKNOWN = 0, ///< 0 is not a legal menu id on Mac KICAD_SEXP, ///< S-expression KiCad file format. - FILE_TYPE_NONE + FILE_TYPE_NONE, + NESTED_TABLE }; static const wxString ShowType( DESIGN_BLOCK_FILE_T aFileType ); diff --git a/common/dialogs/panel_design_block_lib_table.cpp b/common/dialogs/panel_design_block_lib_table.cpp index d6a0a57e9f..88f0263e30 100644 --- a/common/dialogs/panel_design_block_lib_table.cpp +++ b/common/dialogs/panel_design_block_lib_table.cpp @@ -176,10 +176,8 @@ public: DESIGN_BLOCK_IO_MGR::DESIGN_BLOCK_FILE_T pluginType = DESIGN_BLOCK_IO_MGR::GuessPluginTypeFromLibPath( uri ); - if( pluginType == DESIGN_BLOCK_IO_MGR::FILE_TYPE_NONE ) - pluginType = DESIGN_BLOCK_IO_MGR::KICAD_SEXP; - - SetValue( aRow, COL_TYPE, DESIGN_BLOCK_IO_MGR::ShowType( pluginType ) ); + if( pluginType != DESIGN_BLOCK_IO_MGR::FILE_TYPE_NONE ) + SetValue( aRow, COL_TYPE, DESIGN_BLOCK_IO_MGR::ShowType( pluginType ) ); } } diff --git a/eeschema/dialogs/panel_sym_lib_table.cpp b/eeschema/dialogs/panel_sym_lib_table.cpp index 750159d9e9..d6e8b7b29b 100644 --- a/eeschema/dialogs/panel_sym_lib_table.cpp +++ b/eeschema/dialogs/panel_sym_lib_table.cpp @@ -603,10 +603,9 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event ) { // The cancel button adds the library to the table anyway addDuplicates = OKOrCancelDialog( wxGetTopLevelParent( this ), _( "Warning: Duplicate Nickname" ), - wxString::Format( _( "A library nicknamed '%s' already exists." ), + wxString::Format( _( "An item nicknamed '%s' already exists." ), nickname ), - _( "One of the nicknames will need to be changed after adding " - "this library." ), + _( "One of the nicknames will need to be changed." ), _( "Skip" ), _( "Add Anyway" ), &applyToAll ) == wxID_CANCEL; } @@ -623,10 +622,8 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event ) // attempt to auto-detect the plugin type SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromLibPath( filePath ); - if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN ) - pluginType = SCH_IO_MGR::SCH_KICAD; - - m_cur_grid->SetCellValue( last_row, COL_TYPE, SCH_IO_MGR::ShowType( pluginType ) ); + if( pluginType != SCH_IO_MGR::SCH_FILE_UNKNOWN ) + m_cur_grid->SetCellValue( last_row, COL_TYPE, SCH_IO_MGR::ShowType( pluginType ) ); // try to use path normalized to an environmental variable or project path wxString path = NormalizePath( filePath, &envVars, m_project->GetProjectPath() ); diff --git a/eeschema/sch_io/sch_io_mgr.cpp b/eeschema/sch_io/sch_io_mgr.cpp index e1ee2754af..63e55bcdae 100644 --- a/eeschema/sch_io/sch_io_mgr.cpp +++ b/eeschema/sch_io/sch_io_mgr.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." ) #define FMT_NOTFOUND _( "Plugin type '%s' is not found." ) @@ -98,8 +99,8 @@ const wxString SCH_IO_MGR::ShowType( SCH_FILE_T aType ) case SCH_EASYEDAPRO: return wxString( wxT( "EasyEDA (JLCEDA) Pro" ) ); case SCH_LTSPICE: return wxString( wxT( "LTspice" ) ); case SCH_HTTP: return wxString( wxT( "HTTP" ) ); - default: return wxString::Format( _( "Unknown SCH_FILE_T value: %d" ), - aType ); + case SCH_NESTED_TABLE: return LIBRARY_TABLE_ROW::TABLE_TYPE_NAME; + default: return wxString::Format( _( "Unknown SCH_FILE_T value: %d" ), aType ); } } @@ -130,8 +131,8 @@ SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::EnumFromStr( const wxString& aType ) return SCH_LTSPICE; else if( aType == wxT( "HTTP" ) ) return SCH_HTTP; - - // wxASSERT( blow up here ) + else if( aType == LIBRARY_TABLE_ROW::TABLE_TYPE_NAME ) + return SCH_NESTED_TABLE; return SCH_FILE_UNKNOWN; } @@ -139,6 +140,11 @@ SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::EnumFromStr( const wxString& aType ) SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath, int aCtl ) { + LIBRARY_TABLE_PARSER parser; + + if( parser.Parse( aLibPath.ToStdString() ).has_value() ) + return SCH_NESTED_TABLE; + for( const SCH_IO_MGR::SCH_FILE_T& fileType : SCH_IO_MGR::SCH_FILE_T_vector ) { bool isKiCad = fileType == SCH_IO_MGR::SCH_KICAD || fileType == SCH_IO_MGR::SCH_LEGACY; diff --git a/eeschema/sch_io/sch_io_mgr.h b/eeschema/sch_io/sch_io_mgr.h index fc87cd7062..0eef1ec60b 100644 --- a/eeschema/sch_io/sch_io_mgr.h +++ b/eeschema/sch_io/sch_io_mgr.h @@ -69,7 +69,8 @@ public: SCH_HTTP, ///< KiCad HTTP library // Add your schematic type here. - SCH_FILE_UNKNOWN + SCH_FILE_UNKNOWN, + SCH_NESTED_TABLE } ) // clang-format on diff --git a/pcbnew/dialogs/panel_fp_lib_table.cpp b/pcbnew/dialogs/panel_fp_lib_table.cpp index 18900be86b..a956b9d08e 100644 --- a/pcbnew/dialogs/panel_fp_lib_table.cpp +++ b/pcbnew/dialogs/panel_fp_lib_table.cpp @@ -103,10 +103,8 @@ public: wxString uri = LIBRARY_MANAGER::ExpandURI( row.URI(), Pgm().GetSettingsManager().Prj() ); PCB_IO_MGR::PCB_FILE_T pluginType = PCB_IO_MGR::GuessPluginTypeFromLibPath( uri ); - if( pluginType == PCB_IO_MGR::FILE_TYPE_NONE ) - pluginType = PCB_IO_MGR::KICAD_SEXP; - - SetValue( aRow, COL_TYPE, PCB_IO_MGR::ShowType( pluginType ) ); + if( pluginType != PCB_IO_MGR::FILE_TYPE_NONE ) + SetValue( aRow, COL_TYPE, PCB_IO_MGR::ShowType( pluginType ) ); } } @@ -115,12 +113,8 @@ protected: { FP_LIB_TABLE_GRID_DATA_MODEL* table = static_cast( aGrid->GetTable() ); LIBRARY_TABLE_ROW& tableRow = table->at( aRow ); - - if( tableRow.Type() == LIBRARY_TABLE_ROW::TABLE_TYPE_NAME ) - return wxEmptyString; - - PCB_IO_MGR::PCB_FILE_T fileType = PCB_IO_MGR::EnumFromStr( tableRow.Type() ); - const IO_BASE::IO_FILE_DESC& pluginDesc = m_supportedFpFiles.at( fileType ); + PCB_IO_MGR::PCB_FILE_T fileType = PCB_IO_MGR::EnumFromStr( tableRow.Type() ); + const IO_BASE::IO_FILE_DESC& pluginDesc = m_supportedFpFiles.at( fileType ); if( pluginDesc.m_IsFile ) return pluginDesc.FileFilter(); @@ -270,10 +264,6 @@ PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, PRO for( auto& [fileType, desc] : m_supportedFpFiles ) m_pluginChoices.Add( PCB_IO_MGR::ShowType( fileType ) ); - // TODO(JE) should use translated string here but type is stored as untranslated string - // Maybe type storage needs to be enum? - m_pluginChoices.Add( wxT( "Table" ) ); - std::optional table = Pgm().GetLibraryManager().Table( LIBRARY_TABLE_TYPE::FOOTPRINT, LIBRARY_TABLE_SCOPE::GLOBAL ); wxASSERT( table ); @@ -424,6 +414,9 @@ void PANEL_FP_LIB_TABLE::populatePluginList() if( const IO_BASE::IO_FILE_DESC& desc = pi->GetLibraryDesc() ) m_supportedFpFiles.emplace( plugin.m_type, desc ); } + + m_supportedFpFiles.emplace( PCB_IO_MGR::NESTED_TABLE, + IO_BASE::IO_FILE_DESC( _( "Table (nested library table)" ), {} ) ); } @@ -799,10 +792,15 @@ void PANEL_FP_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event ) const IO_BASE::IO_FILE_DESC& fileDesc = m_supportedFpFiles.at( fileType ); PCBNEW_SETTINGS* cfg = GetAppSettings( "pcbnew" ); - wxString title = wxString::Format( _( "Select %s Library" ), PCB_IO_MGR::ShowType( fileType ) ); + wxString title; wxString dummy; wxString* lastDir; + if( fileType == PCB_IO_MGR::NESTED_TABLE ) + title = _( "Select Library Table" ); + else + title = wxString::Format( _( "Select %s Library" ), PCB_IO_MGR::ShowType( fileType ) ); + if( m_cur_grid == m_project_grid ) lastDir = &m_lastProjectLibDir; else @@ -848,8 +846,8 @@ void PANEL_FP_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event ) bool addDuplicates = false; bool applyToAll = false; wxString warning = _( "Warning: Duplicate Nicknames" ); - wxString msg = _( "A library nicknamed '%s' already exists." ); - wxString detailedMsg = _( "One of the nicknames will need to be changed after adding this library." ); + wxString msg = _( "An item nicknamed '%s' already exists." ); + wxString detailedMsg = _( "One of the nicknames will need to be changed." ); for( const wxString& filePath : files ) { diff --git a/pcbnew/pcb_io/pcb_io_mgr.cpp b/pcbnew/pcb_io/pcb_io_mgr.cpp index c36bb121c6..8c4f4baa6c 100644 --- a/pcbnew/pcb_io/pcb_io_mgr.cpp +++ b/pcbnew/pcb_io/pcb_io_mgr.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,7 @@ #include #include #include - +#include #define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." ) @@ -76,14 +77,15 @@ PCB_IO* PCB_IO_MGR::FindPlugin( PCB_FILE_T aFileType ) const wxString PCB_IO_MGR::ShowType( PCB_FILE_T aType ) { + if( aType == PCB_IO_MGR::NESTED_TABLE ) + return LIBRARY_TABLE_ROW::TABLE_TYPE_NAME; + const auto& plugins = PLUGIN_REGISTRY::Instance()->AllPlugins(); for( const auto& plugin : plugins ) { if ( plugin.m_type == aType ) - { return plugin.m_name; - } } return wxString::Format( _( "UNKNOWN (%d)" ), aType ); @@ -92,14 +94,15 @@ const wxString PCB_IO_MGR::ShowType( PCB_FILE_T aType ) PCB_IO_MGR::PCB_FILE_T PCB_IO_MGR::EnumFromStr( const wxString& aType ) { + if( aType == LIBRARY_TABLE_ROW::TABLE_TYPE_NAME ) + return PCB_IO_MGR::NESTED_TABLE; + const auto& plugins = PLUGIN_REGISTRY::Instance()->AllPlugins(); for( const auto& plugin : plugins ) { if( plugin.m_name.CmpNoCase( aType ) == 0 ) - { return plugin.m_type; - } } return PCB_IO_MGR::PCB_FILE_UNKNOWN; @@ -134,6 +137,11 @@ PCB_IO_MGR::PCB_FILE_T PCB_IO_MGR::FindPluginTypeFromBoardPath( const wxString& PCB_IO_MGR::PCB_FILE_T PCB_IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath, int aCtl ) { + LIBRARY_TABLE_PARSER parser; + + if( parser.Parse( aLibPath.ToStdString() ).has_value() ) + return NESTED_TABLE; + const auto& plugins = PCB_IO_MGR::PLUGIN_REGISTRY::Instance()->AllPlugins(); for( const auto& plugin : plugins ) diff --git a/pcbnew/pcb_io/pcb_io_mgr.h b/pcbnew/pcb_io/pcb_io_mgr.h index a0add1ecf4..260fe901e8 100644 --- a/pcbnew/pcb_io/pcb_io_mgr.h +++ b/pcbnew/pcb_io/pcb_io_mgr.h @@ -74,7 +74,8 @@ public: // etc. - FILE_TYPE_NONE + FILE_TYPE_NONE, + NESTED_TABLE }; /**