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)
 
void SetTooltipEnable (int aCol, bool aEnable=true)
 Enable the tooltip for a column. More...
 
bool GetTooltipEnabled (int aCol)
 Query if the tooltip for a column is enabled. More...
 

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 &event)
 
void onCharHook (wxKeyEvent &event)
 
void onUpdateUI (wxUpdateUIEvent &event)
 
void onGridMotion (wxMouseEvent &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
 
std::bitset< GRIDTRICKS_MAX_COLm_tooltipEnabled
 

Detailed Description

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

Definition at line 55 of file grid_tricks.h.

Constructor & Destructor Documentation

◆ GRID_TRICKS()

GRID_TRICKS::GRID_TRICKS ( WX_GRID aGrid)
explicit

Definition at line 40 of file grid_tricks.cpp.

40  :
41  m_grid( aGrid )
42 {
43  m_sel_row_start = 0;
44  m_sel_col_start = 0;
45  m_sel_row_count = 0;
46  m_sel_col_count = 0;
47 
48  aGrid->Connect( wxEVT_GRID_CELL_LEFT_CLICK,
49  wxGridEventHandler( GRID_TRICKS::onGridCellLeftClick ), nullptr, this );
50  aGrid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK,
51  wxGridEventHandler( GRID_TRICKS::onGridCellLeftDClick ), nullptr, this );
52  aGrid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK,
53  wxGridEventHandler( GRID_TRICKS::onGridCellRightClick ), nullptr, this );
54  aGrid->Connect( wxEVT_GRID_LABEL_RIGHT_CLICK,
55  wxGridEventHandler( GRID_TRICKS::onGridLabelRightClick ), nullptr, this );
56  aGrid->Connect( wxEVT_GRID_LABEL_LEFT_CLICK,
57  wxGridEventHandler( GRID_TRICKS::onGridLabelLeftClick ), nullptr, this );
58  aGrid->Connect( GRIDTRICKS_FIRST_ID, GRIDTRICKS_LAST_ID, wxEVT_COMMAND_MENU_SELECTED,
59  wxCommandEventHandler( GRID_TRICKS::onPopupSelection ), nullptr, this );
60  aGrid->Connect( wxEVT_CHAR_HOOK, wxCharEventHandler( GRID_TRICKS::onCharHook ), nullptr, this );
61  aGrid->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( GRID_TRICKS::onKeyDown ), nullptr, this );
62  aGrid->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( GRID_TRICKS::onUpdateUI ),
63  nullptr, this );
64 
65  // The handlers that control the tooltips must be on the actual grid window, not the grid
66  aGrid->GetGridWindow()->Connect( wxEVT_MOTION,
67  wxMouseEventHandler( GRID_TRICKS::onGridMotion ), nullptr, this );
68 }
void onGridLabelLeftClick(wxGridEvent &event)
int m_sel_row_count
Definition: grid_tricks.h:116
void onGridCellLeftClick(wxGridEvent &event)
void onGridCellRightClick(wxGridEvent &event)
int m_sel_col_start
Definition: grid_tricks.h:115
void onGridCellLeftDClick(wxGridEvent &event)
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110
void onPopupSelection(wxCommandEvent &event)
int m_sel_col_count
Definition: grid_tricks.h:117
void onGridMotion(wxMouseEvent &event)
int m_sel_row_start
Definition: grid_tricks.h:114
void onUpdateUI(wxUpdateUIEvent &event)
void onCharHook(wxKeyEvent &event)
void onGridLabelRightClick(wxGridEvent &event)
void onKeyDown(wxKeyEvent &event)

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

Member Function Documentation

◆ cutcopy()

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

Definition at line 687 of file grid_tricks.cpp.

