X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ccdee36f75f1e988409a3455d1bfc3dedb957c9b..8a16d7370e3cdc7d583a6f14ab11b3a1d27b73df:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index f1decc96ce..c216e7291b 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -2,14 +2,14 @@ // Name: src/generic/grid.cpp // Purpose: wxGrid and related classes // Author: Michael Bedward (based on code by Julian Smart, Robin Dunn) -// Modified by: Robin Dunn, Vadim Zeitlin +// Modified by: Robin Dunn, Vadim Zeitlin, Santiago Palacios // Created: 1/08/1999 // RCS-ID: $Id$ // Copyright: (c) Michael Bedward (mbedward@ozemail.com.au) // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -// For compilers that support precompilatixon, includes "wx/wx.h". +// For compilers that support precompilation, includes "wx/wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ @@ -29,6 +29,7 @@ #include "wx/valtext.h" #include "wx/intl.h" #include "wx/math.h" + #include "wx/listbox.h" #endif #include "wx/textfile.h" @@ -104,6 +105,7 @@ DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_LEFT_DCLICK) DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_RIGHT_DCLICK) DEFINE_EVENT_TYPE(wxEVT_GRID_ROW_SIZE) DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SIZE) +DEFINE_EVENT_TYPE(wxEVT_GRID_COL_MOVE) DEFINE_EVENT_TYPE(wxEVT_GRID_RANGE_SELECT) DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGE) DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL) @@ -148,7 +150,7 @@ public: private: wxGrid *m_owner; - void OnPaint( wxPaintEvent &event ); + void OnPaint( wxPaintEvent& event ); void OnMouseEvent( wxMouseEvent& event ); void OnMouseWheel( wxMouseEvent& event ); void OnKeyDown( wxKeyEvent& event ); @@ -188,16 +190,16 @@ class WXDLLIMPEXP_ADV wxGridWindow : public wxWindow public: wxGridWindow() { - m_owner = (wxGrid *)NULL; - m_rowLabelWin = (wxGridRowLabelWindow *)NULL; - m_colLabelWin = (wxGridColLabelWindow *)NULL; + m_owner = NULL; + m_rowLabelWin = NULL; + m_colLabelWin = NULL; } wxGridWindow( wxGrid *parent, wxGridRowLabelWindow *rowLblWin, wxGridColLabelWindow *colLblWin, wxWindowID id, const wxPoint &pos, const wxSize &size ); - ~wxGridWindow() {} + virtual ~wxGridWindow() {} void ScrollWindow( int dx, int dy, const wxRect *rect ); @@ -262,7 +264,6 @@ BEGIN_EVENT_TABLE( wxGridCellEditorEvtHandler, wxEvtHandler ) END_EVENT_TABLE() - // ---------------------------------------------------------------------------- // the internal data representation used by wxGridCellAttrProvider // ---------------------------------------------------------------------------- @@ -370,6 +371,7 @@ private: wxGridDataTypeInfoArray m_typeinfo; }; + // ---------------------------------------------------------------------------- // conditional compilation // ---------------------------------------------------------------------------- @@ -478,7 +480,7 @@ void wxGridCellEditor::Destroy() { if (m_control) { - m_control->PopEventHandler(true /* delete it*/); + m_control->PopEventHandler( true /* delete it*/ ); m_control->Destroy(); m_control = NULL; @@ -507,6 +509,7 @@ void wxGridCellEditor::Show(bool show, wxGridCellAttr *attr) m_fontOld = m_control->GetFont(); m_control->SetFont(attr->GetFont()); #endif + // can't do anything more in the base class version, the other // attributes may only be used by the derived classes } @@ -569,6 +572,12 @@ bool wxGridCellEditor::IsAcceptedKey(wxKeyEvent& event) int key = 0; bool keyOk = true; +#ifdef __WXGTK20__ + // If it's a F-Key or other special key then it shouldn't start the + // editor. + if (event.GetKeyCode() >= WXK_START) + return false; +#endif #if wxUSE_UNICODE // if the unicode key code is not really a unicode character (it may // be a function key or etc., the platforms appear to always give us a @@ -615,7 +624,7 @@ void wxGridCellTextEditor::Create(wxWindow* parent, m_control = new wxTextCtrl(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize #if defined(__WXMSW__) - , wxTE_PROCESS_TAB | wxTE_AUTO_SCROLL + , wxTE_PROCESS_TAB | wxTE_AUTO_SCROLL | wxNO_BORDER #endif ); @@ -631,8 +640,8 @@ void wxGridCellTextEditor::Create(wxWindow* parent, void wxGridCellTextEditor::PaintBackground(const wxRect& WXUNUSED(rectCell), wxGridCellAttr * WXUNUSED(attr)) { - // as we fill the entire client area, don't do anything here to minimize - // flicker + // as we fill the entire client area, + // don't do anything here to minimize flicker } void wxGridCellTextEditor::SetSize(const wxRect& rectOrig) @@ -651,27 +660,33 @@ void wxGridCellTextEditor::SetSize(const wxRect& rectOrig) rect.width -= 1; rect.height -= 1; } -#else // !GTK - int extra_x = ( rect.x > 2 ) ? 2 : 1; +#elif defined(__WXMSW__) + if ( rect.x == 0 ) + rect.x += 2; + else + rect.x += 3; -// MB: treat MSW separately here otherwise the caret doesn't show -// when the editor is in the first row. -#if defined(__WXMSW__) - int extra_y = 2; + if ( rect.y == 0 ) + rect.y += 2; + else + rect.y += 3; + + rect.width -= 2; + rect.height -= 2; #else + int extra_x = ( rect.x > 2 ) ? 2 : 1; int extra_y = ( rect.y > 2 ) ? 2 : 1; -#endif -#if defined(__WXMOTIF__) - extra_x *= 2; - extra_y *= 2; -#endif + #if defined(__WXMOTIF__) + extra_x *= 2; + extra_y *= 2; + #endif rect.SetLeft( wxMax(0, rect.x - extra_x) ); rect.SetTop( wxMax(0, rect.y - extra_y) ); rect.SetRight( rect.GetRight() + 2 * extra_x ); rect.SetBottom( rect.GetBottom() + 2 * extra_y ); -#endif // GTK/!GTK +#endif wxGridCellEditor::SetSize(rect); } @@ -706,6 +721,7 @@ bool wxGridCellTextEditor::EndEdit(int row, int col, wxGrid* grid) grid->GetTable()->SetValue(row, col, value); m_startValue = wxEmptyString; + // No point in setting the text of the hidden control //Text()->SetValue(m_startValue); @@ -798,13 +814,13 @@ void wxGridCellTextEditor::SetParameters(const wxString& params) else { long tmp; - if ( !params.ToLong(&tmp) ) + if ( params.ToLong(&tmp) ) { - wxLogDebug(_T("Invalid wxGridCellTextEditor parameter string '%s' ignored"), params.c_str()); + m_maxChars = (size_t)tmp; } else { - m_maxChars = (size_t)tmp; + wxLogDebug( _T("Invalid wxGridCellTextEditor parameter string '%s' ignored"), params.c_str() ); } } } @@ -848,7 +864,7 @@ void wxGridCellNumberEditor::Create(wxWindow* parent, #if wxUSE_VALIDATORS Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); -#endif // wxUSE_VALIDATORS +#endif } } @@ -1041,7 +1057,7 @@ void wxGridCellFloatEditor::Create(wxWindow* parent, #if wxUSE_VALIDATORS Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); -#endif // wxUSE_VALIDATORS +#endif } void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid) @@ -1176,27 +1192,30 @@ bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event) { if ( wxGridCellEditor::IsAcceptedKey(event) ) { - int keycode = event.GetKeyCode(); - printf("%d\n", keycode); - // accept digits, 'e' as in '1e+6', also '-', '+', and '.' - char tmpbuf[2]; - tmpbuf[0] = (char) keycode; - tmpbuf[1] = '\0'; - wxString strbuf(tmpbuf, *wxConvCurrent); + const int keycode = event.GetKeyCode(); + if ( isascii(keycode) ) + { + char tmpbuf[2]; + tmpbuf[0] = (char) keycode; + tmpbuf[1] = '\0'; + wxString strbuf(tmpbuf, *wxConvCurrent); #if wxUSE_INTL - bool is_decimal_point = - ( strbuf == wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, - wxLOCALE_CAT_NUMBER) ); + const wxString decimalPoint = + wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER); #else - bool is_decimal_point = ( strbuf == _T(".") ); + const wxString decimalPoint(_T('.')); #endif - if ( (keycode < 128) && - (wxIsdigit(keycode) || tolower(keycode) == 'e' || - is_decimal_point || keycode == '+' || keycode == '-') ) - { - return true; + // accept digits, 'e' as in '1e+6', also '-', '+', and '.' + if ( wxIsdigit(keycode) || + tolower(keycode) == 'e' || + keycode == decimalPoint || + keycode == '+' || + keycode == '-' ) + { + return true; + } } } @@ -1307,7 +1326,7 @@ void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr) void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid) { wxASSERT_MSG(m_control, - wxT("The wxGridCellEditor must be Created first!")); + wxT("The wxGridCellEditor must be created first!")); if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL)) { @@ -1327,7 +1346,7 @@ bool wxGridCellBoolEditor::EndEdit(int row, int col, wxGrid* grid) { wxASSERT_MSG(m_control, - wxT("The wxGridCellEditor must be Created first!")); + wxT("The wxGridCellEditor must be created first!")); bool changed = false; bool value = CBox()->GetValue(); @@ -1348,7 +1367,7 @@ bool wxGridCellBoolEditor::EndEdit(int row, int col, void wxGridCellBoolEditor::Reset() { wxASSERT_MSG(m_control, - wxT("The wxGridCellEditor must be Created first!")); + wxT("The wxGridCellEditor must be created first!")); CBox()->SetValue(m_startValue); } @@ -1458,15 +1477,15 @@ void wxGridCellChoiceEditor::PaintBackground(const wxRect& rectCell, // flicker // TODO: It doesn't actually fill the client area since the height of a - // combo always defaults to the standard... Until someone has time to - // figure out the right rectangle to paint, just do it the normal way... + // combo always defaults to the standard. Until someone has time to + // figure out the right rectangle to paint, just do it the normal way. wxGridCellEditor::PaintBackground(rectCell, attr); } void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid) { wxASSERT_MSG(m_control, - wxT("The wxGridCellEditor must be Created first!")); + wxT("The wxGridCellEditor must be created first!")); wxGridCellEditorEvtHandler* evtHandler = NULL; if (m_control) @@ -1638,6 +1657,7 @@ void wxGridCellEditorEvtHandler::OnChar(wxKeyEvent& event) event.Skip(); break; } + case WXK_END: { if ( wholeCellVisible ) @@ -1691,6 +1711,7 @@ void wxGridCellEditorEvtHandler::OnChar(wxKeyEvent& event) default: event.Skip(); + break; } } @@ -1762,21 +1783,21 @@ void wxGridCellStringRenderer::SetTextColoursAndFont(const wxGrid& grid, // different coloured text when the grid is disabled if ( grid.IsEnabled() ) { - if ( isSelected ) - { - dc.SetTextBackground( grid.GetSelectionBackground() ); - dc.SetTextForeground( grid.GetSelectionForeground() ); - } - else - { - dc.SetTextBackground( attr.GetBackgroundColour() ); - dc.SetTextForeground( attr.GetTextColour() ); - } + if ( isSelected ) + { + dc.SetTextBackground( grid.GetSelectionBackground() ); + dc.SetTextForeground( grid.GetSelectionForeground() ); + } + else + { + dc.SetTextBackground( attr.GetBackgroundColour() ); + dc.SetTextForeground( attr.GetTextColour() ); + } } else { - dc.SetTextBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); - dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT)); + dc.SetTextBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); + dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT)); } dc.SetFont( attr.GetFont() ); @@ -1852,7 +1873,9 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid, } if (is_empty) + { rect.width += grid.GetColSize(i); + } else { i--; @@ -1874,10 +1897,10 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid, wxRect clip = rect; clip.x += rectCell.width; // draw each overflow cell individually - int col_end = col+cell_cols + overflowCols; + int col_end = col + cell_cols + overflowCols; if (col_end >= grid.GetNumberCols()) col_end = grid.GetNumberCols() - 1; - for (int i = col+cell_cols; i <= col_end; i++) + for (int i = col + cell_cols; i <= col_end; i++) { clip.width = grid.GetColSize(i) - 1; dc.DestroyClippingRegion(); @@ -2158,7 +2181,7 @@ void wxGridCellBoolRenderer::Draw(wxGrid& grid, // draw a border around checkmark int vAlign, hAlign; - attr.GetAlignment(& hAlign, &vAlign); + attr.GetAlignment(&hAlign, &vAlign); wxRect rectBorder; if (hAlign == wxALIGN_CENTRE) @@ -2185,7 +2208,9 @@ void wxGridCellBoolRenderer::Draw(wxGrid& grid, bool value; if ( grid.GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) ) + { value = grid.GetTable()->GetValueAsBool(row, col); + } else { wxString cellval( grid.GetTable()->GetValue(row, col) ); @@ -2391,7 +2416,9 @@ void wxGridCellAttr::GetAlignment(int *hAlign, int *vAlign) const *vAlign = m_vAlign; } else if (m_defGridAttr && m_defGridAttr != this) + { m_defGridAttr->GetAlignment(hAlign, vAlign); + } else { wxFAIL_MSG(wxT("Missing default cell attribute")); @@ -2411,11 +2438,11 @@ void wxGridCellAttr::GetSize( int *num_rows, int *num_cols ) const // used, otherwise the default editor or renderer is fetched from the grid and // used. It should be the default for the data type of the cell. If it is // NULL (because the table has a type that the grid does not have in its -// registry,) then the grid's default editor or renderer is used. +// registry), then the grid's default editor or renderer is used. wxGridCellRenderer* wxGridCellAttr::GetRenderer(wxGrid* grid, int row, int col) const { - wxGridCellRenderer *renderer; + wxGridCellRenderer *renderer = NULL; if ( m_renderer && this != m_defGridAttr ) { @@ -2431,14 +2458,10 @@ wxGridCellRenderer* wxGridCellAttr::GetRenderer(wxGrid* grid, int row, int col) // GetDefaultRendererForCell() will do IncRef() for us renderer = grid->GetDefaultRendererForCell(row, col); } - else - { - renderer = NULL; - } - if ( !renderer ) + if ( renderer == NULL ) { - if (m_defGridAttr && this != m_defGridAttr ) + if ( (m_defGridAttr != NULL) && (m_defGridAttr != this) ) { // if we still don't have one then use the grid default // (no need for IncRef() here neither) @@ -2463,7 +2486,7 @@ wxGridCellRenderer* wxGridCellAttr::GetRenderer(wxGrid* grid, int row, int col) // same as above, except for s/renderer/editor/g wxGridCellEditor* wxGridCellAttr::GetEditor(wxGrid* grid, int row, int col) const { - wxGridCellEditor *editor; + wxGridCellEditor *editor = NULL; if ( m_editor && this != m_defGridAttr ) { @@ -2479,14 +2502,10 @@ wxGridCellEditor* wxGridCellAttr::GetEditor(wxGrid* grid, int row, int col) cons // GetDefaultEditorForCell() will do IncRef() for us editor = grid->GetDefaultEditorForCell(row, col); } - else - { - editor = NULL; - } - if ( !editor ) + if ( editor == NULL ) { - if ( m_defGridAttr && this != m_defGridAttr ) + if ( (m_defGridAttr != NULL) && (m_defGridAttr != this) ) { // if we still don't have one then use the grid default // (no need for IncRef() here neither) @@ -3204,7 +3223,7 @@ wxString wxGridTableBase::GetColLabelValue( int col ) // reverse the string... wxString s2; - for ( i = 0; i < n; i++ ) + for ( i = 0; i < n; i++ ) { s2 += s[n - i - 1]; } @@ -3373,9 +3392,9 @@ void wxGridStringTable::Clear() { numCols = m_data[0].GetCount(); - for ( row = 0; row < numRows; row++ ) + for ( row = 0; row < numRows; row++ ) { - for ( col = 0; col < numCols; col++ ) + for ( col = 0; col < numCols; col++ ) { m_data[row][col] = wxEmptyString; } @@ -3498,9 +3517,18 @@ bool wxGridStringTable::InsertCols( size_t pos, size_t numCols ) return AppendCols( numCols ); } - for ( row = 0; row < curNumRows; row++ ) + if ( !m_colLabels.IsEmpty() ) { - for ( col = pos; col < pos + numCols; col++ ) + m_colLabels.Insert( wxEmptyString, pos, numCols ); + + size_t i; + for ( i = pos; i < pos + numCols; i++ ) + m_colLabels[i] = wxGridTableBase::GetColLabelValue( i ); + } + + for ( row = 0; row < curNumRows; row++ ) + { + for ( col = pos; col < pos + numCols; col++ ) { m_data[row].Insert( wxEmptyString, col ); } @@ -3535,7 +3563,7 @@ bool wxGridStringTable::AppendCols( size_t numCols ) } #endif - for ( row = 0; row < curNumRows; row++ ) + for ( row = 0; row < curNumRows; row++ ) { m_data[row].Add( wxEmptyString, numCols ); } @@ -3572,12 +3600,23 @@ bool wxGridStringTable::DeleteCols( size_t pos, size_t numCols ) return false; } - if ( numCols > curNumCols - pos ) + int colID; + if ( GetView() ) + colID = GetView()->GetColAt( pos ); + else + colID = pos; + + if ( numCols > curNumCols - colID ) + { + numCols = curNumCols - colID; + } + + if ( !m_colLabels.IsEmpty() ) { - numCols = curNumCols - pos; + m_colLabels.RemoveAt( colID, numCols ); } - for ( row = 0; row < curNumRows; row++ ) + for ( row = 0; row < curNumRows; row++ ) { if ( numCols >= curNumCols ) { @@ -3585,7 +3624,7 @@ bool wxGridStringTable::DeleteCols( size_t pos, size_t numCols ) } else { - m_data[row].RemoveAt( pos, numCols ); + m_data[row].RemoveAt( colID, numCols ); } } @@ -3637,7 +3676,7 @@ void wxGridStringTable::SetRowLabelValue( int row, const wxString& value ) int n = m_rowLabels.GetCount(); int i; - for ( i = n; i <= row; i++ ) + for ( i = n; i <= row; i++ ) { m_rowLabels.Add( wxGridTableBase::GetRowLabelValue(i) ); } @@ -3653,7 +3692,7 @@ void wxGridStringTable::SetColLabelValue( int col, const wxString& value ) int n = m_colLabels.GetCount(); int i; - for ( i = n; i <= col; i++ ) + for ( i = n; i <= col; i++ ) { m_colLabels.Add( wxGridTableBase::GetColLabelValue(i) ); } @@ -3670,17 +3709,17 @@ IMPLEMENT_DYNAMIC_CLASS( wxGridRowLabelWindow, wxWindow ) BEGIN_EVENT_TABLE( wxGridRowLabelWindow, wxWindow ) EVT_PAINT( wxGridRowLabelWindow::OnPaint ) - EVT_MOUSEWHEEL( wxGridRowLabelWindow::OnMouseWheel) + EVT_MOUSEWHEEL( wxGridRowLabelWindow::OnMouseWheel ) EVT_MOUSE_EVENTS( wxGridRowLabelWindow::OnMouseEvent ) EVT_KEY_DOWN( wxGridRowLabelWindow::OnKeyDown ) EVT_KEY_UP( wxGridRowLabelWindow::OnKeyUp ) - EVT_CHAR ( wxGridRowLabelWindow::OnChar ) + EVT_CHAR( wxGridRowLabelWindow::OnChar ) END_EVENT_TABLE() wxGridRowLabelWindow::wxGridRowLabelWindow( wxGrid *parent, wxWindowID id, const wxPoint &pos, const wxSize &size ) - : wxWindow( parent, id, pos, size, wxWANTS_CHARS|wxBORDER_NONE|wxFULL_REPAINT_ON_RESIZE ) + : wxWindow( parent, id, pos, size, wxWANTS_CHARS | wxBORDER_NONE | wxFULL_REPAINT_ON_RESIZE ) { m_owner = parent; } @@ -3697,10 +3736,11 @@ void wxGridRowLabelWindow::OnPaint( wxPaintEvent& WXUNUSED(event) ) int x, y; m_owner->CalcUnscrolledPosition( 0, 0, &x, &y ); - dc.SetDeviceOrigin( 0, -y ); + wxPoint pt = dc.GetDeviceOrigin(); + dc.SetDeviceOrigin( pt.x, pt.y-y ); wxArrayInt rows = m_owner->CalcRowLabelsExposed( GetUpdateRegion() ); - m_owner->DrawRowLabels( dc , rows ); + m_owner->DrawRowLabels( dc, rows ); } void wxGridRowLabelWindow::OnMouseEvent( wxMouseEvent& event ) @@ -3710,7 +3750,7 @@ void wxGridRowLabelWindow::OnMouseEvent( wxMouseEvent& event ) void wxGridRowLabelWindow::OnMouseWheel( wxMouseEvent& event ) { - m_owner->GetEventHandler()->ProcessEvent(event); + m_owner->GetEventHandler()->ProcessEvent( event ); } // This seems to be required for wxMotif otherwise the mouse @@ -3740,17 +3780,17 @@ IMPLEMENT_DYNAMIC_CLASS( wxGridColLabelWindow, wxWindow ) BEGIN_EVENT_TABLE( wxGridColLabelWindow, wxWindow ) EVT_PAINT( wxGridColLabelWindow::OnPaint ) - EVT_MOUSEWHEEL( wxGridColLabelWindow::OnMouseWheel) + EVT_MOUSEWHEEL( wxGridColLabelWindow::OnMouseWheel ) EVT_MOUSE_EVENTS( wxGridColLabelWindow::OnMouseEvent ) EVT_KEY_DOWN( wxGridColLabelWindow::OnKeyDown ) EVT_KEY_UP( wxGridColLabelWindow::OnKeyUp ) - EVT_CHAR ( wxGridColLabelWindow::OnChar ) + EVT_CHAR( wxGridColLabelWindow::OnChar ) END_EVENT_TABLE() wxGridColLabelWindow::wxGridColLabelWindow( wxGrid *parent, wxWindowID id, const wxPoint &pos, const wxSize &size ) - : wxWindow( parent, id, pos, size, wxWANTS_CHARS|wxBORDER_NONE|wxFULL_REPAINT_ON_RESIZE ) + : wxWindow( parent, id, pos, size, wxWANTS_CHARS | wxBORDER_NONE | wxFULL_REPAINT_ON_RESIZE ) { m_owner = parent; } @@ -3767,10 +3807,14 @@ void wxGridColLabelWindow::OnPaint( wxPaintEvent& WXUNUSED(event) ) int x, y; m_owner->CalcUnscrolledPosition( 0, 0, &x, &y ); - dc.SetDeviceOrigin( -x, 0 ); + wxPoint pt = dc.GetDeviceOrigin(); + if (GetLayoutDirection() == wxLayout_RightToLeft) + dc.SetDeviceOrigin( pt.x+x, pt.y ); + else + dc.SetDeviceOrigin( pt.x-x, pt.y ); wxArrayInt cols = m_owner->CalcColLabelsExposed( GetUpdateRegion() ); - m_owner->DrawColLabels( dc , cols ); + m_owner->DrawColLabels( dc, cols ); } void wxGridColLabelWindow::OnMouseEvent( wxMouseEvent& event ) @@ -3780,7 +3824,7 @@ void wxGridColLabelWindow::OnMouseEvent( wxMouseEvent& event ) void wxGridColLabelWindow::OnMouseWheel( wxMouseEvent& event ) { - m_owner->GetEventHandler()->ProcessEvent(event); + m_owner->GetEventHandler()->ProcessEvent( event ); } // This seems to be required for wxMotif otherwise the mouse @@ -3809,18 +3853,18 @@ void wxGridColLabelWindow::OnChar( wxKeyEvent& event ) IMPLEMENT_DYNAMIC_CLASS( wxGridCornerLabelWindow, wxWindow ) BEGIN_EVENT_TABLE( wxGridCornerLabelWindow, wxWindow ) - EVT_MOUSEWHEEL( wxGridCornerLabelWindow::OnMouseWheel) + EVT_MOUSEWHEEL( wxGridCornerLabelWindow::OnMouseWheel ) EVT_MOUSE_EVENTS( wxGridCornerLabelWindow::OnMouseEvent ) - EVT_PAINT( wxGridCornerLabelWindow::OnPaint) + EVT_PAINT( wxGridCornerLabelWindow::OnPaint ) EVT_KEY_DOWN( wxGridCornerLabelWindow::OnKeyDown ) EVT_KEY_UP( wxGridCornerLabelWindow::OnKeyUp ) - EVT_CHAR ( wxGridCornerLabelWindow::OnChar ) + EVT_CHAR( wxGridCornerLabelWindow::OnChar ) END_EVENT_TABLE() wxGridCornerLabelWindow::wxGridCornerLabelWindow( wxGrid *parent, wxWindowID id, const wxPoint &pos, const wxSize &size ) - : wxWindow( parent, id, pos, size, wxWANTS_CHARS|wxBORDER_NONE|wxFULL_REPAINT_ON_RESIZE ) + : wxWindow( parent, id, pos, size, wxWANTS_CHARS | wxBORDER_NONE | wxFULL_REPAINT_ON_RESIZE ) { m_owner = parent; } @@ -3843,7 +3887,7 @@ void wxGridCornerLabelWindow::OnPaint( wxPaintEvent& WXUNUSED(event) ) wxRendererNative::Get().DrawHeaderButton( this, dc, rect, 0 ); #else // !__WXGTK__ - dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW), 1, wxSOLID) ); + dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID) ); dc.DrawLine( client_width - 1, client_height - 1, client_width - 1, 0 ); dc.DrawLine( client_width - 1, client_height - 1, 0, client_height - 1 ); dc.DrawLine( 0, 0, client_width, 0 ); @@ -3892,11 +3936,11 @@ IMPLEMENT_DYNAMIC_CLASS( wxGridWindow, wxWindow ) BEGIN_EVENT_TABLE( wxGridWindow, wxWindow ) EVT_PAINT( wxGridWindow::OnPaint ) - EVT_MOUSEWHEEL( wxGridWindow::OnMouseWheel) + EVT_MOUSEWHEEL( wxGridWindow::OnMouseWheel ) EVT_MOUSE_EVENTS( wxGridWindow::OnMouseEvent ) EVT_KEY_DOWN( wxGridWindow::OnKeyDown ) EVT_KEY_UP( wxGridWindow::OnKeyUp ) - EVT_CHAR ( wxGridWindow::OnChar ) + EVT_CHAR( wxGridWindow::OnChar ) EVT_SET_FOCUS( wxGridWindow::OnFocus ) EVT_KILL_FOCUS( wxGridWindow::OnFocus ) EVT_ERASE_BACKGROUND( wxGridWindow::OnEraseBackground ) @@ -3951,7 +3995,7 @@ void wxGridWindow::OnMouseEvent( wxMouseEvent& event ) void wxGridWindow::OnMouseWheel( wxMouseEvent& event ) { - m_owner->GetEventHandler()->ProcessEvent(event); + m_owner->GetEventHandler()->ProcessEvent( event ); } // This seems to be required for wxMotif/wxGTK otherwise the mouse @@ -3998,9 +4042,7 @@ static int CoordToRowOrCol(int coord, int defaultDist, int minDist, const wxArrayInt& BorderArray, int nMax, bool clipToMinMax); -#define internalXToCol(x) CoordToRowOrCol(x, m_defaultColWidth, \ - m_minAcceptableColWidth, \ - m_colRights, m_numCols, true) +#define internalXToCol(x) XToCol(x, true) #define internalYToRow(y) CoordToRowOrCol(y, m_defaultRowHeight, \ m_minAcceptableRowHeight, \ m_rowBottoms, m_numRows, true) @@ -4097,7 +4139,7 @@ bool wxGrid::Create(wxWindow *parent, wxWindowID id, long style, const wxString& name) { if (!wxScrolledWindow::Create(parent, id, pos, size, - style | wxWANTS_CHARS , name)) + style | wxWANTS_CHARS, name)) return false; m_colMinWidths = wxLongToLongHashMap(GRID_HASH_SIZE); @@ -4139,16 +4181,17 @@ wxGrid::~wxGrid() // be removed as well as the #else cases below. #define _USE_VISATTR 0 -#if _USE_VISATTR -#include "wx/listbox.h" -#endif - void wxGrid::Create() { - m_created = false; // set to true by CreateGrid + // set to true by CreateGrid + m_created = false; + + // create the type registry + m_typeRegistry = new wxGridTypeRegistry; + m_selection = NULL; - m_table = (wxGridTableBase *) NULL; - m_ownTable = false; + m_table = (wxGridTableBase *) NULL; + m_ownTable = false; m_cellEditCtrlEnabled = false; @@ -4183,16 +4226,7 @@ void wxGrid::Create() m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH; m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT; - // create the type registry - m_typeRegistry = new wxGridTypeRegistry; - m_selection = NULL; - // subwindow components that make up the wxGrid - m_cornerLabelWin = new wxGridCornerLabelWindow( this, - wxID_ANY, - wxDefaultPosition, - wxDefaultSize ); - m_rowLabelWin = new wxGridRowLabelWindow( this, wxID_ANY, wxDefaultPosition, @@ -4203,6 +4237,11 @@ void wxGrid::Create() wxDefaultPosition, wxDefaultSize ); + m_cornerLabelWin = new wxGridCornerLabelWindow( this, + wxID_ANY, + wxDefaultPosition, + wxDefaultSize ); + m_gridWin = new wxGridWindow( this, m_rowLabelWin, m_colLabelWin, @@ -4285,15 +4324,15 @@ bool wxGrid::SetTable( wxGridTableBase *table, bool takeOwnership, if (m_ownTable) { - wxGridTableBase *t=m_table; - m_table=0; + wxGridTableBase *t = m_table; + m_table = NULL; delete t; } delete m_selection; - m_table = 0; - m_selection = 0; + m_table = NULL; + m_selection = NULL; m_numRows = 0; m_numCols = 0; } @@ -4327,10 +4366,10 @@ void wxGrid::Init() } else { - m_labelBackgroundColour = wxColour( wxT("WHITE") ); + m_labelBackgroundColour = *wxWHITE; } - m_labelTextColour = wxColour( wxT("BLACK") ); + m_labelTextColour = *wxBLACK; // init attr cache m_attrCache.row = -1; @@ -4367,6 +4406,8 @@ void wxGrid::Init() m_cellHighlightPenWidth = 2; m_cellHighlightROPenWidth = 1; + m_canDragColMove = false; + m_cursorMode = WXGRID_CURSOR_SELECT_CELL; m_winCapture = (wxWindow *)NULL; m_canDragRowSize = true; @@ -4385,8 +4426,8 @@ void wxGrid::Init() m_currentCellCoords = wxGridNoCellCoords; - m_selectingTopLeft = wxGridNoCellCoords; - m_selectingBottomRight = wxGridNoCellCoords; + ClearSelection(); + m_selectionBackground = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); m_selectionForeground = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); @@ -4424,7 +4465,7 @@ void wxGrid::InitRowHeights() m_rowHeights.Add( m_defaultRowHeight, m_numRows ); - for ( int i = 0; i < m_numRows; i++ ) + for ( int i = 0; i < m_numRows; i++ ) { rowBottom += m_defaultRowHeight; m_rowBottoms.Add( rowBottom ); @@ -4442,9 +4483,9 @@ void wxGrid::InitColWidths() m_colWidths.Add( m_defaultColWidth, m_numCols ); - for ( int i = 0; i < m_numCols; i++ ) + for ( int i = 0; i < m_numCols; i++ ) { - colRight += m_defaultColWidth; + colRight = ( GetColPos( i ) + 1 ) * m_defaultColWidth; m_colRights.Add( colRight ); } } @@ -4456,13 +4497,13 @@ int wxGrid::GetColWidth(int col) const int wxGrid::GetColLeft(int col) const { - return m_colRights.IsEmpty() ? col * m_defaultColWidth + return m_colRights.IsEmpty() ? GetColPos( col ) * m_defaultColWidth : m_colRights[col] - m_colWidths[col]; } int wxGrid::GetColRight(int col) const { - return m_colRights.IsEmpty() ? (col + 1) * m_defaultColWidth + return m_colRights.IsEmpty() ? (GetColPos( col ) + 1) * m_defaultColWidth : m_colRights[col]; } @@ -4494,30 +4535,30 @@ void wxGrid::CalcDimensions() ch -= m_colLabelHeight; // grid total size - int w = m_numCols > 0 ? GetColRight(m_numCols - 1) + m_extraWidth + 1 : 0; + int w = m_numCols > 0 ? GetColRight(GetColAt( m_numCols - 1 )) + m_extraWidth + 1 : 0; int h = m_numRows > 0 ? GetRowBottom(m_numRows - 1) + m_extraHeight + 1 : 0; // take into account editor if shown if ( IsCellEditControlShown() ) { - int w2, h2; - int r = m_currentCellCoords.GetRow(); - int c = m_currentCellCoords.GetCol(); - int x = GetColLeft(c); - int y = GetRowTop(r); - - // how big is the editor - wxGridCellAttr* attr = GetCellAttr(r, c); - wxGridCellEditor* editor = attr->GetEditor(this, r, c); - editor->GetControl()->GetSize(&w2, &h2); - w2 += x; - h2 += y; - if ( w2 > w ) - w = w2; - if ( h2 > h ) - h = h2; - editor->DecRef(); - attr->DecRef(); + int w2, h2; + int r = m_currentCellCoords.GetRow(); + int c = m_currentCellCoords.GetCol(); + int x = GetColLeft(c); + int y = GetRowTop(r); + + // how big is the editor + wxGridCellAttr* attr = GetCellAttr(r, c); + wxGridCellEditor* editor = attr->GetEditor(this, r, c); + editor->GetControl()->GetSize(&w2, &h2); + w2 += x; + h2 += y; + if ( w2 > w ) + w = w2; + if ( h2 > h ) + h = h2; + editor->DecRef(); + attr->DecRef(); } // preserve (more or less) the previous position @@ -4540,7 +4581,6 @@ void wxGrid::CalcDimensions() CalcWindowSizes(); } - void wxGrid::CalcWindowSizes() { // escape if the window is has not been fully created yet @@ -4554,19 +4594,18 @@ void wxGrid::CalcWindowSizes() if ( m_cornerLabelWin && m_cornerLabelWin->IsShown() ) m_cornerLabelWin->SetSize( 0, 0, m_rowLabelWidth, m_colLabelHeight ); - if ( m_colLabelWin && m_colLabelWin->IsShown() ) - m_colLabelWin->SetSize( m_rowLabelWidth, 0, cw - m_rowLabelWidth, m_colLabelHeight); + if ( m_colLabelWin && m_colLabelWin->IsShown() ) + m_colLabelWin->SetSize( m_rowLabelWidth, 0, cw - m_rowLabelWidth, m_colLabelHeight ); if ( m_rowLabelWin && m_rowLabelWin->IsShown() ) - m_rowLabelWin->SetSize( 0, m_colLabelHeight, m_rowLabelWidth, ch - m_colLabelHeight); + m_rowLabelWin->SetSize( 0, m_colLabelHeight, m_rowLabelWidth, ch - m_colLabelHeight ); if ( m_gridWin && m_gridWin->IsShown() ) - m_gridWin->SetSize( m_rowLabelWidth, m_colLabelHeight, cw - m_rowLabelWidth, ch - m_colLabelHeight); + m_gridWin->SetSize( m_rowLabelWidth, m_colLabelHeight, cw - m_rowLabelWidth, ch - m_colLabelHeight ); } - -// this is called when the grid table sends a message to say that it -// has been redimensioned +// this is called when the grid table sends a message +// to indicate that it has been redimensioned // bool wxGrid::Redimension( wxGridTableMessage& msg ) { @@ -4616,7 +4655,7 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) if ( pos > 0 ) bottom = m_rowBottoms[pos - 1]; - for ( i = pos; i < m_numRows; i++ ) + for ( i = pos; i < m_numRows; i++ ) { bottom += m_rowHeights[i]; m_rowBottoms[i] = bottom; @@ -4661,7 +4700,7 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) if ( oldNumRows > 0 ) bottom = m_rowBottoms[oldNumRows - 1]; - for ( i = oldNumRows; i < m_numRows; i++ ) + for ( i = oldNumRows; i < m_numRows; i++ ) { bottom += m_rowHeights[i]; m_rowBottoms[i] = bottom; @@ -4697,12 +4736,13 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) m_rowBottoms.RemoveAt( pos, numRows ); int h = 0; - for ( i = 0; i < m_numRows; i++ ) + for ( i = 0; i < m_numRows; i++ ) { h += m_rowHeights[i]; m_rowBottoms[i] = h; } } + if ( !m_numRows ) { m_currentCellCoords = wxGridNoCellCoords; @@ -4719,6 +4759,7 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) if (attrProvider) { attrProvider->UpdateAttrRows( pos, -((int)numRows) ); + // ifdef'd out following patch from Paul Gammans #if 0 // No need to touch column attributes, unless we @@ -4746,6 +4787,25 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) int numCols = msg.GetCommandInt2(); m_numCols += numCols; + if ( !m_colAt.IsEmpty() ) + { + //Shift the column IDs + int i; + for ( i = 0; i < m_numCols - numCols; i++ ) + { + if ( m_colAt[i] >= (int)pos ) + m_colAt[i] += numCols; + } + + m_colAt.Insert( pos, pos, numCols ); + + //Set the new columns' positions + for ( i = pos + 1; i < (int)pos + numCols; i++ ) + { + m_colAt[i] = i; + } + } + if ( !m_colWidths.IsEmpty() ) { m_colWidths.Insert( m_defaultColWidth, pos, numCols ); @@ -4753,10 +4813,13 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) int right = 0; if ( pos > 0 ) - right = m_colRights[pos - 1]; + right = m_colRights[GetColAt( pos - 1 )]; - for ( i = pos; i < m_numCols; i++ ) + int colPos; + for ( colPos = pos; colPos < m_numCols; colPos++ ) { + i = GetColAt( colPos ); + right += m_colWidths[i]; m_colRights[i] = right; } @@ -4780,7 +4843,6 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) CalcDimensions(); m_colLabelWin->Refresh(); } - } result = true; break; @@ -4790,6 +4852,19 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) int numCols = msg.GetCommandInt(); int oldNumCols = m_numCols; m_numCols += numCols; + + if ( !m_colAt.IsEmpty() ) + { + m_colAt.Add( 0, numCols ); + + //Set the new columns' positions + int i; + for ( i = oldNumCols; i < m_numCols; i++ ) + { + m_colAt[i] = i; + } + } + if ( !m_colWidths.IsEmpty() ) { m_colWidths.Add( m_defaultColWidth, numCols ); @@ -4797,10 +4872,13 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) int right = 0; if ( oldNumCols > 0 ) - right = m_colRights[oldNumCols - 1]; + right = m_colRights[GetColAt( oldNumCols - 1 )]; - for ( i = oldNumCols; i < m_numCols; i++ ) + int colPos; + for ( colPos = oldNumCols; colPos < m_numCols; colPos++ ) { + i = GetColAt( colPos ); + right += m_colWidths[i]; m_colRights[i] = right; } @@ -4828,14 +4906,32 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) int numCols = msg.GetCommandInt2(); m_numCols -= numCols; + if ( !m_colAt.IsEmpty() ) + { + int colID = GetColAt( pos ); + + m_colAt.RemoveAt( pos, numCols ); + + //Shift the column IDs + int colPos; + for ( colPos = 0; colPos < m_numCols; colPos++ ) + { + if ( m_colAt[colPos] > colID ) + m_colAt[colPos] -= numCols; + } + } + if ( !m_colWidths.IsEmpty() ) { m_colWidths.RemoveAt( pos, numCols ); m_colRights.RemoveAt( pos, numCols ); int w = 0; - for ( i = 0; i < m_numCols; i++ ) + int colPos; + for ( colPos = 0; colPos < m_numCols; colPos++ ) { + i = GetColAt( colPos ); + w += m_colWidths[i]; m_colRights[i] = w; } @@ -4906,7 +5002,8 @@ wxArrayInt wxGrid::CalcRowLabelsExposed( const wxRegion& reg ) #if defined(__WXMOTIF__) int cw, ch; m_gridWin->GetClientSize( &cw, &ch ); - if ( r.GetTop() > ch ) r.SetTop( 0 ); + if ( r.GetTop() > ch ) + r.SetTop( 0 ); r.SetBottom( wxMin( r.GetBottom(), ch ) ); #endif @@ -4919,7 +5016,7 @@ wxArrayInt wxGrid::CalcRowLabelsExposed( const wxRegion& reg ) // find the row labels within these bounds // int row; - for ( row = internalYToRow(top); row < m_numRows; row++ ) + for ( row = internalYToRow(top); row < m_numRows; row++ ) { if ( GetRowBottom(row) < top ) continue; @@ -4956,7 +5053,8 @@ wxArrayInt wxGrid::CalcColLabelsExposed( const wxRegion& reg ) #if defined(__WXMOTIF__) int cw, ch; m_gridWin->GetClientSize( &cw, &ch ); - if ( r.GetLeft() > cw ) r.SetLeft( 0 ); + if ( r.GetLeft() > cw ) + r.SetLeft( 0 ); r.SetRight( wxMin( r.GetRight(), cw ) ); #endif @@ -4969,8 +5067,11 @@ wxArrayInt wxGrid::CalcColLabelsExposed( const wxRegion& reg ) // find the cells within these bounds // int col; - for ( col = internalXToCol(left); col < m_numCols; col++ ) + int colPos; + for ( colPos = GetColPos( internalXToCol(left) ); colPos < m_numCols; colPos++ ) { + col = GetColAt( colPos ); + if ( GetColRight(col) < left ) continue; @@ -5020,7 +5121,7 @@ wxGridCellCoordsArray wxGrid::CalcCellsExposed( const wxRegion& reg ) // find the cells within these bounds // int row, col; - for ( row = internalYToRow(top); row < m_numRows; row++ ) + for ( row = internalYToRow(top); row < m_numRows; row++ ) { if ( GetRowBottom(row) <= top ) continue; @@ -5028,8 +5129,11 @@ wxGridCellCoordsArray wxGrid::CalcCellsExposed( const wxRegion& reg ) if ( GetRowTop(row) > bottom ) break; - for ( col = internalXToCol(left); col < m_numCols; col++ ) + int colPos; + for ( colPos = GetColPos( internalXToCol(left) ); colPos < m_numCols; colPos++ ) { + col = GetColAt( colPos ); + if ( GetColRight(col) <= left ) continue; @@ -5277,6 +5381,9 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) { m_isDragging = true; m_colLabelWin->CaptureMouse(); + + if ( m_cursorMode == WXGRID_CURSOR_MOVE_COL ) + m_dragRowOrCol = XToCol( x ); } if ( event.LeftIsDown() ) @@ -5320,6 +5427,63 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) } break; + case WXGRID_CURSOR_MOVE_COL: + { + if ( x < 0 ) + m_moveToCol = GetColAt( 0 ); + else + m_moveToCol = XToCol( x ); + + int markerX; + + if ( m_moveToCol < 0 ) + markerX = GetColRight( GetColAt( m_numCols - 1 ) ); + else + markerX = GetColLeft( m_moveToCol ); + + if ( markerX != m_dragLastPos ) + { + wxClientDC dc( m_colLabelWin ); + + int cw, ch; + m_colLabelWin->GetClientSize( &cw, &ch ); + + markerX++; + + //Clean up the last indicator + if ( m_dragLastPos >= 0 ) + { + wxPen pen( m_colLabelWin->GetBackgroundColour(), 2 ); + dc.SetPen(pen); + dc.DrawLine( m_dragLastPos + 1, 0, m_dragLastPos + 1, ch ); + dc.SetPen(wxNullPen); + + if ( XToCol( m_dragLastPos ) != -1 ) + DrawColLabel( dc, XToCol( m_dragLastPos ) ); + } + + //Moving to the same place? Don't draw a marker + if ( (m_moveToCol == m_dragRowOrCol) + || (GetColPos( m_moveToCol ) == GetColPos( m_dragRowOrCol ) + 1) + || (m_moveToCol < 0 && m_dragRowOrCol == GetColAt( m_numCols - 1 ))) + { + m_dragLastPos = -1; + return; + } + + //Draw the marker + wxPen pen( *wxBLUE, 2 ); + dc.SetPen(pen); + + dc.DrawLine( markerX, 0, markerX, ch ); + + dc.SetPen(wxNullPen); + + m_dragLastPos = markerX - 1; + } + } + break; + // default label to suppress warnings about "enumeration value // 'xxx' not handled in switch default: @@ -5360,31 +5524,46 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) if ( col >= 0 && !SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) ) { - if ( !event.ShiftDown() && !event.CmdDown() ) - ClearSelection(); - if ( m_selection ) + if ( m_canDragColMove ) { - if ( event.ShiftDown() ) - { - m_selection->SelectBlock( 0, - m_currentCellCoords.GetCol(), - GetNumberRows() - 1, col, - event.ControlDown(), - event.ShiftDown(), - event.AltDown(), - event.MetaDown() ); - } - else + //Show button as pressed + wxClientDC dc( m_colLabelWin ); + int colLeft = GetColLeft( col ); + int colRight = GetColRight( col ) - 1; + dc.SetPen( wxPen( m_colLabelWin->GetBackgroundColour(), 1 ) ); + dc.DrawLine( colLeft, 1, colLeft, m_colLabelHeight-1 ); + dc.DrawLine( colLeft, 1, colRight, 1 ); + + ChangeCursorMode(WXGRID_CURSOR_MOVE_COL, m_colLabelWin); + } + else + { + if ( !event.ShiftDown() && !event.CmdDown() ) + ClearSelection(); + if ( m_selection ) { - m_selection->SelectCol( col, - event.ControlDown(), - event.ShiftDown(), - event.AltDown(), - event.MetaDown() ); + if ( event.ShiftDown() ) + { + m_selection->SelectBlock( 0, + m_currentCellCoords.GetCol(), + GetNumberRows() - 1, col, + event.ControlDown(), + event.ShiftDown(), + event.AltDown(), + event.MetaDown() ); + } + else + { + m_selection->SelectCol( col, + event.ControlDown(), + event.ShiftDown(), + event.AltDown(), + event.MetaDown() ); + } } - } - ChangeCursorMode(WXGRID_CURSOR_SELECT_COL, m_colLabelWin); + ChangeCursorMode(WXGRID_CURSOR_SELECT_COL, m_colLabelWin); + } } } else @@ -5424,14 +5603,29 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) // else if ( event.LeftUp() ) { - if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL ) + switch ( m_cursorMode ) { - DoEndDragResizeCol(); + case WXGRID_CURSOR_RESIZE_COL: + DoEndDragResizeCol(); - // Note: we are ending the event *after* doing - // default processing in this case - // - SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event ); + // Note: we are ending the event *after* doing + // default processing in this case + // + SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event ); + break; + + case WXGRID_CURSOR_MOVE_COL: + DoEndDragMoveCol(); + + SendEvent( wxEVT_GRID_COL_MOVE, -1, m_dragRowOrCol, event ); + break; + + case WXGRID_CURSOR_SELECT_COL: + case WXGRID_CURSOR_SELECT_CELL: + case WXGRID_CURSOR_RESIZE_ROW: + case WXGRID_CURSOR_SELECT_ROW: + // nothing to do (?) + break; } ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_colLabelWin); @@ -5526,7 +5720,8 @@ void wxGrid::ChangeCursorMode(CursorMode mode, _T("RESIZE_ROW"), _T("RESIZE_COL"), _T("SELECT_ROW"), - _T("SELECT_COL") + _T("SELECT_COL"), + _T("MOVE_COL"), }; wxLogTrace(_T("grid"), @@ -5567,6 +5762,10 @@ void wxGrid::ChangeCursorMode(CursorMode mode, win->SetCursor( m_colResizeCursor ); break; + case WXGRID_CURSOR_MOVE_COL: + win->SetCursor( wxCursor(wxCURSOR_HAND) ); + break; + default: win->SetCursor( *wxSTANDARD_CURSOR ); break; @@ -5642,7 +5841,7 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event ) { if ( m_selectingKeyboard == wxGridNoCellCoords) m_selectingKeyboard = coords; - HighlightBlock ( m_selectingKeyboard, coords ); + HighlightBlock( m_selectingKeyboard, coords ); } else if ( CanDragCell() ) { @@ -5708,9 +5907,9 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event ) dc.SetLogicalFunction(wxINVERT); if ( m_dragLastPos >= 0 ) { - dc.DrawLine( m_dragLastPos, top, m_dragLastPos, top+ch ); + dc.DrawLine( m_dragLastPos, top, m_dragLastPos, top + ch ); } - dc.DrawLine( x, top, x, top+ch ); + dc.DrawLine( x, top, x, top + ch ); m_dragLastPos = x; } @@ -5795,7 +5994,6 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event ) } } - // ------------ Left double click // else if ( event.LeftDClick() && coords != wxGridNoCellCoords ) @@ -5816,7 +6014,6 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event ) } } - // ------------ Left button released // else if ( event.LeftUp() ) @@ -5984,7 +6181,7 @@ void wxGrid::DoEndDragResizeRow() wxClientDC dc( m_gridWin ); PrepareDC( dc ); dc.SetLogicalFunction( wxINVERT ); - dc.DrawLine( left, m_dragLastPos, left+cw, m_dragLastPos ); + dc.DrawLine( left, m_dragLastPos, left + cw, m_dragLastPos ); HideCellEditControl(); SaveEditControlValue(); @@ -6008,7 +6205,7 @@ void wxGrid::DoEndDragResizeRow() { int i, cell_rows, cell_cols, subtract_rows = 0; int leftCol = XToCol(left); - int rightCol = internalXToCol(left+cw); + int rightCol = internalXToCol(left + cw); if (leftCol >= 0) { for (i=leftCol; i= 0) { for (i=topRow; iRefresh(); //Do this to "unpress" the column + return; + } + + int newPos; + if ( m_moveToCol == -1 ) + newPos = m_numCols - 1; + else + { + newPos = GetColPos( m_moveToCol ); + if ( newPos > GetColPos( m_dragRowOrCol ) ) + newPos--; + } + + SetColPos( m_dragRowOrCol, newPos ); +} + +void wxGrid::SetColPos( int colID, int newPos ) +{ + if ( m_colAt.IsEmpty() ) + { + m_colAt.Alloc( m_numCols ); + + int i; + for ( i = 0; i < m_numCols; i++ ) + { + m_colAt.Add( i ); + } + } + + int oldPos = GetColPos( colID ); + + //Reshuffle the m_colAt array + if ( newPos > oldPos ) + { + int i; + for ( i = oldPos; i < newPos; i++ ) + { + m_colAt[i] = m_colAt[i+1]; + } + } + else + { + int i; + for ( i = oldPos; i > newPos; i-- ) + { + m_colAt[i] = m_colAt[i-1]; + } + } + + m_colAt[newPos] = colID; + + //Recalculate the column rights + if ( !m_colWidths.IsEmpty() ) + { + int colRight = 0; + int colPos; + for ( colPos = 0; colPos < m_numCols; colPos++ ) + { + int colID = GetColAt( colPos ); + + colRight += m_colWidths[colID]; + m_colRights[colID] = colRight; + } + } + + m_colLabelWin->Refresh(); + m_gridWin->Refresh(); +} + + + +void wxGrid::EnableDragColMove( bool enable ) +{ + if ( m_canDragColMove == enable ) + return; + + m_canDragColMove = enable; + + if ( !m_canDragColMove ) + { + m_colAt.Clear(); + + //Recalculate the column rights + if ( !m_colWidths.IsEmpty() ) + { + int colRight = 0; + int colPos; + for ( colPos = 0; colPos < m_numCols; colPos++ ) + { + colRight += m_colWidths[colPos]; + m_colRights[colPos] = colRight; + } + } + + m_colLabelWin->Refresh(); + m_gridWin->Refresh(); + } +} + + // // ------ interaction with data model // @@ -6117,7 +6421,7 @@ bool wxGrid::ProcessTableMessage( wxGridTableMessage& msg ) } // The behaviour of this function depends on the grid table class -// Clear() function. For the default wxGridStringTable class the +// Clear() function. For the default wxGridStringTable class the // behavious is to replace all cell contents with wxEmptyString but // not to change the number of rows or cols. // @@ -6129,7 +6433,8 @@ void wxGrid::ClearGrid() DisableCellEditControl(); m_table->Clear(); - if ( !GetBatchCount() ) m_gridWin->Refresh(); + if (!GetBatchCount()) + m_gridWin->Refresh(); } } @@ -6154,6 +6459,7 @@ bool wxGrid::InsertRows( int pos, int numRows, bool WXUNUSED(updateLabels) ) // the table will have sent the results of the insert row // operation to this view object as a grid table message } + return false; } @@ -6171,9 +6477,11 @@ bool wxGrid::AppendRows( int numRows, bool WXUNUSED(updateLabels) ) { bool done = m_table && m_table->AppendRows( numRows ); return done; + // the table will have sent the results of the append row // operation to this view object as a grid table message } + return false; } @@ -6197,6 +6505,7 @@ bool wxGrid::DeleteRows( int pos, int numRows, bool WXUNUSED(updateLabels) ) // the table will have sent the results of the delete row // operation to this view object as a grid table message } + return false; } @@ -6317,6 +6626,32 @@ int wxGrid::SendEvent( const wxEventType type, claimed = GetEventHandler()->ProcessEvent(gridEvt); vetoed = !gridEvt.IsAllowed(); } + else if ( type == wxEVT_GRID_LABEL_LEFT_CLICK || + type == wxEVT_GRID_LABEL_LEFT_DCLICK || + type == wxEVT_GRID_LABEL_RIGHT_CLICK || + type == wxEVT_GRID_LABEL_RIGHT_DCLICK ) + { + wxPoint pos = mouseEv.GetPosition(); + + if ( mouseEv.GetEventObject() == GetGridRowLabelWindow() ) + pos.y += GetColLabelSize(); + if ( mouseEv.GetEventObject() == GetGridColLabelWindow() ) + pos.x += GetRowLabelSize(); + + wxGridEvent gridEvt( GetId(), + type, + this, + row, col, + pos.x, + pos.y, + false, + mouseEv.ControlDown(), + mouseEv.ShiftDown(), + mouseEv.AltDown(), + mouseEv.MetaDown() ); + claimed = GetEventHandler()->ProcessEvent(gridEvt); + vetoed = !gridEvt.IsAllowed(); + } else { wxGridEvent gridEvt( GetId(), @@ -6347,27 +6682,20 @@ int wxGrid::SendEvent( const wxEventType type, int wxGrid::SendEvent( const wxEventType type, int row, int col ) { - bool claimed; - bool vetoed; + bool claimed, vetoed; if ( type == wxEVT_GRID_ROW_SIZE || type == wxEVT_GRID_COL_SIZE ) { int rowOrCol = (row == -1 ? col : row); - wxGridSizeEvent gridEvt( GetId(), - type, - this, - rowOrCol ); + wxGridSizeEvent gridEvt( GetId(), type, this, rowOrCol ); claimed = GetEventHandler()->ProcessEvent(gridEvt); vetoed = !gridEvt.IsAllowed(); } else { - wxGridEvent gridEvt( GetId(), - type, - this, - row, col ); + wxGridEvent gridEvt( GetId(), type, this, row, col ); claimed = GetEventHandler()->ProcessEvent(gridEvt); vetoed = !gridEvt.IsAllowed(); @@ -6382,7 +6710,8 @@ int wxGrid::SendEvent( const wxEventType type, void wxGrid::OnPaint( wxPaintEvent& WXUNUSED(event) ) { - wxPaintDC dc(this); // needed to prevent zillions of paint events on MSW + // needed to prevent zillions of paint events on MSW + wxPaintDC dc(this); } void wxGrid::Refresh(bool eraseb, const wxRect* rect) @@ -6411,7 +6740,8 @@ void wxGrid::Refresh(bool eraseb, const wxRect* rect) width_label = rectWidth; height_label = m_colLabelHeight - rect_y; - if (height_label > rectHeight) height_label = rectHeight; + if (height_label > rectHeight) + height_label = rectHeight; if (rect_x > m_rowLabelWidth) { @@ -6495,15 +6825,21 @@ void wxGrid::OnKeyDown( wxKeyEvent& event ) m_inOnKeyDown = true; // propagate the event up and see if it gets processed - // wxWindow *parent = GetParent(); wxKeyEvent keyEvt( event ); keyEvt.SetEventObject( parent ); if ( !parent->GetEventHandler()->ProcessEvent( keyEvt ) ) { + if (GetLayoutDirection() == wxLayout_RightToLeft) + { + if (event.GetKeyCode() == WXK_RIGHT) + event.m_keyCode = WXK_LEFT; + else if (event.GetKeyCode() == WXK_LEFT) + event.m_keyCode = WXK_RIGHT; + } + // try local handlers - // switch ( event.GetKeyCode() ) { case WXK_UP: @@ -6600,8 +6936,8 @@ 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 ); + MakeCellVisible( m_numRows - 1, m_numCols - 1 ); + SetCurrentCell( m_numRows - 1, m_numCols - 1 ); } else { @@ -6622,12 +6958,13 @@ void wxGrid::OnKeyDown( wxKeyEvent& event ) { if ( m_selection ) { - m_selection->ToggleCellSelection( m_currentCellCoords.GetRow(), - m_currentCellCoords.GetCol(), - event.ControlDown(), - event.ShiftDown(), - event.AltDown(), - event.MetaDown() ); + m_selection->ToggleCellSelection( + m_currentCellCoords.GetRow(), + m_currentCellCoords.GetCol(), + event.ControlDown(), + event.ShiftDown(), + event.AltDown(), + event.MetaDown() ); } break; } @@ -6658,14 +6995,15 @@ void wxGrid::OnKeyUp( wxKeyEvent& event ) { if ( m_selection ) { - m_selection->SelectBlock( m_selectingTopLeft.GetRow(), - m_selectingTopLeft.GetCol(), - m_selectingBottomRight.GetRow(), - m_selectingBottomRight.GetCol(), - event.ControlDown(), - true, - event.AltDown(), - event.MetaDown() ); + m_selection->SelectBlock( + m_selectingTopLeft.GetRow(), + m_selectingTopLeft.GetCol(), + m_selectingBottomRight.GetRow(), + m_selectingBottomRight.GetCol(), + event.ControlDown(), + true, + event.AltDown(), + event.MetaDown() ); } } @@ -6826,9 +7164,9 @@ void wxGrid::HighlightBlock( int topRow, int leftCol, int bottomRow, int rightCo int i; // Store intermediate values - wxCoord oldLeft = m_selectingTopLeft.GetCol(); - wxCoord oldTop = m_selectingTopLeft.GetRow(); - wxCoord oldRight = m_selectingBottomRight.GetCol(); + wxCoord oldLeft = m_selectingTopLeft.GetCol(); + wxCoord oldTop = m_selectingTopLeft.GetRow(); + wxCoord oldRight = m_selectingBottomRight.GetCol(); wxCoord oldBottom = m_selectingBottomRight.GetRow(); // Determine the outer/inner coordinates. @@ -6866,10 +7204,9 @@ void wxGrid::HighlightBlock( int topRow, int leftCol, int bottomRow, int rightCo // Refresh the newly selected or deselected // area to the left of the old or new selection. need_refresh[0] = true; - rect[0] = BlockToDeviceRect( wxGridCellCoords ( oldTop, - oldLeft ), - wxGridCellCoords ( oldBottom, - leftCol - 1 ) ); + rect[0] = BlockToDeviceRect( + wxGridCellCoords( oldTop, oldLeft ), + wxGridCellCoords( oldBottom, leftCol - 1 ) ); } if ( oldTop < topRow ) @@ -6888,8 +7225,8 @@ void wxGrid::HighlightBlock( int topRow, int leftCol, int bottomRow, int rightCo // area to the right of the old or new selection. need_refresh[2] = true; rect[2] = BlockToDeviceRect( - wxGridCellCoords ( oldTop, rightCol + 1 ), - wxGridCellCoords ( oldBottom, oldRight ) ); + wxGridCellCoords( oldTop, rightCol + 1 ), + wxGridCellCoords( oldBottom, oldRight ) ); } if ( oldBottom > bottomRow ) @@ -6898,8 +7235,8 @@ void wxGrid::HighlightBlock( int topRow, int leftCol, int bottomRow, int rightCo // area below the old or new selection. need_refresh[3] = true; rect[3] = BlockToDeviceRect( - wxGridCellCoords ( bottomRow + 1, leftCol ), - wxGridCellCoords ( oldBottom, rightCol ) ); + wxGridCellCoords( bottomRow + 1, leftCol ), + wxGridCellCoords( oldBottom, rightCol ) ); } // various Refresh() calls @@ -6944,9 +7281,9 @@ bool wxGrid::SetModelValues() if ( m_table ) { - for ( row = 0; row < m_numRows; row++ ) + for ( row = 0; row < m_numRows; row++ ) { - for ( col = 0; col < m_numCols; col++ ) + for ( col = 0; col < m_numCols; col++ ) { m_table->SetValue( row, col, GetCellValue(row, col) ); } @@ -6971,7 +7308,7 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells ) int row, col, cell_rows, cell_cols; wxGridCellCoordsArray redrawCells; - for ( i = numCells-1; i >= 0; i-- ) + for ( i = numCells - 1; i >= 0; i-- ) { row = cells[i].GetRow(); col = cells[i].GetCol(); @@ -6980,9 +7317,9 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells ) // If this cell is part of a multicell block, find owner for repaint if ( cell_rows <= 0 || cell_cols <= 0 ) { - wxGridCellCoords cell(row+cell_rows, col+cell_cols); + wxGridCellCoords cell( row + cell_rows, col + cell_cols ); bool marked = false; - for ( int j = 0; j < numCells; j++ ) + for ( int j = 0; j < numCells; j++ ) { if ( cell == cells[j] ) { @@ -7016,7 +7353,7 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells ) { for ( int l = 0; l < cell_rows; l++ ) { - // find a cell in this row to left alreay marked for repaint + // find a cell in this row to leave already marked for repaint int left = col; for (int k = 0; k < int(redrawCells.GetCount()); k++) if ((redrawCells[k].GetCol() < left) && @@ -7072,7 +7409,7 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells ) numCells = redrawCells.GetCount(); - for ( i = numCells - 1; i >= 0; i-- ) + for ( i = numCells - 1; i >= 0; i-- ) { DrawCell( dc, redrawCells[i] ); } @@ -7086,7 +7423,7 @@ void wxGrid::DrawGridSpace( wxDC& dc ) int right, bottom; CalcUnscrolledPosition( cw, ch, &right, &bottom ); - int rightCol = m_numCols > 0 ? GetColRight(m_numCols - 1) : 0; + int rightCol = m_numCols > 0 ? GetColRight(GetColAt( m_numCols - 1 )) : 0; int bottomRow = m_numRows > 0 ? GetRowBottom(m_numRows - 1) : 0; if ( right > rightCol || bottom > bottomRow ) @@ -7099,12 +7436,12 @@ void wxGrid::DrawGridSpace( wxDC& dc ) if ( right > rightCol ) { - dc.DrawRectangle( rightCol, top, right - rightCol, ch); + dc.DrawRectangle( rightCol, top, right - rightCol, ch ); } if ( bottom > bottomRow ) { - dc.DrawRectangle( left, bottomRow, cw, bottom - bottomRow); + dc.DrawRectangle( left, bottomRow, cw, bottom - bottomRow ); } } } @@ -7133,7 +7470,7 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) // Note: However, only if it is really _shown_, i.e. not hidden! if ( isCurrent && IsCellEditControlShown() ) { - // OSAF NB: this "#if..." is temporary and fixes a problem where the + // NB: this "#if..." is temporary and fixes a problem where the // edit control is erased by this code after being rendered. // On wxMac (QD build only), the cell editor is a wxTextCntl and is rendered // implicitly, causing this out-of order render. @@ -7145,8 +7482,7 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) } else { - // but all the rest is drawn by the cell renderer and hence may be - // customized + // but all the rest is drawn by the cell renderer and hence may be customized wxGridCellRenderer *renderer = attr->GetRenderer(this, row, col); renderer->Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords)); renderer->DecRef(); @@ -7173,10 +7509,10 @@ void wxGrid::DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr ) if (penWidth > 0) { - // The center of th drawn line is where the position/width/height of - // the rectangle is actually at, (on wxMSW atr least,) so we will - // reduce the size of the rectangle to compensate for the thickness of - // the line. If this is too strange on non wxMSW platforms then + // The center of the drawn line is where the position/width/height of + // the rectangle is actually at (on wxMSW at least), so the + // size of the rectangle is reduced to compensate for the thickness of + // the line. If this is too strange on non-wxMSW platforms then // please #ifdef this appropriately. rect.x += penWidth / 2; rect.y += penWidth / 2; @@ -7210,7 +7546,22 @@ void wxGrid::DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr ) dc.SetPen(*wxBLACK_PEN); dc.DrawLine(x1, y2, x2, y2); dc.DrawLine(x2, y1, x2, y2 + 1); -#endif // 0 +#endif +} + +wxPen wxGrid::GetDefaultGridLinePen() +{ + return wxPen(GetGridLineColour(), 1, wxSOLID); +} + +wxPen wxGrid::GetRowGridLinePen(int WXUNUSED(row)) +{ + return GetDefaultGridLinePen(); +} + +wxPen wxGrid::GetColGridLinePen(int WXUNUSED(col)) +{ + return GetDefaultGridLinePen(); } void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords ) @@ -7220,17 +7571,16 @@ void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords ) if ( GetColWidth(col) <= 0 || GetRowHeight(row) <= 0 ) return; - dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) ); wxRect rect = CellToRect( row, col ); // right hand border - // + dc.SetPen( GetColGridLinePen(col) ); dc.DrawLine( rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height + 1 ); // bottom border - // + dc.SetPen( GetRowGridLinePen(row) ); dc.DrawLine( rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height); } @@ -7310,13 +7660,13 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) ) // avoid drawing grid lines past the last row and col // - right = wxMin( right, GetColRight(m_numCols - 1) ); + right = wxMin( right, GetColRight(GetColAt( m_numCols - 1 )) ); bottom = wxMin( bottom, GetRowBottom(m_numRows - 1) ); // no gridlines inside multicells, clip them out - int leftCol = internalXToCol(left); - int topRow = internalYToRow(top); - int rightCol = internalXToCol(right); + int leftCol = GetColPos( internalXToCol(left) ); + int topRow = internalYToRow(top); + int rightCol = GetColPos( internalXToCol(right) ); int bottomRow = internalYToRow(bottom); #ifndef __WXMAC__ @@ -7328,8 +7678,11 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) ) for (j=topRow; j 1) || (cell_cols > 1)) { @@ -7339,14 +7692,14 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) ) } else if ((cell_rows < 0) || (cell_cols < 0)) { - rect = CellToRect(j+cell_rows, i+cell_cols); + rect = CellToRect(j + cell_rows, i + cell_cols); CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y ); clippedcells.Subtract(rect); } } } #else - wxRegion clippedcells( left , top, right - left, bottom - top); + wxRegion clippedcells( left, top, right - left, bottom - top ); int i, j, cell_rows, cell_cols; wxRect rect; @@ -7369,9 +7722,9 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) ) } } #endif + dc.SetClippingRegion( clippedcells ); - dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) ); // horizontal grid lines // @@ -7387,15 +7740,24 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) ) if ( bot >= top ) { + dc.SetPen( GetRowGridLinePen(i) ); dc.DrawLine( left, bot, right, bot ); } } // vertical grid lines // - for ( i = internalXToCol(left); i < m_numCols; i++ ) + int colPos; + for ( colPos = leftCol; colPos < m_numCols; colPos++ ) { - int colRight = GetColRight(i) - 1; + i = GetColAt( colPos ); + + int colRight = GetColRight(i); +#ifdef __WXGTK__ + if (GetLayoutDirection() != wxLayout_RightToLeft) +#endif + colRight--; + if ( colRight > right ) { break; @@ -7403,13 +7765,15 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) ) if ( colRight >= left ) { + dc.SetPen( GetColGridLinePen(i) ); dc.DrawLine( colRight, top, colRight, bottom ); } } + dc.DestroyClippingRegion(); } -void wxGrid::DrawRowLabels( wxDC& dc ,const wxArrayInt& rows) +void wxGrid::DrawRowLabels( wxDC& dc, const wxArrayInt& rows) { if ( !m_numRows ) return; @@ -7445,17 +7809,14 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row ) int rowTop = GetRowTop(row), rowBottom = GetRowBottom(row) - 1; - dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW),1, wxSOLID) ); - dc.DrawLine( m_rowLabelWidth-1, rowTop, - m_rowLabelWidth-1, rowBottom ); - + dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID) ); + dc.DrawLine( m_rowLabelWidth - 1, rowTop, m_rowLabelWidth - 1, rowBottom ); dc.DrawLine( 0, rowTop, 0, rowBottom ); - dc.DrawLine( 0, rowBottom, m_rowLabelWidth, rowBottom ); dc.SetPen( *wxWHITE_PEN ); dc.DrawLine( 1, rowTop, 1, rowBottom ); - dc.DrawLine( 1, rowTop, m_rowLabelWidth-1, rowTop ); + dc.DrawLine( 1, rowTop, m_rowLabelWidth - 1, rowTop ); #endif dc.SetBackgroundMode( wxTRANSPARENT ); @@ -7480,7 +7841,7 @@ void wxGrid::DrawColLabels( wxDC& dc,const wxArrayInt& cols ) size_t i; size_t numLabels = cols.GetCount(); - for ( i = 0; i < numLabels; i++ ) + for ( i = 0; i < numLabels; i++ ) { DrawColLabel( dc, cols[i] ); } @@ -7507,11 +7868,9 @@ void wxGrid::DrawColLabel( wxDC& dc, int col ) #else int colRight = GetColRight(col) - 1; - dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW), 1, wxSOLID) ); + dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID) ); dc.DrawLine( colRight, 0, colRight, m_colLabelHeight - 1 ); - dc.DrawLine( colLeft, 0, colRight, 0 ); - dc.DrawLine( colLeft, m_colLabelHeight - 1, colRight + 1, m_colLabelHeight - 1 ); @@ -7547,7 +7906,7 @@ void wxGrid::DrawTextRectangle( wxDC& dc, StringToLines( value, lines ); // Forward to new API. - DrawTextRectangle( dc, + DrawTextRectangle( dc, lines, rect, horizAlign, @@ -7555,32 +7914,32 @@ void wxGrid::DrawTextRectangle( wxDC& dc, textOrientation ); } -void wxGrid::DrawTextRectangle( wxDC& dc, +// VZ: this should be replaced with wxDC::DrawLabel() to which we just have to +// add textOrientation support +void wxGrid::DrawTextRectangle(wxDC& dc, const wxArrayString& lines, const wxRect& rect, int horizAlign, int vertAlign, - int textOrientation ) + int textOrientation) { - long textWidth = 0, textHeight = 0; - long lineWidth = 0, lineHeight = 0; - int nLines; + if ( lines.empty() ) + return; - dc.SetClippingRegion( rect ); + wxDCClipper clip(dc, rect); - nLines = lines.GetCount(); - if ( nLines > 0 ) - { - int l; - float x = 0.0, y = 0.0; + long textWidth, + textHeight; - if ( textOrientation == wxHORIZONTAL ) - GetTextBoxSize(dc, lines, &textWidth, &textHeight); - else - GetTextBoxSize( dc, lines, &textHeight, &textWidth ); + if ( textOrientation == wxHORIZONTAL ) + GetTextBoxSize( dc, lines, &textWidth, &textHeight ); + else + GetTextBoxSize( dc, lines, &textHeight, &textWidth ); - switch ( vertAlign ) - { + int x = 0, + y = 0; + switch ( vertAlign ) + { case wxALIGN_BOTTOM: if ( textOrientation == wxHORIZONTAL ) y = rect.y + (rect.height - textHeight - 1); @@ -7590,9 +7949,9 @@ void wxGrid::DrawTextRectangle( wxDC& dc, case wxALIGN_CENTRE: if ( textOrientation == wxHORIZONTAL ) - y = rect.y + ((rect.height - textHeight)/2); + y = rect.y + ((rect.height - textHeight) / 2); else - x = rect.x + ((rect.width - textWidth)/2); + x = rect.x + ((rect.width - textWidth) / 2); break; case wxALIGN_TOP: @@ -7602,15 +7961,26 @@ void wxGrid::DrawTextRectangle( wxDC& dc, else x = rect.x + 1; break; - } + } - // Align each line of a multi-line label - for ( l = 0; l < nLines; l++ ) + // Align each line of a multi-line label + size_t nLines = lines.GetCount(); + for ( size_t l = 0; l < nLines; l++ ) + { + const wxString& line = lines[l]; + + if ( line.empty() ) { - dc.GetTextExtent(lines[l], &lineWidth, &lineHeight); + *(textOrientation == wxHORIZONTAL ? &y : &x) += dc.GetCharHeight(); + continue; + } - switch ( horizAlign ) - { + long lineWidth = 0, + lineHeight = 0; + dc.GetTextExtent(line, &lineWidth, &lineHeight); + + switch ( horizAlign ) + { case wxALIGN_RIGHT: if ( textOrientation == wxHORIZONTAL ) x = rect.x + (rect.width - lineWidth - 1); @@ -7632,22 +8002,19 @@ void wxGrid::DrawTextRectangle( wxDC& dc, else y = rect.y + rect.height - 1; break; - } + } - if ( textOrientation == wxHORIZONTAL ) - { - dc.DrawText( lines[l], (int)x, (int)y ); - y += lineHeight; - } - else - { - dc.DrawRotatedText( lines[l], (int)x, (int)y, 90.0 ); - x += lineHeight; - } + if ( textOrientation == wxHORIZONTAL ) + { + dc.DrawText( line, x, y ); + y += lineHeight; + } + else + { + dc.DrawRotatedText( line, x, y, 90.0 ); + x += lineHeight; } } - - dc.DestroyClippingRegion(); } // Split multi-line text up into an array of strings. @@ -7675,6 +8042,7 @@ void wxGrid::StringToLines( const wxString& value, wxArrayString& lines ) { lines.Add( value.Mid(startPos, pos) ); } + startPos += pos + 1; } @@ -7693,7 +8061,7 @@ void wxGrid::GetTextBoxSize( const wxDC& dc, long lineW = 0, lineH = 0; size_t i; - for ( i = 0; i < lines.GetCount(); i++ ) + for ( i = 0; i < lines.GetCount(); i++ ) { dc.GetTextExtent( lines[i], &lineW, &lineH ); w = wxMax( w, lineW ); @@ -7773,8 +8141,7 @@ void wxGrid::EnableCellEditControl( bool enable ) return; // this should be checked by the caller! - wxASSERT_MSG( CanEnableCellControl(), - _T("can't enable editing for this cell!") ); + wxASSERT_MSG( CanEnableCellControl(), _T("can't enable editing for this cell!") ); // do it before ShowCellEditControl() m_cellEditCtrlEnabled = enable; @@ -7784,7 +8151,7 @@ void wxGrid::EnableCellEditControl( bool enable ) else { //FIXME:add veto support - SendEvent( wxEVT_GRID_EDITOR_HIDDEN); + SendEvent( wxEVT_GRID_EDITOR_HIDDEN ); HideCellEditControl(); SaveEditControlValue(); @@ -7809,7 +8176,6 @@ bool wxGrid::CanEnableCellControl() const { return m_editable && (m_currentCellCoords != wxGridNoCellCoords) && !IsCurrentCellReadOnly(); - } bool wxGrid::IsCellEditControlEnabled() const @@ -7871,24 +8237,20 @@ void wxGrid::ShowCellEditControl() m_currentCellCoords.SetCol( col ); } - // convert to scrolled coords - // - CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y ); - - int nXMove = 0; - if (rect.x < 0) - nXMove = rect.x; - - // done in PaintBackground() -#if 0 // erase the highlight and the cell contents because the editor // might not cover the entire cell wxClientDC dc( m_gridWin ); PrepareDC( dc ); - dc.SetBrush(*wxLIGHT_GREY_BRUSH); //wxBrush(attr->GetBackgroundColour(), wxSOLID)); + dc.SetBrush(wxBrush(GetCellAttr(row, col)->GetBackgroundColour(), wxSOLID)); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(rect); -#endif // 0 + + // convert to scrolled coords + CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y ); + + int nXMove = 0; + if (rect.x < 0) + nXMove = rect.x; // cell is shifted by one pixel // However, don't allow x or y to become negative @@ -7955,24 +8317,12 @@ void wxGrid::ShowCellEditControl() editor->SetCellAttr( attr ); editor->SetSize( rect ); - editor->GetControl()->Move( - editor->GetControl()->GetPosition().x + nXMove, - editor->GetControl()->GetPosition().y ); + if (nXMove != 0) + editor->GetControl()->Move( + editor->GetControl()->GetPosition().x + nXMove, + editor->GetControl()->GetPosition().y ); editor->Show( true, attr ); - int colXPos = 0; - for (int i = 0; i < m_currentCellCoords.GetCol(); i++) - { - colXPos += GetColSize( i ); - } - - int xUnit = 1, yUnit = 1; - GetScrollPixelsPerUnit( &xUnit, &yUnit ); - if (m_currentCellCoords.GetCol() != 0) - Scroll( colXPos / xUnit - 1, GetScrollPos( wxVERTICAL ) ); - else - Scroll( colXPos / xUnit, GetScrollPos( wxVERTICAL ) ); - // recalc dimensions in case we need to // expand the scrolled window to account for editor CalcDimensions(); @@ -8056,7 +8406,7 @@ void wxGrid::XYToCell( int x, int y, wxGridCellCoords& coords ) int row = YToRow(y); int col = XToCol(x); - if ( row == -1 || col == -1 ) + if ( row == -1 || col == -1 ) { coords = wxGridNoCellCoords; } @@ -8139,21 +8489,84 @@ int wxGrid::YToRow( int y ) m_minAcceptableRowHeight, m_rowBottoms, m_numRows, false); } -int wxGrid::XToCol( int x ) +int wxGrid::XToCol( int x, bool clipToMinMax ) { - return CoordToRowOrCol(x, m_defaultColWidth, - m_minAcceptableColWidth, m_colRights, m_numCols, false); + if (x < 0) + return clipToMinMax && (m_numCols > 0) ? GetColAt( 0 ) : -1; + + if (!m_defaultColWidth) + m_defaultColWidth = 1; + + int maxPos = x / m_defaultColWidth; + int minPos = 0; + + if (m_colRights.IsEmpty()) + { + if(maxPos < m_numCols) + return GetColAt( maxPos ); + return clipToMinMax ? GetColAt( m_numCols - 1 ) : -1; + } + + if ( maxPos >= m_numCols) + maxPos = m_numCols - 1; + else + { + if ( x >= m_colRights[GetColAt( maxPos )]) + { + minPos = maxPos; + if (m_minAcceptableColWidth) + maxPos = x / m_minAcceptableColWidth; + else + maxPos = m_numCols - 1; + } + if ( maxPos >= m_numCols) + maxPos = m_numCols - 1; + } + + //X is beyond the last column + if ( x >= m_colRights[GetColAt( maxPos )]) + return clipToMinMax ? GetColAt( maxPos ) : -1; + + //X is before the first column + if ( x < m_colRights[GetColAt( 0 )] ) + return GetColAt( 0 ); + + //Perform a binary search + while ( maxPos - minPos > 0 ) + { + wxCHECK_MSG(m_colRights[GetColAt( minPos )] <= x && x < m_colRights[GetColAt( maxPos )], + 0, _T("wxGrid: internal error in XToCol")); + + if (x >= m_colRights[GetColAt( maxPos - 1 )]) + return GetColAt( maxPos ); + else + maxPos--; + int median = minPos + (maxPos - minPos + 1) / 2; + if (x < m_colRights[GetColAt( median )]) + maxPos = median; + else + minPos = median; + } + return GetColAt( maxPos ); } -// return the row number that that the y coord is near the edge of, or -// -1 if not near an edge +// return the row number that that the y coord is near +// the edge of, or -1 if not near an edge. +// coords can only possibly be near an edge if +// (a) the row/column is large enough to still allow for an "inner" area +// that is _not_ nead the edge (i.e., if the height/width is smaller +// than WXGRID_LABEL_EDGE_ZONE, coords are _never_ considered to be +// near the edge). +// and +// (b) resizing rows/columns (the thing for which edge detection is +// relevant at all) is enabled. // int wxGrid::YToEdgeOfRow( int y ) { int i; i = internalYToRow(y); - if ( GetRowHeight(i) > WXGRID_LABEL_EDGE_ZONE ) + if ( GetRowHeight(i) > WXGRID_LABEL_EDGE_ZONE && CanDragRowSize() ) { // We know that we are in row i, test whether we are // close enough to lower or upper border, respectively. @@ -8168,15 +8581,16 @@ int wxGrid::YToEdgeOfRow( int y ) // return the col number that that the x coord is near the edge of, or // -1 if not near an edge +// See comment at YToEdgeOfRow for conditions on edge detection. // int wxGrid::XToEdgeOfCol( int x ) { int i; i = internalXToCol(x); - if ( GetColWidth(i) > WXGRID_LABEL_EDGE_ZONE ) + if ( GetColWidth(i) > WXGRID_LABEL_EDGE_ZONE && CanDragColSize() ) { - // We know that we are in column i, test whether we are + // We know that we are in column i; test whether we are // close enough to right or left border, respectively. if ( abs(GetColRight(i) - x) < WXGRID_LABEL_EDGE_ZONE ) return i; @@ -8241,7 +8655,6 @@ bool wxGrid::IsVisible( int row, int col, bool wholeCellVisible ) if ( wholeCellVisible ) { // is the cell wholly visible ? - // return ( left >= 0 && right <= cw && top >= 0 && bottom <= ch ); } @@ -8284,7 +8697,7 @@ void wxGrid::MakeCellVisible( int row, int col ) { int h = r.GetHeight(); ypos = r.GetTop(); - for ( i = row-1; i >= 0; i-- ) + for ( i = row - 1; i >= 0; i-- ) { int rowHeight = GetRowHeight(i); if ( h + rowHeight > ch ) @@ -8295,11 +8708,11 @@ void wxGrid::MakeCellVisible( int row, int col ) } // we divide it later by GRID_SCROLL_LINE, make sure that we don't - // have rounding errors (this is important, because if we do, we - // might not scroll at all and some cells won't be redrawn) + // have rounding errors (this is important, because if we do, + // we might not scroll at all and some cells won't be redrawn) // - // Sometimes GRID_SCROLL_LINE/2 is not enough, so just add a full - // scroll unit... + // Sometimes GRID_SCROLL_LINE / 2 is not enough, + // so just add a full scroll unit... ypos += m_scrollLineY; } @@ -8423,11 +8836,12 @@ bool wxGrid::MoveCursorLeft( bool expandSelection ) HighlightBlock( m_currentCellCoords, m_selectingKeyboard ); } } - else if ( m_currentCellCoords.GetCol() > 0 ) + else if ( GetColPos( m_currentCellCoords.GetCol() ) > 0 ) { int row = m_currentCellCoords.GetRow(); - int col = m_currentCellCoords.GetCol() - 1; + int col = GetColAt( GetColPos( m_currentCellCoords.GetCol() ) - 1 ); ClearSelection(); + MakeCellVisible( row, col ); SetCurrentCell( row, col ); } @@ -8457,11 +8871,12 @@ bool wxGrid::MoveCursorRight( bool expandSelection ) HighlightBlock( m_currentCellCoords, m_selectingKeyboard ); } } - else if ( m_currentCellCoords.GetCol() < m_numCols - 1 ) + else if ( GetColPos( m_currentCellCoords.GetCol() ) < m_numCols - 1 ) { int row = m_currentCellCoords.GetRow(); - int col = m_currentCellCoords.GetCol() + 1; + int col = GetColAt( GetColPos( m_currentCellCoords.GetCol() ) + 1 ); ClearSelection(); + MakeCellVisible( row, col ); SetCurrentCell( row, col ); } @@ -8490,7 +8905,7 @@ bool wxGrid::MovePageUp() if ( newRow == row ) { - //row > 0 , so newrow can never be less than 0 here. + // row > 0, so newRow can never be less than 0 here. newRow = row - 1; } @@ -8518,7 +8933,7 @@ bool wxGrid::MovePageDown() int newRow = internalYToRow( y + ch ); if ( newRow == row ) { - // row < m_numRows , so newrow can't overflow here. + // row < m_numRows, so newRow can't overflow here. newRow = row + 1; } @@ -8884,7 +9299,8 @@ void wxGrid::SetColLabelSize( int height ) else if ( m_colLabelHeight == 0 ) { m_colLabelWin->Show( true ); - if ( m_rowLabelWidth > 0 ) m_cornerLabelWin->Show( true ); + if ( m_rowLabelWidth > 0 ) + m_cornerLabelWin->Show( true ); } m_colLabelHeight = height; @@ -9010,14 +9426,10 @@ void wxGrid::SetColLabelAlignment( int horiz, int vert ) void wxGrid::SetColLabelTextOrientation( int textOrientation ) { if ( textOrientation == wxHORIZONTAL || textOrientation == wxVERTICAL ) - { m_colLabelTextOrientation = textOrientation; - } if ( !GetBatchCount() ) - { m_colLabelWin->Refresh(); - } } void wxGrid::SetRowLabelValue( int row, const wxString& s ) @@ -9412,7 +9824,7 @@ wxGridCellAttr *wxGrid::GetCellAttr(int row, int col) const { if ( !LookupAttr(row, col, &attr) ) { - attr = m_table ? m_table->GetAttr(row, col , wxGridCellAttr::Any) + attr = m_table ? m_table->GetAttr(row, col, wxGridCellAttr::Any) : (wxGridCellAttr *)NULL; CacheAttr(row, col, attr); } @@ -9683,19 +10095,19 @@ void wxGrid::RegisterDataType(const wxString& typeName, } -wxGridCellEditor* wxGrid::GetDefaultEditorForCell(int row, int col) const +wxGridCellEditor * wxGrid::GetDefaultEditorForCell(int row, int col) const { wxString typeName = m_table->GetTypeName(row, col); return GetDefaultEditorForType(typeName); } -wxGridCellRenderer* wxGrid::GetDefaultRendererForCell(int row, int col) const +wxGridCellRenderer * wxGrid::GetDefaultRendererForCell(int row, int col) const { wxString typeName = m_table->GetTypeName(row, col); return GetDefaultRendererForType(typeName); } -wxGridCellEditor* wxGrid::GetDefaultEditorForType(const wxString& typeName) const +wxGridCellEditor * wxGrid::GetDefaultEditorForType(const wxString& typeName) const { int index = m_typeRegistry->FindOrCloneDataType(typeName); if ( index == wxNOT_FOUND ) @@ -9711,7 +10123,7 @@ wxGridCellEditor* wxGrid::GetDefaultEditorForType(const wxString& typeName) cons return m_typeRegistry->GetEditor(index); } -wxGridCellRenderer* wxGrid::GetDefaultRendererForType(const wxString& typeName) const +wxGridCellRenderer * wxGrid::GetDefaultRendererForType(const wxString& typeName) const { int index = m_typeRegistry->FindOrCloneDataType(typeName); if ( index == wxNOT_FOUND ) @@ -9787,7 +10199,7 @@ void wxGrid::SetRowSize( int row, int height ) m_rowHeights[row] = h; int i; - for ( i = row; i < m_numRows; i++ ) + for ( i = row; i < m_numRows; i++ ) { m_rowBottoms[i] += diff; } @@ -9820,7 +10232,7 @@ void wxGrid::SetColSize( int col, int width ) // should we check that it's bigger than GetColMinimalWidth(col) here? // (VZ) // No, because it is reasonable to assume the library user know's - // what he is doing. However whe should test against the weaker + // what he is doing. However we should test against the weaker // constraint of minimalAcceptableWidth, as this breaks rendering // // This test then fixes sf.net bug #645734 @@ -9834,16 +10246,16 @@ void wxGrid::SetColSize( int col, int width ) InitColWidths(); } - // if < 0 calc new width from label + // if < 0 then calculate new width from label if ( width < 0 ) { - long w, h; - wxArrayString lines; - wxClientDC dc(m_colLabelWin); - dc.SetFont(GetLabelFont()); - StringToLines(GetColLabelValue(col), lines); - GetTextBoxSize(dc, lines, &w, &h); - width = w + 6; + long w, h; + wxArrayString lines; + wxClientDC dc(m_colLabelWin); + dc.SetFont(GetLabelFont()); + StringToLines(GetColLabelValue(col), lines); + GetTextBoxSize(dc, lines, &w, &h); + width = w + 6; } int w = wxMax( 0, width ); @@ -9851,8 +10263,10 @@ void wxGrid::SetColSize( int col, int width ) m_colWidths[col] = w; int i; - for ( i = col; i < m_numCols; i++ ) + int colPos; + for ( colPos = GetColPos( col ); colPos < m_numCols; colPos++ ) { + i = GetColAt( colPos ); m_colRights[i] += diff; } @@ -9956,9 +10370,7 @@ void wxGrid::AutoSizeColOrRow( int colOrRow, bool setAsMin, bool column ) wxSize size = renderer->GetBestSize(*this, *attr, dc, row, col); extent = column ? size.x : size.y; if ( extent > extentMax ) - { extentMax = extent; - } renderer->DecRef(); } @@ -9972,18 +10384,16 @@ void wxGrid::AutoSizeColOrRow( int colOrRow, bool setAsMin, bool column ) if ( column ) { - dc.GetTextExtent( GetColLabelValue(col), &w, &h ); + dc.GetMultiLineTextExtent( GetColLabelValue(col), &w, &h ); if ( GetColLabelTextOrientation() == wxVERTICAL ) w = h; } else - dc.GetTextExtent( GetRowLabelValue(row), &w, &h ); + dc.GetMultiLineTextExtent( GetRowLabelValue(row), &w, &h ); extent = column ? w : h; if ( extent > extentMax ) - { extentMax = extent; - } if ( !extentMax ) { @@ -10050,9 +10460,7 @@ int wxGrid::SetOrCalcColumnSizes(bool calcOnly, bool setAsMin) for ( int col = 0; col < m_numCols; col++ ) { if ( !calcOnly ) - { AutoSizeColumn(col, setAsMin); - } width += GetColWidth(col); } @@ -10096,7 +10504,7 @@ void wxGrid::AutoSize() // scrollbar steps wxSize sizeFit( GetScrollX(size.x + m_extraWidth + 1) * m_scrollLineX, - GetScrollY(size.y + m_extraHeight + 1) * m_scrollLineY); + GetScrollY(size.y + m_extraHeight + 1) * m_scrollLineY ); // distribute the extra space between the columns/rows to avoid having // extra white space @@ -10185,7 +10593,7 @@ void wxGrid::AutoSizeColLabelSize( int col ) long w, h; // Hide the edit control, so it - // won't interfer with drag-shrinking. + // won't interfere with drag-shrinking. if ( IsCellEditControlShown() ) { HideCellEditControl(); @@ -10220,7 +10628,7 @@ wxSize wxGrid::DoGetBestSize() const height = 80; // Round up to a multiple the scroll rate - // NOTE: this still doesn't get rid of the scrollbars; + // NOTE: this still doesn't get rid of the scrollbars; // is there any magic incantation for that? int xpu, ypu; GetScrollPixelsPerUnit(&xpu, &ypu); @@ -10458,8 +10866,9 @@ wxArrayInt wxGrid::GetSelectedCols() const void wxGrid::ClearSelection() { - m_selectingTopLeft = wxGridNoCellCoords; - m_selectingBottomRight = wxGridNoCellCoords; + m_selectingTopLeft = + m_selectingBottomRight = + m_selectingKeyboard = wxGridNoCellCoords; if ( m_selection ) m_selection->ClearSelection(); }