28#include <wx/tokenzr.h>
29#include <wx/clipbrd.h>
36#define COL_SEP wxT( '\t' )
37#define ROW_SEP wxT( '\n' )
42 m_addHandler( []( wxCommandEvent& ) {} )
50 m_addHandler( aAddHandler )
63 m_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK,
65 m_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK,
67 m_grid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK,
69 m_grid->Connect( wxEVT_GRID_LABEL_RIGHT_CLICK,
71 m_grid->Connect( wxEVT_GRID_LABEL_LEFT_CLICK,
75 m_grid->Connect( wxEVT_CHAR_HOOK,
77 m_grid->Connect( wxEVT_KEY_DOWN,
79 m_grid->Connect( wxEVT_UPDATE_UI,
83 m_grid->GetGridWindow()->Connect( wxEVT_MOTION,
91 wxGridCellRenderer* renderer =
m_grid->GetCellRenderer( aRow, aCol );
92 bool isCheckbox = (
dynamic_cast<wxGridCellBoolRenderer*
>( renderer ) );
97 if( !aPreserveSelection )
100 m_grid->SetGridCursor( aRow, aCol );
103 wxGridTableBase* model =
m_grid->GetTable();
105 if( model->CanGetValueAs( aRow, aCol, wxGRID_VALUE_BOOL )
106 && model->CanSetValueAs( aRow, aCol, wxGRID_VALUE_BOOL ) )
108 model->SetValueAsBool( aRow, aCol, !model->GetValueAsBool( aRow, aCol ) );
112 if( model->GetValue( aRow, aCol ) == wxT(
"1" ) )
113 model->SetValue( aRow, aCol, wxT(
"0" ) );
115 model->SetValue( aRow, aCol, wxT(
"1" ) );
122 wxGridEvent event(
m_grid->GetId(), wxEVT_GRID_CELL_CHANGED,
m_grid, aRow, aCol );
123 event.SetString( model->GetValue( aRow, aCol ) );
124 m_grid->GetEventHandler()->ProcessEvent( event );
135 if(
m_grid->GetGridCursorRow() != aRow ||
m_grid->GetGridCursorCol() != aCol )
136 m_grid->SetGridCursor( aRow, aCol );
138 if(
m_grid->IsEditable() && !
m_grid->IsReadOnly( aRow, aCol ) )
142 if(
m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
144 wxArrayInt rows =
m_grid->GetSelectedRows();
146 if( rows.size() != 1 || rows.Item( 0 ) != aRow )
147 m_grid->SelectRow( aRow );
170 int row = aEvent.GetRow();
171 int col = aEvent.GetCol();
174 if( !aEvent.GetModifiers() )
176 bool toggled =
false;
199 wxString newVal =
m_grid->GetCellValue( row, col );
203 if( affectedRow == row )
206 m_grid->SetCellValue( affectedRow, col, newVal );
227 wxPoint pt = aEvent.GetPosition();
228 wxPoint pos =
m_grid->CalcScrolledPosition( wxPoint( pt.x, pt.y ) );
230 int col =
m_grid->XToCol( pos.x );
231 int row =
m_grid->YToRow( pos.y );
234 if( ( col == wxNOT_FOUND ) || ( row == wxNOT_FOUND ) || !
m_tooltipEnabled[col] )
236 m_grid->GetGridWindow()->SetToolTip( wxS(
"" ) );
241 m_grid->GetGridWindow()->SetToolTip(
m_grid->GetCellValue( row, col ) );
254 wxGridCellCoordsArray topLeft =
m_grid->GetSelectionBlockTopLeft();
255 wxGridCellCoordsArray botRight =
m_grid->GetSelectionBlockBottomRight();
257 wxArrayInt cols =
m_grid->GetSelectedCols();
258 wxArrayInt rows =
m_grid->GetSelectedRows();
260 if( topLeft.Count() && botRight.Count() )
268 else if( cols.Count() )
275 else if( rows.Count() )
312 for(
int i = 0; i <
m_grid->GetNumberCols(); ++i )
315 menu.AppendCheckItem(
id,
m_grid->GetColLabelValue( i ) );
316 menu.Check(
id,
m_grid->IsColShown( i ) );
319 m_grid->PopupMenu( &menu );
326 _(
"Clear selected cells placing original contents on clipboard" ) );
328 _(
"Copy selected cells to clipboard" ) );
330 _(
"Paste clipboard cells to matrix at current cell" ) );
343 else if( !
m_grid->IsEditable() )
353 if(
m_grid->IsEditable() && wxTheClipboard->Open() )
355 if( wxTheClipboard->IsSupported( wxDF_TEXT )
356 || wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
361 wxTheClipboard->Close();
364 m_grid->PopupMenu( &menu );
376 int menu_id =
event.GetId();
408 if(
m_grid->IsColShown( col ) )
419 bool handled =
false;
421 if( ev.GetKeyCode() == WXK_RETURN &&
m_grid->GetGridCursorRow() ==
m_grid->GetNumberRows() - 1 )
425 wxCommandEvent
dummy;
429 else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() ==
'V' )
431 if(
m_grid->IsCellEditControlShown() && wxTheClipboard->Open() )
433 if( wxTheClipboard->IsSupported( wxDF_TEXT )
434 || wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
436 wxTextDataObject data;
437 wxTheClipboard->GetData( data );
439 if( data.GetText().Contains(
COL_SEP ) || data.GetText().Contains(
ROW_SEP ) )
447 wxTheClipboard->Close();
459 if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() ==
'A' )
464 else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() ==
'C' )
470 else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() ==
'V' )
476 else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() ==
'X' )
482 else if( !ev.GetModifiers() && ev.GetKeyCode() == WXK_DELETE )
490 if(
m_grid->IsEditable() && ev.GetKeyCode() ==
' ' )
495 if(
m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
497 wxArrayInt rowSel =
m_grid->GetSelectedRows();
499 for(
unsigned int rowInd = 0; rowInd < rowSel.GetCount(); rowInd++ )
501 retVal |=
toggleCell( rowSel[rowInd], 0,
true );
506 else if(
m_grid->GetSelectionMode() == wxGrid::wxGridSelectColumns )
508 wxArrayInt colSel =
m_grid->GetSelectedCols();
510 for(
unsigned int colInd = 0; colInd < colSel.GetCount(); colInd++ )
512 retVal |=
toggleCell( 0, colSel[colInd],
true );
517 else if(
m_grid->GetSelectionMode() == wxGrid::wxGridSelectCells )
519 wxArrayInt rowSel =
m_grid->GetSelectedRows();
520 wxArrayInt colSel =
m_grid->GetSelectedCols();
521 wxGridCellCoordsArray cellSel =
m_grid->GetSelectedCells();
522 wxGridCellCoordsArray topLeft =
m_grid->GetSelectionBlockTopLeft();
523 wxGridCellCoordsArray botRight =
m_grid->GetSelectionBlockBottomRight();
526 for(
unsigned int cellInd = 0; cellInd < cellSel.GetCount(); cellInd++ )
528 retVal |=
toggleCell( cellSel[cellInd].GetRow(), cellSel[cellInd].GetCol(),
true );
532 for(
unsigned int colInd = 0; colInd < colSel.GetCount(); colInd++ )
534 for(
int row = 0; row <
m_grid->GetNumberRows(); row++ )
536 retVal |=
toggleCell( row, colSel[colInd],
true );
541 for(
unsigned int rowInd = 0; rowInd < rowSel.GetCount(); rowInd++ )
543 for(
int col = 0; col <
m_grid->GetNumberCols(); col++ )
545 retVal |=
toggleCell( rowSel[rowInd], col,
true );
550 for(
unsigned int blockInd = 0; blockInd < topLeft.GetCount(); blockInd++ )
552 wxGridCellCoords start = topLeft[blockInd];
553 wxGridCellCoords end = botRight[blockInd];
555 for(
int row = start.GetRow(); row <= end.GetRow(); row++ )
557 for(
int col = start.GetCol(); col <= end.GetCol(); col++ )
572 bool ctrl = ev.RawControlDown();
574 bool ctrl = ev.ControlDown();
577 if( ctrl && ev.GetKeyCode() == WXK_TAB )
584 while(
test && !
test->IsTopLevel() )
588 if(
test->HasFocus() )
591 if( !
test->GetChildren().empty() )
595 else if(
test->GetNextSibling() )
609 else if(
test &&
test->GetNextSibling() )
629 if(
m_grid->IsEditable() && wxTheClipboard->Open() )
631 if( wxTheClipboard->IsSupported( wxDF_TEXT )
632 || wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
634 wxTextDataObject data;
636 wxTheClipboard->GetData( data );
641 wxTheClipboard->Close();
649 wxGridTableBase* tbl =
m_grid->GetTable();
651 const int cur_row =
m_grid->GetGridCursorRow();
652 const int cur_col =
m_grid->GetGridCursorCol();
657 bool is_selection =
false;
659 if( cur_row < 0 || cur_col < 0 )
665 if(
m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
672 if(
m_grid->IsSelection() )
676 wxStringTokenizer rows( cb_text,
ROW_SEP, wxTOKEN_RET_EMPTY );
692 end_row = cur_row + rows.CountTokens();
694 if( end_row > tbl->GetNumberRows() )
695 end_row = tbl->GetNumberRows();
701 for(
int row = start_row; row < end_row; ++row )
705 if( !rows.HasMoreTokens() )
706 rows.SetString( cb_text,
ROW_SEP, wxTOKEN_RET_EMPTY );
708 wxString rowTxt = rows.GetNextToken();
710 wxStringTokenizer cols( rowTxt,
COL_SEP, wxTOKEN_RET_EMPTY );
714 end_col = cur_col + cols.CountTokens();
716 if( end_col > tbl->GetNumberCols() )
717 end_col = tbl->GetNumberCols();
720 for(
int col = start_col; col < end_col; ++col )
723 if( !
m_grid->IsColShown( col ) )
728 if( !cols.HasMoreTokens() )
729 cols.SetString( rowTxt,
COL_SEP, wxTOKEN_RET_EMPTY );
731 wxString cellTxt = cols.GetNextToken();
733 if( tbl->CanSetValueAs( row, col, wxGRID_VALUE_STRING ) )
735 tbl->SetValue( row, col, cellTxt );
737 wxGridEvent evt(
m_grid->GetId(), wxEVT_GRID_CELL_CHANGED,
m_grid, row, col );
738 m_grid->GetEventHandler()->ProcessEvent( evt );
749 if( doCopy && !wxTheClipboard->Open() )
752 wxGridTableBase* tbl =
m_grid->GetTable();
760 if( !
m_grid->IsColShown( col ) )
763 txt += tbl->GetValue( row, col );
768 if( doDelete &&
m_grid->IsEditable() )
770 if( tbl->CanSetValueAs( row, col, wxGRID_VALUE_STRING ) )
771 tbl->SetValue( row, col, wxEmptyString );
780 wxTheClipboard->SetData(
new wxTextDataObject( txt ) );
781 wxTheClipboard->Flush();
782 wxTheClipboard->Close();
794 if(
m_grid->GetSelectionMode() == wxGrid::wxGridSelectRows )
796 int cursorRow =
m_grid->GetGridCursorRow();
797 bool cursorInSelectedRow =
false;
799 for(
int row :
m_grid->GetSelectedRows() )
801 if( row == cursorRow )
803 cursorInSelectedRow =
true;
808 if( !cursorInSelectedRow && cursorRow >= 0 )
809 m_grid->SelectRow( cursorRow );
void onGridMotion(wxMouseEvent &event)
void onGridLabelLeftClick(wxGridEvent &event)
virtual void paste_text(const wxString &cb_text)
void init()
Shared initialization for various ctors.
void getSelectedArea()
Puts the selected area into a sensible rectangle of m_sel_{row,col}_{start,count} above.
GRID_TRICKS(WX_GRID *aGrid)
void onKeyDown(wxKeyEvent &event)
void onPopupSelection(wxCommandEvent &event)
virtual void cutcopy(bool doCopy, bool doDelete)
virtual void doPopupSelection(wxCommandEvent &event)
std::function< void(wxCommandEvent &)> m_addHandler
std::bitset< GRIDTRICKS_MAX_COL > m_tooltipEnabled
void onUpdateUI(wxUpdateUIEvent &event)
void onGridCellRightClick(wxGridEvent &event)
WX_GRID * m_grid
I don't own the grid, but he owns me.
void onGridCellLeftDClick(wxGridEvent &event)
void onGridCellLeftClick(wxGridEvent &event)
virtual void showPopupMenu(wxMenu &menu)
virtual bool handleDoubleClick(wxGridEvent &aEvent)
void onCharHook(wxKeyEvent &event)
virtual void paste_clipboard()
bool showEditor(int aRow, int aCol)
void onGridLabelRightClick(wxGridEvent &event)
bool toggleCell(int aRow, int aCol, bool aPreserveSelection=false)
void ShowEditorOnMouseUp()
WxWidgets has a bunch of bugs in its handling of wxGrid mouse events which close cell editors right a...
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
@ GRIDTRICKS_FIRST_SHOWHIDE
std::vector< FAB_LAYER_COLOR > dummy