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