class WXDLLEXPORT wxGridRowLabelWindow;
class WXDLLEXPORT wxGridTableBase;
class WXDLLEXPORT wxGridWindow;
+class WXDLLEXPORT wxGridTypeRegistry;
class WXDLLEXPORT wxCheckBox;
class WXDLLEXPORT wxTextCtrl;
const wxColour& GetBackgroundColour() const;
const wxFont& GetFont() const;
void GetAlignment(int *hAlign, int *vAlign) const;
- wxGridCellRenderer *GetRenderer() const;
- wxGridCellEditor *GetEditor() const;
+ wxGridCellRenderer *GetRenderer(wxGridCellRenderer* def) const;
+ wxGridCellEditor *GetEditor(wxGridCellEditor* def) const;
bool IsReadOnly() const { return m_isReadOnly; }
//
virtual long GetNumberRows() = 0;
virtual long GetNumberCols() = 0;
- virtual wxString GetValue( int row, int col ) = 0;
- virtual void SetValue( int row, int col, const wxString& s ) = 0;
virtual bool IsEmptyCell( int row, int col ) = 0;
+ virtual wxString GetValue( int row, int col ) = 0;
+ virtual void SetValue( int row, int col, const wxString& value ) = 0;
+
+ // Data type determination and value access
+ virtual wxString GetTypeName( int row, int col );
+ virtual bool CanGetValueAs( int row, int col, const wxString& typeName );
+ virtual bool CanSetValueAs( int row, int col, const wxString& typeName );
+
+ virtual long GetValueAsLong( int row, int col );
+ virtual double GetValueAsDouble( int row, int col );
+ virtual bool GetValueAsBool( int row, int col );
+
+ virtual void SetValueAsLong( int row, int col, long value );
+ virtual void SetValueAsDouble( int row, int col, double value );
+ virtual void SetValueAsBool( int row, int col, bool value );
+
+ // For user defined types
+ virtual void* GetValueAsCustom( int row, int col, const wxString& typeName );
+ virtual void SetValueAsCustom( int row, int col, const wxString& typeName, void* value );
+
// Overriding these is optional
//
// get the currently used attr provider (may be NULL)
wxGridCellAttrProvider *GetAttrProvider() const { return m_attrProvider; }
+ // Does this table allow attributes? Default implementation creates
+ // a wxGridCellAttrProvider if necessary.
+ virtual bool CanHaveAttributes();
+
+
// change row/col number in attribute if needed
- void UpdateAttrRows( size_t pos, int numRows );
- void UpdateAttrCols( size_t pos, int numCols );
+ virtual void UpdateAttrRows( size_t pos, int numRows );
+ virtual void UpdateAttrCols( size_t pos, int numCols );
// by default forwarded to wxGridCellAttrProvider if any. May be
- // overridden to handle attributes directly in this class.
+ // overridden to handle attributes directly in the table.
virtual wxGridCellAttr *GetAttr( int row, int col );
// these functions take ownership of the pointer
wxGridCellRenderer* GetCellRenderer(int row, int col);
// takes ownership of the pointer
- void SetDefaultEditor(wxGridCellEditor *editor);
+// void SetDefaultEditor(wxGridCellEditor *editor);
void SetCellEditor(int row, int col, wxGridCellEditor *editor);
- wxGridCellEditor *GetDefaultEditor() const;
+// wxGridCellEditor *GetDefaultEditor() const;
wxGridCellEditor* GetCellEditor(int row, int col);
+
// ------ cell value accessors
//
wxString GetCellValue( int row, int col )
void SetSelectionForeground(const wxColour& c) { m_selectionForeground = c; }
+ // Methods for a registry for mapping data types to Renderers/Editors
+ void RegisterDataType(const wxString& typeName,
+ wxGridCellRenderer* renderer,
+ wxGridCellEditor* editor);
+ wxGridCellEditor* GetDefaultEditorForCell(int row, int col);
+ wxGridCellRenderer* GetDefaultRendererForCell(int row, int col);
+ wxGridCellEditor* GetDefaultEditorForType(const wxString& typeName);
+ wxGridCellRenderer* GetDefaultRendererForType(const wxString& typeName);
+
+
// ------ For compatibility with previous wxGrid only...
//
bool m_inOnKeyDown;
int m_batchCount;
+
+ wxGridTypeRegistry* m_typeRegistry;
+
enum CursorMode
{
WXGRID_CURSOR_SELECT_CELL,
};
+
// ----------------------------------------------------------------------------
// Grid event class and event types
// ----------------------------------------------------------------------------
m_colAttrs;
};
+
+// ----------------------------------------------------------------------------
+// data structures used for the data type registry
+// ----------------------------------------------------------------------------
+
+struct wxGridDataTypeInfo {
+ wxGridDataTypeInfo(const wxString& typeName,
+ wxGridCellRenderer* renderer,
+ wxGridCellEditor* editor)
+ : m_typeName(typeName), m_renderer(renderer), m_editor(editor)
+ { }
+
+ ~wxGridDataTypeInfo() { delete m_renderer; delete m_editor; }
+
+ wxString m_typeName;
+ wxGridCellRenderer* m_renderer;
+ wxGridCellEditor* m_editor;
+};
+
+
+WX_DEFINE_ARRAY(wxGridDataTypeInfo*, wxGridDataTypeInfoArray);
+
+
+class WXDLLEXPORT wxGridTypeRegistry {
+public:
+ ~wxGridTypeRegistry();
+ void RegisterDataType(const wxString& typeName,
+ wxGridCellRenderer* renderer,
+ wxGridCellEditor* editor);
+ int FindDataType(const wxString& typeName);
+ wxGridCellRenderer* GetRenderer(int index);
+ wxGridCellEditor* GetEditor(int index);
+
+private:
+ wxGridDataTypeInfoArray m_typeinfo;
+};
+
+
+
+
// ----------------------------------------------------------------------------
// conditional compilation
// ----------------------------------------------------------------------------
// set the colours/fonts if we have any
if ( attr )
{
- if ( attr->HasTextColour() )
- {
- m_colFgOld = m_control->GetForegroundColour();
- m_control->SetForegroundColour(attr->GetTextColour());
- }
+ m_colFgOld = m_control->GetForegroundColour();
+ m_control->SetForegroundColour(attr->GetTextColour());
- if ( attr->HasBackgroundColour() )
- {
- m_colBgOld = m_control->GetBackgroundColour();
- m_control->SetBackgroundColour(attr->GetBackgroundColour());
- }
+ m_colBgOld = m_control->GetBackgroundColour();
+ m_control->SetBackgroundColour(attr->GetBackgroundColour());
- if ( attr->HasFont() )
- {
- m_fontOld = m_control->GetFont();
- m_control->SetFont(attr->GetFont());
- }
+ m_fontOld = m_control->GetFont();
+ m_control->SetFont(attr->GetFont());
// can't do anything more in the base class version, the other
// attributes may only be used by the derived classes
wxASSERT_MSG(m_control,
wxT("The wxGridCellEditor must be Created first!"));
- m_startValue = !!grid->GetTable()->GetValue(row, col); // FIXME-DATA
+ if (grid->GetTable()->CanGetValueAs(row, col, wxT("bool")))
+ m_startValue = grid->GetTable()->GetValueAsBool(row, col);
+ else
+ m_startValue = !!grid->GetTable()->GetValue(row, col);
CBox()->SetValue(m_startValue);
CBox()->SetFocus();
}
if ( changed )
{
- // FIXME-DATA
- grid->GetTable()->SetValue(row, col, value ? _T("1") : wxEmptyString);
+ if (grid->GetTable()->CanGetValueAs(row, col, wxT("bool")))
+ grid->GetTable()->SetValueAsBool(row, col, value);
+ else
+ grid->GetTable()->SetValue(row, col, value ? _T("1") : wxEmptyString);
}
return changed;
rectMark.Inflate(-margin);
- if ( !!grid.GetTable()->GetValue(row, col) ) // FIXME-DATA
+ bool value;
+ if (grid.GetTable()->CanGetValueAs(row, col, wxT("bool")))
+ value = grid.GetTable()->GetValueAsBool(row, col);
+ else
+ value = !!grid.GetTable()->GetValue(row, col);
+
+ if ( value )
{
dc.SetTextForeground(attr.GetTextColour());
dc.DrawCheckMark(rectMark);
}
-wxGridCellRenderer* wxGridCellAttr::GetRenderer() const
+// GetRenderer and GetEditor use a slightly different decision path about
+// which to use. If a non-default attr object has one then it is used,
+// otherwise the default editor or renderer passed in is used. It should be
+// the default for the data type of the cell. If it is NULL (because the
+// table has a type that the grid does not have in its registry,) then the
+// grid's default editor or renderer is used.
+
+wxGridCellRenderer* wxGridCellAttr::GetRenderer(wxGridCellRenderer* def) const
{
- if (HasRenderer())
+ if ((m_defGridAttr != this || def == NULL) && HasRenderer())
return m_renderer;
+ else if (def)
+ return def;
else if (m_defGridAttr != this)
- return m_defGridAttr->GetRenderer();
+ return m_defGridAttr->GetRenderer(NULL);
else
{
wxFAIL_MSG(wxT("Missing default cell attribute"));
}
}
-wxGridCellEditor* wxGridCellAttr::GetEditor() const
+wxGridCellEditor* wxGridCellAttr::GetEditor(wxGridCellEditor* def) const
{
- if (HasEditor())
+ if ((m_defGridAttr != this || def == NULL) && HasEditor())
return m_editor;
+ else if (def)
+ return def;
else if (m_defGridAttr != this)
- return m_defGridAttr->GetEditor();
+ return m_defGridAttr->GetEditor(NULL);
else
{
wxFAIL_MSG(wxT("Missing default cell attribute"));
}
}
+// ----------------------------------------------------------------------------
+// wxGridTypeRegistry
+// ----------------------------------------------------------------------------
+
+wxGridTypeRegistry::~wxGridTypeRegistry()
+{
+ for (size_t i=0; i<m_typeinfo.Count(); i++)
+ delete m_typeinfo[i];
+}
+
+
+void wxGridTypeRegistry::RegisterDataType(const wxString& typeName,
+ wxGridCellRenderer* renderer,
+ wxGridCellEditor* editor)
+{
+ int loc;
+ wxGridDataTypeInfo* info = new wxGridDataTypeInfo(typeName, renderer, editor);
+
+ // is it already registered?
+ if ((loc = FindDataType(typeName)) != -1) {
+ delete m_typeinfo[loc];
+ m_typeinfo[loc] = info;
+ }
+ else {
+ m_typeinfo.Add(info);
+ }
+}
+
+int wxGridTypeRegistry::FindDataType(const wxString& typeName)
+{
+ int found = -1;
+
+ for (size_t i=0; i<m_typeinfo.Count(); i++) {
+ if (typeName == m_typeinfo[i]->m_typeName) {
+ found = i;
+ break;
+ }
+ }
+
+ return found;
+}
+
+wxGridCellRenderer* wxGridTypeRegistry::GetRenderer(int index)
+{
+ wxGridCellRenderer* renderer = m_typeinfo[index]->m_renderer;
+ return renderer;
+}
+
+wxGridCellEditor* wxGridTypeRegistry::GetEditor(int index)
+{
+ wxGridCellEditor* editor = m_typeinfo[index]->m_editor;
+ return editor;
+}
+
// ----------------------------------------------------------------------------
// wxGridTableBase
// ----------------------------------------------------------------------------
-//////////////////////////////////////////////////////////////////////
-//
-// Abstract base class for grid data (the model)
-//
IMPLEMENT_ABSTRACT_CLASS( wxGridTableBase, wxObject )
m_attrProvider = attrProvider;
}
+bool wxGridTableBase::CanHaveAttributes()
+{
+ if ( ! GetAttrProvider() )
+ {
+ // use the default attr provider by default
+ SetAttrProvider(new wxGridCellAttrProvider);
+ }
+ return TRUE;
+}
+
wxGridCellAttr *wxGridTableBase::GetAttr(int row, int col)
{
if ( m_attrProvider )
wxString wxGridTableBase::GetRowLabelValue( int row )
{
wxString s;
- s << row;
+ s << row + 1; // RD: Starting the rows at zero confuses users, no matter
+ // how much it makes sense to us geeks.
return s;
}
}
+wxString wxGridTableBase::GetTypeName( int WXUNUSED(row), int WXUNUSED(col) )
+{
+ return wxT("string");
+}
+
+bool wxGridTableBase::CanGetValueAs( int WXUNUSED(row), int WXUNUSED(col),
+ const wxString& typeName )
+{
+ return typeName == wxT("string");
+}
+
+bool wxGridTableBase::CanSetValueAs( int row, int col, const wxString& typeName )
+{
+ return CanGetValueAs(row, col, typeName);
+}
+
+long wxGridTableBase::GetValueAsLong( int WXUNUSED(row), int WXUNUSED(col) )
+{
+ return 0;
+}
+
+double wxGridTableBase::GetValueAsDouble( int WXUNUSED(row), int WXUNUSED(col) )
+{
+ return 0.0;
+}
+
+bool wxGridTableBase::GetValueAsBool( int WXUNUSED(row), int WXUNUSED(col) )
+{
+ return FALSE;
+}
+
+void wxGridTableBase::SetValueAsLong( int WXUNUSED(row), int WXUNUSED(col),
+ long WXUNUSED(value) )
+{
+}
+
+void wxGridTableBase::SetValueAsDouble( int WXUNUSED(row), int WXUNUSED(col),
+ double WXUNUSED(value) )
+{
+}
+
+void wxGridTableBase::SetValueAsBool( int WXUNUSED(row), int WXUNUSED(col),
+ bool WXUNUSED(value) )
+{
+}
+
+
+void* wxGridTableBase::GetValueAsCustom( int WXUNUSED(row), int WXUNUSED(col),
+ const wxString& WXUNUSED(typeName) )
+{
+ return NULL;
+}
+
+void wxGridTableBase::SetValueAsCustom( int WXUNUSED(row), int WXUNUSED(col),
+ const wxString& WXUNUSED(typeName),
+ void* WXUNUSED(value) )
+{
+}
+
//////////////////////////////////////////////////////////////////////
//
return m_data[row][col];
}
-void wxGridStringTable::SetValue( int row, int col, const wxString& s )
+void wxGridStringTable::SetValue( int row, int col, const wxString& value )
{
// TODO: bounds checking
//
- m_data[row][col] = s;
+ m_data[row][col] = value;
}
bool wxGridStringTable::IsEmptyCell( int row, int col )
{
int cw, ch;
GetClientSize( &cw, &ch );
-
+
int right, bottom;
m_owner->CalcUnscrolledPosition( cw, ch, &right, &bottom );
-
+
wxRect rightRect;
rightRect = m_owner->CellToRect( 0, m_owner->GetNumberCols()-1 );
wxRect bottomRect;
bottomRect = m_owner->CellToRect( m_owner->GetNumberRows()-1, 0 );
-
+
if ( right > rightRect.GetRight() || bottom > bottomRect.GetBottom() )
{
int left, top;
m_owner->CalcUnscrolledPosition( 0, 0, &left, &top );
-
+
wxClientDC dc( this );
m_owner->PrepareDC( dc );
dc.SetBrush( wxBrush(m_owner->GetDefaultCellBackgroundColour(), wxSOLID) );
dc.SetPen( *wxTRANSPARENT_PEN );
-
+
if ( right > rightRect.GetRight() )
dc.DrawRectangle( rightRect.GetRight()+1, top, right - rightRect.GetRight(), ch );
-
+
if ( bottom > bottomRect.GetBottom() )
dc.DrawRectangle( left, bottomRect.GetBottom()+1, cw, bottom - bottomRect.GetBottom() );
}
if (m_ownTable)
delete m_table;
+
+ delete m_typeRegistry;
}
m_defaultCellAttr = new wxGridCellAttr;
m_defaultCellAttr->SetDefAttr(m_defaultCellAttr);
- // RD: Should we fill the default attrs now or is waiting until Init() okay?
+
+ // Set default cell attributes
+ m_defaultCellAttr->SetFont(GetFont());
+ m_defaultCellAttr->SetAlignment(wxLEFT, wxTOP);
+ m_defaultCellAttr->SetTextColour(
+ wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT));
+ m_defaultCellAttr->SetBackgroundColour(
+ wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
+ m_defaultCellAttr->SetRenderer(new wxGridCellStringRenderer);
+ m_defaultCellAttr->SetEditor(new wxGridCellTextEditor);
m_numRows = 0;
m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH;
m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT;
+ // data type registration
+ m_typeRegistry = new wxGridTypeRegistry;
+ RegisterDataType(wxT("string"), new wxGridCellStringRenderer,
+ new wxGridCellTextEditor);
+ RegisterDataType(wxT("bool"), new wxGridCellBoolRenderer,
+ new wxGridCellBoolEditor);
+
+
+ // subwindow components that make up the wxGrid
m_cornerLabelWin = new wxGridCornerLabelWindow( this,
-1,
wxDefaultPosition,
m_defaultRowHeight += 4;
#endif
- // Set default cell attributes
- m_defaultCellAttr->SetFont(GetFont());
- m_defaultCellAttr->SetAlignment(wxLEFT, wxTOP);
- m_defaultCellAttr->SetRenderer(new wxGridCellStringRenderer);
- m_defaultCellAttr->SetEditor(new wxGridCellTextEditor);
- m_defaultCellAttr->SetTextColour(
- wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT));
- m_defaultCellAttr->SetBackgroundColour(
- wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
-
-
m_gridLineColour = wxColour( 128, 128, 255 );
m_gridLinesEnabled = TRUE;
EnableCellEditControl();
wxGridCellAttr* attr = GetCellAttr(m_currentCellCoords);
- attr->GetEditor()->StartingClick();
+ attr->GetEditor(GetDefaultEditorForCell(coords.GetRow(), coords.GetCol()))->StartingClick();
attr->DecRef();
m_waitForSlowClick = FALSE;
if ( !IsCellEditControlEnabled() && CanEnableCellControl() )
{
EnableCellEditControl();
- wxGridCellAttr* attr = GetCellAttr(m_currentCellCoords);
- attr->GetEditor()->StartingKey(event);
+ int row = m_currentCellCoords.GetRow();
+ int col = m_currentCellCoords.GetCol();
+ wxGridCellAttr* attr = GetCellAttr(row, col);
+ attr->GetEditor(GetDefaultEditorForCell(row, col))->StartingKey(event);
attr->DecRef();
}
else
// if the editor is shown, we should use it and not the renderer
if ( isCurrent && IsCellEditControlEnabled() )
{
- attr->GetEditor()->PaintBackground(rect, attr);
+ attr->GetEditor(GetDefaultEditorForCell(row, col))->
+ PaintBackground(rect, attr);
}
else
{
// but all the rest is drawn by the cell renderer and hence may be
// customized
- attr->GetRenderer()->Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords));
+ attr->GetRenderer(GetDefaultRendererForCell(row,col))->
+ Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords));
+
}
attr->DecRef();
#endif // 0
}
+
void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords )
{
int row = coords.GetRow();
#endif
wxGridCellAttr* attr = GetCellAttr(row, col);
- wxGridCellEditor* editor = attr->GetEditor();
+ wxGridCellEditor* editor = attr->GetEditor(GetDefaultEditorForCell(row, col));
if ( !editor->IsCreated() )
{
editor->Create(m_gridWin, -1,
int col = m_currentCellCoords.GetCol();
wxGridCellAttr* attr = GetCellAttr(row, col);
- attr->GetEditor()->Show( FALSE );
+ attr->GetEditor(GetDefaultEditorForCell(row, col))->Show( FALSE );
attr->DecRef();
m_gridWin->SetFocus();
}
int col = m_currentCellCoords.GetCol();
wxGridCellAttr* attr = GetCellAttr(row, col);
- bool changed = attr->GetEditor()->EndEdit(row, col, TRUE, this);
+ wxGridCellEditor* editor = attr->GetEditor(GetDefaultEditorForCell(row, col));
+ bool changed = editor->EndEdit(row, col, TRUE, this);
attr->DecRef();
m_defaultCellAttr->SetFont(font);
}
-void wxGrid::SetDefaultRenderer(wxGridCellRenderer *renderer)
-{
- m_defaultCellAttr->SetRenderer(renderer);
-}
+// void wxGrid::SetDefaultRenderer(wxGridCellRenderer *renderer)
+// {
+// m_defaultCellAttr->SetRenderer(renderer);
+// }
-void wxGrid::SetDefaultEditor(wxGridCellEditor *editor)
-{
- m_defaultCellAttr->SetEditor(editor);
-}
+// void wxGrid::SetDefaultEditor(wxGridCellEditor *editor)
+// {
+// m_defaultCellAttr->SetEditor(editor);
+// }
// ----------------------------------------------------------------------------
// access to the default attrbiutes
m_defaultCellAttr->GetAlignment(horiz, vert);
}
-wxGridCellRenderer *wxGrid::GetDefaultRenderer() const
-{
- return m_defaultCellAttr->GetRenderer();
-}
+// wxGridCellRenderer *wxGrid::GetDefaultRenderer() const
+// {
+// return m_defaultCellAttr->GetRenderer();
+// }
-wxGridCellEditor *wxGrid::GetDefaultEditor() const
-{
- return m_defaultCellAttr->GetEditor();
-}
+// wxGridCellEditor *wxGrid::GetDefaultEditor() const
+// {
+// return m_defaultCellAttr->GetEditor();
+// }
// ----------------------------------------------------------------------------
// access to cell attributes
wxGridCellRenderer* wxGrid::GetCellRenderer(int row, int col)
{
wxGridCellAttr* attr = GetCellAttr(row, col);
- wxGridCellRenderer* renderer = attr->GetRenderer();
+ wxGridCellRenderer* renderer = attr->GetRenderer(GetDefaultRendererForCell(row,col));
attr->DecRef();
return renderer;
}
wxGridCellEditor* wxGrid::GetCellEditor(int row, int col)
{
wxGridCellAttr* attr = GetCellAttr(row, col);
- wxGridCellEditor* editor = attr->GetEditor();
+ wxGridCellEditor* editor = attr->GetEditor(GetDefaultEditorForCell(row, col));
attr->DecRef();
return editor;
}
return FALSE;
}
- // RD: Maybe m_table->CanHaveAttributes() would be better in case the
- // table is providing the attributes itself??? In which case
- // I don't think the grid should create a Provider object for the
- // table but the table should be smart enough to do that on its own.
- if ( !m_table->GetAttrProvider() )
- {
- // use the default attr provider by default
- // (another choice would be to just return FALSE thus forcing the user
- // to it himself)
- m_table->SetAttrProvider(new wxGridCellAttrProvider);
- }
-
- return TRUE;
+ return m_table->CanHaveAttributes();
}
void wxGrid::ClearAttrCache()
}
}
+// ----------------------------------------------------------------------------
+// Data type registration
+// ----------------------------------------------------------------------------
+
+void wxGrid::RegisterDataType(const wxString& typeName,
+ wxGridCellRenderer* renderer,
+ wxGridCellEditor* editor)
+{
+ m_typeRegistry->RegisterDataType(typeName, renderer, editor);
+}
+
+
+wxGridCellEditor* wxGrid::GetDefaultEditorForCell(int row, int col)
+{
+ wxString typeName = m_table->GetTypeName(row, col);
+ return GetDefaultEditorForType(typeName);
+}
+
+wxGridCellRenderer* wxGrid::GetDefaultRendererForCell(int row, int col)
+{
+ wxString typeName = m_table->GetTypeName(row, col);
+ return GetDefaultRendererForType(typeName);
+}
+
+wxGridCellEditor* wxGrid::GetDefaultEditorForType(const wxString& typeName)
+{
+ int index = m_typeRegistry->FindDataType(typeName);
+ if (index == -1) {
+ // Should we force the failure here or let it fallback to string handling???
+ // wxFAIL_MSG(wxT("Unknown data type name"));
+ return NULL;
+ }
+ return m_typeRegistry->GetEditor(index);
+}
+
+wxGridCellRenderer* wxGrid::GetDefaultRendererForType(const wxString& typeName)
+{
+ int index = m_typeRegistry->FindDataType(typeName);
+ if (index == -1) {
+ // Should we force the failure here or let it fallback to string handling???
+ // wxFAIL_MSG(wxT("Unknown data type name"));
+ return NULL;
+ }
+ return m_typeRegistry->GetRenderer(index);
+}
+
+
// ----------------------------------------------------------------------------
// row/col size
// ----------------------------------------------------------------------------