Commit ae19bbfa authored by Dick Hollenbeck's avatar Dick Hollenbeck
Browse files

add dialog for fp_lib_table

parent 77e1a4c0
Loading
Loading
Loading
Loading
+43 −52
Original line number Diff line number Diff line
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
 * Copyright (C) 2010-12 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
 * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
 * Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors.
 *
@@ -39,7 +39,7 @@ FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) :
    fallBack( aFallBackTable )
{
    // not copying fall back, simply search aFallBackTable separately
    // if "logicalName not found".
    // if "nickName not found".
}


@@ -68,9 +68,9 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR

        in->NeedSYMBOLorNUMBER();

        std::auto_ptr<ROW> row( new ROW( this ) );
        ROW     row( this );

        row->SetLogicalName( in->CurText() );
        row.SetNickName( in->FromUTF8() );

        in->NeedRIGHT();

@@ -82,7 +82,7 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR

        in->NeedSYMBOLorNUMBER();

        row->SetType( in->CurText() );
        row.SetType( in->FromUTF8() );

        in->NeedRIGHT();

@@ -94,7 +94,7 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR

        in->NeedSYMBOLorNUMBER();

        row->SetFullURI( in->CurText() );
        row.SetFullURI( in->FromUTF8() );

        in->NeedRIGHT();

@@ -106,23 +106,21 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR

        in->NeedSYMBOLorNUMBER();

        row->SetOptions( in->CurText() );
        row.SetOptions( in->FromUTF8() );

        in->NeedRIGHT();
        in->NeedRIGHT();            // terminate the (lib..)

        // all logicalNames within this table fragment must be unique, so we do not
        // 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 logicalName and ours will supercede that one since in
        // conflicting nickName and ours will supercede that one since in
        // FindLib() we search this table before any fall back.
        if( !InsertRow( row ) )
        {
            std::string msg;

            msg += '\'';
            msg += row->logicalName;
            msg += '\'';
            msg += " is a duplicate logical footprint library name";
            wxString msg = wxString::Format(
                                _( "'%s' is a duplicate footprint library nickName" ),
                                GetChars( row.nickName )
                                );
            THROW_IO_ERROR( msg );
        }
    }
@@ -135,7 +133,7 @@ void FP_LIB_TABLE::Format( OUTPUTFORMATTER* out, int nestLevel ) const
    out->Print( nestLevel, "(fp_lib_table\n" );

    for( ROWS_CITER it = rows.begin();  it != rows.end();  ++it )
        it->second->Format( out, nestLevel+1 );
        it->Format( out, nestLevel+1 );

    out->Print( nestLevel, ")\n" );
}
@@ -144,48 +142,50 @@ void FP_LIB_TABLE::Format( OUTPUTFORMATTER* out, int nestLevel ) const
void FP_LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
    throw( IO_ERROR )
{
    out->Print( nestLevel, "(lib (logical %s)(type %s)(full_uri %s)(options %s))\n",
                out->Quotes( logicalName ).c_str(),
                out->Quotes( type ).c_str(),
                out->Quotes( uri ).c_str(),
                out->Quotes( options ).c_str() );
    out->Print( nestLevel, "(lib (name %s)(type %s)(full_uri %s)(options %s))\n",
                out->Quotew( nickName ).c_str(),
                out->Quotew( type ).c_str(),
                out->Quotew( uri ).c_str(),
                out->Quotew( options ).c_str()
                );
}


std::vector<std::string> FP_LIB_TABLE::GetLogicalLibs()
std::vector<wxString> 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
    // logical lib name from one of the fall back table(s).
    // nickname from one of the fall back table(s).

    std::set<std::string>      unique;
    std::vector<std::string>   ret;
    std::set<wxString>          unique;
    std::vector<wxString>       ret;
    const FP_LIB_TABLE*         cur = this;

    do
    {
        for( ROWS_CITER it = cur->rows.begin();  it!=cur->rows.end();  ++it )
        {
            unique.insert( it->second->logicalName );
            unique.insert( it->nickName );
        }

    } while( ( cur = cur->fallBack ) != 0 );

    // return a sorted, unique set of logical lib name std::vector<std::string> to caller
    for( std::set<std::string>::const_iterator it = unique.begin();  it!=unique.end();  ++it )
    // return a sorted, unique set of nicknames in a std::vector<wxString> to caller
    for( std::set<wxString>::const_iterator it = unique.begin();  it!=unique.end();  ++it )
        ret.push_back( *it );

    return ret;
}


