Commit 9fe5ce67 authored by Dick Hollenbeck's avatar Dick Hollenbeck

Modular-Kicad milestone B), minor portion:

*)  Implement a framework for "Data Load On Demand".

*)  Implement FP_LIB_TABLE* PROJECT::PcbFootprintLibs(), which is the first
    prototype.

This allows the project specific footprint tables to be part of the Module Editor
when invoked from Eeschema.
parent dc745aa6
...@@ -137,6 +137,12 @@ FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) : ...@@ -137,6 +137,12 @@ FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) :
} }
FP_LIB_TABLE::~FP_LIB_TABLE()
{
// *fallBack is not owned here.
}
wxArrayString FP_LIB_TABLE::FootprintEnumerate( const wxString& aNickname ) wxArrayString FP_LIB_TABLE::FootprintEnumerate( const wxString& aNickname )
{ {
const ROW* row = FindRow( aNickname ); const ROW* row = FindRow( aNickname );
...@@ -514,9 +520,16 @@ std::vector<wxString> FP_LIB_TABLE::GetLogicalLibs() ...@@ -514,9 +520,16 @@ std::vector<wxString> FP_LIB_TABLE::GetLogicalLibs()
} while( ( cur = cur->fallBack ) != 0 ); } while( ( cur = cur->fallBack ) != 0 );
ret.reserve( unique.size() );
// DBG(printf( "%s: count:%zd\n", __func__, unique.size() );)
// return a sorted, unique set of nicknames in a std::vector<wxString> to caller // return a sorted, unique set of nicknames in a std::vector<wxString> to caller
for( std::set<wxString>::const_iterator it = unique.begin(); it!=unique.end(); ++it ) for( std::set<wxString>::const_iterator it = unique.begin(); it!=unique.end(); ++it )
{
//DBG(printf( " %s\n", TO_UTF8( *it ) );)
ret.push_back( *it ); ret.push_back( *it );
}
return ret; return ret;
} }
...@@ -738,7 +751,7 @@ wxString FP_LIB_TABLE::GetGlobalTableFileName() ...@@ -738,7 +751,7 @@ wxString FP_LIB_TABLE::GetGlobalTableFileName()
void FP_LIB_TABLE::Load( const wxString& aFileName ) void FP_LIB_TABLE::Load( const wxString& aFileName )
throw( IO_ERROR ) throw( IO_ERROR )
{ {
// Empty footprint library tables are valid. // It's OK if footprint library tables are missing.
if( wxFileName::IsFileReadable( aFileName ) ) if( wxFileName::IsFileReadable( aFileName ) )
{ {
FILE_LINE_READER reader( aFileName ); FILE_LINE_READER reader( aFileName );
......
...@@ -42,15 +42,22 @@ PROJECT::PROJECT() ...@@ -42,15 +42,22 @@ PROJECT::PROJECT()
memset( m_elems, 0, sizeof(m_elems) ); memset( m_elems, 0, sizeof(m_elems) );
} }
PROJECT::~PROJECT()
void PROJECT::ElemsClear()
{ {
#if 1 // careful here, this should work, but the virtual destructor may not
// careful here, this may work, but the virtual destructor may not
// be in the same link image as PROJECT. // be in the same link image as PROJECT.
for( unsigned i = 0; i<DIM(m_elems); ++i ) for( unsigned i = 0; i<DIM(m_elems); ++i )
{
delete m_elems[i]; delete m_elems[i];
#endif m_elems[i] = NULL;
}
}
PROJECT::~PROJECT()
{
ElemsClear();
} }
...@@ -145,21 +152,29 @@ RETAINED_PATH& PROJECT::RPath( RETPATH_T aIndex ) ...@@ -145,21 +152,29 @@ RETAINED_PATH& PROJECT::RPath( RETPATH_T aIndex )
} }
PROJECT::_ELEM* PROJECT::Elem( ELEM_T aIndex, _ELEM* aElem ) PROJECT::_ELEM* PROJECT::GetElem( ELEM_T aIndex )
{ {
unsigned ndx = unsigned( aIndex ); // This is virtual, so implement it out of line
if( ndx < DIM( m_elems ) ) if( unsigned( aIndex ) < DIM( m_elems ) )
{ {
if( aElem ) return m_elems[aIndex];
m_elems[ndx] = aElem;
return m_elems[ndx];
} }
return NULL; return NULL;
} }
void PROJECT::SetElem( ELEM_T aIndex, _ELEM* aElem )
{
// This is virtual, so implement it out of line
if( unsigned( aIndex ) < DIM( m_elems ) )
{
m_elems[aIndex] = aElem;
}
}
// non-member so it can be moved easily, and kept REALLY private. // non-member so it can be moved easily, and kept REALLY private.
// Do NOT Clear() in here. // Do NOT Clear() in here.
static void add_search_paths( SEARCH_STACK* aDst, wxConfigBase* aCfg, int aIndex ) static void add_search_paths( SEARCH_STACK* aDst, wxConfigBase* aCfg, int aIndex )
......
...@@ -81,23 +81,8 @@ void CVPCB_MAINFRAME::LoadProjectFile( const wxString& aFileName ) ...@@ -81,23 +81,8 @@ void CVPCB_MAINFRAME::LoadProjectFile( const wxString& aFileName )
if( m_NetlistFileExtension.IsEmpty() ) if( m_NetlistFileExtension.IsEmpty() )
m_NetlistFileExtension = wxT( "net" ); m_NetlistFileExtension = wxT( "net" );
// empty the table, Load() it again below. // Force it to be loaded on demand.
FootprintLibs()->Clear(); prj.ElemClear( PROJECT::ELEM_FPTBL );
/* this is done by ConfigLoad(), and that sets the env var too.
prj.SetProjectFullName( fn.GetFullPath() );
*/
wxString projectFpLibTableFileName = prj.FootprintLibTblName();
try
{
FootprintLibs()->Load( projectFpLibTableFileName );
}
catch( const IO_ERROR& ioe )
{
DisplayError( this, ioe.errorText );
}
} }
......
...@@ -488,7 +488,8 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName ) ...@@ -488,7 +488,8 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
wxLogDebug( wxT( "Load footprint <%s> from library <%s>." ), wxLogDebug( wxT( "Load footprint <%s> from library <%s>." ),
fpname.c_str(), nickname.c_str() ); fpname.c_str(), nickname.c_str() );
footprint = FootprintLibs()->FootprintLoad( FROM_UTF8( nickname.c_str() ), FROM_UTF8( fpname.c_str() ) ); footprint = Prj().PcbFootprintLibs()->FootprintLoad(
FROM_UTF8( nickname.c_str() ), FROM_UTF8( fpname.c_str() ) );
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
......
...@@ -128,7 +128,7 @@ void LIBRARY_LISTBOX::SetLibraryList( const wxArrayString& aList ) ...@@ -128,7 +128,7 @@ void LIBRARY_LISTBOX::SetLibraryList( const wxArrayString& aList )
{ {
RefreshItems( 0L, m_libraryList.Count()-1 ); RefreshItems( 0L, m_libraryList.Count()-1 );
#if defined (__WXGTK__ ) // && wxMINOR_VERSION == 8 #if defined (__WXGTK__ ) && wxMINOR_VERSION == 8
// @bug On GTK and wxWidgets 2.8.x, this will assert in debug builds because the // @bug On GTK and wxWidgets 2.8.x, this will assert in debug builds because the
// column parameter is -1. This was the only way to prevent GTK3 from // column parameter is -1. This was the only way to prevent GTK3 from
// ellipsizing long strings down to a few characters. It still doesn't set // ellipsizing long strings down to a few characters. It still doesn't set
......
...@@ -200,24 +200,6 @@ CVPCB_MAINFRAME::~CVPCB_MAINFRAME() ...@@ -200,24 +200,6 @@ CVPCB_MAINFRAME::~CVPCB_MAINFRAME()
} }
FP_LIB_TABLE* CVPCB_MAINFRAME::FootprintLibs() const
{
PROJECT& prj = Prj();
FP_LIB_TABLE* tbl = dynamic_cast<FP_LIB_TABLE*>( prj.Elem( PROJECT::FPTBL ) );
if( !tbl )
{
// 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 );
prj.Elem( PROJECT::FPTBL, tbl );
}
return tbl;
}
void CVPCB_MAINFRAME::LoadSettings( wxConfigBase* aCfg ) void CVPCB_MAINFRAME::LoadSettings( wxConfigBase* aCfg )
{ {
EDA_BASE_FRAME::LoadSettings( aCfg ); EDA_BASE_FRAME::LoadSettings( aCfg );
...@@ -493,7 +475,7 @@ void CVPCB_MAINFRAME::ConfigCvpcb( wxCommandEvent& event ) ...@@ -493,7 +475,7 @@ void CVPCB_MAINFRAME::ConfigCvpcb( wxCommandEvent& event )
void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent ) void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent )
{ {
bool tableChanged = false; bool tableChanged = false;
int r = InvokePcbLibTableEditor( this, &GFootprintTable, FootprintLibs() ); int r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() );
if( r & 1 ) if( r & 1 )
{ {
...@@ -521,7 +503,7 @@ void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent ) ...@@ -521,7 +503,7 @@ void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent )
try try
{ {
FootprintLibs()->Save( fileName ); Prj().PcbFootprintLibs()->Save( fileName );
tableChanged = true; tableChanged = true;
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
...@@ -538,7 +520,7 @@ void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent ) ...@@ -538,7 +520,7 @@ void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent )
if( tableChanged ) if( tableChanged )
{ {
BuildLIBRARY_LISTBOX(); BuildLIBRARY_LISTBOX();
m_footprints.ReadFootprintFiles( FootprintLibs() ); m_footprints.ReadFootprintFiles( Prj().PcbFootprintLibs() );
} }
} }
...@@ -735,7 +717,7 @@ void CVPCB_MAINFRAME::DisplayStatus() ...@@ -735,7 +717,7 @@ void CVPCB_MAINFRAME::DisplayStatus()
bool CVPCB_MAINFRAME::LoadFootprintFiles() bool CVPCB_MAINFRAME::LoadFootprintFiles()
{ {
FP_LIB_TABLE* fptbl = FootprintLibs(); FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
// Check if there are footprint libraries in the footprint library table. // Check if there are footprint libraries in the footprint library table.
if( !fptbl || !fptbl->GetLogicalLibs().size() ) if( !fptbl || !fptbl->GetLogicalLibs().size() )
...@@ -1012,11 +994,13 @@ void CVPCB_MAINFRAME::BuildLIBRARY_LISTBOX() ...@@ -1012,11 +994,13 @@ void CVPCB_MAINFRAME::BuildLIBRARY_LISTBOX()
wxFONTWEIGHT_NORMAL ) ); wxFONTWEIGHT_NORMAL ) );
} }
if( FootprintLibs() ) FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
if( tbl )
{ {
wxArrayString libNames; wxArrayString libNames;
std::vector< wxString > libNickNames = FootprintLibs()->GetLogicalLibs(); std::vector< wxString > libNickNames = tbl->GetLogicalLibs();
for( unsigned ii = 0; ii < libNickNames.size(); ii++ ) for( unsigned ii = 0; ii < libNickNames.size(); ii++ )
libNames.Add( libNickNames[ii] ); libNames.Add( libNickNames[ii] );
......
...@@ -88,12 +88,6 @@ public: ...@@ -88,12 +88,6 @@ public:
bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl=0 ); // overload KIWAY_PLAYER bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl=0 ); // overload KIWAY_PLAYER
/**
* Function FootprintLibs
* @return the project #FP_LIB_TABLE.
*/
FP_LIB_TABLE* FootprintLibs() const;
/** /**
* @return a pointer on the Footprint Viewer frame, if exists, or NULL * @return a pointer on the Footprint Viewer frame, if exists, or NULL
*/ */
......
...@@ -119,346 +119,6 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName ) ...@@ -119,346 +119,6 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
} }
#if 0
/*
This code block was based on two major assumptions that are no longer true:
1) Footprint library basenames would remain the same.
(But no, basenames have been renamed in the github repo.)
2) *.mod files would still be around and merely reside in the FP_LIB_TABLE.
(But no, they have been converted to *.pretty.)
There is a newer replacement code block in the #else region.
*/
/**
* Function missingLegacyLibs
* tests the list of \a aLibNames by URI to determine if any of them are missing from
* the #FP_LIB_TABLE.
*
* @note The missing legacy footprint library test is performed by using old library
* file path lookup method. If the library is found, it is compared against all
* of the URIs in the table rather than the nickname. This was done because the
* user could change the nicknames from the default table. Using the full path
* is more reliable.
*
* @param aLibNames is the list of legacy library names.
* @param aErrorMsg is a pointer to a wxString object to store the URIs of any missing
* legacy library paths. Can be NULL.
* @return true if there are missing legacy libraries. Otherwise false.
*/
static bool missingLegacyLibs( FP_LIB_TABLE* aTbl, SEARCH_STACK& aSStack,
const wxArrayString& aLibNames, wxString* aErrorMsg )
{
bool missing = false;
for( unsigned i = 0; i < aLibNames.GetCount(); i++ )
{
wxFileName fn( wxEmptyString, aLibNames[i], LegacyFootprintLibPathExtension );
wxString legacyLibPath = aSStack.FindValidPath( fn.GetFullPath() );
/*
if( legacyLibPath.IsEmpty() )
continue;
*/
if( !aTbl->FindRowByURI( legacyLibPath ) )
{
missing = true;
if( aErrorMsg )
{
*aErrorMsg += wxChar( '"' );
if( !legacyLibPath )
*aErrorMsg += !legacyLibPath ? aLibNames[i] : legacyLibPath;
*aErrorMsg += wxT( "\"\n" );
}
}
}
return missing;
}
/**
* Function convertFromLegacy
* converts the footprint names in \a aNetList from the legacy format to the #FPID format.
*
* @param aNetList is the #NETLIST object to convert.
* @param aLibNames is the list of legacy footprint library names from the currently loaded
* project.
* @param aReporter is the #REPORTER object to dump messages into.
* @return true if all footprint names were successfully converted to a valid FPID.
*/
static bool convertFromLegacy( FP_LIB_TABLE* aTbl, SEARCH_STACK& aSStack, NETLIST& aNetList,
const wxArrayString& aLibNames, REPORTER* aReporter = NULL ) throw( IO_ERROR )
{
wxString msg;
FPID lastFPID;
COMPONENT* component;
MODULE* module = 0;
bool retv = true;
if( aNetList.IsEmpty() )
return true;
aNetList.SortByFPID();
wxString libPath;
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
for( unsigned ii = 0; ii < aNetList.GetCount(); ii++ )
{
component = aNetList.GetComponent( ii );
// The footprint hasn't been assigned yet so ignore it.
if( component->GetFPID().empty() )
continue;
if( component->GetFPID() != lastFPID )
{
module = NULL;
for( unsigned ii = 0; ii < aLibNames.GetCount(); ii++ )
{
wxFileName fn( wxEmptyString, aLibNames[ii], LegacyFootprintLibPathExtension );
libPath = aSStack.FindValidPath( fn.GetFullPath() );
if( !libPath )
{
if( aReporter )
{
msg.Printf( _( "Cannot find footprint library file '%s' in any of the "
"KiCad legacy library search paths.\n" ),
GetChars( fn.GetFullPath() ) );
aReporter->Report( msg );
}
retv = false;
continue;
}
module = pi->FootprintLoad( libPath, component->GetFPID().GetFootprintName() );
if( module )
{
lastFPID = component->GetFPID();
break;
}
}
}
if( !module )
{
if( aReporter )
{
msg.Printf( _( "Component '%s' footprint '%s' was not found in any legacy "
"library.\n" ),
GetChars( component->GetReference() ),
GetChars( component->GetFPID().Format() ) );
aReporter->Report( msg );
}
// Clear the footprint assignment since the old library lookup method is no
// longer valid.
FPID emptyFPID;
component->SetFPID( emptyFPID );
retv = false;
continue;
}
else
{
wxString libNickname;
const FP_LIB_TABLE::ROW* row;
if( ( row = aTbl->FindRowByURI( libPath ) ) != NULL )
libNickname = row->GetNickName();
if( libNickname.IsEmpty() )
{
if( aReporter )
{
msg.Printf( _( "Component '%s' with footprint '%s' and legacy library path '%s' "
"was not found in the footprint library table.\n" ),
GetChars( component->GetReference() ),
GetChars( component->GetFPID().Format() ),
GetChars( libPath )
);
aReporter->Report( msg );
}
retv = false;
}
else
{
FPID newFPID = lastFPID;
newFPID.SetLibNickname( libNickname );
if( !newFPID.IsValid() )
{
if( aReporter )
{
msg.Printf( _( "Component '%s' FPID '%s' is not valid.\n" ),
GetChars( component->GetReference() ),
GetChars( newFPID.Format() ) );
aReporter->Report( msg );
}
retv = false;
}
else
{
// The footprint name should already be set.
component->SetFPID( newFPID );
}
}
}
}
return retv;
}
bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
{
COMPONENT* component;
wxString msg;
bool isLegacy = true;
ReadSchematicNetlist();
if( m_ListCmp == NULL )
return false;
LoadProjectFile( m_NetlistFileName.GetFullPath() );
LoadFootprintFiles();
BuildFOOTPRINTS_LISTBOX();
BuildLIBRARY_LISTBOX();
m_ListCmp->Clear();
m_undefinedComponentCnt = 0;
if( m_netlist.AnyFootprintsLinked() )
{
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
{
component = m_netlist.GetComponent( i );
if( component->GetFPID().empty() )
continue;
if( isLegacy )
{
if( !component->GetFPID().IsLegacy() )
isLegacy = false;
}
}
}
else
{
isLegacy = false; // None of the components have footprints assigned.
}
wxString missingLibs;
// Check if footprint links were generated before the footprint library table was implemented.
if( isLegacy )
{
if( missingLegacyLibs( FootprintLibs(), Prj().PcbSearchS(), m_ModuleLibNames, &missingLibs ) )
{
msg = wxT( "The following legacy libraries are defined in the project file "
"but were not found in the footprint library table:\n\n" ) + missingLibs;
msg += wxT( "\nDo you want to update the footprint library table before "
"attempting to update the assigned footprints?" );
if( IsOK( this, msg ) )
{
wxCommandEvent cmd;
OnEditFootprintLibraryTable( cmd );
}
}
msg = wxT( "Some or all of the assigned footprints contain legacy entries. Would you "
"like CvPcb to attempt to convert them to the new footprint library table "
"format?" );
if( IsOK( this, msg ) )
{
msg.Clear();
WX_STRING_REPORTER reporter( &msg );
SEARCH_STACK& search = Prj().SchSearchS();
if( !convertFromLegacy( FootprintLibs(), search, m_netlist, m_ModuleLibNames, &reporter ) )
{
HTML_MESSAGE_BOX dlg( this, wxEmptyString );
dlg.MessageSet( wxT( "The following errors occurred attempting to convert the "
"footprint assignments:\n\n" ) );
dlg.ListSet( msg );
dlg.MessageSet( wxT( "\nYou will need to reassign them manually if you want them "
"to be updated correctly the next time you import the "
"netlist in Pcbnew." ) );
dlg.ShowModal();
}
m_modified = true;
}
else
{
// Clear the legacy footprint assignments.
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
{
FPID emptyFPID;
component = m_netlist.GetComponent( i );
component->SetFPID( emptyFPID );
m_modified = true;
}
}
}
for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
{
component = m_netlist.GetComponent( i );
msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1,
GetChars( component->GetReference() ),
GetChars( component->GetValue() ),
GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
m_ListCmp->AppendLine( msg );
if( component->GetFPID().empty() )
{
m_undefinedComponentCnt += 1;
continue;
}
}
if( !m_netlist.IsEmpty() )
m_ListCmp->SetSelection( 0, true );
DisplayStatus();
UpdateTitle();
UpdateFileHistory( m_NetlistFileName.GetFullPath() );
return true;
}
#else // new strategy
/// Return true if the resultant FPID has a certain nickname. The guess /// Return true if the resultant FPID has a certain nickname. The guess
/// is only made if this footprint resides in only one library. /// is only made if this footprint resides in only one library.
/// @return int - 0 on success, 1 on not found, 2 on ambiguous i.e. multiple matches /// @return int - 0 on success, 1 on not found, 2 on ambiguous i.e. multiple matches
...@@ -503,7 +163,6 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() ...@@ -503,7 +163,6 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
{ {
wxString msg; wxString msg;
bool hasMissingNicks = false; bool hasMissingNicks = false;
FP_LIB_TABLE* tbl = FootprintLibs();
ReadSchematicNetlist(); ReadSchematicNetlist();
...@@ -512,6 +171,7 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() ...@@ -512,6 +171,7 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
LoadProjectFile( m_NetlistFileName.GetFullPath() ); LoadProjectFile( m_NetlistFileName.GetFullPath() );
LoadFootprintFiles(); LoadFootprintFiles();
BuildFOOTPRINTS_LISTBOX(); BuildFOOTPRINTS_LISTBOX();
BuildLIBRARY_LISTBOX(); BuildLIBRARY_LISTBOX();
...@@ -554,6 +214,9 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() ...@@ -554,6 +214,9 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
if( component->GetFPID().IsLegacy() ) if( component->GetFPID().IsLegacy() )
{ {
// get this first here, it's possibly obsoleted if we get it too soon.
FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
int guess = guessNickname( tbl, (FPID*) &component->GetFPID() ); int guess = guessNickname( tbl, (FPID*) &component->GetFPID() );
switch( guess ) switch( guess )
...@@ -659,9 +322,6 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() ...@@ -659,9 +322,6 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
} }
#endif
int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName )
{ {
wxFileName fn; wxFileName fn;
...@@ -685,7 +345,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) ...@@ -685,7 +345,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName )
fn.SetExt( ComponentFileExtension ); fn.SetExt( ComponentFileExtension );
// Save the project specific footprint library table. // Save the project specific footprint library table.
if( !FootprintLibs()->IsEmpty( false ) ) if( !Prj().PcbFootprintLibs()->IsEmpty( false ) )
{ {
wxString fp_lib_tbl = Prj().FootprintLibTblName(); wxString fp_lib_tbl = Prj().FootprintLibTblName();
...@@ -695,7 +355,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) ...@@ -695,7 +355,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName )
{ {
try try
{ {
FootprintLibs()->Save( fp_lib_tbl ); Prj().PcbFootprintLibs()->Save( fp_lib_tbl );
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
......
...@@ -270,6 +270,8 @@ public: ...@@ -270,6 +270,8 @@ public:
*/ */
FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable = NULL ); FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable = NULL );
~FP_LIB_TABLE();
/// Delete all rows. /// Delete all rows.
void Clear() void Clear()
{ {
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
class wxConfigBase; class wxConfigBase;
class PARAM_CFG_ARRAY; class PARAM_CFG_ARRAY;
class FP_LIB_TABLE;
#define VTBL_ENTRY virtual #define VTBL_ENTRY virtual
...@@ -49,11 +49,12 @@ class PROJECT ...@@ -49,11 +49,12 @@ class PROJECT
{ {
public: public:
/// Derive PROJECT elements from this, it has a virtual destructor, and /// A PROJECT can hold stuff it knows nothing about, in the form of
/// Elem*() functions can work with it. Implementation is opaque in /// _ELEM derivatives. Derive PROJECT elements from this, it has a virtual
/// class PROJECT. If find you have to include derived class headers in this /// destructor, and Elem*() functions can work with it. Implementation is
/// file, you are doing something wrong. Keep knowledge of derived classes /// opaque in class PROJECT. If find you have to include derived class headers
/// opaque to class PROJECT please. /// in this file, you are doing incompatible with the goal of this class.
/// Keep knowledge of derived classes opaque to class PROJECT please.
class _ELEM class _ELEM
{ {
public: public:
...@@ -63,6 +64,8 @@ public: ...@@ -63,6 +64,8 @@ public:
PROJECT(); PROJECT();
~PROJECT(); ~PROJECT();
//-----<Cross Module API>----------------------------------------------------
// VTBL_ENTRY bool MaybeLoadProjectSettings( const std::vector<wxString>& aFileSet ); // VTBL_ENTRY bool MaybeLoadProjectSettings( const std::vector<wxString>& aFileSet );
/** /**
...@@ -154,18 +157,12 @@ public: ...@@ -154,18 +157,12 @@ public:
*/ */
enum ELEM_T enum ELEM_T
{ {
FPTBL, ELEM_FPTBL,
ELEM_COUNT ELEM_COUNT
}; };
/** /**
* A PROJECT can hold stuff it knows nothing about, in the form of
* _ELEM derivatives. This function gives access to a PROJECT::_ELEM using
* enum ELEM_T as an index.
* <p>
* Acts as setter iff aElem is not NULL, else getter.
* <p>
* Typically wrapped somewhere else in a more meaningful function wrapper. * Typically wrapped somewhere else in a more meaningful function wrapper.
* This is a cross module API, therefore the _ELEM destructor is virtual and * This is a cross module API, therefore the _ELEM destructor is virtual and
* can point to a destructor function in another link image. Be careful that * can point to a destructor function in another link image. Be careful that
...@@ -174,7 +171,47 @@ public: ...@@ -174,7 +171,47 @@ public:
* Summary: 1) cross module API, 2) PROJECT knows nothing about _ELEM objects, * Summary: 1) cross module API, 2) PROJECT knows nothing about _ELEM objects,
* except how to delete them and set and get pointers to them. * except how to delete them and set and get pointers to them.
*/ */
VTBL_ENTRY _ELEM* Elem( ELEM_T aIndex, _ELEM* aElem = NULL ); VTBL_ENTRY _ELEM* GetElem( ELEM_T aIndex );
VTBL_ENTRY void SetElem( ELEM_T aIndex, _ELEM* aElem );
/// Inline, clear the _ELEM at position aIndex
void ElemClear( ELEM_T aIndex )
{
_ELEM* existing = GetElem( aIndex );
delete existing; // virtual
SetElem( aIndex, NULL );
}
/**
* Function ElemsClear
* deletes all the _ELEMs and set their pointers to NULL.
*/
VTBL_ENTRY void ElemsClear();
//-----</Cross Module API>---------------------------------------------------
//-----<KIFACE Specific APIs>------------------------------------------------
// These are the non-virtual DATA LOAD ON DEMAND members. They load project related
// data on demand, and do so typicallly into m_elems[] at a particular index using
// SetElem() & GetElem(). That is, they wrap SetElem() and GetElem().
// To get the data to reload on demand, first SetProjectFullName(),
// then call ElemClear() from client code.
// non-virtuals resident in PCBNEW link image(s). By being non-virtual, these
// functions can get linked into the KIFACE that needs them, and only there.
// In fact, the other KIFACEs don't even know they exist.
#if defined(PCBNEW) || defined(CVPCB)
// These are all prefaced with "Pcb"
FP_LIB_TABLE* PcbFootprintLibs();
#endif
#if defined(EESCHEMA)
// These are all prefaced with "Sch"
#endif
//-----</KIFACE Specific APIs>-----------------------------------------------
private: private:
...@@ -215,10 +252,6 @@ private: ...@@ -215,10 +252,6 @@ private:
//-----<possible futures>--------------------------------------------------------- //-----<possible futures>---------------------------------------------------------
#if 0 #if 0
VTBL_ENTRY int ElemAllocNdx();
VTBL_ENTRY void ElemSet( int aIndex, ELEMENT_BASE* aBlock );
VTBL_ENTRY ELEM_BASE* ElemGet( int aIndex )
/** /**
* Function Value * Function Value
* fetches a project variable @a aVariable and returns true if that variable was * fetches a project variable @a aVariable and returns true if that variable was
......
...@@ -103,7 +103,7 @@ protected: ...@@ -103,7 +103,7 @@ protected:
* *
* @param aFootprintId is the #FPID of component footprint to load. * @param aFootprintId is the #FPID of component footprint to load.
* @return the #MODULE if found or NULL if \a aFootprintId not found in any of the * @return the #MODULE if found or NULL if \a aFootprintId not found in any of the
* libraries in the table returned from #FootprintLibs(). * libraries in the table returned from #Prj().PcbFootprintLibs().
* @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error * @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error
* occurs while reading footprint library files. * occurs while reading footprint library files.
*/ */
...@@ -127,7 +127,7 @@ public: ...@@ -127,7 +127,7 @@ public:
* *
* @param aFootprintId is the #FPID of component footprint to load. * @param aFootprintId is the #FPID of component footprint to load.
* @return the #MODULE if found or NULL if \a aFootprintId not found in any of the * @return the #MODULE if found or NULL if \a aFootprintId not found in any of the
* libraries in table returned from #FootprintLibs(). * libraries in table returned from #Prj().PcbFootprintLibs().
*/ */
MODULE* LoadFootprint( const FPID& aFootprintId ); MODULE* LoadFootprint( const FPID& aFootprintId );
...@@ -466,12 +466,6 @@ public: ...@@ -466,12 +466,6 @@ public:
*/ */
wxString SelectFootprintFromLibBrowser(); wxString SelectFootprintFromLibBrowser();
/**
* Function FootprintLibs
* @return the project #FP_LIB_TABLE.
*/
FP_LIB_TABLE* FootprintLibs() const;
// ratsnest functions // ratsnest functions
/** /**
* Function Compile_Ratsnest * Function Compile_Ratsnest
......
...@@ -174,10 +174,15 @@ PCB_BASE_FRAME::~PCB_BASE_FRAME() ...@@ -174,10 +174,15 @@ PCB_BASE_FRAME::~PCB_BASE_FRAME()
} }
FP_LIB_TABLE* PCB_BASE_FRAME::FootprintLibs() const FP_LIB_TABLE* PROJECT::PcbFootprintLibs()
{ {
PROJECT& prj = Prj(); // This is a lazy loading function, it loads the project specific table when
FP_LIB_TABLE* tbl = dynamic_cast<FP_LIB_TABLE*>( prj.Elem( PROJECT::FPTBL ) ); // that table is asked for, not before.
FP_LIB_TABLE* tbl = (FP_LIB_TABLE*) GetElem( ELEM_FPTBL );
// its gotta be NULL or a FP_LIB_TABLE, or a bug.
wxASSERT( !tbl || dynamic_cast<FP_LIB_TABLE*>( tbl ) );
if( !tbl ) if( !tbl )
{ {
...@@ -186,7 +191,18 @@ FP_LIB_TABLE* PCB_BASE_FRAME::FootprintLibs() const ...@@ -186,7 +191,18 @@ FP_LIB_TABLE* PCB_BASE_FRAME::FootprintLibs() const
// stack this way, all using the same global fallback table. // stack this way, all using the same global fallback table.
tbl = new FP_LIB_TABLE( &GFootprintTable ); tbl = new FP_LIB_TABLE( &GFootprintTable );
prj.Elem( PROJECT::FPTBL, tbl ); SetElem( ELEM_FPTBL, tbl );
wxString projectFpLibTableFileName = FootprintLibTblName();
try
{
tbl->Load( projectFpLibTableFileName );
}
catch( const IO_ERROR& ioe )
{
DisplayError( NULL, ioe.errorText );
}
} }
return tbl; return tbl;
......
...@@ -173,7 +173,7 @@ void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event ) ...@@ -173,7 +173,7 @@ void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event )
Clear_Pcb( true ); Clear_Pcb( true );
// Clear footprint library table for the new board. // Clear footprint library table for the new board.
FootprintLibs()->Clear(); Prj().PcbFootprintLibs()->Clear();
wxFileName fn; wxFileName fn;
...@@ -603,7 +603,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF ...@@ -603,7 +603,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
return false; return false;
// Save the project specific footprint library table. // Save the project specific footprint library table.
if( !FootprintLibs()->IsEmpty( false ) ) if( !Prj().PcbFootprintLibs()->IsEmpty( false ) )
{ {
wxString fp_lib_tbl = Prj().FootprintLibTblName(); wxString fp_lib_tbl = Prj().FootprintLibTblName();
...@@ -613,7 +613,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF ...@@ -613,7 +613,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
{ {
try try
{ {
FootprintLibs()->Save( fp_lib_tbl ); Prj().PcbFootprintLibs()->Save( fp_lib_tbl );
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
......
...@@ -469,7 +469,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary() ...@@ -469,7 +469,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary()
{ {
wxString nickname = getLibNickName(); wxString nickname = getLibNickName();
if( !FootprintLibs()->IsFootprintLibWritable( nickname ) ) if( !Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ) )
{ {
wxString msg = wxString::Format( wxString msg = wxString::Format(
_( "Library '%s' is read only" ), _( "Library '%s' is read only" ),
...@@ -481,7 +481,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary() ...@@ -481,7 +481,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary()
} }
wxString fpid_txt = PCB_BASE_FRAME::SelectFootprint( this, nickname, wxString fpid_txt = PCB_BASE_FRAME::SelectFootprint( this, nickname,
wxEmptyString, wxEmptyString, FootprintLibs() ); wxEmptyString, wxEmptyString, Prj().PcbFootprintLibs() );
if( !fpid_txt ) if( !fpid_txt )
return false; return false;
...@@ -497,7 +497,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary() ...@@ -497,7 +497,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary()
try try
{ {
FootprintLibs()->FootprintDelete( nickname, fpname ); Prj().PcbFootprintLibs()->FootprintDelete( nickname, fpname );
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
...@@ -545,22 +545,24 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aNewModulesOnly ) ...@@ -545,22 +545,24 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aNewModulesOnly )
try try
{ {
FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
// Delete old library if we're replacing it entirely. // Delete old library if we're replacing it entirely.
if( !aNewModulesOnly ) if( !aNewModulesOnly )
{ {
FootprintLibs()->FootprintLibDelete( nickname ); tbl->FootprintLibDelete( nickname );
FootprintLibs()->FootprintLibCreate( nickname ); tbl->FootprintLibCreate( nickname );
for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() ) for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() )
{ {
FootprintLibs()->FootprintSave( nickname, m, true ); tbl->FootprintSave( nickname, m, true );
} }
} }
else else
{ {
for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() ) for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() )
{ {
FootprintLibs()->FootprintSave( nickname, m, false ); tbl->FootprintSave( nickname, m, false );
// Check for request to stop backup (ESCAPE key actuated) // Check for request to stop backup (ESCAPE key actuated)
if( m_canvas->GetAbortRequest() ) if( m_canvas->GetAbortRequest() )
...@@ -627,7 +629,9 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibrary, ...@@ -627,7 +629,9 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibrary,
try try
{ {
MODULE* m = FootprintLibs()->FootprintLoad( aLibrary, footprintName ); FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
MODULE* m = tbl->FootprintLoad( aLibrary, footprintName );
if( m ) if( m )
{ {
...@@ -653,7 +657,7 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibrary, ...@@ -653,7 +657,7 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibrary,
// this always overwrites any existing footprint, but should yell on its // this always overwrites any existing footprint, but should yell on its
// own if the library or footprint is not writable. // own if the library or footprint is not writable.
FootprintLibs()->FootprintSave( aLibrary, aModule ); tbl->FootprintSave( aLibrary, aModule );
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
...@@ -738,7 +742,7 @@ wxString PCB_BASE_FRAME::SelectLibrary( const wxString& aNicknameExisting ) ...@@ -738,7 +742,7 @@ wxString PCB_BASE_FRAME::SelectLibrary( const wxString& aNicknameExisting )
headers.Add( _( "Nickname" ) ); headers.Add( _( "Nickname" ) );
headers.Add( _( "Description" ) ); headers.Add( _( "Description" ) );
FP_LIB_TABLE* fptbl = FootprintLibs(); FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
std::vector< wxArrayString > itemsToDisplay; std::vector< wxArrayString > itemsToDisplay;
std::vector< wxString > nicknames = fptbl->GetLogicalLibs(); std::vector< wxString > nicknames = fptbl->GetLogicalLibs();
......
...@@ -315,7 +315,7 @@ MODULE* PCB_BASE_FRAME::LoadFootprint( const FPID& aFootprintId ) ...@@ -315,7 +315,7 @@ MODULE* PCB_BASE_FRAME::LoadFootprint( const FPID& aFootprintId )
MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId ) MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId )
throw( IO_ERROR, PARSE_ERROR ) throw( IO_ERROR, PARSE_ERROR )
{ {
FP_LIB_TABLE* fptbl = FootprintLibs(); FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
wxCHECK_MSG( fptbl, NULL, wxT( "Cannot look up FPID in NULL FP_LIB_TABLE." ) ); wxCHECK_MSG( fptbl, NULL, wxT( "Cannot look up FPID in NULL FP_LIB_TABLE." ) );
......
...@@ -491,7 +491,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -491,7 +491,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
Clear_Pcb( true ); Clear_Pcb( true );
SetCrossHairPosition( wxPoint( 0, 0 ) ); SetCrossHairPosition( wxPoint( 0, 0 ) );
LoadModuleFromLibrary( getLibNickName(), FootprintLibs(), true ); LoadModuleFromLibrary( getLibNickName(), Prj().PcbFootprintLibs(), true );
redraw = true; redraw = true;
if( GetBoard()->m_Modules ) if( GetBoard()->m_Modules )
......
...@@ -274,7 +274,7 @@ wxString FOOTPRINT_EDIT_FRAME::getLibPath() ...@@ -274,7 +274,7 @@ wxString FOOTPRINT_EDIT_FRAME::getLibPath()
{ {
const wxString& nickname = getLibNickName(); const wxString& nickname = getLibNickName();
const FP_LIB_TABLE::ROW* row = FootprintLibs()->FindRow( nickname ); const FP_LIB_TABLE::ROW* row = Prj().PcbFootprintLibs()->FindRow( nickname );
return row->GetFullURI( true ); return row->GetFullURI( true );
} }
...@@ -481,7 +481,7 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent ...@@ -481,7 +481,7 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent
void FOOTPRINT_EDIT_FRAME::OnUpdateSelectCurrentLib( wxUpdateUIEvent& aEvent ) void FOOTPRINT_EDIT_FRAME::OnUpdateSelectCurrentLib( wxUpdateUIEvent& aEvent )
{ {
FP_LIB_TABLE* fptbl = FootprintLibs(); FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
aEvent.Enable( fptbl && !fptbl->IsEmpty() ); aEvent.Enable( fptbl && !fptbl->IsEmpty() );
} }
...@@ -621,7 +621,7 @@ void FOOTPRINT_EDIT_FRAME::updateTitle() ...@@ -621,7 +621,7 @@ void FOOTPRINT_EDIT_FRAME::updateTitle()
{ {
try try
{ {
bool writable = FootprintLibs()->IsFootprintLibWritable( nickname ); bool writable = Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname );
// no exception was thrown, this means libPath is valid, but it may be read only. // no exception was thrown, this means libPath is valid, but it may be read only.
title = _( "Module Editor (active library: " ) + nickname + wxT( ")" ); title = _( "Module Editor (active library: " ) + nickname + wxT( ")" );
......
...@@ -309,7 +309,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList() ...@@ -309,7 +309,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
{ {
m_libList->Clear(); m_libList->Clear();
std::vector< wxString > nicknames = FootprintLibs()->GetLogicalLibs(); std::vector< wxString > nicknames = Prj().PcbFootprintLibs()->GetLogicalLibs();
for( unsigned ii = 0; ii < nicknames.size(); ii++ ) for( unsigned ii = 0; ii < nicknames.size(); ii++ )
m_libList->Append( nicknames[ii] ); m_libList->Append( nicknames[ii] );
...@@ -348,7 +348,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList() ...@@ -348,7 +348,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList()
FOOTPRINT_LIST fp_info_list; FOOTPRINT_LIST fp_info_list;
fp_info_list.ReadFootprintFiles( FootprintLibs(), &m_libraryName ); fp_info_list.ReadFootprintFiles( Prj().PcbFootprintLibs(), &m_libraryName );
if( fp_info_list.GetErrorCount() ) if( fp_info_list.GetErrorCount() )
{ {
...@@ -509,7 +509,7 @@ void FOOTPRINT_VIEWER_FRAME::OnActivate( wxActivateEvent& event ) ...@@ -509,7 +509,7 @@ 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:
std::vector< wxString > libNicknames = FootprintLibs()->GetLogicalLibs(); std::vector< wxString > libNicknames = Prj().PcbFootprintLibs()->GetLogicalLibs();
if( libNicknames.size() == m_libList->GetCount() ) if( libNicknames.size() == m_libList->GetCount() )
{ {
...@@ -742,13 +742,16 @@ void FOOTPRINT_VIEWER_FRAME::SelectCurrentLibrary( wxCommandEvent& event ) ...@@ -742,13 +742,16 @@ void FOOTPRINT_VIEWER_FRAME::SelectCurrentLibrary( wxCommandEvent& event )
void FOOTPRINT_VIEWER_FRAME::SelectCurrentFootprint( wxCommandEvent& event ) void FOOTPRINT_VIEWER_FRAME::SelectCurrentFootprint( wxCommandEvent& event )
{ {
#if 0 // cannot remember why this is here
// The PCB_EDIT_FRAME may not be the FOOTPRINT_VIEW_FRAME's parent, // The PCB_EDIT_FRAME may not be the FOOTPRINT_VIEW_FRAME's parent,
// so use Kiway().Player() to fetch. // so use Kiway().Player() to fetch.
PCB_EDIT_FRAME* parent = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, true ); PCB_EDIT_FRAME* parent = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, true );
(void*) parent;
#endif
wxString libname = m_libraryName + wxT( "." ) + LegacyFootprintLibPathExtension; wxString libname = m_libraryName + wxT( "." ) + LegacyFootprintLibPathExtension;
MODULE* oldmodule = GetBoard()->m_Modules; MODULE* oldmodule = GetBoard()->m_Modules;
MODULE* module = LoadModuleFromLibrary( libname, parent->FootprintLibs(), false ); MODULE* module = LoadModuleFromLibrary( libname, Prj().PcbFootprintLibs(), false );
if( module ) if( module )
{ {
...@@ -808,7 +811,7 @@ void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( int aMode ) ...@@ -808,7 +811,7 @@ void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( int aMode )
// Delete the current footprint // Delete the current footprint
GetBoard()->m_Modules.DeleteAll(); GetBoard()->m_Modules.DeleteAll();
MODULE* footprint = FootprintLibs()->FootprintLoad( m_libraryName, m_footprintName ); MODULE* footprint = Prj().PcbFootprintLibs()->FootprintLoad( m_libraryName, m_footprintName );
if( footprint ) if( footprint )
GetBoard()->Add( footprint, ADD_APPEND ); GetBoard()->Add( footprint, ADD_APPEND );
......
...@@ -172,7 +172,7 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter ) ...@@ -172,7 +172,7 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
MODULE* module = 0; MODULE* module = 0;
MODULE* fpOnBoard; MODULE* fpOnBoard;
if( aNetlist.IsEmpty() || FootprintLibs()->IsEmpty() ) if( aNetlist.IsEmpty() || Prj().PcbFootprintLibs()->IsEmpty() )
return; return;
aNetlist.SortByFPID(); aNetlist.SortByFPID();
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <class_board.h> #include <class_board.h>
#include <class_zone.h> #include <class_zone.h>
#include <class_pcb_text.h> #include <class_pcb_text.h>
#include <project.h>
#include <pcbnew.h> #include <pcbnew.h>
#include <pcbnew_id.h> #include <pcbnew_id.h>
...@@ -355,7 +356,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) ...@@ -355,7 +356,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
{ {
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
DrawStruct = (BOARD_ITEM*) LoadModuleFromLibrary( DrawStruct = (BOARD_ITEM*) LoadModuleFromLibrary(
wxEmptyString, FootprintLibs(), true, aDC ); wxEmptyString, Prj().PcbFootprintLibs(), true, aDC );
SetCurItem( DrawStruct ); SetCurItem( DrawStruct );
......
...@@ -96,7 +96,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) ...@@ -96,7 +96,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
case ID_PCB_LIB_TABLE_EDIT: case ID_PCB_LIB_TABLE_EDIT:
{ {
bool tableChanged = false; bool tableChanged = false;
int r = InvokePcbLibTableEditor( this, &GFootprintTable, FootprintLibs() ); int r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() );
if( r & 1 ) if( r & 1 )
{ {
...@@ -126,7 +126,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) ...@@ -126,7 +126,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
try try
{ {
FootprintLibs()->Save( tblName ); Prj().PcbFootprintLibs()->Save( tblName );
tableChanged = true; tableChanged = true;
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
...@@ -259,18 +259,7 @@ bool PCB_EDIT_FRAME::LoadProjectSettings( const wxString& aProjectFileName ) ...@@ -259,18 +259,7 @@ bool PCB_EDIT_FRAME::LoadProjectSettings( const wxString& aProjectFileName )
SetElementVisibility( RATSNEST_VISIBLE, showRats ); SetElementVisibility( RATSNEST_VISIBLE, showRats );
#endif #endif
wxString projectFpLibTableFileName = Prj().FootprintLibTblName(); Prj().ElemClear( PROJECT::ELEM_FPTBL ); // Force it to be reloaded on demand.
FootprintLibs()->Clear();
try
{
FootprintLibs()->Load( projectFpLibTableFileName );
}
catch( const IO_ERROR& ioe )
{
DisplayError( this, ioe.errorText );
}
// Load the page layout decr file, from the filename stored in // Load the page layout decr file, from the filename stored in
// BASE_SCREEN::m_PageLayoutDescrFileName, read in config project file // BASE_SCREEN::m_PageLayoutDescrFileName, read in config project file
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <class_board.h> #include <class_board.h>
#include <class_module.h> #include <class_module.h>
#include <project.h>
#include <pcbnew.h> #include <pcbnew.h>
#include <dialog_exchange_modules_base.h> #include <dialog_exchange_modules_base.h>
...@@ -492,7 +493,7 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event ) ...@@ -492,7 +493,7 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event )
wxString newname; wxString newname;
newname = m_parent->SelectFootprint( m_parent, wxEmptyString, wxEmptyString, wxEmptyString, newname = m_parent->SelectFootprint( m_parent, wxEmptyString, wxEmptyString, wxEmptyString,
m_parent->FootprintLibs() ); Prj().PcbFootprintLibs() );
if( newname != wxEmptyString ) if( newname != wxEmptyString )
m_NewModule->SetValue( newname ); m_NewModule->SetValue( newname );
......
...@@ -38,7 +38,7 @@ STABLE=tag:pre-kiway # currently the best mix of features and stabilty ...@@ -38,7 +38,7 @@ STABLE=tag:pre-kiway # currently the best mix of features and stabilty
TESTING=last:1 # the most recent TESTING=last:1 # the most recent
# Set this to STABLE or TESTING or other know revision number: # Set this to STABLE or TESTING or other known revision number:
REVISION=$STABLE REVISION=$STABLE
# For info on revision syntax: # For info on revision syntax:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment