KiCad PCB EDA Suite
GRID_TRICKS Class Reference

Class GRID_TRICKS is used to add cut, copy, and paste to an otherwise unmodied wxGrid instance. More...

#include <grid_tricks.h>

Inheritance diagram for GRID_TRICKS:
FP_GRID_TRICKS SYMBOL_GRID_TRICKS

Public Member Functions

 GRID_TRICKS (wxGrid *aGrid)
 

Protected Member Functions

int getCursorCol () const
 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. More...
 
int getCursorRow () const
 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. More...
 
void getSelectedArea ()
 Puts the selected area into a sensible rectangle of m_sel_{row,col}_{start,count} above. More...
 
void onGridCellLeftClick (wxGridEvent &event)
 
void onGridCellRightClick (wxGridEvent &event)
 
void onRightDown (wxMouseEvent &event)
 
virtual void showPopupMenu ()
 
void onPopupSelection (wxCommandEvent &event)
 
void onKeyDown (wxKeyEvent &ev)
 
bool toggleCell (int aRow, int aCol)
 
virtual void paste_clipboard ()
 
virtual void paste_text (const wxString &cb_text)
 
virtual void cutcopy (bool doCut)
 

Static Protected Member Functions

static bool isCtl (int aChar, const wxKeyEvent &e)
 

Protected Attributes

wxGrid * m_grid
 I don't own the grid, but he owns me. More...
 
int m_sel_row_start
 
int m_sel_col_start
 
int m_sel_row_count
 
int m_sel_col_count
 

Detailed Description

Class GRID_TRICKS is used to add cut, copy, and paste to an otherwise unmodied wxGrid instance.

Definition at line 34 of file grid_tricks.h.

Constructor & Destructor Documentation

GRID_TRICKS::GRID_TRICKS ( wxGrid *  aGrid)

Definition at line 52 of file grid_tricks.cpp.

References m_sel_col_count, m_sel_col_start, m_sel_row_count, m_sel_row_start, MYID_FIRST, MYID_LAST, onGridCellLeftClick(), onGridCellRightClick(), onKeyDown(), onPopupSelection(), and onRightDown().

52  :
53  m_grid( aGrid )
54 {
55  m_sel_row_start = 0;
56  m_sel_col_start = 0;
57  m_sel_row_count = 0;
58  m_sel_col_count = 0;
59 
60  aGrid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( GRID_TRICKS::onGridCellLeftClick ), NULL, this );
61  aGrid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( GRID_TRICKS::onGridCellLeftClick ), NULL, this );
62  aGrid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( GRID_TRICKS::onGridCellRightClick ), NULL, this );
63  aGrid->Connect( MYID_FIRST, MYID_LAST, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GRID_TRICKS::onPopupSelection ), NULL, this );
64  aGrid->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( GRID_TRICKS::onKeyDown ), NULL, this );
65  aGrid->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( GRID_TRICKS::onRightDown ), NULL, this );
66 }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
int m_sel_row_count
Definition: grid_tricks.h:48
void onGridCellLeftClick(wxGridEvent &event)
void onRightDown(wxMouseEvent &event)
Definition: grid_tricks.h:80
void onGridCellRightClick(wxGridEvent &event)
Definition: grid_tricks.h:75
int m_sel_col_start
Definition: grid_tricks.h:47
void onPopupSelection(wxCommandEvent &event)
int m_sel_col_count
Definition: grid_tricks.h:49
int m_sel_row_start
Definition: grid_tricks.h:46
void onKeyDown(wxKeyEvent &ev)

Member Function Documentation

void GRID_TRICKS::cutcopy ( bool  doCut)
protectedvirtual

Definition at line 329 of file grid_tricks.cpp.

References COL_SEP, m_grid, m_sel_col_count, m_sel_col_start, m_sel_row_count, m_sel_row_start, and ROW_SEP.

Referenced by onKeyDown(), onPopupSelection(), and onRightDown().

