]> git.saurik.com Git - wxWidgets.git/blame - src/generic/gridctrl.cpp
Fixed crash caused by A=B?C:D used for returning wxObject derived type.
[wxWidgets.git] / src / generic / gridctrl.cpp
CommitLineData
d10f4bf9
VZ
1///////////////////////////////////////////////////////////////////////////
2// Name: generic/gridctrl.cpp
3// Purpose: wxGrid controls
4// Author: Paul Gammans, Roger Gammans
5// Modified by:
6// Created: 11/04/2001
7// RCS-ID: $Id$
8// Copyright: (c) The Computer Surgery (paul@compsurg.co.uk)
65571936 9// Licence: wxWindows licence
d10f4bf9
VZ
10/////////////////////////////////////////////////////////////////////////////
11
d10f4bf9
VZ
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
f7556ff0 18#if wxUSE_GRID
b53dc7d6 19
7ac05a91
VZ
20#ifndef WX_PRECOMP
21 #include "wx/textctrl.h"
22 #include "wx/dc.h"
23#endif // WX_PRECOMP
24
d10f4bf9
VZ
25#include "wx/generic/gridctrl.h"
26#include "wx/tokenzr.h"
27
28// ----------------------------------------------------------------------------
29// wxGridCellDateTimeRenderer
30// ----------------------------------------------------------------------------
31
e2b87f38
VZ
32#if wxUSE_DATETIME
33
90e572f1 34// Enables a grid cell to display a formatted date and or time
d10f4bf9 35
fbfb8bcc 36wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(const wxString& outformat, const wxString& informat)
d10f4bf9
VZ
37{
38 m_iformat = informat;
39 m_oformat = outformat;
40 m_tz = wxDateTime::Local;
41 m_dateDef = wxDefaultDateTime;
42}
43
44wxGridCellRenderer *wxGridCellDateTimeRenderer::Clone() const
45{
46 wxGridCellDateTimeRenderer *renderer = new wxGridCellDateTimeRenderer;
47 renderer->m_iformat = m_iformat;
48 renderer->m_oformat = m_oformat;
49 renderer->m_dateDef = m_dateDef;
50 renderer->m_tz = m_tz;
51
52 return renderer;
53}
54
fbfb8bcc 55wxString wxGridCellDateTimeRenderer::GetString(const wxGrid& grid, int row, int col)
d10f4bf9
VZ
56{
57 wxGridTableBase *table = grid.GetTable();
58
ca65c044 59 bool hasDatetime = false;
d10f4bf9
VZ
60 wxDateTime val;
61 wxString text;
62 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_DATETIME) )
63 {
64 void * tempval = table->GetValueAsCustom(row, col,wxGRID_VALUE_DATETIME);
65
66 if (tempval){
67 val = *((wxDateTime *)tempval);
ca65c044 68 hasDatetime = true;
d10f4bf9
VZ
69 delete (wxDateTime *)tempval;
70 }
71
72 }
73
74 if (!hasDatetime )
75 {
76 text = table->GetValue(row, col);
77 hasDatetime = (val.ParseFormat( text, m_iformat, m_dateDef ) != (wxChar *)NULL) ;
78 }
79
80 if ( hasDatetime )
81 text = val.Format(m_oformat, m_tz );
82
83 //If we faild to parse string just show what we where given?
84 return text;
85}
86
87void wxGridCellDateTimeRenderer::Draw(wxGrid& grid,
88 wxGridCellAttr& attr,
89 wxDC& dc,
90 const wxRect& rectCell,
91 int row, int col,
92 bool isSelected)
93{
94 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
95
96 SetTextColoursAndFont(grid, attr, dc, isSelected);
97
98 // draw the text right aligned by default
99 int hAlign, vAlign;
100 attr.GetAlignment(&hAlign, &vAlign);
101 hAlign = wxRIGHT;
102
103 wxRect rect = rectCell;
104 rect.Inflate(-1);
105
106 grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
107}
108
109wxSize wxGridCellDateTimeRenderer::GetBestSize(wxGrid& grid,
110 wxGridCellAttr& attr,
111 wxDC& dc,
112 int row, int col)
113{
114 return DoGetBestSize(attr, dc, GetString(grid, row, col));
115}
116
7448de8d
WS
117void wxGridCellDateTimeRenderer::SetParameters(const wxString& params)
118{
119 if (!params.empty())
d10f4bf9
VZ
120 m_oformat=params;
121}
122
e2b87f38
VZ
123#endif // wxUSE_DATETIME
124
d10f4bf9
VZ
125// ----------------------------------------------------------------------------
126// wxGridCellChoiceNumberRenderer
127// ----------------------------------------------------------------------------
128// Renders a number as a textual equivalent.
129// eg data in cell is 0,1,2 ... n the cell could be rendered as "John","Fred"..."Bob"
130
131
132wxGridCellEnumRenderer::wxGridCellEnumRenderer(const wxString& choices)
133{
7448de8d 134 if (!choices.empty())
d10f4bf9
VZ
135 SetParameters(choices);
136}
137
138wxGridCellRenderer *wxGridCellEnumRenderer::Clone() const
139{
140 wxGridCellEnumRenderer *renderer = new wxGridCellEnumRenderer;
141 renderer->m_choices = m_choices;
142 return renderer;
143}
144
fbfb8bcc 145wxString wxGridCellEnumRenderer::GetString(const wxGrid& grid, int row, int col)
d10f4bf9
VZ
146{
147 wxGridTableBase *table = grid.GetTable();
148 wxString text;
149 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
150 {
151 int choiceno = table->GetValueAsLong(row, col);
152 text.Printf(_T("%s"), m_choices[ choiceno ].c_str() );
153 }
154 else
155 {
156 text = table->GetValue(row, col);
157 }
158
159
160 //If we faild to parse string just show what we where given?
161 return text;
162}
163
164void wxGridCellEnumRenderer::Draw(wxGrid& grid,
165 wxGridCellAttr& attr,
166 wxDC& dc,
167 const wxRect& rectCell,
168 int row, int col,
169 bool isSelected)
170{
171 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
172
173 SetTextColoursAndFont(grid, attr, dc, isSelected);
174
175 // draw the text right aligned by default
176 int hAlign, vAlign;
177 attr.GetAlignment(&hAlign, &vAlign);
178 hAlign = wxRIGHT;
179
180 wxRect rect = rectCell;
181 rect.Inflate(-1);
182
183 grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
184}
185
186wxSize wxGridCellEnumRenderer::GetBestSize(wxGrid& grid,
187 wxGridCellAttr& attr,
188 wxDC& dc,
189 int row, int col)
190{
191 return DoGetBestSize(attr, dc, GetString(grid, row, col));
192}
193
194void wxGridCellEnumRenderer::SetParameters(const wxString& params)
195{
196 if ( !params )
197 {
198 // what can we do?
199 return;
200 }
201
202 m_choices.Empty();
203
204 wxStringTokenizer tk(params, _T(','));
205 while ( tk.HasMoreTokens() )
206 {
207 m_choices.Add(tk.GetNextToken());
208 }
209}
210
3a8c693a
VZ
211#if wxUSE_COMBOBOX
212
d10f4bf9
VZ
213// ----------------------------------------------------------------------------
214// wxGridCellEnumEditor
215// ----------------------------------------------------------------------------
3a8c693a
VZ
216
217// A cell editor which displays an enum number as a textual equivalent. eg
218// data in cell is 0,1,2 ... n the cell could be displayed as
219// "John","Fred"..."Bob" in the combo choice box
220
d10f4bf9 221wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices)
7448de8d 222 :wxGridCellChoiceEditor()
d10f4bf9 223{
ffd98768
GT
224 m_startint = -1;
225
7448de8d 226 if (!choices.empty())
d10f4bf9
VZ
227 SetParameters(choices);
228}
229
230wxGridCellEditor *wxGridCellEnumEditor::Clone() const
231{
232 wxGridCellEnumEditor *editor = new wxGridCellEnumEditor();
233 editor->m_startint = m_startint;
234 return editor;
235}
236
237void wxGridCellEnumEditor::BeginEdit(int row, int col, wxGrid* grid)
238{
239 wxASSERT_MSG(m_control,
240 wxT("The wxGridCellEnumEditor must be Created first!"));
241
242 wxGridTableBase *table = grid->GetTable();
243
244 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
245 {
246 m_startint = table->GetValueAsLong(row, col);
247 }
248 else
249 {
250 wxString startValue = table->GetValue(row, col);
7448de8d 251 if (startValue.IsNumber() && !startValue.empty())
d10f4bf9
VZ
252 {
253 startValue.ToLong(&m_startint);
254 }
255 else
256 {
257 m_startint=-1;
258 }
259 }
260
261 Combo()->SetSelection(m_startint);
262 Combo()->SetInsertionPointEnd();
263 Combo()->SetFocus();
264
265}
266
267bool wxGridCellEnumEditor::EndEdit(int row, int col, wxGrid* grid)
268{
269 int pos = Combo()->GetSelection();
270 bool changed = (pos != m_startint);
271 if (changed)
272 {
273 if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER))
274 grid->GetTable()->SetValueAsLong(row, col, pos);
275 else
161f4f73 276 grid->GetTable()->SetValue(row, col,wxString::Format(wxT("%i"),pos));
d10f4bf9
VZ
277 }
278
279 return changed;
280}
281
3a8c693a
VZ
282#endif // wxUSE_COMBOBOX
283
284// ----------------------------------------------------------------------------
285// wxGridCellAutoWrapStringEditor
286// ----------------------------------------------------------------------------
d10f4bf9
VZ
287
288void
289wxGridCellAutoWrapStringEditor::Create(wxWindow* parent,
290 wxWindowID id,
291 wxEvtHandler* evtHandler)
292{
293 m_control = new wxTextCtrl(parent, id, wxEmptyString,
294 wxDefaultPosition, wxDefaultSize,
295 wxTE_MULTILINE | wxTE_RICH);
296
297
298 wxGridCellEditor::Create(parent, id, evtHandler);
299}
300
301void
302wxGridCellAutoWrapStringRenderer::Draw(wxGrid& grid,
303 wxGridCellAttr& attr,
304 wxDC& dc,
305 const wxRect& rectCell,
306 int row, int col,
307 bool isSelected) {
308
309
310 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
311
312 // now we only have to draw the text
313 SetTextColoursAndFont(grid, attr, dc, isSelected);
314
315 int horizAlign, vertAlign;
316 attr.GetAlignment(&horizAlign, &vertAlign);
317
318 wxRect rect = rectCell;
319 rect.Inflate(-1);
320
321 grid.DrawTextRectangle(dc, GetTextLines(grid,dc,attr,rect,row,col),
322 rect, horizAlign, vertAlign);
323}
324
325
326wxArrayString
327wxGridCellAutoWrapStringRenderer::GetTextLines(wxGrid& grid,
328 wxDC& dc,
fbfb8bcc 329 const wxGridCellAttr& attr,
d10f4bf9
VZ
330 const wxRect& rect,
331 int row, int col)
332{
333 wxString data = grid.GetCellValue(row, col);
334
335 wxArrayString lines;
336 dc.SetFont(attr.GetFont());
337
338 //Taken from wxGrid again!
339 wxCoord x = 0, y = 0, curr_x = 0;
340 wxCoord max_x = rect.GetWidth();
341
342 dc.SetFont(attr.GetFont());
343 wxStringTokenizer tk(data , _T(" \n\t\r"));
ca65c044 344 wxString thisline = wxEmptyString;
d10f4bf9
VZ
345
346 while ( tk.HasMoreTokens() )
347 {
348 wxString tok = tk.GetNextToken();
7448de8d
WS
349 //FIXME: this causes us to print an extra unnecesary
350 // space at the end of the line. But it
351 // is invisible , simplifies the size calculation
352 // and ensures tokens are separated in the display
353 tok += _T(" ");
d10f4bf9
VZ
354
355 dc.GetTextExtent(tok, &x, &y);
7448de8d
WS
356 if ( curr_x + x > max_x)
357 {
d10f4bf9 358 lines.Add( wxString(thisline) );
7448de8d
WS
359 thisline = tok;
360 curr_x=x;
361 }
362 else
363 {
d10f4bf9 364 thisline+= tok;
7448de8d
WS
365 curr_x += x;
366 }
d10f4bf9
VZ
367 }
368 //Add last line
369 lines.Add( wxString(thisline) );
370
371 return lines;
372}
373
374
375wxSize
376wxGridCellAutoWrapStringRenderer::GetBestSize(wxGrid& grid,
377 wxGridCellAttr& attr,
378 wxDC& dc,
379 int row, int col)
380{
bc00e715 381 wxCoord x,y, height , width = grid.GetColSize(col) -10;
d10f4bf9
VZ
382 int count = 250; //Limit iterations..
383
384 wxRect rect(0,0,width,10);
385
386 // M is a nice large character 'y' gives descender!.
8dd8f875 387 dc.GetTextExtent(wxT("My"), &x, &y);
d10f4bf9
VZ
388
389 do
390 {
391 width+=10;
392 rect.SetWidth(width);
4a10ea8b 393 height = y * (wx_truncate_cast(wxCoord, GetTextLines(grid,dc,attr,rect,row,col).GetCount()));
d10f4bf9
VZ
394 count--;
395 // Search for a shape no taller than the golden ratio.
396 } while (count && (width < (height*1.68)) );
397
398
399 return wxSize(width,height);
400}
401
3a8c693a
VZ
402#endif // wxUSE_GRID
403