1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxGenericGrid 
   4 // Author:      Julian Smart 
   5 // Modified by: Michael Bedward 
   6 //                Added edit in place facility, 20 Apr 1999 
   7 //                Added cursor key control, 29 Jun 1999 
  10 // Copyright:   (c) Julian Smart and Markus Holzem 
  11 // Licence:     wxWindows license 
  12 ///////////////////////////////////////////////////////////////////////////// 
  15     #pragma implementation "gridg.h" 
  19 // For compilers that support precompilation, includes "wx/wx.h". 
  20 #include "wx/wxprec.h" 
  28     #include "wx/dcclient.h" 
  29     #include "wx/dcmemory.h" 
  30     #include "wx/textctrl.h" 
  31     #include "wx/settings.h" 
  36 #include "wx/string.h" 
  38 #include "wx/generic/gridg.h" 
  40 // Set to zero to use no double-buffering 
  42     #define wxUSE_DOUBLE_BUFFERING 1 
  44     #define wxUSE_DOUBLE_BUFFERING 0 
  47 #define wxGRID_DRAG_NONE       0 
  48 #define wxGRID_DRAG_LEFT_RIGHT 1 
  49 #define wxGRID_DRAG_UP_DOWN    2 
  51 IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid
, wxPanel
) 
  52 IMPLEMENT_DYNAMIC_CLASS(wxGridEvent
, wxEvent
) 
  54 BEGIN_EVENT_TABLE(wxGenericGrid
, wxPanel
) 
  55     EVT_SIZE(wxGenericGrid::OnSize
) 
  56     EVT_PAINT(wxGenericGrid::OnPaint
) 
  57     EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground
) 
  58     EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent
) 
  59     EVT_TEXT(wxGRID_TEXT_CTRL
, wxGenericGrid::OnText
) 
  60     EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlace
) 
  61     EVT_TEXT_ENTER(wxGRID_TEXT_CTRL
, wxGenericGrid::OnTextEnter
) 
  62     EVT_TEXT_ENTER(wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, wxGenericGrid::OnTextInPlaceEnter
) 
  63     EVT_COMMAND_SCROLL(wxGRID_HSCROLL
, wxGenericGrid::OnGridScroll
) 
  64     EVT_COMMAND_SCROLL(wxGRID_VSCROLL
, wxGenericGrid::OnGridScroll
) 
  66     // default wxGridEvent handlers 
  67     EVT_GRID_SELECT_CELL(wxGenericGrid::_OnSelectCell
) 
  68     EVT_GRID_CREATE_CELL(wxGenericGrid::_OnCreateCell
) 
  69     EVT_GRID_CHANGE_LABELS(wxGenericGrid::_OnChangeLabels
) 
  70     EVT_GRID_CHANGE_SEL_LABEL(wxGenericGrid::_OnChangeSelectionLabel
) 
  71     EVT_GRID_CELL_CHANGE(wxGenericGrid::_OnCellChange
) 
  72     EVT_GRID_CELL_LCLICK(wxGenericGrid::_OnCellLeftClick
) 
  73     EVT_GRID_CELL_RCLICK(wxGenericGrid::_OnCellRightClick
) 
  74     EVT_GRID_LABEL_LCLICK(wxGenericGrid::_OnLabelLeftClick
) 
  75     EVT_GRID_LABEL_RCLICK(wxGenericGrid::_OnLabelRightClick
) 
  80 wxGenericGrid::wxGenericGrid(void) 
  83   m_hScrollBar 
= (wxScrollBar 
*) NULL
; 
  84   m_vScrollBar 
= (wxScrollBar 
*) NULL
; 
  85   m_cellTextColour 
= *wxBLACK
; 
  86   m_cellBackgroundColour 
= *wxWHITE
; 
  87   m_labelTextColour 
= *wxBLACK
; 
  88 //  m_labelBackgroundColour = *wxLIGHT_GREY; 
  89   m_labelBackgroundColour 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
  90   m_labelBackgroundBrush 
= wxNullBrush
; 
  91   m_labelTextFont 
= wxNullFont
; 
  92   m_cellTextFont 
= wxNullFont
; 
  93   m_textItem 
= (wxTextCtrl 
*) NULL
; 
  94   m_currentRectVisible 
= FALSE
; 
  98   m_inOnTextInPlace 
= FALSE
; 
 100 #if defined(__WIN95__) 
 101   m_scrollWidth 
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
); 
 102 #elif defined(__WXGTK__) 
 103   m_scrollWidth 
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
); 
 107   m_dragStatus 
= wxGRID_DRAG_NONE
; 
 109   m_dragStartPosition 
= 0; 
 110   m_dragLastPosition 
= 0; 
 111   m_divisionPen 
= wxNullPen
; 
 112   m_leftOfSheet 
= wxGRID_DEFAULT_SHEET_LEFT
; 
 113   m_topOfSheet 
= wxGRID_DEFAULT_SHEET_TOP
; 
 114   m_cellHeight 
= wxGRID_DEFAULT_CELL_HEIGHT
; 
 115   m_totalGridWidth 
= 0; 
 116   m_totalGridHeight 
= 0; 
 117   m_colWidths 
= (short *) NULL
; 
 118   m_rowHeights 
= (short *) NULL
; 
 119   m_verticalLabelWidth 
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
; 
 120   m_horizontalLabelHeight 
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
; 
 121   m_verticalLabelAlignment 
= wxCENTRE
; 
 122   m_horizontalLabelAlignment 
= wxCENTRE
; 
 123   m_editControlPosition
.x 
= wxGRID_DEFAULT_EDIT_X
; 
 124   m_editControlPosition
.y 
= wxGRID_DEFAULT_EDIT_Y
; 
 125   m_editControlPosition
.width 
= wxGRID_DEFAULT_EDIT_WIDTH
; 
 126   m_editControlPosition
.height 
= wxGRID_DEFAULT_EDIT_HEIGHT
; 
 131   m_editCreated 
= FALSE
; 
 134   m_gridCells 
= (wxGridCell 
***) NULL
; 
 135   m_rowLabelCells 
= (wxGridCell 
**) NULL
; 
 136   m_colLabelCells 
= (wxGridCell 
**) NULL
; 
 137   m_textItem 
= (wxTextCtrl 
*) NULL
; 
 140 bool wxGenericGrid::Create(wxWindow 
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, 
 141  long style
, const wxString
& name
) 
 144   m_editingPanel 
= (wxPanel 
*) NULL
; 
 145   m_hScrollBar 
= (wxScrollBar 
*) NULL
; 
 146   m_vScrollBar 
= (wxScrollBar 
*) NULL
; 
 147   m_cellTextColour 
= *wxBLACK
; 
 148   m_cellBackgroundColour 
= *wxWHITE
; 
 149   m_labelTextColour 
= *wxBLACK
; 
 150 //  m_labelBackgroundColour = *wxLIGHT_GREY; 
 151   m_labelBackgroundColour 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
 152   m_labelBackgroundBrush 
= wxNullBrush
; 
 153   m_labelTextFont 
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxBOLD
); 
 154   m_cellTextFont 
= * wxTheFontList
->FindOrCreateFont(10, wxSWISS
, wxNORMAL
, wxNORMAL
); 
 155   m_textItem 
= (wxTextCtrl 
*) NULL
; 
 156   m_currentRectVisible 
= FALSE
; 
 158 #if defined(__WIN95__) 
 159   m_scrollWidth 
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
); 
 160 #elif defined(__WXGTK__) 
 161   m_scrollWidth 
= wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X
); 
 165   m_dragStatus 
= wxGRID_DRAG_NONE
; 
 167   m_dragStartPosition 
= 0; 
 168   m_dragLastPosition 
= 0; 
 169   m_divisionPen 
= * wxThePenList
->FindOrCreatePen("LIGHT GREY", 1, wxSOLID
); 
 170   m_doubleBufferingBitmap 
= (wxBitmap 
*) NULL
; 
 172   if (!m_horizontalSashCursor
.Ok()) 
 174     m_horizontalSashCursor 
= wxCursor(wxCURSOR_SIZEWE
); 
 175     m_verticalSashCursor 
= wxCursor(wxCURSOR_SIZENS
); 
 178   SetLabelBackgroundColour(m_labelBackgroundColour
); 
 180   m_leftOfSheet 
= wxGRID_DEFAULT_SHEET_LEFT
; 
 181   m_topOfSheet 
= wxGRID_DEFAULT_SHEET_TOP
; 
 182   m_cellHeight 
= wxGRID_DEFAULT_CELL_HEIGHT
; 
 183   m_totalGridWidth 
= 0; 
 184   m_totalGridHeight 
= 0; 
 185   m_colWidths 
= (short *) NULL
; 
 186   m_rowHeights 
= (short *) NULL
; 
 188   m_verticalLabelWidth 
= wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH
; 
 189   m_horizontalLabelHeight 
= wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT
; 
 190   m_verticalLabelAlignment 
= wxCENTRE
; 
 191   m_horizontalLabelAlignment 
= wxCENTRE
; 
 192   m_editControlPosition
.x 
= wxGRID_DEFAULT_EDIT_X
; 
 193   m_editControlPosition
.y 
= wxGRID_DEFAULT_EDIT_Y
; 
 194   m_editControlPosition
.width 
= wxGRID_DEFAULT_EDIT_WIDTH
; 
 195   m_editControlPosition
.height 
= wxGRID_DEFAULT_EDIT_HEIGHT
; 
 203   /* Store the rect. coordinates for the current cell */ 
 204   SetCurrentRect(m_wCursorRow
, m_wCursorColumn
); 
 206   m_editCreated 
= FALSE
; 
 210   m_gridCells 
= (wxGridCell 
***) NULL
; 
 211   m_rowLabelCells 
= (wxGridCell 
**) NULL
; 
 212   m_colLabelCells 
= (wxGridCell 
**) NULL
; 
 213   m_textItem 
= (wxTextCtrl 
*) NULL
; 
 215   wxPanel::Create(parent
, id
, pos
, size
, style
, name
); 
 217   m_editingPanel 
= new wxPanel(this); 
 219   m_textItem 
