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 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "gridctrl.h"
16 #include "wx/wxprec.h"
23 #if wxUSE_GRID || wxUSE_NEW_GRID
26 #include "wx/textctrl.h"
30 #include "wx/generic/gridctrl.h"
31 #include "wx/tokenzr.h"
33 // ----------------------------------------------------------------------------
34 // wxGridCellDateTimeRenderer
35 // ----------------------------------------------------------------------------
37 // Enables a grid cell to display a formated date and or time
39 wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(wxString outformat
, wxString informat
)
42 m_oformat
= outformat
;
43 m_tz
= wxDateTime::Local
;
44 m_dateDef
= wxDefaultDateTime
;
47 wxGridCellRenderer
*wxGridCellDateTimeRenderer::Clone() const
49 wxGridCellDateTimeRenderer
*renderer
= new wxGridCellDateTimeRenderer
;
50 renderer
->m_iformat
= m_iformat
;
51 renderer
->m_oformat
= m_oformat
;
52 renderer
->m_dateDef
= m_dateDef
;
53 renderer
->m_tz
= m_tz
;
58 wxString
wxGridCellDateTimeRenderer::GetString(wxGrid
& grid
, int row
, int col
)
60 wxGridTableBase
*table
= grid
.GetTable();
62 bool hasDatetime
= FALSE
;
65 if ( table
->CanGetValueAs(row
, col
, wxGRID_VALUE_DATETIME
) )
67 void * tempval
= table
->GetValueAsCustom(row
, col
,wxGRID_VALUE_DATETIME
);
70 val
= *((wxDateTime
*)tempval
);
72 delete (wxDateTime
*)tempval
;
79 text
= table
->GetValue(row
, col
);
80 hasDatetime
= (val
.ParseFormat( text
, m_iformat
, m_dateDef
) != (wxChar
*)NULL
) ;
84 text
= val
.Format(m_oformat
, m_tz
);
86 //If we faild to parse string just show what we where given?
90 void wxGridCellDateTimeRenderer::Draw(wxGrid
& grid
,
93 const wxRect
& rectCell
,
97 wxGridCellRenderer::Draw(grid
, attr
, dc
, rectCell
, row
, col
, isSelected
);
99 SetTextColoursAndFont(grid
, attr
, dc
, isSelected
);
101 // draw the text right aligned by default
103 attr
.GetAlignment(&hAlign
, &vAlign
);
106 wxRect rect
= rectCell
;
109 grid
.DrawTextRectangle(dc
, GetString(grid
, row
, col
), rect
, hAlign
, vAlign
);
112 wxSize
wxGridCellDateTimeRenderer::GetBestSize(wxGrid
& grid
,
113 wxGridCellAttr
& attr
,
117 return DoGetBestSize(attr
, dc
, GetString(grid
, row
, col
));
120 void wxGridCellDateTimeRenderer::SetParameters(const wxString
& params
){
121 if (!params
.IsEmpty())
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
.IsEmpty())
135 SetParameters(choices
);
138 wxGridCellRenderer
*wxGridCellEnumRenderer::Clone() const
140 wxGridCellEnumRenderer
*renderer
= new wxGridCellEnumRenderer
;
141 renderer
->m_choices
= m_choices
;
145 wxString
wxGridCellEnumRenderer::GetString(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());
211 // ----------------------------------------------------------------------------
212 // wxGridCellEnumEditor
213 // ----------------------------------------------------------------------------
214 // A cell editor which displays an enum number as a textual equivalent.
215 // eg data in cell is 0,1,2 ... n the cell could be displayed as "John","Fred"..."Bob"
216 // in the combo choice box
218 wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString
& choices
)
219 : wxGridCellChoiceEditor()
223 if (!choices
.IsEmpty())
224 SetParameters(choices
);
227 wxGridCellEditor
*wxGridCellEnumEditor::Clone() const
229 wxGridCellEnumEditor
*editor
= new wxGridCellEnumEditor();
230 editor
->m_startint
= m_startint
;
234 void wxGridCellEnumEditor::BeginEdit(int row
, int col
, wxGrid
* grid
)
236 wxASSERT_MSG(m_control
,
237 wxT("The wxGridCellEnumEditor must be Created first!"));
239 wxGridTableBase
*table
= grid
->GetTable();
241 if ( table
->CanGetValueAs(row
, col
, wxGRID_VALUE_NUMBER
) )
243 m_startint
= table
->GetValueAsLong(row
, col
);
247 wxString startValue
= table
->GetValue(row
, col
);
248 if (startValue
.IsNumber() && !startValue
.IsEmpty())
250 startValue
.ToLong(&m_startint
);
258 Combo()->SetSelection(m_startint
);
259 Combo()->SetInsertionPointEnd();
264 bool wxGridCellEnumEditor::EndEdit(int row
, int col
, wxGrid
* grid
)
266 int pos
= Combo()->GetSelection();
267 bool changed
= (pos
!= m_startint
);
270 if (grid
->GetTable()->CanSetValueAs(row
, col
, wxGRID_VALUE_NUMBER
))
271 grid
->GetTable()->SetValueAsLong(row
, col
, pos
);
273 grid
->GetTable()->SetValue(row
, col
,wxString::Format(wxT("%i"),pos
));
281 wxGridCellAutoWrapStringEditor::Create(wxWindow
* parent
,
283 wxEvtHandler
* evtHandler
)
285 m_control
= new wxTextCtrl(parent
, id
, wxEmptyString
,
286 wxDefaultPosition
, wxDefaultSize
,
287 wxTE_MULTILINE
| wxTE_RICH
);
290 wxGridCellEditor::Create(parent
, id
, evtHandler
);
294 wxGridCellAutoWrapStringRenderer::Draw(wxGrid
& grid
,
295 wxGridCellAttr
& attr
,
297 const wxRect
& rectCell
,
302 wxGridCellRenderer::Draw(grid
, attr
, dc
, rectCell
, row
, col
, isSelected
);
304 // now we only have to draw the text
305 SetTextColoursAndFont(grid
, attr
, dc
, isSelected
);
307 int horizAlign
, vertAlign
;
308 attr
.GetAlignment(&horizAlign
, &vertAlign
);
310 wxRect rect
= rectCell
;
313 grid
.DrawTextRectangle(dc
, GetTextLines(grid
,dc
,attr
,rect
,row
,col
),
314 rect
, horizAlign
, vertAlign
);
319 wxGridCellAutoWrapStringRenderer::GetTextLines(wxGrid
& grid
,
321 wxGridCellAttr
& attr
,
325 wxString data
= grid
.GetCellValue(row
, col
);
328 dc
.SetFont(attr
.GetFont());
330 //Taken from wxGrid again!
331 wxCoord x
= 0, y
= 0, curr_x
= 0;
332 wxCoord max_x
= rect
.GetWidth();
334 dc
.SetFont(attr
.GetFont());
335 wxStringTokenizer
tk(data
, _T(" \n\t\r"));
336 wxString
thisline("");
338 while ( tk
.HasMoreTokens() )
340 wxString tok
= tk
.GetNextToken();
341 //FIXME: this causes us to print an extra unnecesary
342 // space at the end of the line. But it
343 // is invisible , simplifies the size calculation
344 // and ensures tokens are seperated in the display
347 dc
.GetTextExtent(tok
, &x
, &y
);
348 if ( curr_x
+ x
> max_x
) {
349 lines
.Add( wxString(thisline
) );
359 lines
.Add( wxString(thisline
) );
366 wxGridCellAutoWrapStringRenderer::GetBestSize(wxGrid
& grid
,
367 wxGridCellAttr
& attr
,
371 wxCoord x
,y
, height
, width
= grid
.GetColSize(col
) -10;
372 int count
= 250; //Limit iterations..
374 wxRect
rect(0,0,width
,10);
376 // M is a nice large character 'y' gives descender!.
377 dc
.GetTextExtent("My", &x
, &y
);
382 rect
.SetWidth(width
);
383 height
= y
*( GetTextLines(grid
,dc
,attr
,rect
,row
,col
).GetCount());
385 // Search for a shape no taller than the golden ratio.
386 } while (count
&& (width
< (height
*1.68)) );
389 return wxSize(width
,height
);