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

more fp_lib_table dialog work

parent 07d31b9c
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -154,6 +154,5 @@ Dick's Final TODO List:
*) Apply Fabrizio and Alexander's linux desktop patches after unifying them.
*) Apply Fabrizio and Alexander's linux desktop patches after unifying them.
*) Get licensing cleaned up.
*) Get licensing cleaned up.
*) Re-arrange the repo architecture.
*) Re-arrange the repo architecture.
*) Merge KiCad GAL/TOM/ORSON if nobody else does.
*) DLL-ization of pcbnew & eeschema
*) DLL-ization of pcbnew & eeschema
   http://www.eevblog.com/forum/open-source-kicad-geda/seriously-irritated-with-the-library-editor!/
   http://www.eevblog.com/forum/open-source-kicad-geda/seriously-irritated-with-the-library-editor!/
+101 −100
Original line number Original line Diff line number Diff line
@@ -56,7 +56,7 @@ enum COL_ORDER


/**
/**
 * Class FP_TBL_MODEL
 * Class FP_TBL_MODEL
 * mixes in wxGridTableBase into FP_LIB_TABLE so that the latter can be used
 * mixes in FP_LIB_TABLE into wxGridTableBase so the result can be used
 * as a table within wxGrid.
 * as a table within wxGrid.
 */
 */
class FP_TBL_MODEL : public wxGridTableBase, public FP_LIB_TABLE
class FP_TBL_MODEL : public wxGridTableBase, public FP_LIB_TABLE
@@ -282,6 +282,79 @@ protected:
 */
 */
