KiCad PCB EDA Suite
GRID_TRICKS Class Reference

Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance. More...

#include <grid_tricks.h>

Inheritance diagram for GRID_TRICKS:
FIELDS_EDITOR_GRID_TRICKS FIELDS_GRID_TRICKS FP_GRID_TRICKS SYMBOL_GRID_TRICKS

Public Member Functions

 GRID_TRICKS (WX_GRID *aGrid)
 

Protected Member Functions

void getSelectedArea ()
 Puts the selected area into a sensible rectangle of m_sel_{row,col}_{start,count} above. More...
 
void onGridCellLeftClick (wxGridEvent &event)
 
void onGridCellLeftDClick (wxGridEvent &event)
 
void onGridCellRightClick (wxGridEvent &event)
 
void onGridLabelLeftClick (wxGridEvent &event)
 
void onGridLabelRightClick (wxGridEvent &event)
 
void onPopupSelection (wxCommandEvent &event)
 
void onKeyDown (wxKeyEvent &ev)
 
void onUpdateUI (wxUpdateUIEvent &event)
 
virtual bool handleDoubleClick (wxGridEvent &aEvent)
 
virtual void showPopupMenu (wxMenu &menu)
 
virtual void doPopupSelection (wxCommandEvent &event)
 
bool toggleCell (int aRow, int aCol, bool aPreserveSelection=false)
 
bool showEditor (int aRow, int aCol)
 
virtual void paste_clipboard ()
 
virtual void paste_text (const wxString &cb_text)
 
virtual void cutcopy (bool doCopy, bool doDelete)
 

Protected Attributes

WX_GRIDm_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

Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.

Definition at line 52 of file grid_tricks.h.

Constructor & Destructor Documentation

◆ GRID_TRICKS()

GRID_TRICKS::GRID_TRICKS ( WX_GRID aGrid)
explicit

Definition at line 38 of file grid_tricks.cpp.

38  :
39  m_grid( aGrid )
40 {
41  m_sel_row_start = 0;
42  m_sel_col_start = 0;
43  m_sel_row_count = 0;
44  m_sel_col_count = 0;
45 
46  aGrid->Connect( wxEVT_GRID_CELL_LEFT_CLICK,
47  wxGridEventHandler( GRID_TRICKS::onGridCellLeftClick ), nullptr, this );
48  aGrid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK,
49  wxGridEventHandler( GRID_TRICKS::onGridCellLeftDClick ), nullptr, this );
50  aGrid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK,
51  wxGridEventHandler( GRID_TRICKS::onGridCellRightClick ), nullptr, this );
52  aGrid->Connect( wxEVT_GRID_LABEL_RIGHT_CLICK,
53  wxGridEventHandler( GRID_TRICKS::onGridLabelRightClick ), nullptr, this );
54  aGrid->Connect( wxEVT_GRID_LABEL_LEFT_CLICK,
55  wxGridEventHandler( GRID_TRICKS::onGridLabelLeftClick ), nullptr, this );
56  aGrid->Connect( GRIDTRICKS_FIRST_ID, GRIDTRICKS_LAST_ID, wxEVT_COMMAND_MENU_SELECTED,
57  wxCommandEventHandler( GRID_TRICKS::onPopupSelection ), nullptr, this );
58  aGrid->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( GRID_TRICKS::onKeyDown ), nullptr, this );
59  aGrid->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( GRID_TRICKS::onUpdateUI ),
60  nullptr, this );
61 }
void onGridLabelLeftClick(wxGridEvent &event)
int m_sel_row_count
Definition: grid_tricks.h:87
void onGridCellLeftClick(wxGridEvent &event)
void onGridCellRightClick(wxGridEvent &event)
int m_sel_col_start
Definition: grid_tricks.h:86
void onGridCellLeftDClick(wxGridEvent &event)
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81
void onPopupSelection(wxCommandEvent &event)
int m_sel_col_count
Definition: grid_tricks.h:88
int m_sel_row_start
Definition: grid_tricks.h:85
void onUpdateUI(wxUpdateUIEvent &event)
void onGridLabelRightClick(wxGridEvent &event)
void onKeyDown(wxKeyEvent &ev)

References GRIDTRICKS_FIRST_ID, GRIDTRICKS_LAST_ID, m_sel_col_count, m_sel_col_start, m_sel_row_count, m_sel_row_start, onGridCellLeftClick(), onGridCellLeftDClick(), onGridCellRightClick(), onGridLabelLeftClick(), onGridLabelRightClick(), onKeyDown(), onPopupSelection(), and onUpdateUI().

Member Function Documentation

◆ cutcopy()

void GRID_TRICKS::cutcopy ( bool  doCopy,
bool  doDelete 
)
protectedvirtual

Definition at line 620 of file grid_tricks.cpp.

621 {
622  wxLogNull doNotLog; // disable logging of failed clipboard actions
623 
624  if( doCopy && !wxTheClipboard->Open() )
625  return;
626 
627  wxGridTableBase* tbl = m_grid->GetTable();
628  wxString txt;
629 
630  // fill txt with a format that is compatible with most spreadsheets
631  for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row )
632  {
633  for( int col = m_sel_col_start; col < m_sel_col_start + m_sel_col_count; ++col )
634  {
635  txt += tbl->GetValue( row, col );
636 
637  if( col < m_sel_col_start + m_sel_col_count - 1 ) // that was not last column
638  txt += COL_SEP;
639 
640  if( doDelete )
641  {
642  if( tbl->CanSetValueAs( row, col, wxGRID_VALUE_STRING ) )
643  tbl->SetValue( row, col, wxEmptyString );
644  }
645  }
646 
647  txt += ROW_SEP;
648  }
649 
650  if( doCopy )
651  {
652  wxTheClipboard->SetData( new wxTextDataObject( txt ) );
653  wxTheClipboard->Flush(); // Allow data to be available after closing KiCad
654  wxTheClipboard->Close();
655  }
656 
657  if( doDelete )
658  m_grid->ForceRefresh();
659 }
int m_sel_row_count
Definition: grid_tricks.h:87
int m_sel_col_start
Definition: grid_tricks.h:86
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81
int m_sel_col_count
Definition: grid_tricks.h:88
int m_sel_row_start
Definition: grid_tricks.h:85
#define ROW_SEP
Definition: grid_tricks.cpp:35
#define COL_SEP
Definition: grid_tricks.cpp:34

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 doPopupSelection(), and onKeyDown().

◆ doPopupSelection()

void GRID_TRICKS::doPopupSelection ( wxCommandEvent &  event)
protectedvirtual

Reimplemented in FP_GRID_TRICKS, FIELDS_EDITOR_GRID_TRICKS, and FIELDS_GRID_TRICKS.

Definition at line 289 of file grid_tricks.cpp.

