From 38a0857a6900ecad2b0649df40934c85f6fd344e Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Wed, 23 Oct 2013 13:56:03 -0500 Subject: [PATCH] *) Factor out Cut, Copy, and Paste for wxGrid into class common/GRID_TRICKS. *) Use it on 3 grids total in DIALOG_FP_PLUGIN_OPTIONS and DIALOG_FP_LIB_TABLE. *) Fix bug when pasting "(fp_lib_table" text into FP_LIB_TABLE. --- common/CMakeLists.txt | 1 + common/grid_tricks.cpp | 282 ++++++++++++ include/fp_lib_table.h | 6 +- include/grid_tricks.h | 96 +++++ pcbnew/dialogs/dialog_fp_lib_table.cpp | 403 ++++-------------- pcbnew/dialogs/dialog_fp_lib_table_base.cpp | 20 - pcbnew/dialogs/dialog_fp_lib_table_base.fbp | 30 +- pcbnew/dialogs/dialog_fp_lib_table_base.h | 6 +- pcbnew/dialogs/dialog_fp_plugin_options.cpp | 15 + .../dialogs/dialog_fp_plugin_options_base.cpp | 34 +- .../dialogs/dialog_fp_plugin_options_base.fbp | 2 +- .../dialogs/dialog_fp_plugin_options_base.h | 2 +- 12 files changed, 523 insertions(+), 374 deletions(-) create mode 100644 common/grid_tricks.cpp create mode 100644 include/grid_tricks.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 73258dbba1..01d2426a95 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -73,6 +73,7 @@ set(COMMON_SRCS filter_reader.cpp gestfich.cpp getrunningmicrosecs.cpp + grid_tricks.cpp gr_basic.cpp hotkeys_basic.cpp hotkey_grid_table.cpp diff --git a/common/grid_tricks.cpp b/common/grid_tricks.cpp new file mode 100644 index 0000000000..768175a080 --- /dev/null +++ b/common/grid_tricks.cpp @@ -0,0 +1,282 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2012 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#include +#include +#include +#include +#include + + + // It works for table data on clipboard for an Excell spreadsheet, +// why not us too for now. +#define COL_SEP wxT( '\t' ) +#define ROW_SEP wxT( '\n' ) + + +enum +{ + MYID_FIRST = -1, + MYID_CUT, + MYID_COPY, + MYID_PASTE, + MYID_SELECT, + MYID_LAST, +}; + + +GRID_TRICKS::GRID_TRICKS( wxGrid* aGrid ): + m_grid( aGrid ) +{ + aGrid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( GRID_TRICKS::onGridCellRightClick ), NULL, this ); + aGrid->Connect( MYID_FIRST, MYID_LAST, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GRID_TRICKS::onPopupSelection ), NULL, this ); + aGrid->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( GRID_TRICKS::onKeyDown ), NULL, this ); + aGrid->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( GRID_TRICKS::onRightDown ), NULL, this ); +} + + +void GRID_TRICKS::getSelectedArea() +{ + wxGridCellCoordsArray topLeft = m_grid->GetSelectionBlockTopLeft(); + wxGridCellCoordsArray botRight = m_grid->GetSelectionBlockBottomRight(); + + wxArrayInt cols = m_grid->GetSelectedCols(); + wxArrayInt rows = m_grid->GetSelectedRows(); + + D(printf("topLeft.Count():%zd botRight:Count():%zd\n", topLeft.Count(), botRight.Count() );) + + if( topLeft.Count() && botRight.Count() ) + { + m_sel_row_start = topLeft[0].GetRow(); + m_sel_col_start = topLeft[0].GetCol(); + + m_sel_row_count = botRight[0].GetRow() - m_sel_row_start + 1; + m_sel_col_count = botRight[0].GetCol() - m_sel_col_start + 1; + } + else if( cols.Count() ) + { + m_sel_col_start = cols[0]; + m_sel_col_count = cols.Count(); + m_sel_row_start = 0; + m_sel_row_count = m_grid->GetNumberRows(); + } + else if( rows.Count() ) + { + m_sel_col_start = 0; + m_sel_col_count = m_grid->GetNumberCols(); + m_sel_row_start = rows[0]; + m_sel_row_count = rows.Count(); + } + else + { + m_sel_row_start = -1; + m_sel_col_start = -1; + m_sel_row_count = 0; + m_sel_col_count = 0; + } + + //D(printf("m_sel_row_start:%d m_sel_col_start:%d m_sel_row_count:%d m_sel_col_count:%d\n", m_sel_row_start, m_sel_col_start, m_sel_row_count, m_sel_col_count );) +} + + +void GRID_TRICKS::showPopupMenu() +{ + wxMenu menu; + + menu.Append( MYID_CUT, _( "Cut\tCTRL+X" ), _( "Clear selected cells pasting original contents to clipboard" ) ); + menu.Append( MYID_COPY, _( "Copy\tCTRL+C" ), _( "Copy selected cells to clipboard" ) ); + menu.Append( MYID_PASTE, _( "Paste\tCTRL+V" ), _( "Paste clipboard cells to matrix at current cell" ) ); + menu.Append( MYID_SELECT, _( "Select All\tCTRL+A" ), _( "Select all cells" ) ); + + getSelectedArea(); + + // if nothing is selected, disable cut and copy. + if( !m_sel_row_count && !m_sel_col_count ) + { + menu.Enable( MYID_CUT, false ); + menu.Enable( MYID_COPY, false ); + } + + bool have_cb_text = false; + if( wxTheClipboard->Open() ) + { + if( wxTheClipboard->IsSupported( wxDF_TEXT ) ) + have_cb_text = true; + + wxTheClipboard->Close(); + } + + if( !have_cb_text ) + { + // if nothing on clipboard, disable paste. + menu.Enable( MYID_PASTE, false ); + } + + m_grid->PopupMenu( &menu ); +} + + +void GRID_TRICKS::onPopupSelection( wxCommandEvent& event ) +{ + int menu_id = event.GetId(); + + // assume getSelectedArea() was called by rightClickPopupMenu() and there's + // no way to have gotten here without that having been called. + + switch( menu_id ) + { + case MYID_CUT: + case MYID_COPY: + cutcopy( menu_id == MYID_CUT ); + break; + + case MYID_PASTE: + paste_clipboard(); + break; + + case MYID_SELECT: + m_grid->SelectAll(); + break; + + default: + ; + } +} + + +void GRID_TRICKS::onKeyDown( wxKeyEvent& ev ) +{ + if( isCtl( 'A', ev ) ) + { + m_grid->SelectAll(); + } + else if( isCtl( 'C', ev ) ) + { + getSelectedArea(); + cutcopy( false ); + } + else if( isCtl( 'V', ev ) ) + { + getSelectedArea(); + paste_clipboard(); + } + else if( isCtl( 'X', ev ) ) + { + getSelectedArea(); + cutcopy( true ); + } + else + ev.Skip(); +} + + +void GRID_TRICKS::paste_clipboard() +{ + if( wxTheClipboard->Open() ) + { + if( wxTheClipboard->IsSupported( wxDF_TEXT ) ) + { + wxTextDataObject data; + + wxTheClipboard->GetData( data ); + + wxString cb_text = data.GetText(); + + paste_text( cb_text ); + } + + wxTheClipboard->Close(); + m_grid->ForceRefresh(); + } +} + + +void GRID_TRICKS::paste_text( const wxString& cb_text ) +{ + wxGridTableBase* tbl = m_grid->GetTable(); + + const int cur_row = std::max( getCursorRow(), 0 ); // no -1 + const int cur_col = std::max( getCursorCol(), 0 ); + + wxStringTokenizer rows( cb_text, ROW_SEP, wxTOKEN_RET_EMPTY ); + + // if clipboard rows would extend past end of current table size... + if( int( rows.CountTokens() ) > tbl->GetNumberRows() - cur_row ) + { + int newRowsNeeded = rows.CountTokens() - ( tbl->GetNumberRows() - cur_row ); + + tbl->AppendRows( newRowsNeeded ); + } + + for( int row = cur_row; rows.HasMoreTokens(); ++row ) + { + wxString rowTxt = rows.GetNextToken(); + + wxStringTokenizer cols( rowTxt, COL_SEP, wxTOKEN_RET_EMPTY ); + + for( int col = cur_col; cols.HasMoreTokens(); ++col ) + { + wxString cellTxt = cols.GetNextToken(); + tbl->SetValue( row, col, cellTxt ); + } + } + m_grid->AutoSizeColumns( false ); +} + + +void GRID_TRICKS::cutcopy( bool doCut ) +{ + if( wxTheClipboard->Open() ) + { + wxGridTableBase* tbl = m_grid->GetTable(); + wxString txt; + + // fill txt with a format that is compatible with most spreadsheets + for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row ) + { + for( int col = m_sel_col_start; col < m_sel_col_start + m_sel_col_count; ++col ) + { + txt += tbl->GetValue( row, col ); + + if( col < m_sel_col_start + m_sel_col_count - 1 ) // that was not last column + txt += COL_SEP; + + if( doCut ) + tbl->SetValue( row, col, wxEmptyString ); + } + txt += ROW_SEP; + } + + wxTheClipboard->SetData( new wxTextDataObject( txt ) ); + wxTheClipboard->Close(); + + if( doCut ) + { + m_grid->AutoSizeColumns( false ); + m_grid->ForceRefresh(); + } + } +} + diff --git a/include/fp_lib_table.h b/include/fp_lib_table.h index 81cfccd687..6820265483 100644 --- a/include/fp_lib_table.h +++ b/include/fp_lib_table.h @@ -313,7 +313,11 @@ public: return false; } - bool operator!=( const FP_LIB_TABLE& r ) const { return !( *this == r ); } + bool operator!=( const FP_LIB_TABLE& r ) const { return !( *this == r ); } + + int GetCount() { return rows.size(); } + + ROW& At( int aIndex ) { return rows[aIndex]; } /** * Function Parse diff --git a/include/grid_tricks.h b/include/grid_tricks.h new file mode 100644 index 0000000000..b4f1ae8d90 --- /dev/null +++ b/include/grid_tricks.h @@ -0,0 +1,96 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2012 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#include +#include + + +/** + * Class GRID_TRICKS + * is used to add cut, copy, and paste to an otherwise unmodied wxGrid instance. + */ +class GRID_TRICKS : public wxEvtHandler +{ +public: + + GRID_TRICKS( wxGrid* aGrid ); + + +protected: + wxGrid* m_grid; ///< I don't own the grid, but he owns me + + // row & col "selection" acquisition + // selected area by cell coordinate and count + int m_sel_row_start; + int m_sel_col_start; + int m_sel_row_count; + int m_sel_col_count; + + /// 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(); + } + + /// Puts the selected area into a sensible rectangle of m_sel_{row,col}_{start,count} above. + void getSelectedArea(); + + static bool isCtl( int aChar, const wxKeyEvent& e ) + { + return e.GetKeyCode() == aChar && e.ControlDown() && !e.AltDown() && !e.ShiftDown() && !e.MetaDown(); + } + + void onGridCellRightClick( wxGridEvent& event ) + { + showPopupMenu(); + } + + void onRightDown( wxMouseEvent& event ) + { + showPopupMenu(); + } + + virtual void showPopupMenu(); + + // the user clicked on a popup menu choice: + void onPopupSelection( wxCommandEvent& event ); + + void onKeyDown( wxKeyEvent& ev ); + + virtual void paste_clipboard(); + + virtual void paste_text( const wxString& cb_text ); + + virtual void cutcopy( bool doCut ); +}; + diff --git a/pcbnew/dialogs/dialog_fp_lib_table.cpp b/pcbnew/dialogs/dialog_fp_lib_table.cpp index a2b4be4115..33797c7334 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table.cpp +++ b/pcbnew/dialogs/dialog_fp_lib_table.cpp @@ -2,6 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2013 CERN * Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -30,18 +31,15 @@ */ -#include -#include -#include -#include -#include #include +#include #include #include #include #include #include +#include /// grid column order is established by this sequence @@ -63,6 +61,8 @@ enum COL_ORDER */ class FP_TBL_MODEL : public wxGridTableBase, public FP_LIB_TABLE { + friend class FP_GRID_TRICKS; + public: /** @@ -120,9 +120,7 @@ public: bool IsEmptyCell( int aRow, int aCol ) { - if( unsigned( aRow ) < rows.size() ) - return false; - return true; + return !GetValue( aRow, aCol ); } bool InsertRows( size_t aPos = 0, size_t aNumRows = 1 ) @@ -212,16 +210,69 @@ public: }; -// It works for table data on clipboard for an Excell spreadsheet, -// why not us too for now. -#define COL_SEP wxT( '\t' ) -#define ROW_SEP wxT( '\n' ) - - -inline bool isCtl( int aChar, const wxKeyEvent& e ) +class FP_GRID_TRICKS : public GRID_TRICKS { - return e.GetKeyCode() == aChar && e.ControlDown() && !e.AltDown() && !e.ShiftDown() && !e.MetaDown(); -} +public: + FP_GRID_TRICKS( wxGrid* aGrid ) : + GRID_TRICKS( aGrid ) + { + } + +protected: + + /// handle specialized clipboard text, with leading "(fp_lib_table", OR + /// spreadsheet formatted text. + virtual void paste_text( const wxString& cb_text ) + { + FP_TBL_MODEL* tbl = (FP_TBL_MODEL*) m_grid->GetTable(); + + size_t ndx = cb_text.find( wxT( "(fp_lib_table" ) ); + + if( ndx != std::string::npos ) + { + // paste the ROWs of s-expression (fp_lib_table), starting + // at column 0 regardless of current cursor column. + + STRING_LINE_READER slr( TO_UTF8( cb_text ), wxT( "Clipboard" ) ); + FP_LIB_TABLE_LEXER lexer( &slr ); + FP_LIB_TABLE tmp_tbl; + bool parsed = true; + + try + { + tmp_tbl.Parse( &lexer ); + } + catch( PARSE_ERROR& pe ) + { + // @todo tell what line and offset + parsed = false; + } + + if( parsed ) + { + const int cur_row = std::max( getCursorRow(), 0 ); + + // if clipboard rows would extend past end of current table size... + if( tmp_tbl.GetCount() > tbl->GetNumberRows() - cur_row ) + { + int newRowsNeeded = tmp_tbl.GetCount() - ( tbl->GetNumberRows() - cur_row ); + tbl->AppendRows( newRowsNeeded ); + } + + for( int i = 0; i < tmp_tbl.GetCount(); ++i ) + { + tbl->At( cur_row+i ) = tmp_tbl.At( i ); + } + } + m_grid->AutoSizeColumns( false ); + } + else + { + // paste spreadsheet formatted text. + GRID_TRICKS::paste_text( cb_text ); + } + } +}; /** @@ -233,23 +284,6 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE { typedef FP_LIB_TABLE::ROW ROW; - enum - { - MYID_FIRST = -1, - MYID_CUT, - MYID_COPY, - MYID_PASTE, - MYID_SELECT, - MYID_LAST, - }; - - // row & col "selection" acquisition - // selected area by cell coordinate and count - int selRowStart; - int selColStart; - int selRowCount; - int selColCount; - /// 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 @@ -264,119 +298,6 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE return m_cur_grid->GetGridCursorRow(); } - /// Puts the selected area into a sensible rectangle of sel{Row,Col}{Start,Count} above. - void getSelectedArea() - { - wxGridCellCoordsArray topLeft = m_cur_grid->GetSelectionBlockTopLeft(); - wxGridCellCoordsArray botRight = m_cur_grid->GetSelectionBlockBottomRight(); - - wxArrayInt cols = m_cur_grid->GetSelectedCols(); - wxArrayInt rows = m_cur_grid->GetSelectedRows(); - - D(printf("topLeft.Count():%zd botRight:Count():%zd\n", topLeft.Count(), botRight.Count() );) - - if( topLeft.Count() && botRight.Count() ) - { - selRowStart = topLeft[0].GetRow(); - selColStart = topLeft[0].GetCol(); - - selRowCount = botRight[0].GetRow() - selRowStart + 1; - selColCount = botRight[0].GetCol() - selColStart + 1; - } - else if( cols.Count() ) - { - selColStart = cols[0]; - selColCount = cols.Count(); - selRowStart = 0; - selRowCount = m_cur_grid->GetNumberRows(); - } - else if( rows.Count() ) - { - selColStart = 0; - selColCount = m_cur_grid->GetNumberCols(); - selRowStart = rows[0]; - selRowCount = rows.Count(); - } - else - { - selRowStart = -1; - selColStart = -1; - selRowCount = 0; - selColCount = 0; - } - - D(printf("selRowStart:%d selColStart:%d selRowCount:%d selColCount:%d\n", selRowStart, selColStart, selRowCount, selColCount );) - } - - void rightClickCellPopupMenu() - { - wxMenu menu; - - menu.Append( MYID_CUT, _( "Cut\tCTRL+X" ), _( "Clear selected cells pasting original contents to clipboard" ) ); - menu.Append( MYID_COPY, _( "Copy\tCTRL+C" ), _( "Copy selected cells to clipboard" ) ); - menu.Append( MYID_PASTE, _( "Paste\tCTRL+V" ), _( "Paste clipboard cells to matrix at current cell" ) ); - menu.Append( MYID_SELECT, _( "Select All\tCTRL+A" ), _( "Select all cells" ) ); - - getSelectedArea(); - - // if nothing is selected, disable cut and copy. - if( !selRowCount && !selColCount ) - { - menu.Enable( MYID_CUT, false ); - menu.Enable( MYID_COPY, false ); - } - - bool have_cb_text = false; - if( wxTheClipboard->Open() ) - { - if( wxTheClipboard->IsSupported( wxDF_TEXT ) ) - have_cb_text = true; - - wxTheClipboard->Close(); - } - - if( !have_cb_text ) - { - // if nothing on clipboard, disable paste. - menu.Enable( MYID_PASTE, false ); - } - - PopupMenu( &menu ); - - // passOnFocus(); - } - - void cutcopy( bool doCut ); - void paste(); - - // the user clicked on a popup menu choice: - void onPopupSelection( wxCommandEvent& event ) - { - int menuId = event.GetId(); - - // assume getSelectedArea() was called by rightClickPopupMenu() and there's - // no way to have gotten here without that having been called. - - switch( menuId ) - { - case MYID_CUT: - case MYID_COPY: - cutcopy( menuId == MYID_CUT ); - break; - - case MYID_PASTE: - paste(); - break; - - case MYID_SELECT: - m_cur_grid->SelectAll(); - break; - - default: - ; - } - } - /** * Function verifyTables @@ -479,27 +400,14 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE void onKeyDown( wxKeyEvent& ev ) { - if( isCtl( 'A', ev ) ) - { - m_cur_grid->SelectAll(); - } - else if( isCtl( 'C', ev ) ) - { - getSelectedArea(); - cutcopy( false ); - } - else if( isCtl( 'V', ev ) ) - { - getSelectedArea(); - paste(); - } - else if( isCtl( 'X', ev ) ) - { - getSelectedArea(); - cutcopy( true ); - } - else - ev.Skip(); +#if 0 + // send the key to the current grid + ((wxEvtHandler*)m_cur_grid)->ProcessEvent( ev ); +#else + // or no: + // m_cur_grid has the focus most of the time anyways, so above not needed. + ev.Skip(); +#endif } void pageChangedHandler( wxAuiNotebookEvent& event ) @@ -646,26 +554,6 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE } } - void onGridCmdSelectCell( wxGridEvent& event ) - { - event.Skip(); - } - - void onGridCellLeftClick( wxGridEvent& event ) - { - event.Skip(); - } - - void onGridCellLeftDClick( wxGridEvent& event ) - { - event.Skip(); - } - - void onGridCellRightClick( wxGridEvent& event ) - { - rightClickCellPopupMenu(); - } - /// Populate the readonly environment variable table with names and values /// by examining all the full_uri columns. void populateEnvironReadOnlyTable() @@ -676,6 +564,7 @@ class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE std::set< wxString > unique; typedef std::set::const_iterator SET_CITER; + // clear the table m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() ); int gblRowCount = m_global_model.GetNumberRows(); @@ -754,6 +643,10 @@ public: 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 ); @@ -779,11 +672,13 @@ public: attr->SetEditor( new wxGridCellChoiceEditor( choices ) ); m_global_grid->SetColAttr( COL_TYPE, attr ); - m_global_grid->AutoSizeColumns(); - m_project_grid->AutoSizeColumns(); + 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(); @@ -801,8 +696,10 @@ public: ~DIALOG_FP_LIB_TABLE() { - Disconnect( MYID_FIRST, MYID_LAST, wxEVT_COMMAND_MENU_SELECTED, - wxCommandEventHandler( DIALOG_FP_LIB_TABLE::onPopupSelection ), NULL, this ); + // 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. @@ -813,128 +710,6 @@ public: }; -void DIALOG_FP_LIB_TABLE::cutcopy( bool doCut ) -{ - // this format is compatible with most spreadsheets - if( wxTheClipboard->Open() ) - { - wxGridTableBase* tbl = m_cur_grid->GetTable(); - wxString txt; - - for( int row = selRowStart; row < selRowStart + selRowCount; ++row ) - { - for( int col = selColStart; col < selColStart + selColCount; ++col ) - { - txt += tbl->GetValue( row, col ); - - if( col < selColStart + selColCount - 1 ) // that was not last column - txt += COL_SEP; - - if( doCut ) - tbl->SetValue( row, col, wxEmptyString ); - } - txt += ROW_SEP; - } - - wxTheClipboard->SetData( new wxTextDataObject( txt ) ); - wxTheClipboard->Close(); - - m_cur_grid->AutoSizeColumns(); - m_cur_grid->ForceRefresh(); - } -} - - -void DIALOG_FP_LIB_TABLE::paste() -{ - // assume format came from a spreadsheet or us. - if( wxTheClipboard->Open() ) - { - if( wxTheClipboard->IsSupported( wxDF_TEXT ) ) - { - wxTextDataObject data; - FP_TBL_MODEL* tbl = (FP_TBL_MODEL*) m_cur_grid->GetTable(); - - wxTheClipboard->GetData( data ); - - wxString cb_text = data.GetText(); - size_t ndx = cb_text.find( wxT( "(fp_lib_table" ) ); - - if( ndx != std::string::npos ) - { - // paste the ROWs of s-expression (fp_lib_table), starting - // at column 0 regardless of current cursor column. - - STRING_LINE_READER slr( TO_UTF8( cb_text ), wxT( "Clipboard" ) ); - FP_LIB_TABLE_LEXER lexer( &slr ); - FP_LIB_TABLE tmp_tbl; - bool parsed = true; - - try - { - tmp_tbl.Parse( &lexer ); - } - catch( PARSE_ERROR& pe ) - { - // @todo tell what line and offset - parsed = false; - } - - if( parsed ) - { - const int cur_row = getCursorRow(); - - // if clipboard rows would extend past end of current table size... - if( int( tmp_tbl.rows.size() ) > tbl->GetNumberRows() - cur_row ) - { - int newRowsNeeded = tmp_tbl.rows.size() - ( tbl->GetNumberRows() - cur_row ); - tbl->AppendRows( newRowsNeeded ); - } - - for( int i = 0; i < (int) tmp_tbl.rows.size(); ++i ) - { - tbl->rows[cur_row+i] = tmp_tbl.rows[i]; - } - } - m_cur_grid->AutoSizeColumns(); - } - else - { - const int cur_row = std::max( getCursorRow(), 0 ); // no -1 - const int cur_col = std::max( getCursorCol(), 0 ); - - wxStringTokenizer rows( cb_text, ROW_SEP, wxTOKEN_RET_EMPTY ); - - // if clipboard rows would extend past end of current table size... - if( int( rows.CountTokens() ) > tbl->GetNumberRows() - cur_row ) - { - int newRowsNeeded = rows.CountTokens() - ( tbl->GetNumberRows() - cur_row ); - - tbl->AppendRows( newRowsNeeded ); - } - - for( int row = cur_row; rows.HasMoreTokens(); ++row ) - { - wxString rowTxt = rows.GetNextToken(); - - wxStringTokenizer cols( rowTxt, COL_SEP, wxTOKEN_RET_EMPTY ); - - for( int col = cur_col; cols.HasMoreTokens(); ++col ) - { - wxString cellTxt = cols.GetNextToken(); - tbl->SetValue( row, col, cellTxt ); - } - } - m_cur_grid->AutoSizeColumns(); - } - } - - wxTheClipboard->Close(); - m_cur_grid->ForceRefresh(); - } -} - - int InvokePcbLibTableEditor( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject ) { DIALOG_FP_LIB_TABLE dlg( aParent, aGlobal, aProject ); diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.cpp b/pcbnew/dialogs/dialog_fp_lib_table_base.cpp index 9a6308bb41..11a220201d 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.cpp +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.cpp @@ -193,16 +193,6 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_FP_LIB_TABLE_BASE::onCancelButtonClick ) ); this->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FP_LIB_TABLE_BASE::onKeyDown ) ); m_auinotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( DIALOG_FP_LIB_TABLE_BASE::pageChangedHandler ), NULL, this ); - m_global_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellLeftClick ), NULL, this ); - m_global_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellLeftDClick ), NULL, this ); - m_global_grid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellRightClick ), NULL, this ); - m_global_grid->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCmdSelectCell ), NULL, this ); - m_global_grid->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FP_LIB_TABLE_BASE::onKeyDown ), NULL, this ); - m_project_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellLeftClick ), NULL, this ); - m_project_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellLeftDClick ), NULL, this ); - m_project_grid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellRightClick ), NULL, this ); - m_project_grid->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCmdSelectCell ), NULL, this ); - m_project_grid->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FP_LIB_TABLE_BASE::onKeyDown ), NULL, this ); m_append_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::appendRowHandler ), NULL, this ); m_delete_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::deleteRowHandler ), NULL, this ); m_move_up_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveUpHandler ), NULL, this ); @@ -218,16 +208,6 @@ DIALOG_FP_LIB_TABLE_BASE::~DIALOG_FP_LIB_TABLE_BASE() this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_FP_LIB_TABLE_BASE::onCancelButtonClick ) ); this->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FP_LIB_TABLE_BASE::onKeyDown ) ); m_auinotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( DIALOG_FP_LIB_TABLE_BASE::pageChangedHandler ), NULL, this ); - m_global_grid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellLeftClick ), NULL, this ); - m_global_grid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellLeftDClick ), NULL, this ); - m_global_grid->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellRightClick ), NULL, this ); - m_global_grid->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCmdSelectCell ), NULL, this ); - m_global_grid->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FP_LIB_TABLE_BASE::onKeyDown ), NULL, this ); - m_project_grid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellLeftClick ), NULL, this ); - m_project_grid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellLeftDClick ), NULL, this ); - m_project_grid->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCellRightClick ), NULL, this ); - m_project_grid->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_FP_LIB_TABLE_BASE::onGridCmdSelectCell ), NULL, this ); - m_project_grid->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FP_LIB_TABLE_BASE::onKeyDown ), NULL, this ); m_append_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::appendRowHandler ), NULL, this ); m_delete_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::deleteRowHandler ), NULL, this ); m_move_up_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveUpHandler ), NULL, this ); diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.fbp b/pcbnew/dialogs/dialog_fp_lib_table_base.fbp index 254f407946..11e3687fb3 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.fbp +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.fbp @@ -30,7 +30,7 @@ wxBOTH - 1 + 0 1 decl_pure_virtual @@ -43,7 +43,7 @@ DIALOG_FP_LIB_TABLE_BASE 900,600 - wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER + wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU DIALOG_SHIM; dialog_shim.h PCB Library Tables @@ -123,7 +123,7 @@ 0 1 - 1 + 0 0 Dock 0 @@ -212,7 +212,7 @@ 0 0 - 1 + 0 0 Dock 0 @@ -365,9 +365,9 @@ - onGridCellLeftClick - onGridCellLeftDClick - onGridCellRightClick + + + @@ -384,7 +384,7 @@ - onGridCmdSelectCell + @@ -396,7 +396,7 @@ - onKeyDown + @@ -441,7 +441,7 @@ 0 1 - 1 + 0 0 Dock 0 @@ -594,9 +594,9 @@ - onGridCellLeftClick - onGridCellLeftDClick - onGridCellRightClick + + + @@ -613,7 +613,7 @@ - onGridCmdSelectCell + @@ -625,7 +625,7 @@ - onKeyDown + diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.h b/pcbnew/dialogs/dialog_fp_lib_table_base.h index feb8d932f3..7ea5300b1b 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.h +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.h @@ -60,10 +60,6 @@ class DIALOG_FP_LIB_TABLE_BASE : public DIALOG_SHIM virtual void onCancelButtonClick( wxCloseEvent& event ) = 0; virtual void onKeyDown( wxKeyEvent& event ) = 0; virtual void pageChangedHandler( wxAuiNotebookEvent& event ) = 0; - virtual void onGridCellLeftClick( wxGridEvent& event ) = 0; - virtual void onGridCellLeftDClick( wxGridEvent& event ) = 0; - virtual void onGridCellRightClick( wxGridEvent& event ) = 0; - virtual void onGridCmdSelectCell( wxGridEvent& event ) = 0; virtual void appendRowHandler( wxMouseEvent& event ) = 0; virtual void deleteRowHandler( wxMouseEvent& event ) = 0; virtual void moveUpHandler( wxMouseEvent& event ) = 0; @@ -75,7 +71,7 @@ class DIALOG_FP_LIB_TABLE_BASE : public DIALOG_SHIM public: - DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("PCB Library Tables"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 900,600 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER ); + DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("PCB Library Tables"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 900,600 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU ); ~DIALOG_FP_LIB_TABLE_BASE(); }; diff --git a/pcbnew/dialogs/dialog_fp_plugin_options.cpp b/pcbnew/dialogs/dialog_fp_plugin_options.cpp index 5040a10a45..583985ead7 100644 --- a/pcbnew/dialogs/dialog_fp_plugin_options.cpp +++ b/pcbnew/dialogs/dialog_fp_plugin_options.cpp @@ -2,6 +2,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 CERN * Copyright (C) 2013 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -26,6 +27,7 @@ #include #include #include +#include class DIALOG_FP_PLUGIN_OPTIONS : public DIALOG_FP_PLUGIN_OPTIONS_BASE @@ -43,6 +45,19 @@ public: _( "Options for Library '%s'" ), GetChars( aNickname ) ); SetTitle( title ); + + m_grid->AutoSizeColumns( false ); + + // add Cut, Copy, and Paste to wxGrids + m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) ); + + // initial focus on the grid please. + m_grid->SetFocus(); + } + + ~DIALOG_FP_PLUGIN_OPTIONS() + { + m_grid->PopEventHandler( true ); } diff --git a/pcbnew/dialogs/dialog_fp_plugin_options_base.cpp b/pcbnew/dialogs/dialog_fp_plugin_options_base.cpp index d4a943ba64..aeba36fc2d 100644 --- a/pcbnew/dialogs/dialog_fp_plugin_options_base.cpp +++ b/pcbnew/dialogs/dialog_fp_plugin_options_base.cpp @@ -22,33 +22,33 @@ DIALOG_FP_PLUGIN_OPTIONS_BASE::DIALOG_FP_PLUGIN_OPTIONS_BASE( wxWindow* parent, wxStaticBoxSizer* sbSizer1; sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Plugin Options:") ), wxVERTICAL ); - m_grid1 = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_grid = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); // Grid - m_grid1->CreateGrid( 5, 2 ); - m_grid1->EnableEditing( true ); - m_grid1->EnableGridLines( true ); - m_grid1->EnableDragGridSize( false ); - m_grid1->SetMargins( 0, 0 ); + m_grid->CreateGrid( 5, 2 ); + m_grid->EnableEditing( true ); + m_grid->EnableGridLines( true ); + m_grid->EnableDragGridSize( false ); + m_grid->SetMargins( 0, 0 ); // Columns - m_grid1->EnableDragColMove( false ); - m_grid1->EnableDragColSize( true ); - m_grid1->SetColLabelSize( 30 ); - m_grid1->SetColLabelValue( 0, _("Option") ); - m_grid1->SetColLabelValue( 1, _("Value") ); - m_grid1->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + m_grid->EnableDragColMove( false ); + m_grid->EnableDragColSize( true ); + m_grid->SetColLabelSize( 30 ); + m_grid->SetColLabelValue( 0, _("Option") ); + m_grid->SetColLabelValue( 1, _("Value") ); + m_grid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); // Rows - m_grid1->EnableDragRowSize( false ); - m_grid1->SetRowLabelSize( 80 ); - m_grid1->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + m_grid->EnableDragRowSize( false ); + m_grid->SetRowLabelSize( 80 ); + m_grid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); // Label Appearance // Cell Defaults - m_grid1->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); - sbSizer1->Add( m_grid1, 1, wxEXPAND, 5 ); + m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + sbSizer1->Add( m_grid, 1, wxEXPAND, 5 ); wxBoxSizer* bSizer6; bSizer6 = new wxBoxSizer( wxHORIZONTAL ); diff --git a/pcbnew/dialogs/dialog_fp_plugin_options_base.fbp b/pcbnew/dialogs/dialog_fp_plugin_options_base.fbp index 3e4ba3aef1..8bd6b26e1a 100644 --- a/pcbnew/dialogs/dialog_fp_plugin_options_base.fbp +++ b/pcbnew/dialogs/dialog_fp_plugin_options_base.fbp @@ -176,7 +176,7 @@ 0 1 - m_grid1 + m_grid 1 diff --git a/pcbnew/dialogs/dialog_fp_plugin_options_base.h b/pcbnew/dialogs/dialog_fp_plugin_options_base.h index e83b94baee..97b724d4d5 100644 --- a/pcbnew/dialogs/dialog_fp_plugin_options_base.h +++ b/pcbnew/dialogs/dialog_fp_plugin_options_base.h @@ -37,7 +37,7 @@ class DIALOG_FP_PLUGIN_OPTIONS_BASE : public DIALOG_SHIM private: protected: - wxGrid* m_grid1; + wxGrid* m_grid; wxButton* m_add_row; wxButton* m_delete_row; wxButton* m_move_up;