= new wxTextCtrl(m_editingPanel
, wxGRID_TEXT_CTRL
, "", 
 220                               wxPoint(m_editControlPosition
.x
, m_editControlPosition
.y
), 
 221                               wxSize(m_editControlPosition
.width
, -1), 
 223   m_textItem
->Show(TRUE
); 
 224   m_textItem
->SetFocus(); 
 225   int controlW
, controlH
; 
 227   m_textItem
->GetSize(&controlW
, &controlH
); 
 228   m_editControlPosition
.height 
= controlH
; 
 230   m_topOfSheet 
= m_editControlPosition
.y 
+ controlH 
+ 2; 
 232   m_editCreated 
= TRUE
; 
 234   m_hScrollBar 
= new wxScrollBar(this, wxGRID_HSCROLL
, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL
); 
 235   m_vScrollBar 
= new wxScrollBar(this, wxGRID_VSCROLL
, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL
); 
 237 //  SetSize(pos.x, pos.y, size.x, size.y); 
 239   m_inPlaceTextItem 
= new wxTextCtrl( (wxPanel
*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL
, "", 
 240                                       wxPoint( m_currentRect
.x
-2, m_currentRect
.y
-2 ), 
 241                                       wxSize( m_currentRect
.width
+4, m_currentRect
.height
+4 ), 
 242                                       wxNO_BORDER 
| wxTE_PROCESS_ENTER 
); 
 243   m_inPlaceTextItem
->Show(TRUE
); 
 244   m_inPlaceTextItem
->SetFocus(); 
 249 wxGenericGrid::~wxGenericGrid(void) 
 254 void wxGenericGrid::ClearGrid(void) 
 259     for (i 
= 0; i 
< m_totalRows
; i
++) 
 261       for (j 
= 0; j 
< m_totalCols
; j
++) 
 262         if (m_gridCells
[i
][j
]) 
 263           delete m_gridCells
[i
][j
]; 
 264       delete[] m_gridCells
[i
]; 
 266     delete[] m_gridCells
; 
 267     m_gridCells 
= (wxGridCell 
***) NULL
; 
 270     delete[] m_colWidths
; 
 271   m_colWidths 
= (short *) NULL
; 
 273     delete[] m_rowHeights
; 
 274   m_rowHeights 
= (short *) NULL
; 
 278     for (i 
= 0; i 
< m_totalRows
; i
++) 
 279       delete m_rowLabelCells
[i
]; 
 280     delete[] m_rowLabelCells
; 
 281     m_rowLabelCells 
= (wxGridCell 
**) NULL
; 
 285     for (i 
= 0; i 
< m_totalCols
; i
++) 
 286       delete m_colLabelCells
[i
]; 
 287     delete[] m_colLabelCells
; 
 288     m_colLabelCells 
= (wxGridCell 
**) NULL
; 
 290   if (m_doubleBufferingBitmap
) 
 292     delete m_doubleBufferingBitmap
; 
 293     m_doubleBufferingBitmap 
= (wxBitmap 
*) NULL
; 
 297 bool wxGenericGrid::CreateGrid(int nRows
, int nCols
, wxString 
**cellValues
, short *widths
, 
 298      short defaultWidth
, short defaultHeight
) 
 304   m_colWidths 
= new short[nCols
]; 
 305   m_rowHeights 
= new short[nRows
]; 
 306   for (i 
= 0; i 
< nCols
; i
++) 
 308       m_colWidths
[i
] = widths
[i
]; 
 310       m_colWidths
[i
] = defaultWidth
; 
 311   for (i 
= 0; i 
< nRows
; i
++) 
 312     m_rowHeights
[i
] = defaultHeight
; 
 314   m_gridCells 
= new wxGridCell 
**[nRows
]; 
 316   for (i 
= 0; i 
< nRows
; i
++) 
 317     m_gridCells
[i
] = new wxGridCell 
*[nCols
]; 
 319   for (i 
= 0; i 
< nRows
; i
++) 
 320     for (j 
= 0; j 
< nCols
; j
++) 
 323         //m_gridCells[i][j] = OnCreateCell(); 
 324         wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, this, i
, j
); 
 325         GetEventHandler()->ProcessEvent(g_evt
); 
 326         m_gridCells
[i
][j
] = g_evt
.m_cell
; 
 327         m_gridCells
[i
][j
]->SetTextValue(cellValues
[i
][j
]); 
 330         m_gridCells
[i
][j
] = (wxGridCell 
*) NULL
; 
 332   m_rowLabelCells 
= new wxGridCell 
*[nRows
]; 
 333   for (i 
= 0; i 
< nRows
; i
++) 
 334     m_rowLabelCells
[i
] = new wxGridCell(this); 
 335   m_colLabelCells 
= new wxGridCell 
*[nCols
]; 
 336   for (i 
= 0; i 
< nCols
; i
++) 
 337     m_colLabelCells
[i
] = new wxGridCell(this); 
 339   m_wCursorRow 
= m_wCursorColumn 
= 0; 
 340   SetCurrentRect(0, 0); 
 342   // Need to determine various dimensions 
 346   int objectSizeX 
= m_totalCols
; 
 348   int viewLengthX 
= m_totalCols
; 
 351   m_hScrollBar->SetViewLength(viewLengthX); 
 352   m_hScrollBar->SetObjectLength(objectSizeX); 
 353   m_hScrollBar->SetPageSize(pageSizeX); 
 355   m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), pageSizeX
, objectSizeX
, viewLengthX
); 
 357   int objectSizeY 
= m_totalRows
; 
 359   int viewLengthY 
= m_totalRows
; 
 362   m_vScrollBar->SetViewLength(viewLengthY); 
 363   m_vScrollBar->SetObjectLength(objectSizeY); 
 364   m_vScrollBar->SetPageSize(pageSizeY); 
 367   m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), pageSizeY
, objectSizeY
, viewLengthY
); 
 372   wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this); 
 373   GetEventHandler()->ProcessEvent(g_evt
); 
 375   //OnChangeSelectionLabel(); 
 376   wxGridEvent 
g_evt2(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this); 
 377   GetEventHandler()->ProcessEvent(g_evt2
); 
 382 // Need to determine various dimensions 
 383 void wxGenericGrid::UpdateDimensions(void) 
 385   int canvasWidth
, canvasHeight
; 
 386   GetSize(&canvasWidth
, &canvasHeight
); 
 388   if (m_editCreated 
&& m_editable
) 
 390     int controlW
, controlH
; 
 391     GetTextItem()->GetSize(&controlW
, &controlH
); 
 392     m_topOfSheet 
= m_editControlPosition
.y 
+ controlH 
+ 2; 
 396   m_rightOfSheet 
= m_leftOfSheet 
+ m_verticalLabelWidth
; 
 398   for (i 
= m_scrollPosX
; i 
< m_totalCols
; i
++) 
 400     if (m_rightOfSheet 
> canvasWidth
) 
 403       m_rightOfSheet 
+= m_colWidths
[i
]; 
 405   m_bottomOfSheet 
= m_topOfSheet 
+ m_horizontalLabelHeight
; 
 406   for (i 
= m_scrollPosY
; i 
< m_totalRows
; i
++) 
 408     if (m_bottomOfSheet 
> canvasHeight
) 
 411       m_bottomOfSheet 
+= m_rowHeights
[i
]; 
 414   m_totalGridWidth 
= m_leftOfSheet 
+ m_verticalLabelWidth
; 
 415   for (i 
= 0; i 
< m_totalCols
; i
++) 
 417     m_totalGridWidth 
+= m_colWidths
[i
]; 
 419   m_totalGridHeight 
= m_topOfSheet 
+ m_horizontalLabelHeight
; 
 420   for (i 
= 0; i 
< m_totalRows
; i
++) 
 422     m_totalGridHeight 
+= m_rowHeights
[i
]; 
 426 wxGridCell 
*wxGenericGrid::GetCell(int row
, int col
) const 
 429     return (wxGridCell 
*) NULL
; 
 431   if ((row 
>= m_totalRows
) || (col 
>= m_totalCols
)) 
 432     return (wxGridCell 
*) NULL
; 
 434   wxGridCell 
*cell 
= m_gridCells
[row
][col
]; 
 437     // m_gridCells[row][col] = OnCreateCell(); 
 438     wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CREATE_CELL
, (wxGenericGrid
*) this, row
, col
); 
 439     GetEventHandler()->ProcessEvent(g_evt
); 
 440     m_gridCells
[row
][col
] = g_evt
.m_cell
; 
 441     return m_gridCells
[row
][col
]; 
 447 void wxGenericGrid::SetGridClippingRegion(wxDC 
*dc
) 
 449   int m_scrollWidthHoriz 
= 0; 
 450   int m_scrollWidthVert 
= 0; 
 452   GetClientSize(&cw
, &ch
); 
 454   if (m_hScrollBar 
&& m_hScrollBar
->IsShown()) 
 455     m_scrollWidthHoriz 
= m_scrollWidth
; 
 456   if (m_vScrollBar 
&& m_vScrollBar
->IsShown()) 
 457     m_scrollWidthVert 
= m_scrollWidth
; 
 459   // Don't paint over the scrollbars 
 460   dc
->SetClippingRegion(m_leftOfSheet
, m_topOfSheet
, 
 461      cw 
- m_scrollWidthVert 
- m_leftOfSheet
, ch 
- m_scrollWidthHoriz 
- m_topOfSheet
); 
 464 void wxGenericGrid::OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
 467   GetClientSize(&w
, &h
); 
 469   bool useDoubleBuffering 
= (bool) wxUSE_DOUBLE_BUFFERING
; 
 470   if (useDoubleBuffering
) 
 472     // Reuse the old bitmap if possible 
 474     if (!m_doubleBufferingBitmap 
|| 
 475        (m_doubleBufferingBitmap
->GetWidth() < w 
|| m_doubleBufferingBitmap
->GetHeight() < h
)) 
 477         if (m_doubleBufferingBitmap
) 
 478             delete m_doubleBufferingBitmap
; 
 479         m_doubleBufferingBitmap 
= new wxBitmap(w
, h
); 
 481     if (!m_doubleBufferingBitmap 
|| !m_doubleBufferingBitmap
->Ok()) 
 483         // If we couldn't create a new bitmap, perhaps because resources were low, 
 484         // then don't complain, just don't double-buffer 
 485         if (m_doubleBufferingBitmap
) 
 486             delete m_doubleBufferingBitmap
; 
 487         m_doubleBufferingBitmap 
= (wxBitmap 
*) NULL
; 
 488         useDoubleBuffering 
= FALSE
; 
 492   if (useDoubleBuffering
) 
 494     wxPaintDC 
paintDC(this); 
 495     wxMemoryDC 
dc(& paintDC
); 
 496     dc
.SelectObject(* m_doubleBufferingBitmap
); 
 500     int vertScrollBarWidth 
= m_scrollWidth
; 
 501     int horizScrollBarHeight 
= m_scrollWidth
; 
 502     if (m_vScrollBar 
&& !m_vScrollBar
->IsShown()) 
 503       vertScrollBarWidth 
= 0; 
 504     if (m_hScrollBar 
&& !m_hScrollBar
->IsShown()) 
 505       horizScrollBarHeight 
= 0; 
 507     paintDC
.Blit(m_leftOfSheet
, m_topOfSheet
, w 
- vertScrollBarWidth 
- m_leftOfSheet
, h 
- horizScrollBarHeight 
- m_topOfSheet
, 
 508       &dc
, m_leftOfSheet
, m_topOfSheet
, wxCOPY
); 
 510     dc
.SelectObject(wxNullBitmap
); 
 519 void wxGenericGrid::PaintGrid(wxDC
& dc
) 
 522     dc
.SetOptimization(FALSE
); 
 524     SetGridClippingRegion(& dc
); 
 526     DrawLabelAreas(& dc
); 
 528     DrawEditableArea(& dc
); 
 529     DrawColumnLabels(& dc
); 
 534     /* Hilight present cell */ 
 535     SetCurrentRect(m_wCursorRow
, m_wCursorColumn
); 
 536     if (m_currentRectVisible 
&& !(m_editable 
&& m_editInPlace
)) 
 539     dc
.DestroyClippingRegion(); 
 540     dc
.SetOptimization(TRUE
); 
 544 // Erase (some of) the background. 
 545 // Currently, a Windows-only optimisation. 
 546 void wxGenericGrid::OnEraseBackground(wxEraseEvent
& WXUNUSED(event
) ) 
 550     dc
.SetOptimization(FALSE
); 
 553     GetClientSize(& w
, & h
); 
 554     dc
.SetBrush(*wxLIGHT_GREY_BRUSH
); 
 555     dc
.SetPen(*wxLIGHT_GREY_PEN
); 
 557     if (m_hScrollBar 
&& m_hScrollBar
->IsShown() && m_vScrollBar 
&& m_vScrollBar
->IsShown()) 
 559         dc
.DrawRectangle(w 
- m_scrollWidth
, h 
- m_scrollWidth
, m_scrollWidth
, m_scrollWidth
); 
 562     dc
.SetOptimization(TRUE
); 
 567 void wxGenericGrid::DrawLabelAreas(wxDC 
*dc
) 
 570   GetClientSize(&cw
, &ch
); 
 572   dc
