diff --git a/common/fp_lib_table.cpp b/common/fp_lib_table.cpp
index 0615293b0e..561b217c72 100644
--- a/common/fp_lib_table.cpp
+++ b/common/fp_lib_table.cpp
@@ -42,18 +42,23 @@
#include
#include
+#define OPT_SEP '|' ///< options separator character
+
using namespace FP_LIB_TABLE_T;
static const wxChar global_tbl_name[] = wxT( "fp-lib-table" );
-void FP_LIB_TABLE_ROW::SetType( const wxString& aType )
+LIB_TABLE_ROW* new_clone( const LIB_TABLE_ROW& aRow )
{
- type = IO_MGR::EnumFromStr( aType );
+ return aRow.clone();
+}
- if( IO_MGR::PCB_FILE_T( -1 ) == type )
- type = IO_MGR::KICAD;
+
+void LIB_TABLE_ROW::setProperties( PROPERTIES* aProperties )
+{
+ properties.reset( aProperties );
}
@@ -75,49 +80,11 @@ const wxString LIB_TABLE_ROW::GetFullURI( bool aSubstituted ) const
return uri_expanded;
#else // late expansion
- return FP_LIB_TABLE::ExpandSubstitutions( uri_user );
+ return LIB_TABLE::ExpandSubstitutions( uri_user );
#endif
}
- else
- return uri_user;
-}
-
-LIB_TABLE_ROW::LIB_TABLE_ROW( const LIB_TABLE_ROW& a ) :
- nickName( a.nickName ),
- options( a.options ),
- description( a.description ),
- properties( 0 )
-{
- // may call ExpandSubstitutions()
- SetFullURI( a.uri_user );
-
- if( a.properties )
- properties = new PROPERTIES( *a.properties );
-}
-
-
-LIB_TABLE_ROW& LIB_TABLE_ROW::operator=( const LIB_TABLE_ROW& r )
-{
- nickName = r.nickName;
- options = r.options;
- description = r.description;
- properties = r.properties ? new PROPERTIES( *r.properties ) : NULL;
-
- // may call ExpandSubstitutions()
- SetFullURI( r.uri_user );
-
- return *this;
-}
-
-
-bool LIB_TABLE_ROW::operator==( const LIB_TABLE_ROW& r ) const
-{
- return nickName == r.nickName
- && uri_user == r.uri_user
- && options == r.options
- && description == r.description
- ;
+ return uri_user;
}
@@ -134,31 +101,113 @@ void LIB_TABLE_ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
}
+void LIB_TABLE_ROW::Parse( std::unique_ptr< LIB_TABLE_ROW >& aRow, FP_LIB_TABLE_LEXER* in )
+ throw( IO_ERROR, PARSE_ERROR )
+{
+ /*
+ * (lib (name NICKNAME)(descr DESCRIPTION)(type TYPE)(full_uri FULL_URI)(options OPTIONS))
+ *
+ * Elements after (name) are order independent.
+ */
+
+ T tok = in->NextTok();
+
+ if( tok != T_lib )
+ in->Expecting( T_lib );
+
+ // (name NICKNAME)
+ in->NeedLEFT();
+
+ if( ( tok = in->NextTok() ) != T_name )
+ in->Expecting( T_name );
+
+ in->NeedSYMBOLorNUMBER();
+
+ aRow->SetNickName( in->FromUTF8() );
+
+ in->NeedRIGHT();
+
+ // After (name), remaining (lib) elements are order independent, and in
+ // some cases optional.
+ bool sawType = false;
+ bool sawOpts = false;
+ bool sawDesc = false;
+ bool sawUri = false;
+
+ while( ( tok = in->NextTok() ) != T_RIGHT )
+ {
+ if( tok == T_EOF )
+ in->Unexpected( T_EOF );
+
+ if( tok != T_LEFT )
+ in->Expecting( T_LEFT );
+
+ tok = in->NeedSYMBOLorNUMBER();
+
+ switch( tok )
+ {
+ case T_uri:
+ if( sawUri )
+ in->Duplicate( tok );
+ sawUri = true;
+ in->NeedSYMBOLorNUMBER();
+ aRow->SetFullURI( in->FromUTF8() );
+ break;
+
+ case T_type:
+ if( sawType )
+ in->Duplicate( tok );
+ sawType = true;
+ in->NeedSYMBOLorNUMBER();
+ aRow->SetType( in->FromUTF8() );
+ break;
+
+ case T_options:
+ if( sawOpts )
+ in->Duplicate( tok );
+ sawOpts = true;
+ in->NeedSYMBOLorNUMBER();
+ aRow->SetOptions( in->FromUTF8() );
+ break;
+
+ case T_descr:
+ if( sawDesc )
+ in->Duplicate( tok );
+ sawDesc = true;
+ in->NeedSYMBOLorNUMBER();
+ aRow->SetDescr( in->FromUTF8() );
+ break;
+
+ default:
+ in->Unexpected( tok );
+ }
+
+ in->NeedRIGHT();
+ }
+
+ if( !sawType )
+ in->Expecting( T_type );
+
+ if( !sawUri )
+ in->Expecting( T_uri );
+}
+
+
+bool LIB_TABLE_ROW::operator==( const LIB_TABLE_ROW& r ) const
+{
+ return nickName == r.nickName
+ && uri_user == r.uri_user
+ && options == r.options
+ && description == r.description;
+}
+
+
void LIB_TABLE_ROW::SetOptions( const wxString& aOptions )
{
options = aOptions;
// set PROPERTIES* from options
- setProperties( FP_LIB_TABLE::ParseOptions( TO_UTF8( aOptions ) ) );
-}
-
-
-FP_LIB_TABLE_ROW::FP_LIB_TABLE_ROW( const FP_LIB_TABLE_ROW& aRow ) :
- LIB_TABLE_ROW( aRow ),
- type( aRow.type )
-{
-}
-
-
-FP_LIB_TABLE_ROW& FP_LIB_TABLE_ROW::operator=( const FP_LIB_TABLE_ROW& aRow )
-{
- LIB_TABLE_ROW::operator = ( aRow );
- type = aRow.type;
-
- // Do not copy the PLUGIN, it is lazily created. Delete any existing destination plugin.
- setPlugin( NULL );
-
- return *this;
+ setProperties( LIB_TABLE::ParseOptions( TO_UTF8( aOptions ) ) );
}
@@ -168,7 +217,16 @@ bool FP_LIB_TABLE_ROW::operator==( const FP_LIB_TABLE_ROW& aRow ) const
}
-FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) :
+void FP_LIB_TABLE_ROW::SetType( const wxString& aType )
+{
+ type = IO_MGR::EnumFromStr( aType );
+
+ if( IO_MGR::PCB_FILE_T( -1 ) == type )
+ type = IO_MGR::KICAD;
+}
+
+
+LIB_TABLE::LIB_TABLE( LIB_TABLE* aFallBackTable ) :
fallBack( aFallBackTable )
{
// not copying fall back, simply search aFallBackTable separately
@@ -176,12 +234,406 @@ FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) :
}
-FP_LIB_TABLE::~FP_LIB_TABLE()
+LIB_TABLE::~LIB_TABLE()
{
// *fallBack is not owned here.
}
+bool LIB_TABLE::IsEmpty( bool aIncludeFallback )
+{
+ if( !aIncludeFallback || !fallBack )
+ return rows.empty();
+
+ return rows.empty() && fallBack->IsEmpty( true );
+}
+
+
+const wxString LIB_TABLE::GetDescription( const wxString& aNickname )
+{
+ // use "no exception" form of find row:
+ const LIB_TABLE_ROW* row = findRow( aNickname );
+
+ if( row )
+ return row->GetDescr();
+ else
+ return wxEmptyString;
+}
+
+
+LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName ) const
+{
+ LIB_TABLE* cur = (LIB_TABLE*) this;
+
+ do
+ {
+ cur->ensureIndex();
+
+ INDEX_CITER it = cur->nickIndex.find( aNickName );
+
+ if( it != cur->nickIndex.end() )
+ {
+ return &cur->rows[it->second]; // found
+ }
+
+ // not found, search fall back table(s), if any
+ } while( ( cur = cur->fallBack ) != 0 );
+
+ return NULL; // not found
+}
+
+
+const LIB_TABLE_ROW* LIB_TABLE::FindRowByURI( const wxString& aURI )
+{
+ LIB_TABLE* cur = this;
+
+ do
+ {
+ cur->ensureIndex();
+
+ for( unsigned i = 0; i < cur->rows.size(); i++ )
+ {
+ wxString uri = cur->rows[i].GetFullURI( true );
+
+ if( wxFileName::GetPathSeparator() == wxChar( '\\' ) && uri.Find( wxChar( '/' ) ) >= 0 )
+ uri.Replace( "/", "\\" );
+
+ if( (wxFileName::IsCaseSensitive() && uri == aURI)
+ || (!wxFileName::IsCaseSensitive() && uri.Upper() == aURI.Upper() ) )
+ {
+ return &cur->rows[i]; // found
+ }
+ }
+
+ // not found, search fall back table(s), if any
+ } while( ( cur = cur->fallBack ) != 0 );
+
+ return NULL; // not found
+}
+
+
+std::vector LIB_TABLE::GetLogicalLibs()
+{
+ // Only return unique logical library names. Use std::set::insert() to
+ // quietly reject any duplicates, which can happen when encountering a duplicate
+ // nickname from one of the fall back table(s).
+
+ std::set< wxString > unique;
+ std::vector< wxString > ret;
+ const LIB_TABLE* cur = this;
+
+ do
+ {
+ for( LIB_TABLE_ROWS_CITER it = cur->rows.begin(); it!=cur->rows.end(); ++it )
+ {
+ unique.insert( it->GetNickName() );
+ }
+
+ } while( ( cur = cur->fallBack ) != 0 );
+
+ ret.reserve( unique.size() );
+
+ // return a sorted, unique set of nicknames in a std::vector to caller
+ for( std::set< wxString >::const_iterator it = unique.begin(); it!=unique.end(); ++it )
+ {
+ ret.push_back( *it );
+ }
+
+ return ret;
+}
+
+
+bool LIB_TABLE::InsertRow( LIB_TABLE_ROW* aRow, bool doReplace )
+{
+ ensureIndex();
+
+ INDEX_CITER it = nickIndex.find( aRow->GetNickName() );
+
+ if( it == nickIndex.end() )
+ {
+ rows.push_back( aRow );
+ nickIndex.insert( INDEX_VALUE( aRow->GetNickName(), rows.size() - 1 ) );
+ return true;
+ }
+
+ if( doReplace )
+ {
+ rows.replace( it->second, aRow );
+ return true;
+ }
+
+ return false;
+}
+
+
+void LIB_TABLE::Load( const wxString& aFileName )
+ throw( IO_ERROR )
+{
+ // It's OK if footprint library tables are missing.
+ if( wxFileName::IsFileReadable( aFileName ) )
+ {
+ FILE_LINE_READER reader( aFileName );
+ FP_LIB_TABLE_LEXER lexer( &reader );
+
+ Parse( &lexer );
+ }
+}
+
+
+void LIB_TABLE::Save( const wxString& aFileName ) const
+ throw( IO_ERROR, boost::interprocess::lock_exception )
+{
+ FILE_OUTPUTFORMATTER sf( aFileName );
+ Format( &sf, 0 );
+}
+
+
+PROPERTIES* LIB_TABLE::ParseOptions( const std::string& aOptionsList )
+{
+ if( aOptionsList.size() )
+ {
+ const char* cp = &aOptionsList[0];
+ const char* end = cp + aOptionsList.size();
+
+ PROPERTIES props;
+ std::string pair;
+
+ // Parse all name=value pairs
+ while( cp < end )
+ {
+ pair.clear();
+
+ // Skip leading white space.
+ while( cp < end && isspace( *cp ) )
+ ++cp;
+
+ // Find the end of pair/field
+ while( cp < end )
+ {
+ if( *cp == '\\' && cp + 1 < end && cp[1] == OPT_SEP )
+ {
+ ++cp; // skip the escape
+ pair += *cp++; // add the separator
+ }
+ else if( *cp == OPT_SEP )
+ {
+ ++cp; // skip the separator
+ break; // process the pair
+ }
+ else
+ pair += *cp++;
+ }
+
+ // stash the pair
+ if( pair.size() )
+ {
+ // first equals sign separates 'name' and 'value'.
+ size_t eqNdx = pair.find( '=' );
+
+ if( eqNdx != pair.npos )
+ {
+ std::string name = pair.substr( 0, eqNdx );
+ std::string value = pair.substr( eqNdx + 1 );
+ props[name] = value;
+ }
+ else
+ props[pair] = ""; // property is present, but with no value.
+ }
+ }
+
+ if( props.size() )
+ return new PROPERTIES( props );
+ }
+
+ return NULL;
+}
+
+
+UTF8 LIB_TABLE::FormatOptions( const PROPERTIES* aProperties )
+{
+ UTF8 ret;
+
+ if( aProperties )
+ {
+ for( PROPERTIES::const_iterator it = aProperties->begin(); it != aProperties->end(); ++it )
+ {
+ const std::string& name = it->first;
+
+ const UTF8& value = it->second;
+
+ if( ret.size() )
+ ret += OPT_SEP;
+
+ ret += name;
+
+ // the separation between name and value is '='
+ if( value.size() )
+ {
+ ret += '=';
+
+ for( std::string::const_iterator si = value.begin(); si != value.end(); ++si )
+ {
+ // escape any separator in the value.
+ if( *si == OPT_SEP )
+ ret += '\\';
+
+ ret += *si;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+const wxString LIB_TABLE::ExpandSubstitutions( const wxString& aString )
+{
+ return ExpandEnvVarSubstitutions( aString );
+}
+
+
+FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) :
+ LIB_TABLE( aFallBackTable )
+{
+ // not copying fall back, simply search aFallBackTable separately
+ // if "nickName not found".
+}
+
+
+void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw()
+{
+ T tok;
+
+ // This table may be nested within a larger s-expression, or not.
+ // Allow for parser of that optional containing s-epression to have looked ahead.
+ if( in->CurTok() != T_fp_lib_table )
+ {
+ in->NeedLEFT();
+ if( ( tok = in->NextTok() ) != T_fp_lib_table )
+ in->Expecting( T_fp_lib_table );
+ }
+
+ while( ( tok = in->NextTok() ) != T_RIGHT )
+ {
+ std::unique_ptr< FP_LIB_TABLE_ROW > row( new FP_LIB_TABLE_ROW );
+
+ if( tok == T_EOF )
+ in->Expecting( T_RIGHT );
+
+ if( tok != T_LEFT )
+ in->Expecting( T_LEFT );
+
+ // in case there is a "row integrity" error, tell where later.
+ int lineNum = in->CurLineNumber();
+ int offset = in->CurOffset();
+
+ if( ( tok = in->NextTok() ) != T_lib )
+ in->Expecting( T_lib );
+
+ // (name NICKNAME)
+ in->NeedLEFT();
+
+ if( ( tok = in->NextTok() ) != T_name )
+ in->Expecting( T_name );
+
+ in->NeedSYMBOLorNUMBER();
+
+ row->SetNickName( in->FromUTF8() );
+
+ in->NeedRIGHT();
+
+ // After (name), remaining (lib) elements are order independent, and in
+ // some cases optional.
+ bool sawType = false;
+ bool sawOpts = false;
+ bool sawDesc = false;
+ bool sawUri = false;
+
+ while( ( tok = in->NextTok() ) != T_RIGHT )
+ {
+ if( tok == T_EOF )
+ in->Unexpected( T_EOF );
+
+ if( tok != T_LEFT )
+ in->Expecting( T_LEFT );
+
+ tok = in->NeedSYMBOLorNUMBER();
+
+ switch( tok )
+ {
+ case T_uri:
+ if( sawUri )
+ in->Duplicate( tok );
+ sawUri = true;
+ in->NeedSYMBOLorNUMBER();
+ row->SetFullURI( in->FromUTF8() );
+ break;
+
+ case T_type:
+ if( sawType )
+ in->Duplicate( tok );
+ sawType = true;
+ in->NeedSYMBOLorNUMBER();
+ row->SetType( in->FromUTF8() );
+ break;
+
+ case T_options:
+ if( sawOpts )
+ in->Duplicate( tok );
+ sawOpts = true;
+ in->NeedSYMBOLorNUMBER();
+ row->SetOptions( in->FromUTF8() );
+ break;
+
+ case T_descr:
+ if( sawDesc )
+ in->Duplicate( tok );
+ sawDesc = true;
+ in->NeedSYMBOLorNUMBER();
+ row->SetDescr( in->FromUTF8() );
+ break;
+
+ default:
+ in->Unexpected( tok );
+ }
+
+ in->NeedRIGHT();
+ }
+
+ if( !sawType )
+ in->Expecting( T_type );
+
+ if( !sawUri )
+ in->Expecting( T_uri );
+
+ // all nickNames within this table fragment must be unique, so we do not
+ // use doReplace in InsertRow(). (However a fallBack table can have a
+ // conflicting nickName and ours will supercede that one since in
+ // FindLib() we search this table before any fall back.)
+ if( !InsertRow( row.release() ) )
+ {
+ wxString msg = wxString::Format(
+ _( "'%s' is a duplicate footprint library nickName" ),
+ GetChars( row->GetNickName() ) );
+ THROW_PARSE_ERROR( msg, in->CurSource(), in->CurLine(), lineNum, offset );
+ }
+ }
+}
+
+
+void FP_LIB_TABLE::Format( OUTPUTFORMATTER* out, int nestLevel ) const
+ throw()
+{
+ out->Print( nestLevel, "(fp_lib_table\n" );
+
+ for( LIB_TABLE_ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
+ it->Format( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+}
+
+
wxArrayString FP_LIB_TABLE::FootprintEnumerate( const wxString& aNickname )
{
const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
@@ -190,6 +642,30 @@ wxArrayString FP_LIB_TABLE::FootprintEnumerate( const wxString& aNickname )
}
+const FP_LIB_TABLE_ROW* FP_LIB_TABLE::FindRow( const wxString& aNickname )
+ throw( IO_ERROR )
+{
+ FP_LIB_TABLE_ROW* row = dynamic_cast< FP_LIB_TABLE_ROW* >( findRow( aNickname ) );
+
+ if( !row )
+ {
+ wxString msg = wxString::Format(
+ _( "fp-lib-table files contain no library with nickname '%s'" ),
+ GetChars( aNickname ) );
+
+ THROW_IO_ERROR( msg );
+ }
+
+ // We've been 'lazy' up until now, but it cannot be deferred any longer,
+ // instantiate a PLUGIN of the proper kind if it is not already in this
+ // FP_LIB_TABLE_ROW.
+ if( !row->plugin )
+ row->setPlugin( IO_MGR::PluginFind( row->type ) );
+
+ return row;
+}
+
+
MODULE* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname, const wxString& aFootprintName )
{
const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
@@ -280,423 +756,6 @@ void FP_LIB_TABLE::FootprintLibCreate( const wxString& aNickname )
}
-const wxString FP_LIB_TABLE::GetDescription( const wxString& aNickname )
-{
- // use "no exception" form of find row:
- const FP_LIB_TABLE_ROW* row = dynamic_cast< FP_LIB_TABLE_ROW* >( findRow( aNickname ) );
-
- if( row )
- return row->GetDescr();
- else
- return wxEmptyString;
-}
-
-
-void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR )
-{
- /*
- (fp_lib_table
- (lib (name NICKNAME)(descr DESCRIPTION)(type TYPE)(full_uri FULL_URI)(options OPTIONS))
- :
- )
-
- Elements after (name) are order independent.
- */
-
- T tok;
-
- // This table may be nested within a larger s-expression, or not.
- // Allow for parser of that optional containing s-epression to have looked ahead.
- if( in->CurTok() != T_fp_lib_table )
- {
- in->NeedLEFT();
- if( ( tok = in->NextTok() ) != T_fp_lib_table )
- in->Expecting( T_fp_lib_table );
- }
-
- while( ( tok = in->NextTok() ) != T_RIGHT )
- {
- FP_LIB_TABLE_ROW row; // reconstructed for each row in input stream.
-
- if( tok == T_EOF )
- in->Expecting( T_RIGHT );
-
- if( tok != T_LEFT )
- in->Expecting( T_LEFT );
-
- // in case there is a "row integrity" error, tell where later.
- int lineNum = in->CurLineNumber();
- int offset = in->CurOffset();
-
- if( ( tok = in->NextTok() ) != T_lib )
- in->Expecting( T_lib );
-
- // (name NICKNAME)
- in->NeedLEFT();
-
- if( ( tok = in->NextTok() ) != T_name )
- in->Expecting( T_name );
-
- in->NeedSYMBOLorNUMBER();
-
- row.SetNickName( in->FromUTF8() );
-
- in->NeedRIGHT();
-
- // After (name), remaining (lib) elements are order independent, and in
- // some cases optional.
- bool sawType = false;
- bool sawOpts = false;
- bool sawDesc = false;
- bool sawUri = false;
-
- while( ( tok = in->NextTok() ) != T_RIGHT )
- {
- if( tok == T_EOF )
- in->Unexpected( T_EOF );
-
- if( tok != T_LEFT )
- in->Expecting( T_LEFT );
-
- tok = in->NeedSYMBOLorNUMBER();
-
- switch( tok )
- {
- case T_uri:
- if( sawUri )
- in->Duplicate( tok );
- sawUri = true;
- in->NeedSYMBOLorNUMBER();
- row.SetFullURI( in->FromUTF8() );
- break;
-
- case T_type:
- if( sawType )
- in->Duplicate( tok );
- sawType = true;
- in->NeedSYMBOLorNUMBER();
- row.SetType( in->FromUTF8() );
- break;
-
- case T_options:
- if( sawOpts )
- in->Duplicate( tok );
- sawOpts = true;
- in->NeedSYMBOLorNUMBER();
- row.SetOptions( in->FromUTF8() );
- break;
-
- case T_descr:
- if( sawDesc )
- in->Duplicate( tok );
- sawDesc = true;
- in->NeedSYMBOLorNUMBER();
- row.SetDescr( in->FromUTF8() );
- break;
-
- default:
- in->Unexpected( tok );
- }
-
- in->NeedRIGHT();
- }
-
- if( !sawType )
- in->Expecting( T_type );
-
- if( !sawUri )
- in->Expecting( T_uri );
-
- // all nickNames within this table fragment must be unique, so we do not
- // use doReplace in InsertRow(). (However a fallBack table can have a
- // conflicting nickName and ours will supercede that one since in
- // FindLib() we search this table before any fall back.)
- if( !InsertRow( row ) )
- {
- wxString msg = wxString::Format(
- _( "'%s' is a duplicate footprint library nickName" ),
- GetChars( row.GetNickName() ) );
- THROW_PARSE_ERROR( msg, in->CurSource(), in->CurLine(), lineNum, offset );
- }
- }
-}
-
-
-void FP_LIB_TABLE::Format( OUTPUTFORMATTER* out, int nestLevel ) const
- throw( IO_ERROR, boost::interprocess::lock_exception )
-{
- out->Print( nestLevel, "(fp_lib_table\n" );
-
- for( FP_LIB_TABLE_ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
- it->Format( out, nestLevel+1 );
-
- out->Print( nestLevel, ")\n" );
-}
-
-
-#define OPT_SEP '|' ///< options separator character
-
-PROPERTIES* FP_LIB_TABLE::ParseOptions( const std::string& aOptionsList )
-{
- if( aOptionsList.size() )
- {
- const char* cp = &aOptionsList[0];
- const char* end = cp + aOptionsList.size();
-
- PROPERTIES props;
- std::string pair;
-
- // Parse all name=value pairs
- while( cp < end )
- {
- pair.clear();
-
- // Skip leading white space.
- while( cp < end && isspace( *cp ) )
- ++cp;
-
- // Find the end of pair/field
- while( cp < end )
- {
- if( *cp=='\\' && cp+1begin(); it != aProperties->end(); ++it )
- {
- const std::string& name = it->first;
-
- const UTF8& value = it->second;
-
- if( ret.size() )
- ret += OPT_SEP;
-
- ret += name;
-
- // the separation between name and value is '='
- if( value.size() )
- {
- ret += '=';
-
- for( std::string::const_iterator si = value.begin(); si != value.end(); ++si )
- {
- // escape any separator in the value.
- if( *si == OPT_SEP )
- ret += '\\';
-
- ret += *si;
- }
- }
- }
- }
-
- return ret;
-}
-
-
-std::vector FP_LIB_TABLE::GetLogicalLibs()
-{
- // Only return unique logical library names. Use std::set::insert() to
- // quietly reject any duplicates, which can happen when encountering a duplicate
- // nickname from one of the fall back table(s).
-
- std::set unique;
- std::vector ret;
- const FP_LIB_TABLE* cur = this;
-
- do
- {
- for( FP_LIB_TABLE_ROWS_CITER it = cur->rows.begin(); it!=cur->rows.end(); ++it )
- {
- unique.insert( it->GetNickName() );
- }
-
- } 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 to caller
- for( std::set::const_iterator it = unique.begin(); it!=unique.end(); ++it )
- {
- //DBG(printf( " %s\n", TO_UTF8( *it ) );)
- ret.push_back( *it );
- }
-
- return ret;
-}
-
-
-LIB_TABLE_ROW* FP_LIB_TABLE::findRow( const wxString& aNickName ) const
-{
- FP_LIB_TABLE* cur = (FP_LIB_TABLE*) this;
-
- do
- {
- cur->ensureIndex();
-
- INDEX_CITER it = cur->nickIndex.find( aNickName );
-
- if( it != cur->nickIndex.end() )
- {
- return &cur->rows[it->second]; // found
- }
-
- // not found, search fall back table(s), if any
- } while( ( cur = cur->fallBack ) != 0 );
-
- return 0; // not found
-}
-
-
-const FP_LIB_TABLE_ROW* FP_LIB_TABLE::FindRowByURI( const wxString& aURI )
-{
- FP_LIB_TABLE* cur = this;
-
- do
- {
- cur->ensureIndex();
-
- for( unsigned i = 0; i < cur->rows.size(); i++ )
- {
- wxString uri = cur->rows[i].GetFullURI( true );
-
- if( wxFileName::GetPathSeparator() == wxChar( '\\' ) && uri.Find( wxChar( '/' ) ) >= 0 )
- uri.Replace( "/", "\\" );
-
- if( (wxFileName::IsCaseSensitive() && uri == aURI)
- || (!wxFileName::IsCaseSensitive() && uri.Upper() == aURI.Upper() ) )
- {
- return &cur->rows[i]; // found
- }
- }
-
- // not found, search fall back table(s), if any
- } while( ( cur = cur->fallBack ) != 0 );
-
- return 0; // not found
-}
-
-
-bool FP_LIB_TABLE::InsertRow( const FP_LIB_TABLE_ROW& aRow, bool doReplace )
-{
- ensureIndex();
-
- INDEX_CITER it = nickIndex.find( aRow.GetNickName() );
-
- if( it == nickIndex.end() )
- {
- rows.push_back( aRow );
- nickIndex.insert( INDEX_VALUE( aRow.GetNickName(), rows.size() - 1 ) );
- return true;
- }
-
- if( doReplace )
- {
- rows[it->second] = aRow;
- return true;
- }
-
- return false;
-}
-
-
-const FP_LIB_TABLE_ROW* FP_LIB_TABLE::FindRow( const wxString& aNickname )
- throw( IO_ERROR )
-{
- FP_LIB_TABLE_ROW* row = dynamic_cast< FP_LIB_TABLE_ROW* >( findRow( aNickname ) );
-
- if( !row )
- {
- wxString msg = wxString::Format(
- _( "fp-lib-table files contain no lib with nickname '%s'" ),
- GetChars( aNickname ) );
-
- THROW_IO_ERROR( msg );
- }
-
- // We've been 'lazy' up until now, but it cannot be deferred any longer,
- // instantiate a PLUGIN of the proper kind if it is not already in this LIB_TABLE_ROW.
- if( !row->plugin )
- row->setPlugin( IO_MGR::PluginFind( row->type ) );
-
- return row;
-}
-
-
-// wxGetenv( wchar_t* ) is not re-entrant on linux.
-// Put a lock on multithreaded use of wxGetenv( wchar_t* ), called from wxEpandEnvVars(),
-// needed by bool ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxString* aNickname = NULL );
-#include
-
-const wxString FP_LIB_TABLE::ExpandSubstitutions( const wxString& aString )
-{
-// Duplicate code: the same is now in common.cpp, due to the fact it is used
-// in many other places than FP_LIB_TABLE
-#if 0
- static MUTEX getenv_mutex;
-
- MUTLOCK lock( getenv_mutex );
-
- // We reserve the right to do this another way, by providing our own member
- // function.
- return wxExpandEnvVars( aString );
-#else
- return ExpandEnvVarSubstitutions( aString );
-#endif
-}
-
-
-bool FP_LIB_TABLE::IsEmpty( bool aIncludeFallback )
-{
- if( !aIncludeFallback || !fallBack )
- return rows.empty();
-
- return rows.empty() && fallBack->IsEmpty( true );
-}
-
-
MODULE* FP_LIB_TABLE::FootprintLoadWithOptionalNickname( const FPID& aFootprintId )
throw( IO_ERROR, PARSE_ERROR, boost::interprocess::lock_exception )
{
@@ -714,11 +773,12 @@ MODULE* FP_LIB_TABLE::FootprintLoadWithOptionalNickname( const FPID& aFootprintI
std::vector nicks = GetLogicalLibs();
// Search each library going through libraries alphabetically.
- for( unsigned i = 0; i
#include
#include
+#include
+
#define FP_LATE_ENVVAR 1 ///< late=1/early=0 environment variable expansion
@@ -41,62 +43,68 @@ class OUTPUTFORMATTER;
class MODULE;
class FP_LIB_TABLE_LEXER;
class FPID;
+class FP_TBL_MODEL;
+class LIB_TABLE_ROW;
+
+
+/**
+ * Function new_clone
+ *
+ * Allows boost pointer containers to make clones of the data stored in them. Since they
+ * store pointers the data is cloned. Copying and assigning pointers would cause ownership
+ * issues if the standard C++ containers were used.
+ */
+LIB_TABLE_ROW* new_clone( const LIB_TABLE_ROW& aRow );
/**
* Class LIB_TABLE_ROW
*
* holds a record identifying a library accessed by the appropriate #PLUGIN object in the
- * #FP_LIB_TABLE.
+ * #LIB_TABLE. This is an abstract base class from which to derive specific library rows.
*/
-class LIB_TABLE_ROW
+class LIB_TABLE_ROW : boost::noncopyable
{
public:
-
- LIB_TABLE_ROW() :
- properties( 0 )
+ LIB_TABLE_ROW()
{
}
virtual ~LIB_TABLE_ROW()
{
- delete properties;
}
LIB_TABLE_ROW( const wxString& aNick, const wxString& aURI, const wxString& aOptions,
const wxString& aDescr = wxEmptyString ) :
nickName( aNick ),
- description( aDescr ),
- properties( 0 )
+ description( aDescr )
{
- SetOptions( aOptions ),
+ properties.reset();
+ SetOptions( aOptions );
SetFullURI( aURI );
}
- LIB_TABLE_ROW( const LIB_TABLE_ROW& aRow );
-
- LIB_TABLE_ROW& operator=( const LIB_TABLE_ROW& r );
-
bool operator==( const LIB_TABLE_ROW& r ) const;
bool operator!=( const LIB_TABLE_ROW& r ) const { return !( *this == r ); }
- //-----------------------------------------------------------
-
/**
* Function GetNickName
- * returns the short name of this library table row.
+ *
+ * @return the logical name of this library table row.
*/
const wxString& GetNickName() const { return nickName; }
/**
* Function SetNickName
+ *
* changes the logical name of this library, useful for an editor.
*/
void SetNickName( const wxString& aNickName ) { nickName = aNickName; }
/**
* Function GetType
+ *
* is a pure virtual function that returns the type of LIB represented by this row.
*/
virtual const wxString GetType() const = 0;
@@ -111,6 +119,7 @@ public:
/**
* Function GetFullURI
+ *
* returns the full location specifying URI for the LIB, either in original
* UI form or in environment variable expanded form.
*
@@ -120,12 +129,14 @@ public:
/**
* Function SetFullURI
+ *
* changes the full URI for the library.
*/
void SetFullURI( const wxString& aFullURI );
/**
* Function GetOptions
+ *
* returns the options string, which may hold a password or anything else needed to
* instantiate the underlying LIB_SOURCE.
*/
@@ -138,24 +149,25 @@ public:
/**
* Function GetDescr
+ *
* returns the description of the library referenced by this row.
*/
const wxString& GetDescr() const { return description; }
/**
* Function SetDescr
+ *
* changes the description of the library referenced by this row.
*/
void SetDescr( const wxString& aDescr ) { description = aDescr; }
/**
* Function GetProperties
+ *
* returns the constant PROPERTIES for this library (LIB_TABLE_ROW). These are
* the "options" in a table.
*/
- const PROPERTIES* GetProperties() const { return properties; }
-
- //----------------------------------------------------------
+ const PROPERTIES* GetProperties() const { return properties.get(); }
/**
* Function Format
@@ -165,26 +177,42 @@ public:
*
* @param out is an #OUTPUTFORMATTER
* @param nestLevel is the indentation level to base all lines of the output.
- * Actual indentation will be 2 spaces for each nestLevel.
+ * Actual indentation will be 2 spaces for each nestLevel.
*/
void Format( OUTPUTFORMATTER* out, int nestLevel ) const
throw( IO_ERROR, boost::interprocess::lock_exception );
-private:
+ static void Parse( std::unique_ptr< LIB_TABLE_ROW >& aRow, FP_LIB_TABLE_LEXER* in )
+ throw( IO_ERROR, PARSE_ERROR );
- /**
- * Function setProperties
- *
- * sets this LIB_TABLE_ROW's PROPERTIES by taking ownership of @a aProperties.
- *
- * @param aProperties ownership is given over to this LIB_TABLE_ROW.
- */
- void setProperties( const PROPERTIES* aProperties )
+ LIB_TABLE_ROW* clone() const
{
- delete properties;
- properties = aProperties;
+ return do_clone();
}
+protected:
+ LIB_TABLE_ROW( const LIB_TABLE_ROW& aRow ) :
+ nickName( aRow.nickName ),
+ uri_user( aRow.uri_user ),
+#if !FP_LATE_ENVVAR
+ uri_expanded( aRow.uri_expanded ),
+#endif
+ options( aRow.options ),
+ description( aRow.description )
+ {
+ if( aRow.properties )
+ properties.reset( new PROPERTIES( *aRow.properties.get() ) );
+ else
+ properties.reset();
+ }
+
+ void operator=( const LIB_TABLE_ROW& aRow );
+
+private:
+ virtual LIB_TABLE_ROW* do_clone() const = 0;
+
+ void setProperties( PROPERTIES* aProperties );
+
wxString nickName;
wxString uri_user; ///< what user entered from UI or loaded from disk
@@ -195,14 +223,19 @@ private:
wxString options;
wxString description;
- const PROPERTIES* properties;
+ std::unique_ptr< PROPERTIES > properties;
};
+/**
+ * Class FP_LIB_TABLE_ROW
+ *
+ * holds a record identifying a library accessed by the appropriate footprint library #PLUGIN
+ *& object in the #FP_LIB_TABLE.
+ */
class FP_LIB_TABLE_ROW : public LIB_TABLE_ROW
{
friend class FP_LIB_TABLE;
- friend class DIALOG_FP_LIB_TABLE;
public:
typedef IO_MGR::PCB_FILE_T LIB_T;
@@ -219,28 +252,38 @@ public:
{
}
- FP_LIB_TABLE_ROW( const FP_LIB_TABLE_ROW& aRow );
-
- FP_LIB_TABLE_ROW& operator=( const FP_LIB_TABLE_ROW& aRow );
-
- /// Used in DIALOG_FP_LIB_TABLE for detecting an edit.
bool operator==( const FP_LIB_TABLE_ROW& aRow ) const;
bool operator!=( const FP_LIB_TABLE_ROW& aRow ) const { return !( *this == aRow ); }
/**
* Function GetType
- * returns the type of LIB represented by this row.
+ *
+ * returns the type of footprint library table represented by this row.
*/
const wxString GetType() const override { return IO_MGR::ShowType( type ); }
/**
* Function SetType
+ *
* changes the type represented by this row.
*/
void SetType( const wxString& aType ) override;
+protected:
+ FP_LIB_TABLE_ROW( const FP_LIB_TABLE_ROW& aRow ) :
+ LIB_TABLE_ROW( aRow ),
+ type( aRow.type )
+ {
+ }
+
private:
+
+ virtual LIB_TABLE_ROW* do_clone() const override
+ {
+ return new FP_LIB_TABLE_ROW( *this );
+ }
+
void setPlugin( PLUGIN* aPlugin )
{
plugin.set( aPlugin );
@@ -252,19 +295,20 @@ private:
/**
- * Class FP_LIB_TABLE
- * holds FP_LIB_TABLE::ROW records (rows), and can be searched based on library nickName.
+ * Class LIB_TABLE
+ * holds LIB_TABLE_ROW records (rows), and can be searched based on library nickname.
*
- * This class owns the footprint library table, which is like fstab in concept and maps
- * logical library name to the library URI, type, and options. It is heavily based on the SWEET
- * parser work done by Dick Hollenbeck and can be seen in new/sch_lib_table.h. A footprint
- * library table had the following columns:
+ * This class owns the library table, which is like fstab in concept and maps
+ * logical library name to the library URI, type, and options. It is heavily based on
+ * the SWEET parser work done by Dick Hollenbeck and can be seen in new/sch_lib_table.h.
+ * A library table has the following columns:
*
* - Logical Library Name (Nickname)
*
- Library Type, used to determine which plugin to load to access the library.
*
- Library URI. The full URI to the library source, form dependent on Type.
*
- Options, used for as yet to be defined information such as user names or passwords
*
+ *
*
* The Library Type can be one of:
*
@@ -272,6 +316,7 @@ private:
* - "ftp"
*
- "http"
*
+ *
*
* For now, the Library URI types needed to support the various types can be one of those
* shown below, which are typical of each type:
@@ -280,37 +325,43 @@ private:
*
"ftp://kicad.org/partlib/trunk"
* "http://kicad.org/partlib"
*
+ *
*
- * The footprint library table is built up from several additive entries (table fragments),
- * and the final table is a (conceptual) merging of the table fragments. Two
- * anticipated sources of the entries are a personal table saved in the KiCad configuration
- * and a project resident table that resides in project file. The project footprint table
- * entries are considered a higher priority in the final dynamically assembled library table.
- * An row in the project file contribution to the library table takes precedence over the
- * personal table if there is a collision of logical library names. Otherwise, the entries
- * simply combine without issue to make up the applicable library table.
+ * The library table is built up from several additive entries (table fragments), and the
+ * final table is a (conceptual) merging of the table fragments. Two anticipated sources
+ * of the entries are a personal table saved in the KiCad configuration and a project
+ * resident table that resides in project file. The project footprint table entries are
+ * considered a higher priority in the final dynamically assembled library table. An row
+ * in the project file contribution to the library table takes precedence over the personal
+ * table if there is a collision of logical library names. Otherwise, the entries simply
+ * combine without issue to make up the applicable library table.
+ *
*
* @author Wayne Stambaugh
*/
-class FP_LIB_TABLE : public PROJECT::_ELEM
+class LIB_TABLE : public PROJECT::_ELEM
{
- friend class FP_LIB_TABLE_ROW;
friend class DIALOG_FP_LIB_TABLE;
+ friend class FP_TBL_MODEL;
public:
+ virtual void Parse( FP_LIB_TABLE_LEXER* aLexer ) throw() = 0;
+
+ virtual void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw() = 0;
+
/**
- * Constructor FP_LIB_TABLE
+ * Constructor LIB_TABLE
* builds a library table by pre-pending this table fragment in front of
* @a aFallBackTable. Loading of this table fragment is done by using Parse().
*
- * @param aFallBackTable is another FP_LIB_TABLE which is searched only when
+ * @param aFallBackTable is another LIB_TABLE which is searched only when
* a row is not found in this table. No ownership is
* taken of aFallBackTable.
*/
- FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable = NULL );
+ LIB_TABLE( LIB_TABLE* aFallBackTable = NULL );
- ~FP_LIB_TABLE();
+ virtual ~LIB_TABLE();
/// Delete all rows.
void Clear()
@@ -319,11 +370,12 @@ public:
nickIndex.clear();
}
- bool operator==( const FP_LIB_TABLE& r ) const
+ bool operator==( const LIB_TABLE& r ) const
{
if( rows.size() == r.rows.size() )
{
unsigned i;
+
for( i = 0; i < rows.size() && rows[i] == r.rows[i]; ++i )
;
@@ -334,79 +386,197 @@ public:
return false;
}
- bool operator!=( const FP_LIB_TABLE& r ) const { return !( *this == r ); }
+ bool operator!=( const LIB_TABLE& r ) const { return !( *this == r ); }
- int GetCount() { return rows.size(); }
+ int GetCount() { return rows.size(); }
- LIB_TABLE_ROW& At( int aIndex ) { return rows[aIndex]; }
+ LIB_TABLE_ROW* At( int aIndex ) { return &rows[aIndex]; }
/**
- * Function Parse
- * fills this table fragment from information in the input stream \a aParser, which
- * is a DSNLEXER customized for the grammar needed to describe instances of this object.
- * The entire textual element spec is
+ * Function IsEmpty
*
- *
- * (fp_lib_table
- * (lib (name LOGICAL)(descr DESCRIPTION)(uri FULL_URI)(type TYPE)(options OPTIONS))
- * (lib (name LOGICAL)(descr DESCRIPTION)(uri FULL_URI)(type TYPE)(options OPTIONS))
- * (lib (name LOGICAL)(descr DESCRIPTION)(uri FULL_URI)(type TYPE)(options OPTIONS))
- * )
- *
+ * @param aIncludeFallback is used to determine if the fallback table should be
+ * included in the test.
*
- * When this function is called, the input token stream given by \a aParser
- * is assumed to be positioned at the '^' in the following example, i.e. just
- * after the identifying keyword and before the content specifying stuff.
- *
- * (lib_table ^ (....) )
- *
- * @param aParser is the input token stream of keywords and symbols.
+ * @return true if the footprint library table is empty.
*/
- void Parse( FP_LIB_TABLE_LEXER* aParser ) throw( IO_ERROR, PARSE_ERROR );
+ bool IsEmpty( bool aIncludeFallback = true );
+
+ /**
+ * Function GetDescription
+ *
+ * @return the library description from @a aNickname, or an empty string
+ * if @a aNickname does not exist.
+ */
+ const wxString GetDescription( const wxString& aNickname );
+
+ /**
+ * Function GetLogicalLibs
+ *
+ * returns the logical library names, all of them that are pertinent to
+ * a look up done on this LIB_TABLE.
+ */
+ std::vector GetLogicalLibs();
+
+ /**
+ * Function InsertRow
+ *
+ * adds aRow if it does not already exist or if doReplace is true. If doReplace
+ * is not true and the key for aRow already exists, the function fails and returns false.
+ *
+ * The key for the table is the nickName, and all in this table must be unique.
+ *
+ * @param aRow is the new row to insert, or to forcibly add if doReplace is true.
+ * @param doReplace if true, means insert regardless of whether aRow's key already
+ * exists. If false, then fail if the key already exists.
+ *
+ * @return bool - true if the operation succeeded.
+ */
+ bool InsertRow( LIB_TABLE_ROW* aRow, bool doReplace = false );
+
+ /**
+ * Function FindRowByURI
+ *
+ * @return a #LIB_TABLE_ROW pointer if \a aURI is found in this table or in any chained
+ * fallBack table fragments, else NULL.
+ */
+ const LIB_TABLE_ROW* FindRowByURI( const wxString& aURI );
+
+ /**
+ * Function Load
+ *
+ * loads the library table using the path defined by \a aFileName aFallBackTable.
+ *
+ * @param aFileName contains the full path to the s-expression file.
+ *
+ * @throw IO_ERROR if an error occurs attempting to load the footprint library
+ * table.
+ */
+ void Load( const wxString& aFileName ) throw( IO_ERROR );
+
+ /**
+ * Function Save
+ *
+ * writes this library table to \a 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, boost::interprocess::lock_exception );
/**
* Function ParseOptions
- * parses @a aOptionsList and places the result into a PROPERTIES object
- * which is returned. If the options field is empty, then the returned PROPERTIES
- * will be a NULL pointer.
+ *
+ * parses @a aOptionsList and places the result into a PROPERTIES object which is
+ * returned. If the options field is empty, then the returned PROPERTIES will be
+ * a NULL pointer.
*
* Typically aOptionsList comes from the "options" field within a LIB_TABLE_ROW and
* the format is simply a comma separated list of name value pairs. e.g.:
* [name1[=value1][|name2[=value2]]] etc. When using the UI to create or edit
- * a fp lib table, this formatting is handled for you.
+ * a library table, this formatting is handled for you.
+ *
*/
static PROPERTIES* ParseOptions( const std::string& aOptionsList );
/**
* Function FormatOptions
+ *
* returns a list of options from the aProperties parameter. The name=value
- * pairs will be separted with the '|' character. The =value portion may not
+ * pairs will be separated with the '|' character. The =value portion may not
* be present. You might expect something like "name1=value1|name2=value2|flag_me".
* Notice that flag_me does not have a value. This is ok.
*
* @param aProperties is the PROPERTIES to format or NULL. If NULL the returned
- * string will be empty.
+ * string will be empty.
*/
static UTF8 FormatOptions( const PROPERTIES* aProperties );
/**
- * Function Format
- * serializes this object as utf8 text to an #OUTPUTFORMATTER, and tries to
- * make it look good using multiple lines and indentation.
+ * Function ExpandSubstitutions
*
- * @param out is an #OUTPUTFORMATTER
- * @param nestLevel is the indentation level to base all lines of the output.
- * Actual indentation will be 2 spaces for each nestLevel.
+ * replaces any environment variable references with their values and is here to fully
+ * embellish the TABLE_ROW::uri in a platform independent way. This enables library
+ * tables to have platform dependent environment variables in them, allowing for a
+ * uniform table across platforms.
*/
- void Format( OUTPUTFORMATTER* out, int nestLevel ) const
- throw( IO_ERROR, boost::interprocess::lock_exception );
+ static const wxString ExpandSubstitutions( const wxString& aString );
+
+protected:
/**
- * Function GetLogicalLibs
- * returns the logical library names, all of them that are pertinent to
- * a lookup done on this FP_LIB_TABLE.
+ * Function findRow
+ * returns a LIB_TABLE_ROW if aNickname is found in this table or in any chained
+ * fallBack table fragment, else NULL.
*/
- std::vector GetLogicalLibs();
+ LIB_TABLE_ROW* findRow( const wxString& aNickname ) const;
+
+ void reindex()
+ {
+ nickIndex.clear();
+
+ for( LIB_TABLE_ROWS_ITER it = rows.begin(); it != rows.end(); ++it )
+ nickIndex.insert( INDEX_VALUE( it->GetNickName(), it - rows.begin() ) );
+ }
+
+ void ensureIndex()
+ {
+ // The dialog lib table editor may not maintain the nickIndex.
+ // Lazy indexing may be required. To handle lazy indexing, we must enforce
+ // that "nickIndex" is either empty or accurate, but never inaccurate.
+ if( !nickIndex.size() )
+ reindex();
+ }
+
+ typedef boost::ptr_vector< LIB_TABLE_ROW > LIB_TABLE_ROWS;
+ typedef LIB_TABLE_ROWS::iterator LIB_TABLE_ROWS_ITER;
+ typedef LIB_TABLE_ROWS::const_iterator LIB_TABLE_ROWS_CITER;
+
+ LIB_TABLE_ROWS rows;
+
+ /// this is a non-owning index into the LIB_TABLE_ROWS table
+ typedef std::map INDEX; // "int" is std::vector array index
+ typedef INDEX::iterator INDEX_ITER;
+ typedef INDEX::const_iterator INDEX_CITER;
+ typedef INDEX::value_type INDEX_VALUE;
+
+ /// this particular key is the nickName within each row.
+ INDEX nickIndex;
+
+ LIB_TABLE* fallBack;
+};
+
+
+class FP_LIB_TABLE : public LIB_TABLE
+{
+public:
+
+ virtual void Parse( FP_LIB_TABLE_LEXER* aLexer ) throw() override;
+
+ virtual void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw() override;
+
+ /**
+ * Constructor FP_LIB_TABLE
+ *
+ * builds a footprint library table by pre-pending this table fragment in front of
+ * @a aFallBackTable. Loading of this table fragment is done by using Parse().
+ *
+ * @param aFallBackTable is another FP_LIB_TABLE which is searched only when
+ * a row is not found in this table. No ownership is
+ * taken of aFallBackTable.
+ */
+ FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable = NULL );
+
+ /**
+ * Function FindRow
+ *
+ * returns an FP_LIB_TABLE_ROW if \a aNickName is found in this table or in any chained
+ * fallBack table fragment. The #PLUGIN is loaded and attached to the "plugin" field
+ * of the #FP_LIB_TABLE_ROW if not already loaded.
+ *
+ * @throw IO_ERROR if \a aNickName cannot be found.
+ */
+ const FP_LIB_TABLE_ROW* FindRow( const wxString& aNickName ) throw( IO_ERROR );
//--------------------------------
@@ -415,11 +585,9 @@ public:
* returns a list of footprint names contained within the library given by
* @a aNickname.
*
- * @param aNickname is a locator for the "library", it is a "name"
- * in FP_LIB_TABLE::LIB_TABLE_ROW
+ * @param aNickname is a locator for the "library", it is a "name" in LIB_TABLE_ROW.
*
- * @return wxArrayString - is the array of available footprint names inside
- * a library
+ * @return wxArrayString - is the array of available footprint names inside a library
*
* @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded.
*/
@@ -427,10 +595,10 @@ public:
/**
* Function FootprintLoad
+ *
* loads a footprint having @a aFootprintName from the library given by @a aNickname.
*
- * @param aNickname is a locator for the "library", it is a "name"
- * in FP_LIB_TABLE::LIB_TABLE_ROW
+ * @param aNickname is a locator for the "library", it is a "name" in #LIB_TABLE_ROW
*
* @param aFootprintName is the name of the footprint to load.
*
@@ -453,30 +621,31 @@ public:
/**
* Function FootprintSave
+ *
* will write @a aFootprint to an existing library given by @a aNickname.
* If a footprint by the same name already exists, it is replaced.
*
- * @param aNickname is a locator for the "library", it is a "name"
- * in FP_LIB_TABLE::LIB_TABLE_ROW
+ * @param aNickname is a locator for the "library", it is a "name" in LIB_TABLE_ROW
*
- * @param aFootprint is what to store in the library. The caller continues
- * to own the footprint after this call.
+ * @param aFootprint is what to store in the library. The caller continues to own the
+ * footprint after this call.
*
- * @param aOverwrite when true means overwrite any existing footprint by the
- * same name, else if false means skip the write and return SAVE_SKIPPED.
+ * @param aOverwrite when true means overwrite any existing footprint by the same name,
+ * else if false means skip the write and return SAVE_SKIPPED.
*
* @return SAVE_T - SAVE_OK or SAVE_SKIPPED. If error saving, then IO_ERROR is thrown.
*
* @throw IO_ERROR if there is a problem saving.
*/
- SAVE_T FootprintSave( const wxString& aNickname, const MODULE* aFootprint, bool aOverwrite = true );
+ SAVE_T FootprintSave( const wxString& aNickname, const MODULE* aFootprint,
+ bool aOverwrite = true );
/**
* Function FootprintDelete
+ *
* deletes the @a aFootprintName from the library given by @a aNickname.
*
- * @param aNickname is a locator for the "library", it is a "name"
- * in FP_LIB_TABLE::LIB_TABLE_ROW
+ * @param aNickname is a locator for the "library", it is a "name" in LIB_TABLE_ROW.
*
* @param aFootprintName is the name of a footprint to delete from the specified library.
*
@@ -486,7 +655,8 @@ public:
/**
* Function IsFootprintLibWritable
- * returns true iff the library given by @a aNickname is writable. (Often
+ *
+ * returns true if the library given by @a aNickname is writable. (Often
* system libraries are read only because of where they are installed.)
*
* @throw IO_ERROR if no library at aLibraryPath exists.
@@ -503,7 +673,7 @@ public:
* Function FootprintLoadWithOptionalNickname
* loads a footprint having @a aFootprintId with possibly an empty nickname.
*
- * @param aFootprintId the [nickname] & fooprint name of the footprint to load.
+ * @param aFootprintId the [nickname] & footprint name of the footprint to load.
*
* @return MODULE* - if found caller owns it, else NULL if not found.
*
@@ -514,59 +684,6 @@ public:
MODULE* FootprintLoadWithOptionalNickname( const FPID& aFootprintId )
throw( IO_ERROR, PARSE_ERROR, boost::interprocess::lock_exception );
- /**
- * Function GetDescription
- * returns the library desicription from @a aNickname, or an empty string
- * if aNickname does not exist.
- */
- const wxString GetDescription( const wxString& aNickname );
-
- /**
- * Function InsertRow
- * adds aRow if it does not already exist or if doReplace is true. If doReplace
- * is not true and the key for aRow already exists, the function fails and returns false.
- * The key for the table is the nickName, and all in this table must be unique.
- * @param aRow is the new row to insert, or to forcibly add if doReplace is true.
- * @param doReplace if true, means insert regardless of whether aRow's key already
- * exists. If false, then fail if the key already exists.
- * @return bool - true if the operation succeeded.
- */
- bool InsertRow( const FP_LIB_TABLE_ROW& aRow, bool doReplace = false );
-
- /**
- * Function FindRow
- * returns a LIB_TABLE_ROW if aNickName is found in this table or in any chained
- * fallBack table fragment. The PLUGIN is loaded and attached
- * to the "plugin" field of the LIB_TABLE_ROW if not already loaded.
- *
- * @throw IO_ERROR if aNickName cannot be found.
- */
- const FP_LIB_TABLE_ROW* FindRow( const wxString& aNickName ) throw( IO_ERROR );
-
- /**
- * Function FindRowByURI
- * returns a #FP_LIB_TABLE::LIB_TABLE_ROW if aURE is found in this table or in any chained
- * fallBack table fragments, else NULL.
- */
- const FP_LIB_TABLE_ROW* FindRowByURI( const wxString& aURI );
-
- /**
- * Function IsEmpty
- * @param aIncludeFallback is used to determine if the fallback table should be
- * included in the test.
- * @return true if the footprint library table is empty.
- */
- bool IsEmpty( bool aIncludeFallback = true );
-
- /**
- * Function ExpandSubstitutions
- * replaces any environment variable references with their values and is
- * here to fully embellish the LIB_TABLE_ROW::uri in a platform independent way.
- * This enables (fp_lib_table)s to have platform dependent environment
- * variables in them, allowing for a uniform table across platforms.
- */
- static const wxString ExpandSubstitutions( const wxString& aString );
-
/**
* Function LoadGlobalTable
* loads the global footprint library table into \a aTable.
@@ -585,90 +702,21 @@ public:
/**
* Function GetGlobalTableFileName
+ *
* @return the platform specific global footprint library path and file name.
*/
static wxString GetGlobalTableFileName();
-#if 0
- /**
- * Function GetFileName
- * @return the footprint library file name.
- */
- static const wxString GetFileName();
-#endif
-
/**
* Function GlobalPathEnvVarVariableName
+ *
* returns the name of the environment variable used to hold the directory of
* locally installed "KiCad sponsored" system footprint libraries. These can
* be either legacy or pretty format. The only thing special about this
* particular environment variable is that it is set automatically by
- * KiCad on program startup, iff it is not set already in the environment.
+ * KiCad on program start up, if it is not set already in the environment.
*/
static const wxString GlobalPathEnvVariableName();
-
- /**
- * Function Load
- * loads the footprint library table using the path defined in \a aFileName with
- * \a aFallBackTable.
- *
- * @param aFileName contains the full path to the s-expression file.
- *
- * @throw IO_ERROR if an error occurs attempting to load the footprint library
- * table.
- */
- 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, boost::interprocess::lock_exception );
-
-protected:
-
- /**
- * Function findRow
- * returns a LIB_TABLE_ROW if aNickname is found in this table or in any chained
- * fallBack table fragment, else NULL.
- */
- LIB_TABLE_ROW* findRow( const wxString& aNickname ) const;
-
- void reindex()
- {
- nickIndex.clear();
-
- for( FP_LIB_TABLE_ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
- nickIndex.insert( INDEX_VALUE( it->GetNickName(), it - rows.begin() ) );
- }
-
- void ensureIndex()
- {
- // The dialog lib table editor may not maintain the nickIndex.
- // Lazy indexing may be required. To handle lazy indexing, we must enforce
- // that "nickIndex" is either empty or accurate, but never inaccurate.
- if( !nickIndex.size() )
- reindex();
- }
-
- typedef std::vector FP_LIB_TABLE_ROWS;
- typedef FP_LIB_TABLE_ROWS::iterator FP_LIB_TABLE_ROWS_ITER;
- typedef FP_LIB_TABLE_ROWS::const_iterator FP_LIB_TABLE_ROWS_CITER;
-
- FP_LIB_TABLE_ROWS rows;
-
- /// this is a non-owning index into the LIB_TABLE_ROWS table
- typedef std::map INDEX; // "int" is std::vector array index
- typedef INDEX::iterator INDEX_ITER;
- typedef INDEX::const_iterator INDEX_CITER;
- typedef INDEX::value_type INDEX_VALUE;
-
- /// this particular key is the nickName within each row.
- INDEX nickIndex;
-
- FP_LIB_TABLE* fallBack;
};
diff --git a/pcbnew/dialogs/dialog_fp_lib_table.cpp b/pcbnew/dialogs/dialog_fp_lib_table.cpp
index afa65e30b7..516b8bb591 100644
--- a/pcbnew/dialogs/dialog_fp_lib_table.cpp
+++ b/pcbnew/dialogs/dialog_fp_lib_table.cpp
@@ -74,9 +74,9 @@ public:
* is a copy constructor that builds a wxGridTableBase (table model) by wrapping
* an FP_LIB_TABLE.
*/
- FP_TBL_MODEL( const FP_LIB_TABLE& aTableToEdit ) :
- FP_LIB_TABLE( aTableToEdit ) // copy constructor
+ FP_TBL_MODEL( const FP_LIB_TABLE& aTableToEdit )
{
+ rows = aTableToEdit.rows;
}
//------------------------------------------------
@@ -88,15 +88,15 @@ public:
{
if( unsigned( aRow ) < rows.size() )
{
- const FP_LIB_TABLE_ROW& r = rows[aRow];
+ const LIB_TABLE_ROW* r = &rows[aRow];
switch( aCol )
{
- case COL_NICKNAME: return r.GetNickName();
- case COL_URI: return r.GetFullURI();
- case COL_TYPE: return r.GetType();
- case COL_OPTIONS: return r.GetOptions();
- case COL_DESCR: return r.GetDescr();
+ case COL_NICKNAME: return r->GetNickName();
+ case COL_URI: return r->GetFullURI();
+ case COL_TYPE: return r->GetType();
+ case COL_OPTIONS: return r->GetOptions();
+ case COL_DESCR: return r->GetDescr();
default:
; // fall thru to wxEmptyString
}
@@ -109,15 +109,15 @@ public:
{
if( unsigned( aRow ) < rows.size() )
{
- FP_LIB_TABLE_ROW& r = rows[aRow];
+ LIB_TABLE_ROW* r = &rows[aRow];
switch( aCol )
{
- case COL_NICKNAME: r.SetNickName( aValue ); break;
- case COL_URI: r.SetFullURI( aValue ); break;
- case COL_TYPE: r.SetType( aValue ); break;
- case COL_OPTIONS: r.SetOptions( aValue ); break;
- case COL_DESCR: r.SetDescr( aValue ); break;
+ case COL_NICKNAME: r->SetNickName( aValue ); break;
+ case COL_URI: r->SetFullURI( aValue ); break;
+ case COL_TYPE: r->SetType( aValue ); break;
+ case COL_OPTIONS: r->SetOptions( aValue ); break;
+ case COL_DESCR: r->SetDescr( aValue ); break;
}
}
}
@@ -131,7 +131,11 @@ public:
{
if( aPos < rows.size() )
{
- rows.insert( rows.begin() + aPos, aNumRows, FP_LIB_TABLE_ROW() );
+ for( size_t i = 0; i < aNumRows; i++ )
+ {
+ rows.insert( rows.begin() + i,
+ dynamic_cast< LIB_TABLE_ROW* >( new FP_LIB_TABLE_ROW ) );
+ }
// use the (wxGridStringTable) source Luke.
if( GetView() )
@@ -146,6 +150,7 @@ public:
return true;
}
+
return false;
}
@@ -153,7 +158,7 @@ public:
{
// do not modify aNumRows, original value needed for wxGridTableMessage below
for( int i = aNumRows; i; --i )
- rows.push_back( FP_LIB_TABLE_ROW() );
+ rows.push_back( new FP_LIB_TABLE_ROW );
if( GetView() )
{
@@ -173,7 +178,7 @@ public:
// aPos+aNumRows may wrap here, so both ends of the range are tested.
if( aPos < rows.size() && aPos + aNumRows <= rows.size() )
{
- FP_LIB_TABLE_ROWS_ITER start = rows.begin() + aPos;
+ LIB_TABLE_ROWS_ITER start = rows.begin() + aPos;
rows.erase( start, start + aNumRows );
if( GetView() )
@@ -188,13 +193,8 @@ public:
return true;
}
- return false;
- }
- void Clear() override
- {
- rows.clear();
- nickIndex.clear();
+ return false;
}
wxString GetColLabelValue( int aCol ) override
@@ -267,9 +267,10 @@ protected:
for( int i = 0; i < tmp_tbl.GetCount(); ++i )
{
- tbl->At( cur_row+i ) = tmp_tbl.At( i );
+ tbl->rows.replace( cur_row+i, tmp_tbl.At( i ) );
}
}
+
m_grid->AutoSizeColumns( false );
}
else
@@ -364,8 +365,8 @@ public:
// Gives a selection for each grid, mainly for delete lib button.
// Without that, we do not see what lib will be deleted
- m_global_grid->SelectRow(0);
- m_project_grid->SelectRow(0);
+ m_global_grid->SelectRow( 0 );
+ m_project_grid->SelectRow( 0 );
// for ALT+A handling, we want the initial focus to be on the first selected grid.
m_cur_grid->SetFocus();
@@ -534,7 +535,6 @@ private:
void deleteRowHandler( wxCommandEvent& event ) override
{
-#if 1
int currRow = getCursorRow();
wxArrayInt selectedRows = m_cur_grid->GetSelectedRows();
@@ -553,36 +553,29 @@ private:
m_cur_grid->SetGridCursor(m_cur_grid->GetNumberRows()-1, getCursorCol() );
m_cur_grid->SelectRow( m_cur_grid->GetGridCursorRow() );
-#else
- int rowCount = m_cur_grid->GetNumberRows();
- int curRow = getCursorRow();
-
- if( curRow >= 0 )
- {
- m_cur_grid->DeleteRows( curRow );
-
- if( curRow && curRow == rowCount - 1 )
- {
- m_cur_grid->SetGridCursor( curRow-1, getCursorCol() );
- }
- }
-#endif
}
void moveUpHandler( wxCommandEvent& event ) override
{
- int curRow = getCursorRow();
+ wxArrayInt rowsSelected = m_cur_grid->GetSelectedRows();
+
+ if( rowsSelected.GetCount() == 0 )
+ return;
+
+ // @todo: add multiple selection moves.
+ int curRow = rowsSelected[0];
+
if( curRow >= 1 )
{
int curCol = getCursorCol();
FP_TBL_MODEL* tbl = cur_model();
- ROW move_me = tbl->rows[curRow];
+ boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
+ tbl->rows.release( tbl->rows.begin() + curRow );
- tbl->rows.erase( tbl->rows.begin() + curRow );
--curRow;
- tbl->rows.insert( tbl->rows.begin() + curRow, move_me );
+ tbl->rows.insert( tbl->rows.begin() + curRow, move_me.release() );
if( tbl->GetView() )
{
@@ -603,18 +596,25 @@ private:
void moveDownHandler( wxCommandEvent& event ) override
{
+ wxArrayInt rowsSelected = m_cur_grid->GetSelectedRows();
+
+ if( rowsSelected.GetCount() == 0 )
+ return;
+
FP_TBL_MODEL* tbl = cur_model();
- int curRow = getCursorRow();
+ // @todo: add multiple selection moves.
+ int curRow = rowsSelected[0];
+
if( unsigned( curRow + 1 ) < tbl->rows.size() )
{
- int curCol = getCursorCol();
+ int curCol = getCursorCol();
- ROW move_me = tbl->rows[curRow];
+ boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
+ tbl->rows.release( tbl->rows.begin() + curRow );
- tbl->rows.erase( tbl->rows.begin() + curRow );
- ++curRow;
- tbl->rows.insert( tbl->rows.begin() + curRow, move_me );
+ ++curRow;
+ tbl->rows.insert( tbl->rows.begin() + curRow, move_me.release() );
if( tbl->GetView() )
{
@@ -639,17 +639,17 @@ private:
if( tbl->GetNumberRows() )
{
- int curRow = getCursorRow();
- ROW& row = tbl->rows[curRow];
+ int curRow = getCursorRow();
+ LIB_TABLE_ROW* row = &tbl->rows[curRow];
wxString result;
- const wxString& options = row.GetOptions();
+ const wxString& options = row->GetOptions();
- InvokePluginOptionsEditor( this, row.GetNickName(), row.GetType(), options, &result );
+ InvokePluginOptionsEditor( this, row->GetNickName(), row->GetType(), options, &result );
if( options != result )
{
- row.SetOptions( result );
+ row->SetOptions( result );
// all but options:
m_cur_grid->AutoSizeColumn( COL_NICKNAME, false );
@@ -690,7 +690,9 @@ private:
{
dialogRet |= 1;
- *m_global = *global_model();
+ m_global->Clear();
+ m_global->rows.transfer( m_global->rows.end(), global_model()->rows.begin(),
+ global_model()->rows.end(), global_model()->rows );
m_global->reindex();
}
@@ -698,7 +700,9 @@ private:
{
dialogRet |= 2;
- *m_project = *project_model();
+ m_project->Clear();
+ m_project->rows.transfer( m_project->rows.end(), project_model()->rows.begin(),
+ project_model()->rows.end(), project_model()->rows );
m_project->reindex();
}
@@ -769,6 +773,7 @@ private:
m_path_subs_grid->AppendRows( unique.size() );
row = 0;
+
for( SET_CITER it = unique.begin(); it != unique.end(); ++it, ++row )
{
wxString evName = *it;
@@ -786,17 +791,18 @@ private:
//--------------------------------------
// caller's tables are modified only on OK button and successful verification.
- FP_LIB_TABLE* m_global;
- FP_LIB_TABLE* m_project;
+ FP_LIB_TABLE* m_global;
+ FP_LIB_TABLE* m_project;
- FP_TBL_MODEL* global_model() const { return (FP_TBL_MODEL*) m_global_grid->GetTable(); }
- FP_TBL_MODEL* project_model() const { return (FP_TBL_MODEL*) m_project_grid->GetTable(); }
- FP_TBL_MODEL* cur_model() const { return (FP_TBL_MODEL*) m_cur_grid->GetTable(); }
+ FP_TBL_MODEL* global_model() const { return (FP_TBL_MODEL*) m_global_grid->GetTable(); }
+ FP_TBL_MODEL* project_model() const { return (FP_TBL_MODEL*) m_project_grid->GetTable(); }
+ FP_TBL_MODEL* cur_model() const { return (FP_TBL_MODEL*) m_cur_grid->GetTable(); }
- wxGrid* m_cur_grid; ///< changed based on tab choice
- static int m_pageNdx; ///< Remember the last notebook page selected during a session
+ wxGrid* m_cur_grid; ///< changed based on tab choice
+ static int m_pageNdx; ///< Remember the last notebook page selected during a session
};
+
int DIALOG_FP_LIB_TABLE::m_pageNdx = 0;
@@ -846,7 +852,8 @@ void DIALOG_FP_LIB_TABLE::OnClickLibraryWizard( wxCommandEvent& event )
}
-int InvokePcbLibTableEditor( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject )
+int InvokePcbLibTableEditor( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal,
+ FP_LIB_TABLE* aProject )
{
DIALOG_FP_LIB_TABLE dlg( aParent, aGlobal, aProject );
@@ -856,7 +863,8 @@ int InvokePcbLibTableEditor( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, F
}
-int InvokeFootprintWizard( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject )
+int InvokeFootprintWizard( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal,
+ FP_LIB_TABLE* aProject )
{
WIZARD_FPLIB_TABLE dlg( aParent );
@@ -875,10 +883,10 @@ int InvokeFootprintWizard( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_
if( it->GetStatus() == WIZARD_FPLIB_TABLE::LIBRARY::INVALID )
continue;
- FP_LIB_TABLE_ROW row( it->GetDescription(),
- it->GetAutoPath( scope ),
- it->GetPluginName(),
- wxEmptyString ); // options
+ FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( it->GetDescription(),
+ it->GetAutoPath( scope ),
+ it->GetPluginName(),
+ wxEmptyString ); // options
fp_tbl->InsertRow( row );
}
}
diff --git a/pcbnew/dialogs/dialog_fp_plugin_options.cpp b/pcbnew/dialogs/dialog_fp_plugin_options.cpp
index f54f33b702..c823c8be79 100644
--- a/pcbnew/dialogs/dialog_fp_plugin_options.cpp
+++ b/pcbnew/dialogs/dialog_fp_plugin_options.cpp
@@ -3,7 +3,7 @@
*
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck
* Copyright (C) 2013 CERN
- * Copyright (C) 2013 KiCad Developers, see change_log.txt for contributors.
+ * Copyright (C) 2013-2016 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -73,7 +73,7 @@ public:
// Fill the grid with existing aOptions
string options = TO_UTF8( aOptions );
- PROPERTIES* props = FP_LIB_TABLE::ParseOptions( options );
+ PROPERTIES* props = LIB_TABLE::ParseOptions( options );
if( props )
{
@@ -192,7 +192,7 @@ private:
}
}
- return FP_LIB_TABLE::FormatOptions( &props );
+ return LIB_TABLE::FormatOptions( &props );
}
void saveColSizes()
diff --git a/pcbnew/dialogs/wizard_add_fplib.cpp b/pcbnew/dialogs/wizard_add_fplib.cpp
index 1d0ccbfc77..d909759f76 100644
--- a/pcbnew/dialogs/wizard_add_fplib.cpp
+++ b/pcbnew/dialogs/wizard_add_fplib.cpp
@@ -4,7 +4,7 @@
* Copyright (C) 2015 CERN
* @author Maciej Suminski
* Copyright (C) 2014-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/pcbnew/github/github_plugin.cpp b/pcbnew/github/github_plugin.cpp
index 31055f6ed8..bc6e0f9ac6 100644
--- a/pcbnew/github/github_plugin.cpp
+++ b/pcbnew/github/github_plugin.cpp
@@ -381,7 +381,7 @@ void GITHUB_PLUGIN::cacheLib( const wxString& aLibraryPath, const PROPERTIES* aP
{
wxString wx_pretty_dir = pretty_dir;
- wx_pretty_dir = FP_LIB_TABLE::ExpandSubstitutions( wx_pretty_dir );
+ wx_pretty_dir = LIB_TABLE::ExpandSubstitutions( wx_pretty_dir );
wxFileName wx_pretty_fn = wx_pretty_dir;
diff --git a/pcbnew/invoke_pcb_dialog.h b/pcbnew/invoke_pcb_dialog.h
index aa5ad14e6b..e74e8a2325 100644
--- a/pcbnew/invoke_pcb_dialog.h
+++ b/pcbnew/invoke_pcb_dialog.h
@@ -5,7 +5,7 @@
/* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck
- * Copyright (C) 2013 KiCad Developers, see change_log.txt for contributors.
+ * Copyright (C) 2013-2016 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -71,7 +71,8 @@ class PCB_PLOT_PARAMS;
* @return int - bits 0 and 1 tell whether a change was made to the @a aGlobal
* and/or the @a aProject table, respectively. If set, table was modified.
*/
-int InvokePcbLibTableEditor( wxTopLevelWindow* aCaller, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject );
+int InvokePcbLibTableEditor( wxTopLevelWindow* aCaller, FP_LIB_TABLE* aGlobal,
+ FP_LIB_TABLE* aProject );
/**
* Function InvokeFootprintWizard
@@ -88,7 +89,8 @@ int InvokePcbLibTableEditor( wxTopLevelWindow* aCaller, FP_LIB_TABLE* aGlobal, F
* 2 - changes in the project table
* 3 - changes in both tables
*/
-int InvokeFootprintWizard( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject );
+int InvokeFootprintWizard( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal,
+ FP_LIB_TABLE* aProject );
/**
* Function Invoke3DShapeLibsDownloaderWizard
diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
index 4a62c43ee0..cf87d8a9db 100644
--- a/pcbnew/modview_frame.cpp
+++ b/pcbnew/modview_frame.cpp
@@ -727,7 +727,7 @@ void FOOTPRINT_VIEWER_FRAME::UpdateTitle()
if( getCurNickname().size() )
{
FP_LIB_TABLE* libtable = Prj().PcbFootprintLibs();
- const FP_LIB_TABLE_ROW* row = libtable->FindRow( getCurNickname() );
+ const LIB_TABLE_ROW* row = libtable->FindRow( getCurNickname() );
if( row )
title << L" \u2014 " << row->GetFullURI( true );