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