- Main change is the addition of wxGridSelectRowsOrColumns selection mode

(which is still probably buggy, wxGridSelection needs to be reviewed)
- Add XYToCell() overloads returning wxGridCellCoords (instead of modifying the
  argument passed by reference -- where did this come from?) and document them.
- Added GoToCell() which does make the new current cell visible unlike
  SetGridCursor() (which was documented as doing it, but wasn't)
- Changed SetCurrentCell() to only not change the cell if wxEVT_GRID_SELECT_CELL
  it generates is vetoed, not just processed as this seems to make more sense
- Split jumbo (~400 lines) ProcessGridCellMouseEvent() function into chunks
- Add many more comments to make reading this code seem less like puzzle
  solving for the next unfortunate soul to do it


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55746 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-09-19 23:33:04 +00:00
parent 0e0977894a
commit 8a3e536cd5
8 changed files with 717 additions and 502 deletions

View File

@@ -392,6 +392,7 @@ All (GUI):
- wxWindow::IsBeingDeleted() now returns true not only if the window itself is
marked for destruction but also if any of its parent windows are.
- Improved drawing of the hint during column move in wxGrid.
- Add wxGridSelectRowsOrColumns selection mode to wxGrid.
- Get/HasModifiers() of wxKeyEvent are now also available in wxMouseEvent.
wxGTK:

View File

@@ -320,7 +320,7 @@ public:
// Show or hide the edit control, use the specified attributes to set
// colours/fonts for it
virtual void Show(bool show, wxGridCellAttr *attr = (wxGridCellAttr *)NULL);
virtual void Show(bool show, wxGridCellAttr *attr = NULL);
// Draws the part of the cell not occupied by the control: the base class
// version just fills it with background colour from the attribute
@@ -1145,6 +1145,10 @@ public:
bool takeOwnership = false,
wxGridSelectionModes selmode = wxGridSelectCells );
bool ProcessTableMessage(wxGridTableMessage&);
wxGridTableBase *GetTable() const { return m_table; }
void SetSelectionMode(wxGridSelectionModes selmode);
wxGridSelectionModes GetSelectionMode() const;
@@ -1163,20 +1167,6 @@ public:
wxGridCellCoordsArray CalcCellsExposed( const wxRegion& reg ) const;
// ------ event handlers
//
void ProcessRowLabelMouseEvent( wxMouseEvent& event );
void ProcessColLabelMouseEvent( wxMouseEvent& event );
void ProcessCornerLabelMouseEvent( wxMouseEvent& event );
void ProcessGridCellMouseEvent( wxMouseEvent& event );
bool ProcessTableMessage( wxGridTableMessage& );
void DoEndDragResizeRow();
void DoEndDragResizeCol();
void DoEndDragMoveCol();
wxGridTableBase * GetTable() const { return m_table; }
void ClearGrid();
bool InsertRows(int pos = 0, int numRows = 1, bool updateLabels = true)
{
@@ -1261,8 +1251,7 @@ public:
int GetBatchCount() { return m_batchCount; }
virtual void Refresh(bool eraseb = true,
const wxRect* rect = (const wxRect *) NULL);
virtual void Refresh(bool eraseb = true, const wxRect* rect = NULL);
// Use this, rather than wxWindow::Refresh(), to force an
// immediate repainting of the grid. Has no effect if you are
@@ -1297,7 +1286,12 @@ public:
// grid cells and labels so you will need to convert from device
// coordinates for mouse events etc.
//
void XYToCell( int x, int y, wxGridCellCoords& ) const;
wxGridCellCoords XYToCell(int x, int y) const;
void XYToCell(int x, int y, wxGridCellCoords& coords) const
{ coords = XYToCell(x, y); }
wxGridCellCoords XYToCell(const wxPoint& pos) const
{ return XYToCell(pos.x, pos.y); }
int YToRow( int y, bool clipToMinMax = false ) const;
int XToCol( int x, bool clipToMinMax = false ) const;
@@ -1324,8 +1318,20 @@ public:
// ------ grid cursor movement functions
//
void SetGridCursor( int row, int col )
{ SetCurrentCell( wxGridCellCoords(row, col) ); }
void SetGridCursor(int row, int col) { SetCurrentCell(row, col); }
void SetGridCursor(const wxGridCellCoords& c) { SetCurrentCell(c); }
void GoToCell(int row, int col)
{
if ( SetCurrentCell(row, col) )
MakeCellVisible(row, col);
}
void GoToCell(const wxGridCellCoords& coords)
{
if ( SetCurrentCell(coords) )
MakeCellVisible(coords);
}
bool MoveCursorUp( bool expandSelection );
bool MoveCursorDown( bool expandSelection );
@@ -1867,10 +1873,22 @@ protected:
wxGridCellCoords m_currentCellCoords;
wxGridCellCoords m_selectingTopLeft;
wxGridCellCoords m_selectingBottomRight;
wxGridCellCoords m_selectingKeyboard;
// the corners of the block being currently selected or wxGridNoCellCoords
wxGridCellCoords m_selectedBlockTopLeft;
wxGridCellCoords m_selectedBlockBottomRight;
// when selecting blocks of cells (either from the keyboard using Shift
// with cursor keys, or by dragging the mouse), the selection is anchored
// at m_currentCellCoords which defines one of the corners of the rectangle
// being selected -- and this variable defines the other corner, i.e. it's
// either m_selectedBlockTopLeft or m_selectedBlockBottomRight depending on
// which of them is not m_currentCellCoords
//
// if no block selection is in process, it is set to wxGridNoCellCoords
wxGridCellCoords m_selectedBlockCorner;
wxGridSelection *m_selection;
wxColour m_selectionBackground;
wxColour m_selectionForeground;
@@ -2007,12 +2025,22 @@ protected:
// for this to work, you should always use it and not set m_cursorMode
// directly!
void ChangeCursorMode(CursorMode mode,
wxWindow *win = (wxWindow *)NULL,
wxWindow *win = NULL,
bool captureMouse = true);
wxWindow *m_winCapture; // the window which captured the mouse
// this variable is used not for finding the correct current cursor but
// mainly for finding out what is going to happen if the mouse starts being
// dragged right now
//
// by default it is WXGRID_CURSOR_SELECT_CELL meaning that nothing else is
// going on, and it is set to one of RESIZE/SELECT/MOVE values while the
// corresponding operation will be started if the user starts dragging the
// mouse from the current position
CursorMode m_cursorMode;
//Column positions
wxArrayInt m_colAt;
int m_moveToCol;
@@ -2029,7 +2057,16 @@ protected:
int m_dragLastPos;
int m_dragRowOrCol;
// true if a drag operation is in progress; when this is true,
// m_startDragPos is valid, i.e. not wxDefaultPosition
bool m_isDragging;
// the position (in physical coordinates) where the user started dragging
// the mouse or wxDefaultPosition if mouse isn't being dragged
//
// notice that this can be != wxDefaultPosition while m_isDragging is still
// false because we wait until the mouse is moved some distance away before
// setting m_isDragging to true
wxPoint m_startDragPos;
bool m_waitForSlowClick;
@@ -2053,14 +2090,20 @@ protected:
bool Redimension( wxGridTableMessage& );
int SendEvent( const wxEventType, int row, int col, wxMouseEvent& );
int SendEvent( const wxEventType, int row, int col );
int SendEvent( const wxEventType type)
{
return SendEvent(type,
m_currentCellCoords.GetRow(),
m_currentCellCoords.GetCol());
}
// generate the appropriate grid event and return -1 if it was vetoed, 1 if
// it was processed (but not vetoed) and 0 if it wasn't processed
int SendEvent(const wxEventType evtType,
int row, int col,
wxMouseEvent& e);
int SendEvent(const wxEventType evtType,
const wxGridCellCoords& coords,
wxMouseEvent& e)
{ return SendEvent(evtType, coords.GetRow(), coords.GetCol(), e); }
int SendEvent(const wxEventType evtType, int row, int col);
int SendEvent(const wxEventType evtType, const wxGridCellCoords& coords)
{ return SendEvent(evtType, coords.GetRow(), coords.GetCol()); }
int SendEvent(const wxEventType evtType)
{ return SendEvent(evtType, m_currentCellCoords); }
void OnPaint( wxPaintEvent& );
void OnSize( wxSizeEvent& );
@@ -2070,16 +2113,20 @@ protected:
void OnEraseBackground( wxEraseEvent& );
void SetCurrentCell( const wxGridCellCoords& coords );
void SetCurrentCell( int row, int col )
{ SetCurrentCell( wxGridCellCoords(row, col) ); }
bool SetCurrentCell( const wxGridCellCoords& coords );
bool SetCurrentCell( int row, int col )
{ return SetCurrentCell( wxGridCellCoords(row, col) ); }
void HighlightBlock( int topRow, int leftCol, int bottomRow, int rightCol );
void HighlightBlock( const wxGridCellCoords& topLeft,
const wxGridCellCoords& bottomRight )
{ HighlightBlock( topLeft.GetRow(), topLeft.GetCol(),
bottomRight.GetRow(), bottomRight.GetCol() ); }
// this function is called to extend the block being currently selected
// from mouse and keyboard event handlers
void UpdateBlockBeingSelected(int topRow, int leftCol,
int bottomRow, int rightCol);
void UpdateBlockBeingSelected(const wxGridCellCoords& topLeft,
const wxGridCellCoords& bottomRight)
{ UpdateBlockBeingSelected(topLeft.GetRow(), topLeft.GetCol(),
bottomRight.GetRow(), bottomRight.GetCol()); }
// ------ functions to get/send data (see also public functions)
//
@@ -2090,10 +2137,56 @@ protected:
friend class wxGridRowOperations;
friend class wxGridColumnOperations;
// they call our private Process{{Corner,Col,Row}Label,GridCell}MouseEvent()
friend class wxGridCornerLabelWindow;
friend class wxGridColLabelWindow;
friend class wxGridRowLabelWindow;
friend class wxGridWindow;
private:
// implement wxScrolledWindow method to return m_gridWin size
virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size);
// event handlers and their helpers
// --------------------------------
// process mouse drag event in WXGRID_CURSOR_SELECT_CELL mode
void DoGridCellDrag(wxMouseEvent& event,
const wxGridCellCoords& coords,
bool isFirstDrag);
// process row/column resizing drag event
void DoGridLineDrag(wxMouseEvent& event, const wxGridOperations& oper);
// process mouse drag event in the grid window
void DoGridDragEvent(wxMouseEvent& event, const wxGridCellCoords& coords);
// process different clicks on grid cells
void DoGridCellLeftDown(wxMouseEvent& event,
const wxGridCellCoords& coords,
const wxPoint& pos);
void DoGridCellLeftDClick(wxMouseEvent& event,
const wxGridCellCoords& coords,
const wxPoint& pos);
void DoGridCellLeftUp(wxMouseEvent& event, const wxGridCellCoords& coords);
// process movement (but not dragging) event in the grid cell area
void DoGridMouseMoveEvent(wxMouseEvent& event,
const wxGridCellCoords& coords,
const wxPoint& pos);
// process mouse events in the grid window
void ProcessGridCellMouseEvent(wxMouseEvent& event);
// process mouse events in the row/column labels/corner windows
void ProcessRowLabelMouseEvent(wxMouseEvent& event);
void ProcessColLabelMouseEvent(wxMouseEvent& event);
void ProcessCornerLabelMouseEvent(wxMouseEvent& event);
void DoEndDragResizeRow();
void DoEndDragResizeCol();
void DoEndDragMoveCol();
// common implementations of methods defined for both rows and columns
void DeselectLine(int line, const wxGridOperations& oper);

