Commit 58299fc9 authored by Dick Hollenbeck's avatar Dick Hollenbeck

more fp_lib_table work

parent 69dbeab9
...@@ -74,27 +74,27 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR ...@@ -74,27 +74,27 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR
in->NeedRIGHT(); in->NeedRIGHT();
// (type "TYPE") // (uri "FULL_URI")
in->NeedLEFT(); in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_type ) if( ( tok = in->NextTok() ) != T_full_uri )
in->Expecting( T_type ); in->Expecting( T_full_uri );
in->NeedSYMBOLorNUMBER(); in->NeedSYMBOLorNUMBER();
row.SetType( in->FromUTF8() ); row.SetFullURI( in->FromUTF8() );
in->NeedRIGHT(); in->NeedRIGHT();
// (uri "FULL_URI") // (type "TYPE")
in->NeedLEFT(); in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_full_uri ) if( ( tok = in->NextTok() ) != T_type )
in->Expecting( T_full_uri ); in->Expecting( T_type );
in->NeedSYMBOLorNUMBER(); in->NeedSYMBOLorNUMBER();
row.SetFullURI( in->FromUTF8() ); row.SetType( in->FromUTF8() );
in->NeedRIGHT(); in->NeedRIGHT();
...@@ -142,11 +142,11 @@ void FP_LIB_TABLE::Format( OUTPUTFORMATTER* out, int nestLevel ) const ...@@ -142,11 +142,11 @@ void FP_LIB_TABLE::Format( OUTPUTFORMATTER* out, int nestLevel ) const
void FP_LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const void FP_LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
throw( IO_ERROR ) throw( IO_ERROR )
{ {
out->Print( nestLevel, "(lib (name %s)(type %s)(full_uri %s)(options %s))\n", out->Print( nestLevel, "(lib (name %s)(full_uri %s)(type %s)(options %s))\n",
out->Quotew( nickName ).c_str(), out->Quotew( GetNickName() ).c_str(),
out->Quotew( type ).c_str(), out->Quotew( GetFullURI() ).c_str(),
out->Quotew( uri ).c_str(), out->Quotew( GetType() ).c_str(),
out->Quotew( options ).c_str() out->Quotew( GetOptions() ).c_str()
); );
} }
...@@ -178,19 +178,19 @@ std::vector<wxString> FP_LIB_TABLE::GetLogicalLibs() ...@@ -178,19 +178,19 @@ std::vector<wxString> FP_LIB_TABLE::GetLogicalLibs()
} }
FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const wxString& aNickName ) const const FP_LIB_TABLE::ROW* FP_LIB_TABLE::findRow( const wxString& aNickName )
{ {
// this function must be *super* fast, so therefore should not instantiate FP_LIB_TABLE* cur = this;
// anything which would require using the heap.
const FP_LIB_TABLE* cur = this;
do do
{ {
cur->ensureIndex();
INDEX_CITER it = cur->nickIndex.find( aNickName ); INDEX_CITER it = cur->nickIndex.find( aNickName );
if( it != cur->nickIndex.end() ) if( it != cur->nickIndex.end() )
{ {
return (FP_LIB_TABLE::ROW*) &cur->rows[it->second]; // found return &cur->rows[it->second]; // found
} }
// not found, search fall back table(s), if any // not found, search fall back table(s), if any
...@@ -202,7 +202,7 @@ FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const wxString& aNickName ) const ...@@ -202,7 +202,7 @@ FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const wxString& aNickName ) const
bool FP_LIB_TABLE::InsertRow( const ROW& aRow, bool doReplace ) bool FP_LIB_TABLE::InsertRow( const ROW& aRow, bool doReplace )
{ {
// this does not need to be super fast. ensureIndex();
INDEX_CITER it = nickIndex.find( aRow.nickName ); INDEX_CITER it = nickIndex.find( aRow.nickName );
...@@ -223,82 +223,50 @@ bool FP_LIB_TABLE::InsertRow( const ROW& aRow, bool doReplace ) ...@@ -223,82 +223,50 @@ bool FP_LIB_TABLE::InsertRow( const ROW& aRow, bool doReplace )
} }
const FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const wxString& aLibraryNickName )
#if 0 // will need PLUGIN_RELEASER.
MODULE* FP_LIB_TABLE::LookupFootprint( const FP_LIB_ID& aFootprintId )
throw( IO_ERROR ) throw( IO_ERROR )
{ {
PLUGIN* plugin = lookupLib( aFootprintId ); const ROW* row = findRow( aLibraryNickName );
return plugin->FootprintLoad( FROM_UTF8( aFootprintId.GetBaseName().c_str() ), if( !row )
FROM_UTF8( aFootprintId.GetLogicalLib().c_str() ) ); {
wxString msg = wxString::Format( _("lib table contains no logical lib '%s'" ),
GetChars( aLibraryNickName ) );
THROW_IO_ERROR( msg );
}
return row;
} }
PLUGIN* FP_LIB_TABLE::lookupLib( const FP_LIB_ID& aFootprintId ) PLUGIN* FP_LIB_TABLE::PluginFind( const wxString& aLibraryNickName )
throw( IO_ERROR ) throw( IO_ERROR )
{ {
if( aFootprintId.GetLogicalLib().size() ) const ROW* row = FindRow( aLibraryNickName );
{
ROW* row = FindRow( aFootprintId.GetLogicalLib() );
if( !row ) // row will never be NULL here.
{
std::string msg = "lib table contains no logical lib '";
msg += aFootprintId.GetLogicalLib();
msg += '\'';
THROW_IO_ERROR( msg );
}
if( !row->lib )
{
loadLib( row );
}
assert( row->lib ); // fix loadLib() to throw if cannot load
return row->lib; PLUGIN* plugin = IO_MGR::PluginFind( row->type );
}
std::string msg = "lookupLib() requires logicalLibName"; return plugin;
THROW_IO_ERROR( msg );
} }
void FP_LIB_TABLE::loadLib( ROW* aRow ) throw( IO_ERROR ) #if 0 // don't know that this is needed yet
MODULE* FP_LIB_TABLE::LookupFootprint( const FP_LIB_ID& aFootprintId )
throw( IO_ERROR )
{ {
assert( !aRow->lib ); // caller should know better. const ROW* row = FindRow( aFootprintId.GetLibraryNickName() );
const std::string& type = aRow->GetType(); // row will never be NULL here.
if( !type.compare( "dir" ) )
{
// @todo Look up plug in here.
}
/* PLUGIN::RELEASER pi( PluginFind( row->type ) );
else if( !type.compare( "schematic" ) )
{
// @todo code and load SCHEMATIC_LIB_SOURCE
}
else if( !type.compare( "subversion" ) ) return pi->FootprintLoad( aLibraryPath->GetFullURI() ),
{ aFootprintId.GetFootprintName(),
// @todo code and load SVN_LIB_SOURCE
}
else if( !type.compare( "http" ) ) // fetch a PROPERTIES instance on stack here
{ row->GetPropertiesFromOptions()
// @todo code and load HTTP_LIB_SOURCE );
}
*/
else
{
std::string msg = "cannot load unknown footprint library type: '";
msg += type;
msg += '\'';
THROW_IO_ERROR( msg );
}
} }
#endif #endif
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#ifndef _FP_LIB_TABLE_H_ #ifndef FP_LIB_TABLE_H_
#define _FP_LIB_TABLE_H_ #define FP_LIB_TABLE_H_
#include <macros.h> #include <macros.h>
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <map> #include <map>
#include <fp_lib_id.h> #include <fp_lib_id.h>
#include <io_mgr.h>
class OUTPUTFORMATTER; class OUTPUTFORMATTER;
...@@ -97,6 +98,25 @@ public: ...@@ -97,6 +98,25 @@ public:
public: public:
typedef IO_MGR::PCB_FILE_T LIB_T;
ROW(){}
ROW( const wxString& aNick, const wxString& aURI, const wxString& aType, const wxString& aOptions ) :
nickName( aNick ),
uri( aURI ),
options( aOptions )
{
SetType( aType );
}
bool operator==( const ROW& r ) const
{
return nickName==r.nickName && uri==r.uri && type==r.type && options==r.options;
}
bool operator!=( const ROW& r ) const { return !( *this == r ); }
/** /**
* Function GetNickName * Function GetNickName
* returns the short name of this library table row. * returns the short name of this library table row.
...@@ -110,9 +130,9 @@ public: ...@@ -110,9 +130,9 @@ public:
* Function GetType * Function GetType
* returns the type of LIB represented by this record. * returns the type of LIB represented by this record.
*/ */
const wxString& GetType() const const wxString GetType() const
{ {
return type; return IO_MGR::ShowType( type );
} }
/** /**
...@@ -160,7 +180,7 @@ public: ...@@ -160,7 +180,7 @@ public:
*/ */
void SetType( const wxString& aType ) void SetType( const wxString& aType )
{ {
type = aType; type = IO_MGR::EnumFromStr( aType );
} }
/** /**
...@@ -183,14 +203,11 @@ public: ...@@ -183,14 +203,11 @@ public:
} }
private: private:
wxString nickName; wxString nickName;
wxString type;
wxString uri; wxString uri;
LIB_T type;
wxString options; wxString options;
/*
PLUGIN* lib; ///< ownership of the loaded LIB is here
*/
}; };
...@@ -240,25 +257,6 @@ public: ...@@ -240,25 +257,6 @@ public:
*/ */
void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR ); void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR );
#if 0
/**
* Function LookupPart
* finds and loads a MODULE, and parses it. As long as the part is
* accessible in any LIB_SOURCE, opened or not opened, this function
* will find it and load it into its containing LIB, even if that means
* having to open a LIB in this table that was not previously opened.
*
* @param aFootprintId The fully qualified name of the footprint to look up.
*
* @return MODULE* - this will never be NULL, and no ownership is transferred because
* all MODULEs live in LIBs. You only get to point to them in some LIB. If the MODULE
* cannot be found, then an exception is thrown.
*
* @throw IO_ERROR if any problem occurs or if the footprint cannot be found.
*/
MODULE* LookupFootprint( const FP_LIB_ID& aFootprintId ) throw( IO_ERROR );
#endif
/** /**
* Function GetLogicalLibs * Function GetLogicalLibs
...@@ -267,10 +265,13 @@ public: ...@@ -267,10 +265,13 @@ public:
*/ */
std::vector<wxString> GetLogicalLibs(); std::vector<wxString> GetLogicalLibs();
//----<read accessors>---------------------------------------------------- //----<read accessors>----------------------------------------------------
// the returning of a const wxString* tells if not found, but might be too // the returning of a const wxString* tells if not found, but might be too
// promiscuous? // promiscuous?
#if 0
/** /**
* Function GetURI * Function GetURI
* returns the full library path from a logical library name. * returns the full library path from a logical library name.
...@@ -306,6 +307,7 @@ public: ...@@ -306,6 +307,7 @@ public:
const ROW* row = FindRow( aLogicalLibraryName ); const ROW* row = FindRow( aLogicalLibraryName );
return row ? &row->options : 0; return row ? &row->options : 0;
} }
#endif
//----</read accessors>--------------------------------------------------- //----</read accessors>---------------------------------------------------
...@@ -315,9 +317,6 @@ public: ...@@ -315,9 +317,6 @@ public:
void Test(); void Test();
#endif #endif
protected: // only a table editor can use these
/** /**
* Function InsertRow * Function InsertRow
* adds aRow if it does not already exist or if doReplace is true. If doReplace * adds aRow if it does not already exist or if doReplace is true. If doReplace
...@@ -330,12 +329,29 @@ protected: // only a table editor can use these ...@@ -330,12 +329,29 @@ protected: // only a table editor can use these
*/ */
bool InsertRow( const ROW& aRow, bool doReplace = false ); bool InsertRow( const ROW& aRow, bool doReplace = false );
/**
* Function PluginFind
* returns a PLUGIN*. Caller should wrap that in a PLUGIN::RELEASER()
* so when it goes out of scope, IO_MGR::PluginRelease() is called.
*/
PLUGIN* PluginFind( const wxString& aLibraryNickName ) throw( IO_ERROR );
/** /**
* Function FindRow * Function FindRow
* returns a #ROW* if aNickName is found in this table or in any chained * returns a #ROW* if aNickName is found in this table or in any chained
* fallBack table fragment, else NULL. * fallBack table fragment, else NULL.
*/ */
ROW* FindRow( const wxString& aNickName ) const; const ROW* FindRow( const wxString& aNickName ) throw( IO_ERROR );
protected:
/**
* Function findRow
* returns a #ROW* if aNickName is found in this table or in any chained
* fallBack table fragment, else NULL.
*/
const ROW* findRow( const wxString& aNickName );
void reindex() void reindex()
{ {
...@@ -345,6 +361,15 @@ protected: // only a table editor can use these ...@@ -345,6 +361,15 @@ protected: // only a table editor can use these
nickIndex.insert( INDEX_VALUE( it->nickName, it - rows.begin() ) ); nickIndex.insert( INDEX_VALUE( it->nickName, 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<ROW> ROWS; typedef std::vector<ROW> ROWS;
typedef ROWS::iterator ROWS_ITER; typedef ROWS::iterator ROWS_ITER;
typedef ROWS::const_iterator ROWS_CITER; typedef ROWS::const_iterator ROWS_CITER;
...@@ -364,35 +389,25 @@ protected: // only a table editor can use these ...@@ -364,35 +389,25 @@ protected: // only a table editor can use these
}; };
#if 0 // I don't think this is going to be needed.
#if 0 // lets see what we need.
/** /**
* Function lookupLib * Function LookupPart
* finds or loads a LIB based on @a aLogicalPartID or @a aFallBackLib. * finds and loads a MODULE, and parses it. As long as the part is
* If the LIB is already loaded then it is returned as is, else it is loaded. * accessible in any LIB_SOURCE, opened or not opened, this function
* * will find it and load it into its containing LIB, even if that means
* @param aLogicalPartID holds the partName and may also hold the logicalLibName. If * having to open a LIB in this table that was not previously opened.
* logicalLibName is empty, then @a aFallBackLib should not be NULL.
* *
* @param aFallBackLib is used only if aLogicalPartID has an empty logicalLibName. * @param aFootprintId The fully qualified name of the footprint to look up.
* This is for the case when an LPID has no logicalLibName because the LPID is using
* a partName from the same LIB as was the referring content.
* *
* @return PLUGIN* - this will never be NULL, and no ownership is transfered because * @return MODULE* - this will never be NULL, and no ownership is transferred because
* all LIBs live in the FP_LIB_TABLEs. You only get to point to them in some FP_LIB_TABLE. * all MODULEs live in LIBs. You only get to point to them in some LIB. If the MODULE
* If the LIB cannot be found, then an exception is thrown. * cannot be found, then an exception is thrown.
* *
* @throw IO_ERROR if any problem occurs or if the LIB cannot be found or cannot be loaded. * @throw IO_ERROR if any problem occurs or if the footprint cannot be found.
*/
PLUGIN* lookupLib( const FP_LIB_ID& aLogicalPartID ) throw( IO_ERROR );
/**
* Function loadLib
* loads a LIB using information in @a aRow. Call only if LIB not
* already loaded.
*/ */
void loadLib( ROW* aRow ) throw( IO_ERROR ); MODULE* LookupFootprint( const FP_LIB_ID& aFootprintId ) throw( IO_ERROR );
#endif #endif
#endif // _FP_LIB_TABLE_H_ #endif // FP_LIB_TABLE_H_
...@@ -31,6 +31,11 @@ ...@@ -31,6 +31,11 @@
#include <wx/grid.h> #include <wx/grid.h>
/**
* Class FP_TBL_MODEL
* mixes in wxGridTableBase into FP_LIB_TABLE so that the latter can be used
* as table within wxGrid.
*/
class FP_TBL_MODEL : public wxGridTableBase, public FP_LIB_TABLE class FP_TBL_MODEL : public wxGridTableBase, public FP_LIB_TABLE
{ {
public: public:
...@@ -161,6 +166,9 @@ public: ...@@ -161,6 +166,9 @@ public:
*/ */
class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
{ {
typedef FP_LIB_TABLE::ROW ROW;
//-----<event handlers>---------------------------------- //-----<event handlers>----------------------------------
void pageChangedHandler( wxAuiNotebookEvent& event ) void pageChangedHandler( wxAuiNotebookEvent& event )
...@@ -228,44 +236,13 @@ public: ...@@ -228,44 +236,13 @@ public:
m_global_model( *aGlobal ), m_global_model( *aGlobal ),
m_project_model( *aProject ) m_project_model( *aProject )
{ {
/*
GetSizer()->SetSizeHints( this );
Centre();
SetAutoLayout( true );
Layout();
*/
#if 1 && defined(DEBUG)
// put some dummy data into table(s)
FP_LIB_TABLE::ROW row;
row.SetNickName( wxT( "passives" ) );
row.SetType( wxT( "kicad" ) );
row.SetFullURI( wxT( "%G/passives" ) );
row.SetOptions( wxT( "speed=fast,purpose=testing" ) );
m_global_model.InsertRow( row );
row.SetNickName( wxT( "micros" ) );
row.SetType( wxT( "legacy" ) );
row.SetFullURI( wxT( "%P/micros" ) );
row.SetOptions( wxT( "speed=fast,purpose=testing" ) );
m_global_model.InsertRow( row );
row.SetFullURI( wxT( "%P/chips" ) );
m_project_model.InsertRow( row );
#endif
m_global_grid->SetTable( (wxGridTableBase*) &m_global_model ); m_global_grid->SetTable( (wxGridTableBase*) &m_global_model );
m_project_grid->SetTable( (wxGridTableBase*) &m_project_model ); m_project_grid->SetTable( (wxGridTableBase*) &m_project_model );
//m_global_grid->AutoSize();
m_global_grid->AutoSizeColumns( false ); m_global_grid->AutoSizeColumns( false );
//m_project_grid->AutoSize();
m_project_grid->AutoSizeColumns( false ); m_project_grid->AutoSizeColumns( false );
//m_path_subs_grid->AutoSize();
m_path_subs_grid->AutoSizeColumns( false ); m_path_subs_grid->AutoSizeColumns( false );
} }
...@@ -275,7 +252,8 @@ public: ...@@ -275,7 +252,8 @@ public:
// since the ~wxGrid() wants the wxGridTableBase to still be non-destroyed. // since the ~wxGrid() wants the wxGridTableBase to still be non-destroyed.
// Without this call, the wxGridTableBase objects are destroyed first // Without this call, the wxGridTableBase objects are destroyed first
// (i.e. destructor called) and there is a segfault since wxGridTableBase's vtable // (i.e. destructor called) and there is a segfault since wxGridTableBase's vtable
// is then no longer valid. // is then no longer valid. If ~wxGrid() would not examine a wxGridTableBase that
// it does not own, then this would not be a concern. But it is, since it does.
DestroyChildren(); DestroyChildren();
} }
}; };
......
...@@ -79,22 +79,50 @@ void IO_MGR::PluginRelease( PLUGIN* aPlugin ) ...@@ -79,22 +79,50 @@ void IO_MGR::PluginRelease( PLUGIN* aPlugin )
} }
const wxString IO_MGR::ShowType( PCB_FILE_T aFileType ) const wxString IO_MGR::ShowType( PCB_FILE_T aType )
{ {
switch( aFileType ) // keep this function in sync with EnumFromStr() relative to the
// text spellings. If you change the spellings, you will obsolete
// library tables, so don't do change, only additions are ok.
switch( aType )
{ {
default: default:
return wxString::Format( _( "Unknown PCB_FILE_T value: %d" ), aFileType ); return wxString::Format( _( "Unknown PCB_FILE_T value: %d" ), aType );
case LEGACY: case LEGACY:
return wxString( wxT( "KiCad Legacy" ) ); return wxString( wxT( "Legacy" ) );
case KICAD: case KICAD:
return wxString( wxT( "KiCad" ) ); return wxString( wxT( "KiCad" ) );
case EAGLE:
return wxString( wxT( "Eagle" ) );
} }
} }
IO_MGR::PCB_FILE_T IO_MGR::EnumFromStr( const wxString& aType )
{
// keep this function in sync with ShowType() relative to the
// text spellings. If you change the spellings, you will obsolete
// library tables, so don't do change, only additions are ok.
if( aType == wxT( "KiCad" ) )
return KICAD;
if( aType == wxT( "Legacy" ) )
return LEGACY;
if( aType == wxT( "Eagle" ) )
return EAGLE;
// wxASSERT( blow up here )
return PCB_FILE_T( -1 );
}
const wxString IO_MGR::GetFileExtension( PCB_FILE_T aFileType ) const wxString IO_MGR::GetFileExtension( PCB_FILE_T aFileType )
{ {
wxString ext = wxEmptyString; wxString ext = wxEmptyString;
......
...@@ -87,6 +87,12 @@ public: ...@@ -87,6 +87,12 @@ public:
*/ */
static const wxString ShowType( PCB_FILE_T aFileType ); static const wxString ShowType( PCB_FILE_T aFileType );
/**
* Function EnumFromStr
* returns the PCB_FILE_T from the corresponding plugin type name: "kicad", "legacy", etc.
*/
static PCB_FILE_T EnumFromStr( const wxString& aFileType );
/** /**
* Function GetFileExtension * Function GetFileExtension
* returns the file extension for \a aFileType. * returns the file extension for \a aFileType.
......
...@@ -84,9 +84,19 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) ...@@ -84,9 +84,19 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
case ID_PCB_LIB_TABLE_EDIT: case ID_PCB_LIB_TABLE_EDIT:
{ {
// scaffolding: dummy up some data into tables, until actual load/save are in place.
FP_LIB_TABLE gbl; FP_LIB_TABLE gbl;
FP_LIB_TABLE prj; FP_LIB_TABLE prj;
gbl.InsertRow( FP_LIB_TABLE::ROW(
wxT( "passives" ), wxT( "%G/passives" ), wxT( "KiCad" ), wxT( "speed=fast,purpose=testing" ) ) );
gbl.InsertRow( FP_LIB_TABLE::ROW(
wxT( "micros" ), wxT( "%P/micros" ), wxT( "Legacy" ), wxT( "speed=fast,purpose=testing" ) ) );
prj.InsertRow( FP_LIB_TABLE::ROW(
wxT( "micros" ), wxT( "%P/potato_chips" ), wxT( "Eagle" ), wxT( "speed=fast,purpose=testing" ) ) );
int r = InvokePcbLibTableEditor( this, &gbl, &prj ); int r = InvokePcbLibTableEditor( this, &gbl, &prj );
if( r & 1 ) if( r & 1 )
......
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