#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( wxString( aFootprintId.GetBaseName().c_str() ),
                                  wxString( aFootprintId.GetLogicalLib().c_str() ) );
    return plugin->FootprintLoad( FROM_UTF8( aFootprintId.GetBaseName().c_str() ),
                                  FROM_UTF8( aFootprintId.GetLogicalLib().c_str() ) );
}


@@ -254,24 +254,22 @@ void FP_LIB_TABLE::loadLib( ROW* aRow ) throw( IO_ERROR )
        THROW_IO_ERROR( msg );
    }
}
#endif


FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const std::string& aLogicalName ) const
FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const wxString& aNickName ) const
{
    // this function must be *super* fast, so therefore should not instantiate
    // anything which would require using the heap.  This function is the reason
    // ptr_map<> was used instead of ptr_set<>, which would have required
    // instantiating a ROW just to find a ROW.
    // anything which would require using the heap.
    const FP_LIB_TABLE* cur = this;

    do
    {
        ROWS_CITER  it = cur->rows.find( aLogicalName );
        INDEX_CITER  it = cur->nickIndex.find( aNickName );

        if( it != cur->rows.end() )
        if( it != cur->nickIndex.end() )
        {
            // reference: http://myitcorner.com/blog/?p=361
            return (FP_LIB_TABLE::ROW*) it->second;  // found
            return (FP_LIB_TABLE::ROW*) &cur->rows[it->second];  // found
        }

        // not found, search fall back table(s), if any
@@ -281,29 +279,22 @@ FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRow( const std::string& aLogicalName ) cons
}


bool FP_LIB_TABLE::InsertRow( std::auto_ptr<ROW>& aRow, bool doReplace )
bool FP_LIB_TABLE::InsertRow( const ROW& aRow, bool doReplace )
{
    // this does not need to be super fast.

    ROWS_CITER it = rows.find( aRow->logicalName );
    INDEX_CITER it = nickIndex.find( aRow.nickName );

    if( it == rows.end() )
    if( it == nickIndex.end() )
    {
        // be careful here, key is needed because aRow can be
        // release()ed before logicalName is captured.
        const std::string& key = aRow->logicalName;
        rows.insert( key, aRow );
        rows.push_back( aRow );
        nickIndex.insert( INDEX_VALUE( aRow.nickName, rows.size() - 1 ) );
        return true;
    }

    if( doReplace )
    {
        rows.erase( aRow->logicalName );

        // be careful here, key is needed because aRow can be
        // release()ed before logicalName is captured.
        const std::string&   key = aRow->logicalName;
        rows.insert( key, aRow );
        rows[it->second] = aRow;
        return true;
    }

+3 −6
Original line number Diff line number Diff line
@@ -27,9 +27,6 @@
#define DLIST_H_


#include <stdio.h>          // NULL definition.


class EDA_ITEM;


@@ -216,20 +213,20 @@ public:

    //-----< STL like functions >---------------------------------------
    T* begin() const { return GetFirst(); }
    T* end() const { return NULL; }
    T* end() const { return 0; }

    T* PopFront()
    {
        if( GetFirst() )
            return Remove( GetFirst() );
        return NULL;
        return 0;
    }

    T* PopBack()
    {
        if( GetLast() )
            return Remove( GetLast() );
        return NULL;
        return 0;
    }

    /**
+121 −44
Original line number Diff line number Diff line
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
 * Copyright (C) 2010-12 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
 * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
 * Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors.
 *
@@ -26,16 +26,18 @@
#ifndef _FP_LIB_TABLE_H_
#define _FP_LIB_TABLE_H_

#include <macros.h>

#include <fp_lib_id.h>
#include <vector>
#include <map>

#include <boost/ptr_container/ptr_map.hpp>
#include <wx/grid.h>
#include <fp_lib_id.h>


class OUTPUTFORMATTER;


class MODULE;
class FP_LIB_TABLE_LEXER;

/**
 * Class FP_LIB_TABLE
@@ -78,7 +80,7 @@ class MODULE;
 *
 * @author Wayne Stambaugh
 */
class FP_LIB_TABLE
class FP_LIB_TABLE : public wxGridTableBase
{
public:

@@ -94,19 +96,19 @@ public:
    public:

        /**
         * Function GetLogicalName
         * returns the logical name of this library table row.
         * Function GetNickName
         * returns the short name of this library table row.
         */
        const std::string& GetLogicalName() const
        const wxString& GetNickName() const
        {
            return logicalName;
            return nickName;
        }

        /**
         * Function GetType
         * returns the type of LIB represented by this record.
         */
        const std::string& GetType() const
        const wxString& GetType() const
        {
            return type;
        }
@@ -115,7 +117,7 @@ public:
         * Function GetFullURI
         * returns the full location specifying URI for the LIB.
         */
        const std::string& GetFullURI() const
        const wxString& GetFullURI() const
        {
            return uri;
        }
@@ -125,14 +127,14 @@ public:
         * returns the options string, which may hold a password or anything else needed to
         * instantiate the underlying LIB_SOURCE.
         */
        const std::string& GetOptions() const
        const wxString& GetOptions() const
        {
            return options;
        }

        ~ROW()
        {
            delete lib;
            // delete lib;
        }

        /**
@@ -149,24 +151,24 @@ public:
    protected:

        ROW( FP_LIB_TABLE* aOwner ) :
            owner( aOwner ),
            lib( 0 )
            owner( aOwner )
            // lib( 0 )
        {}

        /**
         * Function SetLogicalName
         * Function SetNickName
         * changes the logical name of this library, useful for an editor.
         */
        void SetLogicalName( const std::string& aLogicalName )
        void SetNickName( const wxString& aNickName )
        {
            logicalName = aLogicalName;
            nickName = aNickName;
        }

        /**
         * Function SetType
         * changes the type represented by this record.
         */
        void SetType( const std::string& aType )
        void SetType( const wxString& aType )
        {
            type = aType;
        }
@@ -175,7 +177,7 @@ public:
         * Function SetFullURI
         * changes the full URI for the library, useful from a library table editor.
         */
        void SetFullURI( const std::string& aFullURI )
        void SetFullURI( const wxString& aFullURI )
        {
            uri = aFullURI;
        }
@@ -185,21 +187,24 @@ public:
         * changes the options string for this record, and is useful from
         * the library table editor.
         */
        void SetOptions( const std::string& aOptions )
        void SetOptions( const wxString& aOptions )
        {
            options = aOptions;
        }

    private:
        FP_LIB_TABLE*   owner;
        std::string    logicalName;
        std::string    type;
        std::string    uri;
        std::string    options;
        wxString        nickName;
        wxString        type;
        wxString        uri;
        wxString        options;

        /*
        PLUGIN*         lib;        ///< ownership of the loaded LIB is here
        */
    };


    /**
     * Constructor FP_LIB_TABLE
     * builds a library table by pre-pending this table fragment in front of
@@ -246,6 +251,7 @@ public:
     */
    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
@@ -262,25 +268,83 @@ public:
     * @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
     * returns the logical library names, all of them that are pertinent to
     * a lookup done on this FP_LIB_TABLE.
     */
    std::vector<std::string> GetLogicalLibs();
    std::vector<wxString> GetLogicalLibs();


    //-----<wxGridTableBase overloads>-------------------------------------------

    int         GetNumberRows () { return rows.size(); }
    int         GetNumberCols () { return 4; }

    wxString    GetValue( int aRow, int aCol )
    {
        if( unsigned( aRow ) < rows.size() )
        {
            const ROW&  r  = rows[aRow];

            switch( aCol )
            {
            case 0:     return r.GetNickName();
            case 1:     return r.GetType();
            case 2:     return r.GetFullURI();
            case 3:     return r.GetOptions();
            default:
                ;       // fall thru to wxEmptyString
            }
        }

        return wxEmptyString;
    }

    void    SetValue( int aRow, int aCol, const wxString &aValue )
    {
        if( aCol == 0 )
        {
            // when the nickname is changed, there's careful work to do, including
            // ensuring uniqueness of the nickname.
        }
        else if( unsigned( aRow ) < rows.size() )
        {
            ROW&  r  = rows[aRow];

            switch( aCol )
            {
            case 1:     r.SetType( aValue  );
            case 2:     r.SetFullURI( aValue );
            case 3:     r.SetOptions( aValue );
            }
        }
    }

    bool IsEmptyCell( int aRow, int aCol )
    {
        if( unsigned( aRow ) < rows.size() )
            return false;
        return true;
    }

    //-----</wxGridTableBase overloads>------------------------------------------


    //----<read accessors>----------------------------------------------------
    // the returning of a const std::string* tells if not found, but might be too
    // the returning of a const wxString* tells if not found, but might be too
    // promiscuous?

    /**
     * Function GetURI
     * returns the full library path from a logical library name.
     * @param aLogicalLibraryName is the short name for the library of interest.
     * @return const std::string* - or NULL if not found.
     * @return const wxString* - or NULL if not found.
     */
    const std::string* GetURI( const std::string& aLogicalLibraryName ) const
    const wxString* GetURI( const wxString& aLogicalLibraryName ) const
    {
        const ROW* row = FindRow( aLogicalLibraryName );
        return row ? &row->uri : 0;
@@ -290,9 +354,9 @@ public:
     * Function GetType
     * returns the type of a logical library.
     * @param aLogicalLibraryName is the short name for the library of interest.
     * @return const std::string* - or NULL if not found.
     * @return const wxString* - or NULL if not found.
     */
    const std::string* GetType( const std::string& aLogicalLibraryName ) const
    const wxString* GetType( const wxString& aLogicalLibraryName ) const
    {
        const ROW* row = FindRow( aLogicalLibraryName );
        return row ? &row->type : 0;
@@ -302,9 +366,9 @@ public:
     * Function GetLibOptions
     * returns the options string for \a aLogicalLibraryName.
     * @param aLogicalLibraryName is the short name for the library of interest.
     * @return const std::string* - or NULL if not found.
     * @return const wxString* - or NULL if not found.
     */
    const std::string* GetLibOptions( const std::string& aLogicalLibraryName ) const
    const wxString* GetLibOptions( const wxString& aLogicalLibraryName ) const
    {
        const ROW* row = FindRow( aLogicalLibraryName );
        return row ? &row->options : 0;
@@ -324,23 +388,24 @@ protected: // only a table editor can use these
     * 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 logicalName, and all in this table must be unique.
     * 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( std::auto_ptr<ROW>& aRow, bool doReplace = false );
    bool InsertRow( const ROW& aRow, bool doReplace = false );

    /**
     * Function FindRow
     * returns a #ROW* if aLogicalName 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.
     */
    ROW* FindRow( const std::string& aLogicalName ) const;
    ROW* FindRow( const wxString& aNickName ) const;

private:

#if 0   // lets see what we need.
    /**
     * Function lookupLib
     * finds or loads a LIB based on @a aLogicalPartID or @a aFallBackLib.
@@ -367,12 +432,24 @@ private:
     * already loaded.
     */
    void loadLib( ROW* aRow ) throw( IO_ERROR );
#endif

    typedef boost::ptr_map<std::string, ROW>    ROWS;
    typedef std::vector<ROW>            ROWS;
    typedef ROWS::iterator              ROWS_ITER;
    typedef ROWS::const_iterator        ROWS_CITER;

    ROWS           rows;

    /// this is a non-owning index into the ROWS table
    typedef std::map<wxString,int>      INDEX;              // "int" is std::vector array index
    typedef INDEX::iterator             INDEX_ITER;
    typedef INDEX::const_iterator       INDEX_CITER;
    typedef INDEX::value_type           INDEX_VALUE;


    /// the particular key is the nickName within each row.
    INDEX           nickIndex;

    FP_LIB_TABLE*  fallBack;
};

+15 −3
Original line number Diff line number Diff line
@@ -26,8 +26,8 @@
 * @file wxPcbStruct.h
 */

#ifndef  WXPCB_STRUCT_H
#define  WXPCB_STRUCT_H
#ifndef  WXPCB_STRUCT_H_
#define  WXPCB_STRUCT_H_


#include <wxBasePcbFrame.h>
@@ -1604,4 +1604,16 @@ public:
};


#endif  /* WXPCB_STRUCT_H */
class FP_LIB_TABLE;

/**
 * Function InvokePcbLibTableEditor
 * shows the modal DIALOG_FP_LIB_TABLE for purposes of editing two lib tables.
 *
 * @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( wxFrame* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject );


#endif  // WXPCB_STRUCT_H_
+32 −30
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ set(PCBNEW_DIALOGS
    dialogs/dialog_export_3Dfiles_base.cpp
    dialogs/dialog_find_base.cpp
    dialogs/dialog_find.cpp
    dialogs/dialog_fp_lib_table_base.cpp
    dialogs/dialog_fp_lib_table.cpp
    dialogs/dialog_freeroute_exchange.cpp
    dialogs/dialog_freeroute_exchange_base.cpp
    dialogs/dialog_gendrill.cpp
Loading