330 {
331  if( wxTheClipboard->Open() )
332  {
333  wxGridTableBase* tbl = m_grid->GetTable();
334  wxString txt;
335 
336  // fill txt with a format that is compatible with most spreadsheets
337  for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row )
338  {
339  for( int col = m_sel_col_start; col < m_sel_col_start + m_sel_col_count; ++col )
340  {
341  txt += tbl->GetValue( row, col );
342 
343  if( col < m_sel_col_start + m_sel_col_count - 1 ) // that was not last column
344  txt += COL_SEP;
345 
346  if( doCut )
347  tbl->SetValue( row, col, wxEmptyString );
348  }
349  txt += ROW_SEP;
350  }
351 
352  wxTheClipboard->SetData( new wxTextDataObject( txt ) );
353  wxTheClipboard->Close();
354 
355  if( doCut )
356  {
357  m_grid->AutoSizeColumns( false );
358  m_grid->ForceRefresh();
359  }
360  }
361 }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
int m_sel_row_count
Definition: grid_tricks.h:48
int m_sel_col_start
Definition: grid_tricks.h:47
int m_sel_col_count
Definition: grid_tricks.h:49
int m_sel_row_start
Definition: grid_tricks.h:46
#define ROW_SEP
Definition: grid_tricks.cpp:38
#define COL_SEP
Definition: grid_tricks.cpp:37
int GRID_TRICKS::getCursorCol ( ) const
inlineprotected

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.

Definition at line 53 of file grid_tricks.h.

Referenced by onKeyDown(), and paste_text().

54  {
55  return m_grid->GetGridCursorCol();
56  }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
int GRID_TRICKS::getCursorRow ( ) const
inlineprotected

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.

Definition at line 60 of file grid_tricks.h.

References getSelectedArea().

Referenced by onKeyDown(), and paste_text().

61  {
62  return m_grid->GetGridCursorRow();
63  }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
void GRID_TRICKS::getSelectedArea ( )
protected

Puts the selected area into a sensible rectangle of m_sel_{row,col}_{start,count} above.

Definition at line 128 of file grid_tricks.cpp.

References DBG, m_grid, m_sel_col_count, m_sel_col_start, m_sel_row_count, and m_sel_row_start.

Referenced by getCursorRow(), onKeyDown(), and showPopupMenu().

129 {
130  wxGridCellCoordsArray topLeft = m_grid->GetSelectionBlockTopLeft();
131  wxGridCellCoordsArray botRight = m_grid->GetSelectionBlockBottomRight();
132 
133  wxArrayInt cols = m_grid->GetSelectedCols();
134  wxArrayInt rows = m_grid->GetSelectedRows();
135 
136  DBG(printf("topLeft.Count():%d botRight:Count():%d\n", int( topLeft.Count() ), int( botRight.Count() ) );)
137 
138  if( topLeft.Count() && botRight.Count() )
139  {
140  m_sel_row_start = topLeft[0].GetRow();
141  m_sel_col_start = topLeft[0].GetCol();
142 
143  m_sel_row_count = botRight[0].GetRow() - m_sel_row_start + 1;
144  m_sel_col_count = botRight[0].GetCol() - m_sel_col_start + 1;
145  }
146  else if( cols.Count() )
147  {
148  m_sel_col_start = cols[0];
149  m_sel_col_count = cols.Count();
150  m_sel_row_start = 0;
151  m_sel_row_count = m_grid->GetNumberRows();
152  }
153  else if( rows.Count() )
154  {
155  m_sel_col_start = 0;
156  m_sel_col_count = m_grid->GetNumberCols();
157  m_sel_row_start = rows[0];
158  m_sel_row_count = rows.Count();
159  }
160  else
161  {
162  m_sel_row_start = -1;
163  m_sel_col_start = -1;
164  m_sel_row_count = 0;
165  m_sel_col_count = 0;
166  }
167 
168  //DBG(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 );)
169 }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
int m_sel_row_count
Definition: grid_tricks.h:48
int m_sel_col_start
Definition: grid_tricks.h:47
int m_sel_col_count
Definition: grid_tricks.h:49
int m_sel_row_start
Definition: grid_tricks.h:46
#define DBG(x)
Definition: fctsys.h:33
static bool GRID_TRICKS::isCtl ( int  aChar,
const wxKeyEvent &  e 
)
inlinestaticprotected

