mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Thread-safety (potentially KICAD-VMX...)
... KICAD-6PV, KICAD-82, KICAD-R3A, and others.
This commit is contained in:
parent
8bb9c47f9b
commit
68d4940087
@ -37,6 +37,7 @@
|
||||
#include <utility>
|
||||
#include <wx/tokenzr.h>
|
||||
#include <kiface_base.h>
|
||||
#include <locale_io.h>
|
||||
|
||||
DESIGN_BLOCK_INFO* DESIGN_BLOCK_LIST::GetDesignBlockInfo( const wxString& aLibNickname,
|
||||
const wxString& aDesignBlockName )
|
||||
@ -95,6 +96,16 @@ bool DESIGN_BLOCK_INFO::InLibrary( const wxString& aLibrary ) const
|
||||
}
|
||||
|
||||
|
||||
void DESIGN_BLOCK_INFO::ensure_loaded()
|
||||
{
|
||||
// Lazy-loading. MUST NOT be called from multi-threaded environment.
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
if( !m_loaded )
|
||||
load();
|
||||
}
|
||||
|
||||
|
||||
bool operator<( const DESIGN_BLOCK_INFO& lhs, const DESIGN_BLOCK_INFO& rhs )
|
||||
{
|
||||
int retv = StrNumCmp( lhs.m_nickname, rhs.m_nickname, false );
|
||||
|
@ -106,11 +106,7 @@ public:
|
||||
friend bool operator<( const DESIGN_BLOCK_INFO& lhs, const DESIGN_BLOCK_INFO& rhs );
|
||||
|
||||
protected:
|
||||
void ensure_loaded()
|
||||
{
|
||||
if( !m_loaded )
|
||||
load();
|
||||
}
|
||||
void ensure_loaded();
|
||||
|
||||
/// lazily load stuff not filled in by constructor. This may throw IO_ERRORS.
|
||||
virtual void load(){};
|
||||
|
@ -41,8 +41,8 @@ void DESIGN_BLOCK_INFO_IMPL::load()
|
||||
|
||||
wxASSERT( dbtable );
|
||||
|
||||
std::unique_ptr<const DESIGN_BLOCK> design_block( dbtable->GetEnumeratedDesignBlock( m_nickname,
|
||||
m_dbname ) );
|
||||
std::unique_ptr<const DESIGN_BLOCK> design_block( dbtable->GetEnumeratedDesignBlock( m_nickname, m_dbname,
|
||||
true ) );
|
||||
|
||||
if( design_block )
|
||||
{
|
||||
@ -176,7 +176,7 @@ void DESIGN_BLOCK_LIST_IMPL::loadDesignBlocks()
|
||||
CatchErrors(
|
||||
[&]()
|
||||
{
|
||||
m_lib_table->DesignBlockEnumerate( dbnames, nickname, false );
|
||||
m_lib_table->DesignBlockEnumerate( dbnames, nickname, false, true );
|
||||
} );
|
||||
|
||||
for( wxString dbname : dbnames )
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#include <wx/dir.h>
|
||||
#include <wx/hash.h>
|
||||
#include <locale_io.h>
|
||||
|
||||
#define OPT_SEP '|' ///< options separator character
|
||||
|
||||
@ -332,13 +333,24 @@ long long DESIGN_BLOCK_LIB_TABLE::GenerateTimestamp( const wxString* aNickname )
|
||||
}
|
||||
|
||||
|
||||
void DESIGN_BLOCK_LIB_TABLE::DesignBlockEnumerate( wxArrayString& aDesignBlockNames,
|
||||
const wxString& aNickname, bool aBestEfforts )
|
||||
void DESIGN_BLOCK_LIB_TABLE::DesignBlockEnumerate( wxArrayString& aDesignBlockNames, const wxString& aNickname,
|
||||
bool aBestEfforts, bool aThreadSafe )
|
||||
{
|
||||
const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
|
||||
wxASSERT( row->plugin );
|
||||
row->plugin->DesignBlockEnumerate( aDesignBlockNames, row->GetFullURI( true ), aBestEfforts,
|
||||
row->GetProperties() );
|
||||
|
||||
if( !aThreadSafe )
|
||||
{
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
row->plugin->DesignBlockEnumerate( aDesignBlockNames, row->GetFullURI( true ), aBestEfforts,
|
||||
row->GetProperties() );
|
||||
}
|
||||
else
|
||||
{
|
||||
row->plugin->DesignBlockEnumerate( aDesignBlockNames, row->GetFullURI( true ), aBestEfforts,
|
||||
row->GetProperties() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -389,19 +401,34 @@ static void setLibNickname( DESIGN_BLOCK* aModule, const wxString& aNickname,
|
||||
|
||||
const DESIGN_BLOCK*
|
||||
DESIGN_BLOCK_LIB_TABLE::GetEnumeratedDesignBlock( const wxString& aNickname,
|
||||
const wxString& aDesignBlockName )
|
||||
const wxString& aDesignBlockName,
|
||||
bool aThreadSafe )
|
||||
{
|
||||
const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
|
||||
wxASSERT( row->plugin );
|
||||
|
||||
return row->plugin->GetEnumeratedDesignBlock( row->GetFullURI( true ), aDesignBlockName,
|
||||
row->GetProperties() );
|
||||
if( !aThreadSafe )
|
||||
{
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
return row->plugin->GetEnumeratedDesignBlock( row->GetFullURI( true ), aDesignBlockName,
|
||||
row->GetProperties() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return row->plugin->GetEnumeratedDesignBlock( row->GetFullURI( true ), aDesignBlockName,
|
||||
row->GetProperties() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DESIGN_BLOCK_LIB_TABLE::DesignBlockExists( const wxString& aNickname,
|
||||
const wxString& aDesignBlockName )
|
||||
{
|
||||
// NOT THREAD-SAFE! LOCALE_IO is global!
|
||||
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
try
|
||||
{
|
||||
const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
|
||||
@ -421,6 +448,10 @@ DESIGN_BLOCK* DESIGN_BLOCK_LIB_TABLE::DesignBlockLoad( const wxString& aNickname
|
||||
const wxString& aDesignBlockName,
|
||||
bool aKeepUUID )
|
||||
{
|
||||
// NOT THREAD-SAFE! LOCALE_IO is global!
|
||||
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
|
||||
wxASSERT( row->plugin );
|
||||
|
||||
@ -437,6 +468,10 @@ DESIGN_BLOCK_LIB_TABLE::SAVE_T
|
||||
DESIGN_BLOCK_LIB_TABLE::DesignBlockSave( const wxString& aNickname,
|
||||
const DESIGN_BLOCK* aDesignBlock, bool aOverwrite )
|
||||
{
|
||||
// NOT THREAD-SAFE! LOCALE_IO is global!
|
||||
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
|
||||
wxASSERT( row->plugin );
|
||||
|
||||
|
@ -141,7 +141,7 @@ wxString DESIGN_BLOCK_TREE_MODEL_ADAPTER::GenerateInfo( LIB_ID const& aLibId, in
|
||||
|
||||
try
|
||||
{
|
||||
db = m_libs->GetEnumeratedDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName() );
|
||||
db = m_libs->GetEnumeratedDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName(), false );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <utility>
|
||||
#include <wx/tokenzr.h>
|
||||
#include <kiface_base.h>
|
||||
#include <locale_io.h>
|
||||
|
||||
FOOTPRINT_INFO* FOOTPRINT_LIST::GetFootprintInfo( const wxString& aLibNickname,
|
||||
const wxString& aFootprintName )
|
||||
@ -97,6 +98,16 @@ bool FOOTPRINT_INFO::InLibrary( const wxString& aLibrary ) const
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT_INFO::ensure_loaded()
|
||||
{
|
||||
// Lazy-loading. MUST NOT be called from multi-threaded environment.
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
if( !m_loaded )
|
||||
load();
|
||||
}
|
||||
|
||||
|
||||
bool operator<( const FOOTPRINT_INFO& lhs, const FOOTPRINT_INFO& rhs )
|
||||
{
|
||||
int retv = StrNumCmp( lhs.m_nickname, rhs.m_nickname, false );
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include <wx/dir.h>
|
||||
#include <wx/hash.h>
|
||||
#include <locale_io.h>
|
||||
|
||||
#define OPT_SEP '|' ///< options separator character
|
||||
|
||||
@ -307,12 +308,23 @@ long long FP_LIB_TABLE::GenerateTimestamp( const wxString* aNickname )
|
||||
|
||||
|
||||
void FP_LIB_TABLE::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname,
|
||||
bool aBestEfforts )
|
||||
bool aBestEfforts, bool aThreadSafe )
|
||||
{
|
||||
const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
|
||||
wxASSERT( row->plugin );
|
||||
row->plugin->FootprintEnumerate( aFootprintNames, row->GetFullURI( true ), aBestEfforts,
|
||||
row->GetProperties() );
|
||||
|
||||
if( !aThreadSafe )
|
||||
{
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
row->plugin->FootprintEnumerate( aFootprintNames, row->GetFullURI( true ), aBestEfforts,
|
||||
row->GetProperties() );
|
||||
}
|
||||
else
|
||||
{
|
||||
row->plugin->FootprintEnumerate( aFootprintNames, row->GetFullURI( true ), aBestEfforts,
|
||||
row->GetProperties() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -362,18 +374,33 @@ static void setLibNickname( FOOTPRINT* aModule, const wxString& aNickname,
|
||||
|
||||
|
||||
const FOOTPRINT* FP_LIB_TABLE::GetEnumeratedFootprint( const wxString& aNickname,
|
||||
const wxString& aFootprintName )
|
||||
const wxString& aFootprintName,
|
||||
bool aThreadSafe )
|
||||
{
|
||||
const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
|
||||
wxASSERT( row->plugin );
|
||||
|
||||
return row->plugin->GetEnumeratedFootprint( row->GetFullURI( true ), aFootprintName,
|
||||
row->GetProperties() );
|
||||
if( !aThreadSafe )
|
||||
{
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
return row->plugin->GetEnumeratedFootprint( row->GetFullURI( true ), aFootprintName,
|
||||
row->GetProperties() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return row->plugin->GetEnumeratedFootprint( row->GetFullURI( true ), aFootprintName,
|
||||
row->GetProperties() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FP_LIB_TABLE::FootprintExists( const wxString& aNickname, const wxString& aFootprintName )
|
||||
{
|
||||
// NOT THREAD-SAFE! LOCALE_IO is global!
|
||||
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
try
|
||||
{
|
||||
const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
|
||||
@ -392,6 +419,10 @@ bool FP_LIB_TABLE::FootprintExists( const wxString& aNickname, const wxString& a
|
||||
FOOTPRINT* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname,
|
||||
const wxString& aFootprintName, bool aKeepUUID )
|
||||
{
|
||||
// NOT THREAD-SAFE! LOCALE_IO is global!
|
||||
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
|
||||
wxASSERT( row->plugin );
|
||||
|
||||
@ -407,6 +438,10 @@ FOOTPRINT* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname,
|
||||
FP_LIB_TABLE::SAVE_T FP_LIB_TABLE::FootprintSave( const wxString& aNickname,
|
||||
const FOOTPRINT* aFootprint, bool aOverwrite )
|
||||
{
|
||||
// NOT THREAD-SAFE! LOCALE_IO is global!
|
||||
|
||||
LOCALE_IO toggle_locale;
|
||||
|
||||
const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
|
||||
wxASSERT( row->plugin );
|
||||
|
||||
|
@ -304,7 +304,7 @@ FOOTPRINT* DISPLAY_FOOTPRINTS_FRAME::GetFootprint( const wxString& aFootprintNam
|
||||
|
||||
try
|
||||
{
|
||||
if( const FOOTPRINT* fp = fpTable->GetEnumeratedFootprint( libNickname, fpName ) )
|
||||
if( const FOOTPRINT* fp = fpTable->GetEnumeratedFootprint( libNickname, fpName, false ) )
|
||||
footprint = static_cast<FOOTPRINT*>( fp->Duplicate( IGNORE_PARENT_GROUP ) );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
|
@ -58,7 +58,7 @@ static int guessNickname( FP_LIB_TABLE* aTbl, LIB_ID* aFootprintId )
|
||||
{
|
||||
wxArrayString fpnames;
|
||||
|
||||
aTbl->FootprintEnumerate( fpnames, nicks[libNdx], true );
|
||||
aTbl->FootprintEnumerate( fpnames, nicks[libNdx], true, false );
|
||||
|
||||
for( unsigned nameNdx = 0; nameNdx < fpnames.size(); ++nameNdx )
|
||||
{
|
||||
|
@ -48,19 +48,13 @@ static const wxString LinkFormat = wxS( "<a href=\"__HREF__\">__TEXT__</a>" );
|
||||
|
||||
class FOOTPRINT_INFO_GENERATOR
|
||||
{
|
||||
wxString m_html;
|
||||
SYMBOL_LIB_TABLE* m_sym_lib_table;
|
||||
LIB_ID const m_lib_id;
|
||||
LIB_SYMBOL* m_symbol;
|
||||
int m_unit;
|
||||
|
||||
public:
|
||||
FOOTPRINT_INFO_GENERATOR( SYMBOL_LIB_TABLE* aSymbolLibTable, LIB_ID const& aLibId, int aUnit )
|
||||
: m_html( DescriptionFormat ),
|
||||
m_sym_lib_table( aSymbolLibTable ),
|
||||
m_lib_id( aLibId ),
|
||||
m_symbol( nullptr ),
|
||||
m_unit( aUnit )
|
||||
FOOTPRINT_INFO_GENERATOR( SYMBOL_LIB_TABLE* aSymbolLibTable, LIB_ID const& aLibId, int aUnit ) :
|
||||
m_html( DescriptionFormat ),
|
||||
m_sym_lib_table( aSymbolLibTable ),
|
||||
m_lib_id( aLibId ),
|
||||
m_symbol( nullptr ),
|
||||
m_unit( aUnit )
|
||||
{ }
|
||||
|
||||
/**
|
||||
@ -110,7 +104,6 @@ protected:
|
||||
m_html.Replace( wxS( "__NAME__" ), EscapeHTML( UnescapeString( m_symbol->GetName() ) ) );
|
||||
}
|
||||
|
||||
|
||||
void SetHtmlAliasOf()
|
||||
{
|
||||
if( m_symbol->IsRoot() )
|
||||
@ -130,14 +123,12 @@ protected:
|
||||
root_desc = parent->GetDesc();
|
||||
}
|
||||
|
||||
m_html.Replace( wxS( "__ALIASOF__" ),
|
||||
wxString::Format( AliasOfFormat,
|
||||
EscapeHTML( UnescapeString( root_name ) ),
|
||||
EscapeHTML( root_desc ) ) );
|
||||
m_html.Replace( wxS( "__ALIASOF__" ), wxString::Format( AliasOfFormat,
|
||||
EscapeHTML( UnescapeString( root_name ) ),
|
||||
EscapeHTML( root_desc ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SetHtmlDesc()
|
||||
{
|
||||
wxString esc_desc = EscapeHTML( UnescapeString( m_symbol->GetDescription() ) );
|
||||
@ -151,7 +142,6 @@ protected:
|
||||
m_html.Replace( wxS( "__DESC__" ), wxString::Format( DescFormat, esc_desc ) );
|
||||
}
|
||||
|
||||
|
||||
void SetHtmlKeywords()
|
||||
{
|
||||
wxString keywords = m_symbol->GetKeyWords();
|
||||
@ -159,11 +149,9 @@ protected:
|
||||
if( keywords.empty() )
|
||||
m_html.Replace( wxS( "__KEY__" ), wxEmptyString );
|
||||
else
|
||||
m_html.Replace( wxS( "__KEY__" ),
|
||||
wxString::Format( KeywordsFormat, EscapeHTML( keywords ) ) );
|
||||
m_html.Replace( wxS( "__KEY__" ), wxString::Format( KeywordsFormat, EscapeHTML( keywords ) ) );
|
||||
}
|
||||
|
||||
|
||||
wxString GetHtmlFieldRow( const SCH_FIELD& aField ) const
|
||||
{
|
||||
wxString name = aField.GetCanonicalName();
|
||||
@ -263,6 +251,13 @@ protected:
|
||||
|
||||
m_html.Replace( wxS( "__FIELDS__" ), fieldtable );
|
||||
}
|
||||
|
||||
private:
|
||||
wxString m_html;
|
||||
SYMBOL_LIB_TABLE* m_sym_lib_table;
|
||||
LIB_ID const m_lib_id;
|
||||
LIB_SYMBOL* m_symbol;
|
||||
int m_unit;
|
||||
};
|
||||
|
||||
|
||||
|
@ -158,11 +158,13 @@ public:
|
||||
* \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.
|
||||
* @param aThreadSafe if true, do not set LOCALE_IO (which is global). Caller is responsible
|
||||
* for setting it up correctly.
|
||||
*
|
||||
* @throw IO_ERROR if the library cannot be found, or design block cannot be loaded.
|
||||
*/
|
||||
void DesignBlockEnumerate( wxArrayString& aDesignBlockNames, const wxString& aNickname,
|
||||
bool aBestEfforts );
|
||||
bool aBestEfforts, bool aThreadSafe );
|
||||
|
||||
/**
|
||||
* Generate a hashed timestamp representing the last-mod-times of the library indicated
|
||||
@ -195,10 +197,13 @@ public:
|
||||
* A version of #DesignBlockLoad() for use after #DesignBlockEnumerate() for more efficient
|
||||
* cache management.
|
||||
*
|
||||
* @param aThreadSafe if true, do not set LOCALE_IO (which is global). Caller is responsible
|
||||
* for setting it up correctly.
|
||||
*
|
||||
* The return value is const to allow it to return a reference to a cached item.
|
||||
*/
|
||||
const DESIGN_BLOCK* GetEnumeratedDesignBlock( const wxString& aNickname,
|
||||
const wxString& aDesignBlockName );
|
||||
const DESIGN_BLOCK* GetEnumeratedDesignBlock( const wxString& aNickname, const wxString& aDesignBlockName,
|
||||
bool aThreadSafe );
|
||||
/**
|
||||
* The set of return values from DesignBlockSave() below.
|
||||
*/
|
||||
|
@ -127,11 +127,7 @@ public:
|
||||
friend bool operator<( const FOOTPRINT_INFO& lhs, const FOOTPRINT_INFO& rhs );
|
||||
|
||||
protected:
|
||||
void ensure_loaded()
|
||||
{
|
||||
if( !m_loaded )
|
||||
load();
|
||||
}
|
||||
void ensure_loaded();
|
||||
|
||||
/// lazily load stuff not filled in by constructor. This may throw IO_ERRORS.
|
||||
virtual void load() { };
|
||||
|
@ -143,11 +143,13 @@ public:
|
||||
* @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.
|
||||
* @param aThreadSafe if true, do not set LOCALE_IO (which is global). Caller is responsible
|
||||
* for setting it up correctly.
|
||||
*
|
||||
* @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded.
|
||||
*/
|
||||
void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname,
|
||||
bool aBestEfforts );
|
||||
bool aBestEfforts, bool aThreadSafe );
|
||||
|
||||
/**
|
||||
* Generate a hashed timestamp representing the last-mod-times of the library indicated
|
||||
@ -180,10 +182,14 @@ public:
|
||||
* A version of #FootprintLoad() for use after #FootprintEnumerate() for more efficient
|
||||
* cache management.
|
||||
*
|
||||
* @param aThreadSafe if true, do not set LOCALE_IO (which is global). Caller is responsible
|
||||
* for setting it up correctly.
|
||||
*
|
||||
* 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 );
|
||||
const wxString& aFootprintName,
|
||||
bool aThreadSafe );
|
||||
/**
|
||||
* The set of return values from FootprintSave() below.
|
||||
*/
|
||||
|
@ -75,7 +75,7 @@
|
||||
#include <widgets/filedlg_import_non_kicad.h>
|
||||
#include <widgets/wx_html_report_box.h>
|
||||
#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
|
||||
|
||||
#include <locale_io.h>
|
||||
#include <kiplatform/io.h>
|
||||
|
||||
#include <wx/stdpaths.h>
|
||||
@ -840,6 +840,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 )
|
||||
{
|
||||
LOCALE_IO toggle_locale;
|
||||
IO_RELEASER<PCB_IO> piSexpr( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
|
||||
|
||||
for( FOOTPRINT* footprint : loadedFootprints )
|
||||
|
@ -47,7 +47,7 @@ void FOOTPRINT_INFO_IMPL::load()
|
||||
|
||||
wxASSERT( fptable );
|
||||
|
||||
const FOOTPRINT* footprint = fptable->GetEnumeratedFootprint( m_nickname, m_fpname );
|
||||
const FOOTPRINT* footprint = fptable->GetEnumeratedFootprint( m_nickname, m_fpname, true );
|
||||
|
||||
if( footprint == nullptr ) // Should happen only with malformed/broken libraries
|
||||
{
|
||||
@ -192,7 +192,7 @@ void FOOTPRINT_LIST_IMPL::loadFootprints()
|
||||
CatchErrors(
|
||||
[&]()
|
||||
{
|
||||
m_lib_table->FootprintEnumerate( fpnames, nickname, false );
|
||||
m_lib_table->FootprintEnumerate( fpnames, nickname, false, true );
|
||||
} );
|
||||
|
||||
for( wxString fpname : fpnames )
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include <footprint_editor_settings.h>
|
||||
#include <footprint_viewer_frame.h>
|
||||
#include <io/kicad/kicad_io_utils.h>
|
||||
#include <locale_io.h>
|
||||
#include <view/view_controls.h>
|
||||
#include <wx/choicdlg.h>
|
||||
#include <wx/filedlg.h>
|
||||
@ -691,6 +692,7 @@ void PCB_EDIT_FRAME::ExportFootprintsToLibrary( bool aStoreInNewLib, const wxStr
|
||||
libNickname = row->GetNickName();
|
||||
}
|
||||
|
||||
LOCALE_IO toggle_locale;
|
||||
PCB_IO_MGR::PCB_FILE_T piType = PCB_IO_MGR::KICAD_SEXP;
|
||||
IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( piType ) );
|
||||
std::map<std::string, UTF8> options { { "skip_cache_validation", "1" } }; // Skip cache validation -- we just created it
|
||||
@ -1265,7 +1267,7 @@ FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( wxString aFootprintName, const wx
|
||||
// Try to infer the footprint attributes from an existing footprint in the library
|
||||
try
|
||||
{
|
||||
tbl->FootprintEnumerate( fpnames, aLibName, true );
|
||||
tbl->FootprintEnumerate( fpnames, aLibName, true, false );
|
||||
|
||||
if( !fpnames.empty() )
|
||||
footprintAttrs = tbl->FootprintLoad( aLibName, fpnames.Last() )->GetAttributes();
|
||||
|
@ -177,8 +177,8 @@ bool FOOTPRINT_PREVIEW_PANEL::DisplayFootprint( const LIB_ID& aFPID )
|
||||
|
||||
try
|
||||
{
|
||||
const FOOTPRINT* fp = fptbl->GetEnumeratedFootprint( aFPID.GetLibNickname(),
|
||||
aFPID.GetLibItemName() );
|
||||
const FOOTPRINT* fp = fptbl->GetEnumeratedFootprint( aFPID.GetLibNickname(), aFPID.GetLibItemName(),
|
||||
false );
|
||||
|
||||
if( fp )
|
||||
m_currentFootprint.reset( static_cast<FOOTPRINT*>( fp->Duplicate( IGNORE_PARENT_GROUP ) ) );
|
||||
|
@ -1033,7 +1033,7 @@ void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( FPVIEWER_CONSTANTS aMode )
|
||||
GetBoard()->RemoveUnusedNets( nullptr );
|
||||
|
||||
FOOTPRINT* footprint = PROJECT_PCB::PcbFootprintLibs( &Prj() )->FootprintLoad( getCurNickname(),
|
||||
getCurFootprintName() );
|
||||
getCurFootprintName() );
|
||||
|
||||
if( footprint )
|
||||
displayFootprint( footprint );
|
||||
|
@ -101,18 +101,12 @@ std::optional<wxString> GetFootprintDocumentationURL( const FOOTPRINT& aFootprin
|
||||
|
||||
class FOOTPRINT_INFO_GENERATOR
|
||||
{
|
||||
wxString m_html;
|
||||
FP_LIB_TABLE* m_fp_lib_table;
|
||||
LIB_ID const m_lib_id;
|
||||
|
||||
const FOOTPRINT* m_footprint;
|
||||
|
||||
public:
|
||||
FOOTPRINT_INFO_GENERATOR( FP_LIB_TABLE* aFpLibTable, LIB_ID const& aLibId )
|
||||
: m_html( DescriptionFormat ),
|
||||
m_fp_lib_table( aFpLibTable ),
|
||||
m_lib_id( aLibId ),
|
||||
m_footprint( nullptr )
|
||||
FOOTPRINT_INFO_GENERATOR( FP_LIB_TABLE* aFpLibTable, LIB_ID const& aLibId ) :
|
||||
m_html( DescriptionFormat ),
|
||||
m_fp_lib_table( aFpLibTable ),
|
||||
m_lib_id( aLibId ),
|
||||
m_footprint( nullptr )
|
||||
{ }
|
||||
|
||||
/**
|
||||
@ -128,7 +122,8 @@ public:
|
||||
try
|
||||
{
|
||||
m_footprint = m_fp_lib_table->GetEnumeratedFootprint( m_lib_id.GetLibNickname(),
|
||||
m_lib_id.GetLibItemName() );
|
||||
m_lib_id.GetLibItemName(),
|
||||
false );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
@ -183,6 +178,12 @@ public:
|
||||
return m_html;
|
||||
}
|
||||
|
||||
private:
|
||||
wxString m_html;
|
||||
FP_LIB_TABLE* m_fp_lib_table;
|
||||
LIB_ID const m_lib_id;
|
||||
|
||||
const FOOTPRINT* m_footprint;
|
||||
};
|
||||
|
||||
|
||||
|
@ -49,6 +49,7 @@ using namespace std::placeholders;
|
||||
#include <widgets/wx_progress_reporters.h>
|
||||
#include <dialog_pad_properties.h>
|
||||
#include <project_pcb.h>
|
||||
#include <locale_io.h>
|
||||
|
||||
|
||||
static wxArrayString s_FootprintHistoryList;
|
||||
@ -334,6 +335,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveLibraryAs( const wxString& aLibraryPath )
|
||||
wxBusyCursor dummy;
|
||||
wxString msg;
|
||||
|
||||
LOCALE_IO toggle_locale;
|
||||
PCB_IO_MGR::PCB_FILE_T dstType = PCB_IO_MGR::GuessPluginTypeFromLibPath( dstLibPath );
|
||||
PCB_IO_MGR::PCB_FILE_T curType = PCB_IO_MGR::GuessPluginTypeFromLibPath( curLibPath );
|
||||
|
||||
@ -363,12 +365,12 @@ bool FOOTPRINT_EDIT_FRAME::SaveLibraryAs( const wxString& aLibraryPath )
|
||||
|
||||
cur->FootprintEnumerate( footprints, curLibPath, false );
|
||||
|
||||
for( unsigned i = 0; i < footprints.size(); ++i )
|
||||
for( const wxString& fp : footprints )
|
||||
{
|
||||
const FOOTPRINT* footprint = cur->GetEnumeratedFootprint( curLibPath, footprints[i] );
|
||||
const FOOTPRINT* footprint = cur->GetEnumeratedFootprint( curLibPath, fp );
|
||||
dst->FootprintSave( dstLibPath, footprint );
|
||||
|
||||
msg = wxString::Format( _( "Footprint '%s' saved." ), footprints[i] );
|
||||
msg = wxString::Format( _( "Footprint '%s' saved." ), fp );
|
||||
SetStatusText( msg );
|
||||
}
|
||||
}
|
||||
|
@ -355,9 +355,7 @@ void PCB_IO_EASYEDA::FootprintEnumerate( wxArrayString& aFootprintNames,
|
||||
c_para = doc.head.c_para;
|
||||
|
||||
if( c_para )
|
||||
{
|
||||
packageName = get_def( *c_para, wxS( "package" ), packageName );
|
||||
}
|
||||
|
||||
aFootprintNames.Add( packageName );
|
||||
}
|
||||
@ -457,9 +455,8 @@ FOOTPRINT* PCB_IO_EASYEDA::FootprintLoad( const wxString& aLibraryPath,
|
||||
{
|
||||
parts.RemoveAt( 0 );
|
||||
|
||||
FOOTPRINT* footprint =
|
||||
parser.ParseFootprint( origin, orientation, layer, nullptr,
|
||||
paramMap, m_loadedFootprints, parts );
|
||||
FOOTPRINT* footprint = parser.ParseFootprint( origin, orientation, layer, nullptr,
|
||||
paramMap, m_loadedFootprints, parts );
|
||||
|
||||
if( !footprint )
|
||||
return nullptr;
|
||||
@ -502,8 +499,8 @@ FOOTPRINT* PCB_IO_EASYEDA::FootprintLoad( const wxString& aLibraryPath,
|
||||
|
||||
VECTOR2D origin( doc.head.x, doc.head.y );
|
||||
|
||||
FOOTPRINT* footprint = parser.ParseFootprint(
|
||||
origin, ANGLE_0, F_Cu, nullptr, *c_para, m_loadedFootprints, doc.shape );
|
||||
FOOTPRINT* footprint = parser.ParseFootprint( origin, ANGLE_0, F_Cu, nullptr, *c_para,
|
||||
m_loadedFootprints, doc.shape );
|
||||
|
||||
if( !footprint )
|
||||
return nullptr;
|
||||
|
@ -860,7 +860,6 @@ FOOTPRINT* PCB_IO_GEDA::ImportFootprint( const wxString& aFootprintPath,
|
||||
void PCB_IO_GEDA::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath,
|
||||
bool aBestEfforts, const std::map<std::string, UTF8>* aProperties )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
wxDir dir( aLibraryPath );
|
||||
wxString errorMsg;
|
||||
|
||||
@ -869,10 +868,7 @@ void PCB_IO_GEDA::FootprintEnumerate( wxArrayString& aFootprintNames, const wxSt
|
||||
if( aBestEfforts )
|
||||
return;
|
||||
else
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Footprint library '%s' not found." ),
|
||||
aLibraryPath ) );
|
||||
}
|
||||
THROW_IO_ERROR( wxString::Format( _( "Footprint library '%s' not found." ), aLibraryPath ) );
|
||||
}
|
||||
|
||||
init( aProperties );
|
||||
@ -902,8 +898,6 @@ const FOOTPRINT* PCB_IO_GEDA::getFootprint( const wxString& aLibraryPath,
|
||||
const std::map<std::string, UTF8>* aProperties,
|
||||
bool checkModified )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
init( aProperties );
|
||||
|
||||
validateCache( aLibraryPath, checkModified );
|
||||
|
@ -3210,7 +3210,6 @@ void PCB_IO_KICAD_LEGACY::cacheLib( const wxString& aLibraryPath )
|
||||
void PCB_IO_KICAD_LEGACY::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibPath,
|
||||
bool aBestEfforts, const std::map<std::string, UTF8>* aProperties )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
wxString errorMsg;
|
||||
|
||||
init( aProperties );
|
||||
@ -3236,22 +3235,18 @@ void PCB_IO_KICAD_LEGACY::FootprintEnumerate( wxArrayString& aFootprintNames, co
|
||||
|
||||
|
||||
FOOTPRINT* PCB_IO_KICAD_LEGACY::FootprintLoad( const wxString& aLibraryPath,
|
||||
const wxString& aFootprintName, bool aKeepUUID,
|
||||
const std::map<std::string, UTF8>* aProperties )
|
||||
const wxString& aFootprintName, bool aKeepUUID,
|
||||
const std::map<std::string, UTF8>* aProperties )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
init( aProperties );
|
||||
|
||||
cacheLib( aLibraryPath );
|
||||
|
||||
const FOOTPRINT_MAP& footprints = m_cache->m_footprints;
|
||||
const FOOTPRINT_MAP& footprints = m_cache->m_footprints;
|
||||
FOOTPRINT_MAP::const_iterator it = footprints.find( TO_UTF8( aFootprintName ) );
|
||||
|
||||
if( it == footprints.end() )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Return copy of already loaded FOOTPRINT
|
||||
FOOTPRINT* copy = (FOOTPRINT*) it->second->Duplicate( IGNORE_PARENT_GROUP );
|
||||
|
@ -2888,7 +2888,6 @@ void PCB_IO_KICAD_SEXPR::FootprintEnumerate( wxArrayString& aFootprintNames,
|
||||
const wxString& aLibPath, bool aBestEfforts,
|
||||
const std::map<std::string, UTF8>* aProperties )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
wxDir dir( aLibPath );
|
||||
wxString errorMsg;
|
||||
|
||||
@ -2919,8 +2918,6 @@ const FOOTPRINT* PCB_IO_KICAD_SEXPR::getFootprint( const wxString& aLibraryPath,
|
||||
const std::map<std::string, UTF8>* aProperties,
|
||||
bool checkModified )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
init( aProperties );
|
||||
|
||||
try
|
||||
@ -3015,8 +3012,6 @@ FOOTPRINT* PCB_IO_KICAD_SEXPR::FootprintLoad( const wxString& aLibraryPath,
|
||||
void PCB_IO_KICAD_SEXPR::FootprintSave( const wxString& aLibraryPath, const FOOTPRINT* aFootprint,
|
||||
const std::map<std::string, UTF8>* aProperties )
|
||||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
init( aProperties );
|
||||
|
||||
// In this public PLUGIN API function, we can safely assume it was
|
||||
@ -3033,9 +3028,7 @@ void PCB_IO_KICAD_SEXPR::FootprintSave( const wxString& aLibraryPath, const FOOT
|
||||
"Would you like to create it?"),
|
||||
aLibraryPath );
|
||||
|
||||
if( !Pgm().IsGUI()
|
||||
|| wxMessageBox( msg, _( "Library Not Found" ), wxYES_NO | wxICON_QUESTION )
|
||||
!= wxYES )
|
||||
if( !Pgm().IsGUI() || wxMessageBox( msg, _( "Library Not Found" ), wxYES_NO | wxICON_QUESTION ) != wxYES )
|
||||
return;
|
||||
|
||||
// Save throws its own IO_ERROR on failure, so no need to recreate here
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <config.h>
|
||||
#include <kiway_player.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include <locale_io.h>
|
||||
#include <pcb_io/pcb_io_mgr.h>
|
||||
|
||||
#include <pcb_io/eagle/pcb_io_eagle.h>
|
||||
@ -196,6 +196,7 @@ bool PCB_IO_MGR::ConvertLibrary( std::map<std::string, UTF8>* aOldFileProps, con
|
||||
if( oldFileType == PCB_IO_MGR::FILE_TYPE_NONE )
|
||||
return false;
|
||||
|
||||
LOCALE_IO toggle_locale;
|
||||
IO_RELEASER<PCB_IO> oldFilePI( PCB_IO_MGR::PluginFind( oldFileType ) );
|
||||
IO_RELEASER<PCB_IO> kicadPI( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) );
|
||||
wxArrayString fpNames;
|
||||
@ -220,8 +221,8 @@ bool PCB_IO_MGR::ConvertLibrary( std::map<std::string, UTF8>* aOldFileProps, con
|
||||
|
||||
for ( const wxString& fpName : fpNames )
|
||||
{
|
||||
std::unique_ptr<const FOOTPRINT> fp(
|
||||
oldFilePI->GetEnumeratedFootprint( aOldFilePath, fpName, aOldFileProps ) );
|
||||
std::unique_ptr<const FOOTPRINT> fp( oldFilePI->GetEnumeratedFootprint( aOldFilePath, fpName,
|
||||
aOldFileProps ) );
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -392,7 +392,7 @@ wxArrayString GetFootprints( const wxString& aNickName )
|
||||
if( !tbl )
|
||||
return footprintNames;
|
||||
|
||||
tbl->FootprintEnumerate( footprintNames, aNickName, true );
|
||||
tbl->FootprintEnumerate( footprintNames, aNickName, true, false );
|
||||
|
||||
return footprintNames;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h>
|
||||
#include <pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h>
|
||||
#include <richio.h>
|
||||
|
||||
#include <locale_io.h>
|
||||
#include <board.h>
|
||||
#include <footprint.h>
|
||||
|
||||
@ -148,6 +148,7 @@ std::unique_ptr<FOOTPRINT> ReadFootprintFromFileOrStream( const std::string& aFi
|
||||
|
||||
void DumpFootprintToFile( const FOOTPRINT& aFootprint, const std::string& aLibraryPath )
|
||||
{
|
||||
LOCALE_IO toggle_locale;
|
||||
PCB_IO_KICAD_SEXPR io;
|
||||
io.FootprintSave( aLibraryPath, &aFootprint, nullptr );
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user