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