Definition at line 68 of file grid_tricks.h.

References onGridCellLeftClick().

Referenced by onKeyDown().

69  {
70  return e.GetKeyCode() == aChar && e.ControlDown() && !e.AltDown() && !e.ShiftDown() && !e.MetaDown();
71  }
void GRID_TRICKS::onGridCellLeftClick ( wxGridEvent &  event)
protected

Definition at line 107 of file grid_tricks.cpp.

References m_grid, and toggleCell().

Referenced by GRID_TRICKS(), and isCtl().

108 {
109  int row = aEvent.GetRow();
110  int col = aEvent.GetCol();
111 
112  // Don't make users click twice to toggle a checkbox
113 
114  if( !aEvent.GetModifiers() && toggleCell( row, col ) )
115  {
116  m_grid->ClearSelection();
117  m_grid->SetGridCursor( row, col );
118 
119  // eat event
120  }
121  else
122  {
123  aEvent.Skip();
124  }
125 }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
bool toggleCell(int aRow, int aCol)
Definition: grid_tricks.cpp:69
void GRID_TRICKS::onGridCellRightClick ( wxGridEvent &  event)
inlineprotected

Definition at line 75 of file grid_tricks.h.

References showPopupMenu().

Referenced by GRID_TRICKS().

76  {
77  showPopupMenu();
78  }
virtual void showPopupMenu()
void GRID_TRICKS::onKeyDown ( wxKeyEvent &  ev)
protected

Definition at line 237 of file grid_tricks.cpp.

References cutcopy(), getCursorCol(), getCursorRow(), getSelectedArea(), isCtl(), m_grid, paste_clipboard(), and toggleCell().

Referenced by GRID_TRICKS(), and onRightDown().

238 {
239  if( isCtl( 'A', ev ) )
240  {
241  m_grid->SelectAll();
242  return;
243  }
244  else if( isCtl( 'C', ev ) )
245  {
246  getSelectedArea();
247  cutcopy( false );
248  return;
249  }
250  else if( isCtl( 'V', ev ) )
251  {
252  getSelectedArea();
253  paste_clipboard();
254  return;
255  }
256  else if( isCtl( 'X', ev ) )
257  {
258  getSelectedArea();
259  cutcopy( true );
260  return;
261  }
262  else if( ev.GetKeyCode() == ' ' )
263  {
264  int row = getCursorRow();
265  int col = getCursorCol();
266 
267  if( m_grid->IsVisible( row, col ) && toggleCell( row, col ) )
268  return;
269  }
270 
271  ev.Skip( true );
272 }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
int getCursorCol() const
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.
Definition: grid_tricks.h:53
void getSelectedArea()
Puts the selected area into a sensible rectangle of m_sel_{row,col}_{start,count} above...
static bool isCtl(int aChar, const wxKeyEvent &e)
Definition: grid_tricks.h:68
bool toggleCell(int aRow, int aCol)
Definition: grid_tricks.cpp:69
virtual void paste_clipboard()
int getCursorRow() const
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.
Definition: grid_tricks.h:60
virtual void cutcopy(bool doCut)
void GRID_TRICKS::onPopupSelection ( wxCommandEvent &  event)
protected

Definition at line 209 of file grid_tricks.cpp.

References cutcopy(), m_grid, MYID_COPY, MYID_CUT, MYID_PASTE, MYID_SELECT, and paste_clipboard().

Referenced by GRID_TRICKS(), and onRightDown().

210 {
211  int menu_id = event.GetId();
212 
213  // assume getSelectedArea() was called by rightClickPopupMenu() and there's
214  // no way to have gotten here without that having been called.
215 
216  switch( menu_id )
217  {
218  case MYID_CUT:
219  case MYID_COPY:
220  cutcopy( menu_id == MYID_CUT );
221  break;
222 
223  case MYID_PASTE:
224  paste_clipboard();
225  break;
226 
227  case MYID_SELECT:
228  m_grid->SelectAll();
229  break;
230 
231  default:
232  ;
233  }
234 }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
virtual void paste_clipboard()
virtual void cutcopy(bool doCut)
void GRID_TRICKS::onRightDown ( wxMouseEvent &  event)
inlineprotected

