1 ///////////////////////////////////////////////////////////////////////////
2 // Name: generic/gridctrl.cpp
3 // Purpose: wxGrid controls
4 // Author: Paul Gammans, Roger Gammans
8 // Copyright: (c) The Computer Surgery (paul@compsurg.co.uk)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
21 #include "wx/textctrl.h"
25 #include "wx/generic/gridctrl.h"
26 #include "wx/tokenzr.h"
28 // ----------------------------------------------------------------------------
29 // wxGridCellDateTimeRenderer
30 // ----------------------------------------------------------------------------
34 // Enables a grid cell to display a formatted date and or time
36 wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(const wxString& outformat, const wxString& informat)
39 m_oformat = outformat;
40 m_tz = wxDateTime::Local;
41 m_dateDef = wxDefaultDateTime;
44 wxGridCellRenderer *wxGridCellDateTimeRenderer::Clone() const
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;
55 wxString wxGridCellDateTimeRenderer::GetString(const wxGrid& grid, int row, int col)
57 wxGridTableBase *table = grid.GetTable();
59 bool hasDatetime = false;
62 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_DATETIME) )
64 void * tempval = table->GetValueAsCustom(row, col,wxGRID_VALUE_DATETIME);
67 val = *((wxDateTime *)tempval);
69 delete (wxDateTime *)tempval;
76 text = table->GetValue(row, col);
77 hasDatetime = (val.ParseFormat( text, m_iformat, m_dateDef ) != (wxChar *)NULL) ;
81 text = val.Format(m_oformat, m_tz );
83 //If we faild to parse string just show what we where given?
87 void wxGridCellDateTimeRenderer::Draw(wxGrid& grid,
90 const wxRect& rectCell,
94 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
96 SetTextColoursAndFont(grid, attr, dc, isSelected);
98 // draw the text right aligned by default
100 attr.GetAlignment(&hAlign, &vAlign);
103 wxRect rect = rectCell;
106 grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
109 wxSize wxGridCellDateTimeRenderer::GetBestSize(wxGrid& grid,
110 wxGridCellAttr& attr,
114 return DoGetBestSize(attr, dc, GetString(grid, row, col));
117 void wxGridCellDateTimeRenderer::SetParameters(const wxString& params)
123 #endif // wxUSE_DATETIME
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"
132 wxGridCellEnumRenderer::wxGridCellEnumRenderer(const wxString& choices)
134 if (!choices.empty())
135 SetParameters(choices);
138 wxGridCellRenderer *wxGridCellEnumRenderer::Clone() const
140 wxGridCellEnumRenderer *renderer = new wxGridCellEnumRenderer;
141 renderer->m_choices = m_choices;
145 wxString wxGridCellEnumRenderer::GetString(const wxGrid& grid, int row, int col)
147 wxGridTableBase *table = grid.GetTable();
149 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
151 int choiceno = table->GetValueAsLong(row, col);
152 text.Printf(_T("%s"), m_choices[ choiceno ].c_str() );
156 text = table->GetValue(row, col);
160 //If we faild to parse string just show what we where given?
164 void wxGridCellEnumRenderer::Draw(wxGrid& grid,
165 wxGridCellAttr& attr,
167 const wxRect& rectCell,
171 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
173 SetTextColoursAndFont(grid, attr, dc, isSelected);
175 // draw the text right aligned by default
177 attr.GetAlignment(&hAlign, &vAlign);
180 wxRect rect = rectCell;
183 grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
186 wxSize wxGridCellEnumRenderer::GetBestSize(wxGrid& grid,
187 wxGridCellAttr& attr,
191 return DoGetBestSize(attr, dc, GetString(grid, row, col));
194 void wxGridCellEnumRenderer::SetParameters(const wxString& params)
204 wxStringTokenizer tk(params, _T(','));
205 while ( tk.HasMoreTokens() )
207 m_choices.Add(tk.GetNextToken());
213 // ----------------------------------------------------------------------------
214 // wxGridCellEnumEditor
215 // ----------------------------------------------------------------------------
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
221 wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices)
222 :wxGridCellChoiceEditor()
226 if (!choices.empty())
227 SetParameters(choices);
230 wxGridCellEditor *wxGridCellEnumEditor::Clone() const
232 wxGridCellEnumEditor *editor = new wxGridCellEnumEditor();
233 editor->m_startint = m_startint;
237 void wxGridCellEnumEditor::BeginEdit(int row, int col, wxGrid* grid)
239 wxASSERT_MSG(m_control,
240 wxT("The wxGridCellEnumEditor must be Created first!"));
242 wxGridTableBase *table = grid->GetTable();
244 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
246 m_startint = table->GetValueAsLong(row, col);
250 wxString startValue = table->GetValue(row, col);
251 if (startValue.IsNumber() && !startValue.empty())
253 startValue.ToLong(&m_startint);
261 Combo()->SetSelection(m_startint);
262 Combo()->SetInsertionPointEnd();
267 bool wxGridCellEnumEditor::EndEdit(int row, int col, wxGrid* grid)
269 int pos = Combo()->GetSelection();
270 bool changed = (pos != m_startint);
273 if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER))
274 grid->GetTable()->SetValueAsLong(row, col, pos);
276 grid->GetTable()->SetValue(row, col,wxString::Format(wxT("%i"),pos));
282 #endif // wxUSE_COMBOBOX
284 // ----------------------------------------------------------------------------
285 // wxGridCellAutoWrapStringEditor
286 // ----------------------------------------------------------------------------
289 wxGridCellAutoWrapStringEditor::Create(wxWindow* parent,
291 wxEvtHandler* evtHandler)
293 m_control = new wxTextCtrl(parent, id, wxEmptyString,
294 wxDefaultPosition, wxDefaultSize,
295 wxTE_MULTILINE | wxTE_RICH);
298 wxGridCellEditor::Create(parent, id, evtHandler);
302 wxGridCellAutoWrapStringRenderer::Draw(wxGrid& grid,
303 wxGridCellAttr& attr,
305 const wxRect& rectCell,
310 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
312 // now we only have to draw the text
313 SetTextColoursAndFont(grid, attr, dc, isSelected);
315 int horizAlign, vertAlign;
316 attr.GetAlignment(&horizAlign, &vertAlign);
318 wxRect rect = rectCell;
321 grid.DrawTextRectangle(dc, GetTextLines(grid,dc,attr,rect,row,col),
322 rect, horizAlign, vertAlign);
327 wxGridCellAutoWrapStringRenderer::GetTextLines(wxGrid& grid,
329 const wxGridCellAttr& attr,
333 wxString data = grid.GetCellValue(row, col);
336 dc.SetFont(attr.GetFont());
338 //Taken from wxGrid again!
339 wxCoord x = 0, y = 0, curr_x = 0;
340 wxCoord max_x = rect.GetWidth();
342 dc.SetFont(attr.GetFont());
343 wxStringTokenizer tk(data , _T(" \n\t\r"));
344 wxString thisline = wxEmptyString;
346 while ( tk.HasMoreTokens() )
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
355 dc.GetTextExtent(tok, &x, &y);
356 if ( curr_x + x > max_x)
358 lines.Add( wxString(thisline) );
369 lines.Add( wxString(thisline) );
376 wxGridCellAutoWrapStringRenderer::GetBestSize(wxGrid& grid,
377 wxGridCellAttr& attr,
381 wxCoord x,y, height , width = grid.GetColSize(col) -10;
382 int count = 250; //Limit iterations..
384 wxRect rect(0,0,width,10);
386 // M is a nice large character 'y' gives descender!.
387 dc.GetTextExtent(wxT("My"), &x, &y);
392 rect.SetWidth(width);
393 height = y * (wx_truncate_cast(wxCoord, GetTextLines(grid,dc,attr,rect,row,col).GetCount()));
395 // Search for a shape no taller than the golden ratio.
396 } while (count && (width < (height*1.68)) );
399 return wxSize(width,height);