688 {
689  wxLogNull doNotLog; // disable logging of failed clipboard actions
690 
691  if( doCopy && !wxTheClipboard->Open() )
692  return;
693 
694  wxGridTableBase* tbl = m_grid->GetTable();
695  wxString txt;
696 
697  // fill txt with a format that is compatible with most spreadsheets
698  for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row )
699  {
700  for( int col = m_sel_col_start; col < m_sel_col_start + m_sel_col_count; ++col )
701  {
702  if( !m_grid->IsColShown( col ) )
703  continue;
704 
705  txt += tbl->GetValue( row, col );
706 
707  if( col < m_sel_col_start + m_sel_col_count - 1 ) // that was not last column
708  txt += COL_SEP;
709 
710  if( doDelete )
711  {
712  if( tbl->CanSetValueAs( row, col, wxGRID_VALUE_STRING ) )
713  tbl->SetValue( row, col, wxEmptyString );
714  }
715  }
716 
717  txt += ROW_SEP;
718  }
719 
720  if( doCopy )
721  {
722  wxTheClipboard->SetData( new wxTextDataObject( txt ) );
723  wxTheClipboard->Flush(); // Allow data to be available after closing KiCad
724  wxTheClipboard->Close();
725  }
726 
727  if( doDelete )
728  m_grid->ForceRefresh();
729 }
int m_sel_row_count
Definition: grid_tricks.h:116
int m_sel_col_start
Definition: grid_tricks.h:115
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110
int m_sel_col_count
Definition: grid_tricks.h:117
int m_sel_row_start
Definition: grid_tricks.h:114
#define ROW_SEP
Definition: grid_tricks.cpp:37
#define COL_SEP
Definition: grid_tricks.cpp:36

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 322 of file grid_tricks.cpp.