Definition at line 80 of file grid_tricks.h.

References cutcopy(), onKeyDown(), onPopupSelection(), paste_clipboard(), paste_text(), showPopupMenu(), and toggleCell().

Referenced by GRID_TRICKS().

81  {
82  showPopupMenu();
83  }
virtual void showPopupMenu()
void GRID_TRICKS::paste_clipboard ( )
protectedvirtual

Definition at line 275 of file grid_tricks.cpp.

References m_grid, and paste_text().

Referenced by onKeyDown(), onPopupSelection(), and onRightDown().

276 {
277  if( wxTheClipboard->Open() )
278  {
279  if( wxTheClipboard->IsSupported( wxDF_TEXT ) )
280  {
281  wxTextDataObject data;
282 
283  wxTheClipboard->GetData( data );
284 
285  wxString cb_text = data.GetText();
286 
287  paste_text( cb_text );
288  }
289 
290  wxTheClipboard->Close();
291  m_grid->ForceRefresh();
292  }
293 }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
virtual void paste_text(const wxString &cb_text)
void GRID_TRICKS::paste_text ( const wxString &  cb_text)
protectedvirtual

Reimplemented in FP_GRID_TRICKS, and SYMBOL_GRID_TRICKS.

Definition at line 296 of file grid_tricks.cpp.

References COL_SEP, getCursorCol(), getCursorRow(), m_grid, max, and ROW_SEP.

Referenced by onRightDown(), paste_clipboard(), SYMBOL_GRID_TRICKS::paste_text(), and FP_GRID_TRICKS::paste_text().

297 {
298  wxGridTableBase* tbl = m_grid->GetTable();
299 
300  const int cur_row = std::max( getCursorRow(), 0 ); // no -1
301  const int cur_col = std::max( getCursorCol(), 0 );
302 
303  wxStringTokenizer rows( cb_text, ROW_SEP, wxTOKEN_RET_EMPTY );
304 
305  // if clipboard rows would extend past end of current table size...
306  if( int( rows.CountTokens() ) > tbl->GetNumberRows() - cur_row )
307  {
308  int newRowsNeeded = rows.CountTokens() - ( tbl->GetNumberRows() - cur_row );
309 
310  tbl->AppendRows( newRowsNeeded );
311  }
312 
313  for( int row = cur_row; rows.HasMoreTokens(); ++row )
314  {
315  wxString rowTxt = rows.GetNextToken();
316 
317  wxStringTokenizer cols( rowTxt, COL_SEP, wxTOKEN_RET_EMPTY );
318 
319  for( int col = cur_col; cols.HasMoreTokens(); ++col )
320  {
321  wxString cellTxt = cols.GetNextToken();
322  tbl->SetValue( row, col, cellTxt );
323  }
324  }
325  m_grid->AutoSizeColumns( false );
326 }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
int getCursorCol() const
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.
Definition: grid_tricks.h:53
#define ROW_SEP
Definition: grid_tricks.cpp:38
int getCursorRow() const
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.
Definition: grid_tricks.h:60
#define max(a, b)
Definition: auxiliary.h:86
#define COL_SEP
Definition: grid_tricks.cpp:37
void GRID_TRICKS::showPopupMenu ( )
protectedvirtual

Definition at line 172 of file grid_tricks.cpp.

References getSelectedArea(), m_grid, m_sel_col_count, m_sel_row_count, MYID_COPY, MYID_CUT, MYID_PASTE, and MYID_SELECT.

Referenced by onGridCellRightClick(), and onRightDown().

