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

more fp_lib_table work

parent 69dbeab9
Loading
Loading
Loading
Loading
+45 −77
Original line number Original line Diff line number Diff line
@@ -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
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()
}
}




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


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 )
}
}





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 )
{
    PLUGIN* plugin = lookupLib( aFootprintId );

    return plugin->FootprintLoad( FROM_UTF8( aFootprintId.GetBaseName().c_str() ),
                                  FROM_UTF8( aFootprintId.GetLogicalLib().c_str() ) );
}


PLUGIN* FP_LIB_TABLE::lookupLib( const FP_LIB_ID& aFootprintId )
    throw( IO_ERROR )
    throw( IO_ERROR )
{
{
    if( aFootprintId.GetLogicalLib().size() )
    const ROW* row = findRow( aLibraryNickName );
    {
        ROW* row = FindRow( aFootprintId.GetLogicalLib() );


    if( !row )
    if( !row )
    {
    {
            std::string msg = "lib table contains no logical lib '";
        wxString msg = wxString::Format( _("lib table contains no logical lib '%s'" ),
            msg += aFootprintId.GetLogicalLib();
                            GetChars( aLibraryNickName ) );
            msg += '\'';
        THROW_IO_ERROR( msg );
        THROW_IO_ERROR( msg );
    }
    }


        if( !row->lib )
    return row;
        {
            loadLib( row );
}
}


        assert( row->lib );     // fix loadLib() to throw if cannot load


        return row->lib;
PLUGIN* FP_LIB_TABLE::PluginFind( const wxString& aLibraryNickName )
    }
    throw( IO_ERROR )
{
    const ROW* row = FindRow( aLibraryNickName );


    std::string msg = "lookupLib() requires logicalLibName";
    // row will never be NULL here.
    THROW_IO_ERROR( msg );
}


    PLUGIN* plugin = IO_MGR::PluginFind( row->type );


void FP_LIB_TABLE::loadLib( ROW* aRow ) throw( IO_ERROR )
    return plugin;
{
}
    assert( !aRow->lib );   // caller should know better.


    const std::string& type = aRow->GetType();


    if( !type.compare( "dir" ) )
#if 0  // don't know that this is needed yet
MODULE* FP_LIB_TABLE::LookupFootprint( const FP_LIB_ID& aFootprintId )
    throw( IO_ERROR )
{
{
        // @todo Look up plug in here.
    const ROW* row = FindRow( aFootprintId.GetLibraryNickName() );
    }


/*
    // row will never be NULL here.
    else if( !type.compare( "schematic" ) )
    {
        // @todo code and load SCHEMATIC_LIB_SOURCE
    }


    else if( !type.compare( "subversion" ) )
    PLUGIN::RELEASER pi( PluginFind( row->type ) );
    {
        // @todo code and load SVN_LIB_SOURCE
    }


    else if( !type.compare( "http" ) )
    return pi->FootprintLoad(   aLibraryPath->GetFullURI() ),
    {
                                aFootprintId.GetFootprintName(),
        // @todo code and load HTTP_LIB_SOURCE

    }
                                // fetch a PROPERTIES instance on stack here
*/
                                row->GetPropertiesFromOptions()
    else
                                );
    {
        std::string msg = "cannot load unknown footprint library type: '";
        msg += type;
        msg += '\'';
        THROW_IO_ERROR( msg );
    }
}
}
#endif
#endif
+71 −56
Original line number Original line Diff line number Diff line
@@ -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 @@
#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:


    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:
         * 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:
         */
         */
        void SetType( const wxString& aType )
        void SetType( const wxString& aType )
        {
        {
            type = aType;
            type = IO_MGR::EnumFromStr( aType );
        }
        }


        /**
        /**
@@ -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:
     */
     */
    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:
     */
     */
    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:
        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:
    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
     */
     */
    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
            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
};
};




#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_
+10 −32
Original line number Original line Diff line number Diff line
@@ -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:
 */
 */
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:
        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:
        // 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();
    }
    }
};
};
+32 −4
Original line number Original line Diff line number Diff line
@@ -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;
+6 −0
Original line number Original line Diff line number Diff line
@@ -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.
Loading