->SetPen(*wxTRANSPARENT_PEN
); 
 573 //  dc->SetBrush(*dc->GetBackground()); 
 575   // Should blank out any area which isn't going to be painted over. 
 576 //  dc->DrawRectangle(m_leftOfSheet, m_bottomOfSheet, cw - m_leftOfSheet, ch - m_bottomOfSheet); 
 577 //  dc->DrawRectangle(m_rightOfSheet, m_topOfSheet, cw - m_rightOfSheet, ch - m_topOfSheet); 
 579   // Paint the label areas 
 580   dc
->SetBrush(m_labelBackgroundBrush
); 
 581 //  dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_rightOfSheet - m_leftOfSheet + 1, m_horizontalLabelHeight + 1); 
 582   dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, cw
-m_leftOfSheet
, m_horizontalLabelHeight 
+ 1); 
 583 //  dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, m_bottomOfSheet - m_topOfSheet + 1); 
 584   dc
->DrawRectangle(m_leftOfSheet
, m_topOfSheet
, m_verticalLabelWidth 
+ 1, ch
-m_topOfSheet
); 
 587 void wxGenericGrid::DrawEditableArea(wxDC 
*dc
) 
 590   GetClientSize(&cw
, &ch
); 
 592   dc
->SetPen(*wxTRANSPARENT_PEN
); 
 593   dc
->SetBrush(*wxTheBrushList
->FindOrCreateBrush(m_cellBackgroundColour
, wxSOLID
)); 
 594 //  dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight, 
 595 //      m_rightOfSheet-(m_leftOfSheet+m_verticalLabelWidth) + 1, m_bottomOfSheet - (m_topOfSheet+m_horizontalLabelHeight) + 1); 
 596   dc
->DrawRectangle(m_leftOfSheet
+m_verticalLabelWidth
, m_topOfSheet
+m_horizontalLabelHeight
, 
 597       cw
-(m_leftOfSheet
+m_verticalLabelWidth
), ch 
- (m_topOfSheet
+m_horizontalLabelHeight
)); 
 600 void wxGenericGrid::DrawGridLines(wxDC 
*dc
) 
 603   GetClientSize(&cw
, &ch
); 
 607   if (m_divisionPen
.Ok()) 
 609     dc
->SetPen(m_divisionPen
); 
 611     int heightCount 
= m_topOfSheet 
+ m_horizontalLabelHeight
; 
 613     // Draw horizontal grey lines for cells 
 614     for (i 
= m_scrollPosY
; i 
< (m_totalRows
+1); i
++) 
 616       if (heightCount 
> ch
) 
 620         dc
->DrawLine(m_leftOfSheet
, heightCount
, 
 623           heightCount 
+= m_rowHeights
[i
]; 
 628   if (m_verticalLabelWidth 
> 0) 
 630     dc
->SetPen(*wxBLACK_PEN
); 
 632     // Draw horizontal black lines for row labels 
 633     int heightCount 
= m_topOfSheet 
+ m_horizontalLabelHeight
; 
 634     for (i 
= m_scrollPosY
; i 
< (m_totalRows
+1); i
++) 
 636       if (heightCount 
> ch
) 
 640         dc
->DrawLine(m_leftOfSheet
, heightCount
, 
 641                      m_verticalLabelWidth
, heightCount
); 
 643           heightCount 
+= m_rowHeights
[i
]; 
 646     // Draw a black vertical line for row number cells 
 647     dc
->DrawLine(m_leftOfSheet 
+ m_verticalLabelWidth
, m_topOfSheet
, 
 648       m_leftOfSheet 
+ m_verticalLabelWidth
, ch
); 
 649     // First vertical line 
 650     dc
->DrawLine(m_leftOfSheet
, m_topOfSheet
, m_leftOfSheet
, ch
); 
 652     dc
->SetPen(*wxWHITE_PEN
); 
 654     // Draw highlights on row labels 
 655     heightCount 
= m_topOfSheet 
+ m_horizontalLabelHeight
; 
 656     for (i 
= m_scrollPosY
; i 
< m_totalRows
; i
++) 
 658       if (heightCount 
> ch
) 
 662         dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1, 
 663                      m_verticalLabelWidth
, heightCount
+1); 
 664         dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1, 
 665                      m_leftOfSheet
+1, heightCount 
+ m_rowHeights
[i
] - 1); 
 666         heightCount 
+= m_rowHeights
[i
]; 
 669     // Last one - down to the floor. 
 670     dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1, 
 671                  m_verticalLabelWidth
, heightCount
+1); 
 672     dc
->DrawLine(m_leftOfSheet
+1, heightCount
+1, 
 673                    m_leftOfSheet
+1, ch
); 
 677   if (m_divisionPen
.Ok()) 
 679     dc
->SetPen(m_divisionPen
); 
 681     // Draw vertical grey lines for cells 
 682     int widthCount 
= m_leftOfSheet 
+ m_verticalLabelWidth
; 
 683     for (i 
= m_scrollPosX
; i 
< m_totalCols
; i
++) 
 689         // Skip the first one 
 690         if (i 
!= m_scrollPosX
) 
 692          dc
->DrawLine(widthCount
, m_topOfSheet 
+ m_horizontalLabelHeight
, 
 693                        widthCount
, m_bottomOfSheet
); 
 695         widthCount 
+= m_colWidths
[i
]; 
 699     dc
->DrawLine(widthCount
, m_topOfSheet 
+ m_horizontalLabelHeight
, 
 700                     widthCount
, m_bottomOfSheet
); 
 703   dc
->SetPen(*wxBLACK_PEN
); 
 705   // Draw two black horizontal lines for column number cells 
 707           m_leftOfSheet
, m_topOfSheet
, 
 709   dc
->DrawLine(m_leftOfSheet
,  m_topOfSheet 
+ m_horizontalLabelHeight
, 
 710                cw
, m_topOfSheet 
+ m_horizontalLabelHeight
); 
 712   if (m_horizontalLabelHeight 
> 0) 
 714     int widthCount 
= m_leftOfSheet 
+ m_verticalLabelWidth
; 
 716     // Draw black vertical lines for column number cells 
 717     for (i 
= m_scrollPosX
; i 
< m_totalCols
; i
++) 
 723         dc
->DrawLine(widthCount
, m_topOfSheet
, 
 724                       widthCount
, m_topOfSheet 
+ m_horizontalLabelHeight
); 
 725         widthCount 
+= m_colWidths
[i
]; 
 730     dc
->DrawLine(widthCount
, m_topOfSheet
, 
 731                     widthCount
, m_topOfSheet 
+ m_horizontalLabelHeight
); 
 734     dc
->SetPen(*wxWHITE_PEN
); 
 735     widthCount 
= m_leftOfSheet 
+ m_verticalLabelWidth
; 
 737     for (i 
= m_scrollPosX
; i 
< m_totalCols
; i
++) 
 743         dc
->DrawLine(widthCount
+1, m_topOfSheet
+1, 
 744                      widthCount
+m_colWidths
[i
], m_topOfSheet
+1); 
 745         dc
->DrawLine(widthCount
+1, m_topOfSheet
+1, 
 746                      widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
); 
 747         widthCount 
+= m_colWidths
[i
]; 
 750     // Last one - to the right side of the canvas. 
 751     dc
->DrawLine(widthCount
+1, m_topOfSheet
+1, 
 753     dc
->DrawLine(widthCount
+1, m_topOfSheet
+1, 
 754                    widthCount
+1, m_topOfSheet
+m_horizontalLabelHeight
); 
 759 void wxGenericGrid::DrawColumnLabels(wxDC 
*dc
) 
 762   GetClientSize(&cw
, &ch
); 
 764   if (m_horizontalLabelHeight 
== 0) 
 770   // Draw letters for columns 
 771   rect
.y 
= m_topOfSheet 
+ 1; 
 772   rect
.height 
= m_horizontalLabelHeight 
- 1; 
 774   dc
->SetTextBackground(m_labelBackgroundColour
); 
 775   dc
->SetBackgroundMode(wxTRANSPARENT
); 
 776 //  dc->SetTextForeground(m_labelTextColour); 
 778   int widthCount 
= m_leftOfSheet 
+ m_verticalLabelWidth
; 
 779   for (i 
= m_scrollPosX
; i 
< m_totalCols
; i
++) 
 785        rect
.x 
= 1 + widthCount
; 
 786        rect
.width 
= m_colWidths
[i
]; 
 787        DrawColumnLabel(dc
, &rect
, i
); 
 789        widthCount 
+= m_colWidths
[i
]; 
 794 void wxGenericGrid::DrawColumnLabel(wxDC 
*dc
, wxRect 
*rect
, int col
) 
 796   wxGridCell 
*cell 
= GetLabelCell(wxHORIZONTAL
, col
); 
 805     dc
->SetTextForeground(GetLabelTextColour()); 
 806     dc
->SetFont(GetLabelTextFont()); 
 807         if ( !cell
->GetTextValue().IsNull() ) 
 808             DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxHORIZONTAL
)); 
 812 void wxGenericGrid::DrawRowLabels(wxDC 
*dc
) 
 815   GetClientSize(&cw
, &ch
); 
 817   if (m_verticalLabelWidth 
== 0) 
 823   // Draw numbers for rows 
 824   rect
.x 
= m_leftOfSheet
; 
 825   rect
.width 
= m_verticalLabelWidth
; 
 827   int heightCount 
= m_topOfSheet 
+ m_horizontalLabelHeight
; 
 829   dc
->SetTextBackground(m_labelBackgroundColour
); 
 830   dc
->SetBackgroundMode(wxTRANSPARENT
); 
 832   for (i 
= m_scrollPosY
; i 
< m_totalRows
; i
++) 
 834      if (heightCount 
> ch
) 
 838        rect
.y 
= 1 + heightCount
; 
 839        rect
.height 
= m_rowHeights
[i
]; 
 840        DrawRowLabel(dc
, &rect
, i
); 
 842        heightCount 
+= m_rowHeights
[i
]; 
 847 void wxGenericGrid::DrawRowLabel(wxDC 
*dc
, wxRect 
*rect
, int row
) 
 849   wxGridCell 
*cell 
= GetLabelCell(wxVERTICAL
, row
); 
 858     dc
->SetTextForeground(GetLabelTextColour()); 
 859     dc
->SetFont(GetLabelTextFont()); 
 860         if ( !cell
->GetTextValue().IsNull() ) 
 861             DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, GetLabelAlignment(wxVERTICAL
)); 
 865 void wxGenericGrid::DrawCells(wxDC 
*dc
) 
 868   GetClientSize(&cw
, &ch
); 
 872   // Draw value corresponding to each cell 
 873   for (i 
= m_scrollPosY
; i 
< m_totalRows
; i
++) 
 875     for (j 
= m_scrollPosX
; j 
< m_totalCols
; j
++) 
 877       SetCurrentRect(i
, j
, cw
, ch
); 
 878       if (m_currentRectVisible
) 
 880         DrawCellBackground(dc
, &m_currentRect
, i
, j
); 
 881         DrawCellValue(dc
, &m_currentRect
, i
, j
); 
 883       if (m_currentRect
.x 
> cw
) 
 886     if (m_currentRect
.y 
> ch
) 
 889   dc
->SetBackgroundMode(wxSOLID
); 
 890   dc
->SetPen(*wxBLACK_PEN
); 
 893 void wxGenericGrid::DrawCellBackground(wxDC 
*dc
, wxRect 
*rect
, int row
, int col
) 
 895   wxGridCell 
*cell 
= GetCell(row
, col
); 
 898     dc
->SetBrush(cell
->GetBackgroundBrush()); 
 899     dc
->SetPen(*wxTRANSPARENT_PEN
); 
 901 #if 0    // In wxWin 2.0 the dc code is exact. RR. 
 903     dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1); 
 905     dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