173 {
174  wxMenu menu;
175 
176  menu.Append( MYID_CUT, _( "Cut\tCTRL+X" ), _( "Clear selected cells pasting original contents to clipboard" ) );
177  menu.Append( MYID_COPY, _( "Copy\tCTRL+C" ), _( "Copy selected cells to clipboard" ) );
178  menu.Append( MYID_PASTE, _( "Paste\tCTRL+V" ), _( "Paste clipboard cells to matrix at current cell" ) );
179  menu.Append( MYID_SELECT, _( "Select All\tCTRL+A" ), _( "Select all cells" ) );
180 
181  getSelectedArea();
182 
183  // if nothing is selected, disable cut and copy.
185  {
186  menu.Enable( MYID_CUT, false );
187  menu.Enable( MYID_COPY, false );
188  }
189 
190  bool have_cb_text = false;
191  if( wxTheClipboard->Open() )
192  {
193  if( wxTheClipboard->IsSupported( wxDF_TEXT ) )
194  have_cb_text = true;
195 
196  wxTheClipboard->Close();
197  }
198 
199  if( !have_cb_text )
200  {
201  // if nothing on clipboard, disable paste.
202  menu.Enable( MYID_PASTE, false );
203  }
204 
205  m_grid->PopupMenu( &menu );
206 }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42
void getSelectedArea()
Puts the selected area into a sensible rectangle of m_sel_{row,col}_{start,count} above...
int m_sel_row_count
Definition: grid_tricks.h:48
int m_sel_col_count
Definition: grid_tricks.h:49
bool GRID_TRICKS::toggleCell ( int  aRow,
int  aCol 
)
protected

Definition at line 69 of file grid_tricks.cpp.

References m_grid.

Referenced by onGridCellLeftClick(), onKeyDown(), and onRightDown().

70 {
71  auto renderer = m_grid->GetCellRenderer( aRow, aCol );
72  bool isCheckbox = ( dynamic_cast<wxGridCellBoolRenderer*>( renderer ) != nullptr );
73  renderer->DecRef();
74 
75  if( isCheckbox )
76  {
77  wxGridTableBase* model = m_grid->GetTable();
78 
79  if( model->CanGetValueAs( aRow, aCol, wxGRID_VALUE_BOOL )
80  && model->CanSetValueAs( aRow, aCol, wxGRID_VALUE_BOOL ))
81  {
82  model->SetValueAsBool( aRow, aCol, !model->GetValueAsBool( aRow, aCol ));
83  }
84  else // fall back to string processing
85  {
86  if( model->GetValue( aRow, aCol ) == wxT( "1" ) )
87  model->SetValue( aRow, aCol, wxT( "0" ) );
88  else
89  model->SetValue( aRow, aCol, wxT( "1" ) );
90  }
91 
92  // Mac needs this for the keyboard events; Linux appears to always need it.
93  m_grid->ForceRefresh();
94 
95  // Let any clients know
96  wxGridEvent event( m_grid->GetId(), wxEVT_GRID_CELL_CHANGED, m_grid, aRow, aCol );
97  event.SetString( model->GetValue( aRow, aCol ) );
98  m_grid->GetEventHandler()->ProcessEvent( event );
99 
100  return true;
101  }
102 
103  return false;
104 }
wxGrid * m_grid
I don&#39;t own the grid, but he owns me.
Definition: grid_tricks.h:42

Member Data Documentation

wxGrid* GRID_TRICKS::m_grid
protected

I don't own the grid, but he owns me.

Definition at line 42 of file grid_tricks.h.

Referenced by cutcopy(), getSelectedArea(), onGridCellLeftClick(), onKeyDown(), onPopupSelection(), paste_clipboard(), paste_text(), showPopupMenu(), and toggleCell().

int GRID_TRICKS::m_sel_col_count
protected

Definition at line 49 of file grid_tricks.h.

Referenced by cutcopy(), getSelectedArea(), GRID_TRICKS(), and showPopupMenu().

int GRID_TRICKS::m_sel_col_start
protected

Definition at line 47 of file grid_tricks.h.

Referenced by cutcopy(), getSelectedArea(), and GRID_TRICKS().

int GRID_TRICKS::m_sel_row_count
protected

Definition at line 48 of file grid_tricks.h.

Referenced by cutcopy(), getSelectedArea(), GRID_TRICKS(), and showPopupMenu().

int GRID_TRICKS::m_sel_row_start
protected

Definition at line 46 of file grid_tricks.h.

Referenced by cutcopy(), getSelectedArea(), and GRID_TRICKS().


The documentation for this class was generated from the following files: