Port footprint library table to new system

This commit is contained in:
Jon Evans
2025-10-29 22:59:44 -04:00
parent 7a0ea794e5
commit baa29c1a58
72 changed files with 1090 additions and 1072 deletions
@@ -33,7 +33,7 @@
#include <trigo.h>
#include <project.h>
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <eda_3d_viewer_frame.h>
#include <project_pcb.h>
@@ -1020,12 +1020,12 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
try
{
// FindRow() can throw an exception
const FP_LIB_TABLE_ROW* fpRow =
PROJECT_PCB::PcbFootprintLibs( m_boardAdapter.GetBoard()->GetProject() )
->FindRow( libraryName, false );
std::optional<LIBRARY_TABLE_ROW*> fpRow =
PROJECT_PCB::FootprintLibAdapter( m_boardAdapter.GetBoard()->GetProject() )
->GetRow( libraryName );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
footprintBasePath = LIBRARY_MANAGER::GetFullURI( *fpRow, true );
}
catch( ... )
{
@@ -40,7 +40,7 @@
#include <board.h>
#include <footprint.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <eda_3d_viewer_frame.h>
#include <project_pcb.h>
@@ -1272,12 +1272,12 @@ void RENDER_3D_RAYTRACE_BASE::load3DModels( CONTAINER_3D& aDstContainer,
try
{
// FindRow() can throw an exception
const FP_LIB_TABLE_ROW* fpRow =
PROJECT_PCB::PcbFootprintLibs( m_boardAdapter.GetBoard()->GetProject() )
->FindRow( libraryName, false );
std::optional<LIBRARY_TABLE_ROW*> fpRow =
PROJECT_PCB::FootprintLibAdapter( m_boardAdapter.GetBoard()->GetProject() )
->GetRow( libraryName );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
footprintBasePath = LIBRARY_MANAGER::GetFullURI( *fpRow, true );
}
catch( ... )
{
+1 -1
View File
@@ -881,7 +881,6 @@ target_include_directories( common SYSTEM PUBLIC
)
set( PCB_COMMON_SRCS
fp_lib_table.cpp
hash_eda.cpp
${CMAKE_SOURCE_DIR}/pcbnew/pcb_base_frame.cpp
${CMAKE_SOURCE_DIR}/pcbnew/pcbexpr_evaluator.cpp
@@ -903,6 +902,7 @@ set( PCB_COMMON_SRCS
${CMAKE_SOURCE_DIR}/pcbnew/pcb_group.cpp
${CMAKE_SOURCE_DIR}/pcbnew/pcb_marker.cpp
${CMAKE_SOURCE_DIR}/pcbnew/footprint.cpp
${CMAKE_SOURCE_DIR}/pcbnew/footprint_library_adapter.cpp
${CMAKE_SOURCE_DIR}/pcbnew/fix_board_shape.cpp
${CMAKE_SOURCE_DIR}/pcbnew/layer_utils.cpp
${CMAKE_SOURCE_DIR}/pcbnew/netinfo_item.cpp
+17 -11
View File
@@ -51,7 +51,7 @@ wxString DESIGN_BLOCK_LIBRARY_ADAPTER::GlobalPathEnvVariableName()
}
DESIGN_BLOCK_IO* DESIGN_BLOCK_LIBRARY_ADAPTER::plugin( const LIB_DATA* aRow )
DESIGN_BLOCK_IO* DESIGN_BLOCK_LIBRARY_ADAPTER::dbplugin( const LIB_DATA* aRow )
{
DESIGN_BLOCK_IO* ret = dynamic_cast<DESIGN_BLOCK_IO*>( aRow->plugin.get() );
wxCHECK( aRow->plugin && ret, nullptr );
@@ -79,6 +79,12 @@ LIBRARY_RESULT<IO_BASE*> DESIGN_BLOCK_LIBRARY_ADAPTER::createPlugin( const LIBRA
}
IO_BASE* DESIGN_BLOCK_LIBRARY_ADAPTER::plugin( const LIB_DATA* aRow )
{
return dbplugin( aRow );
}
void DESIGN_BLOCK_LIBRARY_ADAPTER::AsyncLoad()
{
// TODO(JE) library tables - how much of this can be shared with other library types?
@@ -166,7 +172,7 @@ void DESIGN_BLOCK_LIBRARY_ADAPTER::AsyncLoad()
try
{
plugin( lib )->DesignBlockEnumerate( dummyList, getUri( lib->row ), false, &options );
dbplugin( lib )->DesignBlockEnumerate( dummyList, getUri( lib->row ), false, &options );
wxLogTrace( traceLibraries, "DB: %s: library enumerated %zu items", nickname, dummyList.size() );
lib->status.load_status = LOAD_STATUS::LOADED;
}
@@ -252,7 +258,7 @@ std::vector<DESIGN_BLOCK*> DESIGN_BLOCK_LIBRARY_ADAPTER::GetDesignBlocks( const
try
{
plugin( lib )->DesignBlockEnumerate( blockNames, getUri( lib->row ), false, &options );
dbplugin( lib )->DesignBlockEnumerate( blockNames, getUri( lib->row ), false, &options );
}
catch( IO_ERROR& e )
{
@@ -264,7 +270,7 @@ std::vector<DESIGN_BLOCK*> DESIGN_BLOCK_LIBRARY_ADAPTER::GetDesignBlocks( const
{
try
{
blocks.emplace_back( plugin( lib )->DesignBlockLoad( getUri( lib->row ), blockName, false, &options ) );
blocks.emplace_back( dbplugin( lib )->DesignBlockLoad( getUri( lib->row ), blockName, false, &options ) );
}
catch( IO_ERROR& e )
{
@@ -287,7 +293,7 @@ std::vector<wxString> DESIGN_BLOCK_LIBRARY_ADAPTER::GetDesignBlockNames( const w
const LIB_DATA* lib = *maybeLib;
std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
plugin( lib )->DesignBlockEnumerate( namesAS, getUri( lib->row ), true, &options );
dbplugin( lib )->DesignBlockEnumerate( namesAS, getUri( lib->row ), true, &options );
}
for( const wxString& name : namesAS )
@@ -305,7 +311,7 @@ DESIGN_BLOCK* DESIGN_BLOCK_LIBRARY_ADAPTER::LoadDesignBlock( const wxString& aNi
const LIB_DATA* lib = *maybeLib;
std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
DESIGN_BLOCK* db = plugin( lib )->DesignBlockLoad( getUri( lib->row ), aDesignBlockName, aKeepUUID, &options );
DESIGN_BLOCK* db = dbplugin( lib )->DesignBlockLoad( getUri( lib->row ), aDesignBlockName, aKeepUUID, &options );
db->GetLibId().SetLibNickname( aNickname );
return db;
}
@@ -321,7 +327,7 @@ bool DESIGN_BLOCK_LIBRARY_ADAPTER::DesignBlockExists( const wxString& aNickname,
const LIB_DATA* lib = *maybeLib;
std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
return plugin( lib )->DesignBlockExists( getUri( lib->row ), aDesignBlockName, &options );
return dbplugin( lib )->DesignBlockExists( getUri( lib->row ), aDesignBlockName, &options );
}
return false;
@@ -336,7 +342,7 @@ const DESIGN_BLOCK* DESIGN_BLOCK_LIBRARY_ADAPTER::GetEnumeratedDesignBlock( cons
const LIB_DATA* lib = *maybeLib;
std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
return plugin( lib )->GetEnumeratedDesignBlock( getUri( lib->row ), aDesignBlockName, &options );
return dbplugin( lib )->GetEnumeratedDesignBlock( getUri( lib->row ), aDesignBlockName, &options );
}
return nullptr;
@@ -351,10 +357,10 @@ DESIGN_BLOCK_LIBRARY_ADAPTER::SAVE_T DESIGN_BLOCK_LIBRARY_ADAPTER::SaveDesignBlo
const LIB_DATA* lib = *maybeLib;
std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
if( !aOverwrite && plugin( lib )->DesignBlockExists( getUri( lib->row ), aDesignBlock->GetName(), &options ) )
if( !aOverwrite && dbplugin( lib )->DesignBlockExists( getUri( lib->row ), aDesignBlock->GetName(), &options ) )
return SAVE_SKIPPED;
plugin( lib )->DesignBlockSave( getUri( lib->row ), aDesignBlock, &options );
dbplugin( lib )->DesignBlockSave( getUri( lib->row ), aDesignBlock, &options );
}
return SAVE_OK;
@@ -368,7 +374,7 @@ void DESIGN_BLOCK_LIBRARY_ADAPTER::DeleteDesignBlock( const wxString& aNickname,
{
const LIB_DATA* lib = *maybeLib;
std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
return plugin( lib )->DesignBlockDelete( getUri( lib->row ), aDesignBlockName, &options );
return dbplugin( lib )->DesignBlockDelete( getUri( lib->row ), aDesignBlockName, &options );
}
}
+6 -1
View File
@@ -42,6 +42,9 @@ public:
void AsyncLoad() override;
// Currently unused for design blocks
std::optional<LIB_STATUS> GetLibraryStatus( const wxString& aNickname ) const override { return std::nullopt; }
/// @return all the design blocks in the given library, if it exists and is loaded (or an empty list)
std::vector<DESIGN_BLOCK*> GetDesignBlocks( const wxString& aNickname );
@@ -151,10 +154,12 @@ protected:
LIBRARY_RESULT<IO_BASE*> createPlugin( const LIBRARY_TABLE_ROW* row ) override;
IO_BASE* plugin( const LIB_DATA* aRow ) override;
private:
/// Helper to cast the ABC plugin in the LIB_DATA* to a concrete plugin
static DESIGN_BLOCK_IO* plugin( const LIB_DATA* aRow );
static DESIGN_BLOCK_IO* dbplugin( const LIB_DATA* aRow );
// The global libraries, potentially shared between multiple different open
// projects, each of which has their own instance of this adapter class
-1
View File
@@ -29,7 +29,6 @@
*/
#include <footprint_info.h>
#include <fp_lib_table.h>
#include <dialogs/html_message_box.h>
#include <string_utils.h>
#include <kiface_ids.h>
+58
View File
@@ -935,6 +935,64 @@ bool LIBRARY_MANAGER_ADAPTER::IsLibraryLoaded( const wxString& aNickname )
}
std::vector<std::pair<wxString, LIB_STATUS>> LIBRARY_MANAGER_ADAPTER::GetLibraryStatuses() const
{
std::vector<std::pair<wxString, LIB_STATUS>> ret;
for( const LIBRARY_TABLE_ROW* row : m_manager.Rows( Type() ) )
{
if( std::optional<LIB_STATUS> result = GetLibraryStatus( row->Nickname() ) )
{
ret.emplace_back( std::make_pair( row->Nickname(), *result ) );
}
else
{
// This should probably never happen, but until that can be proved...
ret.emplace_back( std::make_pair( row->Nickname(), LIB_STATUS( {
.load_status = LOAD_STATUS::LOAD_ERROR,
.error = LIBRARY_ERROR( _( "Library not found in library table" ) )
} ) ) );
}
}
return ret;
}
bool LIBRARY_MANAGER_ADAPTER::IsWritable( const wxString& aNickname ) const
{
if( std::optional<const LIB_DATA*> result = fetchIfLoaded( aNickname ) )
{
const LIB_DATA* rowData = *result;
return rowData->plugin->IsLibraryWritable( getUri( rowData->row ) );
}
return false;
}
bool LIBRARY_MANAGER_ADAPTER::CreateLibrary( const wxString& aNickname )
{
if( LIBRARY_RESULT<LIB_DATA*> result = loadIfNeeded( aNickname ); result.has_value() )
{
LIB_DATA* data = *result;
std::map<std::string, UTF8> options = data->row->GetOptionsMap();
try
{
data->plugin->CreateLibrary( getUri( data->row ), &options );
return true;
}
catch( ... )
{
return false;
}
}
return false;
}
wxString LIBRARY_MANAGER_ADAPTER::getUri( const LIBRARY_TABLE_ROW* aRow )
{
return LIBRARY_MANAGER::ExpandURI( aRow->URI(), Pgm().GetSettingsManager().Prj() );
+11 -30
View File
@@ -30,7 +30,6 @@
#include <confirm.h>
#include <core/kicad_algo.h>
#include <design_block_library_adapter.h>
#include <fp_lib_table.h>
#include <string_utils.h>
#include <kiface_ids.h>
#include <kiway.h>
@@ -41,6 +40,9 @@
#include <git/project_git_utils.h>
#include <git2.h>
#include <project.h>
#include <footprint_library_adapter.h>
#include <project/project_file.h>
#include <trace_helpers.h>
#include <wildcards_and_files_ext.h>
@@ -405,43 +407,22 @@ const wxString PROJECT::AbsolutePath( const wxString& aFileName ) const
}
FP_LIB_TABLE* PROJECT::PcbFootprintLibs( KIWAY& aKiway )
FOOTPRINT_LIBRARY_ADAPTER* PROJECT::FootprintLibAdapter( KIWAY& aKiway )
{
// This is a lazy loading function, it loads the project specific table when
// that table is asked for, not before.
FOOTPRINT_LIBRARY_ADAPTER* adapter = static_cast<FOOTPRINT_LIBRARY_ADAPTER*>( GetElem( ELEM::FPTBL ) );
FP_LIB_TABLE* tbl = (FP_LIB_TABLE*) GetElem( PROJECT::ELEM::FPTBL );
if( tbl )
if( adapter )
{
wxASSERT( tbl->ProjectElementType() == PROJECT::ELEM::FPTBL );
wxASSERT( adapter->ProjectElementType() == PROJECT::ELEM::FPTBL );
}
else
{
try
{
// Build a new project specific FP_LIB_TABLE with the global table as a fallback.
// ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may
// stack this way, all using the same global fallback table.
KIFACE* kiface = aKiway.KiFACE( KIWAY::FACE_PCB );
tbl = (FP_LIB_TABLE*) kiface->IfaceOrAddress( KIFACE_NEW_FOOTPRINT_TABLE );
tbl->Load( FootprintLibTblName() );
SetElem( PROJECT::ELEM::FPTBL, tbl );
}
catch( const IO_ERROR& ioe )
{
DisplayErrorMessage( nullptr, _( "Error loading project footprint library table." ),
ioe.What() );
}
catch( ... )
{
DisplayErrorMessage( nullptr, _( "Error loading project footprint library table." ) );
}
KIFACE* kiface = aKiway.KiFACE( KIWAY::FACE_PCB );
adapter = static_cast<FOOTPRINT_LIBRARY_ADAPTER*>( kiface->IfaceOrAddress( KIFACE_FOOTPRINT_LIBRARY_ADAPTER ) );
SetElem( ELEM::FPTBL, adapter );
}
return tbl;
return adapter;
}
+3 -2
View File
@@ -21,6 +21,7 @@
#include <kiway.h>
#include <kiway_player.h>
#include <project.h>
#include <project_pcb.h>
#include <widgets/footprint_choice.h>
#include <widgets/footprint_select_widget.h>
#include <widgets/wx_progress_reporters.h>
@@ -67,10 +68,10 @@ void FOOTPRINT_SELECT_WIDGET::Load( KIWAY& aKiway, PROJECT& aProject )
// If the fp-info-cache is empty (or, more likely, hasn't been created in a new
// project yet), load footprints the hard way.
FP_LIB_TABLE* fpTable = aProject.PcbFootprintLibs( aKiway );
FOOTPRINT_LIBRARY_ADAPTER* footprints = aProject.FootprintLibAdapter( aKiway );
FOOTPRINT_LIST_IMPL& fpList = static_cast<FOOTPRINT_LIST_IMPL&>( *m_fp_list );
fpList.ReadFootprintFiles( fpTable, nullptr, &progressReporter );
fpList.ReadFootprintFiles( footprints, nullptr, &progressReporter );
}
m_fp_filter.SetList( *m_fp_list );
+7 -68
View File
@@ -24,7 +24,7 @@
*/
#include <confirm.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <footprint_info_impl.h>
#include <kiface_base.h>
#include <pgm_base.h>
@@ -40,8 +40,7 @@ namespace CV {
int testFootprintLink( const wxString& aFootprint, PROJECT* aProject )
{
FP_LIB_TABLE* libTable = PROJECT_PCB::PcbFootprintLibs( aProject );
const FP_LIB_TABLE_ROW* libTableRow = nullptr;
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( aProject );
LIB_ID fpID;
fpID.Parse( aFootprint );
@@ -49,23 +48,14 @@ int testFootprintLink( const wxString& aFootprint, PROJECT* aProject )
wxString libName = fpID.GetLibNickname();
wxString fpName = fpID.GetLibItemName();
try
{
libTableRow = libTable->FindRow( libName );
}
catch( const IO_ERROR& )
{
// Error state processed below
}
if( !libTableRow )
if( !adapter->HasLibrary( libName, false ) )
return KIFACE_TEST_FOOTPRINT_LINK_NO_LIBRARY;
else if( !libTable->HasLibrary( libName, true ) )
else if( !adapter->HasLibrary( libName, true ) )
return KIFACE_TEST_FOOTPRINT_LINK_LIBRARY_NOT_ENABLED;
else if( !libTable->FootprintExists( libName, fpName ) )
else if( !adapter->FootprintExists( libName, fpName ) )
return KIFACE_TEST_FOOTPRINT_LINK_NO_FOOTPRINT;
else
return 0;
return 0;
}
@@ -110,14 +100,6 @@ static struct IFACE : public KIFACE_BASE
case KIFACE_FOOTPRINT_LIST:
return (void*) &GFootprintList;
// Return a new FP_LIB_TABLE with the global table installed as a fallback.
case KIFACE_NEW_FOOTPRINT_TABLE:
return (void*) new FP_LIB_TABLE( &GFootprintTable );
// Return a pointer to the global instance of the global footprint table.
case KIFACE_GLOBAL_FOOTPRINT_TABLE:
return (void*) &GFootprintTable;
case KIFACE_TEST_FOOTPRINT_LINK:
return (void*) testFootprintLink;
@@ -144,12 +126,6 @@ KIFACE_API KIFACE* KIFACE_GETTER( int* aKIFACEversion, int aKIWAYversion, PGM_B
}
/// The global footprint library table. This is not dynamically allocated because
/// in a multiple project environment we must keep its address constant (since it is
/// the fallback table for multiple projects).
FP_LIB_TABLE GFootprintTable;
/// The global footprint info table. This is performance-intensive to build so we
/// keep a hash-stamped global version. Any deviation from the request vs. stored
/// hash will result in it being rebuilt.
@@ -172,43 +148,6 @@ bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits, KIWAY* aKiway )
start_common( aCtlBits );
/* Now that there are no *.mod files in the standard library, this function
has no utility. User should simply set the variable manually.
Looking for *.mod files which do not exist is fruitless.
// SetFootprintLibTablePath();
*/
try
{
// The global table is not related to a specific project. All projects
// will use the same global table. So the KIFACE::OnKifaceStart() contract
// of avoiding anything project specific is not violated here.
if( !FP_LIB_TABLE::LoadGlobalTable( GFootprintTable ) )
{
DisplayInfoMessage( nullptr, _( "You have run CvPcb for the first time using the "
"new footprint library table method for finding "
"footprints.\nCvPcb has either copied the default "
"table or created an empty table in your home "
"folder.\nYou must first configure the library "
"table to include all footprint libraries not "
"included with KiCad.\nSee the \"Footprint Library "
"Table\" section of the CvPcb documentation for "
"more information." ) );
}
}
catch( const IO_ERROR& ioe )
{
// we didnt get anywhere deregister the settings
aProgram->GetSettingsManager().FlushAndRelease( KifaceSettings(), false );
DisplayErrorMessage( nullptr, _( "An error occurred attempting to load the global "
"footprint library table." ),
ioe.What() );
return false;
}
return true;
}
+11 -10
View File
@@ -27,7 +27,7 @@
#include <bitmaps.h>
#include <confirm.h>
#include <eda_dde.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <kiface_base.h>
#include <kiplatform/app.h>
#include <kiway_express.h>
@@ -36,6 +36,7 @@
#include <netlist_reader/netlist_reader.h>
#include <lib_tree_model_adapter.h>
#include <numeric>
#include <richio.h>
#include <tool/action_manager.h>
#include <tool/action_toolbar.h>
#include <tool/common_control.h>
@@ -882,10 +883,10 @@ void CVPCB_MAINFRAME::DisplayStatus()
}
// Extract the library information
FP_LIB_TABLE* fptbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
if( fptbl->HasLibrary( lib ) )
msg = wxString::Format( _( "Library location: %s" ), fptbl->GetFullURI( lib ) );
if( std::optional<LIBRARY_TABLE_ROW*> optRow = adapter->GetRow( lib ); optRow )
msg = wxString::Format( _( "Library location: %s" ), LIBRARY_MANAGER::GetFullURI( *optRow ) );
else
msg = wxString::Format( _( "Library location: unknown" ) );
@@ -895,10 +896,10 @@ void CVPCB_MAINFRAME::DisplayStatus()
bool CVPCB_MAINFRAME::LoadFootprintFiles()
{
FP_LIB_TABLE* fptbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
// Check if there are footprint libraries in the footprint library table.
if( !fptbl || !fptbl->GetLogicalLibs().size() )
if( !adapter || !adapter->Rows().size() )
{
wxMessageBox( _( "No PCB footprint libraries are listed in the current footprint "
"library table." ), _( "Configuration Error" ), wxOK | wxICON_ERROR );
@@ -907,7 +908,7 @@ bool CVPCB_MAINFRAME::LoadFootprintFiles()
WX_PROGRESS_REPORTER progressReporter( this, _( "Load Footprint Libraries" ), 1, PR_CAN_ABORT );
m_FootprintsList->ReadFootprintFiles( fptbl, nullptr, &progressReporter );
m_FootprintsList->ReadFootprintFiles( adapter, nullptr, &progressReporter );
if( m_FootprintsList->GetErrorCount() )
m_FootprintsList->DisplayErrors( this );
@@ -1008,7 +1009,7 @@ void CVPCB_MAINFRAME::BuildLibrariesList()
{
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = Kiway().Prj().GetProjectFile();
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
// Use same sorting algorithm as LIB_TREE_NODE::AssignIntrinsicRanks
struct library_sort
@@ -1039,9 +1040,9 @@ void CVPCB_MAINFRAME::BuildLibrariesList()
};
if( tbl )
if( adapter )
{
std::vector<wxString> libNickNames = tbl->GetLogicalLibs();
std::vector<wxString> libNickNames = adapter->GetLibraryNames();
for( const wxString& libNickName : libNickNames )
process( libNickName );
+2 -2
View File
@@ -29,7 +29,7 @@
#include <widgets/wx_grid.h>
#include <bitmaps.h>
#include <project.h> // For PROJECT_VAR_NAME definition
#include <fp_lib_table.h> // For KICAD7_FOOTPRINT_DIR definition
#include <footprint_library_adapter.h> // For KICAD7_FOOTPRINT_DIR definition
#include <dialog_config_equfiles.h>
#include <project/project_file.h>
@@ -66,7 +66,7 @@ DIALOG_CONFIG_EQUFILES::DIALOG_CONFIG_EQUFILES( wxWindow* aParent ) :
m_gridEnvVars->ClearRows();
m_gridEnvVars->AppendRows( 2 );
m_gridEnvVars->SetCellValue( 0, 0, PROJECT_VAR_NAME );
m_gridEnvVars->SetCellValue( 1, 0, FP_LIB_TABLE::GlobalPathEnvVariableName() );
m_gridEnvVars->SetCellValue( 1, 0, FOOTPRINT_LIBRARY_ADAPTER::GlobalPathEnvVariableName() );
for( int row = 0; row < m_gridEnvVars->GetTable()->GetRowsCount(); row++ )
{
+5 -6
View File
@@ -31,7 +31,7 @@
#include <confirm.h>
#include <settings/cvpcb_settings.h>
#include <footprint_editor_settings.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <id.h>
#include <kiface_base.h>
#include <lib_id.h>
@@ -283,11 +283,10 @@ FOOTPRINT* DISPLAY_FOOTPRINTS_FRAME::GetFootprint( const wxString& aFootprintNam
wxString libNickname = From_UTF8( fpid.GetLibNickname().c_str() );
wxString fpName = From_UTF8( fpid.GetLibItemName().c_str() );
FP_LIB_TABLE* fpTable = PROJECT_PCB::PcbFootprintLibs( &Prj() );
wxASSERT( fpTable );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
// See if the library requested is in the library table
if( !fpTable->HasLibrary( libNickname ) )
if( !adapter->HasLibrary( libNickname ) )
{
aReporter.Report( wxString::Format( _( "Library '%s' is not in the footprint library table." ),
libNickname ),
@@ -296,7 +295,7 @@ FOOTPRINT* DISPLAY_FOOTPRINTS_FRAME::GetFootprint( const wxString& aFootprintNam
}
// See if the footprint requested is in the library
if( !fpTable->FootprintExists( libNickname, fpName ) )
if( !adapter->FootprintExists( libNickname, fpName ) )
{
aReporter.Report( wxString::Format( _( "Footprint '%s' not found." ), aFootprintName ),
RPT_SEVERITY_ERROR );
@@ -305,7 +304,7 @@ FOOTPRINT* DISPLAY_FOOTPRINTS_FRAME::GetFootprint( const wxString& aFootprintNam
try
{
if( const FOOTPRINT* fp = fpTable->GetEnumeratedFootprint( libNickname, fpName ) )
if( const FOOTPRINT* fp = adapter->LoadFootprint( libNickname, fpName, false ) )
footprint = static_cast<FOOTPRINT*>( fp->Duplicate( IGNORE_PARENT_GROUP ) );
}
catch( const IO_ERROR& ioe )
+8 -11
View File
@@ -24,10 +24,11 @@
*/
#include <confirm.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <dialogs/html_message_box.h>
#include <kiway.h>
#include <lib_id.h>
#include <richio.h>
#include <string_utils.h>
#include <cvpcb_mainframe.h>
@@ -43,7 +44,7 @@
*
* @return int - 0 on success, 1 on not found, 2 on ambiguous i.e. multiple matches.
*/
static int guessNickname( FP_LIB_TABLE* aTbl, LIB_ID* aFootprintId )
static int guessNickname( FOOTPRINT_LIBRARY_ADAPTER* aAdapter, LIB_ID* aFootprintId )
{
if( aFootprintId->GetLibNickname().size() )
return 0;
@@ -51,18 +52,14 @@ static int guessNickname( FP_LIB_TABLE* aTbl, LIB_ID* aFootprintId )
wxString nick;
wxString fpname = aFootprintId->GetLibItemName();
std::vector<wxString> nicks = aTbl->GetLogicalLibs();
std::vector<wxString> nicks = aAdapter->GetLibraryNames();
// Search each library going through libraries alphabetically.
for( unsigned libNdx = 0; libNdx < nicks.size(); ++libNdx )
{
wxArrayString fpnames;
aTbl->FootprintEnumerate( fpnames, nicks[libNdx], true );
for( unsigned nameNdx = 0; nameNdx < fpnames.size(); ++nameNdx )
for( const wxString& name : aAdapter->GetFootprintNames( nicks[libNdx], true ) )
{
if( fpname == fpnames[nameNdx] )
if( fpname == name )
{
if( !nick )
nick = nicks[libNdx];
@@ -136,9 +133,9 @@ bool CVPCB_MAINFRAME::readNetListAndFpFiles( const std::string& aNetlist )
if( component->GetFPID().IsLegacy() )
{
// get this first here, it's possibly obsoleted if we get it too soon.
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
int guess = guessNickname( tbl, (LIB_ID*) &component->GetFPID() );
int guess = guessNickname( adapter, (LIB_ID*) &component->GetFPID() );
switch( guess )
{
+12 -70
View File
@@ -56,7 +56,7 @@ wxString SYMBOL_LIBRARY_ADAPTER::GlobalPathEnvVariableName()
}
SCH_IO* SYMBOL_LIBRARY_ADAPTER::plugin( const LIB_DATA* aRow )
SCH_IO* SYMBOL_LIBRARY_ADAPTER::schplugin( const LIB_DATA* aRow )
{
SCH_IO* ret = dynamic_cast<SCH_IO*>( aRow->plugin.get() );
wxCHECK( aRow->plugin && ret, nullptr );
@@ -77,7 +77,7 @@ std::optional<LIB_STATUS> SYMBOL_LIBRARY_ADAPTER::LoadOne( const wxString& aNick
try
{
wxArrayString dummyList;
plugin( lib )->EnumerateSymbolLib( dummyList, getUri( lib->row ), &options );
schplugin( lib )->EnumerateSymbolLib( dummyList, getUri( lib->row ), &options );
wxLogTrace( traceLibraries, "Sym: %s: library enumerated %zu items", aNickname, dummyList.size() );
lib->status.load_status = LOAD_STATUS::LOADED;
}
@@ -136,7 +136,7 @@ std::vector<LIB_SYMBOL*> SYMBOL_LIBRARY_ADAPTER::GetSymbols( const wxString& aNi
try
{
plugin( lib )->EnumerateSymbolLib( symbols, getUri( lib->row ), &options );
schplugin( lib )->EnumerateSymbolLib( symbols, getUri( lib->row ), &options );
}
catch( IO_ERROR& e )
{
@@ -169,7 +169,7 @@ std::vector<wxString> SYMBOL_LIBRARY_ADAPTER::GetSymbolNames( const wxString& aN
if( aType == SYMBOL_TYPE::POWER_ONLY )
options[PropPowerSymsOnly] = "";
plugin( lib )->EnumerateSymbolLib( namesAS, getUri( lib->row ), &options );
schplugin( lib )->EnumerateSymbolLib( namesAS, getUri( lib->row ), &options );
}
for( const wxString& name : namesAS )
@@ -183,7 +183,7 @@ LIB_SYMBOL* SYMBOL_LIBRARY_ADAPTER::LoadSymbol( const wxString& aNickname, const
{
if( std::optional<const LIB_DATA*> lib = fetchIfLoaded( aNickname ) )
{
if( LIB_SYMBOL* symbol = plugin( *lib )->LoadSymbol( getUri( ( *lib )->row ), aName ) )
if( LIB_SYMBOL* symbol = schplugin( *lib )->LoadSymbol( getUri( ( *lib )->row ), aName ) )
{
LIB_ID id = symbol->GetLibId();
id.SetLibNickname( ( *lib )->row->Nickname() );
@@ -303,7 +303,7 @@ void SYMBOL_LIBRARY_ADAPTER::AsyncLoad()
try
{
plugin( lib )->EnumerateSymbolLib( dummyList, getUri( lib->row ), &options );
schplugin( lib )->EnumerateSymbolLib( dummyList, getUri( lib->row ), &options );
wxLogTrace( traceLibraries, "Sym: %s: library enumerated %zu items", nickname, dummyList.size() );
lib->status.load_status = LOAD_STATUS::LOADED;
}
@@ -373,28 +373,6 @@ std::optional<LIBRARY_ERROR> SYMBOL_LIBRARY_ADAPTER::LibraryError(
}
bool SYMBOL_LIBRARY_ADAPTER::CreateLibrary( const wxString& aNickname )
{
if( LIBRARY_RESULT<LIB_DATA*> result = loadIfNeeded( aNickname ); result.has_value() )
{
LIB_DATA* data = *result;
std::map<std::string, UTF8> options = data->row->GetOptionsMap();
try
{
data->plugin->CreateLibrary( getUri( data->row ), &options );
return true;
}
catch( ... )
{
return false;
}
}
return false;
}
std::optional<LIB_STATUS> SYMBOL_LIBRARY_ADAPTER::GetLibraryStatus( const wxString& aNickname ) const
{
if( m_libraries.contains( aNickname ) )
@@ -407,30 +385,6 @@ std::optional<LIB_STATUS> SYMBOL_LIBRARY_ADAPTER::GetLibraryStatus( const wxStri
}
std::vector<std::pair<wxString, LIB_STATUS>> SYMBOL_LIBRARY_ADAPTER::GetLibraryStatuses() const
{
std::vector<std::pair<wxString, LIB_STATUS>> ret;
for( const LIBRARY_TABLE_ROW* row : m_manager.Rows( LIBRARY_TABLE_TYPE::SYMBOL ) )
{
if( std::optional<LIB_STATUS> result = GetLibraryStatus( row->Nickname() ) )
{
ret.emplace_back( std::make_pair( row->Nickname(), *result ) );
}
else
{
// This should probably never happen, but until that can be proved...
ret.emplace_back( std::make_pair( row->Nickname(), LIB_STATUS( {
.load_status = LOAD_STATUS::LOAD_ERROR,
.error = LIBRARY_ERROR( _( "Library not found in library table" ) )
} ) ) );
}
}
return ret;
}
std::vector<wxString> SYMBOL_LIBRARY_ADAPTER::GetAvailableExtraFields(
const wxString& aNickname )
{
@@ -439,12 +393,12 @@ std::vector<wxString> SYMBOL_LIBRARY_ADAPTER::GetAvailableExtraFields(
if( std::optional<LIB_DATA*> result = fetchIfLoaded( aNickname ) )
{
LIB_DATA* rowData = *result;
int hash = plugin( rowData )->GetModifyHash();
int hash = schplugin( rowData )->GetModifyHash();
if( hash != rowData->modify_hash )
{
rowData->modify_hash = hash;
plugin( rowData )->GetAvailableSymbolFields( rowData->available_fields_cache );
schplugin( rowData )->GetAvailableSymbolFields( rowData->available_fields_cache );
}
return rowData->available_fields_cache;
@@ -459,7 +413,7 @@ bool SYMBOL_LIBRARY_ADAPTER::SupportsSubLibraries( const wxString& aNickname ) c
if( std::optional<const LIB_DATA*> result = fetchIfLoaded( aNickname ) )
{
const LIB_DATA* rowData = *result;
return plugin( rowData )->SupportsSubLibraries();
return schplugin( rowData )->SupportsSubLibraries();
}
return false;
@@ -475,13 +429,13 @@ std::vector<SUB_LIBRARY> SYMBOL_LIBRARY_ADAPTER::GetSubLibraries(
{
const LIB_DATA* rowData = *result;
std::vector<wxString> names;
plugin( rowData )->GetSubLibraryNames( names );
schplugin( rowData )->GetSubLibraryNames( names );
for( const wxString& name : names )
{
ret.emplace_back( SUB_LIBRARY {
.nickname = name,
.description = plugin( rowData )->GetSubLibraryDescription( name )
.description = schplugin( rowData )->GetSubLibraryDescription( name )
} );
}
}
@@ -522,21 +476,9 @@ int SYMBOL_LIBRARY_ADAPTER::GetModifyHash() const
{
const LIB_DATA* rowData = *result;
wxCHECK2( rowData->row, continue );
hash += plugin( rowData )->GetModifyHash();
hash += schplugin( rowData )->GetModifyHash();
}
}
return hash;
}
bool SYMBOL_LIBRARY_ADAPTER::IsWritable( const wxString& aNickname ) const
{
if( std::optional<const LIB_DATA*> result = fetchIfLoaded( aNickname ) )
{
const LIB_DATA* rowData = *result;
return rowData->plugin->IsLibraryWritable( getUri( rowData->row ) );
}
return false;
}
+4 -12
View File
@@ -65,10 +65,7 @@ public:
std::optional<LIB_STATUS> LoadOne( const wxString& aNickname );
/// Returns the status of a loaded library, or nullopt if the library hasn't been loaded (yet)
std::optional<LIB_STATUS> GetLibraryStatus( const wxString& aNickname ) const;
/// Returns a list of all library nicknames and their status (even if they failed to load)
std::vector<std::pair<wxString, LIB_STATUS>> GetLibraryStatuses() const;
std::optional<LIB_STATUS> GetLibraryStatus( const wxString& aNickname ) const override;
/// Returns a list of additional (non-mandatory) symbol fields present in the given library
std::vector<wxString> GetAvailableExtraFields( const wxString& aNickname );
@@ -158,15 +155,8 @@ public:
std::optional<LIBRARY_ERROR> LibraryError( const wxString& aNickname ) const;
/// Creates the library (i.e. saves to disk) for the given row if it exists
bool CreateLibrary( const wxString& aNickname );
static std::optional<SCH_IO_MGR::SCH_FILE_T> ParseLibType( const wxString& aType );
int GetModifyHash() const;
bool IsWritable( const wxString& aNickname ) const override;
protected:
std::map<wxString, LIB_DATA>& globalLibs() override { return GlobalLibraries; }
std::map<wxString, LIB_DATA>& globalLibs() const override { return GlobalLibraries; }
@@ -174,9 +164,11 @@ protected:
LIBRARY_RESULT<IO_BASE*> createPlugin( const LIBRARY_TABLE_ROW* row ) override;
IO_BASE* plugin( const LIB_DATA* aRow ) override { return schplugin( aRow ); }
private:
/// Helper to cast the ABC plugin in the LIB_DATA* to a concrete plugin
static SCH_IO* plugin( const LIB_DATA* aRow );
static SCH_IO* schplugin( const LIB_DATA* aRow );
// The global libraries, potentially shared between multiple different open
// projects, each of which has their own instance of this adapter class
+6 -9
View File
@@ -40,7 +40,7 @@
#include <memory>
class FP_LIB_TABLE;
class FOOTPRINT_LIBRARY_ADAPTER;
class FOOTPRINT_LIST;
class FOOTPRINT_LIST_IMPL;
class PROGRESS_REPORTER;
@@ -161,7 +161,7 @@ class APIEXPORT FOOTPRINT_LIST
{
public:
FOOTPRINT_LIST() :
m_lib_table( nullptr )
m_adapter( nullptr )
{
}
@@ -229,7 +229,7 @@ public:
/**
* Read all the footprints provided by the combination of aTable and aNickname.
*
* @param aTable defines all the libraries.
* @param aAdapter is used to access the libraries.
* @param aNickname is the library to read from, or if NULL means read all footprints
* from all known libraries in aTable.
* @param aProgressReporter is an optional progress reporter. ReadFootprintFiles() will
@@ -238,15 +238,12 @@ public:
* errors. If true, it does not mean there were no errors, check GetErrorCount()
* for that, should be zero to indicate success.
*/
virtual bool ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxString* aNickname = nullptr,
virtual bool ReadFootprintFiles( FOOTPRINT_LIBRARY_ADAPTER* aAdapter, const wxString* aNickname = nullptr,
PROGRESS_REPORTER* aProgressReporter = nullptr ) = 0;
void DisplayErrors( wxTopLevelWindow* aCaller = nullptr );
FP_LIB_TABLE* GetTable() const
{
return m_lib_table;
}
FOOTPRINT_LIBRARY_ADAPTER* GetAdapter() const { return m_adapter; }
/**
* Factory function to return a #FOOTPRINT_LIST via Kiway.
@@ -258,7 +255,7 @@ public:
static FOOTPRINT_LIST* GetInstance( KIWAY& aKiway );
protected:
FP_LIB_TABLE* m_lib_table; ///< no ownership
FOOTPRINT_LIBRARY_ADAPTER* m_adapter; ///< no ownership
std::vector<std::unique_ptr<FOOTPRINT_INFO>> m_list;
SYNC_QUEUE<std::unique_ptr<IO_ERROR>> m_errors; ///< some can be PARSE_ERRORs also
-289
View File
@@ -1,289 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef FP_LIB_TABLE_H_
#define FP_LIB_TABLE_H_
#include <lib_table_base.h>
#include <pcb_io/pcb_io_mgr.h>
class FOOTPRINT;
class FP_LIB_TABLE_GRID;
class PCB_IO;
/**
* Hold a record identifying a library accessed by the appropriate footprint library #PLUGIN
* object in the #FP_LIB_TABLE.
*/
class FP_LIB_TABLE_ROW : public LIB_TABLE_ROW
{
public:
FP_LIB_TABLE_ROW( const wxString& aNick, const wxString& aURI, const wxString& aType,
const wxString& aOptions, const wxString& aDescr = wxEmptyString ) :
LIB_TABLE_ROW( aNick, aURI, aOptions, aDescr )
{
SetType( aType );
}
FP_LIB_TABLE_ROW() :
type( PCB_IO_MGR::KICAD_SEXP )
{
}
bool operator==( const FP_LIB_TABLE_ROW& aRow ) const;
bool operator!=( const FP_LIB_TABLE_ROW& aRow ) const { return !( *this == aRow ); }
/**
* return the type of footprint library table represented by this row.
*/
const wxString GetType() const override { return PCB_IO_MGR::ShowType( type ); }
/**
* Change the type represented by this row.
*/
void SetType( const wxString& aType ) override;
bool LibraryExists() const override;
PCB_IO_MGR::PCB_FILE_T GetFileType() { return type; }
protected:
FP_LIB_TABLE_ROW( const FP_LIB_TABLE_ROW& aRow ) :
LIB_TABLE_ROW( aRow ),
type( aRow.type )
{
}
private:
virtual LIB_TABLE_ROW* do_clone() const override
{
return new FP_LIB_TABLE_ROW( *this );
}
void setPlugin( PCB_IO* aPlugin )
{
plugin.reset( aPlugin );
}
friend class FP_LIB_TABLE;
private:
IO_RELEASER<PCB_IO> plugin;
PCB_IO_MGR::PCB_FILE_T type;
};
class FP_LIB_TABLE : public LIB_TABLE
{
public:
PROJECT::ELEM ProjectElementType() override { return PROJECT::ELEM::FPTBL; }
virtual void Parse( LIB_TABLE_LEXER* aLexer ) override;
virtual void Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const override;
/**
* Build a footprint library table by pre-pending this table fragment in front of
* @a aFallBackTable. Loading of this table fragment is done by using Parse().
*
* @param aFallBackTable is another FP_LIB_TABLE which is searched only when a row
* is not found in this table. No ownership is taken of
* \a aFallBackTable.
*/
FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable = nullptr );
bool operator==( const FP_LIB_TABLE& aFpTable ) const;
bool operator!=( const FP_LIB_TABLE& r ) const { return !( *this == r ); }
/**
* Return an #FP_LIB_TABLE_ROW if \a aNickName is found in this table or in any chained
* fall back table fragment.
*
* If \a aCheckIfEnabled is true, the library will be ignored even if it is disabled.
* Otherwise, the row found will be returned even if entry is disabled.
*
* The #PLUGIN is loaded and attached to the "plugin" field of the #FP_LIB_TABLE_ROW if
* not already loaded.
*
* @param aNickName is the name of library nickname to find.
* @param aCheckIfEnabled is the flag to check if the library found is enabled.
* @return the library \a NickName if found.
* @throw IO_ERROR if \a aNickName cannot be found.
*/
const FP_LIB_TABLE_ROW* FindRow( const wxString& aNickName, bool aCheckIfEnabled = false );
/**
* Return a list of footprint names contained within the library given by @a aNickname.
*
* @param aFootprintNames is the list to fill with the footprint names found in \a aNickname
* @param aNickname is a locator for the "library", it is a "name" in LIB_TABLE_ROW.
* @param aBestEfforts if true, don't throw on errors.
*
* @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded.
*/
void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname,
bool aBestEfforts );
/**
* Generate a hashed timestamp representing the last-mod-times of the library indicated
* by \a aNickname, or all libraries if \a aNickname is NULL.
*/
long long GenerateTimestamp( const wxString* aNickname );
/**
* Load a footprint having @a aFootprintName from the library given by @a aNickname.
*
* @param aNickname is a locator for the "library", it is a "name" in #LIB_TABLE_ROW.
* @param aFootprintName is the name of the footprint to load.
* @param aKeepUUID = true to keep initial items UUID, false to set new UUID
* normally true if loaded in the footprint editor, false
* if loaded in the board editor. Used only in kicad_plugin
* @return the footprint if found caller owns it, else NULL if not found.
*
* @throw IO_ERROR if the library cannot be found or read. No exception
* is thrown in the case where aFootprintName cannot be found.
*/
FOOTPRINT* FootprintLoad( const wxString& aNickname, const wxString& aFootprintName,
bool aKeepUUID = false );
/**
* Indicates whether or not the given footprint already exists in the given library.
*/
bool FootprintExists( const wxString& aNickname, const wxString& aFootprintName );
/**
* A version of #FootprintLoad() for use after #FootprintEnumerate() for more efficient
* cache management.
*
* The return value is const to allow it to return a reference to a cached item.
*/
const FOOTPRINT* GetEnumeratedFootprint( const wxString& aNickname,
const wxString& aFootprintName );
/**
* The set of return values from FootprintSave() below.
*/
enum SAVE_T
{
SAVE_OK,
SAVE_SKIPPED,
};
/**
* Write @a aFootprint to an existing library given by @a aNickname.
*
* If a footprint by the same name already exists, it is replaced.
*
* @param aNickname is a locator for the "library", it is a "name" in #LIB_TABLE_ROW.
* @param aFootprint is what to store in the library. The caller continues to own the
* footprint after this call.
* @param aOverwrite when true means overwrite any existing footprint by the same name,
* else if false means skip the write and return SAVE_SKIPPED.
* @return #SAVE_OK or #SAVE_SKIPPED. If error saving, then #IO_ERROR is thrown.
*
* @throw IO_ERROR if there is a problem saving.
*/
SAVE_T FootprintSave( const wxString& aNickname, const FOOTPRINT* aFootprint,
bool aOverwrite = true );
/**
* Delete the @a aFootprintName from the library given by @a aNickname.
*
* @param aNickname is a locator for the "library", it is a "name" in #LIB_TABLE_ROW.
* @param aFootprintName is the name of a footprint to delete from the specified library.
*
* @throw IO_ERROR if there is a problem finding the footprint or the library, or deleting it.
*/
void FootprintDelete( const wxString& aNickname, const wxString& aFootprintName );
/**
* Return true if the library given by @a aNickname is writable.
*
* Often system libraries are read only because of where they are installed.
*
* @throw IO_ERROR if no library at aLibraryPath exists.
*/
bool IsFootprintLibWritable( const wxString& aNickname );
void FootprintLibDelete( const wxString& aNickname );
void FootprintLibCreate( const wxString& aNickname );
/**
* Load a footprint having @a aFootprintId with possibly an empty nickname.
*
* @param aFootprintId the [nickname] and footprint name of the footprint to load.
* @param aKeepUUID = true to keep initial items UUID, false to set new UUID
* normally true if loaded in the footprint editor, false
* if loaded in the board editor
* used only in kicad_plugin
* @return the #FOOTPRINT if found caller owns it, else NULL if not found.
*
* @throw IO_ERROR if the library cannot be found or read. No exception is
* thrown in the case where \a aFootprintName cannot be found.
* @throw PARSE_ERROR if @a aFootprintId is not parsed OK.
*/
FOOTPRINT* FootprintLoadWithOptionalNickname( const LIB_ID& aFootprintId,
bool aKeepUUID = false );
/**
* Load the global footprint library table into \a aTable.
*
* This probably should be move into the application object when KiCad is changed
* to a single process application. This is the least painful solution for the
* time being.
*
* @param aTable the #FP_LIB_TABLE object to load.
* @return true if the global library table exists and is loaded properly.
* @throw IO_ERROR if an error occurs attempting to load the footprint library
* table.
*/
static bool LoadGlobalTable( FP_LIB_TABLE& aTable );
/**
* @return the platform specific global footprint library path and file name.
*/
static wxString GetGlobalTableFileName();
/**
* Return the name of the environment variable used to hold the directory of
* locally installed "KiCad sponsored" system footprint libraries.
*
*These can be either legacy or pretty format. The only thing special about this
* particular environment variable is that it is set automatically by KiCad on
* program start up, <b>if</b> it is not set already in the environment.
*/
static const wxString GlobalPathEnvVariableName();
private:
friend class FP_LIB_TABLE_GRID;
};
extern FP_LIB_TABLE GFootprintTable; // KIFACE scope.
#endif // FP_LIB_TABLE_H_
+1 -14
View File
@@ -37,20 +37,7 @@ enum KIFACE_ADDR_ID : int
* Caller does NOT own.
*/
KIFACE_FOOTPRINT_LIST,
/**
* Return a new FP_LIB_TABLE with the global table installed as a fallback.
* Type is FP_LIB_TABLE*
* Caller takes ownership
*/
KIFACE_NEW_FOOTPRINT_TABLE,
/**
* Return the global FP_LIB_TABLE.
* Type is FP_LIB_TABLE*
* Caller does NOT own.
*/
KIFACE_GLOBAL_FOOTPRINT_TABLE,
KIFACE_FOOTPRINT_LIBRARY_ADAPTER,
KIFACE_LOAD_SCHEMATIC,
KIFACE_NETLIST_SCHEMATIC,
+12 -1
View File
@@ -138,8 +138,17 @@ public:
bool IsLibraryLoaded( const wxString& aNickname );
/// Returns the status of a loaded library, or nullopt if the library hasn't been loaded (yet)
virtual std::optional<LIB_STATUS> GetLibraryStatus( const wxString& aNickname ) const = 0;
/// Returns a list of all library nicknames and their status (even if they failed to load)
std::vector<std::pair<wxString, LIB_STATUS>> GetLibraryStatuses() const;
/// Return true if the given nickname exists and is not a read-only library
virtual bool IsWritable( const wxString& aNickname ) const { return false; }
virtual bool IsWritable( const wxString& aNickname ) const;
/// Creates the library (i.e. saves to disk) for the given row if it exists
bool CreateLibrary( const wxString& aNickname );
virtual bool SupportsConfigurationDialog( const wxString& aNickname ) const { return false; }
@@ -165,6 +174,8 @@ protected:
/// Creates a concrete plugin for the given row
virtual LIBRARY_RESULT<IO_BASE*> createPlugin( const LIBRARY_TABLE_ROW* row ) = 0;
virtual IO_BASE* plugin( const LIB_DATA* aRow ) = 0;
LIBRARY_MANAGER& m_manager;
// The actual library content is held in an associated IO plugin
+3 -5
View File
@@ -44,13 +44,12 @@
#define NAMELESS_PROJECT _( "untitled" )
class DESIGN_BLOCK_LIBRARY_ADAPTER;
class FP_LIB_TABLE;
class LEGACY_SYMBOL_LIBS;
class SEARCH_STACK;
class S3D_CACHE;
class KIWAY;
class SYMBOL_LIB_TABLE;
class FILENAME_RESOLVER;
class FOOTPRINT_LIBRARY_ADAPTER;
class PROJECT_FILE;
class PROJECT_LOCAL_SETTINGS;
class LOCKFILE;
@@ -290,10 +289,9 @@ public:
virtual const wxString AbsolutePath( const wxString& aFileName ) const;
/**
* Return the table of footprint libraries. Requires an active Kiway as this is fetched
* from Pcbnew.
* Fetches the footprint library adapter from the PCB editor instance
*/
virtual FP_LIB_TABLE* PcbFootprintLibs( KIWAY& aKiway );
virtual FOOTPRINT_LIBRARY_ADAPTER* FootprintLibAdapter( KIWAY& aKiway );
/**
* Return the table of design block libraries.
+6 -6
View File
@@ -23,7 +23,7 @@
#pragma once
class FP_LIB_TABLE;
class FOOTPRINT_LIBRARY_ADAPTER;
class PROJECT;
class S3D_CACHE;
class FILENAME_RESOLVER;
@@ -31,10 +31,7 @@ class FILENAME_RESOLVER;
class PROJECT_PCB
{
public:
/**
* Return the table of footprint libraries without Kiway
*/
static FP_LIB_TABLE* PcbFootprintLibs( PROJECT* aProject );
static FOOTPRINT_LIBRARY_ADAPTER* FootprintLibAdapter( PROJECT* aProject );
/**
* Return a pointer to an instance of the 3D cache manager.
@@ -52,4 +49,7 @@ public:
private:
PROJECT_PCB() {}
};
/// Used to synchronise access to FootprintLibAdapter
static std::mutex s_libAdapterMutex;
};
-2
View File
@@ -34,8 +34,6 @@
#include <pcb_edit_frame.h>
#include <sch_edit_frame.h>
#include <fp_lib_table.h>
#include <sch_io/sch_io_mgr.h>
#include <pcb_io/pcb_io_mgr.h>
#include <project_sch.h>
+1 -1
View File
@@ -3475,7 +3475,7 @@ void BOARD::SaveToHistory( const wxString& aProjectPath, std::vector<wxString>&
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::KICAD_SEXP ) );
// Save directly to history mirror path.
pi->SaveBoard( dst.GetFullPath(), this, nullptr );
aFiles.push_back( dst.GetFullPath() );
+1 -1
View File
@@ -363,7 +363,7 @@ void DIALOG_BOARD_SETUP::onAuxiliaryAction( wxCommandEvent& aEvent )
PROJECT* otherPrj = m_frame->GetSettingsManager()->GetProject( projectFn.GetFullPath() );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::KICAD_SEXP ) );
BOARD* otherBoard = nullptr;
try
+1 -1
View File
@@ -271,7 +271,7 @@ void DIALOG_EXPORT_2581::onOKClick( wxCommandEvent& event )
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::IPC2581 ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::IPC2581 ) );
pi->SetProgressReporter( &progress );
pi->SetReporter( &reporter );
pi->SaveBoard( tempFile, m_parent->GetBoard(), &props );
+1 -1
View File
@@ -403,7 +403,7 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO
{
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::ODBPP ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::ODBPP ) );
pi->SetReporter( aReporter );
pi->SetProgressReporter( aProgressReporter );
pi->SaveBoard( tempFile.GetFullPath(), aBoard, &props );
@@ -26,7 +26,7 @@
#include <widgets/wx_grid.h>
#include <pcb_base_frame.h>
#include <kiface_base.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <board.h>
#include <footprint.h>
#include <project_pcb.h>
@@ -58,24 +58,17 @@ bool DIALOG_FOOTPRINT_ASSOCIATIONS::TransferDataToWindow()
wxString libDesc;
wxString fpDesc;
PROJECT* project = m_footprint->GetBoard()->GetProject();
FP_LIB_TABLE* libTable = PROJECT_PCB::PcbFootprintLibs( project );
const LIB_TABLE_ROW* libTableRow = nullptr;
PROJECT* project = m_footprint->GetBoard()->GetProject();
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( project );
try
{
libTableRow = libTable->FindRow( libName );
libDesc = libTableRow->GetDescr();
}
catch( const IO_ERROR& )
{
}
if( std::optional<LIBRARY_TABLE_ROW*> row = adapter->GetRow( libName ); row )
libDesc = ( *row )->Description();
std::shared_ptr<FOOTPRINT> libFootprint;
try
{
libFootprint.reset( libTable->FootprintLoad( libName, fpName, true ) );
libFootprint.reset( adapter->LoadFootprint( libName, fpName, true ) );
fpDesc = libFootprint->GetLibDescription();
}
catch( const IO_ERROR& )
@@ -58,7 +58,7 @@
#include <widgets/text_ctrl_eval.h>
#include <widgets/wx_grid.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <project_pcb.h>
#include <kidialog.h>
@@ -507,9 +507,10 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::checkFootprintName( const wxString&
LIB_ID fpID = m_footprint->GetFPID();
wxString libraryName = fpID.GetLibNickname();
wxString originalFPName = fpID.GetLibItemName();
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() );
if( aFootprintName != originalFPName && tbl->FootprintExists( libraryName, aFootprintName ) )
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() );
if( aFootprintName != originalFPName && adapter->FootprintExists( libraryName, aFootprintName ) )
{
wxString msg = wxString::Format( _( "Footprint '%s' already exists in library '%s'." ),
aFootprintName, libraryName );
+4 -10
View File
@@ -38,7 +38,8 @@
#include <3d_viewer/eda_3d_viewer_frame.h>
#include <panel_fp_lib_table.h>
#include <lib_id.h>
#include <fp_lib_table.h>
#include <lib_table_base.h>
#include <footprint_library_adapter.h>
#include <lib_table_lexer.h>
#include <invoke_pcb_dialog.h>
#include <bitmaps.h>
@@ -137,7 +138,7 @@ protected:
std::map<std::string, UTF8> choices;
PCB_IO_MGR::PCB_FILE_T pi_type = PCB_IO_MGR::EnumFromStr( row.Type() );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pi_type ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( pi_type ) );
pi->GetLibraryOptions( &choices );
DIALOG_PLUGIN_OPTIONS dlg( m_dialog, row.Nickname(), choices, options, &result );
@@ -1083,7 +1084,7 @@ void PANEL_FP_LIB_TABLE::populateEnvironReadOnlyTable()
// not used yet. It is automatically set by KiCad to the directory holding
// the current project.
unique.insert( PROJECT_VAR_NAME );
unique.insert( FP_LIB_TABLE::GlobalPathEnvVariableName() );
unique.insert( ENV_VAR::GetVersionedEnvVarName( wxS( "FOOTPRINT_DIR" ) ) );
// This special environment variable is used to locate 3d shapes
unique.insert( ENV_VAR::GetVersionedEnvVarName( wxS( "3DMODEL_DIR" ) ) );
@@ -1140,9 +1141,6 @@ void InvokePcbLibTableEditor( KIWAY* aKiway, wxWindow* aCaller )
} );
Pgm().GetLibraryManager().LoadGlobalTables( { LIBRARY_TABLE_TYPE::FOOTPRINT } );
// TODO(JE) library tables - remove after legacy loading is upgrade
GFootprintTable.Load( FP_LIB_TABLE::GetGlobalTableFileName() );
}
std::optional<LIBRARY_TABLE*> projectTable =
@@ -1160,10 +1158,6 @@ void InvokePcbLibTableEditor( KIWAY* aKiway, wxWindow* aCaller )
// Trigger a reload of the table and cancel an in-progress background load
Pgm().GetLibraryManager().ProjectChanged();
// TODO(JE) library tables - remove after legacy loading is upgrade
PROJECT* prj = &aKiway->Prj();
PROJECT_PCB::PcbFootprintLibs( prj )->Load( prj->FootprintLibTblName() );
}
// Trigger a reload in case any libraries have been added or removed
@@ -37,7 +37,7 @@
#include <widgets/std_bitmap_button.h>
#include <board.h>
#include <footprint.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <footprint_edit_frame.h>
#include <footprint_editor_settings.h>
#include <dialog_footprint_properties_fp_editor.h>
@@ -421,21 +421,12 @@ void PANEL_FP_PROPERTIES_3D_MODEL::OnAdd3DModel( wxCommandEvent& )
if( dm.IsEmbedded3DModel() )
{
wxString libraryName = m_footprint->GetFPID().GetLibNickname();
const FP_LIB_TABLE_ROW* fpRow = nullptr;
wxString footprintBasePath = wxEmptyString;
try
{
fpRow = PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() )->FindRow( libraryName, false );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
}
catch( ... )
{
// if libraryName is not found in table, do nothing
}
std::optional<LIBRARY_TABLE_ROW*> fpRow =
PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() )->GetRow( libraryName );
if( fpRow )
footprintBasePath = LIBRARY_MANAGER::GetFullURI( *fpRow, true );
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( m_filesPanel->GetLocalFiles() );
@@ -571,21 +562,12 @@ MODEL_VALIDATE_ERRORS PANEL_FP_PROPERTIES_3D_MODEL::validateModelExists( const w
return MODEL_VALIDATE_ERRORS::ILLEGAL_FILENAME;
wxString libraryName = m_footprint->GetFPID().GetLibNickname();
const FP_LIB_TABLE_ROW* fpRow = nullptr;
try
{
fpRow = PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() )->FindRow( libraryName, false );
}
catch( ... )
{
// if libraryName is not found in table, do nothing
}
wxString footprintBasePath = wxEmptyString;
std::optional<LIBRARY_TABLE_ROW*> fpRow =
PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() )->GetRow( libraryName );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
footprintBasePath = LIBRARY_MANAGER::GetFullURI( *fpRow, true );
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( m_filesPanel->GetLocalFiles() );
@@ -26,7 +26,7 @@
#include <kiway.h>
#include <macros.h>
#include <netlist_reader/pcb_netlist.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <board.h>
#include <pcb_shape.h>
#include <pcb_barcode.h>
@@ -979,7 +979,7 @@ bool DRC_TEST_PROVIDER_LIBRARY_PARITY::Run()
std::map<LIB_ID, std::shared_ptr<FOOTPRINT>> libFootprintCache;
FP_LIB_TABLE* libTable = PROJECT_PCB::PcbFootprintLibs( project );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( project );
wxString msg;
int ii = 0;
const int progressDelta = 250;
@@ -1001,7 +1001,7 @@ bool DRC_TEST_PROVIDER_LIBRARY_PARITY::Run()
LIB_ID fpID = footprint->GetFPID();
wxString libName = fpID.GetLibNickname();
wxString fpName = fpID.GetLibItemName();
const LIB_TABLE_ROW* libTableRow = nullptr;
LIBRARY_TABLE_ROW* libTableRow = nullptr;
if( libName.IsEmpty() )
{
@@ -1009,13 +1009,8 @@ bool DRC_TEST_PROVIDER_LIBRARY_PARITY::Run()
continue;
}
try
{
libTableRow = libTable->FindRow( libName );
}
catch( const IO_ERROR& )
{
}
if( std::optional<LIBRARY_TABLE_ROW*> optRow = adapter->GetRow( libName ); optRow )
libTableRow = *optRow;
if( !libTableRow )
{
@@ -1031,7 +1026,7 @@ bool DRC_TEST_PROVIDER_LIBRARY_PARITY::Run()
continue;
}
else if( !libTable->HasLibrary( libName, true ) )
else if( !adapter->HasLibrary( libName, true ) )
{
if( !m_drcEngine->IsErrorLimitExceeded( DRCE_LIB_FOOTPRINT_ISSUES ) )
{
@@ -1045,14 +1040,14 @@ bool DRC_TEST_PROVIDER_LIBRARY_PARITY::Run()
continue;
}
else if( !libTableRow->LibraryExists() )
else if( !adapter->IsLibraryLoaded( libName ) )
{
if( !m_drcEngine->IsErrorLimitExceeded( DRCE_LIB_FOOTPRINT_ISSUES ) )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_LIB_FOOTPRINT_ISSUES );
msg.Printf( _( "The footprint library '%s' was not found at '%s'" ),
UnescapeString( libName ),
libTableRow->GetFullURI( true ) );
LIBRARY_MANAGER::GetFullURI( libTableRow, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( footprint );
reportViolation( drcItem, footprint->GetCenter(), UNDEFINED_LAYER );
@@ -1072,7 +1067,7 @@ bool DRC_TEST_PROVIDER_LIBRARY_PARITY::Run()
{
try
{
libFootprint.reset( libTable->FootprintLoad( libName, fpName, true ) );
libFootprint.reset( adapter->LoadFootprint( libName, fpName, true ) );
if( libFootprint )
libFootprintCache[ fpID ] = libFootprint;
+4 -13
View File
@@ -30,7 +30,7 @@
#include <board.h>
#include <board_design_settings.h>
#include <footprint.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <idf_parser.h>
#include <pad.h>
#include <pcb_shape.h>
@@ -280,19 +280,10 @@ static void idf_export_footprint( BOARD* aPcb, FOOTPRINT* aFootprint, IDF3_BOARD
if( aPcb->GetProject() )
{
const FP_LIB_TABLE_ROW* fpRow = nullptr;
try
{
fpRow = PROJECT_PCB::PcbFootprintLibs( aPcb->GetProject() )->FindRow( libraryName, false );
}
catch( ... )
{
// Not found: do nothing
}
std::optional<LIBRARY_TABLE_ROW*> fpRow =
PROJECT_PCB::FootprintLibAdapter( aPcb->GetProject() )->GetRow( libraryName );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
footprintBasePath = LIBRARY_MANAGER::GetFullURI( *fpRow, true );
}
if( crefdes.empty() || !crefdes.compare( "~" ) )
+4 -13
View File
@@ -33,7 +33,7 @@
#include "3d_cache/3d_info.h"
#include "board.h"
#include "board_design_settings.h"
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include "footprint.h"
#include "pad.h"
#include "pcb_text.h"
@@ -1000,19 +1000,10 @@ void EXPORTER_PCB_VRML::ExportVrmlFootprint( FOOTPRINT* aFootprint, std::ostream
if( m_board->GetProject() )
{
const FP_LIB_TABLE_ROW* fpRow = nullptr;
try
{
fpRow = PROJECT_PCB::PcbFootprintLibs( m_board->GetProject() )->FindRow( libraryName, false );
}
catch( ... )
{
// Not found: do nothing
}
std::optional<LIBRARY_TABLE_ROW*> fpRow =
PROJECT_PCB::FootprintLibAdapter( m_board->GetProject() )->GetRow( libraryName );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
footprintBasePath = LIBRARY_MANAGER::GetFullURI( *fpRow, true );
}
+5 -14
View File
@@ -37,7 +37,7 @@
#include <pcb_painter.h>
#include <pad.h>
#include <zone.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include "step_pcb_model.h"
#include <pgm_base.h>
@@ -299,19 +299,10 @@ bool EXPORTER_STEP::buildFootprint3DShapes( FOOTPRINT* aFootprint, const VECTOR2
if( m_board->GetProject() )
{
try
{
// FindRow() can throw an exception
const FP_LIB_TABLE_ROW* fpRow =
PROJECT_PCB::PcbFootprintLibs( m_board->GetProject() )->FindRow( libraryName, false );
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
}
catch( ... )
{
// Do nothing if the libraryName is not found in lib table
}
std::optional<LIBRARY_TABLE_ROW*> fpRow =
PROJECT_PCB::FootprintLibAdapter( m_board->GetProject() )->GetRow( libraryName );
if( fpRow )
footprintBasePath = LIBRARY_MANAGER::GetFullURI( *fpRow, true );
}
// Exit early if we don't want to include footprint models
+9 -5
View File
@@ -37,7 +37,7 @@
#include <pcb_edit_frame.h>
#include <board_design_settings.h>
#include <3d_viewer/eda_3d_viewer_frame.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <kiface_base.h>
#include <macros.h>
#include <trace_helpers.h>
@@ -602,7 +602,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
else
{
BOARD* loadedBoard = nullptr; // it will be set to non-NULL if loaded OK
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( pluginType ) );
if( LAYER_MAPPABLE_PLUGIN* mappable_pi = dynamic_cast<LAYER_MAPPABLE_PLUGIN*>( pi.get() ) )
{
@@ -783,6 +783,9 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
}
// TODO(JE) library tables -- I think this functionality should be deleted
#if 0
// Import footprints into a project-specific library
//==================================================
// TODO: This should be refactored out of here into somewhere specific to the Project Import
@@ -804,7 +807,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
// which prompts the user to continue with overwrite or abort)
if( newLibPath.Length() > 0 )
{
IO_RELEASER<PCB_IO> piSexpr( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
IO_RELEASER<PCB_IO> piSexpr( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::KICAD_SEXP ) );
for( FOOTPRINT* footprint : loadedFootprints )
{
@@ -868,6 +871,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
}
}
}
#endif
}
{
@@ -1013,7 +1017,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::KICAD_SEXP ) );
pi->SaveBoard( pcbFileName.GetFullPath(), GetBoard(), nullptr );
}
@@ -1093,7 +1097,7 @@ bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::KICAD_SEXP ) );
wxASSERT( pcbFileName.IsAbsolute() );
+10 -10
View File
@@ -43,7 +43,7 @@
#include <footprint_edit_frame.h>
#include <footprint_editor_settings.h>
#include <footprint_info_impl.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <gal/graphics_abstraction_layer.h>
#include <kiface_base.h>
#include <kiplatform/app.h>
@@ -654,7 +654,7 @@ void FOOTPRINT_EDIT_FRAME::ReloadFootprint( FOOTPRINT* aFootprint )
// An empty libname is OK - you get that when creating a new footprint from the main menu
// In that case. treat is as editable, and the user will be prompted for save-as when saving.
else if( !libName.empty()
&& !PROJECT_PCB::PcbFootprintLibs( &Prj() )->IsFootprintLibWritable( libName ) )
&& !PROJECT_PCB::FootprintLibAdapter( &Prj() )->IsFootprintLibWritable( libName ) )
{
wxString msg = wxString::Format( _( "Editing footprint from read-only library %s." ),
UnescapeString( libName ) );
@@ -1069,7 +1069,7 @@ void FOOTPRINT_EDIT_FRAME::UpdateTitle()
{
try
{
writable = PROJECT_PCB::PcbFootprintLibs( &Prj() )->IsFootprintLibWritable( fpid.GetLibNickname() );
writable = PROJECT_PCB::FootprintLibAdapter( &Prj() )->IsFootprintLibWritable( fpid.GetLibNickname() );
}
catch( const IO_ERROR& )
{
@@ -1123,20 +1123,20 @@ void FOOTPRINT_EDIT_FRAME::UpdateView()
void FOOTPRINT_EDIT_FRAME::initLibraryTree()
{
FP_LIB_TABLE* fpTable = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FOOTPRINT_LIBRARY_ADAPTER* footprints = PROJECT_PCB::FootprintLibAdapter( &Prj() );
WX_PROGRESS_REPORTER progressReporter( this, _( "Load Footprint Libraries" ), 1, PR_CAN_ABORT );
if( GFootprintList.GetCount() == 0 )
GFootprintList.ReadCacheFromFile( Prj().GetProjectPath() + wxT( "fp-info-cache" ) );
GFootprintList.ReadFootprintFiles( fpTable, nullptr, &progressReporter );
GFootprintList.ReadFootprintFiles( footprints, nullptr, &progressReporter );
progressReporter.Show( false );
if( GFootprintList.GetErrorCount() )
GFootprintList.DisplayErrors( this );
m_adapter = FP_TREE_SYNCHRONIZING_ADAPTER::Create( this, fpTable );
m_adapter = FP_TREE_SYNCHRONIZING_ADAPTER::Create( this, footprints );
auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
adapter->AddLibraries( this );
@@ -1145,7 +1145,7 @@ void FOOTPRINT_EDIT_FRAME::initLibraryTree()
void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( bool aProgress )
{
FP_LIB_TABLE* fpTable = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FOOTPRINT_LIBRARY_ADAPTER* footprints = PROJECT_PCB::FootprintLibAdapter( &Prj() );
auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
LIB_ID target = GetTargetFPID();
bool targetSelected = ( target == GetLibTree()->GetSelectedLibId() );
@@ -1154,12 +1154,12 @@ void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( bool aProgress )
if( aProgress )
{
WX_PROGRESS_REPORTER progressReporter( this, _( "Update Footprint Libraries" ), 1, PR_CAN_ABORT );
GFootprintList.ReadFootprintFiles( fpTable, nullptr, &progressReporter );
GFootprintList.ReadFootprintFiles( footprints, nullptr, &progressReporter );
progressReporter.Show( false );
}
else
{
GFootprintList.ReadFootprintFiles( fpTable, nullptr, nullptr );
GFootprintList.ReadFootprintFiles( footprints, nullptr, nullptr );
}
// Unselect before syncing to avoid null reference in the adapter
@@ -1167,7 +1167,7 @@ void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( bool aProgress )
GetLibTree()->Unselect();
// Sync the LIB_TREE to the FOOTPRINT_INFO list
adapter->Sync( fpTable );
adapter->Sync( footprints );
GetLibTree()->Regenerate( true );
+6 -6
View File
@@ -26,7 +26,7 @@
#include <dialog_footprint_properties_fp_editor.h>
#include <footprint_edit_frame.h>
#include <footprint_tree_pane.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <functional>
#include <kiway_express.h>
#include <pcb_group.h>
@@ -346,10 +346,10 @@ void FOOTPRINT_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
wxString libNickname;
wxString msg;
FP_LIB_TABLE* libTable = PROJECT_PCB::PcbFootprintLibs( &Prj() );
const LIB_TABLE_ROW* libTableRow = libTable->FindRowByURI( fpFileName.GetPath() );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
std::optional<LIBRARY_TABLE_ROW*> optRow = adapter->FindRowByURI( fpFileName.GetPath() );
if( !libTableRow )
if( !optRow )
{
msg.Printf( _( "The current configuration does not include the footprint library '%s'." ),
fpFileName.GetPath() );
@@ -359,9 +359,9 @@ void FOOTPRINT_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
break;
}
libNickname = libTableRow->GetNickName();
libNickname = ( *optRow )->Nickname();
if( !libTable->HasLibrary( libNickname, true ) )
if( !adapter->HasLibrary( libNickname, true ) )
{
msg.Printf( _( "The footprint library '%s' is not enabled in the current configuration." ),
libNickname );
+10 -11
View File
@@ -25,7 +25,7 @@
#include <dialogs/html_message_box.h>
#include <footprint.h>
#include <footprint_info.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <kiway.h>
#include <lib_id.h>
#include <progress_reporter.h>
@@ -42,11 +42,10 @@
void FOOTPRINT_INFO_IMPL::load()
{
FP_LIB_TABLE* fptable = m_owner->GetTable();
FOOTPRINT_LIBRARY_ADAPTER* adapter = m_owner->GetAdapter();
wxCHECK( adapter, /* void */ );
wxASSERT( fptable );
const FOOTPRINT* footprint = fptable->GetEnumeratedFootprint( m_nickname, m_fpname );
const FOOTPRINT* footprint = adapter->LoadFootprint( m_nickname, m_fpname, false );
if( footprint == nullptr ) // Should happen only with malformed/broken libraries
{
@@ -103,14 +102,14 @@ bool FOOTPRINT_LIST_IMPL::CatchErrors( const std::function<void()>& aFunc )
}
bool FOOTPRINT_LIST_IMPL::ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxString* aNickname,
bool FOOTPRINT_LIST_IMPL::ReadFootprintFiles( FOOTPRINT_LIBRARY_ADAPTER* aAdapter, const wxString* aNickname,
PROGRESS_REPORTER* aProgressReporter )
{
long long int generatedTimestamp = 0;
if( !CatchErrors( [&]()
{
generatedTimestamp = aTable->GenerateTimestamp( aNickname );
generatedTimestamp = aAdapter->GenerateTimestamp( aNickname );
} ) )
{
return false;
@@ -125,7 +124,7 @@ bool FOOTPRINT_LIST_IMPL::ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxStri
m_progress_reporter = aProgressReporter;
m_cancelled = false;
m_lib_table = aTable;
m_adapter = aAdapter;
// Clear data before reading files
m_errors.clear();
@@ -138,7 +137,7 @@ bool FOOTPRINT_LIST_IMPL::ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxStri
}
else
{
for( const wxString& nickname : aTable->GetLogicalLibs() )
for( const wxString& nickname : aAdapter->GetLibraryNames() )
m_queue.push( nickname );
}
@@ -179,12 +178,12 @@ void FOOTPRINT_LIST_IMPL::loadFootprints()
if( m_cancelled || !m_queue.pop( nickname ) )
return 0;
wxArrayString fpnames;
std::vector<wxString> fpnames;
CatchErrors(
[&]()
{
m_lib_table->FootprintEnumerate( fpnames, nickname, false );
fpnames = m_adapter->GetFootprintNames( nickname );
} );
for( wxString fpname : fpnames )
+1 -1
View File
@@ -89,7 +89,7 @@ public:
void WriteCacheToFile( const wxString& aFilePath ) override;
void ReadCacheFromFile( const wxString& aFilePath ) override;
bool ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxString* aNickname = nullptr,
bool ReadFootprintFiles( FOOTPRINT_LIBRARY_ADAPTER* aAdapter, const wxString* aNickname = nullptr,
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;
void Clear() override;
+84 -73
View File
@@ -30,7 +30,7 @@
#include <pcb_edit_frame.h>
#include <eda_list_dialog.h>
#include <filter_reader.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <validators.h>
#include <dialogs/dialog_text_entry.h>
#include <tool/tool_manager.h>
@@ -183,7 +183,7 @@ FOOTPRINT* FOOTPRINT_EDIT_FRAME::ImportFootprint( const wxString& aName )
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( fileType ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( fileType ) );
footprint = pi->ImportFootprint( fn.GetFullPath(), footprintName);
@@ -298,18 +298,18 @@ void FOOTPRINT_EDIT_FRAME::ExportFootprint( FOOTPRINT* aFootprint )
wxString PCB_BASE_EDIT_FRAME::CreateNewProjectLibrary( const wxString& aDialogTitle, const wxString& aLibName )
{
return createNewLibrary( aDialogTitle, aLibName, wxEmptyString, PROJECT_PCB::PcbFootprintLibs( &Prj() ) );
return createNewLibrary( aDialogTitle, aLibName, wxEmptyString, LIBRARY_TABLE_SCOPE::PROJECT );
}
wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary( const wxString& aDialogTitle, const wxString& aInitialPath )
{
return createNewLibrary( aDialogTitle, wxEmptyString, aInitialPath, nullptr );
return createNewLibrary( aDialogTitle, wxEmptyString, aInitialPath );
}
wxString PCB_BASE_EDIT_FRAME::createNewLibrary( const wxString& aDialogTitle, const wxString& aLibName,
const wxString& aInitialPath, FP_LIB_TABLE* aTable )
const wxString& aInitialPath, std::optional<LIBRARY_TABLE_SCOPE> aScope )
{
// Kicad cannot write legacy format libraries, only .pretty new format because the legacy
// format cannot handle current features.
@@ -318,16 +318,11 @@ wxString PCB_BASE_EDIT_FRAME::createNewLibrary( const wxString& aDialogTitle, co
wxFileName fn;
bool doAdd = false;
bool isGlobal = false;
FP_LIB_TABLE* libTable = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FILEDLG_HOOK_NEW_LIBRARY tableChooser( isGlobal );
FILEDLG_HOOK_NEW_LIBRARY* fileDlgHook = &tableChooser;
if( aTable )
{
isGlobal = ( aTable == &GFootprintTable );
libTable = aTable;
if( aScope )
fileDlgHook = nullptr;
}
if( aLibName.IsEmpty() )
{
@@ -342,7 +337,7 @@ wxString PCB_BASE_EDIT_FRAME::createNewLibrary( const wxString& aDialogTitle, co
if( fileDlgHook )
{
isGlobal = fileDlgHook->GetUseGlobalTable();
libTable = isGlobal ? &GFootprintTable : PROJECT_PCB::PcbFootprintLibs( &Prj() );
aScope = isGlobal ? LIBRARY_TABLE_SCOPE::GLOBAL : LIBRARY_TABLE_SCOPE::PROJECT;
}
doAdd = true;
@@ -364,7 +359,7 @@ wxString PCB_BASE_EDIT_FRAME::createNewLibrary( const wxString& aDialogTitle, co
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( piType ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( piType ) );
bool writable = false;
bool exists = false;
@@ -410,7 +405,7 @@ wxString PCB_BASE_EDIT_FRAME::createNewLibrary( const wxString& aDialogTitle, co
}
if( doAdd )
AddLibrary( aDialogTitle, libPath, libTable );
AddLibrary( aDialogTitle, libPath, aScope );
return libPath;
}
@@ -479,17 +474,15 @@ wxString PCB_BASE_EDIT_FRAME::SelectLibrary( const wxString& aDialogTitle, const
bool PCB_BASE_EDIT_FRAME::AddLibrary( const wxString& aDialogTitle, const wxString& aFilename,
FP_LIB_TABLE* aTable )
std::optional<LIBRARY_TABLE_SCOPE> aScope )
{
bool isGlobal = false;
FP_LIB_TABLE* libTable = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FILEDLG_HOOK_NEW_LIBRARY tableChooser( isGlobal );
FILEDLG_HOOK_NEW_LIBRARY* fileDlgHook = &tableChooser;
if( aTable )
if( aScope )
{
isGlobal = ( aTable == &GFootprintTable );
libTable = aTable;
isGlobal = ( *aScope == LIBRARY_TABLE_SCOPE::GLOBAL );
fileDlgHook = nullptr;
}
@@ -506,7 +499,7 @@ bool PCB_BASE_EDIT_FRAME::AddLibrary( const wxString& aDialogTitle, const wxStri
if( fileDlgHook )
{
isGlobal = fileDlgHook->GetUseGlobalTable();
libTable = isGlobal ? &GFootprintTable : PROJECT_PCB::PcbFootprintLibs( &Prj() );
aScope = isGlobal ? LIBRARY_TABLE_SCOPE::GLOBAL : LIBRARY_TABLE_SCOPE::PROJECT;
}
}
@@ -533,13 +526,21 @@ bool PCB_BASE_EDIT_FRAME::AddLibrary( const wxString& aDialogTitle, const wxStri
try
{
FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( libName, normalizedPath, type, wxEmptyString );
libTable->InsertRow( row );
std::optional<LIBRARY_TABLE*> table = Pgm().GetLibraryManager().Table( LIBRARY_TABLE_TYPE::FOOTPRINT, *aScope );
wxCHECK( table, false );
if( isGlobal )
libTable->Save( FP_LIB_TABLE::GetGlobalTableFileName() );
else
libTable->Save( Prj().FootprintLibTblName() );
LIBRARY_TABLE_ROW& row = ( *table )->InsertRow();
row.SetNickname( libName );
row.SetURI( normalizedPath );
row.SetType( type );
( *table )->Save().map_error(
[]( const LIBRARY_ERROR& aError )
{
wxMessageBox( wxString::Format( _( "Error saving library table:\n\n%s" ), aError.message ),
_( "File Save Error" ), wxOK | wxICON_ERROR );
} );
}
catch( const IO_ERROR& ioe )
{
@@ -570,21 +571,19 @@ bool FOOTPRINT_EDIT_FRAME::DeleteFootprintFromLibrary( const LIB_ID& aFPID, bool
if( !aFPID.IsValid() )
return false;
LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
wxString nickname = aFPID.GetLibNickname();
wxString fpname = aFPID.GetLibItemName();
wxString libfullname;
// Legacy libraries are readable, but modifying legacy format is not allowed
// So prompt the user if he try to delete a footprint from a legacy lib
try
{
libfullname = PROJECT_PCB::PcbFootprintLibs( &Prj() )->FindRow( nickname )->GetFullURI();
}
catch( ... )
{
// If we can't find the nickname, stop here
if( std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, nickname ) )
libfullname = *optUri;
else
return false;
}
if( PCB_IO_MGR::GuessPluginTypeFromLibPath( libfullname ) == PCB_IO_MGR::LEGACY )
{
@@ -592,7 +591,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteFootprintFromLibrary( const LIB_ID& aFPID, bool
return false;
}
if( !PROJECT_PCB::PcbFootprintLibs( &Prj() )->IsFootprintLibWritable( nickname ) )
if( !adapter->IsFootprintLibWritable( nickname ) )
{
wxString msg = wxString::Format( _( "Library '%s' is read only." ), nickname );
ShowInfoBarError( msg );
@@ -609,7 +608,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteFootprintFromLibrary( const LIB_ID& aFPID, bool
try
{
PROJECT_PCB::PcbFootprintLibs( &Prj() )->FootprintDelete( nickname, fpname );
adapter->DeleteFootprint( nickname, fpname );
}
catch( const IO_ERROR& ioe )
{
@@ -650,7 +649,7 @@ void PCB_EDIT_FRAME::ExportFootprintsToLibrary( bool aStoreInNewLib, const wxStr
{
try
{
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &prj );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
if( !footprint->GetFPID().GetLibItemName().empty() ) // Handle old boards.
{
@@ -666,7 +665,7 @@ void PCB_EDIT_FRAME::ExportFootprintsToLibrary( bool aStoreInNewLib, const wxStr
for( ZONE* zone : fpCopy->Zones() )
zone->Move( -fpCopy->GetPosition() );
tbl->FootprintSave( nickname, fpCopy, true );
adapter->SaveFootprint( nickname, fpCopy, true );
delete fpCopy;
}
@@ -722,21 +721,16 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( FOOTPRINT* aFootprint )
return false;
}
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
// Legacy libraries are readable, but modifying legacy format is not allowed
// So prompt the user if he try to add/replace a footprint in a legacy lib
wxString libfullname;
try
{
libfullname = tbl->FindRow( libraryName )->GetFullURI();
}
catch( IO_ERROR& error )
{
DisplayInfoMessage( this, error.What() );
if( std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, libraryName ) )
libfullname = *optUri;
else
return false;
}
if( PCB_IO_MGR::GuessPluginTypeFromLibPath( libfullname ) == PCB_IO_MGR::LEGACY )
{
@@ -765,26 +759,33 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( FOOTPRINT* aFootprint )
bool FOOTPRINT_EDIT_FRAME::DuplicateFootprint( FOOTPRINT* aFootprint )
{
LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
LIB_ID fpID = aFootprint->GetFPID();
wxString libraryName = fpID.GetLibNickname();
wxString footprintName = fpID.GetLibItemName();
// Legacy libraries are readable, but modifying legacy format is not allowed
// So prompt the user if he try to add/replace a footprint in a legacy lib
wxString libFullName = PROJECT_PCB::PcbFootprintLibs( &Prj() )->FindRow( libraryName )->GetFullURI();
if( PCB_IO_MGR::GuessPluginTypeFromLibPath( libFullName ) == PCB_IO_MGR::LEGACY )
if( std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, libraryName ) )
{
if( PCB_IO_MGR::GuessPluginTypeFromLibPath( *optUri ) == PCB_IO_MGR::LEGACY )
{
DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
return false;
}
}
else
{
DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
return false;
}
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
int i = 1;
wxString newName = footprintName;
// Append a number to the name until the name is unique in the library.
while( tbl->FootprintExists( libraryName, newName ) )
while( adapter->FootprintExists( libraryName, newName ) )
newName.Printf( "%s_%d", footprintName, i++ );
aFootprint->SetFPID( LIB_ID( libraryName, newName ) );
@@ -803,7 +804,8 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( FOOTPRINT* aFootprint,
{
aFootprint->SetFPID( LIB_ID( wxEmptyString, aFootprint->GetFPID().GetLibItemName() ) );
PROJECT_PCB::PcbFootprintLibs( &Prj() )->FootprintSave( aLibraryName, aFootprint );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
adapter->SaveFootprint( aLibraryName, aFootprint );
aFootprint->SetFPID( LIB_ID( aLibraryName, aFootprint->GetFPID().GetLibItemName() ) );
@@ -967,8 +969,8 @@ public:
EDA_LIST_DIALOG( aParent, _( "Save Footprint As" ), false ),
m_validator( std::move( aValidator ) )
{
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &aParent->Prj() );
std::vector<wxString> nicknames = tbl->GetLogicalLibs();
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
std::vector<wxString> nicknames = adapter->GetLibraryNames();
wxArrayString headers;
std::vector<wxArrayString> itemsToDisplay;
@@ -1041,7 +1043,8 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( FOOTPRINT* aFootprint )
if( aFootprint == nullptr )
return false;
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
SetMsgPanel( aFootprint );
@@ -1070,17 +1073,20 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( FOOTPRINT* aFootprint )
// Legacy libraries are readable, but modifying legacy format is not allowed
// So prompt the user if he try to add/replace a footprint in a legacy lib
const FP_LIB_TABLE_ROW* row = PROJECT_PCB::PcbFootprintLibs( &Prj() )->FindRow( newLib );
wxString libPath = row->GetFullURI();
PCB_IO_MGR::PCB_FILE_T piType = PCB_IO_MGR::GuessPluginTypeFromLibPath( libPath );
if( piType == PCB_IO_MGR::LEGACY )
if( std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, newLib ) )
{
if( PCB_IO_MGR::GuessPluginTypeFromLibPath( *optUri ) == PCB_IO_MGR::LEGACY )
{
DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
return false;
}
}
else
{
DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
return false;
}
footprintExists = tbl->FootprintExists( newLib, newName );
footprintExists = adapter->FootprintExists( newLib, newName );
if( footprintExists )
{
@@ -1182,22 +1188,22 @@ FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( wxString aFootprintName, const wx
if( !aLibName.IsEmpty() )
{
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
wxArrayString fpnames;
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
std::vector<wxString> fpnames;
wxString baseName = aFootprintName;
int idx = 1;
// Make sure the name is unique
while( tbl->FootprintExists( aLibName, aFootprintName ) )
while( adapter->FootprintExists( aLibName, aFootprintName ) )
aFootprintName = baseName + wxString::Format( wxS( "_%d" ), idx++ );
// Try to infer the footprint attributes from an existing footprint in the library
try
{
tbl->FootprintEnumerate( fpnames, aLibName, true );
fpnames = adapter->GetFootprintNames( aLibName, true );
if( !fpnames.empty() )
footprintAttrs = tbl->FootprintLoad( aLibName, fpnames.Last() )->GetAttributes();
footprintAttrs = adapter->LoadFootprint( aLibName, fpnames.back(), false )->GetAttributes();
}
catch( ... )
{
@@ -1288,31 +1294,36 @@ void PCB_BASE_FRAME::GetLibraryItemsForListDialog( wxArrayString& aHeaders,
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = Kiway().Prj().GetProjectFile();
FP_LIB_TABLE* fptbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
std::vector<wxString> nicknames = fptbl->GetLogicalLibs();
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
std::vector<wxString> nicknames = adapter->GetLibraryNames();
for( const wxString& nickname : nicknames )
{
wxString description = adapter->GetLibraryDescription( nickname ).value_or( wxEmptyString );
if( alg::contains( project.m_PinnedFootprintLibs, nickname )
|| alg::contains( cfg->m_Session.pinned_fp_libs, nickname ) )
{
wxArrayString item;
item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
item.Add( fptbl->GetDescription( nickname ) );
item.Add( description );
aItemsToDisplay.push_back( item );
}
}
// TODO this double loop isn't used on the symbol side, what is broken here?
for( const wxString& nickname : nicknames )
{
wxString description = adapter->GetLibraryDescription( nickname ).value_or( wxEmptyString );
if( !alg::contains( project.m_PinnedFootprintLibs, nickname )
&& !alg::contains( cfg->m_Session.pinned_fp_libs, nickname ) )
{
wxArrayString item;
item.Add( nickname );
item.Add( fptbl->GetDescription( nickname ) );
item.Add( description );
aItemsToDisplay.push_back( item );
}
}
+387
View File
@@ -0,0 +1,387 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
* @author Jon Evans <jon@craftyjon.com>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <footprint_library_adapter.h>
#include <env_vars.h>
#include <trace_helpers.h>
#include <magic_enum.hpp>
#include <wx/hash.h>
std::map<wxString, LIB_DATA> FOOTPRINT_LIBRARY_ADAPTER::GlobalLibraries;
std::mutex FOOTPRINT_LIBRARY_ADAPTER::GlobalLibraryMutex;
FOOTPRINT_LIBRARY_ADAPTER::FOOTPRINT_LIBRARY_ADAPTER( LIBRARY_MANAGER& aManager ) :
LIBRARY_MANAGER_ADAPTER( aManager )
{
}
wxString FOOTPRINT_LIBRARY_ADAPTER::GlobalPathEnvVariableName()
{
return ENV_VAR::GetVersionedEnvVarName( wxS( "FOOTPRINT_DIR" ) );
}
void FOOTPRINT_LIBRARY_ADAPTER::AsyncLoad()
{
}
std::optional<LIB_STATUS> FOOTPRINT_LIBRARY_ADAPTER::LoadOne( const wxString& aNickname )
{
if( LIBRARY_RESULT<LIB_DATA*> result = loadIfNeeded( aNickname ); result.has_value() )
{
LIB_DATA* lib = *result;
std::lock_guard lock ( lib->mutex );
lib->status.load_status = LOAD_STATUS::LOADING;
std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
try
{
wxArrayString dummyList;
pcbplugin( lib )->FootprintEnumerate( dummyList, getUri( lib->row ), true, &options );
wxLogTrace( traceLibraries, "Sym: %s: library enumerated %zu items", aNickname, dummyList.size() );
lib->status.load_status = LOAD_STATUS::LOADED;
}
catch( IO_ERROR& e )
{
lib->status.load_status = LOAD_STATUS::LOAD_ERROR;
lib->status.error = LIBRARY_ERROR( { e.What() } );
wxLogTrace( traceLibraries, "Sym: %s: plugin threw exception: %s", aNickname, e.What() );
}
return lib->status;
}
return std::nullopt;
}
std::optional<LIB_STATUS> FOOTPRINT_LIBRARY_ADAPTER::GetLibraryStatus( const wxString& aNickname ) const
{
// TODO(JE) this could be deduplicated with virtual access to GlobalLibraries
if( m_libraries.contains( aNickname ) )
return m_libraries.at( aNickname ).status;
if( GlobalLibraries.contains( aNickname ) )
return GlobalLibraries.at( aNickname ).status;
return std::nullopt;
}
std::vector<FOOTPRINT*> FOOTPRINT_LIBRARY_ADAPTER::GetFootprints( const wxString& aNickname, bool aBestEfforts )
{
std::vector<FOOTPRINT*> footprints;
std::optional<const LIB_DATA*> maybeLib = fetchIfLoaded( aNickname );
if( !maybeLib )
return footprints;
const LIB_DATA* lib = *maybeLib;
std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
wxArrayString namesAS;
try
{
pcbplugin( lib )->FootprintEnumerate( namesAS, getUri( lib->row ), true, &options );
}
catch( IO_ERROR& e )
{
wxLogTrace( traceLibraries, "FP: Exception enumerating library %s: %s",
lib->row->Nickname(), e.What() );
}
for( const wxString& footprintName : namesAS )
{
FOOTPRINT* footprint = nullptr;
try
{
footprint = pcbplugin( lib )->FootprintLoad( getUri( lib->row ),footprintName, false, &options );
}
catch( IO_ERROR& e )
{
wxLogTrace( traceLibraries, "Sym: Exception enumerating library %s: %s",
lib->row->Nickname(), e.What() );
continue;
}
wxCHECK2( footprint, continue );
LIB_ID id = footprint->GetFPID();
id.SetLibNickname( lib->row->Nickname() );
footprint->SetFPID( id );
footprints.emplace_back( footprint );
}
return footprints;
}
std::vector<wxString> FOOTPRINT_LIBRARY_ADAPTER::GetFootprintNames( const wxString& aNickname, bool aBestEfforts )
{
// TODO(JE) can we kill wxArrayString in internal API?
wxArrayString namesAS;
std::vector<wxString> names;
if( std::optional<const LIB_DATA*> maybeLib = fetchIfLoaded( aNickname ) )
{
const LIB_DATA* lib = *maybeLib;
std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
try
{
pcbplugin( lib )->FootprintEnumerate( namesAS, getUri( lib->row ), true, &options );
}
catch( IO_ERROR& e )
{
wxLogTrace( traceLibraries, "FP: Exception enumerating library %s: %s",
lib->row->Nickname(), e.What() );
}
}
for( const wxString& name : namesAS )
names.emplace_back( name );
return names;
}
long long FOOTPRINT_LIBRARY_ADAPTER::GenerateTimestamp( const wxString* aNickname )
{
long long hash = 0;
if( aNickname )
{
wxCHECK( HasLibrary( *aNickname, true ), hash );
if( std::optional<const LIB_DATA*> r = fetchIfLoaded( *aNickname ); r.has_value() )
{
PCB_IO* plugin = dynamic_cast<PCB_IO*>( ( *r )->plugin.get() );
wxCHECK( plugin, hash );
return plugin->GetLibraryTimestamp( LIBRARY_MANAGER::GetFullURI( ( *r )->row, true ) ) +
wxHashTable::MakeKey( *aNickname );
}
}
for( const wxString& nickname : GetLibraryNames() )
{
if( std::optional<const LIB_DATA*> r = fetchIfLoaded( nickname ); r.has_value() )
{
PCB_IO* plugin = dynamic_cast<PCB_IO*>( ( *r )->plugin.get() );
wxCHECK2( plugin, continue );
hash += plugin->GetLibraryTimestamp( LIBRARY_MANAGER::GetFullURI( ( *r )->row, true ) ) +
wxHashTable::MakeKey( nickname );
}
}
return hash;
}
bool FOOTPRINT_LIBRARY_ADAPTER::FootprintExists( const wxString& aNickname, const wxString& aName )
{
if( std::optional<const LIB_DATA*> maybeLib = fetchIfLoaded( aNickname ) )
{
const LIB_DATA* lib = *maybeLib;
std::map<std::string, UTF8> options = lib->row->GetOptionsMap();
return pcbplugin( lib )->FootprintExists( getUri( lib->row ), aName, &options );
}
return false;
}
FOOTPRINT* FOOTPRINT_LIBRARY_ADAPTER::LoadFootprint( const wxString& aNickname, const wxString& aName, bool aKeepUUID )
{
if( std::optional<const LIB_DATA*> lib = fetchIfLoaded( aNickname ) )
{
if( FOOTPRINT* footprint = pcbplugin( *lib )->FootprintLoad( getUri( ( *lib )->row ), aName ) )
{
LIB_ID id = footprint->GetFPID();
id.SetLibNickname( ( *lib )->row->Nickname() );
footprint->SetFPID( id );
return footprint;
}
}
else
{
wxLogTrace( traceLibraries, "LoadFootprint: requested library %s not loaded", aNickname );
}
return nullptr;
}
FOOTPRINT* FOOTPRINT_LIBRARY_ADAPTER::LoadFootprintWithOptionalNickname( const LIB_ID& aFootprintId, bool aKeepUUID )
{
wxString nickname = aFootprintId.GetLibNickname();
wxString footprintName = aFootprintId.GetLibItemName();
if( nickname.size() )
return LoadFootprint( nickname, footprintName, aKeepUUID );
// nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
for( const wxString& library : GetLibraryNames() )
{
// FootprintLoad() returns NULL on not found, does not throw exception
// unless there's an IO_ERROR.
if( FOOTPRINT* ret = LoadFootprint( library, footprintName, aKeepUUID ) )
return ret;
}
return nullptr;
}
FOOTPRINT_LIBRARY_ADAPTER::SAVE_T FOOTPRINT_LIBRARY_ADAPTER::SaveFootprint( const wxString& aNickname,
const FOOTPRINT* aFootprint,
bool aOverwrite )
{
wxCHECK( aFootprint, SAVE_SKIPPED );
if( std::optional<const LIB_DATA*> lib = fetchIfLoaded( aNickname ) )
{
if( !aOverwrite )
{
wxString fpname = aFootprint->GetFPID().GetLibItemName();
try
{
FOOTPRINT* existing = pcbplugin( *lib )->FootprintLoad( getUri( ( *lib )->row ), fpname, false );
if( existing )
return SAVE_SKIPPED;
}
catch( IO_ERROR& e )
{
wxLogTrace( traceLibraries, "SaveFootprint: error checking for existing footprint %s: %s",
aFootprint->GetFPIDAsString(), e.What() );
return SAVE_SKIPPED;
}
}
try
{
pcbplugin( *lib )->FootprintSave( getUri( ( *lib )->row ), aFootprint );
}
catch( IO_ERROR& e )
{
wxLogTrace( traceLibraries, "SaveFootprint: error saving %s: %s",
aFootprint->GetFPIDAsString(), e.What() );
return SAVE_SKIPPED;
}
return SAVE_OK;
}
else
{
wxLogTrace( traceLibraries, "SaveFootprint: requested library %s not loaded", aNickname );
return SAVE_SKIPPED;
}
}
void FOOTPRINT_LIBRARY_ADAPTER::DeleteFootprint( const wxString& aNickname, const wxString& aFootprintName )
{
if( std::optional<const LIB_DATA*> lib = fetchIfLoaded( aNickname ) )
{
try
{
pcbplugin( *lib )->FootprintDelete( getUri( ( *lib )->row ), aFootprintName );
}
catch( IO_ERROR& e )
{
wxLogTrace( traceLibraries, "DeleteFootprint: error deleting %s:%s: %s", aNickname,
aFootprintName, e.What() );
}
}
else
{
wxLogTrace( traceLibraries, "DeleteFootprint: requested library %s not loaded", aNickname );
}
}
bool FOOTPRINT_LIBRARY_ADAPTER::IsFootprintLibWritable( const wxString& aLib )
{
if( m_libraries.contains( aLib ) )
return m_libraries[aLib].plugin->IsLibraryWritable( getUri( m_libraries[aLib].row ) );
if( GlobalLibraries.contains( aLib ) )
return GlobalLibraries[aLib].plugin->IsLibraryWritable( getUri( GlobalLibraries[aLib].row ) );
return false;
}
std::optional<LIBRARY_ERROR> FOOTPRINT_LIBRARY_ADAPTER::LibraryError( const wxString& aNickname ) const
{
if( m_libraries.contains( aNickname ) )
{
return m_libraries.at( aNickname ).status.error;
}
if( GlobalLibraries.contains( aNickname ) )
{
return GlobalLibraries.at( aNickname ).status.error;
}
return std::nullopt;
}
LIBRARY_RESULT<IO_BASE*> FOOTPRINT_LIBRARY_ADAPTER::createPlugin( const LIBRARY_TABLE_ROW* row )
{
PCB_IO_MGR::PCB_FILE_T type = PCB_IO_MGR::EnumFromStr( row->Type() );
if( type == PCB_IO_MGR::PCB_FILE_UNKNOWN )
{
wxLogTrace( traceLibraries, "FP: Plugin type %s is unknown!", row->Type() );
wxString msg = wxString::Format( _( "Unknown library type %s " ), row->Type() );
return tl::unexpected( LIBRARY_ERROR( msg ) );
}
PCB_IO* plugin = PCB_IO_MGR::FindPlugin( type );
wxCHECK( plugin, tl::unexpected( LIBRARY_ERROR( _( "Internal error" ) ) ) );
wxLogTrace( traceLibraries, "FP: Library %s (%s) plugin created",
row->Nickname(), magic_enum::enum_name( row->Scope() ) );
return plugin;
}
PCB_IO* FOOTPRINT_LIBRARY_ADAPTER::pcbplugin( const LIB_DATA* aRow )
{
PCB_IO* ret = dynamic_cast<PCB_IO*>( aRow->plugin.get() );
wxCHECK( aRow->plugin && ret, nullptr );
return ret;
}
+190
View File
@@ -0,0 +1,190 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
* @author Jon Evans <jon@craftyjon.com>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FOOTPRINT_LIBRARY_ADAPTER_H
#define FOOTPRINT_LIBRARY_ADAPTER_H
#include <lib_id.h>
#include <libraries/library_manager.h>
#include <pcb_io/pcb_io.h>
#include <project.h>
class FOOTPRINT;
/**
* An interface to the global shared library manager that is schematic-specific
* and linked to one project in particular. This is what can return actual concrete
* schematic library content (symbols).
*/
class FOOTPRINT_LIBRARY_ADAPTER : public LIBRARY_MANAGER_ADAPTER, public PROJECT::_ELEM
{
public:
FOOTPRINT_LIBRARY_ADAPTER( LIBRARY_MANAGER& aManager );
LIBRARY_TABLE_TYPE Type() const override { return LIBRARY_TABLE_TYPE::FOOTPRINT; }
PROJECT::ELEM ProjectElementType() override { return PROJECT::ELEM::FPTBL; }
static wxString GlobalPathEnvVariableName();
void AsyncLoad() override;
/// Loads or reloads the given library, if it exists
std::optional<LIB_STATUS> LoadOne( const wxString& aNickname );
/// Returns the status of a loaded library, or nullopt if the library hasn't been loaded (yet)
std::optional<LIB_STATUS> GetLibraryStatus( const wxString& aNickname ) const override;
/**
* Retrieves a list of footprints contained in a given loaded library
* @param aNickname is the library to query
* @param aBestEfforts if true, don't throw on errors, just return a smaller or empty list.
* @return a list of footprints contained in the given library
*/
std::vector<FOOTPRINT*> GetFootprints( const wxString& aNickname, bool aBestEfforts = false );
/**
* Retrieves a list of footprint names contained in a given loaded library
* @param aNickname is the library to query
* @param aBestEfforts if true, don't throw on errors, just return a smaller or empty list.
* @return a list of names of footprints contained in the given library
*/
std::vector<wxString> GetFootprintNames( const wxString& aNickname, bool aBestEfforts = false );
/**
* Generates a filesystem timestamp / hash value for library(ies)
* @param aNickname is an optional specific library to timestamp. If nullptr,
* a timestamp will be calculated for all libraries in the table.
* @return a value that can be used to determine if libraries have changed on disk
*/
long long GenerateTimestamp( const wxString* aNickname );
bool FootprintExists( const wxString& aNickname, const wxString& aName );
/**
* Load a #FOOTPRINT having @a aName from the library given by @a aNickname.
*
* @param aNickname is a locator for the "library", it is a "name" in #LIB_TABLE_ROW
* @param aName is the name of the #FOOTPRINT to load.
* @param aKeepUUID = true to keep initial items UUID, false to set new UUID
* normally true if loaded in the footprint editor, false
* if loaded in the board editor. Make sense only in kicad_plugin
* @return the footprint if found or NULL if not found.
* @throw IO_ERROR if the library cannot be found or read. No exception
* is thrown in the case where \a aNickname cannot be found.
*/
FOOTPRINT* LoadFootprint( const wxString& aNickname, const wxString& aName, bool aKeepUUID );
FOOTPRINT* LoadFootprint( const LIB_ID& aLibId, bool aKeepUUID )
{
return LoadFootprint( aLibId.GetLibNickname(), aLibId.GetLibItemName(), aKeepUUID );
}
/**
* Load a footprint having @a aFootprintId with possibly an empty nickname.
*
* @param aFootprintId the [nickname] and name of the design block to load.
* @param aKeepUUID = true to keep initial items UUID, false to set new UUID
* normally true if loaded in the footprint editor, false
* if loaded in the board editor
* used only in kicad_plugin
* @return the #FOOTPRINT if found caller owns it, else NULL if not found.
*
* @throw IO_ERROR if the library cannot be found or read. No exception is
* thrown in the case where \a aFootprintId cannot be found.
* @throw PARSE_ERROR if @a aFootprintId is not parsed OK.
*/
FOOTPRINT* LoadFootprintWithOptionalNickname( const LIB_ID& aFootprintId, bool aKeepUUID );
// TODO(JE) library tables - hoist out?
/**
* The set of return values from SaveSymbol() below.
*/
enum SAVE_T
{
SAVE_OK,
SAVE_SKIPPED,
};
/**
* Write @a aFootprint to an existing library given by @a aNickname.
*
* If a #FOOTPRINT by the same name already exists or there are any conflicting alias
* names, the new #FOOTPRINT will silently overwrite any existing aliases and/or part
* because libraries cannot have duplicate alias names. It is the responsibility of
* the caller to check the library for conflicts before saving.
*
* @param aNickname is a locator for the "library", it is a "name" in LIB_TABLE_ROW
* @param aFootprint is what to store in the library. The library owns the footprint after this
* call.
* @param aOverwrite when true means overwrite any existing symbol by the same name,
* else if false means skip the write and return SAVE_SKIPPED.
* @return SAVE_T - SAVE_OK or SAVE_SKIPPED. If error saving, then IO_ERROR is thrown.
* @throw IO_ERROR if there is a problem saving the footprint.
*/
SAVE_T SaveFootprint( const wxString& aNickname, const FOOTPRINT* aFootprint,
bool aOverwrite = true );
/**
* Deletes the @a aFootprintName from the library given by @a aNickname.
*
* @param aNickname is a locator for the "library", it is a "name" in LIB_TABLE_ROW.
* @param aFootprintName is the name of a footprint to delete from the specified library.
* @throw IO_ERROR if there is a problem finding the footprint or the library, or deleting it.
*/
void DeleteFootprint( const wxString& aNickname, const wxString& aFootprintName );
/**
* Return true if the library given by @a aNickname is writable.
*
* It is possible that some footprint libraries are read only because of where they are
* installed.
*
* @param aNickname is the library nickname in the footprint library table.
* @throw IO_ERROR if no library at @a aNickname exists.
*/
bool IsFootprintLibWritable( const wxString& aNickname );
std::optional<LIBRARY_ERROR> LibraryError( const wxString& aNickname ) const;
protected:
std::map<wxString, LIB_DATA>& globalLibs() override { return GlobalLibraries; }
std::map<wxString, LIB_DATA>& globalLibs() const override { return GlobalLibraries; }
std::mutex& globalLibsMutex() override { return GlobalLibraryMutex; }
LIBRARY_RESULT<IO_BASE*> createPlugin( const LIBRARY_TABLE_ROW* row ) override;
IO_BASE* plugin( const LIB_DATA* aRow ) override { return pcbplugin( aRow ); }
private:
/// Helper to cast the ABC plugin in the LIB_DATA* to a concrete plugin
static PCB_IO* pcbplugin( const LIB_DATA* aRow );
// The global libraries, potentially shared between multiple different open
// projects, each of which has their own instance of this adapter class
static std::map<wxString, LIB_DATA> GlobalLibraries;
static std::mutex GlobalLibraryMutex;
};
#endif //FOOTPRINT_LIBRARY_ADAPTER_H
+3 -3
View File
@@ -32,7 +32,7 @@
#include <dpi_scaling_common.h>
#include <eda_draw_frame.h>
#include <footprint_preview_panel.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <gal/graphics_abstraction_layer.h>
#include <kiway.h>
#include <math/box2.h>
@@ -172,11 +172,11 @@ bool FOOTPRINT_PREVIEW_PANEL::DisplayFootprint( const LIB_ID& aFPID )
GetView()->Clear();
FP_LIB_TABLE* fptbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
try
{
const FOOTPRINT* fp = fptbl->GetEnumeratedFootprint( aFPID.GetLibNickname(), aFPID.GetLibItemName() );
const FOOTPRINT* fp = adapter->LoadFootprint( aFPID.GetLibNickname(), aFPID.GetLibItemName(), false );
if( fp )
m_currentFootprint.reset( static_cast<FOOTPRINT*>( fp->Duplicate( IGNORE_PARENT_GROUP ) ) );
+1 -1
View File
@@ -25,7 +25,7 @@
#include "fp_tree_synchronizing_adapter.h"
#include <widgets/lib_tree.h>
#include <footprint_edit_frame.h>
#include <fp_lib_table.h>
FOOTPRINT_TREE_PANE::FOOTPRINT_TREE_PANE( FOOTPRINT_EDIT_FRAME* aParent )
: wxPanel( aParent ),
+10 -16
View File
@@ -32,7 +32,7 @@
#include <eda_pattern_match.h>
#include <footprint_info.h>
#include <footprint_viewer_frame.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <kiway.h>
#include <kiway_express.h>
#include <netlist_reader/pcb_netlist.h>
@@ -406,7 +406,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = Kiway().Prj().GetProjectFile();
std::vector<wxString> nicknames = PROJECT_PCB::PcbFootprintLibs( &Prj() )->GetLogicalLibs();
std::vector<wxString> nicknames = PROJECT_PCB::FootprintLibAdapter( &Prj() )->GetLibraryNames();
std::vector<wxString> pinnedMatches;
std::vector<wxString> otherMatches;
@@ -491,7 +491,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList()
wxString nickname = getCurNickname();
fp_info_list->ReadFootprintFiles( PROJECT_PCB::PcbFootprintLibs( &Prj() ), !nickname ? nullptr : &nickname );
fp_info_list->ReadFootprintFiles( PROJECT_PCB::FootprintLibAdapter( &Prj() ), !nickname ? nullptr : &nickname );
if( fp_info_list->GetErrorCount() )
{
@@ -909,7 +909,7 @@ void FOOTPRINT_VIEWER_FRAME::OnActivate( wxActivateEvent& event )
if( event.GetActive() )
{
// Ensure we have the right library list:
std::vector< wxString > libNicknames = PROJECT_PCB::PcbFootprintLibs( &Prj() )->GetLogicalLibs();
std::vector< wxString > libNicknames = PROJECT_PCB::FootprintLibAdapter( &Prj() )->GetLibraryNames();
bool stale = false;
if( libNicknames.size() != m_libList->GetCount() )
@@ -982,20 +982,14 @@ COLOR4D FOOTPRINT_VIEWER_FRAME::GetGridColor()
void FOOTPRINT_VIEWER_FRAME::UpdateTitle()
{
wxString title;
LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
if( !getCurNickname().IsEmpty() )
{
try
{
FP_LIB_TABLE* libtable = PROJECT_PCB::PcbFootprintLibs( &Prj() );
const LIB_TABLE_ROW* row = libtable->FindRow( getCurNickname() );
title = getCurNickname() + wxT( " \u2014 " ) + row->GetFullURI( true );
}
catch( ... )
{
if( std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, getCurNickname(), true ) )
title = getCurNickname() + wxT( " \u2014 " ) + *optUri;
else
title = _( "[no library selected]" );
}
}
else
{
@@ -1041,8 +1035,8 @@ void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( FPVIEWER_CONSTANTS aMode )
GetBoard()->DeleteAllFootprints();
GetBoard()->RemoveUnusedNets( nullptr );
FOOTPRINT* footprint = PROJECT_PCB::PcbFootprintLibs( &Prj() )->FootprintLoad( getCurNickname(),
getCurFootprintName() );
FOOTPRINT* footprint = PROJECT_PCB::FootprintLibAdapter( &Prj() )->LoadFootprint( getCurNickname(),
getCurFootprintName(), false );
if( footprint )
displayFootprint( footprint );
+8 -16
View File
@@ -25,7 +25,7 @@
#include <project/project_file.h>
#include <wx/tokenzr.h>
#include <string_utils.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <footprint_info.h>
#include <footprint_info_impl.h>
#include <generate_footprint_info.h>
@@ -33,17 +33,17 @@
#include "fp_tree_model_adapter.h"
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>
FP_TREE_MODEL_ADAPTER::Create( PCB_BASE_FRAME* aParent, LIB_TABLE* aLibs )
FP_TREE_MODEL_ADAPTER::Create( PCB_BASE_FRAME* aParent, FOOTPRINT_LIBRARY_ADAPTER* aLibs )
{
auto* adapter = new FP_TREE_MODEL_ADAPTER( aParent, aLibs );
return wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>( adapter );
}
FP_TREE_MODEL_ADAPTER::FP_TREE_MODEL_ADAPTER( PCB_BASE_FRAME* aParent, LIB_TABLE* aLibs ) :
FP_TREE_MODEL_ADAPTER::FP_TREE_MODEL_ADAPTER( PCB_BASE_FRAME* aParent, FOOTPRINT_LIBRARY_ADAPTER* aLibs ) :
LIB_TREE_MODEL_ADAPTER( aParent, wxT( "pinned_footprint_libs" ),
aParent->GetViewerSettingsBase()->m_LibTree ),
m_libs( (FP_LIB_TABLE*) aLibs )
m_libs( aLibs )
{}
@@ -52,23 +52,15 @@ void FP_TREE_MODEL_ADAPTER::AddLibraries( EDA_BASE_FRAME* aParent )
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = aParent->Prj().GetProjectFile();
for( const wxString& libName : m_libs->GetLogicalLibs() )
for( const wxString& libName : m_libs->GetLibraryNames() )
{
const FP_LIB_TABLE_ROW* library = nullptr;
try
{
library = m_libs->FindRow( libName, true );
}
catch( ... )
{
// Skip loading this library, if not exists/ not found
if( !m_libs->HasLibrary( libName, true ) )
continue;
}
bool pinned = alg::contains( cfg->m_Session.pinned_fp_libs, libName )
|| alg::contains( project.m_PinnedFootprintLibs, libName );
DoAddLibrary( libName, library->GetDescr(), getFootprints( libName ), pinned, true );
DoAddLibrary( libName, *m_libs->GetLibraryDescription( libName ), getFootprints( libName ), pinned, true );
}
m_tree.AssignIntrinsicRanks( m_shownColumns );
+4 -5
View File
@@ -25,8 +25,7 @@
#include <lib_tree_model_adapter.h>
#include <footprint_info.h>
class LIB_TABLE;
class FP_LIB_TABLE;
class FOOTPRINT_LIBRARY_ADAPTER;
class PCB_BASE_FRAME;
class FP_TREE_MODEL_ADAPTER : public LIB_TREE_MODEL_ADAPTER
@@ -38,7 +37,7 @@ public:
* @param aLibs library set from which parts will be loaded
*/
static wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> Create( PCB_BASE_FRAME* aParent,
LIB_TABLE* aLibs );
FOOTPRINT_LIBRARY_ADAPTER* aLibs );
void AddLibraries( EDA_BASE_FRAME* aParent );
@@ -48,14 +47,14 @@ protected:
/**
* Constructor; takes a set of libraries to be included in the search.
*/
FP_TREE_MODEL_ADAPTER( PCB_BASE_FRAME* aParent, LIB_TABLE* aLibs );
FP_TREE_MODEL_ADAPTER( PCB_BASE_FRAME* aParent, FOOTPRINT_LIBRARY_ADAPTER* aLibs );
std::vector<LIB_TREE_ITEM*> getFootprints( const wxString& aLibName );
PROJECT::LIB_TYPE_T getLibType() override { return PROJECT::LIB_TYPE_T::FOOTPRINT_LIB; }
protected:
FP_LIB_TABLE* m_libs;
FOOTPRINT_LIBRARY_ADAPTER* m_libs;
};
#endif // FP_TREE_MODEL_ADAPTER_H
+15 -24
View File
@@ -28,9 +28,10 @@
#include <fp_tree_synchronizing_adapter.h>
#include <footprint_edit_frame.h>
#include <footprint_preview_panel.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <footprint_info_impl.h>
#include <gal/graphics_abstraction_layer.h>
#include <project_pcb.h>
#include <string_utils.h>
#include <board.h>
#include <footprint.h>
@@ -40,7 +41,7 @@
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>
FP_TREE_SYNCHRONIZING_ADAPTER::Create( FOOTPRINT_EDIT_FRAME* aFrame, FP_LIB_TABLE* aLibs )
FP_TREE_SYNCHRONIZING_ADAPTER::Create( FOOTPRINT_EDIT_FRAME* aFrame, FOOTPRINT_LIBRARY_ADAPTER* aLibs )
{
auto* adapter = new FP_TREE_SYNCHRONIZING_ADAPTER( aFrame, aLibs );
return wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>( adapter );
@@ -48,7 +49,7 @@ FP_TREE_SYNCHRONIZING_ADAPTER::Create( FOOTPRINT_EDIT_FRAME* aFrame, FP_LIB_TABL
FP_TREE_SYNCHRONIZING_ADAPTER::FP_TREE_SYNCHRONIZING_ADAPTER( FOOTPRINT_EDIT_FRAME* aFrame,
FP_LIB_TABLE* aLibs ) :
FOOTPRINT_LIBRARY_ADAPTER* aLibs ) :
FP_TREE_MODEL_ADAPTER( aFrame, aLibs ),
m_frame( aFrame )
{
@@ -70,7 +71,7 @@ bool FP_TREE_SYNCHRONIZING_ADAPTER::IsContainer( const wxDataViewItem& aItem ) c
#define PROGRESS_INTERVAL_MILLIS 33 // 30 FPS refresh rate
void FP_TREE_SYNCHRONIZING_ADAPTER::Sync( FP_LIB_TABLE* aLibs )
void FP_TREE_SYNCHRONIZING_ADAPTER::Sync( FOOTPRINT_LIBRARY_ADAPTER* aLibs )
{
m_libs = aLibs;
@@ -84,7 +85,7 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::Sync( FP_LIB_TABLE* aLibs )
// Remove the library if it no longer exists or it exists in both the global and the
// project library but the project library entry is disabled.
if( !m_libs->HasLibrary( name, true )
|| m_libs->FindRow( name, true ) != m_libs->FindRow( name, false ) )
|| m_libs->HasLibrary( name, true ) != m_libs->HasLibrary( name, false ) )
{
it = deleteLibrary( it );
continue;
@@ -107,23 +108,19 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::Sync( FP_LIB_TABLE* aLibs )
PROJECT_FILE& project = m_frame->Prj().GetProjectFile();
size_t count = m_libMap.size();
for( const wxString& libName : m_libs->GetLogicalLibs() )
for( const wxString& libName : m_libs->GetLibraryNames() )
{
if( m_libMap.count( libName ) == 0 )
{
try
if( std::optional<wxString> optDesc = PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() )->
GetLibraryDescription( libName ) )
{
const FP_LIB_TABLE_ROW* library = m_libs->FindRow( libName, true );
bool pinned = alg::contains( cfg->m_Session.pinned_fp_libs, libName )
|| alg::contains( project.m_PinnedFootprintLibs, libName );
DoAddLibrary( libName, library->GetDescr(), getFootprints( libName ), pinned, true );
DoAddLibrary( libName, *optDesc, getFootprints( libName ), pinned, true );
m_libMap.insert( libName );
}
catch( ... )
{
// do nothing if libname is not found. Just skip it
}
}
}
@@ -134,7 +131,7 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::Sync( FP_LIB_TABLE* aLibs )
int FP_TREE_SYNCHRONIZING_ADAPTER::GetLibrariesCount() const
{
return GFootprintTable.GetCount();
return m_libs->GetLibraryNames().size();
}
@@ -241,16 +238,10 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewIte
}
else if( node->m_Type == LIB_TREE_NODE::TYPE::LIBRARY )
{
try
{
const FP_LIB_TABLE_ROW* lib =
GFootprintTable.FindRow( node->m_LibId.GetLibNickname() );
if( lib )
node->m_Desc = lib->GetDescr();
}
catch( IO_ERROR& )
if( std::optional<wxString> optDesc = PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() )->
GetLibraryDescription( node->m_LibId.GetLibNickname() ) )
{
node->m_Desc = *optDesc;
}
}
@@ -371,4 +362,4 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::ShutdownPreview( wxWindow* aParent )
preview->GetCanvas()->SetEvtHandlerEnabled( false );
preview->GetCanvas()->StopDrawing();
}
}
}
+3 -3
View File
@@ -34,11 +34,11 @@ class FP_TREE_SYNCHRONIZING_ADAPTER : public FP_TREE_MODEL_ADAPTER
{
public:
static wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> Create( FOOTPRINT_EDIT_FRAME* aFrame,
FP_LIB_TABLE* aLibs );
FOOTPRINT_LIBRARY_ADAPTER* aLibs );
bool IsContainer( const wxDataViewItem& aItem ) const override;
void Sync( FP_LIB_TABLE* aLibs );
void Sync( FOOTPRINT_LIBRARY_ADAPTER* aLibs );
int GetLibrariesCount() const override;
@@ -51,7 +51,7 @@ public:
void ShutdownPreview( wxWindow* aParent ) override;
protected:
FP_TREE_SYNCHRONIZING_ADAPTER( FOOTPRINT_EDIT_FRAME* aFrame, FP_LIB_TABLE* aLibs );
FP_TREE_SYNCHRONIZING_ADAPTER( FOOTPRINT_EDIT_FRAME* aFrame, FOOTPRINT_LIBRARY_ADAPTER* aLibs );
void updateLibrary( LIB_TREE_NODE_LIBRARY& aLibNode );
+11 -11
View File
@@ -19,9 +19,10 @@
*/
#include <generate_footprint_info.h>
#include <ki_exception.h>
#include <string_utils.h>
#include <footprint.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <wx/log.h>
@@ -102,9 +103,9 @@ std::optional<wxString> GetFootprintDocumentationURL( const FOOTPRINT& aFootprin
class FOOTPRINT_INFO_GENERATOR
{
public:
FOOTPRINT_INFO_GENERATOR( FP_LIB_TABLE* aFpLibTable, LIB_ID const& aLibId ) :
FOOTPRINT_INFO_GENERATOR( FOOTPRINT_LIBRARY_ADAPTER* aAdapter, LIB_ID const& aLibId ) :
m_html( DescriptionFormat ),
m_fp_lib_table( aFpLibTable ),
m_adapter( aAdapter ),
m_lib_id( aLibId ),
m_footprint( nullptr )
{ }
@@ -114,15 +115,14 @@ public:
*/
void GenerateHtml()
{
wxCHECK_RET( m_fp_lib_table, wxT( "Footprint library table pointer is not valid" ) );
wxCHECK_RET( m_adapter, wxT( "Footprint library table pointer is not valid" ) );
if( !m_lib_id.IsValid() )
return;
try
{
m_footprint = m_fp_lib_table->GetEnumeratedFootprint( m_lib_id.GetLibNickname(),
m_lib_id.GetLibItemName() );
m_footprint = m_adapter->LoadFootprint( m_lib_id, false );
}
catch( const IO_ERROR& ioe )
{
@@ -178,17 +178,17 @@ public:
}
private:
wxString m_html;
FP_LIB_TABLE* m_fp_lib_table;
LIB_ID const m_lib_id;
wxString m_html;
FOOTPRINT_LIBRARY_ADAPTER* m_adapter;
LIB_ID const m_lib_id;
const FOOTPRINT* m_footprint;
};
wxString GenerateFootprintInfo( FP_LIB_TABLE* aFpLibTable, LIB_ID const& aLibId )
wxString GenerateFootprintInfo( FOOTPRINT_LIBRARY_ADAPTER* aAdapter, LIB_ID const& aLibId )
{
FOOTPRINT_INFO_GENERATOR gen( aFpLibTable, aLibId );
FOOTPRINT_INFO_GENERATOR gen( aAdapter, aLibId );
gen.GenerateHtml();
return gen.GetHtml();
}
+3 -3
View File
@@ -24,15 +24,15 @@
#include <wx/string.h>
class FP_LIB_TABLE;
class FOOTPRINT_LIBRARY_ADAPTER;
class FOOTPRINT;
class LIB_ID;
/**
* Return an HTML page describing a #LIB_ID in a #FP_LIB_TABLE. This is suitable for inclusion
* Return an HTML page describing a #LIB_ID in a footprint library. This is suitable for inclusion
* in a wxHtmlWindow.
*/
wxString GenerateFootprintInfo( FP_LIB_TABLE* aFpLibTable, LIB_ID const& aLibId );
wxString GenerateFootprintInfo( FOOTPRINT_LIBRARY_ADAPTER* aAdapter, LIB_ID const& aLibId );
/**
* Get a URL to the documentation for a #LIB_ID in a #FP_LIB_TABLE. This is suitable for opening
+5 -8
View File
@@ -34,7 +34,7 @@ using namespace std::placeholders;
#include <footprint_edit_frame.h>
#include <footprint_chooser_frame.h>
#include <footprint_viewer_frame.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <pcb_io/pcb_io_mgr.h>
#include <string_utils.h>
#include <kiway.h>
@@ -240,10 +240,7 @@ FOOTPRINT* PCB_BASE_FRAME::LoadFootprint( const LIB_ID& aFootprintId )
FOOTPRINT* PCB_BASE_FRAME::loadFootprint( const LIB_ID& aFootprintId )
{
FP_LIB_TABLE* fptbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
wxCHECK_MSG( fptbl, nullptr, wxT( "Cannot look up LIB_ID in NULL FP_LIB_TABLE." ) );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
FOOTPRINT *footprint = nullptr;
// When loading a footprint from a library in the footprint editor
@@ -252,7 +249,7 @@ FOOTPRINT* PCB_BASE_FRAME::loadFootprint( const LIB_ID& aFootprintId )
try
{
footprint = fptbl->FootprintLoadWithOptionalNickname( aFootprintId, keepUUID );
footprint = adapter->LoadFootprintWithOptionalNickname( aFootprintId, keepUUID );
}
catch( const IO_ERROR& )
{
@@ -345,8 +342,8 @@ bool FOOTPRINT_EDIT_FRAME::SaveLibraryAs( const wxString& aLibraryPath )
try
{
IO_RELEASER<PCB_IO> cur( PCB_IO_MGR::PluginFind( curType ) );
IO_RELEASER<PCB_IO> dst( PCB_IO_MGR::PluginFind( dstType ) );
IO_RELEASER<PCB_IO> cur( PCB_IO_MGR::FindPlugin( curType ) );
IO_RELEASER<PCB_IO> dst( PCB_IO_MGR::FindPlugin( dstType ) );
if( !cur )
{
+2 -2
View File
@@ -35,7 +35,7 @@ using namespace std::placeholders;
#include <netlist_reader/netlist_reader.h>
#include <reporter.h>
#include <lib_id.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <board.h>
#include <footprint.h>
#include <spread_footprints.h>
@@ -169,7 +169,7 @@ void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER& aReporter )
FOOTPRINT* footprint = nullptr;
FOOTPRINT* fpOnBoard = nullptr;
if( aNetlist.IsEmpty() || PROJECT_PCB::PcbFootprintLibs( &Prj() )->IsEmpty() )
if( aNetlist.IsEmpty() || PROJECT_PCB::FootprintLibAdapter( &Prj() )->Rows().empty() )
return;
aNetlist.SortByFPID();
+3 -2
View File
@@ -28,6 +28,7 @@
#define BASE_EDIT_FRAME_H
#include <pcb_base_frame.h>
#include <libraries/library_table.h>
class APPEARANCE_CONTROLS;
class LAYER_PAIR_SETTINGS;
@@ -94,7 +95,7 @@ public:
* @return true if successfully added.
*/
bool AddLibrary( const wxString& aDialogTitle, const wxString& aLibName = wxEmptyString,
FP_LIB_TABLE* aTable = nullptr );
std::optional<LIBRARY_TABLE_SCOPE> aScope = std::nullopt );
/**
* Install the corresponding dialog editor for the given item.
@@ -261,7 +262,7 @@ protected:
* Create a new library in the given table. (The user will be consulted if the table is null.)
*/
wxString createNewLibrary( const wxString& aDialogTitle, const wxString& aLibName,
const wxString& aInitialPath, FP_LIB_TABLE* aTable );
const wxString& aInitialPath, std::optional<LIBRARY_TABLE_SCOPE> aScope = std::nullopt );
void handleActivateEvent( wxActivateEvent& aEvent ) override;
+8 -8
View File
@@ -42,7 +42,7 @@
#include <confirm.h>
#include <footprint.h>
#include <footprint_editor_settings.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <lset.h>
#include <kiface_base.h>
#include <pcb_painter.h>
@@ -1089,19 +1089,19 @@ void PCB_BASE_FRAME::setFPWatcher( FOOTPRINT* aFootprint )
}
wxString libfullname;
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
if( !aFootprint || !tbl )
if( !aFootprint || !adapter )
return;
try
{
const FP_LIB_TABLE_ROW* row = tbl->FindRow( aFootprint->GetFPID().GetLibNickname() );
std::optional<LIBRARY_TABLE_ROW*> row = adapter->GetRow( aFootprint->GetFPID().GetLibNickname() );
if( !row )
return;
libfullname = row->GetFullURI( true );
libfullname = LIBRARY_MANAGER::GetFullURI( *row, true );
}
catch( const std::exception& e )
{
@@ -1181,13 +1181,13 @@ void PCB_BASE_FRAME::OnFpChangeDebounceTimer( wxTimerEvent& aEvent )
m_watcherLastModified = lastModified;
FOOTPRINT* fp = GetBoard()->GetFirstFootprint();
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &Prj() );
// When loading a footprint from a library in the footprint editor
// the items UUIDs must be keep and not reinitialized
bool keepUUID = IsType( FRAME_FOOTPRINT_EDITOR );
if( !fp || !tbl )
if( !fp || !adapter )
return;
m_inFpChangeTimerEvent = true;
@@ -1201,7 +1201,7 @@ void PCB_BASE_FRAME::OnFpChangeDebounceTimer( wxTimerEvent& aEvent )
try
{
FOOTPRINT* newfp = tbl->FootprintLoad( nickname, fpname, keepUUID );
FOOTPRINT* newfp = adapter->LoadFootprint( nickname, fpname, keepUUID );
if( newfp )
{
+1 -1
View File
@@ -98,7 +98,7 @@ bool PCB_EDIT_FRAME::saveBoardAsFile( BOARD* aBoard, const wxString& aFileName,
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::KICAD_SEXP ) );
wxASSERT( pcbFileName.IsAbsolute() );
+2 -1
View File
@@ -29,7 +29,6 @@
#include <pcb_edit_frame.h>
#include <3d_viewer/eda_3d_viewer_frame.h>
#include <api/api_plugin_manager.h>
#include <fp_lib_table.h>
#include <geometry/geometry_utils.h>
#include <bitmaps.h>
#include <confirm.h>
@@ -136,6 +135,8 @@
#include <action_plugin.h>
#include <pcbnew_scripting_helpers.h>
#include <richio.h>
#include "../scripting/python_scripting.h"
#include <wx/filedlg.h>
+5 -5
View File
@@ -65,7 +65,7 @@
// plugins coexisting.
PCB_IO* PCB_IO_MGR::PluginFind( PCB_FILE_T aFileType )
PCB_IO* PCB_IO_MGR::FindPlugin( PCB_FILE_T aFileType )
{
// This implementation is subject to change, any magic is allowed here.
// The public IO_MGR API is the only pertinent public information.
@@ -160,7 +160,7 @@ BOARD* PCB_IO_MGR::Load( PCB_FILE_T aFileType, const wxString& aFileName, BOARD*
const std::map<std::string, UTF8>* aProperties, PROJECT* aProject,
PROGRESS_REPORTER* aProgressReporter )
{
IO_RELEASER<PCB_IO> pi( PluginFind( aFileType ) );
IO_RELEASER<PCB_IO> pi( FindPlugin( aFileType ) );
if( pi ) // test pi->plugin
{
@@ -175,7 +175,7 @@ BOARD* PCB_IO_MGR::Load( PCB_FILE_T aFileType, const wxString& aFileName, BOARD*
void PCB_IO_MGR::Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aBoard,
const std::map<std::string, UTF8>* aProperties )
{
IO_RELEASER<PCB_IO> pi( PluginFind( aFileType ) );
IO_RELEASER<PCB_IO> pi( FindPlugin( aFileType ) );
if( pi )
{
@@ -196,8 +196,8 @@ bool PCB_IO_MGR::ConvertLibrary( const std::map<std::string, UTF8>& aOldFileProp
if( oldFileType == PCB_IO_MGR::FILE_TYPE_NONE )
return false;
IO_RELEASER<PCB_IO> oldFilePI( PCB_IO_MGR::PluginFind( oldFileType ) );
IO_RELEASER<PCB_IO> kicadPI( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
IO_RELEASER<PCB_IO> oldFilePI( PCB_IO_MGR::FindPlugin( oldFileType ) );
IO_RELEASER<PCB_IO> kicadPI( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::KICAD_SEXP ) );
wxArrayString fpNames;
wxFileName newFileName( aNewFilePath );
+1 -1
View File
@@ -162,7 +162,7 @@ public:
* @param aFileType is from #PCB_FILE_T and tells which plugin to find.
* @return the plug in corresponding to \a aFileType or NULL if not found.
*/
static PCB_IO* PluginFind( PCB_FILE_T aFileType );
static PCB_IO* FindPlugin( PCB_FILE_T aFileType );
/**
* Return a brief name for a plugin given \a aFileType enum.
+10 -62
View File
@@ -39,7 +39,7 @@
#include <footprint_editor_settings.h>
#include <settings/settings_manager.h>
#include <settings/cvpcb_settings.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <footprint_edit_frame.h>
#include <footprint_viewer_frame.h>
#include <footprint_chooser_frame.h>
@@ -59,6 +59,7 @@
#include <panel_3D_display_options.h>
#include <panel_3D_opengl_options.h>
#include <panel_3D_raytracing_options.h>
#include <project_pcb.h>
#include <python_scripting.h>
#include "invoke_pcb_dialog.h"
@@ -362,13 +363,11 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
case KIFACE_FOOTPRINT_LIST:
return (void*) &GFootprintList;
// Return a new FP_LIB_TABLE with the global table installed as a fallback.
case KIFACE_NEW_FOOTPRINT_TABLE:
return (void*) new FP_LIB_TABLE( &GFootprintTable );
// Return a pointer to the global instance of the global footprint table.
case KIFACE_GLOBAL_FOOTPRINT_TABLE:
return (void*) &GFootprintTable;
case KIFACE_FOOTPRINT_LIBRARY_ADAPTER:
// This is the mechanism by which FOOTPRINT_SELECT_WIDGET can get access to the adapter
// without directly linking to pcbnew or pcbcommon, going through PROJECT::FootprintLibAdapter
// TODO this is kind of cursed and needs thought to support multi-project
return PROJECT_PCB::FootprintLibAdapter( &Pgm().GetSettingsManager().Prj() );
case KIFACE_SCRIPTING_LEGACY:
return reinterpret_cast<void*>( PyInit__pcbnew );
@@ -392,8 +391,6 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
bool HandleJobConfig( JOB* aJob, wxWindow* aParent ) override;
private:
bool loadGlobalLibTable();
std::unique_ptr<PCBNEW_JOBS_HANDLER> m_jobHandler;
} kiface( "pcbnew", KIWAY::FACE_PCB );
@@ -415,11 +412,6 @@ KIFACE_API KIFACE* KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BA
}
/// The global footprint library table. This is not dynamically allocated because
/// in a multiple project environment we must keep its address constant (since it is
/// the fallback table for multiple projects).
FP_LIB_TABLE GFootprintTable;
/// The global footprint info table. This is performance-intensive to build so we
/// keep a hash-stamped global version. Any deviation from the request vs. stored
/// hash will result in it being rebuilt.
@@ -449,17 +441,6 @@ bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits, KIWAY* aKiway )
start_common( aCtlBits );
if( !loadGlobalLibTable() )
{
// we didnt get anywhere deregister the settings
mgr.FlushAndRelease( GetAppSettings<CVPCB_SETTINGS>( "cvpcb" ), false );
mgr.FlushAndRelease( KifaceSettings(), false );
mgr.FlushAndRelease( GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" ), false );
mgr.FlushAndRelease( GetAppSettings<EDA_3D_VIEWER_SETTINGS>( "3d_viewer" ), false );
return false;
}
m_jobHandler = std::make_unique<PCBNEW_JOBS_HANDLER>( aKiway );
if( m_start_flags & KFCTL_CLI )
@@ -474,42 +455,6 @@ bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits, KIWAY* aKiway )
void IFACE::Reset()
{
loadGlobalLibTable();
}
bool IFACE::loadGlobalLibTable()
{
wxFileName fn = FP_LIB_TABLE::GetGlobalTableFileName();
if( !fn.FileExists() )
{
}
else
{
try
{
// The global table is not related to a specific project. All projects
// will use the same global table. So the KIFACE::OnKifaceStart() contract
// of avoiding anything project specific is not violated here.
if( !FP_LIB_TABLE::LoadGlobalTable( GFootprintTable ) )
return false;
}
catch( const IO_ERROR& ioe )
{
// if we are here, a incorrect global footprint library table was found.
// Incorrect global symbol library table is not a fatal error:
// the user just has to edit the (partially) loaded table.
wxString msg = _( "An error occurred attempting to load the global footprint library "
"table.\n"
"Please edit this global footprint library table in Preferences "
"menu." );
DisplayErrorMessage( nullptr, msg, ioe.What() );
}
}
return true;
}
@@ -571,6 +516,8 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aSrcPr
// name.
KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
}
// TODO(JE) library tables - does this feature even need to exist?
#if 0
else if( destFile.GetName() == FILEEXT::FootprintLibraryTableFileName )
{
try
@@ -602,6 +549,7 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aSrcPr
aErrors += msg;
}
}
#endif
else
{
wxFAIL_MSG( wxT( "Unexpected filetype for Pcbnew::SaveFileAs()" ) );
+2 -2
View File
@@ -2444,7 +2444,7 @@ int PCBNEW_JOBS_HANDLER::JobExportIpc2581( JOB* aJob )
wxString tempFile = wxFileName::CreateTempFileName( wxS( "pcbnew_ipc" ) );
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::IPC2581 ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::IPC2581 ) );
pi->SetProgressReporter( m_progressReporter );
pi->SaveBoard( tempFile, brd, &props );
}
@@ -2600,7 +2600,7 @@ int PCBNEW_JOBS_HANDLER::JobUpgrade( JOB* aJob )
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::KICAD_SEXP ) );
BOARD* brd = getBoard( job->m_filename );
if( brd->GetFileFormatVersionAtLoad() < SEXPR_BOARD_FILE_VERSION )
shouldSave = true;
+16 -32
View File
@@ -22,55 +22,39 @@
*/
#include "project_pcb.h"
#include <fp_lib_table.h>
#include <project.h>
#include <confirm.h>
#include <pgm_base.h>
#include <3d_cache/3d_cache.h>
#include <paths.h>
#include <settings/common_settings.h>
#include <footprint_library_adapter.h>
#include <mutex>
static std::mutex mutex3D_cacheManager;
std::mutex PROJECT_PCB::s_libAdapterMutex;
FP_LIB_TABLE* PROJECT_PCB::PcbFootprintLibs( PROJECT* aProject )
FOOTPRINT_LIBRARY_ADAPTER* PROJECT_PCB::FootprintLibAdapter( PROJECT* aProject )
{
// This is a lazy loading function, it loads the project specific table when
// that table is asked for, not before.
std::scoped_lock lock( s_libAdapterMutex );
FP_LIB_TABLE* tbl = (FP_LIB_TABLE*) aProject->GetElem( PROJECT::ELEM::FPTBL );
LIBRARY_MANAGER& mgr = Pgm().GetLibraryManager();
std::optional<LIBRARY_MANAGER_ADAPTER*> adapter = mgr.Adapter( LIBRARY_TABLE_TYPE::FOOTPRINT );
// its gotta be NULL or a FP_LIB_TABLE, or a bug.
wxASSERT( !tbl || tbl->ProjectElementType() == PROJECT::ELEM::FPTBL );
if( !tbl )
if( !adapter )
{
// Stack the project specific FP_LIB_TABLE overlay on top of the global table.
// ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may
// stack this way, all using the same global fallback table.
tbl = new FP_LIB_TABLE( &GFootprintTable );
mgr.RegisterAdapter( LIBRARY_TABLE_TYPE::FOOTPRINT,
std::make_unique<FOOTPRINT_LIBRARY_ADAPTER>( mgr ) );
aProject->SetElem( PROJECT::ELEM::FPTBL, tbl );
wxString projectFpLibTableFileName = aProject->FootprintLibTblName();
try
{
tbl->Load( projectFpLibTableFileName );
}
catch( const IO_ERROR& ioe )
{
DisplayErrorMessage( nullptr, _( "Error loading project footprint libraries." ),
ioe.What() );
}
catch( ... )
{
DisplayErrorMessage( nullptr, _( "Error loading project footprint library table." ) );
}
std::optional<LIBRARY_MANAGER_ADAPTER*> created = mgr.Adapter( LIBRARY_TABLE_TYPE::FOOTPRINT );
wxCHECK( created && ( *created )->Type() == LIBRARY_TABLE_TYPE::FOOTPRINT, nullptr );
return static_cast<FOOTPRINT_LIBRARY_ADAPTER*>( *created );
}
return tbl;
wxCHECK( ( *adapter )->Type() == LIBRARY_TABLE_TYPE::FOOTPRINT, nullptr );
return static_cast<FOOTPRINT_LIBRARY_ADAPTER*>( *adapter );
}
@@ -130,4 +114,4 @@ void PROJECT_PCB::Cleanup3DCache( PROJECT* aProject )
if( clearCacheInterval > 0 )
cache->CleanCacheDir( clearCacheInterval );
}
}
}
@@ -40,7 +40,7 @@
#include <drawing_sheet/ds_data_model.h>
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <core/ignore.h>
#include <pcb_io/pcb_io_mgr.h>
#include <string_utils.h>
@@ -333,7 +333,7 @@ bool SaveBoard( wxString& aFileName, BOARD* aBoard, bool aSkipSettings )
}
FP_LIB_TABLE* GetFootprintLibraryTable()
FOOTPRINT_LIBRARY_ADAPTER* getFootprintAdapter()
{
BOARD* board = GetBoard();
@@ -345,7 +345,7 @@ FP_LIB_TABLE* GetFootprintLibraryTable()
if( !project )
return nullptr;
return PROJECT_PCB::PcbFootprintLibs( project );
return PROJECT_PCB::FootprintLibAdapter( project );
}
@@ -353,12 +353,12 @@ wxArrayString GetFootprintLibraries()
{
wxArrayString footprintLibraryNames;
FP_LIB_TABLE* tbl = GetFootprintLibraryTable();
FOOTPRINT_LIBRARY_ADAPTER* adapter = getFootprintAdapter();
if( !tbl )
if( !adapter )
return footprintLibraryNames;
for( const wxString& name : tbl->GetLogicalLibs() )
for( const wxString& name : adapter->GetLibraryNames() )
footprintLibraryNames.Add( name );
return footprintLibraryNames;
@@ -369,12 +369,13 @@ wxArrayString GetFootprints( const wxString& aNickName )
{
wxArrayString footprintNames;
FP_LIB_TABLE* tbl = GetFootprintLibraryTable();
FOOTPRINT_LIBRARY_ADAPTER* adapter = getFootprintAdapter();
if( !tbl )
if( !adapter )
return footprintNames;
tbl->FootprintEnumerate( footprintNames, aNickName, true );
std::vector<wxString> names = adapter->GetFootprintNames( aNickName, true );
footprintNames.assign( names.begin(), names.end() );
return footprintNames;
}
@@ -555,12 +556,6 @@ bool WriteDRCReport( BOARD* aBoard, const wxString& aFileName, EDA_UNITS aUnits,
wxCHECK( prj, false );
// Load the global fp-lib-table otherwise we can't check the libs parity
wxFileName fn_flp = FP_LIB_TABLE::GetGlobalTableFileName();
if( fn_flp.FileExists() )
GFootprintTable.Load( fn_flp.GetFullPath() );
wxString drcRulesPath = prj->AbsolutePath( fn.GetFullName() );
// Rebuild The Instance of ENUM_MAP<PCB_LAYER_ID> (layer names list), because the DRC
+5 -14
View File
@@ -39,7 +39,7 @@
#include <kiplatform/ui.h>
#include <string_utils.h>
#include <tools/board_inspection_tool.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <pcb_shape.h>
#include <widgets/appearance_controls.h>
#include <widgets/wx_html_report_box.h>
@@ -1604,18 +1604,9 @@ void BOARD_INSPECTION_TOOL::DiffFootprint( FOOTPRINT* aFootprint, wxTopLevelWind
r->Report( "" );
PROJECT* project = aFootprint->GetBoard()->GetProject();
FP_LIB_TABLE* libTable = PROJECT_PCB::PcbFootprintLibs( project );
const LIB_TABLE_ROW* libTableRow = nullptr;
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( project );
try
{
libTableRow = libTable->FindRow( libName );
}
catch( const IO_ERROR& )
{
}
if( !libTableRow )
if( !adapter->HasLibrary( libName, false ) )
{
r->Report( _( "The library is not included in the current configuration." )
+ wxS( "&nbsp;&nbsp;&nbsp" )
@@ -1623,7 +1614,7 @@ void BOARD_INSPECTION_TOOL::DiffFootprint( FOOTPRINT* aFootprint, wxTopLevelWind
+ wxS( "</a>" ) );
}
else if( !libTable->HasLibrary( libName, true ) )
else if( !adapter->HasLibrary( libName, true ) )
{
r->Report( _( "The library is not enabled in the current configuration." )
+ wxS( "&nbsp;&nbsp;&nbsp" )
@@ -1637,7 +1628,7 @@ void BOARD_INSPECTION_TOOL::DiffFootprint( FOOTPRINT* aFootprint, wxTopLevelWind
try
{
libFootprint.reset( libTable->FootprintLoad( libName, fpName, true ) );
libFootprint.reset( adapter->LoadFootprint( libName, fpName, true ) );
}
catch( const IO_ERROR& )
{
+22 -45
View File
@@ -47,7 +47,7 @@
#include <pad.h>
#include <pcb_group.h>
#include <zone.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <dialogs/dialog_cleanup_graphics.h>
#include <dialogs/dialog_footprint_checker.h>
#include <footprint_wizard_frame.h>
@@ -181,9 +181,7 @@ void FOOTPRINT_EDITOR_CONTROL::tryToSaveFootprintInLibrary( FOOTPRINT& aFootp
}
else
{
FP_LIB_TABLE& libTable = *PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() );
if( !libTable.IsFootprintLibWritable( libraryName ) )
if( !PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() )->IsFootprintLibWritable( libraryName ) )
{
// If the library is not writeable, we'll give the user a
// footprint not in a library. But add a warning to let them know
@@ -332,11 +330,14 @@ int FOOTPRINT_EDITOR_CONTROL::SaveAs( const TOOL_EVENT& aEvent )
{
if( m_frame->GetTargetFPID().GetLibItemName().empty() )
{
LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
// Save Library As
const wxString& src_libNickname = m_frame->GetTargetFPID().GetLibNickname();
wxString src_libFullName = PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() )->GetFullURI( src_libNickname );
std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, src_libNickname, true );
wxCHECK( optUri, 0 );
if( m_frame->SaveLibraryAs( src_libFullName ) )
if( m_frame->SaveLibraryAs( *optUri ) )
m_frame->SyncLibraryTree( true );
}
else if( m_frame->GetTargetFPID() == m_frame->GetLoadedFPID() )
@@ -409,7 +410,7 @@ int FOOTPRINT_EDITOR_CONTROL::PasteFootprint( const TOOL_EVENT& aEvent )
wxString newLib = m_frame->GetLibTree()->GetSelectedLibId().GetLibNickname();
wxString newName = m_copiedFootprint->GetFPID().GetLibItemName();
while( PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() )->FootprintExists( newLib, newName ) )
while( PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() )->FootprintExists( newLib, newName ) )
newName += _( "_copy" );
m_copiedFootprint->SetFPID( LIB_ID( newLib, newName ) );
@@ -450,7 +451,7 @@ int FOOTPRINT_EDITOR_CONTROL::DuplicateFootprint( const TOOL_EVENT& aEvent )
int FOOTPRINT_EDITOR_CONTROL::RenameFootprint( const TOOL_EVENT& aEvent )
{
LIBRARY_EDITOR_CONTROL* libTool = m_toolMgr->GetTool<LIBRARY_EDITOR_CONTROL>();
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() );
FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( &m_frame->Prj() );
LIB_ID fpID = m_frame->GetLibTree()->GetSelectedLibId();
wxString libraryName = fpID.GetLibNickname();
@@ -470,7 +471,7 @@ int FOOTPRINT_EDITOR_CONTROL::RenameFootprint( const TOOL_EVENT& aEvent )
}
// If no change, accept it without prompting
if( oldName != newName && tbl->FootprintExists( libraryName, newName ) )
if( oldName != newName && adapter->FootprintExists( libraryName, newName ) )
{
msg = wxString::Format( _( "Footprint '%s' already exists in library '%s'." ),
newName, libraryName );
@@ -523,7 +524,7 @@ int FOOTPRINT_EDITOR_CONTROL::RenameFootprint( const TOOL_EVENT& aEvent )
m_frame->SaveFootprintInLibrary( footprint, libraryName );
PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() )->FootprintDelete( libraryName, oldName );
adapter->DeleteFootprint( libraryName, oldName );
}
catch( const IO_ERROR& ioe )
{
@@ -604,31 +605,19 @@ int FOOTPRINT_EDITOR_CONTROL::ExportFootprint( const TOOL_EVENT& aEvent )
int FOOTPRINT_EDITOR_CONTROL::OpenDirectory( const TOOL_EVENT& aEvent )
{
// No check for multi selection since the context menu option must be hidden in that case
FP_LIB_TABLE* globalTable = dynamic_cast<FP_LIB_TABLE*>( &GFootprintTable );
FP_LIB_TABLE* projectTable = PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() );
LIB_ID libId = m_frame->GetTargetFPID();
wxString libName = libId.GetLibNickname();
wxString libItemName = libId.GetLibItemName();
wxString path = wxEmptyString;
for( FP_LIB_TABLE* table : { globalTable, projectTable } )
{
if( !table )
break;
LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, libName, true );
try
{
path = table->FindRow( libName, true )->GetFullURI( true );
}
catch( IO_ERROR& )
{
// Do nothing: libName can be not found in globalTable if libName is in projectTable
}
if( !optUri )
return 0;
if( !path.IsEmpty() )
break;
}
path = *optUri;
wxString fileExt = wxEmptyString;
@@ -684,31 +673,19 @@ int FOOTPRINT_EDITOR_CONTROL::OpenWithTextEditor( const TOOL_EVENT& aEvent )
}
// No check for multi selection since the context menu option must be hidden in that case
FP_LIB_TABLE* globalTable = dynamic_cast<FP_LIB_TABLE*>( &GFootprintTable );
FP_LIB_TABLE* projectTable = PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() );
LIB_ID libId = m_frame->GetLibTree()->GetSelectedLibId();
LIBRARY_MANAGER& manager = Pgm().GetLibraryManager();
wxString libName = libId.GetLibNickname();
wxString libItemName = wxEmptyString;
for( FP_LIB_TABLE* table : { globalTable, projectTable } )
{
if( !table )
break;
std::optional<wxString> optUri = manager.GetFullURI( LIBRARY_TABLE_TYPE::FOOTPRINT, libName, true );
try
{
libItemName = table->FindRow( libName, true )->GetFullURI( true );
}
catch( IO_ERROR& )
{
// Do nothing: libName can be not found in globalTable if libName is in projectTable
}
if( !libItemName.IsEmpty() )
break;
}
if( !optUri )
return 0;
libItemName = *optUri;
libItemName << wxFileName::GetPathSeparator();
libItemName << libId.GetLibItemName();
libItemName << '.' + FILEEXT::KiCadFootprintFileExtension;
+5 -5
View File
@@ -175,7 +175,7 @@ int PCB_CONTROL::DdAddLibrary( const TOOL_EVENT& aEvent )
{
const wxString fn = *aEvent.Parameter<wxString*>();
static_cast<PCB_BASE_EDIT_FRAME*>( m_frame )->AddLibrary( _( "Add Footprint Library" ), fn,
PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() ) );
LIBRARY_TABLE_SCOPE::PROJECT );
return 0;
}
@@ -1336,7 +1336,7 @@ int PCB_CONTROL::AppendBoardFromFile( const TOOL_EVENT& aEvent )
return 1;
PCB_IO_MGR::PCB_FILE_T pluginType = PCB_IO_MGR::FindPluginTypeFromBoardPath( fileName, KICTL_KICAD_ONLY );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( pluginType ) );
if( !pi )
return 1;
@@ -1363,7 +1363,7 @@ int PCB_CONTROL::AppendDesignBlock( const TOOL_EVENT& aEvent )
return 1;
PCB_IO_MGR::PCB_FILE_T pluginType = PCB_IO_MGR::KICAD_SEXP;
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( pluginType ) );
if( !pi )
return 1;
@@ -1593,7 +1593,7 @@ int PCB_CONTROL::PlaceLinkedDesignBlock( const TOOL_EVENT& aEvent )
PCB_IO_MGR::PCB_FILE_T pluginType = PCB_IO_MGR::KICAD_SEXP;
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( pluginType ) );
if( !pi )
return 1;
@@ -2504,7 +2504,7 @@ int PCB_CONTROL::DdAppendBoard( const TOOL_EVENT& aEvent )
wxString filePath = fileName.GetFullPath();
PCB_IO_MGR::PCB_FILE_T pluginType = PCB_IO_MGR::FindPluginTypeFromBoardPath( filePath );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( pluginType ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( pluginType ) );
if( !pi )
return 1;
+4 -4
View File
@@ -35,7 +35,7 @@
#include <pcb_base_frame.h>
#include <pcbnew_settings.h>
#include <pgm_base.h>
#include <fp_lib_table.h>
#include <footprint_library_adapter.h>
#include <settings/settings_manager.h>
#include <widgets/lib_tree.h>
#include <widgets/footprint_preview_widget.h>
@@ -64,12 +64,12 @@ PANEL_FOOTPRINT_CHOOSER::PANEL_FOOTPRINT_CHOOSER( PCB_BASE_FRAME* aFrame, wxTopL
m_escapeHandler( std::move( aEscapeHandler ) )
{
m_CurrFootprint = nullptr;
FP_LIB_TABLE* fpTable = PROJECT_PCB::PcbFootprintLibs( &aFrame->Prj() );
FOOTPRINT_LIBRARY_ADAPTER* footprints = PROJECT_PCB::FootprintLibAdapter( &aFrame->Prj() );
// Load footprint files:
auto* progressReporter = new WX_PROGRESS_REPORTER( aParent, _( "Load Footprint Libraries" ), 1,
PR_CAN_ABORT );
GFootprintList.ReadFootprintFiles( fpTable, nullptr, progressReporter );
GFootprintList.ReadFootprintFiles( footprints, nullptr, progressReporter );
// Force immediate deletion of the WX_PROGRESS_REPORTER. Do not use Destroy(), or use
// Destroy() followed by wxSafeYield() because on Windows, APP_PROGRESS_DIALOG and
@@ -81,7 +81,7 @@ PANEL_FOOTPRINT_CHOOSER::PANEL_FOOTPRINT_CHOOSER( PCB_BASE_FRAME* aFrame, wxTopL
if( GFootprintList.GetErrorCount() )
GFootprintList.DisplayErrors( aParent );
m_adapter = FP_TREE_MODEL_ADAPTER::Create( aFrame, fpTable );
m_adapter = FP_TREE_MODEL_ADAPTER::Create( aFrame, footprints );
FP_TREE_MODEL_ADAPTER* adapter = static_cast<FP_TREE_MODEL_ADAPTER*>( m_adapter.get() );
std::vector<LIB_TREE_ITEM*> historyInfos;
@@ -181,7 +181,7 @@ void PCB_DESIGN_BLOCK_PREVIEW_WIDGET::DisplayDesignBlock( DESIGN_BLOCK* aDesignB
{
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::KICAD_SEXP ) );
WX_PROGRESS_REPORTER progressReporter( this, _( "Load PCB" ), 1, PR_CAN_ABORT );
pi->SetProgressReporter( &progressReporter );
-3
View File
@@ -29,7 +29,6 @@
#include <wx/snglinst.h>
#include <wx/app.h>
#include <board.h>
#include <fp_lib_table.h>
#include <footprint_viewer_frame.h>
#include <footprint.h>
#include <tools/pcb_actions.h>
@@ -41,8 +40,6 @@
struct PCB_SELECTION_FILTER_OPTIONS;
#include <preview_items/selection_area.h>
FP_LIB_TABLE GFootprintTable;
DIALOG_FIND::DIALOG_FIND( PCB_EDIT_FRAME* aParent ) :
DIALOG_FIND_BASE( aParent )
@@ -246,7 +246,7 @@ bool DRC_BASE_FIXTURE::SaveBoardToFile( BOARD* board, const wxString& filename )
{
try
{
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::FindPlugin( PCB_IO_MGR::KICAD_SEXP ) );
pi->SaveBoard( filename, board, nullptr );
return true;
}
+1 -1
View File
@@ -288,7 +288,7 @@ BOOST_DATA_TEST_CASE( CheckCanReadBoard, boost::unit_test::data::make( BoardPlug
{
BOOST_TEST_CONTEXT( entry.m_name )
{
auto plugin = IO_RELEASER<PCB_IO>( PCB_IO_MGR::PluginFind( entry.m_type ) );
auto plugin = IO_RELEASER<PCB_IO>( PCB_IO_MGR::FindPlugin( entry.m_type ) );
bool expectValidHeader = c.m_expected_type == entry.m_type;
BOOST_CHECK_EQUAL( plugin->CanReadBoard( dataPath ), expectValidHeader );