, rect
->height
); 
 909     dc
->DrawRectangle(rect
->x
+1, rect
->y
+1, rect
->width
-1, rect
->height
-1); 
 911     dc
->SetPen(*wxBLACK_PEN
); 
 915 void wxGenericGrid::DrawCellValue(wxDC 
*dc
, wxRect 
*rect
, int row
, int col
) 
 917   wxGridCell 
*cell 
= GetCell(row
, col
); 
 920     wxBitmap 
*bitmap 
= cell
->GetCellBitmap(); 
 930       DrawBitmapRect(dc
, bitmap
, &rect2
, cell
->GetAlignment()); 
 934       dc
->SetBackgroundMode(wxTRANSPARENT
); 
 935       dc
->SetTextForeground(cell
->GetTextColour()); 
 936       dc
->SetFont(cell
->GetFont()); 
 938           if ( !cell
->GetTextValue().IsNull() ) 
 939               DrawTextRect(dc
, cell
->GetTextValue(), &rect2
, cell
->GetAlignment()); 
 944 void wxGenericGrid::AdjustScrollbars(void) 
 947   GetClientSize(&cw
, &ch
); 
 949   // We find the view size by seeing how many rows/cols fit on 
 951   // BUT... this means that the scrollbar should be adjusted every time 
 952   // it's scrolled, as well as when sized, because with variable size rows/cols, 
 953   // the number of rows/col visible on the view differs according to what bit 
 954   // you're looking at. The object length is always the same, but the 
 955   // view length differs. 
 957   // Since this may not be known until the end of this function, we should probably call AdjustScrollbars 
 959   int vertScrollBarWidth 
= m_scrollWidth
; 
 960   int horizScrollBarHeight 
= m_scrollWidth
; 
 961   if (m_vScrollBar 
&& !m_vScrollBar
->IsShown()) 
 962     vertScrollBarWidth 
= 0; 
 963   if (m_hScrollBar 
&& !m_hScrollBar
->IsShown()) 
 964     horizScrollBarHeight 
= 0; 
 966   int noHorizSteps 
= 0; 
 969   if (m_totalGridWidth 
+ vertScrollBarWidth 
<= cw
) 
 978     for (i 
= m_scrollPosX 
; i 
< m_totalCols
; i
++) 
 980       widthCount 
