]> git.saurik.com Git - wxWidgets.git/commitdiff
Added ability for tables, grids, editors and renderers to handle nonstring data.
authorRobin Dunn <robin@alldunn.com>
Mon, 21 Feb 2000 23:17:40 +0000 (23:17 +0000)
committerRobin Dunn <robin@alldunn.com>
Mon, 21 Feb 2000 23:17:40 +0000 (23:17 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6195 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/grid.h
samples/newgrid/griddemo.cpp
samples/newgrid/griddemo.h
src/generic/grid.cpp

index 33cb963168e08c550c682c7890aef7f8ea5ab5be..ee7e4f9424f65e4cf0dc46c42c6e8d1451f5804f 100644 (file)
@@ -61,6 +61,7 @@ class WXDLLEXPORT wxGridCornerLabelWindow;
 class WXDLLEXPORT wxGridRowLabelWindow;
 class WXDLLEXPORT wxGridTableBase;
 class WXDLLEXPORT wxGridWindow;
+class WXDLLEXPORT wxGridTypeRegistry;
 
 class WXDLLEXPORT wxCheckBox;
 class WXDLLEXPORT wxTextCtrl;
@@ -309,8 +310,8 @@ public:
     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; }
 
@@ -406,9 +407,27 @@ public:
     //
     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
     //
@@ -437,12 +456,17 @@ public:
     // 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
@@ -866,12 +890,13 @@ public:
     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 )
@@ -968,6 +993,16 @@ public:
     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...
     //
@@ -1259,6 +1294,9 @@ protected:
     bool m_inOnKeyDown;
     int  m_batchCount;
 
+
+    wxGridTypeRegistry*    m_typeRegistry;
+
     enum CursorMode
     {
         WXGRID_CURSOR_SELECT_CELL,
@@ -1335,6 +1373,7 @@ protected:
 };
 
 
+
 // ----------------------------------------------------------------------------
 // Grid event class and event types
 // ----------------------------------------------------------------------------
index c24309c46e64d1d6c76396314bf1ef78efe8332b..492043c751ca1f0421208c5ab7589b255a52ff5f 100644 (file)
@@ -184,7 +184,11 @@ GridFrame::GridFrame()
     // this will create a grid and, by default, an associated grid
     // table for string data
     //
-    grid->CreateGrid( 100, 100 );
+    //grid->CreateGrid( 100, 100 );
+    grid->SetTable(new SimpleTable(100, 100), TRUE);
+
+    // VZ: cell borders don't look nice otherwise :-) (for now...)
+    grid->SetDefaultCellBackgroundColour(wxColour(200, 200, 180));
 
     grid->SetRowSize( 0, 60 );
     grid->SetCellValue( 0, 0, "Ctrl+Home\nwill go to\nthis cell" );
@@ -724,7 +728,7 @@ BugsGridFrame::BugsGridFrame()
 
     // TODO the correct data type must be used for each column
 
-    wxGrid *grid = new wxGrid(this, -1);
+    wxGrid *grid = new wxGrid(this, -1, wxDefaultPosition);
     wxGridTableBase *table =
         new wxGridStringTable(WXSIZEOF(data), WXSIZEOF(headers));
     for ( size_t row = 0; row < WXSIZEOF(data); row++ )
index d586e320f290b05760ef5e9245f0aa04b56f1516..e54c469f75fe6eeebff29eed0ce1ee0931e6658f 100644 (file)
@@ -121,6 +121,24 @@ public:
 // memory
 // ----------------------------------------------------------------------------
 
+class SimpleTable : public wxGridStringTable {
+public:
+    SimpleTable( int numRows, int numCols )
+        : wxGridStringTable( numRows, numCols ) {}
+
+    // override this to fake a row as all bools
+    wxString GetTypeName( int row, int col )
+        {
+            if (row == 8)
+                return wxT("bool");
+            else if (row == 9 && col == 1)
+                return wxT("unknown type");  // to test fallback
+            else
+                return wxGridStringTable::GetTypeName(row, col);
+        }
+
+};
+
 class BigGridTable : public wxGridTableBase
 {
 public:
@@ -128,7 +146,6 @@ public:
 
     long GetNumberRows() { return m_sizeGrid; }
     long GetNumberCols() { return m_sizeGrid; }
-
     wxString GetValue( int row, int col )
     {
         return wxString::Format("(%d, %d)", row, col);
index 623d484c3bf0d33b6ea0a8fa7d8a629a19a9e9f6..75cecfcf35d8e46ad89029a411342949587f7a33 100644 (file)
@@ -248,6 +248,46 @@ public:
                            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
 // ----------------------------------------------------------------------------
@@ -341,23 +381,14 @@ void wxGridCellEditor::Show(bool show, wxGridCellAttr *attr)
         // 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
@@ -565,7 +596,10 @@ void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid)
     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();
 }
