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"
20 #include "wx/generic/gridctrl.h"
23 #include "wx/textctrl.h"
25 #include "wx/combobox.h"
28 #include "wx/tokenzr.h"
30 // ----------------------------------------------------------------------------
31 // wxGridCellDateTimeRenderer
32 // ----------------------------------------------------------------------------
36 // Enables a grid cell to display a formatted date and or time
38 wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(const wxString
& outformat
, const wxString
& informat
)
41 m_oformat
= outformat
;
42 m_tz
= wxDateTime::Local
;
43 m_dateDef
= wxDefaultDateTime
;
46 wxGridCellRenderer
*wxGridCellDateTimeRenderer::Clone() const
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
;
57 wxString
wxGridCellDateTimeRenderer::GetString(const wxGrid
& grid
, int row
, int col
)
59 wxGridTableBase
*table
= grid
.GetTable();
61 bool hasDatetime
= false;
64 if ( table
->CanGetValueAs(row
, col
, wxGRID_VALUE_DATETIME
) )
66 void * tempval
= table
->GetValueAsCustom(row
, col
,wxGRID_VALUE_DATETIME
);
70 val
= *((wxDateTime
*)tempval
);
72 delete (wxDateTime
*)tempval
;
79 text
= table
->GetValue(row
, col
);
80 const char * const end
= val
.ParseFormat(text
, m_iformat
, m_dateDef
);
81 hasDatetime
= end
&& !*end
;
85 text
= val
.Format(m_oformat
, m_tz
);
87 // If we failed to parse string just show what we where given?
91 void wxGridCellDateTimeRenderer::Draw(wxGrid
& grid
,
94 const wxRect
& rectCell
,
98 wxGridCellRenderer::Draw(grid
, attr
, dc
, rectCell
, row
, col
, isSelected
);
100 SetTextColoursAndFont(grid
, attr
, dc
, isSelected
);
102 // draw the text right aligned by default
104 attr
.GetAlignment(&hAlign
, &vAlign
);
107 wxRect rect
= rectCell
;
110 grid
.DrawTextRectangle(dc
, GetString(grid
, row
, col
), rect
, hAlign
, vAlign
);
113 wxSize
wxGridCellDateTimeRenderer::GetBestSize(wxGrid
& grid
,
114 wxGridCellAttr
& attr
,
118 return DoGetBestSize(attr
, dc
, GetString(grid
, row
, col
));
121 void wxGridCellDateTimeRenderer::SetParameters(const wxString
& params
)
127 #endif // wxUSE_DATETIME
129 // ----------------------------------------------------------------------------
130 // wxGridCellChoiceNumberRenderer
131 // ----------------------------------------------------------------------------
132 // Renders a number as a textual equivalent.
133 // eg data in cell is 0,1,2 ... n the cell could be rendered as "John","Fred"..."Bob"
136 wxGridCellEnumRenderer::wxGridCellEnumRenderer(const wxString
& choices
)
138 if (!choices
.empty())
139 SetParameters(choices
);
142 wxGridCellRenderer
*wxGridCellEnumRenderer::Clone() const
144 wxGridCellEnumRenderer
*renderer
= new wxGridCellEnumRenderer
;
145 renderer
->m_choices
= m_choices
;
149 wxString
wxGridCellEnumRenderer::GetString(const wxGrid
& grid
, int row
, int col
)
151 wxGridTableBase
*table
= grid
.GetTable();
153 if ( table
->CanGetValueAs(row
, col
, wxGRID_VALUE_NUMBER
) )
155 int choiceno
= table
->GetValueAsLong(row
, col
);
156 text
.Printf(_T("%s"), m_choices
[ choiceno
].c_str() );
160 text
= table
->GetValue(row
, col
);
164 //If we faild to parse string just show what we where given?
168 void wxGridCellEnumRenderer::Draw(wxGrid
& grid
,
169 wxGridCellAttr
& attr
,
171 const wxRect
& rectCell
,
175 wxGridCellRenderer::Draw(grid
, attr
, dc
, rectCell
, row
, col
, isSelected
);
177 SetTextColoursAndFont(grid
, attr
, dc
, isSelected
);
179 // draw the text right aligned by default
181 attr
.GetAlignment(&hAlign
, &vAlign
);
184 wxRect rect
= rectCell
;
187 grid
.DrawTextRectangle(dc
, GetString(grid
, row
, col
), rect
, hAlign
, vAlign
);
190 wxSize
wxGridCellEnumRenderer::GetBestSize(wxGrid
& grid
,
191 wxGridCellAttr
& attr
,
195 return DoGetBestSize(attr
, dc
, GetString(grid
, row
, col
));
198 void wxGridCellEnumRenderer::SetParameters(const wxString
& params
)
208 wxStringTokenizer
tk(params
, _T(','));
209 while ( tk
.HasMoreTokens() )
211 m_choices
.Add(tk
.GetNextToken());
217 // ----------------------------------------------------------------------------
218 // wxGridCellEnumEditor
219 // ----------------------------------------------------------------------------
221 // A cell editor which displays an enum number as a textual equivalent. eg
222 // data in cell is 0,1,2 ... n the cell could be displayed as
223 // "John","Fred"..."Bob" in the combo choice box
225 wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString
& choices
)
226 :wxGridCellChoiceEditor()
230 if (!choices
.empty())
231 SetParameters(choices
);
234 wxGridCellEditor
*wxGridCellEnumEditor::Clone() const
236 wxGridCellEnumEditor
*editor
= new wxGridCellEnumEditor();
237 editor
->m_index
= m_index
;
241 void wxGridCellEnumEditor::BeginEdit(int row
, int col
, wxGrid
* grid
)
243 wxASSERT_MSG(m_control
,
244 wxT("The wxGridCellEnumEditor must be Created first!"));
246 wxGridTableBase
*table
= grid
->GetTable();
248 if ( table
->CanGetValueAs(row
, col
, wxGRID_VALUE_NUMBER
) )
250 m_index
= table
->GetValueAsLong(row
, col
);
254 wxString startValue
= table
->GetValue(row
, col
);
255 if (startValue
.IsNumber() && !startValue
.empty())
257 startValue
.ToLong(&m_index
);
265 Combo()->SetSelection(m_index
);
266 Combo()->SetInsertionPointEnd();
271 bool wxGridCellEnumEditor::EndEdit(const wxString
& WXUNUSED(oldval
),
274 long idx
= Combo()->GetSelection();
275 if ( idx
== m_index
)
281 newval
->Printf("%ld", m_index
);
286 void wxGridCellEnumEditor::ApplyEdit(int row
, int col
, wxGrid
* grid
)
288 wxGridTableBase
* const table
= grid
->GetTable();
289 if ( table
->CanSetValueAs(row
, col
, wxGRID_VALUE_NUMBER
) )
290 table
->SetValueAsLong(row
, col
, m_index
);
292 table
->SetValue(row
, col
, wxString::Format("%ld", m_index
));
295 #endif // wxUSE_COMBOBOX
297 // ----------------------------------------------------------------------------
298 // wxGridCellAutoWrapStringEditor
299 // ----------------------------------------------------------------------------
302 wxGridCellAutoWrapStringEditor::Create(wxWindow
* parent
,
304 wxEvtHandler
* evtHandler
)
306 wxGridCellTextEditor::DoCreate(parent
, id
, evtHandler
,
307 wxTE_MULTILINE
| wxTE_RICH
);
311 wxGridCellAutoWrapStringRenderer::Draw(wxGrid
& grid
,
312 wxGridCellAttr
& attr
,
314 const wxRect
& rectCell
,
319 wxGridCellRenderer::Draw(grid
, attr
, dc
, rectCell
, row
, col
, isSelected
);
321 // now we only have to draw the text
322 SetTextColoursAndFont(grid
, attr
, dc
, isSelected
);
324 int horizAlign
, vertAlign
;
325 attr
.GetAlignment(&horizAlign
, &vertAlign
);
327 wxRect rect
= rectCell
;
330 grid
.DrawTextRectangle(dc
, GetTextLines(grid
,dc
,attr
,rect
,row
,col
),
331 rect
, horizAlign
, vertAlign
);
336 wxGridCellAutoWrapStringRenderer::GetTextLines(wxGrid
& grid
,
338 const wxGridCellAttr
& attr
,
342 wxString data
= grid
.GetCellValue(row
, col
);
345 dc
.SetFont(attr
.GetFont());
347 //Taken from wxGrid again!
348 wxCoord x
= 0, y
= 0, curr_x
= 0;
349 wxCoord max_x
= rect
.GetWidth();
351 dc
.SetFont(attr
.GetFont());
352 wxStringTokenizer
tk(data
, _T(" \n\t\r"));
353 wxString thisline
= wxEmptyString
;
355 while ( tk
.HasMoreTokens() )
357 wxString tok
= tk
.GetNextToken();
358 //FIXME: this causes us to print an extra unnecesary
359 // space at the end of the line. But it
360 // is invisible , simplifies the size calculation
361 // and ensures tokens are separated in the display
364 dc
.GetTextExtent(tok
, &x
, &y
);
365 if ( curr_x
+ x
> max_x
)
367 lines
.Add( wxString(thisline
) );
378 lines
.Add( wxString(thisline
) );
385 wxGridCellAutoWrapStringRenderer::GetBestSize(wxGrid
& grid
,
386 wxGridCellAttr
& attr
,
390 wxCoord x
,y
, height
, width
= grid
.GetColSize(col
) -20;
391 // for width, subtract 20 because ColSize includes a magin of 10 pixels
392 // that we do not want here and because we always start with an increment
393 // by 10 in the loop below.
394 int count
= 250; //Limit iterations..
396 wxRect
rect(0,0,width
,10);
398 // M is a nice large character 'y' gives descender!.
399 dc
.GetTextExtent(wxT("My"), &x
, &y
);
404 rect
.SetWidth(width
);
405 height
= y
* (wx_truncate_cast(wxCoord
, GetTextLines(grid
,dc
,attr
,rect
,row
,col
).GetCount()));
407 // Search for a shape no taller than the golden ratio.
408 } while (count
&& (width
< (height
*1.68)) );
411 return wxSize(width
,height
);