class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
{
{

public:
    DIALOG_FP_LIB_TABLE( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject ) :
        DIALOG_FP_LIB_TABLE_BASE( aParent ),
        m_global( aGlobal ),
        m_project( aProject )
    {
        // wxGrid only supports user owned tables if they exist past end of ~wxGrid(),
        // so make it a grid owned table.
        m_global_grid->SetTable(  new FP_TBL_MODEL( *aGlobal ),  true );
        m_project_grid->SetTable( new FP_TBL_MODEL( *aProject ), true );

        // add Cut, Copy, and Paste to wxGrids
        m_global_grid->PushEventHandler( new FP_GRID_TRICKS( m_global_grid ) );
        m_project_grid->PushEventHandler( new FP_GRID_TRICKS( m_project_grid ) );

        m_global_grid->AutoSizeColumns( false );
        m_project_grid->AutoSizeColumns( false );

        wxArrayString choices;

        choices.Add( IO_MGR::ShowType( IO_MGR::KICAD ) );
        choices.Add( IO_MGR::ShowType( IO_MGR::GITHUB ) );
        choices.Add( IO_MGR::ShowType( IO_MGR::LEGACY ) );
        choices.Add( IO_MGR::ShowType( IO_MGR::EAGLE ) );
        choices.Add( IO_MGR::ShowType( IO_MGR::GEDA_PCB ) );

        /* PCAD_PLUGIN does not support Footprint*() functions
        choices.Add( IO_MGR::ShowType( IO_MGR::GITHUB ) );
        */

        wxGridCellAttr* attr;

        attr = new wxGridCellAttr;
        attr->SetEditor( new wxGridCellChoiceEditor( choices ) );
        m_project_grid->SetColAttr( COL_TYPE, attr );

        attr = new wxGridCellAttr;
        attr->SetEditor( new wxGridCellChoiceEditor( choices ) );
        m_global_grid->SetColAttr( COL_TYPE, attr );

        m_global_grid->AutoSizeColumns( false );
        m_project_grid->AutoSizeColumns( false );

        /*
        Connect( MYID_FIRST, MYID_LAST, wxEVT_COMMAND_MENU_SELECTED,
            wxCommandEventHandler( DIALOG_FP_LIB_TABLE::onPopupSelection ), NULL, this );
        */

        populateEnvironReadOnlyTable();

        /* This scrunches the dialog hideously
        Fit();
        */

        // fire pageChangedHandler() so m_cur_grid gets set
        wxAuiNotebookEvent uneventful;
        pageChangedHandler( uneventful );

        // for ALT+A handling, we want the initial focus to be on the first selected grid.
        m_cur_grid->SetFocus();
    }

    ~DIALOG_FP_LIB_TABLE()
    {
        // Delete the GRID_TRICKS.
        // Any additional event handlers should be popped before the window is deleted.
        m_global_grid->PopEventHandler( true );
        m_project_grid->PopEventHandler( true );
    }


private:
    typedef FP_LIB_TABLE::ROW   ROW;
    typedef FP_LIB_TABLE::ROW   ROW;


    /// If the cursor is not on a valid cell, because there are no rows at all, return -1,
    /// If the cursor is not on a valid cell, because there are no rows at all, return -1,
@@ -298,7 +371,6 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
        return m_cur_grid->GetGridCursorRow();
        return m_cur_grid->GetGridCursorRow();
    }
    }



    /**
    /**
     * Function verifyTables
     * Function verifyTables
     * trims important fields, removes blank row entries, and checks for duplicates.
     * trims important fields, removes blank row entries, and checks for duplicates.
@@ -308,7 +380,7 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
    {
    {
        for( int t=0; t<2; ++t )
        for( int t=0; t<2; ++t )
        {
        {
            FP_TBL_MODEL& model = t==0 ? m_global_model : m_project_model;
            FP_TBL_MODEL& model = t==0 ? *global_model() : *project_model();


            for( int r = 0; r < model.GetNumberRows(); )
            for( int r = 0; r < model.GetNumberRows(); )
            {
            {
@@ -330,9 +402,9 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
                        wxT( ":" ), GetChars( nick ), r );
                        wxT( ":" ), GetChars( nick ), r );


                    // show the tabbed panel holding the grid we have flunked:
                    // show the tabbed panel holding the grid we have flunked:
                    if( &model != (FP_TBL_MODEL*) m_cur_grid->GetTable() )
                    if( &model != cur_model() )
                    {
                    {
                        m_auinotebook->SetSelection( &model == &m_global_model ? 0 : 1 );
                        m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 );
                    }
                    }


                    // go to the problematic row
                    // go to the problematic row
@@ -357,7 +429,7 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
        // check for duplicate nickNames, separately in each table.
        // check for duplicate nickNames, separately in each table.
        for( int t=0; t<2; ++t )
        for( int t=0; t<2; ++t )
        {
        {
            FP_TBL_MODEL& model = t==0 ? m_global_model : m_project_model;
            FP_TBL_MODEL& model = t==0 ? *global_model() : *project_model();


            for( int r1 = 0; r1 < model.GetNumberRows() - 1;  ++r1 )
            for( int r1 = 0; r1 < model.GetNumberRows() - 1;  ++r1 )
            {
            {
@@ -375,9 +447,9 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
                            );
                            );


                        // show the tabbed panel holding the grid we have flunked:
                        // show the tabbed panel holding the grid we have flunked:
                        if( &model != (FP_TBL_MODEL*) m_cur_grid->GetTable() )
                        if( &model != cur_model() )
                        {
                        {
                            m_auinotebook->SetSelection( &model == &m_global_model ? 0 : 1 );
                            m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 );
                        }
                        }


                        // go to the lower of the two rows, it is technically the duplicate:
                        // go to the lower of the two rows, it is technically the duplicate:
@@ -422,6 +494,7 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
        {
        {
            int last_row = m_cur_grid->GetNumberRows() - 1;
            int last_row = m_cur_grid->GetNumberRows() - 1;


            // wx documentation is wrong, SetGridCursor does not make visible.
            m_cur_grid->MakeCellVisible( last_row, 0 );
            m_cur_grid->MakeCellVisible( last_row, 0 );
            m_cur_grid->SetGridCursor( last_row, 0 );
            m_cur_grid->SetGridCursor( last_row, 0 );
        }
        }
@@ -445,7 +518,7 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
        {
        {
            int curCol = getCursorCol();
            int curCol = getCursorCol();


            FP_TBL_MODEL* tbl = (FP_TBL_MODEL*) m_cur_grid->GetTable();
            FP_TBL_MODEL* tbl = cur_model();


            ROW move_me = tbl->rows[curRow];
            ROW move_me = tbl->rows[curRow];


@@ -464,13 +537,14 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
                tbl->GetView()->ProcessTableMessage( msg );
                tbl->GetView()->ProcessTableMessage( msg );
            }
            }


            m_cur_grid->MakeCellVisible( curRow, curCol );
            m_cur_grid->SetGridCursor( curRow, curCol );
            m_cur_grid->SetGridCursor( curRow, curCol );
        }
        }
    }
    }


    void moveDownHandler( wxMouseEvent& event )
    void moveDownHandler( wxMouseEvent& event )
    {
    {
        FP_TBL_MODEL* tbl = (FP_TBL_MODEL*) m_cur_grid->GetTable();
        FP_TBL_MODEL* tbl = cur_model();


        int curRow = getCursorRow();
        int curRow = getCursorRow();
        if( unsigned( curRow + 1 ) < tbl->rows.size() )
        if( unsigned( curRow + 1 ) < tbl->rows.size() )
@@ -494,14 +568,14 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
                tbl->GetView()->ProcessTableMessage( msg );
                tbl->GetView()->ProcessTableMessage( msg );
            }
            }


            m_cur_grid->MakeCellVisible( curRow, curCol );
            m_cur_grid->SetGridCursor( curRow, curCol );
            m_cur_grid->SetGridCursor( curRow, curCol );
        }
        }
        DBG(printf("%s\n", __func__);)
    }
    }


    void optionsEditor( wxMouseEvent& event )
    void optionsEditor( wxMouseEvent& event )
    {
    {
        FP_TBL_MODEL*   tbl = (FP_TBL_MODEL*) m_cur_grid->GetTable();
        FP_TBL_MODEL*   tbl = cur_model();


        int     curRow = getCursorRow();
        int     curRow = getCursorRow();
        ROW&    row    = tbl->rows[curRow];
        ROW&    row    = tbl->rows[curRow];
@@ -537,19 +611,19 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE


        if( verifyTables() )
        if( verifyTables() )
        {
        {
            if( m_global_model != *m_global )
            if( *global_model() != *m_global )
            {
            {
                dialogRet |= 1;
                dialogRet |= 1;


                *m_global  = m_global_model;
                *m_global  = *global_model();
                m_global->reindex();
                m_global->reindex();
            }
            }


            if( m_project_model != *m_project )
            if( *project_model() != *m_project )
            {
            {
                dialogRet |= 2;
                dialogRet |= 2;


                *m_project = m_project_model;
                *m_project = *project_model();
                m_project->reindex();
                m_project->reindex();
            }
            }


@@ -570,13 +644,16 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
        // clear the table
        // clear the table
        m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() );
        m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() );


        int gblRowCount = m_global_model.GetNumberRows();
        FP_TBL_MODEL*   gbl = global_model();
        int prjRowCount = m_project_model.GetNumberRows();
        FP_TBL_MODEL*   prj = project_model();

        int gblRowCount = gbl->GetNumberRows();
        int prjRowCount = prj->GetNumberRows();
        int row;
        int row;


        for( row = 0;  row < gblRowCount;  ++row )
        for( row = 0;  row < gblRowCount;  ++row )
        {
        {
            wxString uri = m_global_model.GetValue( row, COL_URI );
            wxString uri = gbl->GetValue( row, COL_URI );


            while( re.Matches( uri ) )
            while( re.Matches( uri ) )
            {
            {
@@ -592,7 +669,7 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE


        for( row = 0;  row < prjRowCount;  ++row )
        for( row = 0;  row < prjRowCount;  ++row )
        {
        {
            wxString uri = m_project_model.GetValue( row, COL_URI );
            wxString uri = prj->GetValue( row, COL_URI );


            while( re.Matches( uri ) )
            while( re.Matches( uri ) )
            {
            {
@@ -625,91 +702,15 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE


    //-----</event handlers>---------------------------------
    //-----</event handlers>---------------------------------


    // caller's tables are modified only on OK button.
    // caller's tables are modified only on OK button and successful verification.
    FP_LIB_TABLE*       m_global;
    FP_LIB_TABLE*       m_global;
    FP_LIB_TABLE*       m_project;
    FP_LIB_TABLE*       m_project;


    // local copies which are edited, but aborted if Cancel button.
    FP_TBL_MODEL*       global_model()  const   { return (FP_TBL_MODEL*) m_global_grid->GetTable(); }
    FP_TBL_MODEL        m_global_model;
    FP_TBL_MODEL*       project_model() const   { return (FP_TBL_MODEL*) m_project_grid->GetTable(); }
    FP_TBL_MODEL        m_project_model;
    FP_TBL_MODEL*       cur_model() const       { return (FP_TBL_MODEL*) m_cur_grid->GetTable(); }


    wxGrid*             m_cur_grid;     ///< changed based on tab choice
    wxGrid*             m_cur_grid;     ///< changed based on tab choice

public:
    DIALOG_FP_LIB_TABLE( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject ) :
        DIALOG_FP_LIB_TABLE_BASE( aParent ),
        m_global( aGlobal ),
        m_project( aProject ),
        m_global_model( *aGlobal ),
        m_project_model( *aProject )
    {
        m_global_grid->SetTable( (wxGridTableBase*) &m_global_model );
        m_project_grid->SetTable( (wxGridTableBase*) &m_project_model );

        // add Cut, Copy, and Paste to wxGrids
        m_global_grid->PushEventHandler( new FP_GRID_TRICKS( m_global_grid ) );
        m_project_grid->PushEventHandler( new FP_GRID_TRICKS( m_project_grid ) );

        m_global_grid->AutoSizeColumns( false );
        m_project_grid->AutoSizeColumns( false );

        wxArrayString choices;

        choices.Add( IO_MGR::ShowType( IO_MGR::KICAD ) );
        choices.Add( IO_MGR::ShowType( IO_MGR::GITHUB ) );
        choices.Add( IO_MGR::ShowType( IO_MGR::LEGACY ) );
        choices.Add( IO_MGR::ShowType( IO_MGR::EAGLE ) );
        choices.Add( IO_MGR::ShowType( IO_MGR::GEDA_PCB ) );

        /* PCAD_PLUGIN does not support Footprint*() functions
        choices.Add( IO_MGR::ShowType( IO_MGR::GITHUB ) );
        */

        wxGridCellAttr* attr;

        attr = new wxGridCellAttr;
        attr->SetEditor( new wxGridCellChoiceEditor( choices ) );
        m_project_grid->SetColAttr( COL_TYPE, attr );

        attr = new wxGridCellAttr;
        attr->SetEditor( new wxGridCellChoiceEditor( choices ) );
        m_global_grid->SetColAttr( COL_TYPE, attr );

        m_global_grid->AutoSizeColumns( false );
        m_project_grid->AutoSizeColumns( false );

        /*
        Connect( MYID_FIRST, MYID_LAST, wxEVT_COMMAND_MENU_SELECTED,
            wxCommandEventHandler( DIALOG_FP_LIB_TABLE::onPopupSelection ), NULL, this );
        */

        populateEnvironReadOnlyTable();

        /* This scrunches the dialog hideously
        Fit();
        */

        // fire pageChangedHandler() so m_cur_grid gets set
        wxAuiNotebookEvent uneventful;
        pageChangedHandler( uneventful );

        // for ALT+A handling, we want the initial focus to be on the first selected grid.
        m_cur_grid->SetFocus();
    }

    ~DIALOG_FP_LIB_TABLE()
    {
        // Delete the GRID_TRICKS.
        // Any additional event handlers should be popped before the window is deleted.
        m_global_grid->PopEventHandler( true );
        m_project_grid->PopEventHandler( true );

        // ~wxGrid() examines its table, and the tables will have been destroyed before
        // the wxGrids are, so remove the tables from the wxGrids' awareness.
        // Otherwise there is a segfault.
        m_global_grid->SetTable( NULL );
        m_project_grid->SetTable( NULL );
    }
};
};