+= m_colWidths
[i
]; 
 981           // A partial bit doesn't count, we still have to scroll to see the 
 983       if (widthCount 
+ m_leftOfSheet 
+ m_verticalLabelWidth 
> (cw
-vertScrollBarWidth
)) 
 992   if (m_totalGridHeight 
+ horizScrollBarHeight 
<= ch
) 
1001     for (i 
= m_scrollPosY 
; i 
< m_totalRows
; i
++) 
1003       heightCount 
+= m_rowHeights
[i
]; 
1004           // A partial bit doesn't count, we still have to scroll to see the 
1006       if (heightCount 
+ m_topOfSheet 
+ m_horizontalLabelHeight 
> (ch
-horizScrollBarHeight
)) 
1015   if (m_totalGridWidth 
+ vertScrollBarWidth 
<= cw
) 
1018             m_hScrollBar
->Show(FALSE
); 
1024           m_hScrollBar
->Show(TRUE
); 
1027   if (m_totalGridHeight 
+ horizScrollBarHeight 
<= ch
) 
1030           m_vScrollBar
->Show(FALSE
); 
1036           m_vScrollBar
->Show(TRUE
); 
1039   UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed 
1041   vertScrollBarWidth 
= m_scrollWidth
; 
1042   horizScrollBarHeight 
= m_scrollWidth
; 
1043   if (m_vScrollBar 
&& !m_vScrollBar
->IsShown()) 
1044     vertScrollBarWidth 
= 0; 
1045   if (m_hScrollBar 
&& !m_hScrollBar
->IsShown()) 
1046     horizScrollBarHeight 
= 0; 
1048   if (m_hScrollBar 
&& m_hScrollBar
->IsShown()) 
1050     int nCols 
= GetCols(); 
1051     m_hScrollBar
->SetScrollbar(m_hScrollBar
->GetThumbPosition(), wxMax(noHorizSteps
, 1), (noHorizSteps 
== 0) ? 1 : nCols
, wxMax(noHorizSteps
, 1)); 
1054     m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2,   // why -2 ? Robert. 
1055       cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth); 
1057     m_hScrollBar
->SetSize(m_leftOfSheet
, ch 
- m_scrollWidth
, 
1058       cw 
- vertScrollBarWidth 
- m_leftOfSheet
, m_scrollWidth
); 
1062   if (m_vScrollBar 
&& m_vScrollBar
->IsShown()) 
1064     int nRows 
= GetRows(); 
1066     m_vScrollBar
->SetScrollbar(m_vScrollBar
->GetThumbPosition(), wxMax(noVertSteps
, 1), (noVertSteps 
== 0) ? 1 : nRows
, wxMax(noVertSteps
, 1)); 
1067     m_vScrollBar
->SetSize(cw 
- m_scrollWidth
, m_topOfSheet
, 
1068        m_scrollWidth
, ch 
- m_topOfSheet 
- horizScrollBarHeight
); 
1072 void wxGenericGrid::OnSize(wxSizeEvent
& WXUNUSED(event
) ) 
1074   if (!m_vScrollBar 
|| !m_hScrollBar
) 
1080   GetClientSize(&cw
, &ch
); 
1082   if (m_editCreated 
&& m_editingPanel 
&& GetTextItem() && GetTextItem()->IsShown()) 
1084     m_editingPanel
->SetSize(0, 0, cw
, m_editControlPosition
.height 
+ m_editControlPosition
.y 
+ 2); 
1085     GetTextItem()->SetSize(m_editControlPosition
.x
, m_editControlPosition
.y
, 
1086       cw 
- 2*m_editControlPosition
.x
, m_editControlPosition
.height
); 
1090 bool wxGenericGrid::CellHitTest(int x
, int y
, int *row
, int *col
) 
1092       // Find the selected cell and call OnSelectCell 
1093       if (x 
>= (m_leftOfSheet 
+ m_verticalLabelWidth
) && y 
>= (m_topOfSheet 
+ m_horizontalLabelHeight
) && 
1094           x 
<= m_rightOfSheet 
&& y 
<= m_bottomOfSheet
) 
1096          // Calculate the cell number from x and y 
1097          x 
-= (m_verticalLabelWidth 
+ m_leftOfSheet
); 
1098          y 
-= (m_topOfSheet 
+ m_horizontalLabelHeight
); 
1102          // Now we need to do a hit test for which row we're on 
1103          int currentHeight 
= 0; 
1104          for (i 
= m_scrollPosY
; i 
< m_totalRows
; i
++) 
1106             if (y 
>= currentHeight 
&& y 
<= (currentHeight 
+ m_rowHeights
[i
])) 
1111             currentHeight 
+= m_rowHeights
[i
]; 
1114          // Now we need to do a hit test for which column we're on 
1115          int currentWidth 
= 0; 
1116          for (i 
= m_scrollPosX
; i 
< m_totalCols
; i
++) 
1118             if (x 
>= currentWidth 
&& x 
<= (currentWidth 
+ m_colWidths
[i
])) 
1123             currentWidth 
+= m_colWidths
[i
]; 
1130 bool wxGenericGrid::LabelSashHitTest(int x
, int y
, int *orientation
, int *rowOrCol
, int *startPos
) 
1135   if (x 
>= (m_leftOfSheet 
+ m_verticalLabelWidth
) && y 
>= m_topOfSheet 
&& 
1136       x 
<= m_rightOfSheet 
&& y 
<= (m_topOfSheet 
+ m_horizontalLabelHeight
)) 
1138     // We may be on a column label sash. 
1139     int currentWidth 
= m_leftOfSheet 
+ m_verticalLabelWidth
; 
1140     for (i 
= m_scrollPosX
; i 
< m_totalCols
; i
++) 
1142       if (x 
>= (currentWidth 
+ m_colWidths
[i
] - tolerance
) && x 
<= (currentWidth 
+ m_colWidths
[i
] + tolerance
)) 
1144         *orientation 
= wxHORIZONTAL
; 
1146         *startPos 
= currentWidth
; 
1149       currentWidth 
+= m_colWidths
[i
]; 
1153   else if (x 
>= m_leftOfSheet 
&& y 
>= (m_topOfSheet 
+ m_horizontalLabelHeight
) && 
1154       x 
<= (m_leftOfSheet 
+ m_verticalLabelWidth
) && y 
<= m_bottomOfSheet
) 
1156     // We may be on a row label sash. 
1157     int currentHeight 
= m_topOfSheet 
+ m_horizontalLabelHeight
; 
1158     for (i 
= m_scrollPosY
; i 
< m_totalRows
; i
++) 
1160       if (y 
>= (currentHeight 
+ m_rowHeights
[i
] - tolerance
) && y 
<= (currentHeight 
+ m_rowHeights
[i
] + tolerance
)) 
1162         *orientation 
= wxVERTICAL
; 
1164         *startPos 
= currentHeight
; 
1167       currentHeight 
+= m_rowHeights
[i
]; 
1174 bool wxGenericGrid::LabelHitTest(int x
, int y
, int *row
, int *col
) 
1176       // Find the selected label 
1177       if (x 
>= m_leftOfSheet 
&& y 
>= m_topOfSheet 
&& 
1178           x 
<= m_rightOfSheet 
&& y 
<= m_bottomOfSheet
) 
1180          // Calculate the cell number from x and y 
1186          // Now we need to do a hit test for which row we're on 
1187          int currentHeight 
= m_horizontalLabelHeight
; 
1188          for (i 
= m_scrollPosY
; i 
< m_totalRows
; i
++) 
1190             if (y 
>= currentHeight 
&& y 
<= (currentHeight 
+ m_rowHeights
[i
])) 
1195             currentHeight 
+= m_rowHeights
[i
]; 
1197          if (y 
>= 0 && y 
<= m_horizontalLabelHeight
) 
1202          // Now we need to do a hit test for which column we're on 
1203          int currentWidth 
= m_verticalLabelWidth
; 
1204          for (i 
= m_scrollPosX
; i 
< m_totalCols
; i
++) 
1206             if (x 
>= currentWidth 
&& x 
<= (currentWidth 
+ m_colWidths
[i
])) 
1211             currentWidth 
+= m_colWidths
[i
]; 
1213          if (x 
>= 0 && x 
<= m_verticalLabelWidth
) 
1218          if ((*col 
== -1) || (*row 
== -1)) 
1226 void wxGenericGrid::OnMouseEvent(wxMouseEvent
& ev
) 
1230     wxClientDC 
dc(this); 
1234     if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
)) 
1236       OnSelectCellImplementation(& dc
, row
, col
); 
1238       //OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown()); 
1239       wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CELL_LCLICK
, this, 
1240                         row
, col
, (int)ev
.GetX(), (int)ev
.GetY(), 
1241                         ev
.ControlDown(), ev
.ShiftDown()); 
1242       GetEventHandler()->ProcessEvent(g_evt
); 
1245     if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
)) 
1247       //OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown()); 
1248       wxGridEvent 
g_evt(GetId(), wxEVT_GRID_LABEL_LCLICK
, this, 
1249                         row
, col
, (int)ev
.GetX(), (int)ev
.GetY(), 
1250                         ev
.ControlDown(), ev
.ShiftDown()); 
1251       GetEventHandler()->ProcessEvent(g_evt
); 
1256   else if (ev
.Dragging() && ev
.LeftIsDown()) 
1258     switch (m_dragStatus
) 
1260       case wxGRID_DRAG_NONE
: 
1263         if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &m_dragRowOrCol
, &m_dragStartPosition
)) 
1265           if (orientation 
== wxHORIZONTAL
) 
1267             m_dragStatus 
= wxGRID_DRAG_LEFT_RIGHT
; 
1268             SetCursor(m_horizontalSashCursor
); 
1269             m_dragLastPosition 
= (int)ev
.GetX(); 
1273             m_dragStatus 
= wxGRID_DRAG_UP_DOWN
; 
1274             SetCursor(m_verticalSashCursor
); 
1275             m_dragLastPosition 
= (int)ev
.GetY(); 
1277           wxClientDC 
dc(this); 
1279           dc
.SetLogicalFunction(wxINVERT
); 
1280           if (orientation 
== wxHORIZONTAL
) 
1281             dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
); 
1283             dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY()); 
1290       case wxGRID_DRAG_LEFT_RIGHT
: 
1292         wxClientDC 
dc(this); 
1294         dc
.SetLogicalFunction(wxINVERT
); 
1295         dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
); 
1297         dc
.DrawLine((int)ev
.GetX(), m_topOfSheet
, (int)ev
.GetX(), m_bottomOfSheet
); 
1300         m_dragLastPosition 
= (int)ev
.GetX(); 
1301         SetCursor(m_horizontalSashCursor
); 
1304       case wxGRID_DRAG_UP_DOWN
: 
1306         wxClientDC 
dc(this); 
1308         dc
.SetLogicalFunction(wxINVERT
); 
1309         dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
); 
1311         dc
.DrawLine(m_leftOfSheet
, (int)ev
.GetY(), m_rightOfSheet
, (int)ev
.GetY()); 
1314         m_dragLastPosition 
= (int)ev
.GetY(); 
1315         SetCursor(m_verticalSashCursor
); 
1320   else if (ev
.Moving()) 
1322     int rowOrCol
, orientation
, startPos
; 
1323     if (LabelSashHitTest((int)ev
.GetX(), (int)ev
.GetY(), &orientation
, &rowOrCol
, &startPos
)) 
1325       if (orientation 
== wxHORIZONTAL
) 
1326         SetCursor(m_horizontalSashCursor
); 
1328         SetCursor(m_verticalSashCursor
); 
1331       SetCursor(*wxSTANDARD_CURSOR
); 
1333   else if (ev
.LeftUp()) 
1335     switch (m_dragStatus
) 
1337       case wxGRID_DRAG_LEFT_RIGHT
: 
1339         wxClientDC 
dc(this); 
1341         dc
.SetLogicalFunction(wxINVERT
); 
1342         dc
.DrawLine(m_dragLastPosition
, m_topOfSheet
, m_dragLastPosition
, m_bottomOfSheet
); 
1343         dc
.SetLogicalFunction(wxCOPY
); 
1347         if (ev
.GetX() > m_dragStartPosition
) 
1349           m_colWidths
[m_dragRowOrCol
] = (short)(ev
.GetX() - m_dragStartPosition
); 
1354         SetCursor(*wxSTANDARD_CURSOR
); 
1356         GetClientSize(&cw
, &ch
); 
1361       case wxGRID_DRAG_UP_DOWN
: 
1363         wxClientDC 
dc(this); 
1365         dc
.SetLogicalFunction(wxINVERT
); 
1366         dc
.DrawLine(m_leftOfSheet
, m_dragLastPosition
, m_rightOfSheet
, m_dragLastPosition
); 
1367         dc
.SetLogicalFunction(wxCOPY
); 
1371         if (ev
.GetY() > m_dragStartPosition
) 
1373           m_rowHeights
[m_dragRowOrCol
] = (short)(ev
.GetY() - m_dragStartPosition
); 
1378         SetCursor(*wxSTANDARD_CURSOR
); 
1382     m_dragStatus 
= wxGRID_DRAG_NONE
; 
1384   else if (ev
.RightDown()) 
1387     if (CellHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
)) 
1389       //OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown()); 
1390       wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CELL_RCLICK
, this, 
1391                         row
, col
, (int)ev
.GetX(), (int)ev
.GetY(), 
1392                         ev
.ControlDown(), ev
.ShiftDown()); 
1393       GetEventHandler()->ProcessEvent(g_evt
); 
1396     if (LabelHitTest((int)ev
.GetX(), (int)ev
.GetY(), &row
, &col
)) 
1398       //OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown()); 
1399       wxGridEvent 
g_evt(GetId(), wxEVT_GRID_LABEL_RCLICK
, this, 
1400                         row
, col
, (int)ev
.GetX(), (int)ev
.GetY(), 
1401                         ev
.ControlDown(), ev
.ShiftDown()); 
1402       GetEventHandler()->ProcessEvent(g_evt
); 
1407 void wxGenericGrid::OnSelectCellImplementation(wxDC 
*dc
, int row
, int col
) 
1409   m_wCursorColumn 
= col
; 
1412   //OnChangeSelectionLabel(); 
1413   wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL
, this); 
1414   GetEventHandler()->ProcessEvent(g_evt
); 
1416   SetGridClippingRegion(dc
); 
1418   // Remove the highlight from the old cell 
1419   if ( m_currentRectVisible 
&& !(m_editable 
&& m_editInPlace
) ) 
1425   // Highlight the new cell and copy its content to the edit control 
1426   SetCurrentRect(m_wCursorRow
, m_wCursorColumn
); 
1427   wxGridCell 
*cell 
= GetCell(m_wCursorRow
, m_wCursorColumn
); 
1430         if ( cell
->GetTextValue().IsNull() ) 
1431                 m_textItem
->SetValue(""); 
1433             m_textItem
->SetValue(cell
->GetTextValue()); 
1436   SetGridClippingRegion(dc
); 
1439   if ( m_editable 
&& m_editInPlace 
) 
1441       m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2, 
1442                                   m_currentRect
.width
+4, m_currentRect
.height
+4 ); 
1446           if ( cell
->GetTextValue().IsNull() ) 
1448               m_inPlaceTextItem
->SetValue( "" ); 
1452               m_inPlaceTextItem
->SetFont( cell
->GetFont() ); 
1453               m_inPlaceTextItem
->SetValue( cell
->GetTextValue() ); 
1457       m_inPlaceTextItem
->Show(TRUE
); 
1458       m_inPlaceTextItem
->SetFocus(); 
1462       // 1) Why isn't this needed for Windows?? 
1463       // Probably because of the SetValue?? JS. 
1464       // 2) Arrrrrgh. This isn't needed anywhere, 
1465       // of course. One hour of debugging... RR. 
1467       // 3) It *is* needed for Motif - michael 
1470       if ( !(m_editable 
&& m_editInPlace
) ) 
1475   dc
->DestroyClippingRegion(); 
1477   OnSelectCell(row
, col
); 
1478   wxGridEvent 
g_evt2(GetId(), wxEVT_GRID_SELECT_CELL
, this, row
, col
); 
1479   GetEventHandler()->ProcessEvent(g_evt2
); 
1482 wxGridCell 
*wxGenericGrid::OnCreateCell(void) 
1484   return new wxGridCell(this); 
1487 void wxGenericGrid::OnChangeLabels(void) 
1491   for (i 
= 0; i 
< m_totalRows
; i
++) 
1493     sprintf(buf
, "%d", i
+1); 
1494     SetLabelValue(wxVERTICAL
, buf
, i
); 
1496   // A...Z,AA...ZZ,AAA...ZZZ, etc. 
1497   for (i 
= 0; i 
< m_totalCols
; i
++) 
1500     int noTimes 
= (i
/26 + 1); 
1501     int ch 
= (i 
% 26) + 65; 
1503     for (j 
= 0; j 
< noTimes
; j
++) 
1506       sprintf(buf2
, "%c", (char)ch
); 
1509     SetLabelValue(wxHORIZONTAL
, buf
, i
); 
1513 void wxGenericGrid::OnChangeSelectionLabel(void) 
1518   wxString 
rowLabel(GetLabelValue(wxVERTICAL
, GetCursorRow())); 
1519   wxString 
colLabel(GetLabelValue(wxHORIZONTAL
, GetCursorColumn())); 
1521   wxString newLabel 
= colLabel 
+ rowLabel
; 
1522   if ((newLabel
.Length() > 0) && (newLabel
.Length() <= 8) && GetTextItem()) 
1524 //    GetTextItem()->SetLabel(newLabel); 
1528 void wxGenericGrid::HighlightCell(wxDC 
*dc
) 
1530   dc
->SetLogicalFunction(wxINVERT
); 
1533   dc
->DrawLine( m_currentRect
.x 
+ 1, 
1534                 m_currentRect
.y 
+ 1, 
1535                 m_currentRect
.x 
+ m_currentRect
.width 
- 1, 
1536                 m_currentRect
.y 
+ 1); 
1538   dc
->DrawLine( m_currentRect
.x 
+ m_currentRect
.width 
- 1, 
1539                 m_currentRect
.y 
+ 1, 
1540                 m_currentRect
.x 
+ m_currentRect
.width 
- 1, 
1541                 m_currentRect
.y 
+m_currentRect
.height 
- 1 ); 
1543   dc
->DrawLine( m_currentRect
.x 
+ m_currentRect
.width 
- 1, 
1544                 m_currentRect
.y 
+ m_currentRect
.height 
- 1, 
1545                 m_currentRect
.x 
+ 1, 
1546                 m_currentRect
.y 
+ m_currentRect
.height 
- 1); 
1548   dc
->DrawLine( m_currentRect
.x 
+ 1, 
1549                 m_currentRect
.y 
+ m_currentRect
.height 
- 1, 
1550                 m_currentRect
.x 
+ 1, 
1551                 m_currentRect
.y 
+ 1); 
1553   dc
->SetLogicalFunction(wxCOPY
); 
1556 void wxGenericGrid::DrawCellText(void) 
1558   if (!m_currentRectVisible
) 
1561   wxGridCell 
*cell 
= GetCell(GetCursorRow(), GetCursorColumn()); 
1565   wxClientDC 
dc(this); 
1568   SetGridClippingRegion(& dc
); 
1570   dc
.SetBackgroundMode(wxTRANSPARENT
); 
1571   dc
.SetBrush(cell
->GetBackgroundBrush()); 
1573   wxString editValue 
= m_textItem
->GetValue(); 
1576   rect 
= m_currentRect
; 
1582   // FIXME: what's this string of spaces supposed to represent? 
1583   DrawTextRect(& dc
, "                                    ", &rect
, wxLEFT
); 
1584   DrawTextRect(& dc
, editValue
, &rect
, cell
->GetAlignment()); 
1586   dc
.DestroyClippingRegion(); 
1588   dc
.SetBackgroundMode(wxSOLID
); 
1593 void wxGenericGrid::SetCurrentRect(int Row
, int Column
, int canvasW
, int canvasH
) 
1595   int currentWidth 
= m_leftOfSheet 
+ m_verticalLabelWidth
; 
1597   for (i 
= m_scrollPosX
; i 
< Column
; i
++) 
1598     currentWidth 
+= m_colWidths
[i
]; 
1600   int currentHeight 
= m_topOfSheet 
+ m_horizontalLabelHeight
; 
1601   for (i 
= m_scrollPosY
; i 
< Row
; i
++) 
1602     currentHeight 
+= m_rowHeights
[i
]; 
1604   m_currentRect
.x 
= currentWidth
; 
1605   m_currentRect
.y 
= currentHeight
; 
1606   m_currentRect
.width 
= m_colWidths 
? (m_colWidths
[Column
]) : 0; 
1607   m_currentRect
.height 
= m_rowHeights 
? (m_rowHeights
[Row
]) : 0; 
1609   if (Row 
< m_scrollPosY 
|| Column 
< m_scrollPosX
) 
1610     m_currentRectVisible 
= FALSE
; 
1611   else if ((canvasW 
!= -1 && canvasH 
!= -1) && (m_currentRect
.x 
> canvasW 
|| m_currentRect
.y 
> canvasH
)) 
1612     m_currentRectVisible 
= FALSE
; 
1613   else m_currentRectVisible 
= TRUE
; 
1616 static bool wxRectIntersection(wxRect 
*rect1
, wxRect 
*rect2
, wxRect 
*rect3
) 
1618   int x2_1 
= rect1
->x 
+ rect1
->width
; 
1619   int y2_1 
= rect1
->y 
+ rect1
->height
; 
1621   int x2_2 
= rect2
->x 
+ rect2
->width
; 
1622   int y2_2 
= rect2
->y 
+ rect2
->height
; 
1626   // Check for intersection 
1627   if ((rect1
->x 
> x2_2
) || (rect2
->x 
> x2_1
) || 
1628       (rect1
->y 
> y2_2
) || (rect2
->y 
> y2_1
)) 
1631     rect3
->x 
= rect3
->y 
= rect3
->width 
= rect3
->height 
= 0; 
1635   if (rect1
->x 
> rect2
->x
) 
1636     rect3
->x 
= rect1
->x
; 
1638     rect3
->x 
= rect2
->x
; 
1639   if (rect1
->y 
> rect2
->y
) 
1640     rect3
->y 
= rect1
->y
; 
1642     rect3
->y 
= rect2
->y
; 
1653   rect3
->width 
= (int)(x2_3 
- rect3
->x
); 
1654   rect3
->height 
= (int)(y2_3 
- rect3
->y
); 
1658 void wxGenericGrid::DrawTextRect(wxDC 
*dc
, const wxString
& text
, wxRect 
*rect
, int flag
) 
1662   // Ultimately, this functionality should be built into wxWindows, 
1663   // and optimized for each platform. E.g. on Windows, use DrawText 
1664   // passing a clipping rectangle, so that the wxWindows clipping region 
1665   // does not have to be used to implement this. 
1667   // If we're already clipping, we need to find the intersection 
1668   // between current clipping area and text clipping area. 
1672   long clipX
, clipY
, clipW
, clipH
; 
1673   dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
); 
1674   clipRect
.x 
= (int)clipX
; clipRect
.y 
= (int)clipY
; 
1675   clipRect
.width 
= (int)clipW
; clipRect
.height 
= (int)clipH
; 
1677   bool alreadyClipping 
= TRUE
; 
1679   if (clipRect
.x 
== 0 && clipRect
.y 
== 0 && clipRect
.width 
== 0 && clipRect
.height 
== 0) 
1681     alreadyClipping 
= FALSE
; 
1682     clipRect2
.x 
= rect
->x
; clipRect2
.y 
= rect
->y
; 
1683     clipRect2
.width 
= rect
->width
; clipRect2
.height 
= rect
->height
; 
1687     // Find intersection. 
1688     if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
)) 
1692   if (alreadyClipping
) 
1693     dc
->DestroyClippingRegion(); 
1695   dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
); 
1696   long textWidth
, textHeight
; 
1698   dc
->GetTextExtent(text
, &textWidth
, &textHeight
); 
1706       x 
= (rect
->x 
+ rect
->width 
- textWidth 
- 1.0); 
1707       y 
= (rect
->y 
+ (rect
->height 
- textHeight
)/2.0); 
1712       x 
= (rect
->x 
+ (rect
->width 
- textWidth
)/2.0); 
1713       y 
= (rect
->y 
+ (rect
->height 
- textHeight
)/2.0); 
1719       x 
= (rect
->x 
+ 1.0); 
1720       y 
= (rect
->y 
+ (rect
->height 
- textHeight
)/2.0); 
1724   dc
->DrawText(text
, (long)x
, (long)y 
); 
1726   dc
->DestroyClippingRegion(); 
1728   // Restore old clipping 
1729   if (alreadyClipping
) 
1730     dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
); 
1735 void wxGenericGrid::DrawBitmapRect(wxDC 
*dc
, wxBitmap 
*bitmap
, wxRect 
*rect
, int flag
) 
1739   // Ultimately, this functionality should be built into wxWindows, 
1740   // and optimized for each platform. E.g. on Windows, use DrawText 
1741   // passing a clipping rectangle, so that the wxWindows clipping region 
1742   // does not have to be used to implement this. 
1744   // If we're already clipping, we need to find the intersection 
1745   // between current clipping area and text clipping area. 
1749   long clipX
, clipY
, clipW
, clipH
; 
1750   dc
->GetClippingBox(&clipX
, &clipY
, &clipW
, &clipH
); 
1751   clipRect
.x 
= (int)clipX
; clipRect
.y 
= (int)clipY
; 
1752   clipRect
.width 
= (int)clipW
; clipRect
.height 
= (int)clipH
; 
1754   bool alreadyClipping 
= TRUE
; 
1756   if (clipRect
.x 
== 0 && clipRect
.y 
== 0 && clipRect
.width 
== 0 && clipRect
.height 
== 0) 
1758     alreadyClipping 
= FALSE
; 
1759     clipRect2
.x 
= rect
->x
; clipRect2
.y 
= rect
->y
; 
1760     clipRect2
.width 
= rect
->width
; clipRect2
.height 
= rect
->height
; 
1764     // Find intersection. 
1765     if (!wxRectIntersection(rect
, &clipRect
, &clipRect2
)) 
1769   if (alreadyClipping
) 
1770     dc
->DestroyClippingRegion(); 
1772   dc
->SetClippingRegion(clipRect2
.x
, clipRect2
.y
, clipRect2
.width
, clipRect2
.height
); 
1773   float bitmapWidth
, bitmapHeight
; 
1775   bitmapWidth 
= bitmap
->GetWidth(); 
1776   bitmapHeight 
= bitmap
->GetHeight(); 
1784       x 
= (long)(rect
->x 
+ rect
->width 
- bitmapWidth 
- 1); 
1785       y 
= (long)(rect
->y 
+ (rect
->height 
- bitmapHeight
)/2.0); 
1790       x 
= (long)(rect
->x 
+ (rect
->width 
- bitmapWidth
)/2.0); 
1791       y 
= (long)(rect
->y 
+ (rect
->height 
- bitmapHeight
)/2.0); 
1797       x 
= (long)(rect
->x 
+ 1); 
1798       y 
= (long)(rect
->y 
+ (rect
->height 
- bitmapHeight
)/2.0); 
1803   dcTemp
.SelectObject(*bitmap
); 
1805   dc
->Blit( (long)x
, (long)y
, (long)bitmapWidth
, (long)bitmapHeight
, &dcTemp
, 0, 0); 
1806   dcTemp
.SelectObject(wxNullBitmap
); 
1808   dc
->DestroyClippingRegion(); 
1810   // Restore old clipping 
1811   if (alreadyClipping
) 
1812     dc
->SetClippingRegion(clipRect
.x
, clipRect
.y
, clipRect
.width
, clipRect
.height
); 
1817 void wxGenericGrid::OnActivate(bool active
) 
1821     // Edit control should always have the focus 
1822     if (GetTextItem() && GetEditable()) 
1824       GetTextItem()->SetFocus(); 
1825       wxGridCell 
*cell 
= GetCell(GetCursorRow(), GetCursorColumn()); 
1827         GetTextItem()->SetValue(cell
->GetTextValue()); 
1832 void wxGenericGrid::SetCellValue(const wxString
& val
, int row
, int col
) 
1834   wxGridCell 
*cell 
= GetCell(row
, col
); 
1837     cell
->SetTextValue(val
); 
1839     RefreshCell(row
, col
, TRUE
); 
1843 void wxGenericGrid::RefreshCell(int row
, int col
, bool setText
) 
1845     // Don't refresh within a pair of batch brackets 
1846     if (GetBatchCount() > 0) 
1850     GetClientSize(&cw
, &ch
); 
1852     SetCurrentRect(row
, col
, cw
, ch
); 
1853     if (m_currentRectVisible
) 
1855       wxGridCell 
*cell 
= GetCell(row
, col
); 
1857       bool currentPos 
= FALSE
; 
1858       if (row 
== m_wCursorRow 
&& col 
== m_wCursorColumn 
&& GetTextItem() && GetTextItem()->IsShown() && setText
) 
1860         GetTextItem()->SetValue(cell
->GetTextValue()); 
1863       // Gets refreshed anyway in MSW 
1868         wxClientDC 
dc(this); 
1870         DrawCellBackground(& dc
, &m_currentRect
, row
, col
); 
1871         DrawCellValue(& dc
, &m_currentRect
, row
, col
); 
1877 wxString
& wxGenericGrid::GetCellValue(int row
, int col
) const 
1879   static wxString 
emptyString(""); 
1881   wxGridCell 
*cell 
= GetCell(row
, col
); 
1883     return cell
->GetTextValue(); 
1888 void wxGenericGrid::SetColumnWidth(int col
, int width
) 
1890   if (col 
<= m_totalCols
) 
1891     m_colWidths
[col
] = width
; 
1894 int wxGenericGrid::GetColumnWidth(int col
) const 
1896   if (col 
<= m_totalCols
) 
1897     return m_colWidths
[col
]; 
1902 void wxGenericGrid::SetRowHeight(int row
, int height
) 
1904   if (row 
<= m_totalRows
) 
1905     m_rowHeights
[row
] = height
; 
1908 int wxGenericGrid::GetRowHeight(int row
) const 
1910   if (row 
<= m_totalRows
) 
1911     return m_rowHeights
[row
]; 
1916 void wxGenericGrid::SetLabelSize(int orientation
, int sz
) 
1918   if (orientation 
== wxHORIZONTAL
) 
1919     m_horizontalLabelHeight 
= sz
; 
1921     m_verticalLabelWidth 
= sz
; 
1923   SetCurrentRect(GetCursorRow(), GetCursorColumn()); 
1926 int wxGenericGrid::GetLabelSize(int orientation
) const 
1928   if (orientation 
== wxHORIZONTAL
) 
1929     return m_horizontalLabelHeight
; 
1931     return m_verticalLabelWidth
; 
1934 wxGridCell 
*wxGenericGrid::GetLabelCell(int orientation
, int pos
) const 
1936   if (orientation 
== wxHORIZONTAL
) 
1938     if (m_colLabelCells 
&& pos 
< m_totalCols
) 
1939       return m_colLabelCells
[pos
]; 
1941       return (wxGridCell 
*) NULL
; 
1945     if (m_rowLabelCells 
&& pos 
< m_totalRows
) 
1946       return m_rowLabelCells
[pos
]; 
1948       return (wxGridCell 
*) NULL
; 
1952 void wxGenericGrid::SetLabelValue(int orientation
, const wxString
& val
, int pos
) 
1954   wxGridCell 
*cell 
= GetLabelCell(orientation
, pos
); 
1956     cell
->SetTextValue(val
); 
1959 wxString
& wxGenericGrid::GetLabelValue(int orientation
, int pos
) const 
1961  static wxString emptyString 
= ""; 
1962   wxGridCell 
*cell 
= GetLabelCell(orientation
, pos
); 
1964     return cell
->GetTextValue(); 
1969 void wxGenericGrid::SetLabelAlignment(int orientation
, int align
) 
1971   if (orientation 
== wxHORIZONTAL
) 
1972     m_horizontalLabelAlignment 
= align
; 
1974     m_verticalLabelAlignment 
= align
; 
1976   SetCurrentRect(GetCursorRow(), GetCursorColumn()); 
1979 int wxGenericGrid::GetLabelAlignment(int orientation
) const 
1981   if (orientation 
== wxHORIZONTAL
) 
1982     return m_horizontalLabelAlignment
; 
1984     return m_verticalLabelAlignment
; 
1987 void wxGenericGrid::SetLabelTextColour(const wxColour
& colour
) 
1989   m_labelTextColour 
= colour
; 
1993 void wxGenericGrid::SetLabelBackgroundColour(const wxColour
& colour
) 
1995   m_labelBackgroundColour 
= colour
; 
1996   m_labelBackgroundBrush 
= * wxTheBrushList
->FindOrCreateBrush(m_labelBackgroundColour
, wxSOLID
); 
1999 void wxGenericGrid::SetEditable(bool edit
) 
2004     int controlW
, controlH
; 
2005     m_textItem
->GetSize(&controlW
, &controlH
); 
2006     m_editControlPosition
.height 
= controlH
; 
2008     m_topOfSheet 
= m_editControlPosition
.x 
+ controlH 
+ 2; 
2011       m_editingPanel
->Show(TRUE
); 
2012       m_textItem
->Show(TRUE
); 
2013       m_textItem
->SetFocus(); 
2016     if (m_inPlaceTextItem
) 
2018         m_inPlaceTextItem
->Show(TRUE
); 
2019         m_inPlaceTextItem
->SetFocus(); 
2027       m_textItem
->Show(FALSE
); 
2028       m_editingPanel
->Show(FALSE
); 
2031     if ( m_inPlaceTextItem 
) 
2033         m_inPlaceTextItem
->Show(FALSE
); 
2037   SetCurrentRect(GetCursorRow(), GetCursorColumn()); 
2040   GetClientSize(&cw
, &ch
); 
2045   int m_scrollWidth = 16; 
2046   GetClientSize(&cw, &ch); 
2049     m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet, 
2050        m_scrollWidth, ch - m_topOfSheet - m_scrollWidth); 
2055 void wxGenericGrid::SetEditInPlace(bool edit
) 
2057   if ( m_editInPlace 
!= edit 
) 
2059       m_editInPlace 
= edit
; 
2061       if ( m_editInPlace 
)  // switched on 
2063           if ( m_currentRectVisible 
&& m_editable 
) 
2065               m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2, 
2066                                           m_currentRect
.width
+4, m_currentRect
.height
+4 ); 
2068               wxGridCell 
*cell 
= GetCell(m_wCursorRow
, m_wCursorColumn
); 
2072                   if ( cell
->GetTextValue().IsNull() ) 
2074                       m_inPlaceTextItem
->SetValue( "" ); 
2078                       m_inPlaceTextItem
->SetFont( cell
->GetFont() ); 
2079                       m_inPlaceTextItem
->SetValue( cell
->GetTextValue() ); 
2083               m_inPlaceTextItem
->Show( TRUE 
); 
2084               m_inPlaceTextItem
->SetFocus(); 
2087       else  // switched off 
2089           m_inPlaceTextItem
->Show( FALSE 
); 
2095 void wxGenericGrid::SetCellAlignment(int flag
, int row
, int col
) 
2097   wxGridCell 
*cell 
= GetCell(row
, col
); 
2099     cell
->SetAlignment(flag
); 
2102 int wxGenericGrid::GetCellAlignment(int row
, int col
) const 
2104   wxGridCell 
*cell 
= GetCell(row
, col
); 
2106     return cell
->GetAlignment(); 
2108     return m_cellAlignment
; 
2111 void wxGenericGrid::SetCellAlignment(int flag
) 
2113   m_cellAlignment 
= flag
; 
2115   for (i 
= 0; i 
< GetRows(); i
++) 
2116     for (j 
= 0; j 
< GetCols(); j
++) 
2118         GetCell(i
, j
)->SetAlignment(flag
); 
2121 int wxGenericGrid::GetCellAlignment(void) const 
2123   return m_cellAlignment
; 
2126 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& col
) 
2128   m_cellBackgroundColour 
= col
; 
2130   for (i 
= 0; i 
< GetRows(); i
++) 
2131     for (j 
= 0; j 
< GetCols(); j
++) 
2133         GetCell(i
, j
)->SetBackgroundColour(col
); 
2136 void wxGenericGrid::SetCellBackgroundColour(const wxColour
& val
, int row
, int col
) 
2138   wxGridCell 
*cell 
= GetCell(row
, col
); 
2141     cell
->SetBackgroundColour(val
); 
2142     RefreshCell(row
, col
); 
2146 wxColour
& wxGenericGrid::GetCellBackgroundColour(int row
, int col
) const 
2148   wxGridCell 
*cell 
= GetCell(row
, col
); 
2150     return cell
->GetBackgroundColour(); 
2152     return (wxColour
&) m_cellBackgroundColour
; 
2155 void wxGenericGrid::SetCellTextColour(const wxColour
& val
, int row
, int col
) 
2157   wxGridCell 
*cell 
= GetCell(row
, col
); 
2160     cell
->SetTextColour(val
); 
2161     RefreshCell(row
, col
); 
2165 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
, int row
, int col
) 
2167   wxGridCell 
*cell 
= GetCell(row
, col
); 
2171     RefreshCell(row
, col
); 
2175 wxFont
& wxGenericGrid::GetCellTextFont(int row
, int col
) const 
2177   wxGridCell 
*cell 
= GetCell(row
, col
); 
2179     return (wxFont
&) cell
->GetFont(); 
2181     return (wxFont
&) m_cellTextFont
; 
2184 wxColour
& wxGenericGrid::GetCellTextColour(int row
, int col
) const 
2186   wxGridCell 
*cell 
= GetCell(row
, col
); 
2188     return (wxColour
&) cell
->GetTextColour(); 
2190     return (wxColour
&) m_cellTextColour
; 
2193 void wxGenericGrid::SetCellTextColour(const wxColour
& val
) 
2195   m_cellTextColour 
= val
; 
2197   for (i 
= 0; i 
< GetRows(); i
++) 
2198     for (j 
= 0; j 
< GetCols(); j
++) 
2200         GetCell(i
, j
)->SetTextColour(val
); 
2203 void wxGenericGrid::SetCellTextFont(const wxFont
& fnt
) 
2205   m_cellTextFont 
= fnt
; 
2207   for (i 
= 0; i 
< GetRows(); i
++) 
2208     for (j 
= 0; j 
< GetCols(); j
++) 
2210         GetCell(i
, j
)->SetFont(fnt
); 
2213 void wxGenericGrid::SetCellBitmap(wxBitmap 
*bitmap
, int row
, int col
) 
2215   wxGridCell 
*cell 
= GetCell(row
, col
); 
2218     cell
->SetCellBitmap(bitmap
); 
2219     RefreshCell(row
, col
); 
2223 wxBitmap 
*wxGenericGrid::GetCellBitmap(int row
, int col
) const 
2225   wxGridCell 
*cell 
= GetCell(row
, col
); 
2228     return cell
->GetCellBitmap(); 
2231     return (wxBitmap 
*) NULL
; 
2234 bool wxGenericGrid::InsertCols(int pos
, int n
, bool updateLabels
) 
2236   if (pos 
> m_totalCols
) 
2240     return CreateGrid(1, n
); 
2245     for (i 
= 0; i 
< m_totalRows
; i
++) 
2247       wxGridCell 
**cols 
= m_gridCells
[i
]; 
2248       wxGridCell 
**newCols 
= new wxGridCell 
*[m_totalCols 
+ n
]; 
2249       for (j 
= 0; j 
< pos
; j
++) 
2250         newCols
[j
] = cols
[j
]; 
2251       for (j 
= pos
; j 
< pos 
+ n
; j
++) 
2252         newCols
[j
] = new wxGridCell(this); 
2253       for (j 
= pos 
+ n
; j 
< m_totalCols 
+ n
; j
++) 
2254         newCols
[j
] = cols
[j 
- n
]; 
2257       m_gridCells
[i
] = newCols
; 
2261     short *newColWidths 
= new short[m_totalCols 
+ n
]; 
2262     for (j 
= 0; j 
< pos
; j
++) 
2263       newColWidths
[j
] = m_colWidths
[j
]; 
2264     for (j 
= pos
; j 
< pos 
+ n
; j
++) 
2265       newColWidths
[j
] = wxGRID_DEFAULT_CELL_WIDTH
; 
2266     for (j 
= pos 
+ n
; j 
< m_totalCols 
+ n
; j
++) 
2267       newColWidths
[j
] = m_colWidths
[j 
- n
]; 
2268     delete[] m_colWidths
; 
2269     m_colWidths 
= newColWidths
; 
2272     wxGridCell 
**newLabels 
= new wxGridCell 
*[m_totalCols 
+ n
]; 
2273     for (j 
= 0; j 
< pos
; j
++) 
2274       newLabels
[j
] = m_colLabelCells
[j
]; 
2275     for (j 
= pos
; j 
< pos 
+ n
; j
++) 
2276       newLabels
[j
] = new wxGridCell(this); 
2277     for (j 
= pos 
+ n
; j 
< m_totalCols 
+ n
; j
++) 
2278       newLabels
[j
] = m_colLabelCells
[j 
- n
]; 
2280     delete[] m_colLabelCells
; 
2281     m_colLabelCells 
= newLabels
; 
2287         wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this); 
2288         GetEventHandler()->ProcessEvent(g_evt
); 
2297 bool wxGenericGrid::InsertRows(int pos
, int n
, bool updateLabels
) 
2299   if (pos 
> m_totalRows
) 
2303     return CreateGrid(n
, 1); 
2308     wxGridCell 
***rows 
= new wxGridCell 
**[m_totalRows 
+ n
]; 
2311     for (i 
= 0; i 
< pos
; i
++) 
2312       rows
[i
] = m_gridCells
[i
]; 
2314     for (i 
= pos
; i 
< pos 
+ n
; i
++) 
2316       rows
[i
] = new wxGridCell 
*[m_totalCols
]; 
2317       for (j 
= 0; j 
< m_totalCols
; j
++) 
2318         rows
[i
][j
] = new wxGridCell(this); 
2321     for (i 
= pos 
+ n
; i 
< m_totalRows 
+ n
; i
++) 
2322       rows
[i
] = m_gridCells
[i 
- n
]; 
2324     delete[] m_gridCells
; 
2328     short *newRowHeights 
= new short[m_totalRows 
+ n
]; 
2329     for (i 
= 0; i 
< pos
; i
++) 
2330       newRowHeights
[i
] = m_rowHeights
[i
]; 
2331     for (i 
= pos
; i 
< pos 
+ n
; i
++) 
2332       newRowHeights
[i
] = wxGRID_DEFAULT_CELL_HEIGHT
; 
2333     for (i 
= pos 
+ n
; i 
< m_totalRows 
+ n
; i
++) 
2334       newRowHeights
[i
] = m_rowHeights
[i 
- n
]; 
2335     delete[] m_rowHeights
; 
2336     m_rowHeights 
= newRowHeights
; 
2339     wxGridCell 
**newLabels 
= new wxGridCell 
*[m_totalRows 
+ n
]; 
2340     for (i 
= 0; i 
< pos
; i
++) 
2341       newLabels
[i
] = m_rowLabelCells
[i
]; 
2342     for (i 
= pos
; i 
< pos 
+ n
; i
++) 
2343       newLabels
[i
] = new wxGridCell(this); 
2344     for (i 
= pos 
+ n
; i 
< m_totalRows 
+ n
; i
++) 
2345       newLabels
[i
] = m_rowLabelCells
[i 
- n
]; 
2347     delete[] m_rowLabelCells
; 
2348     m_rowLabelCells 
= newLabels
; 
2354           wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this); 
2355           GetEventHandler()->ProcessEvent(g_evt
); 
2364 bool wxGenericGrid::AppendCols(int n
, bool updateLabels
) 
2366   return InsertCols(GetCols(), n
, updateLabels
); 
2369 bool wxGenericGrid::AppendRows(int n
, bool updateLabels
) 
2371   return InsertRows(GetRows(), n
, updateLabels
); 
2374 bool wxGenericGrid::DeleteRows(int pos
, int n
, bool updateLabels
) 
2376   if (pos 
> m_totalRows
) 
2383   wxGridCell 
***rows 
= new wxGridCell 
**[m_totalRows 
- n
]; 
2386   for (i 
= 0; i 
< pos
; i
++) 
2387     rows
[i
] = m_gridCells
[i
]; 
2389   for (i 
= pos 
+ n
; i 
< m_totalRows
; i
++) 
2390     rows
[i
-n
] = m_gridCells
[i
]; 
2392   delete[] m_gridCells
; 
2396   short *newRowHeights 
= new short[m_totalRows 
- n
]; 
2397   for (i 
= 0; i 
< pos
; i
++) 
2398     newRowHeights
[i
] = m_rowHeights
[i
]; 
2399   for (i 
= pos 
+ n
; i 
< m_totalRows
; i
++) 
2400     newRowHeights
[i
-n
] = m_rowHeights
[i
]; 
2401   delete[] m_rowHeights
; 
2402   m_rowHeights 
= newRowHeights
; 
2405   wxGridCell 
**newLabels 
= new wxGridCell 
*[m_totalRows 
- n
]; 
2406   for (i 
= 0; i 
< pos
; i
++) 
2407     newLabels
[i
] = m_rowLabelCells
[i
]; 
2408   for (i 
= pos 
+ n
; i 
< m_totalRows
; i
++) 
2409     newLabels
[i
-n
] = m_rowLabelCells
[i
]; 
2411   delete[] m_rowLabelCells
; 
2412   m_rowLabelCells 
= newLabels
; 
2418         wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this); 
2419         GetEventHandler()->ProcessEvent(g_evt
); 
2426 bool wxGenericGrid::DeleteCols(int pos
, int n
, bool updateLabels
) 
2428   if (pos 
+ n 
> m_totalCols
) 
2436   for (i 
= 0; i 
< m_totalRows
; i
++) 
2438       wxGridCell 
**cols 
= m_gridCells
[i
]; 
2439       wxGridCell 
**newCols 
= new wxGridCell 
*[m_totalCols 
- n
]; 
2440       for (j 
= 0; j 
< pos
; j
++) 
2441         newCols
[j
] = cols
[j
]; 
2442       for (j 
= pos
; j 
< pos 
+ n
; j
++) 
2444       for (j 
= pos 
+ n
; j 
< m_totalCols
; j
++) 
2445         newCols
[j
-n
] = cols
[j
]; 
2448       m_gridCells
[i
] = newCols
; 
2452   short *newColWidths 
= new short[m_totalCols 
- n
]; 
2453   for (j 
= 0; j 
< pos
; j
++) 
2454     newColWidths
[j
] = m_colWidths
[j
]; 
2455   for (j 
= pos 
+ n
; j 
< m_totalCols
; j
++) 
2456     newColWidths
[j
-n
] = m_colWidths
[j
]; 
2457   delete[] m_colWidths
; 
2458   m_colWidths 
= newColWidths
; 
2461   wxGridCell 
**newLabels 
= new wxGridCell 
*[m_totalCols 
- n
]; 
2462   for (j 
= 0; j 
< pos
; j
++) 
2463     newLabels
[j
] = m_colLabelCells
[j
]; 
2464   for (j 
= pos 
+ n
; j 
< m_totalCols
; j
++) 
2465     newLabels
[j
-n
] = m_colLabelCells
[j
]; 
2467   delete[] m_colLabelCells
; 
2468   m_colLabelCells 
= newLabels
; 
2474         wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS
, this); 
2475         GetEventHandler()->ProcessEvent(g_evt
); 
2482 void wxGenericGrid::SetGridCursor(int row
, int col
) 
2484   if (row 
>= m_totalRows 
|| col 
>= m_totalCols
) 
2487   if (row 
== GetCursorRow() && col 
== GetCursorColumn()) 
2490   wxClientDC 
dc(this); 
2493   SetGridClippingRegion(& dc
); 
2495   if (m_currentRectVisible 
&& !(m_editable 
&& m_editInPlace
) ) 
2496     HighlightCell(& dc
); 
2499   m_wCursorColumn 
= col
; 
2502   GetClientSize(&cw
, &ch
); 
2504   SetCurrentRect(row
, col
, cw
, ch
); 
2506   if (m_currentRectVisible 
&& !(m_editable 
&& m_editInPlace
) ) 
2507     HighlightCell(& dc
); 
2509   dc
.DestroyClippingRegion(); 
2517 wxGridCell::wxGridCell(wxGenericGrid 
*window
) 
2519   cellBitmap 
= (wxBitmap 
*) NULL
; 
2521   backgroundBrush 
= wxNullBrush
; 
2523     textColour 
= window
->GetCellTextColour(); 
2525     textColour
.Set(0,0,0); 
2527     backgroundColour 
= window
->GetCellBackgroundColour(); 
2529     backgroundColour
.Set(255,255,255); 
2532     font 
= window
->GetCellTextFont(); 
2534     font 
= * wxTheFontList
->FindOrCreateFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
); 
2536   SetBackgroundColour(backgroundColour
); 
2539     alignment 
= window
->GetCellAlignment(); 
2544 wxGridCell::~wxGridCell(void) 
2548 void wxGridCell::SetBackgroundColour(const wxColour
& colour
) 
2550   backgroundColour 
= colour
; 
2551   backgroundBrush 
= * wxTheBrushList
->FindOrCreateBrush(backgroundColour
, wxSOLID
); 
2554 void wxGenericGrid::OnText(wxCommandEvent
& WXUNUSED(ev
) ) 
2556   // michael - added this conditional to prevent change to 
2557   // grid cell text when edit control is hidden but still has 
2562       wxGenericGrid 
*grid 
= this; 
2563       wxGridCell 
*cell 
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn()); 
2564       if (cell 
&& grid
->CurrentCellVisible()) 
2566           cell
->SetTextValue(grid
->GetTextItem()->GetValue()); 
2567           if ( m_editInPlace 
&& !m_inOnTextInPlace 
) 
2569               m_inPlaceTextItem
->SetValue( grid
->GetTextItem()->GetValue() ); 
2572           wxClientDC 
dc(grid
); 
2575           grid
->SetGridClippingRegion(& dc
); 
2576           grid
->DrawCellBackground(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn()); 
2577           grid
->DrawCellValue(& dc
, &grid
->GetCurrentRect(), grid
->GetCursorRow(), grid
->GetCursorColumn()); 
2578           if ( !(m_editable 
&& m_editInPlace 
) ) grid
->HighlightCell(& dc
); 
2579           dc
.DestroyClippingRegion(); 
2582           //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn()); 
2583           wxGridEvent 
g_evt(GetId(), wxEVT_GRID_CELL_CHANGE
, grid
, 
2584                             grid
->GetCursorRow(), grid
->GetCursorColumn()); 
2585           GetEventHandler()->ProcessEvent(g_evt
); 
2587           //    grid->DrawCellText(); 
2592 void wxGenericGrid::OnTextEnter(wxCommandEvent
& WXUNUSED(ev
) ) 
2594   // move the cursor down the current row (if possible) 
2595   // when the enter key has been pressed 
2599       if ( GetCursorRow() < GetRows()-1 ) 
2601           wxClientDC 
dc( this ); 
2603           OnSelectCellImplementation(& dc
, 
2605                                      GetCursorColumn() ); 
2611 void wxGenericGrid::OnTextInPlace(wxCommandEvent
& ev 
) 
2615       wxGenericGrid 
*grid 
= this; 
2616       wxGridCell 
*cell 
= grid
->GetCell(grid
->GetCursorRow(), grid
->GetCursorColumn()); 
2617       if (cell 
&& grid
->CurrentCellVisible()) 
2619           m_inOnTextInPlace 
= TRUE
; 
2620           grid
->GetTextItem()->SetValue( m_inPlaceTextItem
->GetValue() ); 
2622           m_inOnTextInPlace 
= FALSE
; 
2627 void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent
& WXUNUSED(ev
) ) 
2629   // move the cursor down the current row (if possible) 
2630   // when the enter key has been pressed 
2634       if ( GetCursorRow() < GetRows()-1 ) 
2636           wxClientDC 
dc( this ); 
2638           OnSelectCellImplementation(& dc
, 
2640                                      GetCursorColumn() ); 
2646 void wxGenericGrid::OnGridScroll(wxScrollEvent
& ev
) 
2648   static bool inScroll 
= FALSE
; 
2653   if ( m_editInPlace 
) m_inPlaceTextItem
->Show(FALSE
); 
2656   wxGenericGrid 
*win 
= this; 
2658   bool change 
= FALSE
; 
2660   if (ev
.GetEventObject() == win
->GetHorizScrollBar()) 
2662     change 
= (ev
.GetPosition() != m_scrollPosX
); 
2663     win
->SetScrollPosX(ev
.GetPosition()); 
2667     change 
= (ev
.GetPosition() != m_scrollPosY
); 
2668     win
->SetScrollPosY(ev
.GetPosition()); 
2671   win
->UpdateDimensions(); 
2673   win
->SetCurrentRect(win
->GetCursorRow(), win
->GetCursorColumn()); 
2675   // Because rows and columns can be arbitrary sizes, 
2676   // the scrollbars will need to be adjusted to reflect the 
2680   if (change
) win
->Refresh(FALSE
); 
2682   if ( m_editInPlace 
&& m_currentRectVisible 
) 
2684       m_inPlaceTextItem
->SetSize( m_currentRect
.x
-2, m_currentRect
.y
-2, 
2685                                   m_currentRect
.width
+4, m_currentRect
.height
+4 ); 
2686       m_inPlaceTextItem
->Show( TRUE 
); 
2687       m_inPlaceTextItem
->SetFocus(); 
2695 //---------------------------------------------------------------------- 
2696 // Default wxGridEvent handlers 
2697 //      (just redirect to the pre-existing virtual methods) 
2699 void wxGenericGrid::_OnSelectCell(wxGridEvent
& ev
) 
2701     OnSelectCell(ev
.m_row
, ev
.m_col
); 
2704 void wxGenericGrid::_OnCreateCell(wxGridEvent
& ev
) 
2706     ev
.m_cell 
= OnCreateCell(); 
2709 void wxGenericGrid::_OnChangeLabels(wxGridEvent
& WXUNUSED(ev
)) 
2714 void wxGenericGrid::_OnChangeSelectionLabel(wxGridEvent
& WXUNUSED(ev
)) 
2716     OnChangeSelectionLabel(); 
2719 void wxGenericGrid::_OnCellChange(wxGridEvent
& ev
) 
2721     OnCellChange(ev
.m_row
, ev
.m_col
); 
2724 void wxGenericGrid::_OnCellLeftClick(wxGridEvent
& ev
) 
2726     OnCellLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
); 
2729 void wxGenericGrid::_OnCellRightClick(wxGridEvent
& ev
) 
2731     OnCellRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
); 
2734 void wxGenericGrid::_OnLabelLeftClick(wxGridEvent
& ev
) 
2736     OnLabelLeftClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
); 
2739 void wxGenericGrid::_OnLabelRightClick(wxGridEvent
& ev
) 
2741     OnLabelRightClick(ev
.m_row
, ev
.m_col
, ev
.m_x
, ev
.m_y
, ev
.m_control
, ev
.m_shift
);