323 {
324  int menu_id = event.GetId();
325 
326  // assume getSelectedArea() was called by rightClickPopupMenu() and there's
327  // no way to have gotten here without that having been called.
328 
329  switch( menu_id )
330  {
331  case GRIDTRICKS_ID_CUT:
332  cutcopy( true, true );
333  break;
334 
335  case GRIDTRICKS_ID_COPY:
336  cutcopy( true, false );
337  break;
338 
340  cutcopy( false, true );
341  break;
342 
343  case GRIDTRICKS_ID_PASTE:
344  paste_clipboard();
345  break;
346 
348  m_grid->SelectAll();
349  break;
350 
351  default:
352  if( menu_id >= GRIDTRICKS_FIRST_SHOWHIDE )
353  {
354  int col = menu_id - GRIDTRICKS_FIRST_SHOWHIDE;
355 
356  if( m_grid->IsColShown( col ) )
357  m_grid->HideCol( col );
358  else
359  m_grid->ShowCol( col );
360  }
361  }
362 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110
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 205 of file grid_tricks.cpp.

206 {
207  wxGridCellCoordsArray topLeft = m_grid->GetSelectionBlockTopLeft();
208  wxGridCellCoordsArray botRight = m_grid->GetSelectionBlockBottomRight();
209 
210  wxArrayInt cols = m_grid->GetSelectedCols();
211  wxArrayInt rows = m_grid->GetSelectedRows();
212 
213  if( topLeft.Count() && botRight.Count() )
214  {
215  m_sel_row_start = topLeft[0].GetRow();
216  m_sel_col_start = topLeft[0].GetCol();
217 
218  m_sel_row_count = botRight[0].GetRow() - m_sel_row_start + 1;
219  m_sel_col_count = botRight[0].GetCol() - m_sel_col_start + 1;
220  }
221  else if( cols.Count() )
222  {
223  m_sel_col_start = cols[0];
224  m_sel_col_count = cols.Count();
225  m_sel_row_start = 0;
226  m_sel_row_count = m_grid->GetNumberRows();
227  }
228  else if( rows.Count() )
229  {
230  m_sel_col_start = 0;
231  m_sel_col_count = m_grid->GetNumberCols();
232  m_sel_row_start = rows[0];
233  m_sel_row_count = rows.Count();
234  }
235  else
236  {
237  m_sel_row_start = m_grid->GetGridCursorRow();
238  m_sel_col_start = m_grid->GetGridCursorCol();
239  m_sel_row_count = m_sel_row_start >= 0 ? 1 : 0;
240  m_sel_col_count = m_sel_col_start >= 0 ? 1 : 0;
241  }
242 }
int m_sel_row_count
Definition: grid_tricks.h:116
int m_sel_col_start
Definition: grid_tricks.h:115
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110
int m_sel_col_count
Definition: grid_tricks.h:117
int m_sel_row_start
Definition: grid_tricks.h:114

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().

◆ GetTooltipEnabled()

bool GRID_TRICKS::GetTooltipEnabled ( int  aCol)
inline

Query if the tooltip for a column is enabled.

Parameters
aColis the column to query
Returns
if the tooltip is enabled for the column

Definition at line 79 of file grid_tricks.h.

80  {
81  return m_tooltipEnabled[aCol];
82  }
std::bitset< GRIDTRICKS_MAX_COL > m_tooltipEnabled
Definition: grid_tricks.h:119

References m_tooltipEnabled.

◆ handleDoubleClick()

bool GRID_TRICKS::handleDoubleClick ( wxGridEvent &  aEvent)
protectedvirtual

Reimplemented in FP_GRID_TRICKS.

Definition at line 198 of file grid_tricks.cpp.

199 {
200  // Double-click processing must be handled by specific sub-classes
201  return false;
202 }

Referenced by onGridCellLeftDClick().

◆ onCharHook()

void GRID_TRICKS::onCharHook ( wxKeyEvent &  event)
protected

Definition at line 365 of file grid_tricks.cpp.

366 {
367  bool handled = false;
368 
369  if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'V' )
370  {
371  if( m_grid->IsCellEditControlShown() && wxTheClipboard->Open() )
372  {
373  if( wxTheClipboard->IsSupported( wxDF_TEXT ) )
374  {
375  wxTextDataObject data;
376  wxTheClipboard->GetData( data );
377 
378  if( data.GetText().Contains( COL_SEP ) || data.GetText().Contains( ROW_SEP ) )
379  {
380  m_grid->CommitPendingChanges( true /* quiet mode */ );
381  paste_text( data.GetText() );
382  handled = true;
383  }
384  }
385 
386  wxTheClipboard->Close();
387  m_grid->ForceRefresh();
388  }
389  }
390 
391  if( !handled )
392  ev.Skip( true );
393 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110
virtual void paste_text(const wxString &cb_text)
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:226
#define ROW_SEP
Definition: grid_tricks.cpp:37
#define COL_SEP
Definition: grid_tricks.cpp:36

References COL_SEP, WX_GRID::CommitPendingChanges(), m_grid, paste_text(), and ROW_SEP.

Referenced by GRID_TRICKS().

◆ onGridCellLeftClick()

void GRID_TRICKS::onGridCellLeftClick ( wxGridEvent &  event)
protected

Definition at line 149 of file grid_tricks.cpp.

150 {
151  int row = aEvent.GetRow();
152  int col = aEvent.GetCol();
153 
154  // Don't make users click twice to toggle a checkbox or edit a text cell
155  if( !aEvent.GetModifiers() )
156  {
157  if( toggleCell( row, col ) )
158  return;
159 
160  if( showEditor( row, col ) )
161  return;
162  }
163 
164  aEvent.Skip();
165 }
bool toggleCell(int aRow, int aCol, bool aPreserveSelection=false)
Definition: grid_tricks.cpp:71
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 168 of file grid_tricks.cpp.

169 {
170  if( !handleDoubleClick( aEvent ) )
171  onGridCellLeftClick( aEvent );
172 }
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 245 of file grid_tricks.cpp.

246 {
247  wxMenu menu;
248 
249  showPopupMenu( menu );
250 }
virtual void showPopupMenu(wxMenu &menu)

References showPopupMenu().

Referenced by GRID_TRICKS().

◆ onGridLabelLeftClick()

void GRID_TRICKS::onGridLabelLeftClick ( wxGridEvent &  event)
protected

Definition at line 253 of file grid_tricks.cpp.

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

References WX_GRID::CommitPendingChanges(), and m_grid.

Referenced by GRID_TRICKS().

◆ onGridLabelRightClick()

void GRID_TRICKS::onGridLabelRightClick ( wxGridEvent &  event)
protected

Definition at line 261 of file grid_tricks.cpp.

262 {
263  wxMenu menu;
264 
265  for( int i = 0; i < m_grid->GetNumberCols(); ++i )
266  {
267  int id = GRIDTRICKS_FIRST_SHOWHIDE + i;
268  menu.AppendCheckItem( id, m_grid->GetColLabelValue( i ) );
269  menu.Check( id, m_grid->IsColShown( i ) );
270  }
271 
272  m_grid->PopupMenu( &menu );
273 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110

References GRIDTRICKS_FIRST_SHOWHIDE, and m_grid.

Referenced by GRID_TRICKS().

◆ onGridMotion()

void GRID_TRICKS::onGridMotion ( wxMouseEvent &  event)
protected

Definition at line 175 of file grid_tricks.cpp.

176 {
177  // Always skip the event
178  aEvent.Skip();
179 
180  wxPoint pt = aEvent.GetPosition();
181  wxPoint pos = m_grid->CalcScrolledPosition( wxPoint( pt.x, pt.y ) );
182 
183  int col = m_grid->XToCol( pos.x );
184  int row = m_grid->YToRow( pos.y );
185 
186  // Empty tooltip if the cell doesn't exist or the column doesn't have tooltips
187  if( ( col == wxNOT_FOUND ) || ( row == wxNOT_FOUND ) || !m_tooltipEnabled[col] )
188  {
189  m_grid->GetGridWindow()->SetToolTip( "" );
190  return;
191  }
192 
193  // Set the tooltip to the string contained in the cell
194  m_grid->GetGridWindow()->SetToolTip( m_grid->GetCellValue( row, col ) );
195 }
std::bitset< GRIDTRICKS_MAX_COL > m_tooltipEnabled
Definition: grid_tricks.h:119
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110

References m_grid, and m_tooltipEnabled.

Referenced by GRID_TRICKS().

◆ onKeyDown()

void GRID_TRICKS::onKeyDown ( wxKeyEvent &  event)
protected

Definition at line 396 of file grid_tricks.cpp.

397 {
398  if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'A' )
399  {
400  m_grid->SelectAll();
401  return;
402  }
403  else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'C' )
404  {
405  getSelectedArea();
406  cutcopy( true, false );
407  return;
408  }
409  else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'V' )
410  {
411  getSelectedArea();
412  paste_clipboard();
413  return;
414  }
415  else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'X' )
416  {
417  getSelectedArea();
418  cutcopy( true, true );
419  return;
420  }
421  else if( !ev.GetModifiers() && ev.GetKeyCode() == WXK_DELETE )
422  {
423  getSelectedArea();
424  cutcopy( false, true );
425  return;
426  }
427 
428  // space-bar toggling of checkboxes
429  if( ev.GetKeyCode() == ' ' )
430  {
431  bool retVal = false;
432 
433  // If only rows can be selected, only toggle the first cell in a row
434  if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
435  {
436  wxArrayInt rowSel = m_grid->GetSelectedRows();
437 
438  for( unsigned int rowInd = 0; rowInd < rowSel.GetCount(); rowInd++ )
439  {
440  retVal |= toggleCell( rowSel[rowInd], 0, true );
441  }
442  }
443 
444  // If only columns can be selected, only toggle the first cell in a column
445  else if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectColumns )
446  {
447  wxArrayInt colSel = m_grid->GetSelectedCols();
448 
449  for( unsigned int colInd = 0; colInd < colSel.GetCount(); colInd++ )
450  {
451  retVal |= toggleCell( 0, colSel[colInd], true );
452  }
453  }
454 
455  // If the user can select the individual cells, toggle each cell selected
456  else if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectCells )
457  {
458  wxArrayInt rowSel = m_grid->GetSelectedRows();
459  wxArrayInt colSel = m_grid->GetSelectedCols();
460  wxGridCellCoordsArray cellSel = m_grid->GetSelectedCells();
461  wxGridCellCoordsArray topLeft = m_grid->GetSelectionBlockTopLeft();
462  wxGridCellCoordsArray botRight = m_grid->GetSelectionBlockBottomRight();
463 
464  // Iterate over every individually selected cell and try to toggle it
465  for( unsigned int cellInd = 0; cellInd < cellSel.GetCount(); cellInd++ )
466  {
467  retVal |= toggleCell( cellSel[cellInd].GetRow(), cellSel[cellInd].GetCol(), true );
468  }
469 
470  // Iterate over every column and try to toggle each cell in it
471  for( unsigned int colInd = 0; colInd < colSel.GetCount(); colInd++ )
472  {
473  for( int row = 0; row < m_grid->GetNumberRows(); row++ )
474  {
475  retVal |= toggleCell( row, colSel[colInd], true );
476  }
477  }
478 
479  // Iterate over every row and try to toggle each cell in it
480  for( unsigned int rowInd = 0; rowInd < rowSel.GetCount(); rowInd++ )
481  {
482  for( int col = 0; col < m_grid->GetNumberCols(); col++ )
483  {
484  retVal |= toggleCell( rowSel[rowInd], col, true );
485  }
486  }
487 
488  // Iterate over the selection blocks
489  for( unsigned int blockInd = 0; blockInd < topLeft.GetCount(); blockInd++ )
490  {
491  wxGridCellCoords start = topLeft[blockInd];
492  wxGridCellCoords end = botRight[blockInd];
493 
494  for( int row = start.GetRow(); row <= end.GetRow(); row++ )
495  {
496  for( int col = start.GetCol(); col <= end.GetCol(); col++ )
497  {
498  retVal |= toggleCell( row, col, true );
499  }
500  }
501  }
502  }
503  else
504  {
505  }
506 
507  // Return if there were any cells toggled
508  if( retVal )
509  return;
510  }
511 
512  // ctrl-tab for exit grid
513 #ifdef __APPLE__
514  bool ctrl = ev.RawControlDown();
515 #else
516  bool ctrl = ev.ControlDown();
517 #endif
518 
519  if( ctrl && ev.GetKeyCode() == WXK_TAB )
520  {
521  wxWindow* test = m_grid->GetNextSibling();
522 
523  if( !test )
524  test = m_grid->GetParent()->GetNextSibling();
525 
526  while( test && !test->IsTopLevel() )
527  {
528  test->SetFocus();
529 
530  if( test->HasFocus() )
531  break;
532 
533  if( !test->GetChildren().empty() )
534  {
535  test = test->GetChildren().front();
536  }
537  else if( test->GetNextSibling() )
538  {
539  test = test->GetNextSibling();
540  }
541  else
542  {
543  while( test )
544  {
545  test = test->GetParent();
546 
547  if( test && test->IsTopLevel() )
548  {
549  break;
550  }
551  else if( test && test->GetNextSibling() )
552  {
553  test = test->GetNextSibling();
554  break;
555  }
556  }
557  }
558  }
559 
560  return;
561  }
562 
563  ev.Skip( true );
564 }
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:110
bool toggleCell(int aRow, int aCol, bool aPreserveSelection=false)
Definition: grid_tricks.cpp:71
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 316 of file grid_tricks.cpp.

