]> git.saurik.com Git - wxWidgets.git/blame - src/generic/gridctrl.cpp
wxDbGrid additions - Added support for ODBC date types
[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)
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
5c737c4c 13 #pragma implementation "gridctrl.h"
d10f4bf9
VZ
14#endif
15
16#include "wx/wxprec.h"
17
18#ifdef __BORLANDC__
19 #pragma hdrstop
20#endif
21
7ac05a91
VZ
22#ifndef WX_PRECOMP
23 #include "wx/textctrl.h"
24 #include "wx/dc.h"
25#endif // WX_PRECOMP
26
d10f4bf9
VZ
27#include "wx/generic/gridctrl.h"
28#include "wx/tokenzr.h"
29
30// ----------------------------------------------------------------------------
31// wxGridCellDateTimeRenderer
32// ----------------------------------------------------------------------------
33
34// Enables a grid cell to display a formated date and or time
35
36wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(wxString outformat, wxString informat)
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
55wxString wxGridCellDateTimeRenderer::GetString(wxGrid& grid, int row, int col)
56{
57 wxGridTableBase *table = grid.GetTable();
58
59 bool hasDatetime = FALSE;
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);
68 hasDatetime = TRUE;
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
117void wxGridCellDateTimeRenderer::SetParameters(const wxString& params){
bc00e715 118 if (!params.IsEmpty())
d10f4bf9
VZ
119 m_oformat=params;
120}
121
122// ----------------------------------------------------------------------------
123// wxGridCellChoiceNumberRenderer
124// ----------------------------------------------------------------------------
125// Renders a number as a textual equivalent.
126// eg data in cell is 0,1,2 ... n the cell could be rendered as "John","Fred"..."Bob"
127
128
129wxGridCellEnumRenderer::wxGridCellEnumRenderer(const wxString& choices)
130{
bc00e715 131 if (!choices.IsEmpty())
d10f4bf9
VZ
132 SetParameters(choices);
133}
134
135wxGridCellRenderer *wxGridCellEnumRenderer::Clone() const
136{
137 wxGridCellEnumRenderer *renderer = new wxGridCellEnumRenderer;
138 renderer->m_choices = m_choices;
139 return renderer;
140}
141
142wxString wxGridCellEnumRenderer::GetString(wxGrid& grid, int row, int col)
143{
144 wxGridTableBase *table = grid.GetTable();
145 wxString text;
146 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
147 {
148 int choiceno = table->GetValueAsLong(row, col);
149 text.Printf(_T("%s"), m_choices[ choiceno ].c_str() );
150 }
151 else
152 {
153 text = table->GetValue(row, col);
154 }
155
156
157 //If we faild to parse string just show what we where given?
158 return text;
159}
160
161void wxGridCellEnumRenderer::Draw(wxGrid& grid,
162 wxGridCellAttr& attr,
163 wxDC& dc,
164 const wxRect& rectCell,
165 int row, int col,
166 bool isSelected)
167{
168 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
169
170 SetTextColoursAndFont(grid, attr, dc, isSelected);
171
172 // draw the text right aligned by default
173 int hAlign, vAlign;
174 attr.GetAlignment(&hAlign, &vAlign);
175 hAlign = wxRIGHT;
176
177 wxRect rect = rectCell;
178 rect.Inflate(-1);
179
180 grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
181}
182
183wxSize wxGridCellEnumRenderer::GetBestSize(wxGrid& grid,
184 wxGridCellAttr& attr,
185 wxDC& dc,
186 int row, int col)
187{
188 return DoGetBestSize(attr, dc, GetString(grid, row, col));
189}
190
191void wxGridCellEnumRenderer::SetParameters(const wxString& params)
192{
193 if ( !params )
194 {
195 // what can we do?
196 return;
197 }
198
199 m_choices.Empty();
200
201 wxStringTokenizer tk(params, _T(','));
202 while ( tk.HasMoreTokens() )
203 {
204 m_choices.Add(tk.GetNextToken());
205 }
206}
207
208// ----------------------------------------------------------------------------
209// wxGridCellEnumEditor
210// ----------------------------------------------------------------------------
211// A cell editor which displays an enum number as a textual equivalent.
212// eg data in cell is 0,1,2 ... n the cell could be displayed as "John","Fred"..."Bob"
213// in the combo choice box
214//
215wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices)
216 : wxGridCellChoiceEditor()
217{
ffd98768
GT
218 m_startint = -1;
219
bc00e715 220 if (!choices.IsEmpty())
d10f4bf9
VZ
221 SetParameters(choices);
222}
223
224wxGridCellEditor *wxGridCellEnumEditor::Clone() const
225{
226 wxGridCellEnumEditor *editor = new wxGridCellEnumEditor();
227 editor->m_startint = m_startint;
228 return editor;
229}
230
231void wxGridCellEnumEditor::BeginEdit(int row, int col, wxGrid* grid)
232{
233 wxASSERT_MSG(m_control,
234 wxT("The wxGridCellEnumEditor must be Created first!"));
235
236 wxGridTableBase *table = grid->GetTable();
237
238 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
239 {
240 m_startint = table->GetValueAsLong(row, col);
241 }
242 else
243 {
244 wxString startValue = table->GetValue(row, col);
245 if (startValue.IsNumber() && !startValue.IsEmpty())
246 {
247 startValue.ToLong(&m_startint);
248 }
249 else
250 {
251 m_startint=-1;
252 }
253 }
254
255 Combo()->SetSelection(m_startint);
256 Combo()->SetInsertionPointEnd();
257 Combo()->SetFocus();
258
259}
260
261bool wxGridCellEnumEditor::EndEdit(int row, int col, wxGrid* grid)
262{
263 int pos = Combo()->GetSelection();
264 bool changed = (pos != m_startint);
265 if (changed)
266 {
267 if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER))
268 grid->GetTable()->SetValueAsLong(row, col, pos);
269 else
161f4f73 270 grid->GetTable()->SetValue(row, col,wxString::Format(wxT("%i"),pos));
d10f4bf9
VZ
271 }
272
273 return changed;
274}
275
276
277void
278wxGridCellAutoWrapStringEditor::Create(wxWindow* parent,
279 wxWindowID id,
280 wxEvtHandler* evtHandler)
281{
282 m_control = new wxTextCtrl(parent, id, wxEmptyString,
283 wxDefaultPosition, wxDefaultSize,
284 wxTE_MULTILINE | wxTE_RICH);
285
286
287 wxGridCellEditor::Create(parent, id, evtHandler);
288}
289
290void
291wxGridCellAutoWrapStringRenderer::Draw(wxGrid& grid,
292 wxGridCellAttr& attr,
293 wxDC& dc,
294 const wxRect& rectCell,
295 int row, int col,
296 bool isSelected) {
297
298
299 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
300
301 // now we only have to draw the text
302 SetTextColoursAndFont(grid, attr, dc, isSelected);
303
304 int horizAlign, vertAlign;
305 attr.GetAlignment(&horizAlign, &vertAlign);
306
307 wxRect rect = rectCell;
308 rect.Inflate(-1);
309
310 grid.DrawTextRectangle(dc, GetTextLines(grid,dc,attr,rect,row,col),
311 rect, horizAlign, vertAlign);
312}
313
314
315wxArrayString
316wxGridCellAutoWrapStringRenderer::GetTextLines(wxGrid& grid,
317 wxDC& dc,
318 wxGridCellAttr& attr,
319 const wxRect& rect,
320 int row, int col)
321{
322 wxString data = grid.GetCellValue(row, col);
323
324 wxArrayString lines;
325 dc.SetFont(attr.GetFont());
326
327 //Taken from wxGrid again!
328 wxCoord x = 0, y = 0, curr_x = 0;
329 wxCoord max_x = rect.GetWidth();
330
331 dc.SetFont(attr.GetFont());
332 wxStringTokenizer tk(data , _T(" \n\t\r"));
333 wxString thisline("");
334
335 while ( tk.HasMoreTokens() )
336 {
337 wxString tok = tk.GetNextToken();
338 //FIXME: this causes us to print an extra unnecesary
339 // space at the end of the line. But it
340 // is invisible , simplifies the size calculation
341 // and ensures tokens are seperated in the display
342 tok += _T(" ");
343
344 dc.GetTextExtent(tok, &x, &y);
345 if ( curr_x + x > max_x) {
346 lines.Add( wxString(thisline) );
347 thisline = tok;
348 curr_x=x;
349 } else {
350 thisline+= tok;
351 curr_x += x;
352 }
353
354 }
355 //Add last line
356 lines.Add( wxString(thisline) );
357
358 return lines;
359}
360
361
362wxSize
363wxGridCellAutoWrapStringRenderer::GetBestSize(wxGrid& grid,
364 wxGridCellAttr& attr,
365 wxDC& dc,
366 int row, int col)
367{
bc00e715 368 wxCoord x,y, height , width = grid.GetColSize(col) -10;
d10f4bf9
VZ
369 int count = 250; //Limit iterations..
370
371 wxRect rect(0,0,width,10);
372
373 // M is a nice large character 'y' gives descender!.
374 dc.GetTextExtent("My", &x, &y);
375
376 do
377 {
378 width+=10;
379 rect.SetWidth(width);
380 height = y *( GetTextLines(grid,dc,attr,rect,row,col).GetCount());
381 count--;
382 // Search for a shape no taller than the golden ratio.
383 } while (count && (width < (height*1.68)) );
384
385
386 return wxSize(width,height);
387}
388