@@ -584,8 +618,10 @@ bool wxGridCellBoolEditor::EndEdit(int row, int col,
 
     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;
@@ -764,7 +800,13 @@ void wxGridCellBoolRenderer::Draw(wxGrid& grid,
 
     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);
@@ -837,12 +879,21 @@ void wxGridCellAttr::GetAlignment(int *hAlign, int *vAlign) const
 }
 
 
-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"));
@@ -850,12 +901,14 @@ wxGridCellRenderer* wxGridCellAttr::GetRenderer() const
     }
 }
 
-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"));
@@ -1156,14 +1209,64 @@ void wxGridCellAttrProvider::UpdateAttrCols( size_t pos, int numCols )
     }
 }
 
+// ----------------------------------------------------------------------------
+// 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 )
 
 
@@ -1184,6 +1287,16 @@ void wxGridTableBase::SetAttrProvider(wxGridCellAttrProvider *attrProvider)
     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 )
@@ -1302,7 +1415,8 @@ bool wxGridTableBase::DeleteCols( size_t pos, size_t numCols )
 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;
 }
 
@@ -1333,6 +1447,65 @@ wxString wxGridTableBase::GetColLabelValue( int col )
 }
 
 
+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) )
+{
+}
+
 
 //////////////////////////////////////////////////////////////////////
 //
@@ -1418,11 +1591,11 @@ wxString wxGridStringTable::GetValue( int row, int col )
     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 )
@@ -1980,29 +2153,29 @@ void wxGridWindow::OnEraseBackground(wxEraseEvent& event)
 {
     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() );
     }
@@ -2049,6 +2222,8 @@ wxGrid::~wxGrid()
 
     if (m_ownTable)
         delete m_table;
+
+    delete m_typeRegistry;
 }
 
 
@@ -2068,7 +2243,16 @@ void wxGrid::Create()
 
     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;
@@ -2078,6 +2262,15 @@ void wxGrid::Create()
     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,
@@ -2200,17 +2393,6 @@ void wxGrid::Init()
     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;
 
@@ -3282,7 +3464,7 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
                         EnableCellEditControl();
 
                         wxGridCellAttr* attr = GetCellAttr(m_currentCellCoords);
-                        attr->GetEditor()->StartingClick();
+                        attr->GetEditor(GetDefaultEditorForCell(coords.GetRow(), coords.GetCol()))->StartingClick();
                         attr->DecRef();
 
                         m_waitForSlowClick = FALSE;
@@ -4043,8 +4225,10 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
                 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
@@ -4196,13 +4380,16 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords )
     // 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();
@@ -4252,6 +4439,7 @@ void wxGrid::DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr )
 #endif // 0
 }
 
+
 void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords )
 {
     int row = coords.GetRow();
@@ -4735,7 +4923,7 @@ void wxGrid::ShowCellEditControl()
 #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,
@@ -4759,7 +4947,7 @@ void wxGrid::HideCellEditControl()
         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();
     }
@@ -4781,7 +4969,8 @@ void wxGrid::SaveEditControlValue()
         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();
 
@@ -5677,15 +5866,15 @@ void wxGrid::SetDefaultCellFont( const wxFont& font )
     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
@@ -5711,15 +5900,15 @@ void wxGrid::GetDefaultCellAlignment( int *horiz, int *vert )
     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
@@ -5759,7 +5948,7 @@ void wxGrid::GetCellAlignment( int row, int col, int *horiz, int *vert )
 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;
 }
@@ -5767,7 +5956,7 @@ wxGridCellRenderer* wxGrid::GetCellRenderer(int row, int col)
 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;
 }
@@ -5791,19 +5980,7 @@ bool wxGrid::CanHaveAttributes()
         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()
@@ -5993,6 +6170,53 @@ void wxGrid::SetReadOnly(int row, int col, bool isReadOnly)
     }
 }
 
+// ----------------------------------------------------------------------------
+// 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
 // ----------------------------------------------------------------------------