317 {
318  doPopupSelection( event );
319 }
virtual void doPopupSelection(wxCommandEvent &event)

References doPopupSelection().

Referenced by GRID_TRICKS().

◆ onUpdateUI()

void GRID_TRICKS::onUpdateUI ( wxUpdateUIEvent &  event)
protected

Definition at line 732 of file grid_tricks.cpp.

733 {
734  // Respect ROW selectionMode when moving cursor
735 
736  if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
737  {
738  int cursorRow = m_grid->GetGridCursorRow();
739  bool cursorInSelectedRow = false;
740 
741  for( int row : m_grid->GetSelectedRows() )
742  {
743  if( row == cursorRow )
744  {
745  cursorInSelectedRow = true;
746  break;
747  }
748  }
749 
750  if( !cursorInSelectedRow && cursorRow >= 0 )
751  m_grid->SelectRow( cursorRow );
752  }
753 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110

References m_grid.

Referenced by GRID_TRICKS().

◆ paste_clipboard()

void GRID_TRICKS::paste_clipboard ( )
protectedvirtual

Definition at line 567 of file grid_tricks.cpp.

568 {
569  wxLogNull doNotLog; // disable logging of failed clipboard actions
570 
571  if( wxTheClipboard->Open() )
572  {
573  if( wxTheClipboard->IsSupported( wxDF_TEXT )
574  || wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
575  {
576  wxTextDataObject data;
577 
578  wxTheClipboard->GetData( data );
579 
580  paste_text( data.GetText() );
581  }
582 
583  wxTheClipboard->Close();
584  m_grid->ForceRefresh();
585  }
586 }
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110
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 589 of file grid_tricks.cpp.

590 {
591  wxGridTableBase* tbl = m_grid->GetTable();
592 
593  const int cur_row = m_grid->GetGridCursorRow();
594  const int cur_col = m_grid->GetGridCursorCol();
595  int start_row;
596  int end_row;
597  int start_col;
598  int end_col;
599  bool is_selection = false;
600 
601  if( cur_row < 0 || cur_col < 0 )
602  {
603  wxBell();
604  return;
605  }
606 
607  if( m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
608  {
609  if( m_sel_row_count > 1 )
610  is_selection = true;
611  }
612  else
613  {
614  if( m_grid->IsSelection() )
615  is_selection = true;
616  }
617 
618  wxStringTokenizer rows( cb_text, ROW_SEP, wxTOKEN_RET_EMPTY );
619 
620  // If selection of cells is present
621  // then a clipboard pastes to selected cells only.
622  if( is_selection )
623  {
624  start_row = m_sel_row_start;
625  end_row = m_sel_row_start + m_sel_row_count;
626  start_col = m_sel_col_start;
627  end_col = m_sel_col_start + m_sel_col_count;
628  }
629  // Otherwise, paste whole clipboard
630  // starting from cell with cursor.
631  else
632  {
633  start_row = cur_row;
634  end_row = cur_row + rows.CountTokens();
635 
636  if( end_row > tbl->GetNumberRows() )
637  end_row = tbl->GetNumberRows();
638 
639  start_col = cur_col;
640  end_col = start_col; // end_col actual value calculates later
641  }
642 
643  for( int row = start_row; row < end_row; ++row )
644  {
645  // If number of selected rows is larger than the count of rows on the clipboard, paste
646  // again and again until the end of the selection is reached.
647  if( !rows.HasMoreTokens() )
648  rows.SetString( cb_text, ROW_SEP, wxTOKEN_RET_EMPTY );
649 
650  wxString rowTxt = rows.GetNextToken();
651 
652  wxStringTokenizer cols( rowTxt, COL_SEP, wxTOKEN_RET_EMPTY );
653 
654  if( !is_selection )
655  {
656  end_col = cur_col + cols.CountTokens();
657 
658  if( end_col > tbl->GetNumberCols() )
659  end_col = tbl->GetNumberCols();
660  }
661 
662  for( int col = start_col; col < end_col; ++col )
663  {
664  // Skip hidden columns
665  if( !m_grid->IsColShown( col ) )
666  continue;
667 
668  // If number of selected cols is larger than the count of cols on the clipboard,
669  // paste again and again until the end of the selection is reached.
670  if( !cols.HasMoreTokens() )
671  cols.SetString( rowTxt, COL_SEP, wxTOKEN_RET_EMPTY );
672 
673  wxString cellTxt = cols.GetNextToken();
674 
675  if( tbl->CanSetValueAs( row, col, wxGRID_VALUE_STRING ) )
676  {
677  tbl->SetValue( row, col, cellTxt );
678 
679  wxGridEvent evt( m_grid->GetId(), wxEVT_GRID_CELL_CHANGED, m_grid, row, col );
680  m_grid->GetEventHandler()->ProcessEvent( evt );
681  }
682  }
683  }
684 }
int m_sel_row_count
Definition: grid_tricks.h:116
int m_sel_col_start
Definition: grid_tricks.h:115
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110
int m_sel_col_count
Definition: grid_tricks.h:117
int m_sel_row_start
Definition: grid_tricks.h:114
#define ROW_SEP
Definition: grid_tricks.cpp:37
#define COL_SEP
Definition: grid_tricks.cpp:36

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

◆ SetTooltipEnable()

void GRID_TRICKS::SetTooltipEnable ( int  aCol,
bool  aEnable = true 
)
inline

Enable the tooltip for a column.

The tooltip is read from the string contained in the cell data.

Parameters
aColis the column to use
aEnableis true to enable the tooltip (default)

Definition at line 68 of file grid_tricks.h.

69  {
70  m_tooltipEnabled[aCol] = aEnable;
71  }
std::bitset< GRIDTRICKS_MAX_COL > m_tooltipEnabled
Definition: grid_tricks.h:119

References m_tooltipEnabled.

Referenced by PANEL_FP_PROPERTIES_3D_MODEL::PANEL_FP_PROPERTIES_3D_MODEL().

◆ showEditor()

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

Definition at line 114 of file grid_tricks.cpp.

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

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 276 of file grid_tricks.cpp.

277 {
278  menu.Append( GRIDTRICKS_ID_CUT, _( "Cut" ) + "\tCtrl+X",
279  _( "Clear selected cells placing original contents on clipboard" ) );
280  menu.Append( GRIDTRICKS_ID_COPY, _( "Copy" ) + "\tCtrl+C",
281  _( "Copy selected cells to clipboard" ) );
282  menu.Append( GRIDTRICKS_ID_PASTE, _( "Paste" ) + "\tCtrl+V",
283  _( "Paste clipboard cells to matrix at current cell" ) );
284  menu.Append( GRIDTRICKS_ID_DELETE, _( "Delete" ) + "\tDel", _( "Delete selected cells" ) );
285  menu.Append( GRIDTRICKS_ID_SELECT, _( "Select All" ) + "\tCtrl+A", _( "Select all cells" ) );
286 
287  getSelectedArea();
288 
289  // if nothing is selected, disable cut, copy and delete.
291  {
292  menu.Enable( GRIDTRICKS_ID_CUT, false );
293  menu.Enable( GRIDTRICKS_ID_COPY, false );
294  menu.Enable( GRIDTRICKS_ID_DELETE, false );
295  }
296 
297  menu.Enable( GRIDTRICKS_ID_PASTE, false );
298 
299  wxLogNull doNotLog; // disable logging of failed clipboard actions
300 
301  if( wxTheClipboard->Open() )
302  {
303  if( wxTheClipboard->IsSupported( wxDF_TEXT )
304  || wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
305  {
306  menu.Enable( GRIDTRICKS_ID_PASTE, true );
307  }
308 
309  wxTheClipboard->Close();
310  }
311 
312  m_grid->PopupMenu( &menu );
313 }
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:116
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:110
int m_sel_col_count
Definition: grid_tricks.h:117
#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 71 of file grid_tricks.cpp.

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

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 117 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 115 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 116 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 114 of file grid_tricks.h.

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

◆ m_tooltipEnabled

std::bitset<GRIDTRICKS_MAX_COL> GRID_TRICKS::m_tooltipEnabled
protected

Definition at line 119 of file grid_tricks.h.

Referenced by GetTooltipEnabled(), onGridMotion(), and SetTooltipEnable().


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