Pcbnew footprint library plug in fixes and minor code cleaning.
* When loading footprint do not retest every footprint in cache. Only test the footprint being loaded. Fixes long load times on libraries with a lot of parts. * Fix footprint name bug where file extension was added to the end of the footprint name. * Fix bug in path equivalence test due to Posix path separators in footprint library table. Convert paths to native separator before comparison. * Fix a bug in FOOTPRINT_VIEWER_FRAME::OnActivate() which cause the footprint list to always get reloaded when using footprint library tables. * Remove some unnecessary debugging messages. * Add a few Doxygen comments to FP_CACHE in kicad_plugin.cpp.
This commit is contained in:
parent
7125da8a45
commit
85777d6569
|
@ -158,9 +158,6 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( FP_LIB_TABLE& aTable )
|
||||||
wxString path = FP_LIB_TABLE::ExpandSubstitutions( row->GetFullURI() );
|
wxString path = FP_LIB_TABLE::ExpandSubstitutions( row->GetFullURI() );
|
||||||
wxArrayString fpnames = pi->FootprintEnumerate( path );
|
wxArrayString fpnames = pi->FootprintEnumerate( path );
|
||||||
|
|
||||||
wxLogDebug( wxT( "Load footprint library type %s from path <%s>" ),
|
|
||||||
GetChars( row->GetType() ), GetChars( path ) );
|
|
||||||
|
|
||||||
for( unsigned i=0; i<fpnames.GetCount(); ++i )
|
for( unsigned i=0; i<fpnames.GetCount(); ++i )
|
||||||
{
|
{
|
||||||
std::auto_ptr<MODULE> m( pi->FootprintLoad( path, fpnames[i] ) );
|
std::auto_ptr<MODULE> m( pi->FootprintLoad( path, fpnames[i] ) );
|
||||||
|
|
|
@ -59,7 +59,7 @@ using namespace std;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition for enabling and disabling footprint library trace output. See the
|
* Definition for enabling and disabling footprint library trace output. See the
|
||||||
* wxWidgets documentation on useing the WXTRACE environment variable.
|
* wxWidgets documentation on using the WXTRACE environment variable.
|
||||||
*/
|
*/
|
||||||
static const wxString traceFootprintLibrary( wxT( "KicadFootprintLib" ) );
|
static const wxString traceFootprintLibrary( wxT( "KicadFootprintLib" ) );
|
||||||
|
|
||||||
|
@ -95,12 +95,25 @@ FP_CACHE_ITEM::FP_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName ) :
|
||||||
m_module( aModule )
|
m_module( aModule )
|
||||||
{
|
{
|
||||||
m_file_name = aFileName;
|
m_file_name = aFileName;
|
||||||
m_mod_time.Now();
|
|
||||||
|
if( m_file_name.FileExists() )
|
||||||
|
m_mod_time = m_file_name.GetModificationTime();
|
||||||
|
else
|
||||||
|
m_mod_time.Now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool FP_CACHE_ITEM::IsModified() const
|
bool FP_CACHE_ITEM::IsModified() const
|
||||||
{
|
{
|
||||||
|
if( !m_file_name.FileExists() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxLogTrace( traceFootprintLibrary, wxT( "File <%s>, m_mod_time %s-%s, file mod time: %s-%s." ),
|
||||||
|
GetChars( m_file_name.GetFullPath() ),
|
||||||
|
GetChars( m_mod_time.FormatDate() ), GetChars( m_mod_time.FormatTime() ),
|
||||||
|
GetChars( m_file_name.GetModificationTime().FormatDate() ),
|
||||||
|
GetChars( m_file_name.GetModificationTime().FormatTime() ) );
|
||||||
|
|
||||||
return m_file_name.GetModificationTime() != m_mod_time;
|
return m_file_name.GetModificationTime() != m_mod_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,9 +149,35 @@ public:
|
||||||
|
|
||||||
void Remove( const wxString& aFootprintName );
|
void Remove( const wxString& aFootprintName );
|
||||||
|
|
||||||
wxDateTime GetLibModificationTime();
|
wxDateTime GetLibModificationTime() const;
|
||||||
|
|
||||||
bool IsModified();
|
/**
|
||||||
|
* Function IsModified
|
||||||
|
* check if the footprint cache has been modified relative to \a aLibPath
|
||||||
|
* and \a aFootprintName.
|
||||||
|
*
|
||||||
|
* @param aLibPath is a path to test the current cache library path against.
|
||||||
|
* @param aFootprintName is the footprint name in the cache to test. If the footprint
|
||||||
|
* name is empty, the all the footprint files in the library are
|
||||||
|
* checked to see if they have been modified.
|
||||||
|
* @return true if the cache has been modified.
|
||||||
|
*/
|
||||||
|
bool IsModified( const wxString& aLibPath,
|
||||||
|
const wxString& aFootprintName = wxEmptyString ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function IsPath
|
||||||
|
* checks if \a aPath is the same as the current cache path.
|
||||||
|
*
|
||||||
|
* This tests paths by converting \a aPath using the native separators. Internally
|
||||||
|
* #FP_CACHE stores the current path using native separators. This prevents path
|
||||||
|
* miscompares on Windows due to the fact that paths can be stored with / instead of \\
|
||||||
|
* in the footprint library table.
|
||||||
|
*
|
||||||
|
* @param aPath is the library path to test against.
|
||||||
|
* @return true if \a aPath is the same as the cache path.
|
||||||
|
*/
|
||||||
|
bool IsPath( const wxString& aPath ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,7 +188,7 @@ FP_CACHE::FP_CACHE( PCB_IO* aOwner, const wxString& aLibraryPath )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxDateTime FP_CACHE::GetLibModificationTime()
|
wxDateTime FP_CACHE::GetLibModificationTime() const
|
||||||
{
|
{
|
||||||
return m_lib_path.GetModificationTime();
|
return m_lib_path.GetModificationTime();
|
||||||
}
|
}
|
||||||
|
@ -181,7 +220,8 @@ void FP_CACHE::Save()
|
||||||
// Allow file output stream to go out of scope to close the file stream before
|
// Allow file output stream to go out of scope to close the file stream before
|
||||||
// renaming the file.
|
// renaming the file.
|
||||||
{
|
{
|
||||||
// wxLogTrace( traceFootprintLibrary, wxT( "Creating temporary library file %s" ), GetChars( tempFileName ) );
|
wxLogTrace( traceFootprintLibrary, wxT( "Creating temporary library file %s" ),
|
||||||
|
GetChars( tempFileName ) );
|
||||||
|
|
||||||
FILE_OUTPUTFORMATTER formatter( tempFileName );
|
FILE_OUTPUTFORMATTER formatter( tempFileName );
|
||||||
|
|
||||||
|
@ -228,9 +268,12 @@ void FP_CACHE::Load()
|
||||||
|
|
||||||
m_owner->m_parser->SetLineReader( &reader );
|
m_owner->m_parser->SetLineReader( &reader );
|
||||||
|
|
||||||
std::string name = TO_UTF8( fpFileName );
|
std::string name = TO_UTF8( fullPath.GetName() );
|
||||||
|
MODULE* footprint = (MODULE*) m_owner->m_parser->Parse();
|
||||||
|
|
||||||
m_modules.insert( name, new FP_CACHE_ITEM( (MODULE*) m_owner->m_parser->Parse(), fpFileName ) );
|
// The footprint name is the file name without the extension.
|
||||||
|
footprint->SetFPID( fullPath.GetName() );
|
||||||
|
m_modules.insert( name, new FP_CACHE_ITEM( footprint, fullPath ) );
|
||||||
|
|
||||||
} while( dir.GetNext( &fpFileName ) );
|
} while( dir.GetNext( &fpFileName ) );
|
||||||
|
|
||||||
|
@ -263,30 +306,56 @@ void FP_CACHE::Remove( const wxString& aFootprintName )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool FP_CACHE::IsModified()
|
bool FP_CACHE::IsPath( const wxString& aPath ) const
|
||||||
{
|
{
|
||||||
if( !m_lib_path.DirExists() )
|
// Converts path separators to native path separators
|
||||||
|
wxFileName newPath;
|
||||||
|
newPath.AssignDir( aPath );
|
||||||
|
|
||||||
|
return m_lib_path == newPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FP_CACHE::IsModified( const wxString& aLibPath, const wxString& aFootprintName ) const
|
||||||
|
{
|
||||||
|
// The library is modified if the library path got deleted or changed.
|
||||||
|
if( !m_lib_path.DirExists() || !IsPath( aLibPath ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for( MODULE_ITER it = m_modules.begin(); it != m_modules.end(); ++it )
|
// If no footprint was specified, check every file modification time against the time
|
||||||
|
// it was loaded.
|
||||||
|
if( aFootprintName.IsEmpty() )
|
||||||
{
|
{
|
||||||
wxFileName fn = it->second->GetFileName();
|
for( MODULE_CITER it = m_modules.begin(); it != m_modules.end(); ++it )
|
||||||
|
|
||||||
if( !fn.FileExists() )
|
|
||||||
{
|
{
|
||||||
wxLogTrace( traceFootprintLibrary, wxT( "Footprint cache file '%s' does not exist." ),
|
wxFileName fn = m_lib_path;
|
||||||
fn.GetFullPath().GetData() );
|
fn.SetName( it->second->GetFileName().GetName() );
|
||||||
return true;
|
fn.SetExt( KiCadFootprintFileExtension );
|
||||||
}
|
|
||||||
|
|
||||||
if( it->second->IsModified() )
|
if( !fn.FileExists() )
|
||||||
{
|
{
|
||||||
wxLogTrace( traceFootprintLibrary,
|
wxLogTrace( traceFootprintLibrary,
|
||||||
wxT( "Footprint cache file '%s' has been modified." ),
|
wxT( "Footprint cache file '%s' does not exist." ),
|
||||||
fn.GetFullPath().GetData() );
|
fn.GetFullPath().GetData() );
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( it->second->IsModified() )
|
||||||
|
{
|
||||||
|
wxLogTrace( traceFootprintLibrary,
|
||||||
|
wxT( "Footprint cache file '%s' has been modified." ),
|
||||||
|
fn.GetFullPath().GetData() );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MODULE_CITER it = m_modules.find( TO_UTF8( aFootprintName ) );
|
||||||
|
|
||||||
|
if( it == m_modules.end() || it->second->IsModified() )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1590,9 +1659,9 @@ void PCB_IO::init( PROPERTIES* aProperties )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_IO::cacheLib( const wxString& aLibraryPath )
|
void PCB_IO::cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName )
|
||||||
{
|
{
|
||||||
if( !m_cache || m_cache->GetPath() != aLibraryPath || m_cache->IsModified() )
|
if( !m_cache || m_cache->IsModified( aLibraryPath, aFootprintName ) )
|
||||||
{
|
{
|
||||||
// a spectacular episode in memory management:
|
// a spectacular episode in memory management:
|
||||||
delete m_cache;
|
delete m_cache;
|
||||||
|
@ -1630,7 +1699,7 @@ MODULE* PCB_IO::FootprintLoad( const wxString& aLibraryPath, const wxString& aFo
|
||||||
|
|
||||||
init( aProperties );
|
init( aProperties );
|
||||||
|
|
||||||
cacheLib( aLibraryPath );
|
cacheLib( aLibraryPath, aFootprintName );
|
||||||
|
|
||||||
const MODULE_MAP& mods = m_cache->GetModules();
|
const MODULE_MAP& mods = m_cache->GetModules();
|
||||||
|
|
||||||
|
@ -1817,7 +1886,7 @@ bool PCB_IO::FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProp
|
||||||
wxMilliSleep( 250L );
|
wxMilliSleep( 250L );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( m_cache && m_cache->GetPath() == aLibraryPath )
|
if( m_cache && !m_cache->IsPath( aLibraryPath ) )
|
||||||
{
|
{
|
||||||
delete m_cache;
|
delete m_cache;
|
||||||
m_cache = NULL;
|
m_cache = NULL;
|
||||||
|
|
|
@ -210,7 +210,7 @@ private:
|
||||||
throw( IO_ERROR );
|
throw( IO_ERROR );
|
||||||
|
|
||||||
/// we only cache one footprint library for now, this determines which one.
|
/// we only cache one footprint library for now, this determines which one.
|
||||||
void cacheLib( const wxString& aLibraryPath );
|
void cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName = wxEmptyString );
|
||||||
|
|
||||||
void init( PROPERTIES* aProperties );
|
void init( PROPERTIES* aProperties );
|
||||||
};
|
};
|
||||||
|
|
|
@ -149,7 +149,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* aParent,
|
||||||
SetBoard( new BOARD() );
|
SetBoard( new BOARD() );
|
||||||
// Ensure all layers and items are visible:
|
// Ensure all layers and items are visible:
|
||||||
GetBoard()->SetVisibleAlls();
|
GetBoard()->SetVisibleAlls();
|
||||||
SetScreen( new PCB_SCREEN(GetPageSizeIU()) );
|
SetScreen( new PCB_SCREEN( GetPageSizeIU() ) );
|
||||||
GetScreen()->m_Center = true; // Center coordinate origins on screen.
|
GetScreen()->m_Center = true; // Center coordinate origins on screen.
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* aParent,
|
||||||
|
|
||||||
DisplayLibInfos();
|
DisplayLibInfos();
|
||||||
|
|
||||||
// If a footprint was previsiously loaded, reload it
|
// If a footprint was previously loaded, reload it
|
||||||
if( !m_libraryName.IsEmpty() && !m_footprintName.IsEmpty() )
|
if( !m_libraryName.IsEmpty() && !m_footprintName.IsEmpty() )
|
||||||
{
|
{
|
||||||
#if !defined( USE_FP_LIB_TABLE )
|
#if !defined( USE_FP_LIB_TABLE )
|
||||||
|
@ -235,9 +235,9 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* aParent,
|
||||||
mesg.MessageToolbarPane();
|
mesg.MessageToolbarPane();
|
||||||
|
|
||||||
|
|
||||||
// Manage main toolbal
|
// Manage main toolbar
|
||||||
m_auimgr.AddPane( m_mainToolBar,
|
m_auimgr.AddPane( m_mainToolBar,
|
||||||
wxAuiPaneInfo( horiz ).Name( wxT ("m_mainToolBar" ) ).Top().Row( 0 ) );
|
wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top().Row( 0 ) );
|
||||||
|
|
||||||
wxSize minsize( 60, -1 );
|
wxSize minsize( 60, -1 );
|
||||||
|
|
||||||
|
@ -290,6 +290,7 @@ FOOTPRINT_VIEWER_FRAME::~FOOTPRINT_VIEWER_FRAME()
|
||||||
m_Draw3DFrame->Destroy();
|
m_Draw3DFrame->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* return the frame name used when creating the frame
|
/* return the frame name used when creating the frame
|
||||||
* used to get a reference to this frame, if exists
|
* used to get a reference to this frame, if exists
|
||||||
*/
|
*/
|
||||||
|
@ -298,13 +299,14 @@ const wxChar* FOOTPRINT_VIEWER_FRAME::GetFootprintViewerFrameName()
|
||||||
return FOOTPRINT_VIEWER_FRAME_NAME;
|
return FOOTPRINT_VIEWER_FRAME_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* return a reference to the current opened Footprint viewer
|
/* return a reference to the current opened Footprint viewer
|
||||||
* or NULL if no Footprint viewer currently opened
|
* or NULL if no Footprint viewer currently opened
|
||||||
*/
|
*/
|
||||||
FOOTPRINT_VIEWER_FRAME* FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer()
|
FOOTPRINT_VIEWER_FRAME* FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer()
|
||||||
{
|
{
|
||||||
return (FOOTPRINT_VIEWER_FRAME*)
|
return (FOOTPRINT_VIEWER_FRAME*)
|
||||||
wxWindow::FindWindowByName(GetFootprintViewerFrameName());
|
wxWindow::FindWindowByName( GetFootprintViewerFrameName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -400,8 +402,8 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* If not found, clear current library selection because it can be
|
// If not found, clear current library selection because it can be deleted after
|
||||||
* deleted after a config change. */
|
// a configuration change.
|
||||||
m_libraryName = wxEmptyString;
|
m_libraryName = wxEmptyString;
|
||||||
m_footprintName = wxEmptyString;
|
m_footprintName = wxEmptyString;
|
||||||
}
|
}
|
||||||
|
@ -452,6 +454,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList()
|
||||||
|
|
||||||
if( !libLoaded )
|
if( !libLoaded )
|
||||||
{
|
{
|
||||||
|
m_footprintName = wxEmptyString;
|
||||||
m_libraryName = wxEmptyString;
|
m_libraryName = wxEmptyString;
|
||||||
|
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
@ -462,7 +465,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList()
|
||||||
msg += _( "Files not found:\n\n" ) + fp_info_list.m_filesNotFound;
|
msg += _( "Files not found:\n\n" ) + fp_info_list.m_filesNotFound;
|
||||||
|
|
||||||
if( !fp_info_list.m_filesInvalid.IsEmpty() )
|
if( !fp_info_list.m_filesInvalid.IsEmpty() )
|
||||||
msg += _("\n\nFile load errors:\n\n" ) + fp_info_list.m_filesInvalid;
|
msg += _( "\n\nFile load errors:\n\n" ) + fp_info_list.m_filesInvalid;
|
||||||
|
|
||||||
DisplayError( this, msg );
|
DisplayError( this, msg );
|
||||||
return;
|
return;
|
||||||
|
@ -566,7 +569,7 @@ void FOOTPRINT_VIEWER_FRAME::DClickOnFootprintList( wxCommandEvent& event )
|
||||||
// event in the parent window which would cause the part to be parked
|
// event in the parent window which would cause the part to be parked
|
||||||
// rather than staying in mode mode.
|
// rather than staying in mode mode.
|
||||||
// Remember the mouse button will be released in the parent window
|
// Remember the mouse button will be released in the parent window
|
||||||
// thus creating a mouse button release event which should be ingnored.
|
// thus creating a mouse button release event which should be ignored
|
||||||
((PCB_BASE_FRAME*)GetParent())->SkipNextLeftButtonReleaseEvent();
|
((PCB_BASE_FRAME*)GetParent())->SkipNextLeftButtonReleaseEvent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -640,19 +643,37 @@ void FOOTPRINT_VIEWER_FRAME::OnActivate( wxActivateEvent& event )
|
||||||
m_selectedFootprintName.Empty();
|
m_selectedFootprintName.Empty();
|
||||||
|
|
||||||
// Ensure we have the right library list:
|
// Ensure we have the right library list:
|
||||||
|
#if !defined( USE_FP_LIB_TABLE )
|
||||||
if( g_LibraryNames.GetCount() == m_LibList->GetCount() )
|
if( g_LibraryNames.GetCount() == m_LibList->GetCount() )
|
||||||
{
|
{
|
||||||
unsigned ii;
|
unsigned ii;
|
||||||
|
|
||||||
for( ii = 0; ii < g_LibraryNames.GetCount(); ii++ )
|
for( ii = 0; ii < g_LibraryNames.GetCount(); ii++ )
|
||||||
{
|
{
|
||||||
if( m_LibList->GetString(ii) != g_LibraryNames[ii] )
|
if( m_LibList->GetString( ii ) != g_LibraryNames[ii] )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ii == g_LibraryNames.GetCount() )
|
if( ii == g_LibraryNames.GetCount() )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
std::vector< wxString > libNicknames = m_footprintLibTable->GetLogicalLibs();
|
||||||
|
|
||||||
|
if( libNicknames.size() == m_LibList->GetCount() )
|
||||||
|
{
|
||||||
|
unsigned ii;
|
||||||
|
|
||||||
|
for( ii = 0; ii < libNicknames.size(); ii++ )
|
||||||
|
{
|
||||||
|
if( libNicknames[ii] != m_LibList->GetString( ii ) )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ii == libNicknames.size() )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// If we are here, the library list has changed, rebuild it
|
// If we are here, the library list has changed, rebuild it
|
||||||
ReCreateLibraryList();
|
ReCreateLibraryList();
|
||||||
|
|
|
@ -754,8 +754,8 @@ T PCB_PARSER::lookUpLayer( const M& aMap ) throw( PARSE_ERROR, IO_ERROR )
|
||||||
// dump the whole darn table, there's something wrong with it.
|
// dump the whole darn table, there's something wrong with it.
|
||||||
for( it = aMap.begin(); it != aMap.end(); ++it )
|
for( it = aMap.begin(); it != aMap.end(); ++it )
|
||||||
{
|
{
|
||||||
printf( &aMap == (void*)&m_layerIndices ? "lm[%s] = %d\n" : "lm[%s] = %08X\n",
|
wxLogDebug( &aMap == (void*)&m_layerIndices ? wxT( "lm[%s] = %d" ) :
|
||||||
it->first.c_str(), it->second );
|
wxT( "lm[%s] = %08X" ), it->first.c_str(), it->second );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue