simplify and fix the technique used to get the project fp-lib-table

This commit is contained in:
Dick Hollenbeck 2014-03-20 20:24:35 -05:00
parent 34dda6a1b0
commit a7f1939203
11 changed files with 160 additions and 153 deletions

View File

@ -24,6 +24,7 @@
*/ */
#include <fctsys.h>
#include <wx/config.h> // wxExpandEnvVars() #include <wx/config.h> // wxExpandEnvVars()
#include <wx/filename.h> #include <wx/filename.h>
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
@ -45,19 +46,6 @@
using namespace FP_LIB_TABLE_T; using namespace FP_LIB_TABLE_T;
/**
* Definition for enabling and disabling footprint library trace output. See the
* wxWidgets documentation on using the WXTRACE environment variable.
*/
static const wxString traceFpLibTable( wxT( "KicadFpLibTable" ) );
/// The footprint library table name used when no project file is passed to Pcbnew or CvPcb.
/// This is used temporarily to store the project specific library table until the project
/// file being edited is saved. It is then moved to the file fp-lib-table in the folder where
/// the project file is saved.
static const wxChar templateProjectFileName[] = wxT( "prj-fp-lib-table" );
static const wxChar global_tbl_name[] = wxT( "fp-lib-table" ); static const wxChar global_tbl_name[] = wxT( "fp-lib-table" );
@ -408,19 +396,6 @@ void FP_LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
); );
} }
void FP_LIB_TABLE::Save( const wxFileName& aPath ) const throw( IO_ERROR )
{
wxFileName fn = GetProjectTableFileName( aPath.GetFullPath() );
wxLogTrace( traceFpLibTable, wxT( "Saving footprint libary table <%s>." ),
GetChars( fn.GetFullPath() ) );
FILE_OUTPUTFORMATTER sf( fn.GetFullPath() );
Format( &sf, 0 );
}
#define OPT_SEP '|' ///< options separator character #define OPT_SEP '|' ///< options separator character
PROPERTIES* FP_LIB_TABLE::ParseOptions( const std::string& aOptionsList ) PROPERTIES* FP_LIB_TABLE::ParseOptions( const std::string& aOptionsList )
@ -842,34 +817,6 @@ const wxString FP_LIB_TABLE::GlobalPathEnvVariableName()
} }
wxString FP_LIB_TABLE::GetProjectTableFileName( const wxString& aProjectFullName )
{
wxFileName fn = aProjectFullName;
wxString path = fn.GetPath();
// Set $KICAD_PRJ_PATH to user's configuration path if aPath is not set or does not exist.
if( !fn.IsOk() || !wxFileName::IsDirReadable( path ) )
{
fn.AssignDir( wxStandardPaths::Get().GetUserConfigDir() );
#if defined( __WINDOWS__ )
fn.AppendDir( wxT( "kicad" ) );
#endif
fn.SetName( templateProjectFileName );
}
else
{
fn.SetName( global_tbl_name );
}
wxLogTrace( traceFpLibTable, wxT( "Project footprint lib table file '%s'." ),
GetChars( fn.GetFullPath() ) );
return fn.GetFullPath();
}
bool FP_LIB_TABLE::LoadGlobalTable( FP_LIB_TABLE& aTable ) throw (IO_ERROR, PARSE_ERROR ) bool FP_LIB_TABLE::LoadGlobalTable( FP_LIB_TABLE& aTable ) throw (IO_ERROR, PARSE_ERROR )
{ {
bool tableExists = true; bool tableExists = true;
@ -911,39 +858,38 @@ wxString FP_LIB_TABLE::GetGlobalTableFileName()
{ {
wxFileName fn; wxFileName fn;
// This is possibly problematic with an uncertain wxApp title, which is now
// the case. We'll need a better technique soon.
fn.SetPath( wxStandardPaths::Get().GetUserConfigDir() ); fn.SetPath( wxStandardPaths::Get().GetUserConfigDir() );
#if defined( __WINDOWS__ ) #if defined( __WINDOWS__ )
fn.AppendDir( wxT( "kicad" ) ); fn.AppendDir( wxT( "kicad" ) );
#endif #endif
fn.SetName( GetFileName() ); fn.SetName( global_tbl_name );
wxLogTrace( traceFpLibTable, wxT( "Global footprint library table file '%s'." ),
GetChars( fn.GetFullPath() ) );
return fn.GetFullPath(); return fn.GetFullPath();
} }
// prefer wxString filename so it can be seen in a debugger easier than wxFileName.
const wxString FP_LIB_TABLE::GetFileName() void FP_LIB_TABLE::Load( const wxString& aFileName )
{
return global_tbl_name;
}
void FP_LIB_TABLE::Load( const wxFileName& aFileName, FP_LIB_TABLE* aFallBackTable )
throw( IO_ERROR ) throw( IO_ERROR )
{ {
fallBack = aFallBackTable;
// Empty footprint library tables are valid. // Empty footprint library tables are valid.
if( aFileName.IsOk() && aFileName.FileExists() ) if( wxFileName::IsFileReadable( aFileName ) )
{ {
FILE_LINE_READER reader( aFileName.GetFullPath() ); FILE_LINE_READER reader( aFileName );
FP_LIB_TABLE_LEXER lexer( &reader ); FP_LIB_TABLE_LEXER lexer( &reader );
Parse( &lexer ); Parse( &lexer );
} }
} }
void FP_LIB_TABLE::Save( const wxString& aFileName ) const throw( IO_ERROR )
{
FILE_OUTPUTFORMATTER sf( aFileName );
Format( &sf, 0 );
}

View File

@ -82,6 +82,49 @@ const wxString PROJECT::GetProjectFullName() const
} }
const wxString PROJECT::FootprintLibTblName() const
{
wxFileName fn = GetProjectFullName();
wxString path = fn.GetPath();
// DBG(printf( "path:'%s' fn:'%s'\n", TO_UTF8(path), TO_UTF8(fn.GetFullPath()) );)
// if there's no path to the project name, or the name as a whole is bogus or its not
// write-able then use a template file.
if( !fn.GetDirCount() || !fn.IsOk() || !wxFileName::IsDirWritable( path ) )
{
// return a template filename now.
// this next line is likely a problem now, since it relies on an
// application title which is no longer constant or known. This next line needs
// to be re-thought out.
fn.AssignDir( wxStandardPaths::Get().GetUserConfigDir() );
#if defined( __WINDOWS__ )
fn.AppendDir( wxT( "kicad" ) );
#endif
/*
The footprint library table name used when no project file is passed
to Pcbnew or CvPcb. This is used temporarily to store the project
specific library table until the project file being edited is saved.
It is then moved to the file fp-lib-table in the folder where the
project file is saved.
*/
fn.SetName( wxT( "prj-fp-lib-table" ) );
}
else // normal path.
{
fn.SetName( wxT( "fp-lib-table" ) );
}
fn.ClearExt();
return fn.GetFullPath();
}
RETAINED_PATH& PROJECT::RPath( RETPATH_T aIndex ) RETAINED_PATH& PROJECT::RPath( RETPATH_T aIndex )
{ {
unsigned ndx = unsigned( aIndex ); unsigned ndx = unsigned( aIndex );

View File

@ -93,14 +93,11 @@ void CVPCB_MAINFRAME::LoadProjectFile( const wxString& aFileName )
prj.SetProjectFullName( fn.GetFullPath() ); prj.SetProjectFullName( fn.GetFullPath() );
*/ */
wxFileName projectFpLibTableFileName = FP_LIB_TABLE::GetProjectTableFileName( fn.GetFullPath() ); wxString projectFpLibTableFileName = prj.FootprintLibTblName();
try try
{ {
// Stack the project specific FP_LIB_TABLE overlay on top of the global table. FootprintLibs()->Load( projectFpLibTableFileName );
// ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may
// stack this way, all using the same global fallback table.
FootprintLibs()->Load( projectFpLibTableFileName, &GFootprintTable );
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {

View File

@ -210,6 +210,9 @@ FP_LIB_TABLE* CVPCB_MAINFRAME::FootprintLibs() const
if( !tbl ) 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 ); tbl = new FP_LIB_TABLE( &GFootprintTable );
prj.Elem( PROJECT::FPTBL, tbl ); prj.Elem( PROJECT::FPTBL, tbl );
} }
@ -499,46 +502,45 @@ 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, FootprintLibs() );
if( r & 1 ) if( r & 1 )
{ {
wxString fileName = FP_LIB_TABLE::GetGlobalTableFileName();
try try
{ {
FILE_OUTPUTFORMATTER sf( FP_LIB_TABLE::GetGlobalTableFileName() ); GFootprintTable.Save( fileName );
GFootprintTable.Format( &sf, 0 );
tableChanged = true; tableChanged = true;
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxString msg = wxString::Format( _( wxString msg = wxString::Format( _(
"Error occurred saving the global footprint library " "Error occurred saving the global footprint library table:\n'%s'\n%s" ),
"table:\n\n%s" ), GetChars( fileName ),
GetChars( ioe.errorText ) ); GetChars( ioe.errorText )
);
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
} }
} }
if( r & 2 ) if( r & 2 )
{ {
wxFileName fn = m_NetlistFileName; wxString fileName = Prj().FootprintLibTblName();
fn.SetName( FP_LIB_TABLE::GetFileName() );
fn.SetExt( wxEmptyString );
try try
{ {
FILE_OUTPUTFORMATTER sf( fn.GetFullPath() ); FootprintLibs()->Save( fileName );
FootprintLibs()->Format( &sf, 0 );
tableChanged = true; tableChanged = true;
} }
catch( IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxString msg; wxString msg = wxString::Format( _(
msg.Printf( _( "Error occurred saving the global footprint library " "Error occurred saving the project footprint library table:\n'%s'\n%s" ),
"table:\n\n%s" ), ioe.errorText.GetData() ); GetChars( fileName ),
GetChars( ioe.errorText )
);
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
} }
} }

View File

@ -317,25 +317,25 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName )
// Save the project specific footprint library table. // Save the project specific footprint library table.
if( !FootprintLibs()->IsEmpty( false ) ) if( !FootprintLibs()->IsEmpty( false ) )
{ {
wxFileName fpLibFileName = fn; wxString fp_lib_tbl = Prj().FootprintLibTblName();
fpLibFileName.ClearExt();
fpLibFileName.SetName( FP_LIB_TABLE::GetFileName() );
if( fpLibFileName.FileExists() if( wxFileName::FileExists( fp_lib_tbl )
&& IsOK( this, _( "A footprint library table already exists in this path.\n\nDo " && IsOK( this, _( "A footprint library table already exists in this path.\n\nDo "
"you want to overwrite it?" ) ) ) "you want to overwrite it?" ) ) )
{ {
try try
{ {
FootprintLibs()->Save( fpLibFileName ); FootprintLibs()->Save( fp_lib_tbl );
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
DisplayError( this, wxString msg = wxString::Format( _(
wxString::Format( _( "An error occurred attempting to save the " "An error occurred attempting to save the "
"footprint library table <%s>\n\n%s" ), "footprint library table '%s'\n\n%s" ),
GetChars( fpLibFileName.GetFullPath() ), GetChars( fp_lib_tbl ),
GetChars( ioe.errorText ) ) ); GetChars( ioe.errorText )
);
DisplayError( this, msg );
} }
} }
} }

View File

@ -357,8 +357,6 @@ public:
*/ */
void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR ); void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR );
void Save( const wxFileName& aPath ) const throw( IO_ERROR );
/** /**
* Function GetLogicalLibs * Function GetLogicalLibs
* returns the logical library names, all of them that are pertinent to * returns the logical library names, all of them that are pertinent to
@ -544,11 +542,13 @@ public:
*/ */
static wxString GetGlobalTableFileName(); static wxString GetGlobalTableFileName();
#if 0
/** /**
* Function GetFileName * Function GetFileName
* @return the footprint library file name. * @return the footprint library file name.
*/ */
static const wxString GetFileName(); static const wxString GetFileName();
#endif
/** /**
* Function GlobalPathEnvVarVariableName * Function GlobalPathEnvVarVariableName
@ -560,19 +560,24 @@ public:
*/ */
static const wxString GlobalPathEnvVariableName(); static const wxString GlobalPathEnvVariableName();
static wxString GetProjectTableFileName( const wxString& aProjectFullName );
/** /**
* Function Load * Function Load
* loads the footprint library table using the path defined in \a aFileName with * loads the footprint library table using the path defined in \a aFileName with
* \a aFallBackTable. * \a aFallBackTable.
* *
* @param aFileName contains the path and possible the file name and extension. * @param aFileName contains the full path to the s-expression file.
* @param aFallBackTable the fall back footprint library table which can be NULL. *
* @throw IO_ERROR if an error occurs attempting to load the footprint library * @throw IO_ERROR if an error occurs attempting to load the footprint library
* table. * table.
*/ */
void Load( const wxFileName& aFileName, FP_LIB_TABLE* aFallBackTable ) throw( IO_ERROR ); void Load( const wxString& aFileName ) throw( IO_ERROR );
/**
* Function Save
* writes this table to aFileName in s-expression form.
* @param aFileName is the name of the file to write to.
*/
void Save( const wxString& aFileName ) const throw( IO_ERROR );
protected: protected:

View File

@ -82,6 +82,13 @@ public:
*/ */
VTBL_ENTRY const wxString GetProjectFullName() const; VTBL_ENTRY const wxString GetProjectFullName() const;
/**
* Function FootprintLibTblName
* returns the path and filename of this project's fp-lib-table,
* i.e. the project specific one, not the global one.
*/
VTBL_ENTRY const wxString FootprintLibTblName() const;
/** /**
* Function ConfigSave * Function ConfigSave
* saves the current "project" parameters into the wxConfigBase* derivative. * saves the current "project" parameters into the wxConfigBase* derivative.

View File

@ -181,7 +181,11 @@ FP_LIB_TABLE* PCB_BASE_FRAME::FootprintLibs() const
if( !tbl ) 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 ); tbl = new FP_LIB_TABLE( &GFootprintTable );
prj.Elem( PROJECT::FPTBL, tbl ); prj.Elem( PROJECT::FPTBL, tbl );
} }

View File

@ -605,25 +605,25 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
// Save the project specific footprint library table. // Save the project specific footprint library table.
if( !FootprintLibs()->IsEmpty( false ) ) if( !FootprintLibs()->IsEmpty( false ) )
{ {
wxFileName fn = pcbFileName; wxString fp_lib_tbl = Prj().FootprintLibTblName();
fn.ClearExt();
fn.SetName( FP_LIB_TABLE::GetFileName() );
if( fn.FileExists() if( wxFileName::FileExists( fp_lib_tbl )
&& IsOK( this, _( "A footprint library table already exists in this path.\n\nDo " && IsOK( this, _( "A footprint library table already exists in this path.\n\nDo "
"you want to overwrite it?" ) ) ) "you want to overwrite it?" ) ) )
{ {
try try
{ {
FootprintLibs()->Save( fn ); FootprintLibs()->Save( fp_lib_tbl );
} }
catch( IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
DisplayError( this, wxString msg = wxString::Format( _(
wxString::Format( _( "An error occurred attempting to save the " "An error occurred attempting to save the "
"footprint library table '%s'\n\n%s" ), "footprint library table '%s'\n\n%s" ),
GetChars( fn.GetFullPath() ), GetChars( fp_lib_tbl ),
GetChars( ioe.errorText ) ) ); GetChars( ioe.errorText )
);
DisplayError( this, msg );
} }
} }
} }

View File

@ -478,6 +478,9 @@ void IFACE::OnKifaceEnd()
// wxPython will do its own cleanup as part of that process. // wxPython will do its own cleanup as part of that process.
// This should only be called if python was setup correctly. // This should only be called if python was setup correctly.
/* bring this in, but without a linker error:
pcbnewFinishPythonScripting(); pcbnewFinishPythonScripting();
*/
#endif #endif
} }

View File

@ -82,13 +82,13 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
case ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR: case ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR:
m_show_microwave_tools = ! m_show_microwave_tools; m_show_microwave_tools = ! m_show_microwave_tools;
m_auimgr.GetPane( wxT( "m_microWaveToolBar" ) ).Show( m_show_microwave_tools ); m_auimgr.GetPane( wxT( "m_microWaveToolBar" ) ).Show( m_show_microwave_tools );
m_auimgr.Update(); m_auimgr.Update();
GetMenuBar()->SetLabel( ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR, GetMenuBar()->SetLabel( ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR,
m_show_microwave_tools ? m_show_microwave_tools ?
_( "Hide Microwave Toolbar" ): _( "Show Microwave Toolbar" )); _( "Hide Microwave Toolbar" ): _( "Show Microwave Toolbar" ));
break; break;
case ID_PCB_LAYERS_SETUP: case ID_PCB_LAYERS_SETUP:
InstallDialogLayerSetup(); InstallDialogLayerSetup();
@ -108,7 +108,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
GFootprintTable.Format( &sf, 0 ); GFootprintTable.Format( &sf, 0 );
tableChanged = true; tableChanged = true;
} }
catch( IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxString msg = wxString::Format( _( wxString msg = wxString::Format( _(
"Error occurred saving the global footprint library " "Error occurred saving the global footprint library "
@ -123,18 +123,20 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
// is kept in memory and created in the path when the new board is saved. // is kept in memory and created in the path when the new board is saved.
if( (r & 2) && !GetBoard()->GetFileName().IsEmpty() ) if( (r & 2) && !GetBoard()->GetFileName().IsEmpty() )
{ {
wxFileName fn = GetBoard()->GetFileName(); wxString tblName = Prj().FootprintLibTblName();
try try
{ {
FootprintLibs()->Save( fn ); FootprintLibs()->Save( tblName );
tableChanged = true; tableChanged = true;
} }
catch( IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxString msg; wxString msg = wxString::Format( _(
msg.Printf( _( "Error occurred saving project specific footprint library " "Error occurred saving project specific footprint library "
"table:\n\n%s" ), ioe.errorText.GetData() ); "table:\n\n%s" ),
GetChars( ioe.errorText )
);
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
} }
} }
@ -171,27 +173,27 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
break; break;
case ID_CONFIG_READ: case ID_CONFIG_READ:
{
fn = GetBoard()->GetFileName();
fn.SetExt( ProjectFileExtension );
wxFileDialog dlg( this, _( "Read Project File" ), fn.GetPath(),
fn.GetFullName(), ProjectFileWildcard,
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
if( dlg.ShowModal() == wxID_CANCEL )
break;
if( !wxFileExists( dlg.GetPath() ) )
{ {
wxString msg; fn = GetBoard()->GetFileName();
msg.Printf( _( "File %s not found" ), GetChars( dlg.GetPath() ) ); fn.SetExt( ProjectFileExtension );
DisplayError( this, msg );
break;
}
LoadProjectSettings( dlg.GetPath() ); wxFileDialog dlg( this, _( "Read Project File" ), fn.GetPath(),
} fn.GetFullName(), ProjectFileWildcard,
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
if( dlg.ShowModal() == wxID_CANCEL )
break;
if( !wxFileExists( dlg.GetPath() ) )
{
wxString msg;
msg.Printf( _( "File %s not found" ), GetChars( dlg.GetPath() ) );
DisplayError( this, msg );
break;
}
LoadProjectSettings( dlg.GetPath() );
}
break; break;
// Hotkey IDs // Hotkey IDs
@ -258,17 +260,15 @@ bool PCB_EDIT_FRAME::LoadProjectSettings( const wxString& aProjectFileName )
SetElementVisibility( RATSNEST_VISIBLE, showRats ); SetElementVisibility( RATSNEST_VISIBLE, showRats );
#endif #endif
fn = GetBoard()->GetFileName(); wxString projectFpLibTableFileName = Prj().FootprintLibTblName();
wxFileName projectFpLibTableFileName = FP_LIB_TABLE::GetProjectTableFileName( fn.GetFullPath() );
FootprintLibs()->Clear(); FootprintLibs()->Clear();
try try
{ {
FootprintLibs()->Load( projectFpLibTableFileName, &GFootprintTable ); FootprintLibs()->Load( projectFpLibTableFileName );
} }
catch( IO_ERROR ioe ) catch( const IO_ERROR& ioe )
{ {
DisplayError( this, ioe.errorText ); DisplayError( this, ioe.errorText );
} }