]> git.saurik.com Git - wxWidgets.git/blob - src/generic/gridctrl.cpp
added wxLocale::IsAvailable() (extended patch 1547191)
[wxWidgets.git] / src / generic / gridctrl.cpp
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 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15     #pragma hdrstop
16 #endif
17
18 #if wxUSE_GRID
19
20 #ifndef WX_PRECOMP
21     #include "wx/textctrl.h"
22     #include "wx/dc.h"
23 #endif // WX_PRECOMP
24
25 #include "wx/generic/gridctrl.h"
26 #include "wx/tokenzr.h"
27
28 // ----------------------------------------------------------------------------
29 // wxGridCellDateTimeRenderer
30 // ----------------------------------------------------------------------------
31
32 #if wxUSE_DATETIME
33
34 // Enables a grid cell to display a formatted date and or time
35
36 wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(const wxString& outformat, const wxString& informat)
37 {
38     m_iformat = informat;
39     m_oformat = outformat;
40     m_tz = wxDateTime::Local;
41     m_dateDef = wxDefaultDateTime;
42 }
43
44 wxGridCellRenderer *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
55 wxString wxGridCellDateTimeRenderer::GetString(const 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
87 void 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
109 wxSize 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
117 void wxGridCellDateTimeRenderer::SetParameters(const wxString& params)
118 {
119     if (!params.empty())
120         m_oformat=params;
121 }
122
123 #endif // wxUSE_DATETIME
124
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
132 wxGridCellEnumRenderer::wxGridCellEnumRenderer(const wxString& choices)
133 {
134     if (!choices.empty())
135         SetParameters(choices);
136 }
137
138 wxGridCellRenderer *wxGridCellEnumRenderer::Clone() const
139 {
140     wxGridCellEnumRenderer *renderer = new wxGridCellEnumRenderer;
141     renderer->m_choices = m_choices;
142     return renderer;
143 }
144
145 wxString wxGridCellEnumRenderer::GetString(const wxGrid& grid, int row, int col)
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
164 void 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
186 wxSize 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
194 void 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
211 #if wxUSE_COMBOBOX
212
213 // ----------------------------------------------------------------------------
214 // wxGridCellEnumEditor
215 // ----------------------------------------------------------------------------
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
221 wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices)
222                      :wxGridCellChoiceEditor()
223 {
224     m_startint = -1;
225
226     if (!choices.empty())
227         SetParameters(choices);
228 }
229
230 wxGridCellEditor *wxGridCellEnumEditor::Clone() const
231 {
232     wxGridCellEnumEditor *editor = new wxGridCellEnumEditor();
233     editor->m_startint = m_startint;
234     return editor;
235 }
236
237 void 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);
251         if (startValue.IsNumber() && !startValue.empty())
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
267 bool 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
276             grid->GetTable()->SetValue(row, col,wxString::Format(wxT("%i"),pos));
277     }
278
279     return changed;
280 }
281
282 #endif // wxUSE_COMBOBOX
283
284 // ----------------------------------------------------------------------------
285 // wxGridCellAutoWrapStringEditor
286 // ----------------------------------------------------------------------------
287
288 void
289 wxGridCellAutoWrapStringEditor::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
301 void
302 wxGridCellAutoWrapStringRenderer::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
326 wxArrayString
327 wxGridCellAutoWrapStringRenderer::GetTextLines(wxGrid& grid,
328                                                wxDC& dc,
329                                                const wxGridCellAttr& attr,
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"));
344     wxString thisline = wxEmptyString;
345
346     while ( tk.HasMoreTokens() )
347     {
348         wxString tok = tk.GetNextToken();
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(" ");
354
355         dc.GetTextExtent(tok, &x, &y);
356         if ( curr_x + x > max_x)
357         {
358             lines.Add( wxString(thisline) );
359             thisline = tok;
360             curr_x=x;
361         }
362         else
363         {
364             thisline+= tok;
365             curr_x += x;
366         }
367     }
368     //Add last line
369     lines.Add( wxString(thisline) );
370
371     return lines;
372 }
373
374
375 wxSize
376 wxGridCellAutoWrapStringRenderer::GetBestSize(wxGrid& grid,
377                                               wxGridCellAttr& attr,
378                                               wxDC& dc,
379                                               int row, int col)
380 {
381     wxCoord x,y, height , width = grid.GetColSize(col) -10;
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!.
387     dc.GetTextExtent(wxT("My"), &x, &y);
388
389     do
390     {
391         width+=10;
392         rect.SetWidth(width);
393         height = y * (wx_truncate_cast(wxCoord, GetTextLines(grid,dc,attr,rect,row,col).GetCount()));
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
402 #endif // wxUSE_GRID
403