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