void ctlSQLGrid::OnLabelClick(wxGridEvent &event) { int row = event.GetRow(); int col = event.GetCol(); // add support for (de)selecting multiple rows and cols with Control pressed if ( row >= 0 && (event.ControlDown() || event.CmdDown()) ) { if (GetSelectedRows().Index(row) == wxNOT_FOUND) SelectRow(row, true); else DeselectRow(row); } else if ( col >= 0 && (event.ControlDown() || event.CmdDown()) ) { if (GetSelectedCols().Index(col) == wxNOT_FOUND) SelectCol(col, true); else DeselectCol(col); } else event.Skip(); }
/** * The Table row and column selection behaviour follows the conventions * for file selection on Mac/Windows/Linux: * - A single click selects a row/col and deselects everything else. * - Cmd (Ctrl on Win/Lin) click allows multiple item selection/deselection * - Shift click selects a range of items and deselects everything outside * of that range. * * Notes: * - ev.GetRow() refers to the displayed row numbers in the table, not * the possibly permuted rows. However, the TableBase::FromGrid___ * take care of this * - ev.GetCol() refers to the permuted columns, not necessarily the * visible column order since wxGrid hides column moves from * the underlying wxGridTableBase. This somewhat complicates * shift-click selection for columns. * * The proper shift-selection function requires a anchor point stack. We * have implemented a stateless shift select which feels quite logical in * practice. */ void TableFrame::OnLabelLeftClickEvent( wxGridEvent& ev ) { using namespace std; LOG_MSG("Entering TableFrame::OnLabelLeftClickEvent"); LOG(ev.GetCol()); LOG(ev.GetRow()); LOG(ev.ShiftDown()); LOG(ev.CmdDown()); int row = ev.GetRow(); int col = ev.GetCol(); TableInterface* table_int = project->GetTableInt(); int rows = table_int->GetNumberRows(); int cols = table_int->GetNumberCols(); if (col < 0 && row >= 0) { if (!ev.ShiftDown() && !ev.CmdDown()) { table_base->FromGridSelectOnlyRow(row); } else if (!ev.ShiftDown()) { if (table_base->FromGridIsSelectedRow(row)) { table_base->FromGridDeselectRow(row); } else { table_base->FromGridSelectRow(row); } } else { // shift down bool sel_found = false; int first_sel = -1; int last_sel = -1; for (int i=0; i<rows; i++) { if (table_base->FromGridIsSelectedRow(i)) { if (!sel_found) { first_sel = i; last_sel = i; sel_found = true; } if (i < first_sel) first_sel = i; if (i > last_sel) last_sel = i; } } if (!sel_found) { first_sel = row; last_sel = row; } else if (row <= first_sel) { last_sel = first_sel; first_sel = row; } else if (row >= last_sel) { first_sel = last_sel; last_sel = row; } else { // in the middle, so leave endpoints as they are } table_base->FromGridSelectRowRange(first_sel, last_sel); } // unselect whatever the wxGrid object selects since we are doing our // own selection. grid->ClearSelection(); grid->Refresh(); } else if (col >= 0) { // deal with column selection if (!ev.ShiftDown() && !ev.CmdDown()) table_base->DeselectAllCols(); if (!ev.ShiftDown()) { if (table_base->FromGridIsSelectedCol(col)) { table_base->FromGridDeselectCol(col); } else { table_base->FromGridSelectCol(col); } } else { // shift down. For columns, we need to work with displayed // order. So, need to get a translation from displayed col to col // and col to displayed col. vector<int> col_to_dispc(cols); vector<int> dispc_to_col(cols); for (int i=0; i<cols; i++) col_to_dispc[i] = grid->GetColPos(i); for (int i=0; i<cols; i++) dispc_to_col[i] = grid->GetColAt(i); bool sel_found = false; int dpos_first_sel = -1; int dpos_last_sel = -1; for (int dpos=0; dpos<cols; ++dpos) { if (table_base->FromGridIsSelectedCol(dispc_to_col[dpos])) { if (!sel_found) { dpos_first_sel = dpos; dpos_last_sel = dpos; sel_found = true; } if (dpos < dpos_first_sel) dpos_first_sel = dpos; if (dpos > dpos_last_sel) dpos_last_sel = dpos; } } int dispc = col_to_dispc[col]; if (!sel_found) { dpos_first_sel = dispc; dpos_last_sel = dispc; } else if (dispc <= dpos_first_sel) { dpos_last_sel = dpos_first_sel; dpos_first_sel = dispc; } else if (dispc >= dpos_last_sel) { dpos_first_sel = dpos_last_sel; dpos_last_sel = dispc; } else { // in the middle, so leave endpoints as they are } for (int dc=0; dc<cols; ++dc) { int id = dispc_to_col[dc]; if (dc < dpos_first_sel || dc > dpos_last_sel) { if (table_base->FromGridIsSelectedCol(id)) { table_base->FromGridDeselectCol(id); } } else { if (!table_base->FromGridIsSelectedCol(id)) { table_base->FromGridSelectCol(id); } } } } // unselect whatever the wxGrid object selects since we are doing our // own selection. grid->ClearSelection(); grid->Refresh(); ev.Skip(); // Col move doesn't work if we don't call ev.Skip() } else if (col < 0 && row < 0) { // Deselect all rows and columns table_base->DeselectAllRows(); table_base->DeselectAllCols(); // unselect whatever the wxGrid object selects since we are doing our // own selection. grid->ClearSelection(); grid->Refresh(); //ev.Skip(); } LOG_MSG("Exiting TableFrame::OnLabelLeftClickEvent"); }
void ctlSQLGrid::OnLabelDoubleClick(wxGridEvent &event) { int maxHeight, maxWidth; GetClientSize(&maxWidth, &maxHeight); int row = event.GetRow(); int col = event.GetCol(); int extent, extentWant = 0; if (row >= 0) { for (col = 0 ; col < GetNumberCols() ; col++) { extent = GetBestSize(row, col).GetHeight(); if (extent > extentWant) extentWant = extent; } extentWant += EXTRAEXTENT_HEIGHT; extentWant = wxMax(extentWant, GetRowMinimalAcceptableHeight()); extentWant = wxMin(extentWant, maxHeight * 3 / 4); int currentHeight = GetRowHeight(row); if (currentHeight >= maxHeight * 3 / 4 || currentHeight == extentWant) extentWant = GetRowMinimalAcceptableHeight(); else if (currentHeight < maxHeight / 4) extentWant = wxMin(maxHeight / 4, extentWant); else if (currentHeight < maxHeight / 2) extentWant = wxMin(maxHeight / 2, extentWant); else if (currentHeight < maxHeight * 3 / 4) extentWant = wxMin(maxHeight * 3 / 4, extentWant); if (extentWant != currentHeight) { BeginBatch(); if(IsCellEditControlShown()) { HideCellEditControl(); SaveEditControlValue(); } SetRowHeight(row, extentWant); EndBatch(); } } else if (col >= 0) { // Holding Ctrl or Meta switches back to automatic column's sizing if (event.ControlDown() || event.CmdDown()) { colSizes.erase(GetColKeyValue(col)); BeginBatch(); if(IsCellEditControlShown()) { HideCellEditControl(); SaveEditControlValue(); } AutoSizeColumn(col, false); EndBatch(); } else // toggle between some predefined sizes { if (col < (int)colMaxSizes.GetCount() && colMaxSizes[col] >= 0) extentWant = colMaxSizes[col]; else { for (row = 0 ; row < GetNumberRows() ; row++) { if (CheckRowPresent(row)) { extent = GetBestSize(row, col).GetWidth(); if (extent > extentWant) extentWant = extent; } } } extentWant += EXTRAEXTENT_WIDTH; extentWant = wxMax(extentWant, GetColMinimalAcceptableWidth()); extentWant = wxMin(extentWant, maxWidth * 3 / 4); int currentWidth = GetColumnWidth(col); if (currentWidth >= maxWidth * 3 / 4 || currentWidth == extentWant) extentWant = GetColMinimalAcceptableWidth(); else if (currentWidth < maxWidth / 4) extentWant = wxMin(maxWidth / 4, extentWant); else if (currentWidth < maxWidth / 2) extentWant = wxMin(maxWidth / 2, extentWant); else if (currentWidth < maxWidth * 3 / 4) extentWant = wxMin(maxWidth * 3 / 4, extentWant); if (extentWant != currentWidth) { BeginBatch(); if(IsCellEditControlShown()) { HideCellEditControl(); SaveEditControlValue(); } SetColumnWidth(col, extentWant); EndBatch(); colSizes[GetColKeyValue(col)] = extentWant; } } } }