From: Robin Dunn <robin@alldunn.com> Date: Mon, 21 Feb 2000 23:17:40 +0000 (+0000) Subject: Added ability for tables, grids, editors and renderers to handle nonstring data. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/f2d7623799d9756be1d48d2a91b8c8c7a57b911a Added ability for tables, grids, editors and renderers to handle nonstring data. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6195 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index 33cb963168..ee7e4f9424 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -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 // ---------------------------------------------------------------------------- diff --git a/samples/newgrid/griddemo.cpp b/samples/newgrid/griddemo.cpp index c24309c46e..492043c751 100644 --- a/samples/newgrid/griddemo.cpp +++ b/samples/newgrid/griddemo.cpp @@ -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++ ) diff --git a/samples/newgrid/griddemo.h b/samples/newgrid/griddemo.h index d586e320f2..e54c469f75 100644 --- a/samples/newgrid/griddemo.h +++ b/samples/newgrid/griddemo.h @@ -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); diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 623d484c3b..75cecfcf35 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -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 // ----------------------------------------------------------------------------