290 {
291  int menu_id = event.GetId();
292 
293  // assume getSelectedArea() was called by rightClickPopupMenu() and there's
294  // no way to have gotten here without that having been called.
295 
296  switch( menu_id )
297  {
298  case GRIDTRICKS_ID_CUT:
299  cutcopy( true, true );
300  break;
301 
302  case GRIDTRICKS_ID_COPY:
303  cutcopy( true, false );
304  break;
305 
307  cutcopy( false, true );
308  break;
309 
310  case GRIDTRICKS_ID_PASTE:
311  paste_clipboard();
312  break;
313 
315  m_grid->SelectAll();
316  break;
317 
318  default:
319  if( menu_id >= GRIDTRICKS_FIRST_SHOWHIDE )
320  {
321  int col = menu_id - GRIDTRICKS_FIRST_SHOWHIDE;
322 
323  if( m_grid->IsColShown( col ) )
324  m_grid->HideCol( col );
325  else
326  m_grid->ShowCol( col );
327  }
328  }
329 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81
virtual void cutcopy(bool doCopy, bool doDelete)
virtual void paste_clipboard()

References cutcopy(), GRIDTRICKS_FIRST_SHOWHIDE, GRIDTRICKS_ID_COPY, GRIDTRICKS_ID_CUT, GRIDTRICKS_ID_DELETE, GRIDTRICKS_ID_PASTE, GRIDTRICKS_ID_SELECT, m_grid, and paste_clipboard().

Referenced by FIELDS_GRID_TRICKS::doPopupSelection(), FIELDS_EDITOR_GRID_TRICKS::doPopupSelection(), FP_GRID_TRICKS::doPopupSelection(), and onPopupSelection().

◆ getSelectedArea()

void GRID_TRICKS::getSelectedArea ( )
protected

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

Definition at line 175 of file grid_tricks.cpp.

176 {
177  wxGridCellCoordsArray topLeft = m_grid->GetSelectionBlockTopLeft();
178  wxGridCellCoordsArray botRight = m_grid->GetSelectionBlockBottomRight();
179 
180  wxArrayInt cols = m_grid->GetSelectedCols();
181  wxArrayInt rows = m_grid->GetSelectedRows();
182 
183  if( topLeft.Count() && botRight.Count() )
184  {
185  m_sel_row_start = topLeft[0].GetRow();
186  m_sel_col_start = topLeft[0].GetCol();
187 
188  m_sel_row_count = botRight[0].GetRow() - m_sel_row_start + 1;
189  m_sel_col_count = botRight[0].GetCol() - m_sel_col_start + 1;
190  }
191  else if( cols.Count() )
192  {
193  m_sel_col_start = cols[0];
194  m_sel_col_count = cols.Count();
195  m_sel_row_start = 0;
196  m_sel_row_count = m_grid->GetNumberRows();
197  }
198  else if( rows.Count() )
199  {
200  m_sel_col_start = 0;
201  m_sel_col_count = m_grid->GetNumberCols();
202  m_sel_row_start = rows[0];
203  m_sel_row_count = rows.Count();
204  }
205  else
206  {
207  m_sel_row_start = m_grid->GetGridCursorRow();
208  m_sel_col_start = m_grid->GetGridCursorCol();
209  m_sel_row_count = m_sel_row_start >= 0 ? 1 : 0;
210  m_sel_col_count = m_sel_col_start >= 0 ? 1 : 0;
211  }
212 }
int m_sel_row_count
Definition: grid_tricks.h:87
int m_sel_col_start
Definition: grid_tricks.h:86
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81
int m_sel_col_count
Definition: grid_tricks.h:88
int m_sel_row_start
Definition: grid_tricks.h:85

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

Referenced by onKeyDown(), and showPopupMenu().

◆ handleDoubleClick()

bool GRID_TRICKS::handleDoubleClick ( wxGridEvent &  aEvent)
protectedvirtual

Reimplemented in FP_GRID_TRICKS.

Definition at line 168 of file grid_tricks.cpp.

169 {
170  // Double-click processing must be handled by specific sub-classes
171  return false;
172 }

Referenced by onGridCellLeftDClick().

◆ onGridCellLeftClick()

void GRID_TRICKS::onGridCellLeftClick ( wxGridEvent &  event)
protected

Definition at line 142 of file grid_tricks.cpp.

143 {
144  int row = aEvent.GetRow();
145  int col = aEvent.GetCol();
146 
147  // Don't make users click twice to toggle a checkbox or edit a text cell
148  if( !aEvent.GetModifiers() )
149  {
150  if( toggleCell( row, col ) )
151  return;
152 
153  if( showEditor( row, col ) )
154  return;
155  }
156 
157  aEvent.Skip();
158 }
bool toggleCell(int aRow, int aCol, bool aPreserveSelection=false)
Definition: grid_tricks.cpp:64
bool showEditor(int aRow, int aCol)

References showEditor(), and toggleCell().

Referenced by GRID_TRICKS(), and onGridCellLeftDClick().

◆ onGridCellLeftDClick()

void GRID_TRICKS::onGridCellLeftDClick ( wxGridEvent &  event)
protected

Definition at line 161 of file grid_tricks.cpp.

162 {
163  if( !handleDoubleClick( aEvent ) )
164  onGridCellLeftClick( aEvent );
165 }
void onGridCellLeftClick(wxGridEvent &event)
virtual bool handleDoubleClick(wxGridEvent &aEvent)

References handleDoubleClick(), and onGridCellLeftClick().

Referenced by GRID_TRICKS().

◆ onGridCellRightClick()

void GRID_TRICKS::onGridCellRightClick ( wxGridEvent &  event)
protected

Definition at line 215 of file grid_tricks.cpp.

216 {
217  wxMenu menu;
218 
219  showPopupMenu( menu );
220 }
virtual void showPopupMenu(wxMenu &menu)

References showPopupMenu().

Referenced by GRID_TRICKS().

◆ onGridLabelLeftClick()

void GRID_TRICKS::onGridLabelLeftClick ( wxGridEvent &  event)
protected

Definition at line 223 of file grid_tricks.cpp.

224 {
226 
227  aEvent.Skip();
228 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:180

References WX_GRID::CommitPendingChanges(), and m_grid.

Referenced by GRID_TRICKS().

◆ onGridLabelRightClick()

void GRID_TRICKS::onGridLabelRightClick ( wxGridEvent &  event)
protected

Definition at line 231 of file grid_tricks.cpp.

232 {
233  wxMenu menu;
234 
235  for( int i = 0; i < m_grid->GetNumberCols(); ++i )
236  {
237  int id = GRIDTRICKS_FIRST_SHOWHIDE + i;
238  menu.AppendCheckItem( id, m_grid->GetColLabelValue( i ) );
239  menu.Check( id, m_grid->IsColShown( i ) );
240  }
241 
242  m_grid->PopupMenu( &menu );
243 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81

References GRIDTRICKS_FIRST_SHOWHIDE, and m_grid.

Referenced by GRID_TRICKS().

◆ onKeyDown()

void GRID_TRICKS::onKeyDown ( wxKeyEvent &  ev)
protected

Definition at line 332 of file grid_tricks.cpp.

333 {
334  if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'A' )
335  {
336  m_grid->SelectAll();
337  return;
338  }
339  else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'C' )
340  {
341  getSelectedArea();
342  cutcopy( true, false );
343  return;
344  }
345  else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'V' )
346  {
347  getSelectedArea();
348  paste_clipboard();
349  return;
350  }
351  else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'X' )
352  {
353  getSelectedArea();
354  cutcopy( true, true );
355  return;
356  }
357  else if( !ev.GetModifiers() && ev.GetKeyCode() == WXK_DELETE )
358  {
359  getSelectedArea();
360  cutcopy( false, true );
361  return;
362  }
363 
364  // space-bar toggling of checkboxes
365  if( ev.GetKeyCode() == ' ' )
366  {
367  bool retVal = false;
368 
369  // If only rows can be selected, only toggle the first cell in a row
370  if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
371  {
372  wxArrayInt rowSel = m_grid->GetSelectedRows();
373 
374  for( unsigned int rowInd = 0; rowInd < rowSel.GetCount(); rowInd++ )
375  {
376  retVal |= toggleCell( rowSel[rowInd], 0, true );
377  }
378  }
379 
380  // If only columns can be selected, only toggle the first cell in a column
381  else if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectColumns )
382  {
383  wxArrayInt colSel = m_grid->GetSelectedCols();
384 
385  for( unsigned int colInd = 0; colInd < colSel.GetCount(); colInd++ )
386  {
387  retVal |= toggleCell( 0, colSel[colInd], true );
388  }
389  }
390 
391  // If the user can select the individual cells, toggle each cell selected
392  else if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectCells )
393  {
394  wxArrayInt rowSel = m_grid->GetSelectedRows();
395  wxArrayInt colSel = m_grid->GetSelectedCols();
396  wxGridCellCoordsArray cellSel = m_grid->GetSelectedCells();
397  wxGridCellCoordsArray topLeft = m_grid->GetSelectionBlockTopLeft();
398  wxGridCellCoordsArray botRight = m_grid->GetSelectionBlockBottomRight();
399 
400  // Iterate over every individually selected cell and try to toggle it
401  for( unsigned int cellInd = 0; cellInd < cellSel.GetCount(); cellInd++ )
402  {
403  retVal |= toggleCell( cellSel[cellInd].GetRow(), cellSel[cellInd].GetCol(), true );
404  }
405 
406  // Iterate over every column and try to toggle each cell in it
407  for( unsigned int colInd = 0; colInd < colSel.GetCount(); colInd++ )
408  {
409  for( int row = 0; row < m_grid->GetNumberRows(); row++ )
410  {
411  retVal |= toggleCell( row, colSel[colInd], true );
412  }
413  }
414 
415  // Iterate over every row and try to toggle each cell in it
416  for( unsigned int rowInd = 0; rowInd < rowSel.GetCount(); rowInd++ )
417  {
418  for( int col = 0; col < m_grid->GetNumberCols(); col++ )
419  {
420  retVal |= toggleCell( rowSel[rowInd], col, true );
421  }
422  }
423 
424  // Iterate over the selection blocks
425  for( unsigned int blockInd = 0; blockInd < topLeft.GetCount(); blockInd++ )
426  {
427  wxGridCellCoords start = topLeft[blockInd];
428  wxGridCellCoords end = botRight[blockInd];
429 
430  for( int row = start.GetRow(); row <= end.GetRow(); row++ )
431  {
432  for( int col = start.GetCol(); col <= end.GetCol(); col++ )
433  {
434  retVal |= toggleCell( row, col, true );
435  }
436  }
437  }
438  }
439  else
440  {
441  }
442 
443  // Return if there were any cells toggled
444  if( retVal )
445  return;
446  }
447 
448  // ctrl-tab for exit grid
449 #ifdef __APPLE__
450  bool ctrl = ev.RawControlDown();
451 #else
452  bool ctrl = ev.ControlDown();
453 #endif
454 
455  if( ctrl && ev.GetKeyCode() == WXK_TAB )
456  {
457  wxWindow* test = m_grid->GetNextSibling();
458 
459  if( !test )
460  test = m_grid->GetParent()->GetNextSibling();
461 
462  while( test && !test->IsTopLevel() )
463  {
464  test->SetFocus();
465 
466  if( test->HasFocus() )
467  break;
468 
469  if( !test->GetChildren().empty() )
470  {
471  test = test->GetChildren().front();
472  }
473  else if( test->GetNextSibling() )
474  {
475  test = test->GetNextSibling();
476  }
477  else
478  {
479  while( test )
480  {
481  test = test->GetParent();
482 
483  if( test && test->IsTopLevel() )
484  {
485  break;
486  }
487  else if( test && test->GetNextSibling() )
488  {
489  test = test->GetNextSibling();
490  break;
491  }
492  }
493  }
494  }
495 
496  return;
497  }
498 
499  ev.Skip( true );
500 }
void getSelectedArea()
Puts the selected area into a sensible rectangle of m_sel_{row,col}_{start,count} above.
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81
bool toggleCell(int aRow, int aCol, bool aPreserveSelection=false)
Definition: grid_tricks.cpp:64
virtual void cutcopy(bool doCopy, bool doDelete)
virtual void paste_clipboard()

