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 formated 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
);