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