View File

@@ -44,10 +44,23 @@ public:
bool ControlDown = false, bool ShiftDown = false,
bool AltDown = false, bool MetaDown = false,
bool sendEvent = true );
void SelectBlock( const wxGridCellCoords& topLeft,
const wxGridCellCoords& bottomRight,
bool ControlDown = false, bool ShiftDown = false,
bool AltDown = false, bool MetaDown = false,
bool sendEvent = true )
{
SelectBlock(topLeft.GetRow(), topLeft.GetCol(),
bottomRight.GetRow(), bottomRight.GetCol(),
ControlDown, ShiftDown, AltDown, MetaDown,
sendEvent);
}
void SelectCell( int row, int col,
bool ControlDown = false, bool ShiftDown = false,
bool AltDown = false, bool MetaDown = false,
bool sendEvent = true );
void ToggleCellSelection( int row, int col,
bool ControlDown = false,
bool ShiftDown = false,

View File

@@ -2130,6 +2130,19 @@ public:
*/
wxGridTableBase *GetTable() const;
//@{
/**
Make the given cell current and ensure it is visible.
This method is equivalent to calling MakeCellVisible() and
SetGridCursor() and so, as with the latter, a wxEVT_GRID_SELECT_CELL
event is generated by it and the selected cell doesn't change if the
event is vetoed.
*/
void GoToCell(int row, int col);
void GoToCell(const wxGridCellCoords& coords);
//@}
/**
Returns @true if drawing of grid lines is turned on, @false otherwise.
*/
@@ -2693,12 +2706,22 @@ public:
*/
void SetDefaultRowSize(int height, bool resizeExistingRows = false);
//@{
/**
Set the grid cursor to the specified cell.
This function calls MakeCellVisible().
The grid cursor indicates the current cell and can be moved by the user
using the arrow keys or the mouse.
Calling this function generates a wxEVT_GRID_SELECT_CELL event and if
the event handler vetoes this event, the cursor is not moved.
This function doesn't make the target call visible, use GoToCell() to
do this.
*/
void SetGridCursor(int row, int col);
void SetGridCursor(const wxGridCellCoords& coords);
//@}
/**
Sets the colour used to draw grid lines.
@@ -2883,6 +2906,27 @@ public:
*/
int XToEdgeOfCol(int x) const;
//@{
/**
Translates logical pixel coordinates to the grid cell coordinates.
Notice that this function expects logical coordinates on input so if
you use this function in a mouse event handler you need to translate
the mouse position, which is expressed in device coordinates, to
logical ones.
@see XToCol(), YToRow()
*/
// XYToCell(int, int, wxGridCellCoords&) overload is intentionally
// undocumented, using it is ugly and non-const reference parameters are
// not used in wxWidgets API
wxGridCellCoords XYToCell(int x, int y) const;
wxGridCellCoords XYToCell(const wxPoint& pos) const;
//@}
/**
Returns the row whose bottom edge is close to the given logical y
position.

View File

@@ -92,6 +92,7 @@ BEGIN_EVENT_TABLE( GridFrame, wxFrame )
EVT_MENU( ID_SELCELLS, GridFrame::SelectCells )
EVT_MENU( ID_SELROWS, GridFrame::SelectRows )
EVT_MENU( ID_SELCOLS, GridFrame::SelectCols )
EVT_MENU( ID_SELROWSORCOLS, GridFrame::SelectRowsOrCols )
EVT_MENU( ID_SET_CELL_FG_COLOUR, GridFrame::SetCellFgColour )
EVT_MENU( ID_SET_CELL_BG_COLOUR, GridFrame::SetCellBgColour )
@@ -223,9 +224,10 @@ GridFrame::GridFrame()
selectionMenu,
_T("Change selection mode") );
selectionMenu->Append( ID_SELCELLS, _T("Select &Cells") );
selectionMenu->Append( ID_SELROWS, _T("Select &Rows") );
selectionMenu->Append( ID_SELCOLS, _T("Select C&ols") );
selectionMenu->Append( ID_SELCELLS, _T("Select &cells") );
selectionMenu->Append( ID_SELROWS, _T("Select &rows") );
selectionMenu->Append( ID_SELCOLS, _T("Select col&umns") );
selectionMenu->Append( ID_SELROWSORCOLS, _T("Select rows &or columns") );
wxMenu *autosizeMenu = new wxMenu;
autosizeMenu->Append( ID_SIZE_ROW, _T("Selected &row data") );
@@ -807,6 +809,11 @@ void GridFrame::SelectCols( wxCommandEvent& WXUNUSED(ev) )
grid->SetSelectionMode( wxGrid::wxGridSelectColumns );
}
void GridFrame::SelectRowsOrCols( wxCommandEvent& WXUNUSED(ev) )
{
grid->SetSelectionMode( wxGrid::wxGridSelectRowsOrColumns );
}
void GridFrame::SetCellFgColour( wxCommandEvent& WXUNUSED(ev) )
{
wxColour col = wxGetColourFromUser(this);

View File

@@ -64,6 +64,7 @@ class GridFrame : public wxFrame
void SelectCells( wxCommandEvent& );
void SelectRows( wxCommandEvent& );
void SelectCols( wxCommandEvent& );
void SelectRowsOrCols( wxCommandEvent& );
void DeselectCell(wxCommandEvent& event);
void DeselectCol(wxCommandEvent& event);
@@ -144,6 +145,7 @@ public:
ID_SELCELLS,
ID_SELROWS,
ID_SELCOLS,
ID_SELROWSORCOLS,
ID_SET_CELL_FG_COLOUR,
ID_SET_CELL_BG_COLOUR,
ID_VTABLE,

View File

@@ -471,11 +471,20 @@ public:
// Draws a line parallel to the row or column, i.e. horizontal or vertical:
// pos is the vertical or horizontal position of the line and start and end
// pos is the horizontal or vertical position of the line and start and end
// are the coordinates of the line extremities in the other direction
virtual void
DrawParallelLine(wxDC& dc, int start, int end, int pos) const = 0;
// Draw a horizontal or vertical line across the given rectangle
// (this is implemented in terms of above and uses Select() to extract
// start and end from the given rectangle)
void DrawParallelLineInRect(wxDC& dc, const wxRect& rect, int pos) const
{
const int posStart = Select(rect.GetPosition());
DrawParallelLine(dc, posStart, posStart + Select(rect.GetSize()), pos);
}
// Return the row or column at the given pixel coordinate.
virtual int
@@ -785,13 +794,22 @@ private:
wxGridCellCoords wxGridNoCellCoords( -1, -1 );
wxRect wxGridNoCellRect( -1, -1, -1, -1 );
namespace
{
// scroll line size
static const size_t GRID_SCROLL_LINE_X = 15;
static const size_t GRID_SCROLL_LINE_Y = GRID_SCROLL_LINE_X;
const size_t GRID_SCROLL_LINE_X = 15;
const size_t GRID_SCROLL_LINE_Y = GRID_SCROLL_LINE_X;
// the size of hash tables used a bit everywhere (the max number of elements
// in these hash tables is the number of rows/columns)
static const int GRID_HASH_SIZE = 100;
const int GRID_HASH_SIZE = 100;
// the minimal distance in pixels the mouse needs to move to start a drag
// operation
const int DRAG_SENSITIVITY = 3;
} // anonymous namespace
// ----------------------------------------------------------------------------
// private helpers
@@ -4708,22 +4726,22 @@ wxGrid::SetTable(wxGridTableBase *table,
// If the newly set table is smaller than the
// original one current cell and selection regions
// might be invalid,
m_selectingKeyboard = wxGridNoCellCoords;
m_selectedBlockCorner = wxGridNoCellCoords;
m_currentCellCoords =
wxGridCellCoords(wxMin(m_numRows, m_currentCellCoords.GetRow()),
wxMin(m_numCols, m_currentCellCoords.GetCol()));
if (m_selectingTopLeft.GetRow() >= m_numRows ||
m_selectingTopLeft.GetCol() >= m_numCols)
if (m_selectedBlockTopLeft.GetRow() >= m_numRows ||
m_selectedBlockTopLeft.GetCol() >= m_numCols)
{
m_selectingTopLeft = wxGridNoCellCoords;
m_selectingBottomRight = wxGridNoCellCoords;
m_selectedBlockTopLeft = wxGridNoCellCoords;
m_selectedBlockBottomRight = wxGridNoCellCoords;
}
else
m_selectingBottomRight =
m_selectedBlockBottomRight =
wxGridCellCoords(wxMin(m_numRows,
m_selectingBottomRight.GetRow()),
m_selectedBlockBottomRight.GetRow()),
wxMin(m_numCols,
m_selectingBottomRight.GetCol()));
m_selectedBlockBottomRight.GetCol()));
}
CalcDimensions();
@@ -6132,6 +6150,8 @@ void wxGrid::CancelMouseCapture()
if ( m_winCapture )
{
m_isDragging = false;
m_startDragPos = wxDefaultPosition;
m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
m_winCapture->SetCursor( *wxSTANDARD_CURSOR );
m_winCapture = NULL;
@@ -6214,186 +6234,155 @@ void wxGrid::ChangeCursorMode(CursorMode mode,
}
}
void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
// ----------------------------------------------------------------------------
// grid mouse event processing
// ----------------------------------------------------------------------------
void
wxGrid::DoGridCellDrag(wxMouseEvent& event,
const wxGridCellCoords& coords,
bool isFirstDrag)
{
int x, y;
wxPoint pos( event.GetPosition() );
CalcUnscrolledPosition( pos.x, pos.y, &x, &y );
if ( coords == wxGridNoCellCoords )
return; // we're outside any valid cell
wxGridCellCoords coords;
XYToCell( x, y, coords );
int cell_rows, cell_cols;
bool isFirstDrag = !m_isDragging;
GetCellSize( coords.GetRow(), coords.GetCol(), &cell_rows, &cell_cols );
if ((cell_rows < 0) || (cell_cols < 0))
{
coords.SetRow(coords.GetRow() + cell_rows);
coords.SetCol(coords.GetCol() + cell_cols);
}
if ( event.Dragging() )
{
//wxLogDebug("pos(%d, %d) coords(%d, %d)", pos.x, pos.y, coords.GetRow(), coords.GetCol());
// Don't start doing anything until the mouse has been dragged at
// least 3 pixels in any direction...
if (! m_isDragging)
{
if (m_startDragPos == wxDefaultPosition)
{
m_startDragPos = pos;
return;
}
if (abs(m_startDragPos.x - pos.x) < 4 && abs(m_startDragPos.y - pos.y) < 4)
return;
}
m_isDragging = true;
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
// Hide the edit control, so it
// won't interfere with drag-shrinking.
// Hide the edit control, so it won't interfere with drag-shrinking.
if ( IsCellEditControlShown() )
{
HideCellEditControl();
SaveEditControlValue();
}
if ( coords != wxGridNoCellCoords )
switch ( event.GetModifiers() )
{
if ( event.CmdDown() )
{
if ( m_selectingKeyboard == wxGridNoCellCoords)
m_selectingKeyboard = coords;
HighlightBlock( m_selectingKeyboard, coords );
}
else if ( CanDragCell() )
case wxMOD_CMD:
if ( m_selectedBlockCorner == wxGridNoCellCoords)
m_selectedBlockCorner = coords;
UpdateBlockBeingSelected(m_selectedBlockCorner, coords);
break;
case wxMOD_NONE:
if ( CanDragCell() )
{
if ( isFirstDrag )
{
if ( m_selectingKeyboard == wxGridNoCellCoords)
m_selectingKeyboard = coords;
if ( m_selectedBlockCorner == wxGridNoCellCoords)
m_selectedBlockCorner = coords;
SendEvent( wxEVT_GRID_CELL_BEGIN_DRAG,
coords.GetRow(),
coords.GetCol(),
event );
SendEvent(wxEVT_GRID_CELL_BEGIN_DRAG, coords, event);
return;
}
}
else
{
if ( !IsSelection() )
{
HighlightBlock( coords, coords );
UpdateBlockBeingSelected(m_currentCellCoords, coords);
break;
default:
// we don't handle the other key modifiers
event.Skip();
}
else
}
void wxGrid::DoGridLineDrag(wxMouseEvent& event, const wxGridOperations& oper)
{
wxClientDC dc(m_gridWin);
PrepareDC(dc);
dc.SetLogicalFunction(wxINVERT);
const wxRect rectWin(CalcUnscrolledPosition(wxPoint(0, 0)),
m_gridWin->GetClientSize());
// erase the previously drawn line, if any
if ( m_dragLastPos >= 0 )
oper.DrawParallelLineInRect(dc, rectWin, m_dragLastPos);
// we need the vertical position for rows and horizontal for columns here
m_dragLastPos = oper.Dual().Select(CalcUnscrolledPosition(event.GetPosition()));
// don't allow resizing beneath the minimal size
const int posMin = oper.GetLineStartPos(this, m_dragRowOrCol) +
oper.GetMinimalLineSize(this, m_dragRowOrCol);
if ( m_dragLastPos < posMin )
m_dragLastPos = posMin;
// and draw it at the new position
oper.DrawParallelLineInRect(dc, rectWin, m_dragLastPos);
}
void wxGrid::DoGridDragEvent(wxMouseEvent& event, const wxGridCellCoords& coords)
{
if ( !m_isDragging )
{
HighlightBlock( m_currentCellCoords, coords );
}
// Don't start doing anything until the mouse has been dragged far
// enough
const wxPoint& pt = event.GetPosition();
if ( m_startDragPos == wxDefaultPosition )
{
m_startDragPos = pt;
return;
}
if (! IsVisible(coords))
if ( abs(m_startDragPos.x - pt.x) <= DRAG_SENSITIVITY &&
abs(m_startDragPos.y - pt.y) <= DRAG_SENSITIVITY )
return;
}
const bool isFirstDrag = !m_isDragging;
m_isDragging = true;
switch ( m_cursorMode )
{
MakeCellVisible(coords);
// TODO: need to introduce a delay or something here. The
// scrolling is way too fast, at least under MSW and GTK.
case WXGRID_CURSOR_SELECT_CELL:
DoGridCellDrag(event, coords, isFirstDrag);
break;
case WXGRID_CURSOR_RESIZE_ROW:
DoGridLineDrag(event, wxGridRowOperations());
break;
case WXGRID_CURSOR_RESIZE_COL:
DoGridLineDrag(event, wxGridColumnOperations());
break;
default:
event.Skip();
}
}
// Have we captured the mouse yet?
if (! m_winCapture)
if ( isFirstDrag )
{
m_winCapture = m_gridWin;
m_winCapture->CaptureMouse();
}
}
}
else if ( event.LeftIsDown() &&
m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
void
wxGrid::DoGridCellLeftDown(wxMouseEvent& event,
const wxGridCellCoords& coords,
const wxPoint& pos)
{
if ( SendEvent(wxEVT_GRID_CELL_LEFT_CLICK, coords, event) )
{
int cw, ch, left, dummy;
m_gridWin->GetClientSize( &cw, &ch );
CalcUnscrolledPosition( 0, 0, &left, &dummy );
wxClientDC dc( m_gridWin );
PrepareDC( dc );
y = wxMax( y, GetRowTop(m_dragRowOrCol) +
GetRowMinimalHeight(m_dragRowOrCol) );
dc.SetLogicalFunction(wxINVERT);
if ( m_dragLastPos >= 0 )
{
dc.DrawLine( left, m_dragLastPos, left+cw, m_dragLastPos );
}
dc.DrawLine( left, y, left+cw, y );
m_dragLastPos = y;
}
else if ( event.LeftIsDown() &&
m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
{
int cw, ch, dummy, top;
m_gridWin->GetClientSize( &cw, &ch );
CalcUnscrolledPosition( 0, 0, &dummy, &top );
wxClientDC dc( m_gridWin );
PrepareDC( dc );
x = wxMax( x, GetColLeft(m_dragRowOrCol) +
GetColMinimalWidth(m_dragRowOrCol) );
dc.SetLogicalFunction(wxINVERT);
if ( m_dragLastPos >= 0 )
{
dc.DrawLine( m_dragLastPos, top, m_dragLastPos, top + ch );
}
dc.DrawLine( x, top, x, top + ch );
m_dragLastPos = x;
}
// event handled by user code, no need to do anything here
return;
}
m_isDragging = false;
m_startDragPos = wxDefaultPosition;
// VZ: if we do this, the mode is reset to WXGRID_CURSOR_SELECT_CELL
// immediately after it becomes WXGRID_CURSOR_RESIZE_ROW/COL under
// wxGTK
#if 0
if ( event.Entering() || event.Leaving() )
{
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
m_gridWin->SetCursor( *wxSTANDARD_CURSOR );
}
else
#endif // 0
// ------------ Left button pressed
//
if ( event.LeftDown() && coords != wxGridNoCellCoords )
{
if ( !SendEvent( wxEVT_GRID_CELL_LEFT_CLICK,
coords.GetRow(),
coords.GetCol(),
event ) )
{
if ( !event.CmdDown() )
ClearSelection();
if ( event.ShiftDown() )
{
if ( m_selection )
{
m_selection->SelectBlock( m_currentCellCoords.GetRow(),
m_currentCellCoords.GetCol(),
coords.GetRow(),
coords.GetCol(),
m_selection->SelectBlock( m_currentCellCoords,
coords,
event.ControlDown(),
event.ShiftDown(),
event.AltDown(),
event.MetaDown() );
m_selectedBlockCorner = coords;
}
}
else if ( XToEdgeOfCol(x) < 0 &&
YToEdgeOfRow(y) < 0 )
else if ( XToEdgeOfCol(pos.x) < 0 && YToEdgeOfRow(pos.y) < 0 )
{
DisableCellEditControl();
MakeCellVisible( coords );
@@ -6402,16 +6391,15 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
{
if ( m_selection )
{
m_selection->ToggleCellSelection( coords.GetRow(),
coords.GetCol(),
m_selection->ToggleCellSelection( coords,
event.ControlDown(),
event.ShiftDown(),
event.AltDown(),
event.MetaDown() );
}
m_selectingTopLeft = wxGridNoCellCoords;
m_selectingBottomRight = wxGridNoCellCoords;
m_selectingKeyboard = coords;
m_selectedBlockTopLeft = wxGridNoCellCoords;
m_selectedBlockBottomRight = wxGridNoCellCoords;
m_selectedBlockCorner = coords;
}
else
{
@@ -6420,33 +6408,27 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
SetCurrentCell( coords );
}
}
}
}
}
// ------------ Left double click
//
else if ( event.LeftDClick() && coords != wxGridNoCellCoords )
void
wxGrid::DoGridCellLeftDClick(wxMouseEvent& event,
const wxGridCellCoords& coords,
const wxPoint& pos)
{
if ( XToEdgeOfCol(pos.x) < 0 && YToEdgeOfRow(pos.y) < 0 )
{
DisableCellEditControl();
if ( XToEdgeOfCol(x) < 0 && YToEdgeOfRow(y) < 0 )
{
if ( !SendEvent( wxEVT_GRID_CELL_LEFT_DCLICK,
coords.GetRow(),
coords.GetCol(),
event ) )
if ( !SendEvent(wxEVT_GRID_CELL_LEFT_DCLICK, coords, event) )
{
// we want double click to select a cell and start editing
// (i.e. to behave in same way as sequence of two slow clicks):
m_waitForSlowClick = true;
}
}
}
}
// ------------ Left button released
//
else if ( event.LeftUp() )
{
void
wxGrid::DoGridCellLeftUp(wxMouseEvent& event, const wxGridCellCoords& coords)
{
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
if (m_winCapture)
@@ -6469,23 +6451,21 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
m_waitForSlowClick = false;
}
else if ( m_selectingTopLeft != wxGridNoCellCoords &&
m_selectingBottomRight != wxGridNoCellCoords )
else if ( m_selectedBlockTopLeft != wxGridNoCellCoords &&
m_selectedBlockBottomRight != wxGridNoCellCoords )
{
if ( m_selection )
{
m_selection->SelectBlock( m_selectingTopLeft.GetRow(),
m_selectingTopLeft.GetCol(),
m_selectingBottomRight.GetRow(),
m_selectingBottomRight.GetCol(),
m_selection->SelectBlock( m_selectedBlockTopLeft,
m_selectedBlockBottomRight,
event.ControlDown(),
event.ShiftDown(),
event.AltDown(),
event.MetaDown() );
}
m_selectingTopLeft = wxGridNoCellCoords;
m_selectingBottomRight = wxGridNoCellCoords;
m_selectedBlockTopLeft = wxGridNoCellCoords;
m_selectedBlockBottomRight = wxGridNoCellCoords;
// Show the edit control, if it has been hidden for
// drag-shrinking.
@@ -6514,40 +6494,13 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
}
m_dragLastPos = -1;
}
}
// ------------ Right button down
//
else if ( event.RightDown() && coords != wxGridNoCellCoords )
{
DisableCellEditControl();
if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_CLICK,
coords.GetRow(),
coords.GetCol(),
event ) )
{
// no default action at the moment
}
}
// ------------ Right double click
//
else if ( event.RightDClick() && coords != wxGridNoCellCoords )
{
DisableCellEditControl();
if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_DCLICK,
coords.GetRow(),
coords.GetCol(),
event ) )
{
// no default action at the moment
}
}
// ------------ Moving and no button action
//
else if ( event.Moving() && !event.IsButton() )
{
void
wxGrid::DoGridMouseMoveEvent(wxMouseEvent& WXUNUSED(event),
const wxGridCellCoords& coords,
const wxPoint& pos)
{
if ( coords.GetRow() < 0 || coords.GetCol() < 0 )
{
// out of grid cell area
@@ -6555,8 +6508,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
return;
}
int dragRow = YToEdgeOfRow( y );
int dragCol = XToEdgeOfCol( x );
int dragRow = YToEdgeOfRow( pos.y );
int dragCol = XToEdgeOfCol( pos.x );
// Dragging on the corner of a cell to resize in both
// directions is not implemented yet...
@@ -6594,6 +6547,76 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
}
}
}
void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event)
{
const wxPoint pos = CalcUnscrolledPosition(event.GetPosition());
// coordinates of the cell under mouse
wxGridCellCoords coords = XYToCell(pos);
int cell_rows, cell_cols;
GetCellSize( coords.GetRow(), coords.GetCol(), &cell_rows, &cell_cols );
if ( (cell_rows < 0) || (cell_cols < 0) )
{
coords.SetRow(coords.GetRow() + cell_rows);
coords.SetCol(coords.GetCol() + cell_cols);
}
if ( event.Dragging() )
{
if ( event.LeftIsDown() )
DoGridDragEvent(event, coords);
else
event.Skip();
return;
}
m_isDragging = false;
m_startDragPos = wxDefaultPosition;
// VZ: if we do this, the mode is reset to WXGRID_CURSOR_SELECT_CELL
// immediately after it becomes WXGRID_CURSOR_RESIZE_ROW/COL under
// wxGTK
#if 0
if ( event.Entering() || event.Leaving() )
{
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
m_gridWin->SetCursor( *wxSTANDARD_CURSOR );
}
#endif // 0
// deal with various button presses
if ( event.IsButton() )
{
if ( coords != wxGridNoCellCoords )
{
DisableCellEditControl();
if ( event.LeftDown() )
DoGridCellLeftDown(event, coords, pos);
else if ( event.LeftDClick() )
DoGridCellLeftDClick(event, coords, pos);
else if ( event.RightDown() )
SendEvent(wxEVT_GRID_CELL_RIGHT_CLICK, coords, event);
else if ( event.RightDClick() )
SendEvent(wxEVT_GRID_CELL_RIGHT_DCLICK, coords, event);
}
// this one should be called even if we're not over any cell
if ( event.LeftUp() )
{
DoGridCellLeftUp(event, coords);
}
}
else if ( event.Moving() )
{
DoGridMouseMoveEvent(event, coords, pos);
}
else // unknown mouse event?
{
event.Skip();
}
}
@@ -6883,12 +6906,14 @@ wxGrid::DoAppendLines(bool (wxGridTableBase::*funcAppend)(size_t),
// ----- event handlers
//
// Generate a grid event based on a mouse event and
// return the result of ProcessEvent()
//
int wxGrid::SendEvent( const wxEventType type,
// Generate a grid event based on a mouse event and return:
// -1 if the event was vetoed
// +1 if the event was processed (but not vetoed)
// 0 if the event wasn't handled
int
wxGrid::SendEvent(const wxEventType type,
int row, int col,
wxMouseEvent& mouseEv )
wxMouseEvent& mouseEv)
{
bool claimed, vetoed;
@@ -6916,8 +6941,8 @@ int wxGrid::SendEvent( const wxEventType type,
wxGridRangeSelectEvent gridEvt( GetId(),
type,
this,
m_selectingTopLeft,
m_selectingBottomRight,
m_selectedBlockTopLeft,
m_selectedBlockBottomRight,
true,
mouseEv.ControlDown(),
mouseEv.ShiftDown(),
@@ -6977,11 +7002,9 @@ int wxGrid::SendEvent( const wxEventType type,
return claimed ? 1 : 0;
}
// Generate a grid event of specified type and return the result
// of ProcessEvent().
// Generate a grid event of specified type, return value same as above
//
int wxGrid::SendEvent( const wxEventType type,
int row, int col )
int wxGrid::SendEvent(const wxEventType type, int row, int col)
{
bool claimed, vetoed;
@@ -7224,8 +7247,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
case WXK_HOME:
if ( event.ControlDown() )
{
MakeCellVisible( 0, 0 );
SetCurrentCell( 0, 0 );
GoToCell(0, 0);
}
else
{
@@ -7236,8 +7258,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
case WXK_END:
if ( event.ControlDown() )
{
MakeCellVisible( m_numRows - 1, m_numCols - 1 );
SetCurrentCell( m_numRows - 1, m_numCols - 1 );
GoToCell(m_numRows - 1, m_numCols - 1);
}
else
{
@@ -7299,16 +7320,14 @@ void wxGrid::OnKeyUp( wxKeyEvent& event )
//
if ( event.GetKeyCode() == WXK_SHIFT )
{
if ( m_selectingTopLeft != wxGridNoCellCoords &&
m_selectingBottomRight != wxGridNoCellCoords )
if ( m_selectedBlockTopLeft != wxGridNoCellCoords &&
m_selectedBlockBottomRight != wxGridNoCellCoords )
{
if ( m_selection )
{
m_selection->SelectBlock(
m_selectingTopLeft.GetRow(),
m_selectingTopLeft.GetCol(),
m_selectingBottomRight.GetRow(),
m_selectingBottomRight.GetCol(),
m_selectedBlockTopLeft,
m_selectedBlockBottomRight,
event.ControlDown(),
true,
event.AltDown(),
@@ -7316,9 +7335,9 @@ void wxGrid::OnKeyUp( wxKeyEvent& event )
}
}
m_selectingTopLeft = wxGridNoCellCoords;
m_selectingBottomRight = wxGridNoCellCoords;
m_selectingKeyboard = wxGridNoCellCoords;
m_selectedBlockTopLeft = wxGridNoCellCoords;
m_selectedBlockBottomRight = wxGridNoCellCoords;
m_selectedBlockCorner = wxGridNoCellCoords;
}
}
@@ -7367,12 +7386,12 @@ void wxGrid::OnEraseBackground(wxEraseEvent&)
{
}
void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
bool wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
{
if ( SendEvent( wxEVT_GRID_SELECT_CELL, coords.GetRow(), coords.GetCol() ) )
if ( SendEvent(wxEVT_GRID_SELECT_CELL, coords) == -1 )
{
// the event has been intercepted - do nothing
return;
// the event has been vetoed - do nothing
return false;
}
#if !defined(__WXMAC__)
@@ -7417,35 +7436,62 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
DrawCellHighlight( dc, attr );
#endif
attr->DecRef();
return true;
}
void wxGrid::HighlightBlock(int topRow, int leftCol, int bottomRow, int rightCol)
void
wxGrid::UpdateBlockBeingSelected(int topRow, int leftCol,
int bottomRow, int rightCol)
{
wxGridCellCoords updateTopLeft, updateBottomRight;
if ( m_selection )
{
if ( m_selection->GetSelectionMode() == wxGrid::wxGridSelectRows )
switch ( m_selection->GetSelectionMode() )
{
default:
wxFAIL_MSG( "unknown selection mode" );
// fall through
case wxGridSelectCells:
// arbitrary blocks selection allowed so just use the cell
// coordinates as is
break;
case wxGridSelectRows:
// only full rows selection allowd, ensure that we do select
// full rows
leftCol = 0;
rightCol = GetNumberCols() - 1;
}
else if ( m_selection->GetSelectionMode() == wxGrid::wxGridSelectColumns )
{
break;
case wxGridSelectColumns:
// same as above but for columns
topRow = 0;
bottomRow = GetNumberRows() - 1;
break;
case wxGridSelectRowsOrColumns:
// in this mode we can select only full rows or full columns so
// it doesn't make sense to select blocks at all (and we can't
// extend the block because there is no preferred direction, we
// could only extend it to cover the entire grid but this is
// not useful)
return;
}
}
m_selectedBlockCorner = wxGridCellCoords(bottomRow, rightCol);
MakeCellVisible(m_selectedBlockCorner);
EnsureFirstLessThanSecond(topRow, bottomRow);
EnsureFirstLessThanSecond(leftCol, rightCol);
updateTopLeft = wxGridCellCoords( topRow, leftCol );
updateBottomRight = wxGridCellCoords( bottomRow, rightCol );
wxGridCellCoords updateTopLeft = wxGridCellCoords(topRow, leftCol),
updateBottomRight = wxGridCellCoords(bottomRow, rightCol);
// First the case that we selected a completely new area
if ( m_selectingTopLeft == wxGridNoCellCoords ||
m_selectingBottomRight == wxGridNoCellCoords )
if ( m_selectedBlockTopLeft == wxGridNoCellCoords ||
m_selectedBlockBottomRight == wxGridNoCellCoords )
{
wxRect rect;
rect = BlockToDeviceRect( wxGridCellCoords ( topRow, leftCol ),
@@ -7454,8 +7500,8 @@ void wxGrid::HighlightBlock(int topRow, int leftCol, int bottomRow, int rightCol
}
// Now handle changing an existing selection area.
else if ( m_selectingTopLeft != updateTopLeft ||
m_selectingBottomRight != updateBottomRight )
else if ( m_selectedBlockTopLeft != updateTopLeft ||
m_selectedBlockBottomRight != updateBottomRight )
{
// Compute two optimal update rectangles:
// Either one rectangle is a real subset of the
@@ -7469,10 +7515,10 @@ void wxGrid::HighlightBlock(int topRow, int leftCol, int bottomRow, int rightCol
int i;
// Store intermediate values
wxCoord oldLeft = m_selectingTopLeft.GetCol();
wxCoord oldTop = m_selectingTopLeft.GetRow();
wxCoord oldRight = m_selectingBottomRight.GetCol();
wxCoord oldBottom = m_selectingBottomRight.GetRow();
wxCoord oldLeft = m_selectedBlockTopLeft.GetCol();
wxCoord oldTop = m_selectedBlockTopLeft.GetRow();
wxCoord oldRight = m_selectedBlockBottomRight.GetCol();
wxCoord oldBottom = m_selectedBlockBottomRight.GetRow();
// Determine the outer/inner coordinates.
EnsureFirstLessThanSecond(oldLeft, leftCol);
@@ -7531,8 +7577,8 @@ void wxGrid::HighlightBlock(int topRow, int leftCol, int bottomRow, int rightCol
}
// change selection
m_selectingTopLeft = updateTopLeft;
m_selectingBottomRight = updateBottomRight;
m_selectedBlockTopLeft = updateTopLeft;
m_selectedBlockBottomRight = updateBottomRight;
}
//
@@ -8371,7 +8417,7 @@ void wxGrid::EnableCellEditControl( bool enable )
{
if ( enable )
{
if (SendEvent( wxEVT_GRID_EDITOR_SHOWN) <0)
if ( SendEvent(wxEVT_GRID_EDITOR_SHOWN) == -1 )
return;
// this should be checked by the caller!
@@ -8385,7 +8431,7 @@ void wxGrid::EnableCellEditControl( bool enable )
else
{
//FIXME:add veto support
SendEvent( wxEVT_GRID_EDITOR_HIDDEN );
SendEvent(wxEVT_GRID_EDITOR_HIDDEN);
HideCellEditControl();
SaveEditControlValue();
@@ -8624,9 +8670,7 @@ void wxGrid::SaveEditControlValue()
if (changed)
{
if ( SendEvent( wxEVT_GRID_CELL_CHANGE,
m_currentCellCoords.GetRow(),
m_currentCellCoords.GetCol() ) < 0 )
if ( SendEvent(wxEVT_GRID_CELL_CHANGE) == -1 )
{
// Event has been vetoed, set the data back.
SetCellValue(row, col, oldval);
@@ -8642,19 +8686,13 @@ void wxGrid::SaveEditControlValue()
// coordinates for mouse events etc.
//
void wxGrid::XYToCell( int x, int y, wxGridCellCoords& coords ) const
wxGridCellCoords wxGrid::XYToCell(int x, int y) const
{
int row = YToRow(y);
int col = XToCol(x);
if ( row == -1 || col == -1 )
{
coords = wxGridNoCellCoords;
}
else
{
coords.Set( row, col );
}
return row == -1 || col == -1 ? wxGridNoCellCoords
: wxGridCellCoords(row, col);
}
// compute row or column from some (unscrolled) coordinate value, using either
@@ -8957,28 +8995,28 @@ wxGrid::DoMoveCursor(bool expandSelection,
if ( expandSelection )
{
if ( m_selectingKeyboard == wxGridNoCellCoords )
m_selectingKeyboard = m_currentCellCoords;
wxGridCellCoords coords = m_selectedBlockCorner;
if ( coords == wxGridNoCellCoords )
coords = m_currentCellCoords;
if ( diroper.IsAtBoundary(m_selectingKeyboard) )
if ( diroper.IsAtBoundary(coords) )
return false;
diroper.Advance(m_selectingKeyboard);
diroper.Advance(coords);
MakeCellVisible(m_selectingKeyboard);
HighlightBlock(m_currentCellCoords, m_selectingKeyboard);
UpdateBlockBeingSelected(m_currentCellCoords, coords);
}
else
else // don't expand selection
{
ClearSelection();
if ( diroper.IsAtBoundary(m_currentCellCoords) )
return false;
ClearSelection();
wxGridCellCoords coords = m_currentCellCoords;
diroper.Advance(coords);
MakeCellVisible(coords);
SetCurrentCell(coords);
GoToCell(coords);
}
return true;
@@ -9025,8 +9063,7 @@ bool wxGrid::DoMoveCursorByPage(const wxGridDirectionOperations& diroper)
newRow = coords.GetRow();
}
MakeCellVisible(newRow, m_currentCellCoords.GetCol());
SetCurrentCell(newRow, m_currentCellCoords.GetCol());
GoToCell(newRow, m_currentCellCoords.GetCol());
return true;
}
@@ -9097,16 +9134,14 @@ wxGrid::DoMoveCursorByBlock(bool expandSelection,
}
}
MakeCellVisible(coords);
if ( expandSelection )
{
m_selectingKeyboard = coords;
HighlightBlock(m_currentCellCoords, m_selectingKeyboard);
UpdateBlockBeingSelected(m_currentCellCoords, coords);
}
else
{
ClearSelection();
SetCurrentCell(coords);
GoToCell(coords);
}
return true;
@@ -10718,17 +10753,17 @@ void wxGrid::DeselectCell( int row, int col )
bool wxGrid::IsSelection() const
{
return ( m_selection && (m_selection->IsSelection() ||
( m_selectingTopLeft != wxGridNoCellCoords &&
m_selectingBottomRight != wxGridNoCellCoords) ) );
( m_selectedBlockTopLeft != wxGridNoCellCoords &&
m_selectedBlockBottomRight != wxGridNoCellCoords) ) );
}
bool wxGrid::IsInSelection( int row, int col ) const
{
return ( m_selection && (m_selection->IsInSelection( row, col ) ||
( row >= m_selectingTopLeft.GetRow() &&
col >= m_selectingTopLeft.GetCol() &&
row <= m_selectingBottomRight.GetRow() &&
col <= m_selectingBottomRight.GetCol() )) );
( row >= m_selectedBlockTopLeft.GetRow() &&
col >= m_selectedBlockTopLeft.GetCol() &&
row <= m_selectedBlockBottomRight.GetRow() &&
col <= m_selectedBlockBottomRight.GetCol() )) );
}
wxGridCellCoordsArray wxGrid::GetSelectedCells() const
@@ -10788,13 +10823,18 @@ wxArrayInt wxGrid::GetSelectedCols() const
void wxGrid::ClearSelection()
{
wxRect r1 = BlockToDeviceRect( m_selectingTopLeft, m_selectingBottomRight);
wxRect r2 = BlockToDeviceRect( m_currentCellCoords, m_selectingKeyboard );
m_selectingTopLeft =
m_selectingBottomRight =
m_selectingKeyboard = wxGridNoCellCoords;
wxRect r1 = BlockToDeviceRect(m_selectedBlockTopLeft,
m_selectedBlockBottomRight);
wxRect r2 = BlockToDeviceRect(m_currentCellCoords,
m_selectedBlockCorner);
m_selectedBlockTopLeft =
m_selectedBlockBottomRight =
m_selectedBlockCorner = wxGridNoCellCoords;
Refresh( false, &r1 );
Refresh( false, &r2 );
if ( m_selection )
m_selection->ClearSelection();
}

View File

@@ -385,15 +385,30 @@ void wxGridSelection::SelectBlock( int topRow, int leftCol,
bool sendEvent )
{
// Fix the coordinates of the block if needed.
if ( m_selectionMode == wxGrid::wxGridSelectRows )
switch ( m_selectionMode )
{
default:
wxFAIL_MSG( "unknown selection mode" );
// fall through
case wxGrid::wxGridSelectCells:
// nothing to do -- in this mode arbitrary blocks can be selected
break;
case wxGrid::wxGridSelectRows:
leftCol = 0;
rightCol = m_grid->GetNumberCols() - 1;
}
else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
{
break;
case wxGrid::wxGridSelectColumns:
topRow = 0;
bottomRow = m_grid->GetNumberRows() - 1;
break;
case wxGrid::wxGridSelectRowsOrColumns:
// block selection doesn't make sense for this mode, we could only
// select the entire grid but this wouldn't be useful
return;
}
if ( topRow > bottomRow )