X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e685e57bbd1eb01843ddda92e5825613be0971ca..5612a518581c13625ac3f77b0fc98bf306dc1544:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 02484668f6..2f85221fd1 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -1,4 +1,4 @@ -//////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// // Name: grid.cpp // Purpose: wxGrid and related classes // Author: Michael Bedward (based on code by Julian Smart, Robin Dunn) @@ -9,13 +9,6 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// - -#include "wx/defs.h" - -#if !defined(wxUSE_NEW_GRID) || !(wxUSE_NEW_GRID) -#include "gridg.cpp" -#else - #ifdef __GNUG__ #pragma implementation "grid.h" #endif @@ -23,10 +16,16 @@ // For compilers that support precompilation, includes "wx/wx.h". #include "wx/wxprec.h" +#include "wx/defs.h" + #ifdef __BORLANDC__ #pragma hdrstop #endif +#if !defined(wxUSE_NEW_GRID) || !(wxUSE_NEW_GRID) +#include "gridg.cpp" +#else + #ifndef WX_PRECOMP #include "wx/utils.h" #include "wx/dcclient.h" @@ -64,8 +63,8 @@ wxGridTableBase::~wxGridTableBase() bool wxGridTableBase::InsertRows( size_t pos, size_t numRows ) { - wxLogWarning( "Called grid table class function InsertRows(pos=%d, N=%d)\n" - "but your derived table class does not override this function", + wxLogWarning( wxT("Called grid table class function InsertRows(pos=%d, N=%d)\n" + "but your derived table class does not override this function"), pos, numRows ); return FALSE; @@ -73,8 +72,8 @@ bool wxGridTableBase::InsertRows( size_t pos, size_t numRows ) bool wxGridTableBase::AppendRows( size_t numRows ) { - wxLogWarning( "Called grid table class function AppendRows(N=%d)\n" - "but your derived table class does not override this function", + wxLogWarning( wxT("Called grid table class function AppendRows(N=%d)\n" + "but your derived table class does not override this function"), numRows ); return FALSE; @@ -82,8 +81,8 @@ bool wxGridTableBase::AppendRows( size_t numRows ) bool wxGridTableBase::DeleteRows( size_t pos, size_t numRows ) { - wxLogWarning( "Called grid table class function DeleteRows(pos=%d, N=%d)\n" - "but your derived table class does not override this function", + wxLogWarning( wxT("Called grid table class function DeleteRows(pos=%d, N=%d)\n" + "but your derived table class does not override this function"), pos, numRows ); return FALSE; @@ -91,8 +90,8 @@ bool wxGridTableBase::DeleteRows( size_t pos, size_t numRows ) bool wxGridTableBase::InsertCols( size_t pos, size_t numCols ) { - wxLogWarning( "Called grid table class function InsertCols(pos=%d, N=%d)\n" - "but your derived table class does not override this function", + wxLogWarning( wxT("Called grid table class function InsertCols(pos=%d, N=%d)\n" + "but your derived table class does not override this function"), pos, numCols ); return FALSE; @@ -100,8 +99,8 @@ bool wxGridTableBase::InsertCols( size_t pos, size_t numCols ) bool wxGridTableBase::AppendCols( size_t numCols ) { - wxLogWarning( "Called grid table class function AppendCols(N=%d)\n" - "but your derived table class does not override this function", + wxLogWarning( wxT("Called grid table class function AppendCols(N=%d)\n" + "but your derived table class does not override this function"), numCols ); return FALSE; @@ -109,8 +108,8 @@ bool wxGridTableBase::AppendCols( size_t numCols ) bool wxGridTableBase::DeleteCols( size_t pos, size_t numCols ) { - wxLogWarning( "Called grid table class function DeleteCols(pos=%d, N=%d)\n" - "but your derived table class does not override this function", + wxLogWarning( wxT("Called grid table class function DeleteCols(pos=%d, N=%d)\n" + "but your derived table class does not override this function"), pos, numCols ); return FALSE; @@ -187,7 +186,7 @@ wxGridTableMessage::wxGridTableMessage( wxGridTableBase *table, int id, // this is a magic incantation which must be done! #include -WX_DEFINE_OBJARRAY(wxGridStringArray); +WX_DEFINE_OBJARRAY(wxGridStringArray) IMPLEMENT_DYNAMIC_CLASS( wxGridStringTable, wxGridTableBase ) @@ -355,8 +354,8 @@ bool wxGridStringTable::DeleteRows( size_t pos, size_t numRows ) if ( pos >= curNumRows ) { - wxLogError( "Called wxGridStringTable::DeleteRows(pos=%d, N=%d)...\n" - "Pos value is invalid for present table with %d rows", + wxLogError( wxT("Called wxGridStringTable::DeleteRows(pos=%d, N=%d)...\n" + "Pos value is invalid for present table with %d rows"), pos, numRows, curNumRows ); return FALSE; } @@ -433,8 +432,8 @@ bool wxGridStringTable::AppendCols( size_t numCols ) { // TODO: something better than this ? // - wxLogError( "Unable to append cols to a grid table with no rows.\n" - "Call AppendRows() first" ); + wxLogError( wxT("Unable to append cols to a grid table with no rows.\n" + "Call AppendRows() first") ); return FALSE; } @@ -467,8 +466,8 @@ bool wxGridStringTable::DeleteCols( size_t pos, size_t numCols ) if ( pos >= curNumCols ) { - wxLogError( "Called wxGridStringTable::DeleteCols(pos=%d, N=%d)...\n" - "Pos value is invalid for present table with %d cols", + wxLogError( wxT("Called wxGridStringTable::DeleteCols(pos=%d, N=%d)...\n" + "Pos value is invalid for present table with %d cols"), pos, numCols, curNumCols ); return FALSE; } @@ -602,6 +601,8 @@ void wxGridTextCtrl::OnKeyDown( wxKeyEvent& ev ) case WXK_DOWN: case WXK_LEFT: case WXK_RIGHT: + case WXK_PRIOR: + case WXK_NEXT: case WXK_RETURN: if ( m_isCellControl ) { @@ -739,20 +740,24 @@ void wxGrid::Init() m_rowHeights.Alloc( m_numRows ); m_rowBottoms.Alloc( m_numRows ); + m_sumRowHeights = 0; for ( i = 0; i < m_numRows; i++ ) { m_rowHeights.Add( m_defaultRowHeight ); m_rowBottoms.Add( 0 ); // set by CalcDimensions() } - + m_sumRowHeights = m_defaultRowHeight * m_numRows; + m_colWidths.Alloc( m_numCols ); m_colRights.Alloc( m_numRows ); + m_sumColWidths = 0; for ( i = 0; i < m_numCols; i++ ) { m_colWidths.Add( m_defaultColWidth ); m_colRights.Add( 0 ); // set by CalcDimensions() } - + m_sumColWidths = m_defaultColWidth * m_numCols; + // TODO: improve this ? // m_defaultCellFont = this->GetFont(); @@ -805,10 +810,9 @@ void wxGrid::Init() wxGRID_CELLCTRL, "", wxPoint(1,1), - wxSize(1,1), - wxNO_BORDER + wxSize(1,1) #ifdef __WXMSW__ - | wxTE_MULTILINE | wxTE_NO_VSCROLL + , wxTE_MULTILINE | wxTE_NO_VSCROLL #endif ); @@ -816,9 +820,10 @@ void wxGrid::Init() m_cellEditCtrlEnabled = TRUE; m_editCtrlType = wxGRID_TEXTCTRL; - // Not really needed here, it gets called by OnSize() + // This is here in case OnSize does not get called when the grid is + // displayed // - // CalcDimensions(); + CalcDimensions(); } @@ -838,23 +843,8 @@ void wxGrid::CalcDimensions() m_top = 0; } - int bottom = m_top + m_colLabelHeight; - for ( i = m_scrollPosY; i < m_numRows; i++ ) - { - bottom += m_rowHeights[i]; - m_rowBottoms[i] = bottom; - } - - int right = m_left + m_rowLabelWidth; - for ( i = m_scrollPosX; i < m_numCols; i++ ) - { - right += m_colWidths[i]; - m_colRights[i] = right; - } - - // adjust the scroll bars + // check to see if either of the scroll bars are required // - int cw, ch; GetClientSize(&cw, &ch); @@ -870,58 +860,84 @@ void wxGrid::CalcDimensions() int check; for ( check = 0; check < 2; check++ ) { - if ( m_numRows > 0 && - m_rowBottoms[m_numRows-1] + horizScrollBarHeight > ch ) + if ( m_top + m_colLabelHeight + m_sumRowHeights + horizScrollBarHeight > ch ) { vertScrollBarWidth = m_scrollBarWidth; + } - m_wholeRowsVisible = 0; - for ( i = m_scrollPosY; i < m_numRows; i++ ) - { - // A partial row doesn't count, we still have to scroll to - // see the rest of it - if ( m_rowBottoms[i] + horizScrollBarHeight > ch ) break; + if ( m_left + m_rowLabelWidth + m_sumColWidths + vertScrollBarWidth > cw) + { + horizScrollBarHeight = m_scrollBarWidth; + } + } - m_wholeRowsVisible++ ; - } + + // if the window has been resized while scrolled then the scroll + // position might need to be adjusted... + // + bool adjustScrollPos = FALSE; + if ( !vertScrollBarWidth ) + { + if ( m_scrollPosY ) + { + adjustScrollPos = TRUE; + m_scrollPosY = 0; } - else + } + if ( !horizScrollBarHeight ) + { + if ( m_scrollPosX ) { - m_wholeRowsVisible = m_numRows - m_scrollPosY; - if ( m_scrollPosY ) - { - vertScrollBarWidth = m_scrollBarWidth; - } + adjustScrollPos = TRUE; + m_scrollPosX = 0; } - + } - if ( m_numCols && - m_colRights[m_numCols-1] + vertScrollBarWidth > cw) + + // calculate the coords of row bottom edges and col right edges + // + int bottom = m_top + m_colLabelHeight; + for ( i = m_scrollPosY; i < m_numRows; i++ ) + { + bottom += m_rowHeights[i]; + m_rowBottoms[i] = bottom; + } + + int right = m_left + m_rowLabelWidth; + for ( i = m_scrollPosX; i < m_numCols; i++ ) + { + right += m_colWidths[i]; + m_colRights[i] = right; + } + + + // check how many rows and cols are visible + // + m_wholeRowsVisible = 0; + if ( m_numRows > 0 ) + { + for ( i = m_scrollPosY; i < m_numRows; i++ ) { - horizScrollBarHeight = m_scrollBarWidth; + // A partial row doesn't count, we still have to scroll to + // see the rest of it + if ( m_rowBottoms[i] + horizScrollBarHeight > ch ) break; - m_wholeColsVisible = 0; - for ( i = m_scrollPosX; i < m_numCols; i++ ) - { - // A partial col doesn't count, we still have to scroll to - // see the rest of it - if ( m_colRights[i] + vertScrollBarWidth > cw ) break; - - m_wholeColsVisible++ ; - } + m_wholeRowsVisible++ ; } - else + } + + m_wholeColsVisible = 0; + if ( m_numCols ) + { + for ( i = m_scrollPosX; i < m_numCols; i++ ) { - // we can see the right-most column - // - m_wholeColsVisible = m_numCols - m_scrollPosX; - if ( m_scrollPosX ) - { - horizScrollBarHeight = m_scrollBarWidth; - } + // A partial col doesn't count, we still have to scroll to + // see the rest of it + if ( m_colRights[i] + vertScrollBarWidth > cw ) break; + + m_wholeColsVisible++ ; } } - if ( m_vertScrollBar ) { @@ -979,6 +995,12 @@ void wxGrid::CalcDimensions() m_right = wxMin( m_colRights[m_numCols-1], cw - vertScrollBarWidth ); } + + // if the scroll position was adjusted (due to a window resize) + // ensure that the cell highlight and edit control are displayed + // correctly + // + if ( adjustScrollPos ) SelectCell( m_currentCellCoords ); } @@ -1007,6 +1029,7 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) { m_rowHeights.Insert( m_defaultRowHeight, pos ); m_rowBottoms.Insert( 0, pos ); + m_sumRowHeights += m_defaultRowHeight; } m_numRows += numRows; CalcDimensions(); @@ -1020,6 +1043,7 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) { m_rowHeights.Add( m_defaultRowHeight ); m_rowBottoms.Add( 0 ); + m_sumRowHeights += m_defaultRowHeight; } m_numRows += numRows; CalcDimensions(); @@ -1032,6 +1056,7 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) int numRows = msg.GetCommandInt2(); for ( i = 0; i < numRows; i++ ) { + m_sumRowHeights -= m_rowHeights[ pos ]; m_rowHeights.Remove( pos ); m_rowBottoms.Remove( pos ); } @@ -1065,6 +1090,7 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) { m_colWidths.Insert( m_defaultColWidth, pos ); m_colRights.Insert( 0, pos ); + m_sumColWidths += m_defaultColWidth; } m_numCols += numCols; CalcDimensions(); @@ -1078,6 +1104,7 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) { m_colWidths.Add( m_defaultColWidth ); m_colRights.Add( 0 ); + m_sumColWidths += m_defaultColWidth; } m_numCols += numCols; CalcDimensions(); @@ -1090,6 +1117,7 @@ bool wxGrid::Redimension( wxGridTableMessage& msg ) int numCols = msg.GetCommandInt2(); for ( i = 0; i < numCols; i++ ) { + m_sumColWidths -= m_colWidths[ pos ]; m_colWidths.Remove( pos ); m_colRights.Remove( pos ); } @@ -1133,8 +1161,8 @@ bool wxGrid::SendEvent( const wxEventType type, int row, int col, wxMouseEvent& mouseEv ) { - if ( type == EVT_WXGRID_ROW_SIZE || - type == EVT_WXGRID_COL_SIZE ) + if ( type == EVT_GRID_ROW_SIZE || + type == EVT_GRID_COL_SIZE ) { int rowOrCol = (row == -1 ? col : row); @@ -1150,7 +1178,7 @@ bool wxGrid::SendEvent( const wxEventType type, return GetEventHandler()->ProcessEvent(gridEvt); } - else if ( type == EVT_WXGRID_RANGE_SELECT ) + else if ( type == EVT_GRID_RANGE_SELECT ) { wxGridRangeSelectEvent gridEvt( GetId(), type, @@ -1187,8 +1215,8 @@ bool wxGrid::SendEvent( const wxEventType type, bool wxGrid::SendEvent( const wxEventType type, int row, int col ) { - if ( type == EVT_WXGRID_ROW_SIZE || - type == EVT_WXGRID_COL_SIZE ) + if ( type == EVT_GRID_ROW_SIZE || + type == EVT_GRID_COL_SIZE ) { int rowOrCol = (row == -1 ? col : row); @@ -1211,7 +1239,7 @@ bool wxGrid::SendEvent( const wxEventType type, } -void wxGrid::OnPaint( wxPaintEvent& ev ) +void wxGrid::OnPaint( wxPaintEvent& WXUNUSED(ev) ) { wxPaintDC dc( this ); @@ -1259,9 +1287,9 @@ void wxGrid::OnPaint( wxPaintEvent& ev ) } -void wxGrid::OnSize( wxSizeEvent& ev ) +void wxGrid::OnSize( wxSizeEvent& WXUNUSED(ev) ) { - CalcDimensions(); + if ( m_created ) CalcDimensions(); } @@ -1293,9 +1321,29 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) { SelectBlock( cellCoords, cellCoords ); } - else if ( !IsInSelection( cellCoords ) ) + else { - SelectBlock( m_currentCellCoords, cellCoords ); + // check for the mouse being outside the cell area + // (we still want to let the user grow the selected block) + // + if ( cellCoords.GetCol() == -1 ) + { + if ( x >= m_right ) + cellCoords.SetCol( m_numCols-1 ); + else + cellCoords.SetCol( m_scrollPosX ); + } + + if ( cellCoords.GetRow() == -1 ) + { + if ( y >= m_bottom ) + cellCoords.SetRow( m_numRows-1 ); + else + cellCoords.SetRow( m_scrollPosY ); + } + + if ( !IsInSelection( cellCoords ) ) + SelectBlock( m_currentCellCoords, cellCoords ); } } } @@ -1380,7 +1428,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) if ( YToEdgeOfRow(y) < 0 ) { row = YToRow(y); - if ( !SendEvent( EVT_WXGRID_LABEL_LEFT_CLICK, row, col, ev ) ) + if ( !SendEvent( EVT_GRID_LABEL_LEFT_CLICK, row, col, ev ) ) { SelectRow( row, ev.ShiftDown() ); m_cursorMode = WXGRID_CURSOR_SELECT_ROW; @@ -1398,7 +1446,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) if ( XToEdgeOfCol(x) < 0 ) { col = XToCol(x); - if ( !SendEvent( EVT_WXGRID_LABEL_LEFT_CLICK, row, col, ev ) ) + if ( !SendEvent( EVT_GRID_LABEL_LEFT_CLICK, row, col, ev ) ) { SelectCol( col, ev.ShiftDown() ); m_cursorMode = WXGRID_CURSOR_SELECT_COL; @@ -1411,7 +1459,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) { // leave both row and col as -1 // - if ( !SendEvent( EVT_WXGRID_LABEL_LEFT_CLICK, row, col, ev ) ) + if ( !SendEvent( EVT_GRID_LABEL_LEFT_CLICK, row, col, ev ) ) { SelectAll(); } @@ -1421,7 +1469,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) case WXGRID_CELL: { XYToCell( x, y, cellCoords ); - if ( !SendEvent( EVT_WXGRID_CELL_LEFT_CLICK, + if ( !SendEvent( EVT_GRID_CELL_LEFT_CLICK, cellCoords.GetRow(), cellCoords.GetCol(), ev ) ) @@ -1460,7 +1508,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) if ( YToEdgeOfRow(y) < 0 ) { row = YToRow(y); - SendEvent( EVT_WXGRID_LABEL_LEFT_DCLICK, row, col, ev ); + SendEvent( EVT_GRID_LABEL_LEFT_DCLICK, row, col, ev ); } } break; @@ -1474,7 +1522,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) if ( XToEdgeOfCol(x) < 0 ) { col = XToCol(x); - SendEvent( EVT_WXGRID_LABEL_LEFT_DCLICK, row, col, ev ); + SendEvent( EVT_GRID_LABEL_LEFT_DCLICK, row, col, ev ); } } break; @@ -1483,14 +1531,14 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) { // leave both row and col as -1 // - SendEvent( EVT_WXGRID_LABEL_LEFT_DCLICK, row, col, ev ); + SendEvent( EVT_GRID_LABEL_LEFT_DCLICK, row, col, ev ); } break; case WXGRID_CELL: { XYToCell( x, y, cellCoords ); - SendEvent( EVT_WXGRID_CELL_LEFT_DCLICK, + SendEvent( EVT_GRID_CELL_LEFT_DCLICK, cellCoords.GetRow(), cellCoords.GetCol(), ev ); @@ -1526,8 +1574,11 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) int top = m_top + m_colLabelHeight; if ( m_dragRowOrCol > 0 ) top = m_rowBottoms[m_dragRowOrCol-1]; + + m_sumRowHeights -= m_rowHeights[ m_dragRowOrCol ]; m_rowHeights[m_dragRowOrCol] = wxMax( ev.GetY() - top, WXGRID_MIN_ROW_HEIGHT ); + m_sumRowHeights += m_rowHeights[ m_dragRowOrCol ]; CalcDimensions(); ShowCellEditControl(); Refresh(); @@ -1535,7 +1586,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) // Note: we are ending the event *after* doing // default processing in this case // - SendEvent( EVT_WXGRID_ROW_SIZE, m_dragRowOrCol, -1, ev ); + SendEvent( EVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, ev ); } } break; @@ -1554,8 +1605,12 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) int left = m_left + m_rowLabelWidth; if ( m_dragRowOrCol > 0 ) left = m_colRights[m_dragRowOrCol-1]; + + m_sumColWidths -= m_colWidths[m_dragRowOrCol]; m_colWidths[m_dragRowOrCol] = wxMax( ev.GetX() - left, WXGRID_MIN_COL_WIDTH ); + m_sumColWidths += m_colWidths[m_dragRowOrCol]; + CalcDimensions(); ShowCellEditControl(); Refresh(); @@ -1563,7 +1618,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) // Note: we are ending the event *after* doing // default processing in this case // - SendEvent( EVT_WXGRID_COL_SIZE, -1, m_dragRowOrCol, ev ); + SendEvent( EVT_GRID_COL_SIZE, -1, m_dragRowOrCol, ev ); } } break; @@ -1575,7 +1630,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) // Note: we are ending the event *after* doing // default processing in this case // - SendEvent( EVT_WXGRID_RANGE_SELECT, -1, -1, ev ); + SendEvent( EVT_GRID_RANGE_SELECT, -1, -1, ev ); } } break; @@ -1599,7 +1654,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) case WXGRID_ROWLABEL: { row = YToRow(y); - if ( !SendEvent( EVT_WXGRID_LABEL_RIGHT_CLICK, row, col, ev ) ) + if ( !SendEvent( EVT_GRID_LABEL_RIGHT_CLICK, row, col, ev ) ) { // TODO: default processing ? } @@ -1609,7 +1664,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) case WXGRID_COLLABEL: { col = XToCol(x); - if ( !SendEvent( EVT_WXGRID_LABEL_RIGHT_CLICK, row, col, ev ) ) + if ( !SendEvent( EVT_GRID_LABEL_RIGHT_CLICK, row, col, ev ) ) { // TODO: default processing ? } @@ -1620,7 +1675,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) { // leave both row and col as -1 // - if ( !SendEvent( EVT_WXGRID_LABEL_RIGHT_CLICK, row, col, ev ) ) + if ( !SendEvent( EVT_GRID_LABEL_RIGHT_CLICK, row, col, ev ) ) { // TODO: default processing ? } @@ -1630,7 +1685,7 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) case WXGRID_CELL: { XYToCell( x, y, cellCoords ); - if ( !SendEvent( EVT_WXGRID_CELL_RIGHT_CLICK, + if ( !SendEvent( EVT_GRID_CELL_RIGHT_CLICK, cellCoords.GetRow(), cellCoords.GetCol(), ev ) ) @@ -1663,14 +1718,14 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) case WXGRID_ROWLABEL: { row = YToRow(y); - SendEvent( EVT_WXGRID_LABEL_RIGHT_DCLICK, row, col, ev ); + SendEvent( EVT_GRID_LABEL_RIGHT_DCLICK, row, col, ev ); } break; case WXGRID_COLLABEL: { col = XToCol(x); - SendEvent( EVT_WXGRID_LABEL_RIGHT_DCLICK, row, col, ev ); + SendEvent( EVT_GRID_LABEL_RIGHT_DCLICK, row, col, ev ); } break; @@ -1678,14 +1733,14 @@ void wxGrid::OnMouse( wxMouseEvent& ev ) { // leave both row and col as -1 // - SendEvent( EVT_WXGRID_LABEL_RIGHT_DCLICK, row, col, ev ); + SendEvent( EVT_GRID_LABEL_RIGHT_DCLICK, row, col, ev ); } break; case WXGRID_CELL: { XYToCell( x, y, cellCoords ); - SendEvent( EVT_WXGRID_CELL_RIGHT_DCLICK, + SendEvent( EVT_GRID_CELL_RIGHT_DCLICK, cellCoords.GetRow(), cellCoords.GetCol(), ev ); @@ -1771,7 +1826,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& ev ) { // shouldn't be here - we are going round in circles... // - wxLogFatalError( "wxGrid::OnKeyDown called while alread active" ); + wxLogFatalError( wxT("wxGrid::OnKeyDown called while alread active") ); } m_inOnKeyDown = TRUE; @@ -1860,6 +1915,14 @@ void wxGrid::OnKeyDown( wxKeyEvent& ev ) } break; + case WXK_PRIOR: + MovePageUp(); + break; + + case WXK_NEXT: + MovePageDown(); + break; + default: // now try the cell edit control // @@ -1904,20 +1967,38 @@ void wxGrid::OnText( wxKeyEvent& ev ) break; } } - else if ( ctrl == m_topEditCtrl && - IsCellEditControlEnabled() ) + else if ( ctrl == m_topEditCtrl ) { - switch ( m_editCtrlType ) + if ( IsCellEditControlEnabled() ) { - case wxGRID_TEXTCTRL: - ((wxTextCtrl *)m_cellEditCtrl)-> - SetValue(((wxTextCtrl *)ctrl)->GetValue()); - break; - - case wxGRID_COMBOBOX: - ((wxComboBox *)m_cellEditCtrl)-> - SetValue(((wxComboBox *)ctrl)->GetValue()); - break; + switch ( m_editCtrlType ) + { + case wxGRID_TEXTCTRL: + ((wxTextCtrl *)m_cellEditCtrl)-> + SetValue(((wxTextCtrl *)ctrl)->GetValue()); + break; + + case wxGRID_COMBOBOX: + ((wxComboBox *)m_cellEditCtrl)-> + SetValue(((wxComboBox *)ctrl)->GetValue()); + break; + } + } + else + { + // in the case when in-place editing is turned off we just want to + // echo the text changes in the cell but not yet update the grid table + // + switch ( m_editCtrlType ) + { + case wxGRID_TEXTCTRL: + DrawCellValue( m_currentCellCoords, ((wxTextCtrl *)ctrl)->GetValue() ); + break; + + case wxGRID_COMBOBOX: + DrawCellValue( m_currentCellCoords, ((wxComboBox *)ctrl)->GetValue() ); + break; + } } } } @@ -1956,6 +2037,12 @@ void wxGrid::OnGridScroll( wxScrollEvent& ev ) void wxGrid::SelectCell( const wxGridCellCoords& coords ) { + if ( SendEvent( EVT_GRID_SELECT_CELL, coords.GetRow(), coords.GetCol() ) ) + { + // the event has been intercepted - do nothing + return; + } + wxClientDC dc( this ); if ( m_currentCellCoords != wxGridNoCellCoords ) @@ -2040,7 +2127,10 @@ void wxGrid::SetEditControlValue( const wxString& value ) if ( m_table ) { wxString s; - s = ( value == wxEmptyString ? GetCellValue(m_currentCellCoords) : value ); + if ( !value ) + s = GetCellValue(m_currentCellCoords); + else + s = value; if ( IsTopEditControlEnabled() ) { @@ -2142,7 +2232,7 @@ void wxGrid::SaveEditControlValue() if ( valueChanged ) { - SendEvent( EVT_WXGRID_CELL_CHANGE, + SendEvent( EVT_GRID_CELL_CHANGE, m_currentCellCoords.GetRow(), m_currentCellCoords.GetCol() ); } @@ -2363,6 +2453,54 @@ bool wxGrid::MoveCursorRight() return FALSE; } +bool wxGrid::MovePageUp() +{ + if ( m_currentCellCoords != wxGridNoCellCoords && + m_scrollPosY > 0 ) + { + int row = m_currentCellCoords.GetRow(); + int y = m_rowBottoms[ row ] - m_rowHeights[ row ]; + while ( row > 0 ) + { + if ( y + m_rowHeights[row-1] > m_bottom ) break; + y += m_rowHeights[ --row ]; + } + SetVerticalScrollPos( row ); + + SelectCell( row, m_currentCellCoords.GetCol() ); + return TRUE; + } + + return FALSE; +} + +bool wxGrid::MovePageDown() +{ + if ( m_currentCellCoords != wxGridNoCellCoords && + m_scrollPosY + m_wholeRowsVisible < m_numRows ) + { + if ( m_wholeRowsVisible > 0 ) + { + SetVerticalScrollPos( m_scrollPosY + m_wholeRowsVisible ); + } + else if ( m_scrollPosY < m_numRows - 1 ) + { + SetVerticalScrollPos( m_scrollPosY + 1 ); + } + else + { + return FALSE; + } + + // m_scrollPosY will have been updated + // + SelectCell( m_scrollPosY, m_currentCellCoords.GetCol() ); + return TRUE; + } + + return FALSE; +} + bool wxGrid::MoveCursorUpBlock() { if ( m_table && @@ -2927,7 +3065,11 @@ void wxGrid::DrawCellBackground( wxDC& dc, const wxRect& rect, int row, int col } -void wxGrid::DrawCellValue( wxDC& dc, const wxRect& rect, int row, int col ) +// This draws a text value in the given cell. If useValueArg is FALSE +// (the default) then the grid table value will be used +// +void wxGrid::DrawCellValue( wxDC& dc, const wxRect& rect, int row, int col, + const wxString& value, bool useValueArg ) { wxRect rect2; rect2 = rect; @@ -2954,7 +3096,37 @@ void wxGrid::DrawCellValue( wxDC& dc, const wxRect& rect, int row, int col ) int hAlign, vAlign; GetCellAlignment( row, col, &hAlign, &vAlign ); - DrawTextRectangle( dc, GetCellValue( row, col ), rect2, hAlign, vAlign ); + + if ( useValueArg ) + { + DrawTextRectangle( dc, value, rect2, hAlign, vAlign ); + } + else + { + DrawTextRectangle( dc, GetCellValue( row, col ), rect2, hAlign, vAlign ); + } +} + + +// this is used to echo text being entered into the top edit control when +// in-place editing is turned off +// +void wxGrid::DrawCellValue( const wxGridCellCoords& coords, const wxString& value ) +{ + if ( IsVisible( coords ) ) + { + int row = coords.GetRow(); + int col = coords.GetCol(); + wxRect rect; + rect.x = m_colRights[ col ] - m_colWidths[ col ]; + rect.y = m_rowBottoms[ row ] - m_rowHeights[ row ]; + rect.width = m_colWidths[ col ]; + rect.height = m_rowHeights[ row ]; + + wxClientDC dc( this ); + DrawCellBackground( dc, rect, row, col ); + DrawCellValue( dc, rect, row, col, value, TRUE ); + } } @@ -2976,13 +3148,13 @@ void wxGrid::DrawCellHighlight( wxDC& dc, int row, int col ) y = m_rowBottoms[row] - m_rowHeights[row]; if ( y >= ch ) return; - dc.SetLogicalFunction( wxXOR ); + dc.SetLogicalFunction( wxINVERT ); dc.SetPen( wxPen(GetCellHighlightColour(), 2, wxSOLID) ); dc.SetBrush( *wxTRANSPARENT_BRUSH ); - dc.DrawRectangle( x, y, - m_colWidths[col] + 2, - m_rowHeights[row] + 2 ); + dc.DrawRectangle( x-2, y-2, + m_colWidths[col] + 6, + m_rowHeights[row] + 6 ); dc.SetLogicalFunction( wxCOPY ); } @@ -3045,7 +3217,6 @@ void wxGrid::DrawTextRectangle( wxDC& dc, int horizAlign, int vertAlign ) { - int i; long textWidth, textHeight; long lineWidth, lineHeight; wxArrayString lines; @@ -3123,7 +3294,7 @@ void wxGrid::DrawTextRectangle( wxDC& dc, break; } - for ( i = 0; i < lines.GetCount(); i++ ) + for ( size_t i = 0; i < lines.GetCount(); i++ ) { dc.DrawText( lines[i], (long)x, (long)y ); y += lineHeight; @@ -3141,10 +3312,10 @@ void wxGrid::DrawTextRectangle( wxDC& dc, void wxGrid::StringToLines( const wxString& value, wxArrayString& lines ) { // TODO: this won't work for WXMAC ? (lines end with '\r') - // + // => use wxTextFile functions then (VZ) int startPos = 0; int pos; - while ( startPos < value.Length() ) + while ( startPos < (int)value.Length() ) { pos = value.Mid(startPos).Find( '\n' ); if ( pos < 0 ) @@ -3168,7 +3339,7 @@ void wxGrid::StringToLines( const wxString& value, wxArrayString& lines ) } startPos += pos+1; } - if ( startPos < value.Length() ) + if ( startPos < (int)value.Length() ) { lines.Add( value.Mid( startPos ) ); } @@ -3183,7 +3354,7 @@ void wxGrid::GetTextBoxSize( wxDC& dc, long h = 0; long lineW, lineH; - int i; + size_t i; for ( i = 0; i < lines.GetCount(); i++ ) { dc.GetTextExtent( lines[i], &lineW, &lineH ); @@ -3243,7 +3414,7 @@ bool wxGrid::CreateGrid( int numRows, int numCols ) { if ( m_created ) { - wxLogError( "wxGrid::CreateGrid(numRows, numCols) called more than once" ); + wxLogError( wxT("wxGrid::CreateGrid(numRows, numCols) called more than once") ); return FALSE; } else @@ -3283,7 +3454,7 @@ bool wxGrid::InsertRows( int pos, int numRows, bool WXUNUSED(updateLabels) ) if ( !m_created ) { - wxLogError( "Called wxGrid::InsertRows() before calling CreateGrid()" ); + wxLogError( wxT("Called wxGrid::InsertRows() before calling CreateGrid()") ); return FALSE; } @@ -3296,8 +3467,26 @@ bool wxGrid::InsertRows( int pos, int numRows, bool WXUNUSED(updateLabels) ) // if ( ok ) { + if ( m_numCols == 0 ) + { + m_table->AppendCols( WXGRID_DEFAULT_NUMBER_COLS ); + // + // TODO: perhaps instead of appending the default number of cols + // we should remember what the last non-zero number of cols was ? + // + } + + if ( m_currentCellCoords == wxGridNoCellCoords ) + { + // if we have just inserted cols into an empty grid the current + // cell will be undefined... + // + SelectCell( 0, 0 ); + } + if ( !GetBatchCount() ) Refresh(); } + SetEditControlValue(); return ok; } @@ -3313,12 +3502,20 @@ bool wxGrid::AppendRows( int numRows, bool WXUNUSED(updateLabels) ) if ( !m_created ) { - wxLogError( "Called wxGrid::AppendRows() before calling CreateGrid()" ); + wxLogError( wxT("Called wxGrid::AppendRows() before calling CreateGrid()") ); return FALSE; } if ( m_table && m_table->AppendRows( numRows ) ) { + if ( m_currentCellCoords == wxGridNoCellCoords ) + { + // if we have just inserted cols into an empty grid the current + // cell will be undefined... + // + SelectCell( 0, 0 ); + } + // the table will have sent the results of the append row // operation to this view object as a grid table message // @@ -3337,7 +3534,7 @@ bool wxGrid::DeleteRows( int pos, int numRows, bool WXUNUSED(updateLabels) ) if ( !m_created ) { - wxLogError( "Called wxGrid::DeleteRows() before calling CreateGrid()" ); + wxLogError( wxT("Called wxGrid::DeleteRows() before calling CreateGrid()") ); return FALSE; } @@ -3366,7 +3563,7 @@ bool wxGrid::InsertCols( int pos, int numCols, bool WXUNUSED(updateLabels) ) if ( !m_created ) { - wxLogError( "Called wxGrid::InsertCols() before calling CreateGrid()" ); + wxLogError( wxT("Called wxGrid::InsertCols() before calling CreateGrid()") ); return FALSE; } @@ -3374,13 +3571,23 @@ bool wxGrid::InsertCols( int pos, int numCols, bool WXUNUSED(updateLabels) ) { HideCellEditControl(); bool ok = m_table->InsertCols( pos, numCols ); + + // the table will have sent the results of the insert col + // operation to this view object as a grid table message + // if ( ok ) { - // the table will have sent the results of the insert col - // operation to this view object as a grid table message - // + if ( m_currentCellCoords == wxGridNoCellCoords ) + { + // if we have just inserted cols into an empty grid the current + // cell will be undefined... + // + SelectCell( 0, 0 ); + } + if ( !GetBatchCount() ) Refresh(); } + SetEditControlValue(); return ok; } @@ -3396,7 +3603,7 @@ bool wxGrid::AppendCols( int numCols, bool WXUNUSED(updateLabels) ) if ( !m_created ) { - wxLogError( "Called wxGrid::AppendCols() before calling CreateGrid()" ); + wxLogError( wxT("Called wxGrid::AppendCols() before calling CreateGrid()") ); return FALSE; } @@ -3405,6 +3612,13 @@ bool wxGrid::AppendCols( int numCols, bool WXUNUSED(updateLabels) ) // the table will have sent the results of the append col // operation to this view object as a grid table message // + if ( m_currentCellCoords == wxGridNoCellCoords ) + { + // if we have just inserted cols into an empty grid the current + // cell will be undefined... + // + SelectCell( 0, 0 ); + } if ( !GetBatchCount() ) Refresh(); return TRUE; } @@ -3420,7 +3634,7 @@ bool wxGrid::DeleteCols( int pos, int numCols, bool WXUNUSED(updateLabels) ) if ( !m_created ) { - wxLogError( "Called wxGrid::DeleteCols() before calling CreateGrid()" ); + wxLogError( wxT("Called wxGrid::DeleteCols() before calling CreateGrid()") ); return FALSE; } @@ -3486,6 +3700,9 @@ void wxGrid::EnableCellEditControl( bool enable ) if ( m_cellEditCtrl && enable != m_cellEditCtrlEnabled ) { + wxClientDC dc( this ); + + HideCurrentCellHighlight( dc ); HideCellEditControl(); SaveEditControlValue(); @@ -3493,6 +3710,7 @@ void wxGrid::EnableCellEditControl( bool enable ) SetEditControlValue(); ShowCellEditControl(); + ShowCurrentCellHighlight( dc ); } } @@ -3674,7 +3892,7 @@ wxColour wxGrid::GetDefaultCellBackgroundColour() return wxColour( 255, 255, 255 ); } -wxColour wxGrid::GetCellBackgroundColour( int row, int col ) +wxColour wxGrid::GetCellBackgroundColour( int WXUNUSED(row), int WXUNUSED(col) ) { // TODO: replace this temp test code // @@ -3688,7 +3906,7 @@ wxColour wxGrid::GetDefaultCellTextColour() return wxColour( 0, 0, 0 ); } -wxColour wxGrid::GetCellTextColour( int row, int col ) +wxColour wxGrid::GetCellTextColour( int WXUNUSED(row), int WXUNUSED(col) ) { // TODO: replace this temp test code // @@ -3709,7 +3927,7 @@ wxFont wxGrid::GetDefaultCellFont() return m_defaultCellFont; } -wxFont wxGrid::GetCellFont( int row, int col ) +wxFont wxGrid::GetCellFont( int WXUNUSED(row), int WXUNUSED(col) ) { // TODO: replace this temp test code // @@ -3724,7 +3942,7 @@ void wxGrid::GetDefaultCellAlignment( int *horiz, int *vert ) *vert = wxTOP; } -void wxGrid::GetCellAlignment( int row, int col, int *horiz, int *vert ) +void wxGrid::GetCellAlignment( int WXUNUSED(row), int WXUNUSED(col), int *horiz, int *vert ) { // TODO: replace this temp test code // @@ -3746,6 +3964,7 @@ void wxGrid::SetDefaultRowSize( int height, bool resizeExistingRows ) { m_rowHeights[row] = m_defaultRowHeight; } + m_sumRowHeights = m_defaultRowHeight * m_numRows; CalcDimensions(); if ( !GetBatchCount() ) Refresh(); } @@ -3755,14 +3974,16 @@ void wxGrid::SetRowSize( int row, int height ) { if ( row >= 0 && row < m_numRows ) { + m_sumRowHeights -= m_rowHeights[row]; m_rowHeights[row] = wxMax( 0, height ); + m_sumRowHeights += m_rowHeights[row]; CalcDimensions(); if ( !GetBatchCount() ) Refresh(); // Note: we are ending the event *after* doing // default processing in this case // - SendEvent( EVT_WXGRID_ROW_SIZE, + SendEvent( EVT_GRID_ROW_SIZE, row, -1 ); } else @@ -3785,6 +4006,7 @@ void wxGrid::SetDefaultColSize( int width, bool resizeExistingCols ) { m_colWidths[col] = m_defaultColWidth; } + m_sumColWidths = m_defaultColWidth * m_numCols; CalcDimensions(); if ( !GetBatchCount() ) Refresh(); } @@ -3794,14 +4016,16 @@ void wxGrid::SetColSize( int col, int width ) { if ( col >= 0 && col < m_numCols ) { + m_sumColWidths -= m_colWidths[col]; m_colWidths[col] = wxMax( 0, width ); + m_sumColWidths += m_colWidths[col]; CalcDimensions(); if ( !GetBatchCount() ) Refresh(); // Note: we are ending the event *after* doing // default processing in this case // - SendEvent( EVT_WXGRID_COL_SIZE, + SendEvent( EVT_GRID_COL_SIZE, -1, col ); } else @@ -3816,7 +4040,7 @@ void wxGrid::SetDefaultCellBackgroundColour( const wxColour& ) // } -void wxGrid::SetCellBackgroundColour( int row, int col, const wxColour& ) +void wxGrid::SetCellBackgroundColour( int WXUNUSED(row), int WXUNUSED(col), const wxColour& ) { // TODO: everything !!! // @@ -3828,7 +4052,7 @@ void wxGrid::SetDefaultCellTextColour( const wxColour& ) // } -void wxGrid::SetCellTextColour( int row, int col, const wxColour& ) +void wxGrid::SetCellTextColour( int WXUNUSED(row), int WXUNUSED(col), const wxColour& ) { // TODO: everything !!! // @@ -3846,19 +4070,19 @@ void wxGrid::SetDefaultCellFont( const wxFont& ) // } -void wxGrid::SetCellFont( int row, int col, const wxFont& ) +void wxGrid::SetCellFont( int WXUNUSED(row), int WXUNUSED(col), const wxFont& ) { // TODO: everything !!! // } -void wxGrid::SetDefaultCellAlignment( int horiz, int vert ) +void wxGrid::SetDefaultCellAlignment( int WXUNUSED(horiz), int WXUNUSED(vert) ) { // TODO: everything !!! // } -void wxGrid::SetCellAlignment( int row, int col, int horiz, int vert ) +void wxGrid::SetCellAlignment( int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(horiz), int WXUNUSED(vert) ) { // TODO: everything !!! // @@ -4040,7 +4264,7 @@ void wxGrid::SelectRow( int row, bool addToSelected ) } wxGridRangeSelectEvent gridEvt( GetId(), - EVT_WXGRID_RANGE_SELECT, + EVT_GRID_RANGE_SELECT, this, m_selectedTopLeft, m_selectedBottomRight ); @@ -4077,7 +4301,7 @@ void wxGrid::SelectCol( int col, bool addToSelected ) } wxGridRangeSelectEvent gridEvt( GetId(), - EVT_WXGRID_RANGE_SELECT, + EVT_GRID_RANGE_SELECT, this, m_selectedTopLeft, m_selectedBottomRight ); @@ -4119,7 +4343,7 @@ void wxGrid::SelectBlock( int topRow, int leftCol, int bottomRow, int rightCol ) if ( !m_isDragging ) { wxGridRangeSelectEvent gridEvt( GetId(), - EVT_WXGRID_RANGE_SELECT, + EVT_GRID_RANGE_SELECT, this, m_selectedTopLeft, m_selectedBottomRight );