+121 −1
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@
 */
 */




#include <fctsys.h>
#include <invoke_pcb_dialog.h>
#include <invoke_pcb_dialog.h>
#include <dialog_fp_plugin_options_base.h>
#include <dialog_fp_plugin_options_base.h>
#include <fp_lib_table.h>
#include <fp_lib_table.h>
@@ -36,6 +37,12 @@ static int col_width_option;
static int col_width_value;
static int col_width_value;




/**
 * Class DIALOG_FP_PLUGIN_OPTIONS
 * is an options editor in the form of a two column name/value
 * spreadsheet like (table) UI.  It takes hints from a pcbnew PLUGIN as to
 * supported options.
 */
class DIALOG_FP_PLUGIN_OPTIONS : public DIALOG_FP_PLUGIN_OPTIONS_BASE
class DIALOG_FP_PLUGIN_OPTIONS : public DIALOG_FP_PLUGIN_OPTIONS_BASE
{
{


@@ -60,7 +67,7 @@ public:


        if( props )
        if( props )
        {
        {
            if( props->size() > m_grid->GetNumberRows() )
            if( (int) props->size() > m_grid->GetNumberRows() )
                m_grid->AppendRows( props->size() - m_grid->GetNumberRows() );
                m_grid->AppendRows( props->size() - m_grid->GetNumberRows() );


            int row = 0;
            int row = 0;
@@ -98,6 +105,42 @@ private:
    const wxString& m_callers_options;
    const wxString& m_callers_options;
    wxString*       m_result;
    wxString*       m_result;


    /// If the cursor is not on a valid cell, because there are no rows at all, return -1,
    /// else return a 0 based column index.
    int getCursorCol() const
    {
        return m_grid->GetGridCursorCol();
    }

    /// If the cursor is not on a valid cell, because there are no rows at all, return -1,
    /// else return a 0 based row index.
    int getCursorRow() const
    {
        return m_grid->GetGridCursorRow();
    }

    wxArrayString getRow( int aRow )
    {
        wxArrayString row;

        const int col_count = m_grid->GetNumberCols();
        for( int col = 0;  col < col_count;  ++col )
        {
            row.Add( m_grid->GetCellValue( aRow, col ) );
        }

        return row;
    }

    void setRow( int aRow, const wxArrayString& aPair )
    {
        const int col_count = m_grid->GetNumberCols();
        for( int col = 0;  col < col_count;  ++col )
        {
            m_grid->SetCellValue( aRow, col, aPair[col] );
        }
    }

    wxString makeResult()
    wxString makeResult()
    {
    {
        PROPERTIES  props;
        PROPERTIES  props;
@@ -133,21 +176,98 @@ private:
        EndModal( 0 );
        EndModal( 0 );
    }
    }




    //-----<event handlers>------------------------------------------------------
    //-----<event handlers>------------------------------------------------------
    void onAddRow( wxCommandEvent& event )
    void onAddRow( wxCommandEvent& event )
    {
    {
        if( m_grid->AppendRows( 1 ) )
        {
            int last_row = m_grid->GetNumberRows() - 1;

            // wx documentation is wrong, SetGridCursor does not make visible.
            m_grid->MakeCellVisible( last_row, 0 );
            m_grid->SetGridCursor( last_row, 0 );
        }
    }
    }


    void onDeleteRow( wxCommandEvent& event )
    void onDeleteRow( wxCommandEvent& event )
    {
    {
        int rowCount = m_grid->GetNumberRows();
        int curRow   = getCursorRow();

        m_grid->DeleteRows( curRow );

        if( curRow && curRow == rowCount - 1 )
        {
            m_grid->MakeCellVisible( curRow-1, getCursorCol() );
            m_grid->SetGridCursor( curRow-1, getCursorCol() );
        }
    }
    }


    void onMoveUp( wxCommandEvent& event )
    void onMoveUp( wxCommandEvent& event )
    {
    {
        int curRow = getCursorRow();
        if( curRow >= 1 )
        {
            int curCol = getCursorCol();

            wxArrayString move_me = getRow( curRow );

            m_grid->DeleteRows( curRow );
            --curRow;
            m_grid->InsertRows( curRow );

            setRow( curRow, move_me );

            wxGridTableBase* tbl = m_grid->GetTable();

            if( tbl->GetView() )
            {
                // fire a msg to cause redrawing
                wxGridTableMessage msg( tbl,
                                        wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
                                        curRow,
                                        0 );

                tbl->GetView()->ProcessTableMessage( msg );
            }

            m_grid->MakeCellVisible( curRow, curCol );
            m_grid->SetGridCursor( curRow, curCol );
        }
    }
    }


    void onMoveDown( wxCommandEvent& event )
    void onMoveDown( wxCommandEvent& event )
    {
    {
        int curRow = getCursorRow();
        if( curRow + 1 < m_grid->GetNumberRows() )
        {
            int curCol  = getCursorCol();

            wxArrayString move_me = getRow( curRow );

            m_grid->DeleteRows( curRow );
             ++curRow;
            m_grid->InsertRows( curRow );
            setRow( curRow, move_me );

            wxGridTableBase* tbl = m_grid->GetTable();

            if( tbl->GetView() )
            {
                // fire a msg to cause redrawing
                wxGridTableMessage msg( tbl,
                                        wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
                                        curRow - 1,
                                        0 );

                tbl->GetView()->ProcessTableMessage( msg );
            }

            m_grid->MakeCellVisible( curRow, curCol );
            m_grid->SetGridCursor( curRow, curCol );
        }
    }
    }


    void onCancelButtonClick( wxCommandEvent& event )
    void onCancelButtonClick( wxCommandEvent& event )