From: Vadim Zeitlin Date: Tue, 29 Feb 2000 18:36:04 +0000 (+0000) Subject: 1. more corrections for ref counted editors/renderers (doesn't crash any more, X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/0b190b0f6ae1de468733c1c8f8aad877a7d44792?hp=39bcce60fea0a8211b44c7f1fdbcea576ad39822 1. more corrections for ref counted editors/renderers (doesn't crash any more, might leak memory though) 2. attempt to add parameters to renderers - failed. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6357 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index 89bae8bd1f..5295d43d2a 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -127,6 +127,10 @@ public: wxDC& dc, int row, int col) = 0; + // interpret renderer parameters: arbitrary string whose interpretatin is + // left to the derived classes + virtual void SetParameters(const wxString& params); + protected: // virtual dtor for any base class - private because only DecRef() can // delete us @@ -195,13 +199,13 @@ protected: class WXDLLEXPORT wxGridCellFloatRenderer : public wxGridCellStringRenderer { public: - wxGridCellFloatRenderer(int width, int precision); + wxGridCellFloatRenderer(int width = -1, int precision = -1); // get/change formatting parameters int GetWidth() const { return m_width; } - void SetWidth(int width) { m_width = width; } + void SetWidth(int width) { m_width = width; m_format.clear(); } int GetPrecision() const { return m_precision; } - void SetPrecision(int precision) { m_precision = precision; } + void SetPrecision(int precision) { m_precision = precision; m_format.clear(); } // draw the string right aligned with given width/precision virtual void Draw(wxGrid& grid, @@ -215,13 +219,17 @@ public: wxGridCellAttr& attr, wxDC& dc, int row, int col); + + // parameters string format is "width[,precision]" + virtual void SetParameters(const wxString& params); + protected: wxString GetString(wxGrid& grid, int row, int col); private: // formatting parameters int m_width, - m_precision; + m_precision; wxString m_format; }; @@ -1089,11 +1097,18 @@ public: void DisableDragGridSize() { EnableDragGridSize(FALSE); } bool CanDragGridSize() { return m_canDragGridSize; } - // this sets the specified attribute for all cells in this row/col void SetRowAttr(int row, wxGridCellAttr *attr); void SetColAttr(int col, wxGridCellAttr *attr); + // shortcuts for setting the column parameters + + // set the format for the data in the column: default is string + void SetColFormatBool(int col); + void SetColFormatNumber(int col); + void SetColFormatFloat(int col, int width = -1, int precision = -1); + void SetColFormatCustom(int col, const wxString& typeName); + void EnableGridLines( bool enable = TRUE ); bool GridLinesEnabled() { return m_gridLinesEnabled; } diff --git a/samples/newgrid/griddemo.cpp b/samples/newgrid/griddemo.cpp index e961046b0b..23ff16424d 100644 --- a/samples/newgrid/griddemo.cpp +++ b/samples/newgrid/griddemo.cpp @@ -231,6 +231,16 @@ GridFrame::GridFrame() grid->SetColSize(4, 120); grid->SetColMinimalWidth(4, 120); + grid->SetColFormatFloat(5); + grid->SetCellValue(0, 5, "3.1415"); + grid->SetCellValue(1, 5, "1415"); + grid->SetCellValue(2, 5, "12345.67890"); + + grid->SetColFormatFloat(6, 6, 2); + grid->SetCellValue(0, 6, "3.1415"); + grid->SetCellValue(1, 6, "1415"); + grid->SetCellValue(2, 6, "12345.67890"); + wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL ); topSizer->Add( grid, 1, @@ -1096,5 +1106,8 @@ BugsGridFrame::BugsGridFrame() grid->SetMargins(0, 0); grid->Fit(); - Fit(); + wxSize size = grid->GetSize(); + size.x += 10; + size.y += 10; + SetClientSize(size); } diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index ea8228ec99..1674f1e502 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -1079,6 +1079,11 @@ void wxGridCellRenderer::Draw(wxGrid& grid, dc.DrawRectangle(rect); } +void wxGridCellRenderer::SetParameters(const wxString& WXUNUSED(params)) +{ + // nothing to do +} + wxGridCellRenderer::~wxGridCellRenderer() { } @@ -1214,21 +1219,45 @@ wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width, int precision) wxString wxGridCellFloatRenderer::GetString(wxGrid& grid, int row, int col) { wxGridTableBase *table = grid.GetTable(); + + bool hasDouble; + double val; wxString text; if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) ) { - if ( !m_format ) - { - m_format.Printf(_T("%%%d.%d%%f"), m_width, m_precision); - } - - text.Printf(m_format, table->GetValueAsDouble(row, col)); + val = table->GetValueAsDouble(row, col); + hasDouble = TRUE; } else { text = table->GetValue(row, col); + hasDouble = text.ToDouble(&val); } + if ( hasDouble ) + { + if ( !m_format ) + { + if ( m_width == -1 ) + { + // default width/precision + m_format = _T("%f"); + } + else if ( m_precision == -1 ) + { + // default precision + m_format.Printf(_T("%%%d.f"), m_width); + } + else + { + m_format.Printf(_T("%%%d.%df"), m_width, m_precision); + } + } + + text.Printf(m_format, val); + } + //else: text already contains the string + return text; } @@ -1262,6 +1291,54 @@ wxSize wxGridCellFloatRenderer::GetBestSize(wxGrid& grid, return DoGetBestSize(attr, dc, GetString(grid, row, col)); } +void wxGridCellFloatRenderer::SetParameters(const wxString& params) +{ + bool ok = TRUE; + + if ( !params ) + { + // reset to defaults + SetWidth(-1); + SetPrecision(-1); + } + else + { + wxString tmp = params.BeforeFirst(_T(',')); + if ( !!tmp ) + { + long width; + if ( !tmp.ToLong(&width) ) + { + ok = FALSE; + } + else + { + SetWidth((int)width); + + tmp = params.AfterFirst(_T(',')); + if ( !!tmp ) + { + long precision; + if ( !tmp.ToLong(&precision) ) + { + ok = FALSE; + } + else + { + SetPrecision((int)precision); + } + } + } + } + + if ( !ok ) + { + wxLogDebug(_T("Invalid wxGridCellFloatRenderer parameter string " + "'%s ignored"), params.c_str()); + } + } +} + // ---------------------------------------------------------------------------- // wxGridCellBoolRenderer // ---------------------------------------------------------------------------- @@ -1462,38 +1539,58 @@ void wxGridCellAttr::GetAlignment(int *hAlign, int *vAlign) const wxGridCellRenderer* wxGridCellAttr::GetRenderer(wxGrid* grid, int row, int col) const { - if ((m_defGridAttr != this || grid == NULL) && HasRenderer()) - return m_renderer; // use local attribute - wxGridCellRenderer* renderer = NULL; - if (grid) // get renderer for the data type - renderer = grid->GetDefaultRendererForCell(row, col); - if (! renderer) + if ( m_defGridAttr != this || grid == NULL ) + { + renderer = m_renderer; // use local attribute + if ( renderer ) + renderer->IncRef(); + } + + if ( !renderer && grid ) // get renderer for the data type + { + // GetDefaultRendererForCell() will do IncRef() for us + renderer = grid->GetDefaultRendererForCell(row, col); + } + + if ( !renderer ) + { // if we still don't have one then use the grid default + // (no need for IncRef() here neither) renderer = m_defGridAttr->GetRenderer(NULL,0,0); + } - if (! renderer) + if ( !renderer) + { wxFAIL_MSG(wxT("Missing default cell attribute")); + } return renderer; } wxGridCellEditor* wxGridCellAttr::GetEditor(wxGrid* grid, int row, int col) const { - if ((m_defGridAttr != this || grid == NULL) && HasEditor()) - return m_editor; // use local attribute - wxGridCellEditor* editor = NULL; - if (grid) // get renderer for the data type + + if ( m_defGridAttr != this || grid == NULL ) + { + editor = m_editor; // use local attribute + if ( editor ) + editor->IncRef(); + } + + if ( grid ) // get renderer for the data type editor = grid->GetDefaultEditorForCell(row, col); - if (! editor) + if ( !editor ) // if we still don't have one then use the grid default editor = m_defGridAttr->GetEditor(NULL,0,0); - if (! editor) + if ( !editor ) + { wxFAIL_MSG(wxT("Missing default cell attribute")); + } return editor; } @@ -1839,12 +1936,14 @@ int wxGridTypeRegistry::FindDataType(const wxString& typeName) wxGridCellRenderer* wxGridTypeRegistry::GetRenderer(int index) { wxGridCellRenderer* renderer = m_typeinfo[index]->m_renderer; + renderer->IncRef(); return renderer; } -wxGridCellEditor* wxGridTypeRegistry::GetEditor(int index) +wxGridCellEditor* wxGridTypeRegistry::GetEditor(int index) { wxGridCellEditor* editor = m_typeinfo[index]->m_editor; + editor->IncRef(); return editor; } @@ -2091,7 +2190,6 @@ void wxGridTableBase::SetValueAsCustom( int WXUNUSED(row), int WXUNUSED(col), { } - ////////////////////////////////////////////////////////////////////// // // Message class for the grid table to send requests and notifications @@ -2832,6 +2930,9 @@ void wxGrid::Create() RegisterDataType(wxGRID_VALUE_NUMBER, new wxGridCellNumberRenderer, new wxGridCellNumberEditor); + RegisterDataType(wxGRID_VALUE_FLOAT, + new wxGridCellFloatRenderer, + new wxGridCellFloatEditor); // subwindow components that make up the wxGrid m_cornerLabelWin = new wxGridCornerLabelWindow( this, @@ -4041,7 +4142,11 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event ) EnableCellEditControl(); wxGridCellAttr* attr = GetCellAttr(m_currentCellCoords); - attr->GetEditor(this, coords.GetRow(), coords.GetCol())->StartingClick(); + wxGridCellEditor *editor = attr->GetEditor(this, + coords.GetRow(), + coords.GetCol()); + editor->StartingClick(); + editor->DecRef(); attr->DecRef(); m_waitForSlowClick = FALSE; @@ -4810,7 +4915,9 @@ void wxGrid::OnKeyDown( wxKeyEvent& event ) int row = m_currentCellCoords.GetRow(); int col = m_currentCellCoords.GetCol(); wxGridCellAttr* attr = GetCellAttr(row, col); - attr->GetEditor(this, row, col)->StartingKey(event); + wxGridCellEditor *editor = attr->GetEditor(this, row, col); + editor->StartingKey(event); + editor->DecRef(); attr->DecRef(); } else @@ -4991,15 +5098,17 @@ 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(this, row, col)->PaintBackground(rect, attr); + wxGridCellEditor *editor = attr->GetEditor(this, row, col); + editor->PaintBackground(rect, attr); + editor->DecRef(); } else { // but all the rest is drawn by the cell renderer and hence may be // customized - attr->GetRenderer(this, row, col)-> - Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords)); - + wxGridCellRenderer *renderer = attr->GetRenderer(this, row, col); + renderer->Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords)); + renderer->DecRef(); } attr->DecRef(); @@ -5512,10 +5621,12 @@ void wxGrid::ShowCellEditControl() } editor->Show( TRUE, attr ); - + editor->SetSize( rect ); editor->BeginEdit(row, col, this); + + editor->DecRef(); attr->DecRef(); } } @@ -5530,7 +5641,9 @@ void wxGrid::HideCellEditControl() int col = m_currentCellCoords.GetCol(); wxGridCellAttr* attr = GetCellAttr(row, col); - attr->GetEditor(this, row, col)->Show( FALSE ); + wxGridCellEditor *editor = attr->GetEditor(this, row, col); + editor->Show( FALSE ); + editor->DecRef(); attr->DecRef(); m_gridWin->SetFocus(); } @@ -5548,6 +5661,7 @@ void wxGrid::SaveEditControlValue() wxGridCellEditor* editor = attr->GetEditor(this, row, col); bool changed = editor->EndEdit(row, col, this); + editor->DecRef(); attr->DecRef(); if (changed) @@ -6478,7 +6592,7 @@ void wxGrid::GetDefaultCellAlignment( int *horiz, int *vert ) wxGridCellRenderer *wxGrid::GetDefaultRenderer() const { - return m_defaultCellAttr->GetRenderer(NULL,0,0); + return m_defaultCellAttr->GetRenderer(NULL, 0, 0); } wxGridCellEditor *wxGrid::GetDefaultEditor() const @@ -6526,6 +6640,7 @@ wxGridCellRenderer* wxGrid::GetCellRenderer(int row, int col) wxGridCellAttr* attr = GetCellAttr(row, col); wxGridCellRenderer* renderer = attr->GetRenderer(this, row, col); attr->DecRef(); + return renderer; } @@ -6534,6 +6649,7 @@ wxGridCellEditor* wxGrid::GetCellEditor(int row, int col) wxGridCellAttr* attr = GetCellAttr(row, col); wxGridCellEditor* editor = attr->GetEditor(this, row, col); attr->DecRef(); + return editor; } @@ -6648,6 +6764,40 @@ wxGridCellAttr *wxGrid::GetOrCreateCellAttr(int row, int col) const return attr; } +// ---------------------------------------------------------------------------- +// setting column attributes (wrappers around SetColAttr) +// ---------------------------------------------------------------------------- + +void wxGrid::SetColFormatBool(int col) +{ + SetColFormatCustom(col, wxGRID_VALUE_BOOL); +} + +void wxGrid::SetColFormatNumber(int col) +{ + SetColFormatCustom(col, wxGRID_VALUE_NUMBER); +} + +void wxGrid::SetColFormatFloat(int col, int width, int precision) +{ + wxString typeName = wxGRID_VALUE_FLOAT; + if ( (width != -1) || (precision != -1) ) + { + typeName << _T(':') << width << _T(',') << precision; + } + + SetColFormatCustom(col, typeName); +} + +void wxGrid::SetColFormatCustom(int col, const wxString& typeName) +{ + wxGridCellAttr *attr = new wxGridCellAttr; + wxGridCellRenderer *renderer = GetDefaultRendererForType(typeName); + attr->SetRenderer(renderer); + + SetColAttr(col, attr); +} + // ---------------------------------------------------------------------------- // setting cell attributes: this is forwarded to the table // ---------------------------------------------------------------------------- @@ -6774,24 +6924,37 @@ wxGridCellEditor* wxGrid::GetDefaultEditorForType(const wxString& typeName) const { 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")); + if ( index == wxNOT_FOUND ) + { + wxFAIL_MSG(wxT("Unknown data type name")); + return NULL; } + return m_typeRegistry->GetEditor(index); } wxGridCellRenderer* wxGrid::GetDefaultRendererForType(const wxString& typeName) const { - 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")); + // the first part of the typename is the "real" type, anything after ':' + // are the parameters for the renderer + wxString type = typeName.BeforeFirst(_T(':')); + + int index = m_typeRegistry->FindDataType(type); + if ( index == wxNOT_FOUND ) + { + wxFAIL_MSG(wxT("Unknown data type name")); + return NULL; } - return m_typeRegistry->GetRenderer(index); + + wxGridCellRenderer *renderer = m_typeRegistry->GetRenderer(index); + + // do it even if there are no parameters to reset them to defaults + renderer->SetParameters(typeName.AfterFirst(_T(':'))); + + return renderer; } @@ -6942,6 +7105,8 @@ void wxGrid::AutoSizeColOrRow( int colOrRow, bool setAsMin, bool column ) { extentMax = extent; } + + renderer->DecRef(); } attr->DecRef();