+ 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 ) )
+ {
+ // try local handlers
+ //
+ switch ( event.KeyCode() )
+ {
+ case WXK_UP:
+ if ( event.ControlDown() )
+ {
+ MoveCursorUpBlock();
+ }
+ else
+ {
+ MoveCursorUp();
+ }
+ break;
+
+ case WXK_DOWN:
+ if ( event.ControlDown() )
+ {
+ MoveCursorDownBlock();
+ }
+ else
+ {
+ MoveCursorDown();
+ }
+ break;
+
+ case WXK_LEFT:
+ if ( event.ControlDown() )
+ {
+ MoveCursorLeftBlock();
+ }
+ else
+ {
+ MoveCursorLeft();
+ }
+ break;
+
+ case WXK_RIGHT:
+ if ( event.ControlDown() )
+ {
+ MoveCursorRightBlock();
+ }
+ else
+ {
+ MoveCursorRight();
+ }
+ break;
+
+ case WXK_SPACE:
+ if ( !IsEditable() )
+ {
+ MoveCursorRight();
+ }
+ else
+ {
+ event.Skip();
+ }
+ break;
+
+ case WXK_RETURN:
+ if ( event.ControlDown() )
+ {
+ event.Skip(); // to let the edit control have the return
+ }
+ else
+ {
+ MoveCursorDown();
+ }
+ break;
+
+ case WXK_HOME:
+ if ( event.ControlDown() )
+ {
+ MakeCellVisible( 0, 0 );
+ SetCurrentCell( 0, 0 );
+ }
+ else
+ {
+ event.Skip();
+ }
+ break;
+
+ case WXK_END:
+ if ( event.ControlDown() )
+ {
+ MakeCellVisible( m_numRows-1, m_numCols-1 );
+ SetCurrentCell( m_numRows-1, m_numCols-1 );
+ }
+ else
+ {
+ event.Skip();
+ }
+ break;
+
+ case WXK_PRIOR:
+ MovePageUp();
+ break;
+
+ case WXK_NEXT:
+ MovePageDown();
+ break;
+
+ default:
+ // now try the cell edit control
+ //
+ if ( IsCellEditControlEnabled() )
+ {
+ event.SetEventObject( m_cellEditCtrl );
+ m_cellEditCtrl->GetEventHandler()->ProcessEvent( event );
+ }
+ break;
+ }
+ }
+
+ m_inOnKeyDown = FALSE;
+}
+
+
+void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
+{
+ if ( SendEvent( EVT_GRID_SELECT_CELL, coords.GetRow(), coords.GetCol() ) )
+ {
+ // the event has been intercepted - do nothing
+ return;
+ }
+
+ if ( m_displayed &&
+ m_currentCellCoords != wxGridNoCellCoords )
+ {
+ HideCellEditControl();
+ SaveEditControlValue();
+ }
+
+ m_currentCellCoords = coords;
+
+ SetEditControlValue();
+
+ if ( m_displayed )
+ {
+ ShowCellEditControl();
+
+ if ( IsSelection() )
+ {
+ wxRect r( SelectionToDeviceRect() );
+ ClearSelection();
+ if ( !GetBatchCount() ) m_gridWin->Refresh( FALSE, &r );
+ }
+ }
+}
+
+
+//
+// ------ functions to get/send data (see also public functions)
+//
+
+bool wxGrid::GetModelValues()
+{
+ if ( m_table )
+ {
+ // all we need to do is repaint the grid
+ //
+ m_gridWin->Refresh();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+bool wxGrid::SetModelValues()
+{
+ int row, col;
+
+ if ( m_table )
+ {
+ for ( row = 0; row < m_numRows; row++ )
+ {
+ for ( col = 0; col < m_numCols; col++ )
+ {
+ m_table->SetValue( row, col, GetCellValue(row, col) );
+ }
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+
+// Note - this function only draws cells that are in the list of
+// exposed cells (usually set from the update region by
+// CalcExposedCells)
+//
+void wxGrid::DrawGridCellArea( wxDC& dc )
+{
+ if ( !m_numRows || !m_numCols ) return;
+
+ size_t i;
+ size_t numCells = m_cellsExposed.GetCount();
+
+ for ( i = 0; i < numCells; i++ )
+ {
+ DrawCell( dc, m_cellsExposed[i] );
+ }
+}
+
+
+void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords )
+{
+ if ( m_colWidths[coords.GetCol()] <=0 ||
+ m_rowHeights[coords.GetRow()] <= 0 ) return;
+
+#if !WXGRID_DRAW_LINES
+ if ( m_gridLinesEnabled )
+ DrawCellBorder( dc, coords );
+#endif
+
+ DrawCellBackground( dc, coords );
+
+ // TODO: separate functions here for different kinds of cells ?
+ // e.g. text, image
+ //
+ DrawCellValue( dc, coords );
+}
+
+
+void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords )
+{
+ if ( m_colWidths[coords.GetCol()] <=0 ||
+ m_rowHeights[coords.GetRow()] <= 0 ) return;
+
+ dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) );
+ int row = coords.GetRow();
+ int col = coords.GetCol();
+
+ // right hand border
+ //
+ dc.DrawLine( m_colRights[col], m_rowBottoms[row] - m_rowHeights[row],
+ m_colRights[col], m_rowBottoms[row] );
+
+ // bottom border
+ //
+ dc.DrawLine( m_colRights[col] - m_colWidths[col], m_rowBottoms[row],
+ m_colRights[col], m_rowBottoms[row] );
+}
+
+
+void wxGrid::DrawCellBackground( wxDC& dc, const wxGridCellCoords& coords )
+{
+ if ( m_colWidths[coords.GetCol()] <=0 ||
+ m_rowHeights[coords.GetRow()] <= 0 ) return;
+
+ int row = coords.GetRow();
+ int col = coords.GetCol();
+
+ dc.SetBackgroundMode( wxSOLID );
+
+ if ( IsInSelection( coords ) )
+ {
+ // TODO: improve this
+ //
+ dc.SetBrush( *wxBLACK_BRUSH );
+ }
+ else
+ {
+ dc.SetBrush( wxBrush(GetCellBackgroundColour(row, col), wxSOLID) );
+ }
+
+ dc.SetPen( *wxTRANSPARENT_PEN );
+
+ dc.DrawRectangle( m_colRights[col] - m_colWidths[col] + 1,
+ m_rowBottoms[row] - m_rowHeights[row] + 1,
+ m_colWidths[col]-1,
+ m_rowHeights[row]-1 );
+}
+
+
+void wxGrid::DrawCellValue( wxDC& dc, const wxGridCellCoords& coords )
+{
+ if ( m_colWidths[coords.GetCol()] <=0 ||
+ m_rowHeights[coords.GetRow()] <= 0 ) return;
+
+ int row = coords.GetRow();
+ int col = coords.GetCol();
+
+ dc.SetBackgroundMode( wxTRANSPARENT );
+
+ if ( IsInSelection( row, col ) )
+ {
+ // TODO: improve this
+ //
+ dc.SetTextBackground( wxColour(0, 0, 0) );
+ dc.SetTextForeground( wxColour(255, 255, 255) );
+ }
+ else
+ {
+ dc.SetTextBackground( GetCellBackgroundColour(row, col) );
+ dc.SetTextForeground( GetCellTextColour(row, col) );
+ }
+ dc.SetFont( GetCellFont(row, col) );
+
+ int hAlign, vAlign;
+ GetCellAlignment( row, col, &hAlign, &vAlign );
+
+ wxRect rect;
+ rect.SetX( m_colRights[col] - m_colWidths[col] + 2 );
+ rect.SetY( m_rowBottoms[row] - m_rowHeights[row] + 2 );
+ rect.SetWidth( m_colWidths[col] - 4 );
+ rect.SetHeight( m_rowHeights[row] - 4 );
+
+ DrawTextRectangle( dc, GetCellValue( row, col ), rect, hAlign, vAlign );
+}
+
+
+
+// TODO: remove this ???
+// This is used to redraw all grid lines e.g. when the grid line colour
+// has been changed
+//
+void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & reg )
+{
+ if ( !m_gridLinesEnabled ||
+ !m_numRows ||
+ !m_numCols ) return;
+
+ int top, bottom, left, right;
+
+ if (reg.IsEmpty()){
+ int cw, ch;
+ m_gridWin->GetClientSize(&cw, &ch);
+
+ // virtual coords of visible area
+ //
+ CalcUnscrolledPosition( 0, 0, &left, &top );
+ CalcUnscrolledPosition( cw, ch, &right, &bottom );
+ }
+ else{
+ wxCoord x, y, w, h;
+ reg.GetBox(x, y, w, h);
+ CalcUnscrolledPosition( x, y, &left, &top );
+ CalcUnscrolledPosition( x + w, y + h, &right, &bottom );
+ }
+
+ // avoid drawing grid lines past the last row and col
+ //
+ right = wxMin( right, m_colRights[m_numCols-1] );
+ bottom = wxMin( bottom, m_rowBottoms[m_numRows-1] );
+
+ dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) );
+
+ // horizontal grid lines
+ //
+ int i;
+ for ( i = 0; i < m_numRows; i++ )
+ {
+ if ( m_rowBottoms[i] > bottom )
+ {
+ break;
+ }
+ else if ( m_rowBottoms[i] >= top )
+ {
+ dc.DrawLine( left, m_rowBottoms[i], right, m_rowBottoms[i] );
+ }
+ }
+
+
+ // vertical grid lines
+ //
+ for ( i = 0; i < m_numCols; i++ )
+ {
+ if ( m_colRights[i] > right )
+ {
+ break;
+ }
+ else if ( m_colRights[i] >= left )
+ {
+ dc.DrawLine( m_colRights[i], top, m_colRights[i], bottom );
+ }
+ }
+}
+
+
+void wxGrid::DrawRowLabels( wxDC& dc )
+{
+ if ( !m_numRows || !m_numCols ) return;
+
+ size_t i;
+ size_t numLabels = m_rowLabelsExposed.GetCount();
+
+ for ( i = 0; i < numLabels; i++ )
+ {
+ DrawRowLabel( dc, m_rowLabelsExposed[i] );
+ }
+}
+
+
+void wxGrid::DrawRowLabel( wxDC& dc, int row )
+{
+ if ( m_rowHeights[row] <= 0 ) return;
+
+ int rowTop = m_rowBottoms[row] - m_rowHeights[row];
+
+ dc.SetPen( *wxBLACK_PEN );
+ dc.DrawLine( m_rowLabelWidth-1, rowTop,
+ m_rowLabelWidth-1, m_rowBottoms[row]-1 );
+
+ dc.DrawLine( 0, m_rowBottoms[row]-1,
+ m_rowLabelWidth-1, m_rowBottoms[row]-1 );
+
+ dc.SetPen( *wxWHITE_PEN );
+ dc.DrawLine( 0, rowTop, 0, m_rowBottoms[row]-1 );
+ dc.DrawLine( 0, rowTop, m_rowLabelWidth-1, rowTop );
+
+ dc.SetBackgroundMode( wxTRANSPARENT );
+ dc.SetTextForeground( GetLabelTextColour() );
+ dc.SetFont( GetLabelFont() );
+
+ int hAlign, vAlign;
+ GetRowLabelAlignment( &hAlign, &vAlign );
+
+ wxRect rect;
+ rect.SetX( 2 );
+ rect.SetY( m_rowBottoms[row] - m_rowHeights[row] + 2 );
+ rect.SetWidth( m_rowLabelWidth - 4 );
+ rect.SetHeight( m_rowHeights[row] - 4 );
+ DrawTextRectangle( dc, GetRowLabelValue( row ), rect, hAlign, vAlign );
+}
+
+
+void wxGrid::DrawColLabels( wxDC& dc )
+{
+ if ( !m_numRows || !m_numCols ) return;
+
+ size_t i;
+ size_t numLabels = m_colLabelsExposed.GetCount();
+
+ for ( i = 0; i < numLabels; i++ )
+ {
+ DrawColLabel( dc, m_colLabelsExposed[i] );
+ }
+}
+
+
+void wxGrid::DrawColLabel( wxDC& dc, int col )
+{
+ if ( m_colWidths[col] <= 0 ) return;
+
+ int colLeft = m_colRights[col] - m_colWidths[col];
+
+ dc.SetPen( *wxBLACK_PEN );
+ dc.DrawLine( m_colRights[col]-1, 0,
+ m_colRights[col]-1, m_colLabelHeight-1 );
+
+ dc.DrawLine( colLeft, m_colLabelHeight-1,
+ m_colRights[col]-1, m_colLabelHeight-1 );
+
+ dc.SetPen( *wxWHITE_PEN );
+ dc.DrawLine( colLeft, 0, colLeft, m_colLabelHeight-1 );
+ dc.DrawLine( colLeft, 0, m_colRights[col]-1, 0 );
+
+ dc.SetBackgroundMode( wxTRANSPARENT );
+ dc.SetTextForeground( GetLabelTextColour() );
+ dc.SetFont( GetLabelFont() );
+
+ dc.SetBackgroundMode( wxTRANSPARENT );
+ dc.SetTextForeground( GetLabelTextColour() );
+ dc.SetFont( GetLabelFont() );
+
+ int hAlign, vAlign;
+ GetColLabelAlignment( &hAlign, &vAlign );
+
+ wxRect rect;
+ rect.SetX( m_colRights[col] - m_colWidths[col] + 2 );
+ rect.SetY( 2 );
+ rect.SetWidth( m_colWidths[col] - 4 );
+ rect.SetHeight( m_colLabelHeight - 4 );
+ DrawTextRectangle( dc, GetColLabelValue( col ), rect, hAlign, vAlign );
+}
+
+
+void wxGrid::DrawTextRectangle( wxDC& dc,
+ const wxString& value,
+ const wxRect& rect,
+ int horizAlign,
+ int vertAlign )
+{
+ long textWidth, textHeight;
+ long lineWidth, lineHeight;
+ wxArrayString lines;
+
+ dc.SetClippingRegion( rect );
+ StringToLines( value, lines );
+ if ( lines.GetCount() )
+ {
+ GetTextBoxSize( dc, lines, &textWidth, &textHeight );
+ dc.GetTextExtent( lines[0], &lineWidth, &lineHeight );
+
+ float x, y;
+ switch ( horizAlign )
+ {
+ case wxRIGHT:
+ x = rect.x + (rect.width - textWidth - 1);
+ break;
+
+ case wxCENTRE:
+ x = rect.x + ((rect.width - textWidth)/2);
+ break;
+
+ case wxLEFT:
+ default:
+ x = rect.x + 1;
+ break;
+ }
+
+ switch ( vertAlign )
+ {
+ case wxBOTTOM:
+ y = rect.y + (rect.height - textHeight - 1);
+ break;
+
+ case wxCENTRE:
+ y = rect.y + ((rect.height - textHeight)/2);
+ break;
+
+ case wxTOP:
+ default:
+ y = rect.y + 1;
+ break;
+ }
+
+ for ( size_t i = 0; i < lines.GetCount(); i++ )
+ {
+ dc.DrawText( lines[i], (long)x, (long)y );
+ y += lineHeight;
+ }
+ }
+
+ dc.DestroyClippingRegion();