]> git.saurik.com Git - wxWidgets.git/blame - src/generic/gridg.cpp
Added an #ifdef
[wxWidgets.git] / src / generic / gridg.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: gridg.cpp
3// Purpose: wxGenericGrid
4// Author: Julian Smart
dfe1eee3
VZ
5// Modified by: Michael Bedward
6// Added edit in place facility, 20 Apr 1999
7// Added cursor key control, 29 Jun 1999
bf6c2b35
VZ
8// Gerhard Gruber
9// Added keyboard navigation, client data, other fixes
c801d85f
KB
10// Created: 04/01/98
11// RCS-ID: $Id$
12// Copyright: (c) Julian Smart and Markus Holzem
dfe1eee3 13// Licence: wxWindows license
c801d85f
KB
14/////////////////////////////////////////////////////////////////////////////
15
16#ifdef __GNUG__
dfe1eee3
VZ
17 #pragma implementation "gridg.h"
18 #pragma interface
c801d85f
KB
19#endif
20
21// For compilers that support precompilation, includes "wx/wx.h".
22#include "wx/wxprec.h"
23
24#ifdef __BORLANDC__
dfe1eee3 25 #pragma hdrstop
c801d85f
KB
26#endif
27
28#ifndef WX_PRECOMP
dfe1eee3
VZ
29 #include "wx/utils.h"
30 #include "wx/dcclient.h"
31 #include "wx/dcmemory.h"
32 #include "wx/textctrl.h"
33 #include "wx/settings.h"
c801d85f
KB
34#endif
35
36#include <string.h>
37
38#include "wx/string.h"
dfe1eee3 39
c801d85f 40#include "wx/generic/gridg.h"
c801d85f 41
da938cfd 42// Set to zero to use no double-buffering
2049ba38 43#ifdef __WXMSW__
c0b042fc 44 #define wxUSE_DOUBLE_BUFFERING 1
da938cfd 45#else
c0b042fc 46 #define wxUSE_DOUBLE_BUFFERING 0
da938cfd 47#endif
c801d85f
KB
48
49#define wxGRID_DRAG_NONE 0
50#define wxGRID_DRAG_LEFT_RIGHT 1
51#define wxGRID_DRAG_UP_DOWN 2
52
53IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid, wxPanel)
1f481e6a 54IMPLEMENT_DYNAMIC_CLASS(wxGridEvent, wxEvent)
c801d85f
KB
55
56BEGIN_EVENT_TABLE(wxGenericGrid, wxPanel)
8aa04e8b
JS
57 EVT_SIZE(wxGenericGrid::OnSize)
58 EVT_PAINT(wxGenericGrid::OnPaint)
59 EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground)
60 EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent)
c801d85f 61 EVT_TEXT(wxGRID_TEXT_CTRL, wxGenericGrid::OnText)
c0b042fc 62 EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL, wxGenericGrid::OnTextInPlace)
dfe1eee3
VZ
63 EVT_TEXT_ENTER(wxGRID_TEXT_CTRL, wxGenericGrid::OnTextEnter)
64 EVT_TEXT_ENTER(wxGRID_EDIT_IN_PLACE_TEXT_CTRL, wxGenericGrid::OnTextInPlaceEnter)
c801d85f
KB
65 EVT_COMMAND_SCROLL(wxGRID_HSCROLL, wxGenericGrid::OnGridScroll)
66 EVT_COMMAND_SCROLL(wxGRID_VSCROLL, wxGenericGrid::OnGridScroll)
1f481e6a
RD
67
68 // default wxGridEvent handlers
69 EVT_GRID_SELECT_CELL(wxGenericGrid::_OnSelectCell)
70 EVT_GRID_CREATE_CELL(wxGenericGrid::_OnCreateCell)
71 EVT_GRID_CHANGE_LABELS(wxGenericGrid::_OnChangeLabels)
72 EVT_GRID_CHANGE_SEL_LABEL(wxGenericGrid::_OnChangeSelectionLabel)
73 EVT_GRID_CELL_CHANGE(wxGenericGrid::_OnCellChange)
74 EVT_GRID_CELL_LCLICK(wxGenericGrid::_OnCellLeftClick)
75 EVT_GRID_CELL_RCLICK(wxGenericGrid::_OnCellRightClick)
76 EVT_GRID_LABEL_LCLICK(wxGenericGrid::_OnLabelLeftClick)
77 EVT_GRID_LABEL_RCLICK(wxGenericGrid::_OnLabelRightClick)
78
c801d85f
KB
79END_EVENT_TABLE()
80
1f481e6a 81
bf6c2b35 82wxGenericGrid::wxGenericGrid()
c801d85f 83{
bf6c2b35
VZ
84 m_viewWidth = 0;
85 m_viewHeight = 0;
da938cfd 86 m_batchCount = 0;
c67daf87
UR
87 m_hScrollBar = (wxScrollBar *) NULL;
88 m_vScrollBar = (wxScrollBar *) NULL;
da938cfd
JS
89 m_cellTextColour = *wxBLACK;
90 m_cellBackgroundColour = *wxWHITE;
91 m_labelTextColour = *wxBLACK;
903f689b
RR
92// m_labelBackgroundColour = *wxLIGHT_GREY;
93 m_labelBackgroundColour = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
c0ed460c
JS
94 m_labelBackgroundBrush = wxNullBrush;
95 m_labelTextFont = wxNullFont;
96 m_cellTextFont = wxNullFont;
c67daf87 97 m_textItem = (wxTextCtrl *) NULL;
da938cfd
JS
98 m_currentRectVisible = FALSE;
99 m_editable = TRUE;
c0b042fc
VZ
100
101 m_editInPlace = TRUE;
102 m_inOnTextInPlace = FALSE;
dfe1eee3 103
c801d85f 104#if defined(__WIN95__)
da938cfd 105 m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
cd2df130 106#elif defined(__WXGTK__)
caaa4cfd 107 m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
c801d85f 108#else
da938cfd 109 m_scrollWidth = 16;
c801d85f 110#endif
da938cfd
JS
111 m_dragStatus = wxGRID_DRAG_NONE;
112 m_dragRowOrCol = 0;
113 m_dragStartPosition = 0;
114 m_dragLastPosition = 0;
c0ed460c 115 m_divisionPen = wxNullPen;
da938cfd
JS
116 m_leftOfSheet = wxGRID_DEFAULT_SHEET_LEFT;
117 m_topOfSheet = wxGRID_DEFAULT_SHEET_TOP;
118 m_cellHeight = wxGRID_DEFAULT_CELL_HEIGHT;
119 m_totalGridWidth = 0;
120 m_totalGridHeight = 0;
c67daf87
UR
121 m_colWidths = (short *) NULL;
122 m_rowHeights = (short *) NULL;
da938cfd
JS
123 m_verticalLabelWidth = wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH;
124 m_horizontalLabelHeight = wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT;
125 m_verticalLabelAlignment = wxCENTRE;
126 m_horizontalLabelAlignment = wxCENTRE;
127 m_editControlPosition.x = wxGRID_DEFAULT_EDIT_X;
128 m_editControlPosition.y = wxGRID_DEFAULT_EDIT_Y;
129 m_editControlPosition.width = wxGRID_DEFAULT_EDIT_WIDTH;
130 m_editControlPosition.height = wxGRID_DEFAULT_EDIT_HEIGHT;
131 m_wCursorRow = 0;
132 m_wCursorColumn = 0;
133 m_scrollPosX = 0;
134 m_scrollPosY = 0;
135 m_editCreated = FALSE;
136 m_totalRows = 0;
137 m_totalCols = 0;
c67daf87
UR
138 m_gridCells = (wxGridCell ***) NULL;
139 m_rowLabelCells = (wxGridCell **) NULL;
140 m_colLabelCells = (wxGridCell **) NULL;
141 m_textItem = (wxTextCtrl *) NULL;
da938cfd
JS
142}
143
bf6c2b35
VZ
144bool wxGenericGrid::Create(wxWindow *parent,
145 wxWindowID id,
146 const wxPoint& pos,
147 const wxSize& size,
148 long style,
149 const wxString& name)
da938cfd 150{
bf6c2b35
VZ
151 m_viewWidth = 0;
152 m_viewHeight = 0;
da938cfd 153 m_batchCount = 0;
c67daf87
UR
154 m_editingPanel = (wxPanel *) NULL;
155 m_hScrollBar = (wxScrollBar *) NULL;
156 m_vScrollBar = (wxScrollBar *) NULL;
da938cfd
JS
157 m_cellTextColour = *wxBLACK;
158 m_cellBackgroundColour = *wxWHITE;
159 m_labelTextColour = *wxBLACK;
903f689b
RR
160// m_labelBackgroundColour = *wxLIGHT_GREY;
161 m_labelBackgroundColour = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
c0ed460c
JS
162 m_labelBackgroundBrush = wxNullBrush;
163 m_labelTextFont = * wxTheFontList->FindOrCreateFont(10, wxSWISS, wxNORMAL, wxBOLD);
164 m_cellTextFont = * wxTheFontList->FindOrCreateFont(10, wxSWISS, wxNORMAL, wxNORMAL);
c67daf87 165 m_textItem = (wxTextCtrl *) NULL;
da938cfd
JS
166 m_currentRectVisible = FALSE;
167 m_editable = TRUE;
c801d85f 168#if defined(__WIN95__)
da938cfd 169 m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
cd2df130 170#elif defined(__WXGTK__)
caaa4cfd 171 m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
c801d85f 172#else
da938cfd 173 m_scrollWidth = 16;
c801d85f 174#endif
da938cfd
JS
175 m_dragStatus = wxGRID_DRAG_NONE;
176 m_dragRowOrCol = 0;
177 m_dragStartPosition = 0;
178 m_dragLastPosition = 0;
c0ed460c 179 m_divisionPen = * wxThePenList->FindOrCreatePen("LIGHT GREY", 1, wxSOLID);
c67daf87 180 m_doubleBufferingBitmap = (wxBitmap *) NULL;
c801d85f 181
c0ed460c 182 if (!m_horizontalSashCursor.Ok())
c801d85f 183 {
c0ed460c
JS
184 m_horizontalSashCursor = wxCursor(wxCURSOR_SIZEWE);
185 m_verticalSashCursor = wxCursor(wxCURSOR_SIZENS);
c801d85f 186 }
1f481e6a 187
da938cfd
JS
188 SetLabelBackgroundColour(m_labelBackgroundColour);
189
190 m_leftOfSheet = wxGRID_DEFAULT_SHEET_LEFT;
191 m_topOfSheet = wxGRID_DEFAULT_SHEET_TOP;
192 m_cellHeight = wxGRID_DEFAULT_CELL_HEIGHT;
193 m_totalGridWidth = 0;
194 m_totalGridHeight = 0;
c67daf87
UR
195 m_colWidths = (short *) NULL;
196 m_rowHeights = (short *) NULL;
da938cfd
JS
197
198 m_verticalLabelWidth = wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH;
199 m_horizontalLabelHeight = wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT;
200 m_verticalLabelAlignment = wxCENTRE;
201 m_horizontalLabelAlignment = wxCENTRE;
202 m_editControlPosition.x = wxGRID_DEFAULT_EDIT_X;
203 m_editControlPosition.y = wxGRID_DEFAULT_EDIT_Y;
204 m_editControlPosition.width = wxGRID_DEFAULT_EDIT_WIDTH;
205 m_editControlPosition.height = wxGRID_DEFAULT_EDIT_HEIGHT;
206
207 m_wCursorRow = 0;
208 m_wCursorColumn = 0;
209
210 m_scrollPosX = 0;
211 m_scrollPosY = 0;
c801d85f
KB
212
213 /* Store the rect. coordinates for the current cell */
da938cfd 214 SetCurrentRect(m_wCursorRow, m_wCursorColumn);
c801d85f 215
da938cfd 216 m_editCreated = FALSE;
c801d85f 217
da938cfd
JS
218 m_totalRows = 0;
219 m_totalCols = 0;
c67daf87
UR
220 m_gridCells = (wxGridCell ***) NULL;
221 m_rowLabelCells = (wxGridCell **) NULL;
222 m_colLabelCells = (wxGridCell **) NULL;
223 m_textItem = (wxTextCtrl *) NULL;
c801d85f
KB
224
225 wxPanel::Create(parent, id, pos, size, style, name);
226
da938cfd
JS
227 m_editingPanel = new wxPanel(this);
228
229 m_textItem = new wxTextCtrl(m_editingPanel, wxGRID_TEXT_CTRL, "",
c0b042fc
VZ
230 wxPoint(m_editControlPosition.x, m_editControlPosition.y),
231 wxSize(m_editControlPosition.width, -1),
dfe1eee3 232 wxTE_PROCESS_ENTER);
da938cfd
JS
233 m_textItem->Show(TRUE);
234 m_textItem->SetFocus();
c801d85f 235 int controlW, controlH;
1f481e6a 236
da938cfd
JS
237 m_textItem->GetSize(&controlW, &controlH);
238 m_editControlPosition.height = controlH;
c801d85f 239
da938cfd
JS
240 m_topOfSheet = m_editControlPosition.y + controlH + 2;
241
242 m_editCreated = TRUE;
243
244 m_hScrollBar = new wxScrollBar(this, wxGRID_HSCROLL, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL);
245 m_vScrollBar = new wxScrollBar(this, wxGRID_VSCROLL, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL);
c801d85f 246
aed0ed3c 247// SetSize(pos.x, pos.y, size.x, size.y);
82540ef2 248
c0b042fc 249 m_inPlaceTextItem = new wxTextCtrl( (wxPanel*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL, "",
dfe1eee3
VZ
250 wxPoint( m_currentRect.x-2, m_currentRect.y-2 ),
251 wxSize( m_currentRect.width+4, m_currentRect.height+4 ),
252 wxNO_BORDER | wxTE_PROCESS_ENTER );
c0b042fc
VZ
253 m_inPlaceTextItem->Show(TRUE);
254 m_inPlaceTextItem->SetFocus();
dfe1eee3 255
c801d85f
KB
256 return TRUE;
257}
258
bf6c2b35 259wxGenericGrid::~wxGenericGrid()
c801d85f
KB
260{
261 ClearGrid();
262}
263
bf6c2b35 264void wxGenericGrid::ClearGrid()
c801d85f
KB
265{
266 int i,j;
da938cfd 267 if (m_gridCells)
c801d85f 268 {
da938cfd 269 for (i = 0; i < m_totalRows; i++)
c801d85f 270 {
da938cfd
JS
271 for (j = 0; j < m_totalCols; j++)
272 if (m_gridCells[i][j])
273 delete m_gridCells[i][j];
274 delete[] m_gridCells[i];
c801d85f 275 }
da938cfd 276 delete[] m_gridCells;
c67daf87 277 m_gridCells = (wxGridCell ***) NULL;
da938cfd
JS
278 }
279 if (m_colWidths)
280 delete[] m_colWidths;
c67daf87 281 m_colWidths = (short *) NULL;
da938cfd
JS
282 if (m_rowHeights)
283 delete[] m_rowHeights;
c67daf87 284 m_rowHeights = (short *) NULL;
da938cfd
JS
285
286 if (m_rowLabelCells)
c801d85f 287 {
da938cfd
JS
288 for (i = 0; i < m_totalRows; i++)
289 delete m_rowLabelCells[i];
290 delete[] m_rowLabelCells;
c67daf87 291 m_rowLabelCells = (wxGridCell **) NULL;
c801d85f 292 }
da938cfd 293 if (m_colLabelCells)
c801d85f 294 {
da938cfd
JS
295 for (i = 0; i < m_totalCols; i++)
296 delete m_colLabelCells[i];
297 delete[] m_colLabelCells;
c67daf87 298 m_colLabelCells = (wxGridCell **) NULL;
da938cfd
JS
299 }
300 if (m_doubleBufferingBitmap)
301 {
302 delete m_doubleBufferingBitmap;
c67daf87 303 m_doubleBufferingBitmap = (wxBitmap *) NULL;
c801d85f
KB
304 }
305}
306
307bool wxGenericGrid::CreateGrid(int nRows, int nCols, wxString **cellValues, short *widths,
308 short defaultWidth, short defaultHeight)
309{
da938cfd
JS
310 m_totalRows = nRows;
311 m_totalCols = nCols;
c801d85f
KB
312
313 int i,j;
da938cfd
JS
314 m_colWidths = new short[nCols];
315 m_rowHeights = new short[nRows];
c801d85f
KB
316 for (i = 0; i < nCols; i++)
317 if (widths)
da938cfd 318 m_colWidths[i] = widths[i];
c801d85f 319 else
da938cfd 320 m_colWidths[i] = defaultWidth;
c801d85f 321 for (i = 0; i < nRows; i++)
da938cfd
JS
322 m_rowHeights[i] = defaultHeight;
323
324 m_gridCells = new wxGridCell **[nRows];
325
c801d85f 326 for (i = 0; i < nRows; i++)
da938cfd
JS
327 m_gridCells[i] = new wxGridCell *[nCols];
328
c801d85f
KB
329 for (i = 0; i < nRows; i++)
330 for (j = 0; j < nCols; j++)
331 if (cellValues)
332 {
1f481e6a
RD
333 //m_gridCells[i][j] = OnCreateCell();
334 wxGridEvent g_evt(GetId(), wxEVT_GRID_CREATE_CELL, this, i, j);
335 GetEventHandler()->ProcessEvent(g_evt);
336 m_gridCells[i][j] = g_evt.m_cell;
da938cfd 337 m_gridCells[i][j]->SetTextValue(cellValues[i][j]);
c801d85f
KB
338 }
339 else
c67daf87 340 m_gridCells[i][j] = (wxGridCell *) NULL;
da938cfd
JS
341
342 m_rowLabelCells = new wxGridCell *[nRows];
c801d85f 343 for (i = 0; i < nRows; i++)
da938cfd
JS
344 m_rowLabelCells[i] = new wxGridCell(this);
345 m_colLabelCells = new wxGridCell *[nCols];
c801d85f 346 for (i = 0; i < nCols; i++)
da938cfd 347 m_colLabelCells[i] = new wxGridCell(this);
c801d85f 348
da938cfd 349 m_wCursorRow = m_wCursorColumn = 0;
c801d85f
KB
350 SetCurrentRect(0, 0);
351
352 // Need to determine various dimensions
353 UpdateDimensions();
354
355 // Number of 'lines'
da938cfd 356 int objectSizeX = m_totalCols;
c801d85f 357 int pageSizeX = 1;
da938cfd 358 int viewLengthX = m_totalCols;
34138703
JS
359
360/*
da938cfd
JS
361 m_hScrollBar->SetViewLength(viewLengthX);
362 m_hScrollBar->SetObjectLength(objectSizeX);
363 m_hScrollBar->SetPageSize(pageSizeX);
34138703 364*/
4fabb575 365 m_hScrollBar->SetScrollbar(m_hScrollBar->GetThumbPosition(), pageSizeX, objectSizeX, viewLengthX);
c801d85f 366
da938cfd 367 int objectSizeY = m_totalRows;
c801d85f 368 int pageSizeY = 1;
da938cfd 369 int viewLengthY = m_totalRows;
c801d85f 370
34138703 371/*
da938cfd
JS
372 m_vScrollBar->SetViewLength(viewLengthY);
373 m_vScrollBar->SetObjectLength(objectSizeY);
374 m_vScrollBar->SetPageSize(pageSizeY);
34138703
JS
375*/
376
4fabb575 377 m_vScrollBar->SetScrollbar(m_vScrollBar->GetThumbPosition(), pageSizeY, objectSizeY, viewLengthY);
c801d85f
KB
378
379 AdjustScrollbars();
380
1f481e6a
RD
381 //OnChangeLabels();
382 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS, this);
383 GetEventHandler()->ProcessEvent(g_evt);
384
385 //OnChangeSelectionLabel();
386 wxGridEvent g_evt2(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL, this);
387 GetEventHandler()->ProcessEvent(g_evt2);
388
c801d85f
KB
389 return TRUE;
390}
391
392// Need to determine various dimensions
bf6c2b35 393void wxGenericGrid::UpdateDimensions()
c801d85f
KB
394{
395 int canvasWidth, canvasHeight;
396 GetSize(&canvasWidth, &canvasHeight);
1f481e6a 397
da938cfd 398 if (m_editCreated && m_editable)
c801d85f
KB
399 {
400 int controlW, controlH;
401 GetTextItem()->GetSize(&controlW, &controlH);
da938cfd 402 m_topOfSheet = m_editControlPosition.y + controlH + 2;
c801d85f
KB
403 }
404 else
da938cfd
JS
405 m_topOfSheet = 0;
406 m_rightOfSheet = m_leftOfSheet + m_verticalLabelWidth;
c801d85f 407 int i;
da938cfd 408 for (i = m_scrollPosX; i < m_totalCols; i++)
c801d85f 409 {
da938cfd 410 if (m_rightOfSheet > canvasWidth)
c801d85f
KB
411 break;
412 else
da938cfd 413 m_rightOfSheet += m_colWidths[i];
c801d85f 414 }
da938cfd
JS
415 m_bottomOfSheet = m_topOfSheet + m_horizontalLabelHeight;
416 for (i = m_scrollPosY; i < m_totalRows; i++)
c801d85f 417 {
da938cfd 418 if (m_bottomOfSheet > canvasHeight)
c801d85f
KB
419 break;
420 else
da938cfd 421 m_bottomOfSheet += m_rowHeights[i];
c801d85f 422 }
1f481e6a 423
da938cfd
JS
424 m_totalGridWidth = m_leftOfSheet + m_verticalLabelWidth;
425 for (i = 0; i < m_totalCols; i++)
c801d85f 426 {
da938cfd 427 m_totalGridWidth += m_colWidths[i];
c801d85f 428 }
da938cfd
JS
429 m_totalGridHeight = m_topOfSheet + m_horizontalLabelHeight;
430 for (i = 0; i < m_totalRows; i++)
c801d85f 431 {
da938cfd 432 m_totalGridHeight += m_rowHeights[i];
c801d85f
KB
433 }
434}
435
c0ed460c 436wxGridCell *wxGenericGrid::GetCell(int row, int col) const
c801d85f 437{
da938cfd 438 if (!m_gridCells)
c67daf87 439 return (wxGridCell *) NULL;
c801d85f 440
da938cfd 441 if ((row >= m_totalRows) || (col >= m_totalCols))
c67daf87 442 return (wxGridCell *) NULL;
1f481e6a 443
da938cfd 444 wxGridCell *cell = m_gridCells[row][col];
c801d85f
KB
445 if (!cell)
446 {
1f481e6a 447 // m_gridCells[row][col] = OnCreateCell();
c0ed460c 448 wxGridEvent g_evt(GetId(), wxEVT_GRID_CREATE_CELL, (wxGenericGrid*) this, row, col);
1f481e6a
RD
449 GetEventHandler()->ProcessEvent(g_evt);
450 m_gridCells[row][col] = g_evt.m_cell;
da938cfd 451 return m_gridCells[row][col];
c801d85f
KB
452 }
453 else
454 return cell;
455}
456
457void wxGenericGrid::SetGridClippingRegion(wxDC *dc)
458{
da938cfd
JS
459 int m_scrollWidthHoriz = 0;
460 int m_scrollWidthVert = 0;
c801d85f
KB
461 int cw, ch;
462 GetClientSize(&cw, &ch);
463
da938cfd
JS
464 if (m_hScrollBar && m_hScrollBar->IsShown())
465 m_scrollWidthHoriz = m_scrollWidth;
466 if (m_vScrollBar && m_vScrollBar->IsShown())
467 m_scrollWidthVert = m_scrollWidth;
c801d85f
KB
468
469 // Don't paint over the scrollbars
da938cfd
JS
470 dc->SetClippingRegion(m_leftOfSheet, m_topOfSheet,
471 cw - m_scrollWidthVert - m_leftOfSheet, ch - m_scrollWidthHoriz - m_topOfSheet);
c801d85f
KB
472}
473
474void wxGenericGrid::OnPaint(wxPaintEvent& WXUNUSED(event))
475{
da938cfd
JS
476 int w, h;
477 GetClientSize(&w, &h);
c801d85f 478
47d67540 479 bool useDoubleBuffering = (bool) wxUSE_DOUBLE_BUFFERING;
da938cfd
JS
480 if (useDoubleBuffering)
481 {
482 // Reuse the old bitmap if possible
c801d85f 483
da938cfd
JS
484 if (!m_doubleBufferingBitmap ||
485 (m_doubleBufferingBitmap->GetWidth() < w || m_doubleBufferingBitmap->GetHeight() < h))
486 {
487 if (m_doubleBufferingBitmap)
488 delete m_doubleBufferingBitmap;
489 m_doubleBufferingBitmap = new wxBitmap(w, h);
490 }
491 if (!m_doubleBufferingBitmap || !m_doubleBufferingBitmap->Ok())
492 {
493 // If we couldn't create a new bitmap, perhaps because resources were low,
494 // then don't complain, just don't double-buffer
495 if (m_doubleBufferingBitmap)
496 delete m_doubleBufferingBitmap;
c67daf87 497 m_doubleBufferingBitmap = (wxBitmap *) NULL;
da938cfd
JS
498 useDoubleBuffering = FALSE;
499 }
500 }
c801d85f 501
da938cfd
JS
502 if (useDoubleBuffering)
503 {
504 wxPaintDC paintDC(this);
505 wxMemoryDC dc(& paintDC);
5260b1c5 506 dc.SelectObject(* m_doubleBufferingBitmap);
c801d85f 507
da938cfd 508 PaintGrid(dc);
c801d85f 509
da938cfd
JS
510 int vertScrollBarWidth = m_scrollWidth;
511 int horizScrollBarHeight = m_scrollWidth;
512 if (m_vScrollBar && !m_vScrollBar->IsShown())
513 vertScrollBarWidth = 0;
514 if (m_hScrollBar && !m_hScrollBar->IsShown())
515 horizScrollBarHeight = 0;
c801d85f 516
da938cfd
JS
517 paintDC.Blit(m_leftOfSheet, m_topOfSheet, w - vertScrollBarWidth - m_leftOfSheet, h - horizScrollBarHeight - m_topOfSheet,
518 &dc, m_leftOfSheet, m_topOfSheet, wxCOPY);
c801d85f 519
da938cfd
JS
520 dc.SelectObject(wxNullBitmap);
521 }
522 else
523 {
524 wxPaintDC dc(this);
525 PaintGrid(dc);
526 }
527}
528
529void wxGenericGrid::PaintGrid(wxDC& dc)
530{
531 dc.BeginDrawing();
532 dc.SetOptimization(FALSE);
533
534 SetGridClippingRegion(& dc);
c801d85f 535
da938cfd
JS
536 DrawLabelAreas(& dc);
537
538 DrawEditableArea(& dc);
539 DrawColumnLabels(& dc);
540 DrawRowLabels(& dc);
541 DrawCells(& dc);
542 DrawGridLines(& dc);
543
544 /* Hilight present cell */
545 SetCurrentRect(m_wCursorRow, m_wCursorColumn);
c0b042fc 546 if (m_currentRectVisible && !(m_editable && m_editInPlace))
da938cfd
JS
547 HighlightCell(& dc);
548
549 dc.DestroyClippingRegion();
550 dc.SetOptimization(TRUE);
551 dc.EndDrawing();
552}
553
554// Erase (some of) the background.
555// Currently, a Windows-only optimisation.
e3e65dac 556void wxGenericGrid::OnEraseBackground(wxEraseEvent& WXUNUSED(event) )
da938cfd
JS
557{
558 wxClientDC dc(this);
559 dc.BeginDrawing();
560 dc.SetOptimization(FALSE);
561
562 int w, h;
563 GetClientSize(& w, & h);
564 dc.SetBrush(*wxLIGHT_GREY_BRUSH);
565 dc.SetPen(*wxLIGHT_GREY_PEN);
566
567 if (m_hScrollBar && m_hScrollBar->IsShown() && m_vScrollBar && m_vScrollBar->IsShown())
568 {
569 dc.DrawRectangle(w - m_scrollWidth, h - m_scrollWidth, m_scrollWidth, m_scrollWidth);
570 }
571
572 dc.SetOptimization(TRUE);
573 dc.EndDrawing();
c801d85f
KB
574}
575
da938cfd 576
c801d85f
KB
577void wxGenericGrid::DrawLabelAreas(wxDC *dc)
578{
579 int cw, ch;
580 GetClientSize(&cw, &ch);
581
582 dc->SetPen(*wxTRANSPARENT_PEN);
583// dc->SetBrush(*dc->GetBackground());
584
585 // Should blank out any area which isn't going to be painted over.
da938cfd
JS
586// dc->DrawRectangle(m_leftOfSheet, m_bottomOfSheet, cw - m_leftOfSheet, ch - m_bottomOfSheet);
587// dc->DrawRectangle(m_rightOfSheet, m_topOfSheet, cw - m_rightOfSheet, ch - m_topOfSheet);
c801d85f
KB
588
589 // Paint the label areas
c0ed460c 590 dc->SetBrush(m_labelBackgroundBrush);
da938cfd
JS
591// dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_rightOfSheet - m_leftOfSheet + 1, m_horizontalLabelHeight + 1);
592 dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, cw-m_leftOfSheet, m_horizontalLabelHeight + 1);
593// dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, m_bottomOfSheet - m_topOfSheet + 1);
594 dc->DrawRectangle(m_leftOfSheet, m_topOfSheet, m_verticalLabelWidth + 1, ch-m_topOfSheet);
c801d85f
KB
595}
596
597void wxGenericGrid::DrawEditableArea(wxDC *dc)
598{
599 int cw, ch;
600 GetClientSize(&cw, &ch);
601
602 dc->SetPen(*wxTRANSPARENT_PEN);
da938cfd
JS
603 dc->SetBrush(*wxTheBrushList->FindOrCreateBrush(m_cellBackgroundColour, wxSOLID));
604// dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
605// m_rightOfSheet-(m_leftOfSheet+m_verticalLabelWidth) + 1, m_bottomOfSheet - (m_topOfSheet+m_horizontalLabelHeight) + 1);
606 dc->DrawRectangle(m_leftOfSheet+m_verticalLabelWidth, m_topOfSheet+m_horizontalLabelHeight,
607 cw-(m_leftOfSheet+m_verticalLabelWidth), ch - (m_topOfSheet+m_horizontalLabelHeight));
c801d85f
KB
608}
609
610void wxGenericGrid::DrawGridLines(wxDC *dc)
611{
612 int cw, ch;
613 GetClientSize(&cw, &ch);
1f481e6a 614
c801d85f
KB
615 int i;
616
c0ed460c 617 if (m_divisionPen.Ok())
c801d85f 618 {
c0ed460c 619 dc->SetPen(m_divisionPen);
c801d85f 620
da938cfd 621 int heightCount = m_topOfSheet + m_horizontalLabelHeight;
c801d85f
KB
622
623 // Draw horizontal grey lines for cells
da938cfd 624 for (i = m_scrollPosY; i < (m_totalRows+1); i++)
c801d85f
KB
625 {
626 if (heightCount > ch)
627 break;
628 else
629 {
da938cfd 630 dc->DrawLine(m_leftOfSheet, heightCount,
c801d85f 631 cw, heightCount);
da938cfd
JS
632 if (i < m_totalRows)
633 heightCount += m_rowHeights[i];
c801d85f
KB
634 }
635 }
636 }
637
da938cfd 638 if (m_verticalLabelWidth > 0)
c801d85f
KB
639 {
640 dc->SetPen(*wxBLACK_PEN);
641
642 // Draw horizontal black lines for row labels
da938cfd
JS
643 int heightCount = m_topOfSheet + m_horizontalLabelHeight;
644 for (i = m_scrollPosY; i < (m_totalRows+1); i++)
c801d85f
KB
645 {
646 if (heightCount > ch)
647 break;
648 else
649 {
da938cfd
JS
650 dc->DrawLine(m_leftOfSheet, heightCount,
651 m_verticalLabelWidth, heightCount);
652 if (i < m_totalRows)
653 heightCount += m_rowHeights[i];
c801d85f
KB
654 }
655 }
656 // Draw a black vertical line for row number cells
da938cfd
JS
657 dc->DrawLine(m_leftOfSheet + m_verticalLabelWidth, m_topOfSheet,
658 m_leftOfSheet + m_verticalLabelWidth, ch);
c801d85f 659 // First vertical line
da938cfd 660 dc->DrawLine(m_leftOfSheet, m_topOfSheet, m_leftOfSheet, ch);
c801d85f
KB
661
662 dc->SetPen(*wxWHITE_PEN);
663
664 // Draw highlights on row labels
da938cfd
JS
665 heightCount = m_topOfSheet + m_horizontalLabelHeight;
666 for (i = m_scrollPosY; i < m_totalRows; i++)
c801d85f
KB
667 {
668 if (heightCount > ch)
669 break;
670 else
671 {
da938cfd
JS
672 dc->DrawLine(m_leftOfSheet+1, heightCount+1,
673 m_verticalLabelWidth, heightCount+1);
674 dc->DrawLine(m_leftOfSheet+1, heightCount+1,
675 m_leftOfSheet+1, heightCount + m_rowHeights[i] - 1);
676 heightCount += m_rowHeights[i];
c801d85f
KB
677 }
678 }
679 // Last one - down to the floor.
da938cfd
JS
680 dc->DrawLine(m_leftOfSheet+1, heightCount+1,
681 m_verticalLabelWidth, heightCount+1);
682 dc->DrawLine(m_leftOfSheet+1, heightCount+1,
683 m_leftOfSheet+1, ch);
c801d85f
KB
684
685 }
686
c0ed460c 687 if (m_divisionPen.Ok())
c801d85f 688 {
c0ed460c 689 dc->SetPen(m_divisionPen);
c801d85f
KB
690
691 // Draw vertical grey lines for cells
da938cfd
JS
692 int widthCount = m_leftOfSheet + m_verticalLabelWidth;
693 for (i = m_scrollPosX; i < m_totalCols; i++)
c801d85f
KB
694 {
695 if (widthCount > cw)
696 break;
697 else
698 {
699 // Skip the first one
da938cfd 700 if (i != m_scrollPosX)
c801d85f 701 {
da938cfd
JS
702 dc->DrawLine(widthCount, m_topOfSheet + m_horizontalLabelHeight,
703 widthCount, m_bottomOfSheet);
c801d85f 704 }
da938cfd 705 widthCount += m_colWidths[i];
c801d85f
KB
706 }
707 }
708 // Last one
da938cfd
JS
709 dc->DrawLine(widthCount, m_topOfSheet + m_horizontalLabelHeight,
710 widthCount, m_bottomOfSheet);
c801d85f
KB
711 }
712
713 dc->SetPen(*wxBLACK_PEN);
714
715 // Draw two black horizontal lines for column number cells
716 dc->DrawLine(
da938cfd
JS
717 m_leftOfSheet, m_topOfSheet,
718 cw, m_topOfSheet);
719 dc->DrawLine(m_leftOfSheet, m_topOfSheet + m_horizontalLabelHeight,
720 cw, m_topOfSheet + m_horizontalLabelHeight);
c801d85f 721
da938cfd 722 if (m_horizontalLabelHeight > 0)
c801d85f 723 {
da938cfd
JS
724 int widthCount = m_leftOfSheet + m_verticalLabelWidth;
725
c801d85f 726 // Draw black vertical lines for column number cells
da938cfd 727 for (i = m_scrollPosX; i < m_totalCols; i++)
c801d85f
KB
728 {
729 if (widthCount > cw)
730 break;
731 else
732 {
da938cfd
JS
733 dc->DrawLine(widthCount, m_topOfSheet,
734 widthCount, m_topOfSheet + m_horizontalLabelHeight);
735 widthCount += m_colWidths[i];
c801d85f
KB
736 }
737 }
738
739 // Last one
da938cfd
JS
740 dc->DrawLine(widthCount, m_topOfSheet,
741 widthCount, m_topOfSheet + m_horizontalLabelHeight);
c801d85f
KB
742
743 // Draw highlights
744 dc->SetPen(*wxWHITE_PEN);
da938cfd
JS
745 widthCount = m_leftOfSheet + m_verticalLabelWidth;
746
747 for (i = m_scrollPosX; i < m_totalCols; i++)
c801d85f
KB
748 {
749 if (widthCount > cw)
750 break;
751 else
752 {
da938cfd
JS
753 dc->DrawLine(widthCount+1, m_topOfSheet+1,
754 widthCount+m_colWidths[i], m_topOfSheet+1);
755 dc->DrawLine(widthCount+1, m_topOfSheet+1,
756 widthCount+1, m_topOfSheet+m_horizontalLabelHeight);
757 widthCount += m_colWidths[i];
c801d85f
KB
758 }
759 }
760 // Last one - to the right side of the canvas.
da938cfd
JS
761 dc->DrawLine(widthCount+1, m_topOfSheet+1,
762 cw, m_topOfSheet+1);
763 dc->DrawLine(widthCount+1, m_topOfSheet+1,
764 widthCount+1, m_topOfSheet+m_horizontalLabelHeight);
c801d85f
KB
765
766 }
767}
768
769void wxGenericGrid::DrawColumnLabels(wxDC *dc)
770{
771 int cw, ch;
772 GetClientSize(&cw, &ch);
773
da938cfd 774 if (m_horizontalLabelHeight == 0)
c801d85f 775 return;
1f481e6a 776
c801d85f 777 int i;
16e93305 778 wxRect rect;
c801d85f
KB
779
780 // Draw letters for columns
da938cfd
JS
781 rect.y = m_topOfSheet + 1;
782 rect.height = m_horizontalLabelHeight - 1;
c801d85f 783
da938cfd 784 dc->SetTextBackground(m_labelBackgroundColour);
c801d85f 785 dc->SetBackgroundMode(wxTRANSPARENT);
da938cfd 786// dc->SetTextForeground(m_labelTextColour);
1f481e6a 787
da938cfd
JS
788 int widthCount = m_leftOfSheet + m_verticalLabelWidth;
789 for (i = m_scrollPosX; i < m_totalCols; i++)
c801d85f
KB
790 {
791 if (widthCount > cw)
792 break;
793 else
794 {
795 rect.x = 1 + widthCount;
da938cfd 796 rect.width = m_colWidths[i];
c801d85f
KB
797 DrawColumnLabel(dc, &rect, i);
798
da938cfd 799 widthCount += m_colWidths[i];
c801d85f
KB
800 }
801 }
802}
803
16e93305 804void wxGenericGrid::DrawColumnLabel(wxDC *dc, wxRect *rect, int col)
c801d85f
KB
805{
806 wxGridCell *cell = GetLabelCell(wxHORIZONTAL, col);
807 if (cell)
808 {
16e93305 809 wxRect rect2;
c801d85f
KB
810 rect2 = *rect;
811 rect2.x += 3;
812 rect2.y += 2;
813 rect2.width -= 5;
814 rect2.height -= 4;
815 dc->SetTextForeground(GetLabelTextColour());
c0ed460c 816 dc->SetFont(GetLabelTextFont());
dfe1eee3
VZ
817 if ( !cell->GetTextValue().IsNull() )
818 DrawTextRect(dc, cell->GetTextValue(), &rect2, GetLabelAlignment(wxHORIZONTAL));
c801d85f
KB
819 }
820}
821
822void wxGenericGrid::DrawRowLabels(wxDC *dc)
823{
824 int cw, ch;
825 GetClientSize(&cw, &ch);
826
da938cfd 827 if (m_verticalLabelWidth == 0)
c801d85f
KB
828 return;
829
830 int i;
16e93305 831 wxRect rect;
1f481e6a 832
c801d85f 833 // Draw numbers for rows
da938cfd
JS
834 rect.x = m_leftOfSheet;
835 rect.width = m_verticalLabelWidth;
c801d85f 836
da938cfd 837 int heightCount = m_topOfSheet + m_horizontalLabelHeight;
c801d85f 838
da938cfd 839 dc->SetTextBackground(m_labelBackgroundColour);
c801d85f
KB
840 dc->SetBackgroundMode(wxTRANSPARENT);
841
da938cfd 842 for (i = m_scrollPosY; i < m_totalRows; i++)
c801d85f
KB
843 {
844 if (heightCount > ch)
845 break;
846 else
847 {
848 rect.y = 1 + heightCount;
da938cfd 849 rect.height = m_rowHeights[i];
c801d85f 850 DrawRowLabel(dc, &rect, i);
1f481e6a 851
da938cfd 852 heightCount += m_rowHeights[i];
c801d85f
KB
853 }
854 }
855}
856
16e93305 857void wxGenericGrid::DrawRowLabel(wxDC *dc, wxRect *rect, int row)
c801d85f
KB
858{
859 wxGridCell *cell = GetLabelCell(wxVERTICAL, row);
860 if (cell)
861 {
16e93305 862 wxRect rect2;
c801d85f
KB
863 rect2 = *rect;
864 rect2.x += 3;
865 rect2.y += 2;
866 rect2.width -= 5;
867 rect2.height -= 4;
868 dc->SetTextForeground(GetLabelTextColour());
c0ed460c 869 dc->SetFont(GetLabelTextFont());
dfe1eee3
VZ
870 if ( !cell->GetTextValue().IsNull() )
871 DrawTextRect(dc, cell->GetTextValue(), &rect2, GetLabelAlignment(wxVERTICAL));
c801d85f
KB
872 }
873}
874
875void wxGenericGrid::DrawCells(wxDC *dc)
876{
877 int cw, ch;
878 GetClientSize(&cw, &ch);
879
880 int i,j;
1f481e6a 881
c801d85f 882 // Draw value corresponding to each cell
da938cfd 883 for (i = m_scrollPosY; i < m_totalRows; i++)
c801d85f 884 {
da938cfd 885 for (j = m_scrollPosX; j < m_totalCols; j++)
c801d85f
KB
886 {
887 SetCurrentRect(i, j, cw, ch);
da938cfd 888 if (m_currentRectVisible)
c801d85f 889 {
da938cfd
JS
890 DrawCellBackground(dc, &m_currentRect, i, j);
891 DrawCellValue(dc, &m_currentRect, i, j);
c801d85f 892 }
da938cfd 893 if (m_currentRect.x > cw)
c801d85f
KB
894 break;
895 }
da938cfd 896 if (m_currentRect.y > ch)
c801d85f
KB
897 break;
898 }
899 dc->SetBackgroundMode(wxSOLID);
900 dc->SetPen(*wxBLACK_PEN);
901}
902
16e93305 903void wxGenericGrid::DrawCellBackground(wxDC *dc, wxRect *rect, int row, int col)
c801d85f
KB
904{
905 wxGridCell *cell = GetCell(row, col);
906 if (cell)
907 {
c0ed460c 908 dc->SetBrush(cell->GetBackgroundBrush());
c801d85f 909 dc->SetPen(*wxTRANSPARENT_PEN);
1f481e6a 910
34138703 911#if 0 // In wxWin 2.0 the dc code is exact. RR.
2049ba38 912#ifdef __WXMOTIF__
c801d85f
KB
913 dc->DrawRectangle(rect->x+1, rect->y+1, rect->width-1, rect->height-1);
914#else
915 dc->DrawRectangle(rect->x+1, rect->y+1, rect->width, rect->height);
916#endif
903f689b
RR
917#endif
918
919 dc->DrawRectangle(rect->x+1, rect->y+1, rect->width-1, rect->height-1);
920
c801d85f
KB
921 dc->SetPen(*wxBLACK_PEN);
922 }
923}
924
16e93305 925void wxGenericGrid::DrawCellValue(wxDC *dc, wxRect *rect, int row, int col)
c801d85f
KB
926{
927 wxGridCell *cell = GetCell(row, col);
928 if (cell)
929 {
930 wxBitmap *bitmap = cell->GetCellBitmap();
16e93305 931 wxRect rect2;
c801d85f
KB
932 rect2 = *rect;
933 rect2.x += 3;
934 rect2.y += 2;
935 rect2.width -= 5;
936 rect2.height -= 4;
937
938 if (bitmap)
939 {
940 DrawBitmapRect(dc, bitmap, &rect2, cell->GetAlignment());
941 }
942 else
943 {
944 dc->SetBackgroundMode(wxTRANSPARENT);
945 dc->SetTextForeground(cell->GetTextColour());
c0ed460c 946 dc->SetFont(cell->GetFont());
c801d85f 947
dfe1eee3
VZ
948 if ( !cell->GetTextValue().IsNull() )
949 DrawTextRect(dc, cell->GetTextValue(), &rect2, cell->GetAlignment());
c801d85f
KB
950 }
951 }
952}
953
bf6c2b35 954void wxGenericGrid::AdjustScrollbars()
c801d85f
KB
955{
956 int cw, ch;
957 GetClientSize(&cw, &ch);
1f481e6a 958
c801d85f
KB
959 // We find the view size by seeing how many rows/cols fit on
960 // the current view.
961 // BUT... this means that the scrollbar should be adjusted every time
962 // it's scrolled, as well as when sized, because with variable size rows/cols,
963 // the number of rows/col visible on the view differs according to what bit
964 // you're looking at. The object length is always the same, but the
965 // view length differs.
966
967 // Since this may not be known until the end of this function, we should probably call AdjustScrollbars
968 // twice.
da938cfd
JS
969 int vertScrollBarWidth = m_scrollWidth;
970 int horizScrollBarHeight = m_scrollWidth;
971 if (m_vScrollBar && !m_vScrollBar->IsShown())
c801d85f 972 vertScrollBarWidth = 0;
da938cfd 973 if (m_hScrollBar && !m_hScrollBar->IsShown())
c801d85f 974 horizScrollBarHeight = 0;
1f481e6a 975
c801d85f
KB
976 int noHorizSteps = 0;
977 int noVertSteps = 0;
1f481e6a 978
bf6c2b35 979 if (m_totalGridWidth + vertScrollBarWidth > cw)
c801d85f 980 {
c801d85f 981 int widthCount = 0;
c801d85f
KB
982
983 int i;
bf6c2b35 984 int nx = 0;
da938cfd 985 for (i = m_scrollPosX ; i < m_totalCols; i++)
c801d85f 986 {
da938cfd 987 widthCount += m_colWidths[i];
bf6c2b35
VZ
988 // A partial bit doesn't count, we still have to scroll to see the
989 // rest of it
da938cfd 990 if (widthCount + m_leftOfSheet + m_verticalLabelWidth > (cw-vertScrollBarWidth))
c801d85f 991 break;
bf6c2b35
VZ
992 else
993 nx ++;
c801d85f 994 }
1f481e6a 995
c801d85f
KB
996 noHorizSteps += nx;
997 }
bf6c2b35
VZ
998 m_viewWidth = noHorizSteps;
999
1000 if (m_totalGridHeight + horizScrollBarHeight > ch)
c801d85f 1001 {
c801d85f 1002 int heightCount = 0;
c801d85f
KB
1003
1004 int i;
bf6c2b35 1005 int ny = 0;
da938cfd 1006 for (i = m_scrollPosY ; i < m_totalRows; i++)
c801d85f 1007 {
da938cfd 1008 heightCount += m_rowHeights[i];
bf6c2b35
VZ
1009 // A partial bit doesn't count, we still have to scroll to see the
1010 // rest of it
da938cfd 1011 if (heightCount + m_topOfSheet + m_horizontalLabelHeight > (ch-horizScrollBarHeight))
c801d85f 1012 break;
bf6c2b35
VZ
1013 else
1014 ny ++;
c801d85f 1015 }
1f481e6a 1016
c801d85f
KB
1017 noVertSteps += ny;
1018 }
1f481e6a 1019
bf6c2b35
VZ
1020 m_viewHeight = noVertSteps;
1021
386af6a2 1022 if (m_totalGridWidth + vertScrollBarWidth <= cw)
c801d85f 1023 {
bf6c2b35
VZ
1024 if ( m_hScrollBar )
1025 m_hScrollBar->Show(FALSE);
c801d85f
KB
1026 SetScrollPosX(0);
1027 }
1028 else
1029 {
8aa04e8b
JS
1030 if ( m_hScrollBar )
1031 m_hScrollBar->Show(TRUE);
c801d85f
KB
1032 }
1033
386af6a2 1034 if (m_totalGridHeight + horizScrollBarHeight <= ch)
c801d85f 1035 {
8aa04e8b
JS
1036 if ( m_vScrollBar )
1037 m_vScrollBar->Show(FALSE);
1038 SetScrollPosY(0);
c801d85f
KB
1039 }
1040 else
1041 {
8aa04e8b
JS
1042 if ( m_vScrollBar )
1043 m_vScrollBar->Show(TRUE);
c801d85f
KB
1044 }
1045
da938cfd 1046 UpdateDimensions(); // Necessary in case m_scrollPosX/Y changed
c801d85f 1047
da938cfd
JS
1048 vertScrollBarWidth = m_scrollWidth;
1049 horizScrollBarHeight = m_scrollWidth;
1050 if (m_vScrollBar && !m_vScrollBar->IsShown())
c801d85f 1051 vertScrollBarWidth = 0;
da938cfd 1052 if (m_hScrollBar && !m_hScrollBar->IsShown())
c801d85f
KB
1053 horizScrollBarHeight = 0;
1054
b412f9be 1055 if (m_hScrollBar && m_hScrollBar->IsShown())
c801d85f
KB
1056 {
1057 int nCols = GetCols();
4fabb575 1058 m_hScrollBar->SetScrollbar(m_hScrollBar->GetThumbPosition(), wxMax(noHorizSteps, 1), (noHorizSteps == 0) ? 1 : nCols, wxMax(noHorizSteps, 1));
c801d85f 1059
caaa4cfd
RR
1060/*
1061 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth -2, // why -2 ? Robert.
da938cfd 1062 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
caaa4cfd
RR
1063*/
1064 m_hScrollBar->SetSize(m_leftOfSheet, ch - m_scrollWidth,
1065 cw - vertScrollBarWidth - m_leftOfSheet, m_scrollWidth);
1066
c801d85f 1067 }
1f481e6a 1068
b412f9be 1069 if (m_vScrollBar && m_vScrollBar->IsShown())
c801d85f
KB
1070 {
1071 int nRows = GetRows();
c801d85f 1072
4fabb575 1073 m_vScrollBar->SetScrollbar(m_vScrollBar->GetThumbPosition(), wxMax(noVertSteps, 1), (noVertSteps == 0) ? 1 : nRows, wxMax(noVertSteps, 1));
da938cfd
JS
1074 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
1075 m_scrollWidth, ch - m_topOfSheet - horizScrollBarHeight);
c801d85f
KB
1076 }
1077}
1078
1079void wxGenericGrid::OnSize(wxSizeEvent& WXUNUSED(event) )
1080{
da938cfd 1081 if (!m_vScrollBar || !m_hScrollBar)
dfe1eee3 1082 return;
c801d85f
KB
1083
1084 AdjustScrollbars();
1f481e6a 1085
c801d85f
KB
1086 int cw, ch;
1087 GetClientSize(&cw, &ch);
1088
da938cfd 1089 if (m_editCreated && m_editingPanel && GetTextItem() && GetTextItem()->IsShown())
c801d85f 1090 {
da938cfd
JS
1091 m_editingPanel->SetSize(0, 0, cw, m_editControlPosition.height + m_editControlPosition.y + 2);
1092 GetTextItem()->SetSize(m_editControlPosition.x, m_editControlPosition.y,
caaa4cfd 1093 cw - 2*m_editControlPosition.x, m_editControlPosition.height);
c801d85f
KB
1094 }
1095}
1096
1097bool wxGenericGrid::CellHitTest(int x, int y, int *row, int *col)
1098{
1099 // Find the selected cell and call OnSelectCell
da938cfd
JS
1100 if (x >= (m_leftOfSheet + m_verticalLabelWidth) && y >= (m_topOfSheet + m_horizontalLabelHeight) &&
1101 x <= m_rightOfSheet && y <= m_bottomOfSheet)
c801d85f
KB
1102 {
1103 // Calculate the cell number from x and y
da938cfd
JS
1104 x -= (m_verticalLabelWidth + m_leftOfSheet);
1105 y -= (m_topOfSheet + m_horizontalLabelHeight);
c801d85f
KB
1106
1107 int i;
1f481e6a 1108
c801d85f
KB
1109 // Now we need to do a hit test for which row we're on
1110 int currentHeight = 0;
da938cfd 1111 for (i = m_scrollPosY; i < m_totalRows; i++)
c801d85f 1112 {
da938cfd 1113 if (y >= currentHeight && y <= (currentHeight + m_rowHeights[i]))
c801d85f
KB
1114 {
1115 *row = i;
1116 break;
1117 }
da938cfd 1118 currentHeight += m_rowHeights[i];
c801d85f 1119 }
1f481e6a 1120
c801d85f
KB
1121 // Now we need to do a hit test for which column we're on
1122 int currentWidth = 0;
da938cfd 1123 for (i = m_scrollPosX; i < m_totalCols; i++)
c801d85f 1124 {
da938cfd 1125 if (x >= currentWidth && x <= (currentWidth + m_colWidths[i]))
c801d85f
KB
1126 {
1127 *col = i;
1128 break;
1129 }
da938cfd 1130 currentWidth += m_colWidths[i];
c801d85f
KB
1131 }
1132 return TRUE;
1133 }
1134 return FALSE;
1135}
1136
1137bool wxGenericGrid::LabelSashHitTest(int x, int y, int *orientation, int *rowOrCol, int *startPos)
1138{
1139 int i;
1140 int tolerance = 3;
1f481e6a 1141
da938cfd
JS
1142 if (x >= (m_leftOfSheet + m_verticalLabelWidth) && y >= m_topOfSheet &&
1143 x <= m_rightOfSheet && y <= (m_topOfSheet + m_horizontalLabelHeight))
c801d85f
KB
1144 {
1145 // We may be on a column label sash.
da938cfd
JS
1146 int currentWidth = m_leftOfSheet + m_verticalLabelWidth;
1147 for (i = m_scrollPosX; i < m_totalCols; i++)
c801d85f 1148 {
da938cfd 1149 if (x >= (currentWidth + m_colWidths[i] - tolerance) && x <= (currentWidth + m_colWidths[i] + tolerance))
c801d85f
KB
1150 {
1151 *orientation = wxHORIZONTAL;
1152 *rowOrCol = i;
1153 *startPos = currentWidth;
1154 return TRUE;
1155 }
da938cfd 1156 currentWidth += m_colWidths[i];
c801d85f
KB
1157 }
1158 return FALSE;
1159 }
da938cfd
JS
1160 else if (x >= m_leftOfSheet && y >= (m_topOfSheet + m_horizontalLabelHeight) &&
1161 x <= (m_leftOfSheet + m_verticalLabelWidth) && y <= m_bottomOfSheet)
c801d85f
KB
1162 {
1163 // We may be on a row label sash.
da938cfd
JS
1164 int currentHeight = m_topOfSheet + m_horizontalLabelHeight;
1165 for (i = m_scrollPosY; i < m_totalRows; i++)
c801d85f 1166 {
da938cfd 1167 if (y >= (currentHeight + m_rowHeights[i] - tolerance) && y <= (currentHeight + m_rowHeights[i] + tolerance))
c801d85f
KB
1168 {
1169 *orientation = wxVERTICAL;
1170 *rowOrCol = i;
1171 *startPos = currentHeight;
1172 return TRUE;
1173 }
da938cfd 1174 currentHeight += m_rowHeights[i];
c801d85f
KB
1175 }
1176 return FALSE;
1177 }
1178 return FALSE;
1179}
1180
1181bool wxGenericGrid::LabelHitTest(int x, int y, int *row, int *col)
1182{
1183 // Find the selected label
da938cfd
JS
1184 if (x >= m_leftOfSheet && y >= m_topOfSheet &&
1185 x <= m_rightOfSheet && y <= m_bottomOfSheet)
c801d85f
KB
1186 {
1187 // Calculate the cell number from x and y
da938cfd
JS
1188 x -= m_leftOfSheet;
1189 y -= m_topOfSheet;
c801d85f
KB
1190
1191 int i;
1192
1193 // Now we need to do a hit test for which row we're on
da938cfd
JS
1194 int currentHeight = m_horizontalLabelHeight;
1195 for (i = m_scrollPosY; i < m_totalRows; i++)
c801d85f 1196 {
da938cfd 1197 if (y >= currentHeight && y <= (currentHeight + m_rowHeights[i]))
c801d85f
KB
1198 {
1199 *row = i;
1200 break;
1201 }
da938cfd 1202 currentHeight += m_rowHeights[i];
c801d85f 1203 }
da938cfd 1204 if (y >= 0 && y <= m_horizontalLabelHeight)
c801d85f
KB
1205 {
1206 *row = -1;
1207 }
1208
1209 // Now we need to do a hit test for which column we're on
da938cfd
JS
1210 int currentWidth = m_verticalLabelWidth;
1211 for (i = m_scrollPosX; i < m_totalCols; i++)
c801d85f 1212 {
da938cfd 1213 if (x >= currentWidth && x <= (currentWidth + m_colWidths[i]))
c801d85f
KB
1214 {
1215 *col = i;
1216 break;
1217 }
da938cfd 1218 currentWidth += m_colWidths[i];
c801d85f 1219 }
da938cfd 1220 if (x >= 0 && x <= m_verticalLabelWidth)
c801d85f
KB
1221 {
1222 *col = -1;
1223 }
1224
1225 if ((*col == -1) || (*row == -1))
1226 {
1227 return TRUE;
1228 }
1229 }
1230 return FALSE;
1231}
1232
1233void wxGenericGrid::OnMouseEvent(wxMouseEvent& ev)
1234{
1235 if (ev.LeftDown())
1236 {
1237 wxClientDC dc(this);
1238 dc.BeginDrawing();
1f481e6a 1239
c801d85f
KB
1240 int row, col;
1241 if (CellHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
1242 {
1243 OnSelectCellImplementation(& dc, row, col);
1f481e6a
RD
1244
1245 //OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1246 wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_LCLICK, this,
1247 row, col, (int)ev.GetX(), (int)ev.GetY(),
1248 ev.ControlDown(), ev.ShiftDown());
1249 GetEventHandler()->ProcessEvent(g_evt);
1250
c801d85f
KB
1251 }
1252 if (LabelHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
1253 {
1f481e6a
RD
1254 //OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1255 wxGridEvent g_evt(GetId(), wxEVT_GRID_LABEL_LCLICK, this,
1256 row, col, (int)ev.GetX(), (int)ev.GetY(),
1257 ev.ControlDown(), ev.ShiftDown());
1258 GetEventHandler()->ProcessEvent(g_evt);
1259
c801d85f
KB
1260 }
1261 dc.EndDrawing();
1262 }
1263 else if (ev.Dragging() && ev.LeftIsDown())
1264 {
da938cfd 1265 switch (m_dragStatus)
c801d85f
KB
1266 {
1267 case wxGRID_DRAG_NONE:
1268 {
1269 int orientation;
da938cfd 1270 if (LabelSashHitTest((int)ev.GetX(), (int)ev.GetY(), &orientation, &m_dragRowOrCol, &m_dragStartPosition))
c801d85f
KB
1271 {
1272 if (orientation == wxHORIZONTAL)
1273 {
da938cfd 1274 m_dragStatus = wxGRID_DRAG_LEFT_RIGHT;
c0ed460c 1275 SetCursor(m_horizontalSashCursor);
da938cfd 1276 m_dragLastPosition = (int)ev.GetX();
c801d85f
KB
1277 }
1278 else
1279 {
da938cfd 1280 m_dragStatus = wxGRID_DRAG_UP_DOWN;
c0ed460c 1281 SetCursor(m_verticalSashCursor);
da938cfd 1282 m_dragLastPosition = (int)ev.GetY();
c801d85f
KB
1283 }
1284 wxClientDC dc(this);
1285 dc.BeginDrawing();
1286 dc.SetLogicalFunction(wxINVERT);
1287 if (orientation == wxHORIZONTAL)
da938cfd 1288 dc.DrawLine((int)ev.GetX(), m_topOfSheet, (int)ev.GetX(), m_bottomOfSheet);
c801d85f 1289 else
da938cfd 1290 dc.DrawLine(m_leftOfSheet, (int)ev.GetY(), m_rightOfSheet, (int)ev.GetY());
c801d85f 1291 dc.EndDrawing();
1f481e6a 1292
c801d85f
KB
1293 CaptureMouse();
1294 }
1295 break;
1296 }
1297 case wxGRID_DRAG_LEFT_RIGHT:
1298 {
1299 wxClientDC dc(this);
1300 dc.BeginDrawing();
1301 dc.SetLogicalFunction(wxINVERT);
da938cfd 1302 dc.DrawLine(m_dragLastPosition, m_topOfSheet, m_dragLastPosition, m_bottomOfSheet);
c801d85f 1303
da938cfd 1304 dc.DrawLine((int)ev.GetX(), m_topOfSheet, (int)ev.GetX(), m_bottomOfSheet);
c801d85f
KB
1305 dc.EndDrawing();
1306
da938cfd 1307 m_dragLastPosition = (int)ev.GetX();
c0ed460c 1308 SetCursor(m_horizontalSashCursor);
c801d85f
KB
1309 break;
1310 }
1311 case wxGRID_DRAG_UP_DOWN:
1312 {
1313 wxClientDC dc(this);
1314 dc.BeginDrawing();
1315 dc.SetLogicalFunction(wxINVERT);
da938cfd 1316 dc.DrawLine(m_leftOfSheet, m_dragLastPosition, m_rightOfSheet, m_dragLastPosition);
c801d85f 1317
da938cfd 1318 dc.DrawLine(m_leftOfSheet, (int)ev.GetY(), m_rightOfSheet, (int)ev.GetY());
c801d85f
KB
1319 dc.EndDrawing();
1320
da938cfd 1321 m_dragLastPosition = (int)ev.GetY();
c0ed460c 1322 SetCursor(m_verticalSashCursor);
c801d85f
KB
1323 break;
1324 }
1325 }
1326 }
1327 else if (ev.Moving())
1328 {
1329 int rowOrCol, orientation, startPos;
1330 if (LabelSashHitTest((int)ev.GetX(), (int)ev.GetY(), &orientation, &rowOrCol, &startPos))
1331 {
1332 if (orientation == wxHORIZONTAL)
c0ed460c 1333 SetCursor(m_horizontalSashCursor);
c801d85f 1334 else
c0ed460c 1335 SetCursor(m_verticalSashCursor);
c801d85f
KB
1336 }
1337 else
1338 SetCursor(*wxSTANDARD_CURSOR);
1339 }
1340 else if (ev.LeftUp())
1341 {
da938cfd 1342 switch (m_dragStatus)
c801d85f
KB
1343 {
1344 case wxGRID_DRAG_LEFT_RIGHT:
1345 {
1346 wxClientDC dc(this);
1347 dc.BeginDrawing();
1348 dc.SetLogicalFunction(wxINVERT);
da938cfd 1349 dc.DrawLine(m_dragLastPosition, m_topOfSheet, m_dragLastPosition, m_bottomOfSheet);
c801d85f
KB
1350 dc.SetLogicalFunction(wxCOPY);
1351 dc.EndDrawing();
1352
1353 ReleaseMouse();
da938cfd 1354 if (ev.GetX() > m_dragStartPosition)
c801d85f 1355 {
da938cfd 1356 m_colWidths[m_dragRowOrCol] = (short)(ev.GetX() - m_dragStartPosition);
c801d85f
KB
1357 UpdateDimensions();
1358 AdjustScrollbars();
1359 Refresh();
1360 }
1361 SetCursor(*wxSTANDARD_CURSOR);
1362 int cw, ch;
1363 GetClientSize(&cw, &ch);
dfe1eee3 1364 wxSizeEvent evt;
c801d85f
KB
1365 OnSize(evt);
1366 break;
1367 }
1368 case wxGRID_DRAG_UP_DOWN:
1369 {
1370 wxClientDC dc(this);
1371 dc.BeginDrawing();
1372 dc.SetLogicalFunction(wxINVERT);
da938cfd 1373 dc.DrawLine(m_leftOfSheet, m_dragLastPosition, m_rightOfSheet, m_dragLastPosition);
c801d85f
KB
1374 dc.SetLogicalFunction(wxCOPY);
1375 dc.EndDrawing();
1376
1377 ReleaseMouse();
da938cfd 1378 if (ev.GetY() > m_dragStartPosition)
c801d85f 1379 {
da938cfd 1380 m_rowHeights[m_dragRowOrCol] = (short)(ev.GetY() - m_dragStartPosition);
c801d85f
KB
1381 UpdateDimensions();
1382 AdjustScrollbars();
1383 Refresh();
1384 }
1385 SetCursor(*wxSTANDARD_CURSOR);
1386 break;
1387 }
1388 }
da938cfd 1389 m_dragStatus = wxGRID_DRAG_NONE;
c801d85f
KB
1390 }
1391 else if (ev.RightDown())
1392 {
1393 int row, col;
1394 if (CellHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
1395 {
1f481e6a
RD
1396 //OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1397 wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_RCLICK, this,
1398 row, col, (int)ev.GetX(), (int)ev.GetY(),
1399 ev.ControlDown(), ev.ShiftDown());
1400 GetEventHandler()->ProcessEvent(g_evt);
1401
c801d85f
KB
1402 }
1403 if (LabelHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
1404 {
1f481e6a
RD
1405 //OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
1406 wxGridEvent g_evt(GetId(), wxEVT_GRID_LABEL_RCLICK, this,
1407 row, col, (int)ev.GetX(), (int)ev.GetY(),
1408 ev.ControlDown(), ev.ShiftDown());
1409 GetEventHandler()->ProcessEvent(g_evt);
c801d85f
KB
1410 }
1411 }
1412}
1413
1414void wxGenericGrid::OnSelectCellImplementation(wxDC *dc, int row, int col)
1415{
da938cfd
JS
1416 m_wCursorColumn = col;
1417 m_wCursorRow = row;
1418
1f481e6a
RD
1419 //OnChangeSelectionLabel();
1420 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_SEL_LABEL, this);
1421 GetEventHandler()->ProcessEvent(g_evt);
c801d85f
KB
1422
1423 SetGridClippingRegion(dc);
1424
1425 // Remove the highlight from the old cell
c0b042fc
VZ
1426 if ( m_currentRectVisible && !(m_editable && m_editInPlace) )
1427 {
1428 HighlightCell(dc);
1429 }
dfe1eee3 1430
c801d85f
KB
1431
1432 // Highlight the new cell and copy its content to the edit control
da938cfd
JS
1433 SetCurrentRect(m_wCursorRow, m_wCursorColumn);
1434 wxGridCell *cell = GetCell(m_wCursorRow, m_wCursorColumn);
c801d85f
KB
1435 if (cell)
1436 {
dfe1eee3
VZ
1437 if ( cell->GetTextValue().IsNull() )
1438 m_textItem->SetValue("");
1439 else
1440 m_textItem->SetValue(cell->GetTextValue());
c801d85f
KB
1441 }
1442
1443 SetGridClippingRegion(dc);
1444
c0b042fc
VZ
1445
1446 if ( m_editable && m_editInPlace )
1447 {
13315b0c
VZ
1448 int x, y, width, height;
1449 if ( m_currentRect.x <= 0 )
1450 {
1451 x = 0;
1452 width = m_currentRect.width + 2;
1453 }
1454 else
1455 {
1456 x = m_currentRect.x - 2;
1457 width = m_currentRect.width + 4;
1458 }
1459
1460 if ( m_currentRect.y <= 0 )
1461 {
1462 y = 0;
1463 height = m_currentRect.height + 2;
1464 }
1465 else
1466 {
1467 y = m_currentRect.y - 2;
1468 height = m_currentRect.height + 4;
1469 }
1470
1471 m_inPlaceTextItem->SetSize( x, y, width, height );
c0b042fc
VZ
1472
1473 if ( cell )
dfe1eee3
VZ
1474 {
1475 if ( cell->GetTextValue().IsNull() )
1476 {
1477 m_inPlaceTextItem->SetValue( "" );
1478 }
1479 else
1480 {
1481 m_inPlaceTextItem->SetFont( cell->GetFont() );
1482 m_inPlaceTextItem->SetValue( cell->GetTextValue() );
1483 }
1484 }
1485
c0b042fc
VZ
1486 m_inPlaceTextItem->Show(TRUE);
1487 m_inPlaceTextItem->SetFocus();
1488 }
1489 else
dfe1eee3 1490 {
c0b042fc
VZ
1491 // 1) Why isn't this needed for Windows??
1492 // Probably because of the SetValue?? JS.
dfe1eee3 1493 // 2) Arrrrrgh. This isn't needed anywhere,
c0b042fc
VZ
1494 // of course. One hour of debugging... RR.
1495 //
1496 // 3) It *is* needed for Motif - michael
1497 //
9dc12949 1498#ifdef __WXMOTIF__
c0b042fc
VZ
1499 if ( !(m_editable && m_editInPlace) )
1500 HighlightCell(dc);
7bcb11d3 1501#endif
c0b042fc 1502 }
9dc12949 1503
c801d85f 1504 dc->DestroyClippingRegion();
1f481e6a 1505
c0b042fc 1506 OnSelectCell(row, col);
1f481e6a 1507 wxGridEvent g_evt2(GetId(), wxEVT_GRID_SELECT_CELL, this, row, col);
dfe1eee3 1508 GetEventHandler()->ProcessEvent(g_evt2);
c801d85f
KB
1509}
1510
bf6c2b35 1511wxGridCell *wxGenericGrid::OnCreateCell()
c801d85f
KB
1512{
1513 return new wxGridCell(this);
1514}
1515
bf6c2b35 1516void wxGenericGrid::OnChangeLabels()
c801d85f
KB
1517{
1518 char buf[100];
1519 int i;
da938cfd 1520 for (i = 0; i < m_totalRows; i++)
c801d85f
KB
1521 {
1522 sprintf(buf, "%d", i+1);
1523 SetLabelValue(wxVERTICAL, buf, i);
1524 }
1525 // A...Z,AA...ZZ,AAA...ZZZ, etc.
da938cfd 1526 for (i = 0; i < m_totalCols; i++)
c801d85f
KB
1527 {
1528 int j;
1529 int noTimes = (i/26 + 1);
1530 int ch = (i % 26) + 65;
1531 buf[0] = 0;
1532 for (j = 0; j < noTimes; j++)
1533 {
1534 char buf2[20];
1535 sprintf(buf2, "%c", (char)ch);
1536 strcat(buf, buf2);
1537 }
1538 SetLabelValue(wxHORIZONTAL, buf, i);
1539 }
1540}
1541
bf6c2b35 1542void wxGenericGrid::OnChangeSelectionLabel()
c801d85f
KB
1543{
1544 if (!GetEditable())
1545 return;
1f481e6a 1546
c801d85f
KB
1547 wxString rowLabel(GetLabelValue(wxVERTICAL, GetCursorRow()));
1548 wxString colLabel(GetLabelValue(wxHORIZONTAL, GetCursorColumn()));
1f481e6a 1549
c801d85f
KB
1550 wxString newLabel = colLabel + rowLabel;
1551 if ((newLabel.Length() > 0) && (newLabel.Length() <= 8) && GetTextItem())
1552 {
1553// GetTextItem()->SetLabel(newLabel);
1554 }
1555}
1556
1557void wxGenericGrid::HighlightCell(wxDC *dc)
1558{
1559 dc->SetLogicalFunction(wxINVERT);
1f481e6a 1560
c801d85f 1561 // Top
1f481e6a
RD
1562 dc->DrawLine( m_currentRect.x + 1,
1563 m_currentRect.y + 1,
1564 m_currentRect.x + m_currentRect.width - 1,
dfe1eee3 1565 m_currentRect.y + 1);
c801d85f 1566 // Right
1f481e6a 1567 dc->DrawLine( m_currentRect.x + m_currentRect.width - 1,
903f689b 1568 m_currentRect.y + 1,
1f481e6a 1569 m_currentRect.x + m_currentRect.width - 1,
dfe1eee3 1570 m_currentRect.y +m_currentRect.height - 1 );
c801d85f 1571 // Bottom
1f481e6a 1572 dc->DrawLine( m_currentRect.x + m_currentRect.width - 1,
903f689b 1573 m_currentRect.y + m_currentRect.height - 1,
1f481e6a 1574 m_currentRect.x + 1,
dfe1eee3 1575 m_currentRect.y + m_currentRect.height - 1);
c801d85f 1576 // Left
1f481e6a
RD
1577 dc->DrawLine( m_currentRect.x + 1,
1578 m_currentRect.y + m_currentRect.height - 1,
dfe1eee3
VZ
1579 m_currentRect.x + 1,
1580 m_currentRect.y + 1);
c801d85f
KB
1581
1582 dc->SetLogicalFunction(wxCOPY);
1583}
1584
bf6c2b35 1585void wxGenericGrid::DrawCellText()
c801d85f 1586{
da938cfd 1587 if (!m_currentRectVisible)
c801d85f 1588 return;
1f481e6a 1589
c801d85f
KB
1590 wxGridCell *cell = GetCell(GetCursorRow(), GetCursorColumn());
1591 if (!cell)
1592 return;
1f481e6a 1593
c801d85f
KB
1594 wxClientDC dc(this);
1595 dc.BeginDrawing();
1596
1597 SetGridClippingRegion(& dc);
1598
1599 dc.SetBackgroundMode(wxTRANSPARENT);
c0ed460c 1600 dc.SetBrush(cell->GetBackgroundBrush());
c801d85f 1601
c0b042fc 1602 wxString editValue = m_textItem->GetValue();
da938cfd 1603
16e93305 1604 wxRect rect;
da938cfd 1605 rect = m_currentRect;
c801d85f
KB
1606 rect.x += 3;
1607 rect.y += 2;
1608 rect.width -= 5;
1609 rect.height -= 4;
1610
c0b042fc
VZ
1611 // FIXME: what's this string of spaces supposed to represent?
1612 DrawTextRect(& dc, " ", &rect, wxLEFT);
1613 DrawTextRect(& dc, editValue, &rect, cell->GetAlignment());
1f481e6a 1614
c801d85f 1615 dc.DestroyClippingRegion();
1f481e6a 1616
c801d85f
KB
1617 dc.SetBackgroundMode(wxSOLID);
1618
1619 dc.EndDrawing();
1620}
1621
1622void wxGenericGrid::SetCurrentRect(int Row, int Column, int canvasW, int canvasH)
1623{
da938cfd 1624 int currentWidth = m_leftOfSheet + m_verticalLabelWidth;
c801d85f 1625 int i;
da938cfd
JS
1626 for (i = m_scrollPosX; i < Column; i++)
1627 currentWidth += m_colWidths[i];
c801d85f 1628
da938cfd
JS
1629 int currentHeight = m_topOfSheet + m_horizontalLabelHeight;
1630 for (i = m_scrollPosY; i < Row; i++)
1631 currentHeight += m_rowHeights[i];
c801d85f 1632
da938cfd
JS
1633 m_currentRect.x = currentWidth;
1634 m_currentRect.y = currentHeight;
1635 m_currentRect.width = m_colWidths ? (m_colWidths[Column]) : 0;
1636 m_currentRect.height = m_rowHeights ? (m_rowHeights[Row]) : 0;
1637
1638 if (Row < m_scrollPosY || Column < m_scrollPosX)
1639 m_currentRectVisible = FALSE;
1640 else if ((canvasW != -1 && canvasH != -1) && (m_currentRect.x > canvasW || m_currentRect.y > canvasH))
1641 m_currentRectVisible = FALSE;
1642 else m_currentRectVisible = TRUE;
c801d85f
KB
1643}
1644
16e93305 1645static bool wxRectIntersection(wxRect *rect1, wxRect *rect2, wxRect *rect3)
c801d85f
KB
1646{
1647 int x2_1 = rect1->x + rect1->width;
1648 int y2_1 = rect1->y + rect1->height;
1649
1650 int x2_2 = rect2->x + rect2->width;
1651 int y2_2 = rect2->y + rect2->height;
1f481e6a 1652
c801d85f 1653 int x2_3, y2_3;
1f481e6a 1654
c801d85f
KB
1655 // Check for intersection
1656 if ((rect1->x > x2_2) || (rect2->x > x2_1) ||
1657 (rect1->y > y2_2) || (rect2->y > y2_1))
1658 {
1659 // No intersection
1660 rect3->x = rect3->y = rect3->width = rect3->height = 0;
1661 return FALSE;
1662 }
1663
1664 if (rect1->x > rect2->x)
1665 rect3->x = rect1->x;
1666 else
1667 rect3->x = rect2->x;
1668 if (rect1->y > rect2->y)
1669 rect3->y = rect1->y;
1670 else
1671 rect3->y = rect2->y;
1f481e6a 1672
c801d85f
KB
1673 if (x2_1 > x2_2)
1674 x2_3 = x2_2;
1675 else
1676 x2_3 = x2_1;
1677 if (y2_1 > y2_2)
1678 y2_3 = y2_2;
1679 else
1680 y2_3 = y2_1;
1f481e6a 1681
c801d85f
KB
1682 rect3->width = (int)(x2_3 - rect3->x);
1683 rect3->height = (int)(y2_3 - rect3->y);
1684 return TRUE;
1685}
1686
16e93305 1687void wxGenericGrid::DrawTextRect(wxDC *dc, const wxString& text, wxRect *rect, int flag)
c801d85f
KB
1688{
1689 dc->BeginDrawing();
1f481e6a 1690
c801d85f
KB
1691 // Ultimately, this functionality should be built into wxWindows,
1692 // and optimized for each platform. E.g. on Windows, use DrawText
1693 // passing a clipping rectangle, so that the wxWindows clipping region
1694 // does not have to be used to implement this.
1f481e6a 1695
c801d85f
KB
1696 // If we're already clipping, we need to find the intersection
1697 // between current clipping area and text clipping area.
1f481e6a 1698
16e93305
JS
1699 wxRect clipRect;
1700 wxRect clipRect2;
c801d85f
KB
1701 long clipX, clipY, clipW, clipH;
1702 dc->GetClippingBox(&clipX, &clipY, &clipW, &clipH);
1703 clipRect.x = (int)clipX; clipRect.y = (int)clipY;
1704 clipRect.width = (int)clipW; clipRect.height = (int)clipH;
1f481e6a 1705
c801d85f
KB
1706 bool alreadyClipping = TRUE;
1707
1708 if (clipRect.x == 0 && clipRect.y == 0 && clipRect.width == 0 && clipRect.height == 0)
1709 {
1710 alreadyClipping = FALSE;
1711 clipRect2.x = rect->x; clipRect2.y = rect->y;
1712 clipRect2.width = rect->width; clipRect2.height = rect->height;
1713 }
1714 else
1715 {
1716 // Find intersection.
1717 if (!wxRectIntersection(rect, &clipRect, &clipRect2))
1718 return;
1719 }
1720
1721 if (alreadyClipping)
1722 dc->DestroyClippingRegion();
1f481e6a 1723
c801d85f
KB
1724 dc->SetClippingRegion(clipRect2.x, clipRect2.y, clipRect2.width, clipRect2.height);
1725 long textWidth, textHeight;
1f481e6a 1726
c801d85f 1727 dc->GetTextExtent(text, &textWidth, &textHeight);
1f481e6a 1728
c801d85f
KB
1729 // Do alignment
1730 float x,y;
1731 switch (flag)
1732 {
1733 case wxRIGHT:
1734 {
1735 x = (rect->x + rect->width - textWidth - 1.0);
1736 y = (rect->y + (rect->height - textHeight)/2.0);
1737 break;
1738 }
1739 case wxCENTRE:
1740 {
1741 x = (rect->x + (rect->width - textWidth)/2.0);
1742 y = (rect->y + (rect->height - textHeight)/2.0);
1743 break;
1744 }
1745 case wxLEFT:
1746 default:
1747 {
1748 x = (rect->x + 1.0);
1749 y = (rect->y + (rect->height - textHeight)/2.0);
1750 break;
1751 }
1752 }
1753 dc->DrawText(text, (long)x, (long)y );
1f481e6a 1754
c801d85f
KB
1755 dc->DestroyClippingRegion();
1756
1757 // Restore old clipping
1758 if (alreadyClipping)
1759 dc->SetClippingRegion(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1760
1761 dc->EndDrawing();
1762}
1763
16e93305 1764void wxGenericGrid::DrawBitmapRect(wxDC *dc, wxBitmap *bitmap, wxRect *rect, int flag)
c801d85f
KB
1765{
1766 dc->BeginDrawing();
1f481e6a 1767
c801d85f
KB
1768 // Ultimately, this functionality should be built into wxWindows,
1769 // and optimized for each platform. E.g. on Windows, use DrawText
1770 // passing a clipping rectangle, so that the wxWindows clipping region
1771 // does not have to be used to implement this.
1f481e6a 1772
c801d85f
KB
1773 // If we're already clipping, we need to find the intersection
1774 // between current clipping area and text clipping area.
1f481e6a 1775
16e93305
JS
1776 wxRect clipRect;
1777 wxRect clipRect2;
c801d85f
KB
1778 long clipX, clipY, clipW, clipH;
1779 dc->GetClippingBox(&clipX, &clipY, &clipW, &clipH);
1780 clipRect.x = (int)clipX; clipRect.y = (int)clipY;
1781 clipRect.width = (int)clipW; clipRect.height = (int)clipH;
1f481e6a 1782
c801d85f
KB
1783 bool alreadyClipping = TRUE;
1784
1785 if (clipRect.x == 0 && clipRect.y == 0 && clipRect.width == 0 && clipRect.height == 0)
1786 {
1787 alreadyClipping = FALSE;
1788 clipRect2.x = rect->x; clipRect2.y = rect->y;
1789 clipRect2.width = rect->width; clipRect2.height = rect->height;
1790 }
1791 else
1792 {
1793 // Find intersection.
1794 if (!wxRectIntersection(rect, &clipRect, &clipRect2))
1795 return;
1796 }
1797
1798 if (alreadyClipping)
1799 dc->DestroyClippingRegion();
1f481e6a 1800
c801d85f
KB
1801 dc->SetClippingRegion(clipRect2.x, clipRect2.y, clipRect2.width, clipRect2.height);
1802 float bitmapWidth, bitmapHeight;
1f481e6a 1803
c801d85f
KB
1804 bitmapWidth = bitmap->GetWidth();
1805 bitmapHeight = bitmap->GetHeight();
1f481e6a 1806
c801d85f
KB
1807 // Do alignment
1808 long x,y;
1809 switch (flag)
1810 {
1811 case wxRIGHT:
1812 {
1813 x = (long)(rect->x + rect->width - bitmapWidth - 1);
1814 y = (long)(rect->y + (rect->height - bitmapHeight)/2.0);
1815 break;
1816 }
1817 case wxCENTRE:
1818 {
1819 x = (long)(rect->x + (rect->width - bitmapWidth)/2.0);
1820 y = (long)(rect->y + (rect->height - bitmapHeight)/2.0);
1821 break;
1822 }
1823 case wxLEFT:
1824 default:
1825 {
1826 x = (long)(rect->x + 1);
1827 y = (long)(rect->y + (rect->height - bitmapHeight)/2.0);
1828 break;
1829 }
1830 }
1831 wxMemoryDC dcTemp;
1832 dcTemp.SelectObject(*bitmap);
1f481e6a 1833
c801d85f
KB
1834 dc->Blit( (long)x, (long)y, (long)bitmapWidth, (long)bitmapHeight, &dcTemp, 0, 0);
1835 dcTemp.SelectObject(wxNullBitmap);
1f481e6a 1836
c801d85f
KB
1837 dc->DestroyClippingRegion();
1838
1839 // Restore old clipping
1840 if (alreadyClipping)
1841 dc->SetClippingRegion(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
1842
1843 dc->EndDrawing();
1844}
1845
1846void wxGenericGrid::OnActivate(bool active)
1847{
1848 if (active)
1849 {
1850 // Edit control should always have the focus
1851 if (GetTextItem() && GetEditable())
1852 {
1853 GetTextItem()->SetFocus();
1854 wxGridCell *cell = GetCell(GetCursorRow(), GetCursorColumn());
1855 if (cell)
1856 GetTextItem()->SetValue(cell->GetTextValue());
1857 }
1858 }
1859}
1860
1861void wxGenericGrid::SetCellValue(const wxString& val, int row, int col)
1862{
1863 wxGridCell *cell = GetCell(row, col);
1864 if (cell)
1865 {
1866 cell->SetTextValue(val);
1867
1868 RefreshCell(row, col, TRUE);
1869 }
1870}
1871
1872void wxGenericGrid::RefreshCell(int row, int col, bool setText)
1873{
1874 // Don't refresh within a pair of batch brackets
1875 if (GetBatchCount() > 0)
1876 return;
1f481e6a 1877
c801d85f
KB
1878 int cw, ch;
1879 GetClientSize(&cw, &ch);
1880
1881 SetCurrentRect(row, col, cw, ch);
da938cfd 1882 if (m_currentRectVisible)
c801d85f
KB
1883 {
1884 wxGridCell *cell = GetCell(row, col);
1885
1886 bool currentPos = FALSE;
da938cfd 1887 if (row == m_wCursorRow && col == m_wCursorColumn && GetTextItem() && GetTextItem()->IsShown() && setText)
c801d85f
KB
1888 {
1889 GetTextItem()->SetValue(cell->GetTextValue());
1890 currentPos = TRUE;
1891 }
1892 // Gets refreshed anyway in MSW
2049ba38 1893#ifdef __WXMSW__
c801d85f
KB
1894 if (!currentPos)
1895#endif
1896 {
1897 wxClientDC dc(this);
1898 dc.BeginDrawing();
da938cfd
JS
1899 DrawCellBackground(& dc, &m_currentRect, row, col);
1900 DrawCellValue(& dc, &m_currentRect, row, col);
c801d85f
KB
1901 dc.EndDrawing();
1902 }
1903 }
1904}
1905
c0ed460c 1906wxString& wxGenericGrid::GetCellValue(int row, int col) const
c801d85f
KB
1907{
1908 static wxString emptyString("");
1f481e6a 1909
c801d85f
KB
1910 wxGridCell *cell = GetCell(row, col);
1911 if (cell)
1912 return cell->GetTextValue();
1913 else
1914 return emptyString;
1915}
1916
1917void wxGenericGrid::SetColumnWidth(int col, int width)
1918{
da938cfd
JS
1919 if (col <= m_totalCols)
1920 m_colWidths[col] = width;
c801d85f
KB
1921}
1922
c0ed460c 1923int wxGenericGrid::GetColumnWidth(int col) const
c801d85f 1924{
da938cfd
JS
1925 if (col <= m_totalCols)
1926 return m_colWidths[col];
c801d85f
KB
1927 else
1928 return 0;
1929}
1930
1931void wxGenericGrid::SetRowHeight(int row, int height)
1932{
da938cfd
JS
1933 if (row <= m_totalRows)
1934 m_rowHeights[row] = height;
c801d85f
KB
1935}
1936
c0ed460c 1937int wxGenericGrid::GetRowHeight(int row) const
c801d85f 1938{
da938cfd
JS
1939 if (row <= m_totalRows)
1940 return m_rowHeights[row];
c801d85f
KB
1941 else
1942 return 0;
1943}
1944
1945void wxGenericGrid::SetLabelSize(int orientation, int sz)
1946{
1947 if (orientation == wxHORIZONTAL)
da938cfd 1948 m_horizontalLabelHeight = sz;
c801d85f 1949 else
da938cfd 1950 m_verticalLabelWidth = sz;
c801d85f
KB
1951 UpdateDimensions();
1952 SetCurrentRect(GetCursorRow(), GetCursorColumn());
1953}
1954
c0ed460c 1955int wxGenericGrid::GetLabelSize(int orientation) const
c801d85f
KB
1956{
1957 if (orientation == wxHORIZONTAL)
da938cfd 1958 return m_horizontalLabelHeight;
c801d85f 1959 else
da938cfd 1960 return m_verticalLabelWidth;
c801d85f
KB
1961}
1962
c0ed460c 1963wxGridCell *wxGenericGrid::GetLabelCell(int orientation, int pos) const
c801d85f
KB
1964{
1965 if (orientation == wxHORIZONTAL)
1966 {
da938cfd
JS
1967 if (m_colLabelCells && pos < m_totalCols)
1968 return m_colLabelCells[pos];
c801d85f 1969 else
c67daf87 1970 return (wxGridCell *) NULL;
c801d85f
KB
1971 }
1972 else
1973 {
da938cfd
JS
1974 if (m_rowLabelCells && pos < m_totalRows)
1975 return m_rowLabelCells[pos];
c801d85f 1976 else
c67daf87 1977 return (wxGridCell *) NULL;
c801d85f
KB
1978 }
1979}
1980
1981void wxGenericGrid::SetLabelValue(int orientation, const wxString& val, int pos)
1982{
1983 wxGridCell *cell = GetLabelCell(orientation, pos);
1984 if (cell)
1985 cell->SetTextValue(val);
1986}
1987
c0ed460c 1988wxString& wxGenericGrid::GetLabelValue(int orientation, int pos) const
c801d85f
KB
1989{
1990 static wxString emptyString = "";
1991 wxGridCell *cell = GetLabelCell(orientation, pos);
1992 if (cell)
1993 return cell->GetTextValue();
1994 else
1995 return emptyString;
1996}
1997
1998void wxGenericGrid::SetLabelAlignment(int orientation, int align)
1999{
2000 if (orientation == wxHORIZONTAL)
da938cfd 2001 m_horizontalLabelAlignment = align;
c801d85f 2002 else
da938cfd 2003 m_verticalLabelAlignment = align;
c801d85f
KB
2004 UpdateDimensions();
2005 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2006}
2007
c0ed460c 2008int wxGenericGrid::GetLabelAlignment(int orientation) const
c801d85f
KB
2009{
2010 if (orientation == wxHORIZONTAL)
da938cfd 2011 return m_horizontalLabelAlignment;
c801d85f 2012 else
da938cfd 2013 return m_verticalLabelAlignment;
c801d85f
KB
2014}
2015
2016void wxGenericGrid::SetLabelTextColour(const wxColour& colour)
2017{
da938cfd 2018 m_labelTextColour = colour;
c801d85f
KB
2019
2020}
2021
2022void wxGenericGrid::SetLabelBackgroundColour(const wxColour& colour)
2023{
da938cfd 2024 m_labelBackgroundColour = colour;
c0ed460c 2025 m_labelBackgroundBrush = * wxTheBrushList->FindOrCreateBrush(m_labelBackgroundColour, wxSOLID);
c801d85f
KB
2026}
2027
2028void wxGenericGrid::SetEditable(bool edit)
2029{
da938cfd 2030 m_editable = edit;
c801d85f
KB
2031 if (edit)
2032 {
2033 int controlW, controlH;
da938cfd
JS
2034 m_textItem->GetSize(&controlW, &controlH);
2035 m_editControlPosition.height = controlH;
2036
2037 m_topOfSheet = m_editControlPosition.x + controlH + 2;
2038 if (m_textItem)
c801d85f 2039 {
da938cfd
JS
2040 m_editingPanel->Show(TRUE);
2041 m_textItem->Show(TRUE);
2042 m_textItem->SetFocus();
c801d85f 2043 }
c0b042fc
VZ
2044
2045 if (m_inPlaceTextItem)
2046 {
dfe1eee3
VZ
2047 m_inPlaceTextItem->Show(TRUE);
2048 m_inPlaceTextItem->SetFocus();
c0b042fc 2049 }
c801d85f
KB
2050 }
2051 else
2052 {
da938cfd
JS
2053 m_topOfSheet = 0;
2054 if (m_textItem)
c801d85f 2055 {
da938cfd
JS
2056 m_textItem->Show(FALSE);
2057 m_editingPanel->Show(FALSE);
c801d85f 2058 }
dfe1eee3 2059
c0b042fc
VZ
2060 if ( m_inPlaceTextItem )
2061 {
dfe1eee3 2062 m_inPlaceTextItem->Show(FALSE);
c0b042fc 2063 }
c801d85f
KB
2064 }
2065 UpdateDimensions();
2066 SetCurrentRect(GetCursorRow(), GetCursorColumn());
2067
2068 int cw, ch;
2069 GetClientSize(&cw, &ch);
2070 wxSizeEvent evt;
2071 OnSize(evt);
2072/*
2073 int cw, ch;
da938cfd 2074 int m_scrollWidth = 16;
c801d85f 2075 GetClientSize(&cw, &ch);
1f481e6a 2076
da938cfd
JS
2077 if (m_vScrollBar)
2078 m_vScrollBar->SetSize(cw - m_scrollWidth, m_topOfSheet,
2079 m_scrollWidth, ch - m_topOfSheet - m_scrollWidth);
c801d85f
KB
2080*/
2081}
2082
c0b042fc
VZ
2083
2084void wxGenericGrid::SetEditInPlace(bool edit)
2085{
2086 if ( m_editInPlace != edit )
2087 {
2088 m_editInPlace = edit;
dfe1eee3 2089
c0b042fc 2090 if ( m_editInPlace ) // switched on
dfe1eee3
VZ
2091 {
2092 if ( m_currentRectVisible && m_editable )
2093 {
2094 m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2,
2095 m_currentRect.width+4, m_currentRect.height+4 );
2096
2097 wxGridCell *cell = GetCell(m_wCursorRow, m_wCursorColumn);
2098
2099 if ( cell )
2100 {
2101 if ( cell->GetTextValue().IsNull() )
2102 {
2103 m_inPlaceTextItem->SetValue( "" );
2104 }
2105 else
2106 {
2107 m_inPlaceTextItem->SetFont( cell->GetFont() );
2108 m_inPlaceTextItem->SetValue( cell->GetTextValue() );
2109 }
2110 }
2111
2112 m_inPlaceTextItem->Show( TRUE );
2113 m_inPlaceTextItem->SetFocus();
2114 }
2115 }
c0b042fc 2116 else // switched off
dfe1eee3
VZ
2117 {
2118 m_inPlaceTextItem->Show( FALSE );
2119 }
c0b042fc
VZ
2120 }
2121}
2122
2123
c801d85f
KB
2124void wxGenericGrid::SetCellAlignment(int flag, int row, int col)
2125{
2126 wxGridCell *cell = GetCell(row, col);
2127 if (cell)
2128 cell->SetAlignment(flag);
2129}
2130
c0ed460c 2131int wxGenericGrid::GetCellAlignment(int row, int col) const
c801d85f
KB
2132{
2133 wxGridCell *cell = GetCell(row, col);
2134 if (cell)
2135 return cell->GetAlignment();
2136 else
da938cfd 2137 return m_cellAlignment;
c801d85f
KB
2138}
2139
2140void wxGenericGrid::SetCellAlignment(int flag)
2141{
da938cfd 2142 m_cellAlignment = flag;
c801d85f
KB
2143 int i,j;
2144 for (i = 0; i < GetRows(); i++)
2145 for (j = 0; j < GetCols(); j++)
2146 if (GetCell(i, j))
2147 GetCell(i, j)->SetAlignment(flag);
2148}
2149
c0ed460c 2150int wxGenericGrid::GetCellAlignment(void) const
c801d85f 2151{
da938cfd 2152 return m_cellAlignment;
c801d85f
KB
2153}
2154
2155void wxGenericGrid::SetCellBackgroundColour(const wxColour& col)
2156{
da938cfd 2157 m_cellBackgroundColour = col;
c801d85f
KB
2158 int i,j;
2159 for (i = 0; i < GetRows(); i++)
2160 for (j = 0; j < GetCols(); j++)
2161 if (GetCell(i, j))
2162 GetCell(i, j)->SetBackgroundColour(col);
2163}
2164
2165void wxGenericGrid::SetCellBackgroundColour(const wxColour& val, int row, int col)
2166{
2167 wxGridCell *cell = GetCell(row, col);
2168 if (cell)
2169 {
2170 cell->SetBackgroundColour(val);
2171 RefreshCell(row, col);
2172 }
2173}
2174
c0ed460c 2175wxColour& wxGenericGrid::GetCellBackgroundColour(int row, int col) const
c801d85f
KB
2176{
2177 wxGridCell *cell = GetCell(row, col);
2178 if (cell)
2179 return cell->GetBackgroundColour();
2180 else
c0ed460c 2181 return (wxColour&) m_cellBackgroundColour;
c801d85f
KB
2182}
2183
2184void wxGenericGrid::SetCellTextColour(const wxColour& val, int row, int col)
2185{
2186 wxGridCell *cell = GetCell(row, col);
2187 if (cell)
2188 {
2189 cell->SetTextColour(val);
2190 RefreshCell(row, col);
2191 }
2192}
2193
c0ed460c 2194void wxGenericGrid::SetCellTextFont(const wxFont& fnt, int row, int col)
c801d85f
KB
2195{
2196 wxGridCell *cell = GetCell(row, col);
2197 if (cell)
2198 {
2199 cell->SetFont(fnt);
2200 RefreshCell(row, col);
2201 }
2202}
2203
c0ed460c 2204wxFont& wxGenericGrid::GetCellTextFont(int row, int col) const
c801d85f
KB
2205{
2206 wxGridCell *cell = GetCell(row, col);
2207 if (cell)
c0ed460c 2208 return (wxFont&) cell->GetFont();
c801d85f 2209 else
c0ed460c 2210 return (wxFont&) m_cellTextFont;
c801d85f
KB
2211}
2212
c0ed460c 2213wxColour& wxGenericGrid::GetCellTextColour(int row, int col) const
c801d85f
KB
2214{
2215 wxGridCell *cell = GetCell(row, col);
2216 if (cell)
c0ed460c 2217 return (wxColour&) cell->GetTextColour();
c801d85f 2218 else
c0ed460c 2219 return (wxColour&) m_cellTextColour;
c801d85f
KB
2220}
2221
2222void wxGenericGrid::SetCellTextColour(const wxColour& val)
2223{
da938cfd 2224 m_cellTextColour = val;
c801d85f
KB
2225 int i,j;
2226 for (i = 0; i < GetRows(); i++)
2227 for (j = 0; j < GetCols(); j++)
2228 if (GetCell(i, j))
2229 GetCell(i, j)->SetTextColour(val);
2230}
2231
c0ed460c 2232void wxGenericGrid::SetCellTextFont(const wxFont& fnt)
c801d85f 2233{
da938cfd 2234 m_cellTextFont = fnt;
c801d85f
KB
2235 int i,j;
2236 for (i = 0; i < GetRows(); i++)
2237 for (j = 0; j < GetCols(); j++)
2238 if (GetCell(i, j))
2239 GetCell(i, j)->SetFont(fnt);
2240}
2241
2242void wxGenericGrid::SetCellBitmap(wxBitmap *bitmap, int row, int col)
2243{
2244 wxGridCell *cell = GetCell(row, col);
2245 if (cell)
2246 {
2247 cell->SetCellBitmap(bitmap);
2248 RefreshCell(row, col);
2249 }
2250}
2251
c0ed460c 2252wxBitmap *wxGenericGrid::GetCellBitmap(int row, int col) const
c801d85f
KB
2253{
2254 wxGridCell *cell = GetCell(row, col);
2255 if (cell)
2256 {
2257 return cell->GetCellBitmap();
2258 }
2259 else
c67daf87 2260 return (wxBitmap *) NULL;
c801d85f
KB
2261}
2262
2263bool wxGenericGrid::InsertCols(int pos, int n, bool updateLabels)
2264{
da938cfd 2265 if (pos > m_totalCols)
c801d85f 2266 return FALSE;
1f481e6a 2267
da938cfd 2268 if (!m_gridCells)
c801d85f
KB
2269 return CreateGrid(1, n);
2270 else
2271 {
2272 int i, j;
2273 // Cells
da938cfd 2274 for (i = 0; i < m_totalRows; i++)
c801d85f 2275 {
da938cfd
JS
2276 wxGridCell **cols = m_gridCells[i];
2277 wxGridCell **newCols = new wxGridCell *[m_totalCols + n];
c801d85f
KB
2278 for (j = 0; j < pos; j++)
2279 newCols[j] = cols[j];
2280 for (j = pos; j < pos + n; j++)
2281 newCols[j] = new wxGridCell(this);
da938cfd 2282 for (j = pos + n; j < m_totalCols + n; j++)
c801d85f 2283 newCols[j] = cols[j - n];
1f481e6a 2284
c801d85f 2285 delete[] cols;
da938cfd 2286 m_gridCells[i] = newCols;
c801d85f
KB
2287 }
2288
2289 // Column widths
da938cfd 2290 short *newColWidths = new short[m_totalCols + n];
c801d85f 2291 for (j = 0; j < pos; j++)
da938cfd 2292 newColWidths[j] = m_colWidths[j];
c801d85f
KB
2293 for (j = pos; j < pos + n; j++)
2294 newColWidths[j] = wxGRID_DEFAULT_CELL_WIDTH;
da938cfd
JS
2295 for (j = pos + n; j < m_totalCols + n; j++)
2296 newColWidths[j] = m_colWidths[j - n];
2297 delete[] m_colWidths;
2298 m_colWidths = newColWidths;
c801d85f
KB
2299
2300 // Column labels
da938cfd 2301 wxGridCell **newLabels = new wxGridCell *[m_totalCols + n];
c801d85f 2302 for (j = 0; j < pos; j++)
da938cfd 2303 newLabels[j] = m_colLabelCells[j];
c801d85f
KB
2304 for (j = pos; j < pos + n; j++)
2305 newLabels[j] = new wxGridCell(this);
da938cfd
JS
2306 for (j = pos + n; j < m_totalCols + n; j++)
2307 newLabels[j] = m_colLabelCells[j - n];
2308
2309 delete[] m_colLabelCells;
2310 m_colLabelCells = newLabels;
2311
2312 m_totalCols += n;
c801d85f 2313
1f481e6a
RD
2314 if (updateLabels) {
2315 //OnChangeLabels();
2316 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS, this);
2317 GetEventHandler()->ProcessEvent(g_evt);
2318 }
2319
c801d85f
KB
2320 UpdateDimensions();
2321 AdjustScrollbars();
2322 return TRUE;
2323 }
2324}
2325
2326bool wxGenericGrid::InsertRows(int pos, int n, bool updateLabels)
2327{
da938cfd 2328 if (pos > m_totalRows)
c801d85f 2329 return FALSE;
1f481e6a 2330
da938cfd 2331 if (!m_gridCells)
c801d85f
KB
2332 return CreateGrid(n, 1);
2333 else
2334 {
2335 int i, j;
1f481e6a 2336
da938cfd 2337 wxGridCell ***rows = new wxGridCell **[m_totalRows + n];
c801d85f
KB
2338
2339 // Cells
2340 for (i = 0; i < pos; i++)
da938cfd 2341 rows[i] = m_gridCells[i];
c801d85f
KB
2342
2343 for (i = pos; i < pos + n; i++)
2344 {
da938cfd
JS
2345 rows[i] = new wxGridCell *[m_totalCols];
2346 for (j = 0; j < m_totalCols; j++)
c801d85f
KB
2347 rows[i][j] = new wxGridCell(this);
2348 }
1f481e6a 2349
da938cfd
JS
2350 for (i = pos + n; i < m_totalRows + n; i++)
2351 rows[i] = m_gridCells[i - n];
2352
2353 delete[] m_gridCells;
2354 m_gridCells = rows;
c801d85f
KB
2355
2356 // Row heights
da938cfd 2357 short *newRowHeights = new short[m_totalRows + n];
c801d85f 2358 for (i = 0; i < pos; i++)
da938cfd 2359 newRowHeights[i] = m_rowHeights[i];
c801d85f
KB
2360 for (i = pos; i < pos + n; i++)
2361 newRowHeights[i] = wxGRID_DEFAULT_CELL_HEIGHT;
da938cfd
JS
2362 for (i = pos + n; i < m_totalRows + n; i++)
2363 newRowHeights[i] = m_rowHeights[i - n];
2364 delete[] m_rowHeights;
2365 m_rowHeights = newRowHeights;
c801d85f
KB
2366
2367 // Column labels
da938cfd 2368 wxGridCell **newLabels = new wxGridCell *[m_totalRows + n];
c801d85f 2369 for (i = 0; i < pos; i++)
da938cfd 2370 newLabels[i] = m_rowLabelCells[i];
c801d85f
KB
2371 for (i = pos; i < pos + n; i++)
2372 newLabels[i] = new wxGridCell(this);
da938cfd
JS
2373 for (i = pos + n; i < m_totalRows + n; i++)
2374 newLabels[i] = m_rowLabelCells[i - n];
2375
2376 delete[] m_rowLabelCells;
2377 m_rowLabelCells = newLabels;
2378
2379 m_totalRows += n;
c801d85f 2380
1f481e6a
RD
2381 if (updateLabels) {
2382 //OnChangeLabels();
2383 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS, this);
2384 GetEventHandler()->ProcessEvent(g_evt);
2385 }
2386
c801d85f
KB
2387 UpdateDimensions();
2388 AdjustScrollbars();
2389 return TRUE;
2390 }
2391}
2392
2393bool wxGenericGrid::AppendCols(int n, bool updateLabels)
2394{
2395 return InsertCols(GetCols(), n, updateLabels);
2396}
2397
2398bool wxGenericGrid::AppendRows(int n, bool updateLabels)
2399{
2400 return InsertRows(GetRows(), n, updateLabels);
2401}
2402
2403bool wxGenericGrid::DeleteRows(int pos, int n, bool updateLabels)
2404{
da938cfd 2405 if (pos > m_totalRows)
c801d85f 2406 return FALSE;
da938cfd 2407 if (!m_gridCells)
c801d85f
KB
2408 return FALSE;
2409
2410 int i;
1f481e6a 2411
da938cfd 2412 wxGridCell ***rows = new wxGridCell **[m_totalRows - n];
c801d85f
KB
2413
2414 // Cells
2415 for (i = 0; i < pos; i++)
da938cfd 2416 rows[i] = m_gridCells[i];
c801d85f 2417
da938cfd
JS
2418 for (i = pos + n; i < m_totalRows; i++)
2419 rows[i-n] = m_gridCells[i];
2420
2421 delete[] m_gridCells;
2422 m_gridCells = rows;
c801d85f
KB
2423
2424 // Row heights
da938cfd 2425 short *newRowHeights = new short[m_totalRows - n];
c801d85f 2426 for (i = 0; i < pos; i++)
da938cfd
JS
2427 newRowHeights[i] = m_rowHeights[i];
2428 for (i = pos + n; i < m_totalRows; i++)
2429 newRowHeights[i-n] = m_rowHeights[i];
2430 delete[] m_rowHeights;
2431 m_rowHeights = newRowHeights;
c801d85f
KB
2432
2433 // Column labels
da938cfd 2434 wxGridCell **newLabels = new wxGridCell *[m_totalRows - n];
c801d85f 2435 for (i = 0; i < pos; i++)
da938cfd
JS
2436 newLabels[i] = m_rowLabelCells[i];
2437 for (i = pos + n; i < m_totalRows; i++)
2438 newLabels[i-n] = m_rowLabelCells[i];
2439
2440 delete[] m_rowLabelCells;
2441 m_rowLabelCells = newLabels;
2442
2443 m_totalRows -= n;
c801d85f 2444
1f481e6a
RD
2445 if (updateLabels){
2446 //OnChangeLabels();
2447 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS, this);
2448 GetEventHandler()->ProcessEvent(g_evt);
2449 }
c801d85f
KB
2450 UpdateDimensions();
2451 AdjustScrollbars();
2452 return TRUE;
2453}
2454
2455bool wxGenericGrid::DeleteCols(int pos, int n, bool updateLabels)
2456{
da938cfd 2457 if (pos + n > m_totalCols)
c801d85f 2458 return FALSE;
da938cfd 2459 if (!m_gridCells)
c801d85f
KB
2460 return FALSE;
2461
2462 int i, j;
2463
2464 // Cells
da938cfd 2465 for (i = 0; i < m_totalRows; i++)
c801d85f 2466 {
da938cfd
JS
2467 wxGridCell **cols = m_gridCells[i];
2468 wxGridCell **newCols = new wxGridCell *[m_totalCols - n];
c801d85f
KB
2469 for (j = 0; j < pos; j++)
2470 newCols[j] = cols[j];
2471 for (j = pos; j < pos + n; j++)
2472 delete cols[j];
da938cfd 2473 for (j = pos + n; j < m_totalCols; j++)
c801d85f 2474 newCols[j-n] = cols[j];
1f481e6a 2475
c801d85f 2476 delete[] cols;
da938cfd 2477 m_gridCells[i] = newCols;
c801d85f
KB
2478 }
2479
2480 // Column widths
da938cfd 2481 short *newColWidths = new short[m_totalCols - n];
c801d85f 2482 for (j = 0; j < pos; j++)
da938cfd
JS
2483 newColWidths[j] = m_colWidths[j];
2484 for (j = pos + n; j < m_totalCols; j++)
2485 newColWidths[j-n] = m_colWidths[j];
2486 delete[] m_colWidths;
2487 m_colWidths = newColWidths;
c801d85f
KB
2488
2489 // Column labels
da938cfd 2490 wxGridCell **newLabels = new wxGridCell *[m_totalCols - n];
c801d85f 2491 for (j = 0; j < pos; j++)
da938cfd
JS
2492 newLabels[j] = m_colLabelCells[j];
2493 for (j = pos + n; j < m_totalCols; j++)
2494 newLabels[j-n] = m_colLabelCells[j];
2495
2496 delete[] m_colLabelCells;
2497 m_colLabelCells = newLabels;
2498
2499 m_totalCols -= n;
c801d85f 2500
1f481e6a
RD
2501 if (updateLabels) {
2502 //OnChangeLabels();
2503 wxGridEvent g_evt(GetId(), wxEVT_GRID_CHANGE_LABELS, this);
2504 GetEventHandler()->ProcessEvent(g_evt);
2505 }
c801d85f
KB
2506 UpdateDimensions();
2507 AdjustScrollbars();
2508 return TRUE;
2509}
2510
2511void wxGenericGrid::SetGridCursor(int row, int col)
2512{
da938cfd 2513 if (row >= m_totalRows || col >= m_totalCols)
c801d85f 2514 return;
1f481e6a 2515
c801d85f
KB
2516 if (row == GetCursorRow() && col == GetCursorColumn())
2517 return;
1f481e6a 2518
c801d85f
KB
2519 wxClientDC dc(this);
2520 dc.BeginDrawing();
1f481e6a 2521
c801d85f
KB
2522 SetGridClippingRegion(& dc);
2523
c0b042fc 2524 if (m_currentRectVisible && !(m_editable && m_editInPlace) )
c801d85f 2525 HighlightCell(& dc);
1f481e6a 2526
da938cfd
JS
2527 m_wCursorRow = row;
2528 m_wCursorColumn = col;
2243eed5
JS
2529
2530 int cw, ch;
2531 GetClientSize(&cw, &ch);
2532
2533 SetCurrentRect(row, col, cw, ch);
2534
c0b042fc 2535 if (m_currentRectVisible && !(m_editable && m_editInPlace) )
c801d85f
KB
2536 HighlightCell(& dc);
2537
2538 dc.DestroyClippingRegion();
2539 dc.EndDrawing();
2540}
2541
bf6c2b35
VZ
2542// ----------------------------------------------------------------------------
2543// Grid cell
2544// ----------------------------------------------------------------------------
1f481e6a 2545
c801d85f
KB
2546wxGridCell::wxGridCell(wxGenericGrid *window)
2547{
c67daf87 2548 cellBitmap = (wxBitmap *) NULL;
c0ed460c
JS
2549 font = wxNullFont;
2550 backgroundBrush = wxNullBrush;
c801d85f
KB
2551 if (window)
2552 textColour = window->GetCellTextColour();
2553 else
2554 textColour.Set(0,0,0);
2555 if (window)
2556 backgroundColour = window->GetCellBackgroundColour();
2557 else
2558 backgroundColour.Set(255,255,255);
1f481e6a 2559
c801d85f
KB
2560 if (window)
2561 font = window->GetCellTextFont();
2562 else
c0ed460c 2563 font = * wxTheFontList->FindOrCreateFont(12, wxSWISS, wxNORMAL, wxNORMAL);
1f481e6a 2564
c801d85f 2565 SetBackgroundColour(backgroundColour);
1f481e6a 2566
c801d85f
KB
2567 if (window)
2568 alignment = window->GetCellAlignment();
2569 else
2570 alignment = wxLEFT;
bf6c2b35
VZ
2571
2572 cellData = (void *)NULL;
c801d85f
KB
2573}
2574
bf6c2b35 2575wxGridCell::~wxGridCell()
c801d85f
KB
2576{
2577}
2578
2579void wxGridCell::SetBackgroundColour(const wxColour& colour)
2580{
2581 backgroundColour = colour;
c0ed460c 2582 backgroundBrush = * wxTheBrushList->FindOrCreateBrush(backgroundColour, wxSOLID);
c801d85f
KB
2583}
2584
2585void wxGenericGrid::OnText(wxCommandEvent& WXUNUSED(ev) )
2586{
c0b042fc
VZ
2587 // michael - added this conditional to prevent change to
2588 // grid cell text when edit control is hidden but still has
2589 // focus
2590 //
2591 if ( m_editable )
2592 {
2593 wxGenericGrid *grid = this;
2594 wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn());
2595 if (cell && grid->CurrentCellVisible())
dfe1eee3
VZ
2596 {
2597 cell->SetTextValue(grid->GetTextItem()->GetValue());
2598 if ( m_editInPlace && !m_inOnTextInPlace )
2599 {
2600 m_inPlaceTextItem->SetValue( grid->GetTextItem()->GetValue() );
2601 }
2602
2603 wxClientDC dc(grid);
2604
2605 dc.BeginDrawing();
2606 grid->SetGridClippingRegion(& dc);
2607 grid->DrawCellBackground(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn());
2608 grid->DrawCellValue(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn());
2609 if ( !(m_editable && m_editInPlace ) ) grid->HighlightCell(& dc);
2610 dc.DestroyClippingRegion();
2611 dc.EndDrawing();
2612
2613 //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
2614 wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_CHANGE, grid,
2615 grid->GetCursorRow(), grid->GetCursorColumn());
2616 GetEventHandler()->ProcessEvent(g_evt);
2617
2618 // grid->DrawCellText();
2619 }
2620 }
2621}
2622
2623void wxGenericGrid::OnTextEnter(wxCommandEvent& WXUNUSED(ev) )
2624{
2625 // move the cursor down the current row (if possible)
2626 // when the enter key has been pressed
2627 //
2628 if ( m_editable )
2629 {
2630 if ( GetCursorRow() < GetRows()-1 )
2631 {
2632 wxClientDC dc( this );
2633 dc.BeginDrawing();
2634 OnSelectCellImplementation(& dc,
2635 GetCursorRow()+1,
2636 GetCursorColumn() );
2637 dc.EndDrawing();
2638 }
c0b042fc
VZ
2639 }
2640}
1f481e6a 2641
c0b042fc
VZ
2642void wxGenericGrid::OnTextInPlace(wxCommandEvent& ev )
2643{
2644 if ( m_editable )
2645 {
2646 wxGenericGrid *grid = this;
2647 wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn());
2648 if (cell && grid->CurrentCellVisible())
dfe1eee3
VZ
2649 {
2650 m_inOnTextInPlace = TRUE;
2651 grid->GetTextItem()->SetValue( m_inPlaceTextItem->GetValue() );
2652 OnText( ev );
2653 m_inOnTextInPlace = FALSE;
2654 }
2655 }
2656}
2657
2658void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent& WXUNUSED(ev) )
2659{
2660 // move the cursor down the current row (if possible)
2661 // when the enter key has been pressed
2662 //
2663 if ( m_editable )
2664 {
2665 if ( GetCursorRow() < GetRows()-1 )
2666 {
2667 wxClientDC dc( this );
2668 dc.BeginDrawing();
2669 OnSelectCellImplementation(& dc,
2670 GetCursorRow()+1,
2671 GetCursorColumn() );
2672 dc.EndDrawing();
2673 }
c0b042fc 2674 }
c801d85f
KB
2675}
2676
2677void wxGenericGrid::OnGridScroll(wxScrollEvent& ev)
2678{
2679 static bool inScroll = FALSE;
2680
2681 if ( inScroll )
dfe1eee3 2682 return;
c801d85f 2683
c0b042fc
VZ
2684 if ( m_editInPlace ) m_inPlaceTextItem->Show(FALSE);
2685
c801d85f
KB
2686 inScroll = TRUE;
2687 wxGenericGrid *win = this;
2688
2689 bool change = FALSE;
1f481e6a 2690
c801d85f
KB
2691 if (ev.GetEventObject() == win->GetHorizScrollBar())
2692 {
da938cfd 2693 change = (ev.GetPosition() != m_scrollPosX);
c801d85f
KB
2694 win->SetScrollPosX(ev.GetPosition());
2695 }
2696 else
2697 {
da938cfd 2698 change = (ev.GetPosition() != m_scrollPosY);
c801d85f
KB
2699 win->SetScrollPosY(ev.GetPosition());
2700 }
2701
2702 win->UpdateDimensions();
8aa04e8b 2703
c801d85f
KB
2704 win->SetCurrentRect(win->GetCursorRow(), win->GetCursorColumn());
2705
2706 // Because rows and columns can be arbitrary sizes,
2707 // the scrollbars will need to be adjusted to reflect the
2708 // current view.
2709 AdjustScrollbars();
2710
2711 if (change) win->Refresh(FALSE);
c0b042fc
VZ
2712
2713 if ( m_editInPlace && m_currentRectVisible )
2714 {
dfe1eee3
VZ
2715 m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2,
2716 m_currentRect.width+4, m_currentRect.height+4 );
c0b042fc 2717 m_inPlaceTextItem->Show( TRUE );
dfe1eee3 2718 m_inPlaceTextItem->SetFocus();
c0b042fc
VZ
2719 }
2720
c801d85f 2721 inScroll = FALSE;
1f481e6a 2722
c801d85f 2723}
1f481e6a
RD
2724
2725
2726//----------------------------------------------------------------------
2727// Default wxGridEvent handlers
2728// (just redirect to the pre-existing virtual methods)
2729
2730void wxGenericGrid::_OnSelectCell(wxGridEvent& ev)
2731{
2732 OnSelectCell(ev.m_row, ev.m_col);
2733}
2734
2735void wxGenericGrid::_OnCreateCell(wxGridEvent& ev)
2736{
2737 ev.m_cell = OnCreateCell();
2738}
2739
031b2a7b 2740void wxGenericGrid::_OnChangeLabels(wxGridEvent& WXUNUSED(ev))
1f481e6a
RD
2741{
2742 OnChangeLabels();
2743}
2744
031b2a7b 2745void wxGenericGrid::_OnChangeSelectionLabel(wxGridEvent& WXUNUSED(ev))
1f481e6a
RD
2746{
2747 OnChangeSelectionLabel();
2748}
2749
2750void wxGenericGrid::_OnCellChange(wxGridEvent& ev)
2751{
2752 OnCellChange(ev.m_row, ev.m_col);
2753}
2754
2755void wxGenericGrid::_OnCellLeftClick(wxGridEvent& ev)
2756{
2757 OnCellLeftClick(ev.m_row, ev.m_col, ev.m_x, ev.m_y, ev.m_control, ev.m_shift);
2758}
2759
2760void wxGenericGrid::_OnCellRightClick(wxGridEvent& ev)
2761{
2762 OnCellRightClick(ev.m_row, ev.m_col, ev.m_x, ev.m_y, ev.m_control, ev.m_shift);
2763}
2764
2765void wxGenericGrid::_OnLabelLeftClick(wxGridEvent& ev)
2766{
2767 OnLabelLeftClick(ev.m_row, ev.m_col, ev.m_x, ev.m_y, ev.m_control, ev.m_shift);
2768}
2769
2770void wxGenericGrid::_OnLabelRightClick(wxGridEvent& ev)
2771{
2772 OnLabelRightClick(ev.m_row, ev.m_col, ev.m_x, ev.m_y, ev.m_control, ev.m_shift);
2773}
2774
bf6c2b35
VZ
2775void *wxGenericGrid::SetCellData(void *data, int row, int col)
2776{
2777 void *rc = NULL;
2778
2779 wxGridCell *cell = GetCell(row, col);
2780 if ( cell )
2781 rc = cell->SetCellData(data);
2782
2783 return rc;
2784}
2785
2786void *wxGenericGrid::GetCellData(int row, int col)
2787{
2788 void *rc = NULL;
2789
2790 wxGridCell *cell = GetCell(row, col);
2791 if ( cell )
2792 rc = cell->GetCellData();
2793
2794 return rc;
2795}
1f481e6a 2796