References cutcopy(), getSelectedArea(), m_grid, paste_clipboard(), and toggleCell().

Referenced by GRID_TRICKS().

◆ onPopupSelection()

void GRID_TRICKS::onPopupSelection ( wxCommandEvent &  event)
protected

Definition at line 283 of file grid_tricks.cpp.

284 {
285  doPopupSelection( event );
286 }
virtual void doPopupSelection(wxCommandEvent &event)

References doPopupSelection().

Referenced by GRID_TRICKS().

◆ onUpdateUI()

void GRID_TRICKS::onUpdateUI ( wxUpdateUIEvent &  event)
protected

Definition at line 662 of file grid_tricks.cpp.

663 {
664  // Respect ROW selectionMode when moving cursor
665 
666  if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
667  {
668  int cursorRow = m_grid->GetGridCursorRow();
669  bool cursorInSelectedRow = false;
670 
671  for( int row : m_grid->GetSelectedRows() )
672  {
673  if( row == cursorRow )
674  {
675  cursorInSelectedRow = true;
676  break;
677  }
678  }
679 
680  if( !cursorInSelectedRow && cursorRow >= 0 )
681  m_grid->SelectRow( cursorRow );
682  }
683 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81

References m_grid.

Referenced by GRID_TRICKS().

◆ paste_clipboard()

void GRID_TRICKS::paste_clipboard ( )
protectedvirtual

Definition at line 503 of file grid_tricks.cpp.

504 {
505  wxLogNull doNotLog; // disable logging of failed clipboard actions
506 
507  if( wxTheClipboard->Open() )
508  {
509  if( wxTheClipboard->IsSupported( wxDF_TEXT ) )
510  {
511  wxTextDataObject data;
512 
513  wxTheClipboard->GetData( data );
514 
515  paste_text( data.GetText() );
516  }
517 
518  wxTheClipboard->Close();
519  m_grid->ForceRefresh();
520  }
521 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81
virtual void paste_text(const wxString &cb_text)

References m_grid, and paste_text().

Referenced by doPopupSelection(), and onKeyDown().

◆ paste_text()

void GRID_TRICKS::paste_text ( const wxString &  cb_text)
protectedvirtual

Reimplemented in FP_GRID_TRICKS, and SYMBOL_GRID_TRICKS.

Definition at line 524 of file grid_tricks.cpp.

525 {
526  wxGridTableBase* tbl = m_grid->GetTable();
527 
528  const int cur_row = m_grid->GetGridCursorRow();
529  const int cur_col = m_grid->GetGridCursorCol();
530  int start_row;
531  int end_row;
532  int start_col;
533  int end_col;
534  bool is_selection = false;
535 
536  if( cur_row < 0 || cur_col < 0 )
537  {
538  wxBell();
539  return;
540  }
541 
542  if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
543  {
544  if( m_sel_row_count > 1 )
545  is_selection = true;
546  }
547  else
548  {
549  if( m_grid->IsSelection() )
550  is_selection = true;
551  }
552 
553  wxStringTokenizer rows( cb_text, ROW_SEP, wxTOKEN_RET_EMPTY );
554 
555  // If selection of cells is present
556  // then a clipboard pastes to selected cells only.
557  if( is_selection )
558  {
559  start_row = m_sel_row_start;
560  end_row = m_sel_row_start + m_sel_row_count;
561  start_col = m_sel_col_start;
562  end_col = m_sel_col_start + m_sel_col_count;
563  }
564  // Otherwise, paste whole clipboard
565  // starting from cell with cursor.
566  else
567  {
568  start_row = cur_row;
569  end_row = cur_row + rows.CountTokens();
570 
571  if( end_row > tbl->GetNumberRows() )
572  end_row = tbl->GetNumberRows();
573 
574  start_col = cur_col;
575  end_col = start_col; // end_col actual value calculates later
576  }
577 
578  for( int row = start_row; row < end_row; ++row )
579  {
580  // If number of selected rows bigger than count of rows in
581  // the clipboard, paste from the clipboard again and again
582  // while end of the selection is reached.
583  if( !rows.HasMoreTokens() )
584  rows.SetString( cb_text, ROW_SEP, wxTOKEN_RET_EMPTY );
585 
586  wxString rowTxt = rows.GetNextToken();
587 
588  wxStringTokenizer cols( rowTxt, COL_SEP, wxTOKEN_RET_EMPTY );
589 
590  if( !is_selection )
591  {
592  end_col = cur_col + cols.CountTokens();
593 
594  if( end_col > tbl->GetNumberCols() )
595  end_col = tbl->GetNumberCols();
596  }
597 
598  for( int col = start_col; col < end_col; ++col )
599  {
600  // If number of selected columns bigger than count of columns in
601  // the clipboard, paste from the clipboard again and again while
602  // end of the selection is reached.
603  if( !cols.HasMoreTokens() )
604  cols.SetString( rowTxt, COL_SEP, wxTOKEN_RET_EMPTY );
605 
606  wxString cellTxt = cols.GetNextToken();
607 
608  if( tbl->CanSetValueAs( row, col, wxGRID_VALUE_STRING ) )
609  {
610  tbl->SetValue( row, col, cellTxt );
611 
612  wxGridEvent evt( m_grid->GetId(), wxEVT_GRID_CELL_CHANGED, m_grid, row, col );
613  m_grid->GetEventHandler()->ProcessEvent( evt );
614  }
615  }
616  }
617 }
int m_sel_row_count
Definition: grid_tricks.h:87
int m_sel_col_start
Definition: grid_tricks.h:86
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81
int m_sel_col_count
Definition: grid_tricks.h:88
int m_sel_row_start
Definition: grid_tricks.h:85
#define ROW_SEP
Definition: grid_tricks.cpp:35
#define COL_SEP
Definition: grid_tricks.cpp:34

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 paste_clipboard(), SYMBOL_GRID_TRICKS::paste_text(), and FP_GRID_TRICKS::paste_text().

◆ showEditor()

bool GRID_TRICKS::showEditor ( int  aRow,
int  aCol 
)
protected

Definition at line 107 of file grid_tricks.cpp.

108 {
109  if( m_grid->GetGridCursorRow() != aRow || m_grid->GetGridCursorCol() != aCol )
110  m_grid->SetGridCursor( aRow, aCol );
111 
112  if( m_grid->IsEditable() && !m_grid->IsReadOnly( aRow, aCol ) )
113  {
114  m_grid->ClearSelection();
115 
116  if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
117  {
118  wxArrayInt rows = m_grid->GetSelectedRows();
119 
120  if( rows.size() != 1 || rows.Item( 0 ) != aRow )
121  m_grid->SelectRow( aRow );
122  }
123 
124  // For several reasons we can't enable the control here. There's the whole
125  // SetInSetFocus() issue/hack in wxWidgets, and there's also wxGrid's MouseUp
126  // handler which doesn't notice it's processing a MouseUp until after it has
127  // disabled the editor yet again. So we re-use wxWidgets' slow-click hack,
128  // which is processed later in the MouseUp handler.
129  //
130  // It should be pointed out that the fact that it's wxWidgets' hack doesn't
131  // make it any less of a hack. Be extra careful with any modifications here.
132  // See, in particular, https://bugs.launchpad.net/kicad/+bug/1817965.
134 
135  return true;
136  }
137 
138  return false;
139 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81
void ShowEditorOnMouseUp()
WxWidgets has a bunch of bugs in its handling of wxGrid mouse events which close cell editors right a...
Definition: wx_grid.h:99

References m_grid, and WX_GRID::ShowEditorOnMouseUp().

Referenced by onGridCellLeftClick().

◆ showPopupMenu()

void GRID_TRICKS::showPopupMenu ( wxMenu &  menu)
protectedvirtual

Reimplemented in FP_GRID_TRICKS, FIELDS_EDITOR_GRID_TRICKS, and FIELDS_GRID_TRICKS.

Definition at line 246 of file grid_tricks.cpp.

247 {
248  menu.Append( GRIDTRICKS_ID_CUT, _( "Cut" ) + "\tCtrl+X",
249  _( "Clear selected cells placing original contents on clipboard" ) );
250  menu.Append( GRIDTRICKS_ID_COPY, _( "Copy" ) + "\tCtrl+C",
251  _( "Copy selected cells to clipboard" ) );
252  menu.Append( GRIDTRICKS_ID_PASTE, _( "Paste" ) + "\tCtrl+V",
253  _( "Paste clipboard cells to matrix at current cell" ) );
254  menu.Append( GRIDTRICKS_ID_DELETE, _( "Delete" ) + "\tDel", _( "Delete selected cells" ) );
255  menu.Append( GRIDTRICKS_ID_SELECT, _( "Select All" ) + "\tCtrl+A", _( "Select all cells" ) );
256 
257  getSelectedArea();
258 
259  // if nothing is selected, disable cut, copy and delete.
261  {
262  menu.Enable( GRIDTRICKS_ID_CUT, false );
263  menu.Enable( GRIDTRICKS_ID_COPY, false );
264  menu.Enable( GRIDTRICKS_ID_DELETE, false );
265  }
266 
267  menu.Enable( GRIDTRICKS_ID_PASTE, false );
268 
269  wxLogNull doNotLog; // disable logging of failed clipboard actions
270 
271  if( wxTheClipboard->Open() )
272  {
273  if( wxTheClipboard->IsSupported( wxDF_TEXT ) )
274  menu.Enable( GRIDTRICKS_ID_PASTE, true );
275 
276  wxTheClipboard->Close();
277  }
278 
279  m_grid->PopupMenu( &menu );
280 }
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:87
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81
int m_sel_col_count
Definition: grid_tricks.h:88
#define _(s)

References _, getSelectedArea(), GRIDTRICKS_ID_COPY, GRIDTRICKS_ID_CUT, GRIDTRICKS_ID_DELETE, GRIDTRICKS_ID_PASTE, GRIDTRICKS_ID_SELECT, m_grid, m_sel_col_count, and m_sel_row_count.

Referenced by onGridCellRightClick(), FIELDS_GRID_TRICKS::showPopupMenu(), FIELDS_EDITOR_GRID_TRICKS::showPopupMenu(), and FP_GRID_TRICKS::showPopupMenu().

◆ toggleCell()

bool GRID_TRICKS::toggleCell ( int  aRow,
int  aCol,
bool  aPreserveSelection = false 
)
protected

Definition at line 64 of file grid_tricks.cpp.

65 {
66  auto renderer = m_grid->GetCellRenderer( aRow, aCol );
67  bool isCheckbox = ( dynamic_cast<wxGridCellBoolRenderer*>( renderer ) != nullptr );
68  renderer->DecRef();
69 
70  if( isCheckbox )
71  {
72  if( !aPreserveSelection )
73  m_grid->ClearSelection();
74 
75  m_grid->SetGridCursor( aRow, aCol );
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 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:81

References m_grid.

Referenced by onGridCellLeftClick(), and onKeyDown().

Member Data Documentation

◆ m_grid

◆ m_sel_col_count

int GRID_TRICKS::m_sel_col_count
protected

Definition at line 88 of file grid_tricks.h.

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

◆ m_sel_col_start

int GRID_TRICKS::m_sel_col_start
protected

Definition at line 86 of file grid_tricks.h.

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

◆ m_sel_row_count

int GRID_TRICKS::m_sel_row_count
protected

Definition at line 87 of file grid_tricks.h.

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

◆ m_sel_row_start

int GRID_TRICKS::m_sel_row_start
protected

Definition at line 85 of file grid_tricks.h.

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


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