diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index 21184f9c17..ff744330d7 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -628,6 +628,9 @@ private: friend class wxGridCellAttrDummyFriend; }; +// Smart pointer to wxGridCellAttr, calling DecRef() on it automatically. +typedef wxObjectDataPtr wxGridCellAttrPtr; + // ---------------------------------------------------------------------------- // wxGridCellAttrProvider: class used by wxGridTableBase to retrieve/store the // cell attributes. @@ -650,6 +653,13 @@ public: virtual wxGridCellAttr *GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind ) const; + // Helper returning smart pointer calling DecRef() automatically. + wxGridCellAttrPtr GetAttrPtr(int row, int col, + wxGridCellAttr::wxAttrKind kind ) const + { + return wxGridCellAttrPtr(GetAttr(row, col, kind)); + } + // all these functions take ownership of the pointer, don't call DecRef() // on it virtual void SetAttr(wxGridCellAttr *attr, int row, int col); @@ -824,6 +834,11 @@ public: virtual wxGridCellAttr *GetAttr( int row, int col, wxGridCellAttr::wxAttrKind kind ); + wxGridCellAttrPtr GetAttrPtr(int row, int col, + wxGridCellAttr::wxAttrKind kind) + { + return wxGridCellAttrPtr(GetAttr(row, col, kind)); + } // these functions take ownership of the pointer virtual void SetAttr(wxGridCellAttr* attr, int row, int col); @@ -1478,6 +1493,11 @@ public: // DecRef() must be called on the returned pointer, as usual wxGridCellAttr *GetOrCreateCellAttr(int row, int col) const; + wxGridCellAttrPtr GetOrCreateCellAttrPtr(int row, int col) const + { + return wxGridCellAttrPtr(GetOrCreateCellAttr(row, col)); + } + // shortcuts for setting the column parameters @@ -2196,6 +2216,16 @@ protected: wxGridCellAttr *GetCellAttr(const wxGridCellCoords& coords ) const { return GetCellAttr( coords.GetRow(), coords.GetCol() ); } + wxGridCellAttrPtr GetCellAttrPtr(int row, int col) const + { + return wxGridCellAttrPtr(GetCellAttr(row, col)); + } + wxGridCellAttrPtr GetCellAttrPtr(const wxGridCellCoords& coords) const + { + return wxGridCellAttrPtr(GetCellAttr(coords)); + } + + // the default cell attr object for cells that don't have their own wxGridCellAttr* m_defaultCellAttr; diff --git a/interface/wx/grid.h b/interface/wx/grid.h index 77319ed411..612d936ed9 100644 --- a/interface/wx/grid.h +++ b/interface/wx/grid.h @@ -976,6 +976,10 @@ public: changing their attributes from the defaults. An object of this class may be returned by wxGridTableBase::GetAttr(). + Note that objects of this class are reference-counted and it's recommended + to use wxGridCellAttrPtr smart pointer class when working with them to + avoid memory leaks. + @library{wxcore} @category{grid} */ @@ -1257,6 +1261,20 @@ protected: virtual ~wxGridCellAttr(); }; +/** + Smart pointer wrapping wxGridCellAttr. + + wxGridCellAttrPtr takes ownership of wxGridCellAttr passed to it on + construction and calls DecRef() on it automatically when it is destroyed. + It also provides transparent access to wxGridCellAttr methods by allowing + to use objects of this class as if they were wxGridCellAttr pointers. + + @since 3.1.4 + + @category{grid} +*/ +typedef wxObjectDataPtr wxGridCellAttrPtr; + /** Base class for header cells renderers. @@ -1459,7 +1477,7 @@ public: the cell attribute having the highest precedence. Notice that the caller must call DecRef() on the returned pointer if it - is non-@NULL. + is non-@NULL. GetAttrPtr() method can be used to do this automatically. @param row The row of the cell. @@ -1474,6 +1492,17 @@ public: virtual wxGridCellAttr *GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind) const; + /** + Get the attribute to use for the specified cell. + + This method is identical to GetAttr(), but returns a smart pointer, + which frees the caller from the need to call DecRef() manually. + + @since 3.1.4 + */ + wxGridCellAttrPtr GetAttrPtr(int row, int col, + wxGridCellAttr::wxAttrKind kind) const; + /*! @name Setting attributes. @@ -2121,10 +2150,24 @@ public: By default this function is simply forwarded to wxGridCellAttrProvider::GetAttr() but it may be overridden to handle attributes directly in the table. + + Prefer to use GetAttrPtr() to avoid the need to call DecRef() on the + returned pointer manually. */ virtual wxGridCellAttr *GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind); + /** + Return the attribute for the given cell. + + This method is identical to GetAttr(), but returns a smart pointer, + which frees the caller from the need to call DecRef() manually. + + @since 3.1.4 + */ + wxGridCellAttrPtr GetAttrPtr(int row, int col, + wxGridCellAttr::wxAttrKind kind); + /** Set attribute of the specified cell. @@ -4939,10 +4982,24 @@ public: attribute is created, associated with the cell and returned. In any case the caller must call DecRef() on the returned pointer. + Prefer to use GetOrCreateCellAttrPtr() to avoid the need to call + DecRef() on the returned pointer. + This function may only be called if CanHaveAttributes() returns @true. */ wxGridCellAttr *GetOrCreateCellAttr(int row, int col) const; + /** + Returns the attribute for the given cell creating one if necessary. + + This method is identical to GetOrCreateCellAttr(), but returns a smart + pointer, which frees the caller from the need to call DecRef() + manually. + + @since 3.1.4 + */ + wxGridCellAttrPtr GetOrCreateCellAttrPtr(int row, int col) const; + /** Returns a base pointer to the current table object. diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 09c4fde9d5..c0aff5fc4c 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -2837,7 +2837,7 @@ void wxGrid::CalcDimensions() int y = GetRowTop(r); // how big is the editor - wxGridCellAttr* attr = GetCellAttr(r, c); + wxGridCellAttrPtr attr = GetCellAttrPtr(r, c); wxGridCellEditor* editor = attr->GetEditor(this, r, c); editor->GetWindow()->GetSize(&w2, &h2); w2 += x; @@ -2847,7 +2847,6 @@ void wxGrid::CalcDimensions() if ( h2 > h ) h = h2; editor->DecRef(); - attr->DecRef(); } wxPoint offset = GetGridWindowOffset(m_gridWin); @@ -4484,11 +4483,10 @@ wxGrid::DoGridCellLeftUp(wxMouseEvent& event, ClearSelection(); EnableCellEditControl(); - wxGridCellAttr *attr = GetCellAttr(coords); + wxGridCellAttrPtr attr = GetCellAttrPtr(coords); wxGridCellEditor *editor = attr->GetEditor(this, coords.GetRow(), coords.GetCol()); editor->StartingClick(); editor->DecRef(); - attr->DecRef(); m_waitForSlowClick = false; } @@ -5729,7 +5727,7 @@ void wxGrid::OnChar( wxKeyEvent& event ) // yes, now check whether the cells editor accepts the key int row = m_currentCellCoords.GetRow(); int col = m_currentCellCoords.GetCol(); - wxGridCellAttr *attr = GetCellAttr(row, col); + wxGridCellAttrPtr attr = GetCellAttrPtr(row, col); wxGridCellEditor *editor = attr->GetEditor(this, row, col); // is special and will always start editing, for @@ -5754,7 +5752,6 @@ void wxGrid::OnChar( wxKeyEvent& event ) } editor->DecRef(); - attr->DecRef(); } else { @@ -5885,11 +5882,10 @@ bool wxGrid::SetCurrentCell( const wxGridCellCoords& coords ) #if !defined(__WXMAC__) if ( !GetBatchCount() ) { - wxGridCellAttr *attr = GetCellAttr( coords ); + wxGridCellAttrPtr attr = GetCellAttrPtr( coords ); wxClientDC dc( currentGridWindow ); PrepareDCFor(dc, currentGridWindow); - DrawCellHighlight( dc, attr ); - attr->DecRef(); + DrawCellHighlight( dc, attr.get() ); } #endif @@ -6086,11 +6082,7 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells ) { if (!m_table->IsEmptyCell(row + l, j)) { - wxGridCellAttr *attr = GetCellAttr(row + l, j); - const bool canOverflow = attr->CanOverflow(); - attr->DecRef(); - - if ( canOverflow ) + if ( GetCellAttrPtr(row + l, j)->CanOverflow() ) { wxGridCellCoords cell(row + l, j); bool marked = false; @@ -6177,7 +6169,7 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) return; // we draw the cell border ourselves - wxGridCellAttr* attr = GetCellAttr(row, col); + wxGridCellAttrPtr attr = GetCellAttrPtr(row, col); bool isCurrent = coords == m_currentCellCoords; @@ -6198,8 +6190,6 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) renderer->Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords)); renderer->DecRef(); } - - attr->DecRef(); } void wxGrid::DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr ) @@ -6326,9 +6316,8 @@ void wxGrid::DrawHighlight(wxDC& dc, const wxGridCellCoordsArray& cells) if ( cell == m_currentCellCoords ) { - wxGridCellAttr* attr = GetCellAttr(m_currentCellCoords); - DrawCellHighlight(dc, attr); - attr->DecRef(); + wxGridCellAttrPtr attr = GetCellAttrPtr(m_currentCellCoords); + DrawCellHighlight(dc, attr.get()); break; } @@ -7070,12 +7059,8 @@ void wxGrid::EnableCellEditControl( bool enable ) bool wxGrid::IsCurrentCellReadOnly() const { - wxGridCellAttr* - attr = const_cast(this)->GetCellAttr(m_currentCellCoords); - bool readonly = attr->IsReadOnly(); - attr->DecRef(); - - return readonly; + return const_cast(this)-> + GetCellAttrPtr(m_currentCellCoords)->IsReadOnly(); } bool wxGrid::CanEnableCellControl() const @@ -7099,9 +7084,7 @@ bool wxGrid::IsCellEditControlShown() const { int row = m_currentCellCoords.GetRow(); int col = m_currentCellCoords.GetCol(); - wxGridCellAttr* attr = GetCellAttr(row, col); - wxGridCellEditor* editor = attr->GetEditor(this, row, col); - attr->DecRef(); + wxGridCellEditor* editor = GetCellAttrPtr(row, col)->GetEditor(this, row, col); if ( editor ) { @@ -7149,7 +7132,7 @@ void wxGrid::ShowCellEditControl() // might not cover the entire cell wxClientDC dc( gridWindow ); PrepareDCFor(dc, gridWindow); - wxGridCellAttr* attr = GetCellAttr(row, col); + wxGridCellAttrPtr attr = GetCellAttrPtr(row, col); dc.SetBrush(wxBrush(attr->GetBackgroundColour())); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(rect); @@ -7238,13 +7221,13 @@ void wxGrid::ShowCellEditControl() rect.SetRight( client_right - 1 ); } - editor->SetCellAttr( attr ); + editor->SetCellAttr( attr.get() ); editor->SetSize( rect ); if (nXMove != 0) editor->GetWindow()->Move( editor->GetWindow()->GetPosition().x + nXMove, editor->GetWindow()->GetPosition().y ); - editor->Show( true, attr ); + editor->Show( true, attr.get() ); // recalc dimensions in case we need to // expand the scrolled window to account for editor @@ -7254,7 +7237,6 @@ void wxGrid::ShowCellEditControl() editor->SetCellAttr(NULL); editor->DecRef(); - attr->DecRef(); } } } @@ -7266,7 +7248,7 @@ void wxGrid::HideCellEditControl() int row = m_currentCellCoords.GetRow(); int col = m_currentCellCoords.GetCol(); - wxGridCellAttr *attr = GetCellAttr(row, col); + wxGridCellAttrPtr attr = GetCellAttrPtr(row, col); wxGridCellEditor *editor = attr->GetEditor(this, row, col); const bool editorHadFocus = editor->GetWindow()->IsDescendant(FindFocus()); @@ -7275,7 +7257,6 @@ void wxGrid::HideCellEditControl() editor->Show( false ); editor->DecRef(); - attr->DecRef(); wxGridWindow *gridWindow = CellToGridWindow(row, col); // return the focus to the grid itself if the editor had it @@ -7330,7 +7311,7 @@ void wxGrid::DoSaveEditControlValue() wxString oldval = GetCellValue(row, col); - wxGridCellAttr* attr = GetCellAttr(row, col); + wxGridCellAttrPtr attr = GetCellAttrPtr(row, col); wxGridCellEditor* editor = attr->GetEditor(this, row, col); wxString newval; @@ -7351,7 +7332,6 @@ void wxGrid::DoSaveEditControlValue() } editor->DecRef(); - attr->DecRef(); } void wxGrid::OnHideEditor(wxCommandEvent& WXUNUSED(event)) @@ -8383,9 +8363,8 @@ void wxGrid::SetCellHighlightColour( const wxColour& colour ) wxClientDC dc( gridWindow ); PrepareDCFor( dc, gridWindow ); - wxGridCellAttr* attr = GetCellAttr(m_currentCellCoords); - DrawCellHighlight(dc, attr); - attr->DecRef(); + wxGridCellAttrPtr attr = GetCellAttrPtr(m_currentCellCoords); + DrawCellHighlight(dc, attr.get()); } } @@ -8629,53 +8608,33 @@ wxGridCellEditor *wxGrid::GetDefaultEditor() const wxColour wxGrid::GetCellBackgroundColour(int row, int col) const { - wxGridCellAttr *attr = GetCellAttr(row, col); - wxColour colour = attr->GetBackgroundColour(); - attr->DecRef(); - - return colour; + return GetCellAttrPtr(row, col)->GetBackgroundColour(); } wxColour wxGrid::GetCellTextColour( int row, int col ) const { - wxGridCellAttr *attr = GetCellAttr(row, col); - wxColour colour = attr->GetTextColour(); - attr->DecRef(); - - return colour; + return GetCellAttrPtr(row, col)->GetTextColour(); } wxFont wxGrid::GetCellFont( int row, int col ) const { - wxGridCellAttr *attr = GetCellAttr(row, col); - wxFont font = attr->GetFont(); - attr->DecRef(); - - return font; + return GetCellAttrPtr(row, col)->GetFont(); } void wxGrid::GetCellAlignment( int row, int col, int *horiz, int *vert ) const { - wxGridCellAttr *attr = GetCellAttr(row, col); - attr->GetAlignment(horiz, vert); - attr->DecRef(); + return GetCellAttrPtr(row, col)->GetAlignment(horiz, vert); } wxGridFitMode wxGrid::GetCellFitMode( int row, int col ) const { - wxGridCellAttr *attr = GetCellAttr(row, col); - wxGridFitMode fitMode = attr->GetFitMode(); - attr->DecRef(); - - return fitMode; + return GetCellAttrPtr(row, col)->GetFitMode(); } wxGrid::CellSpan wxGrid::GetCellSize( int row, int col, int *num_rows, int *num_cols ) const { - wxGridCellAttr *attr = GetCellAttr(row, col); - attr->GetSize( num_rows, num_cols ); - attr->DecRef(); + GetCellAttrPtr(row, col)->GetSize( num_rows, num_cols ); if ( *num_rows == 1 && *num_cols == 1 ) return CellSpan_None; // just a normal cell @@ -8689,29 +8648,17 @@ wxGrid::GetCellSize( int row, int col, int *num_rows, int *num_cols ) const wxGridCellRenderer* wxGrid::GetCellRenderer(int row, int col) const { - wxGridCellAttr* attr = GetCellAttr(row, col); - wxGridCellRenderer* renderer = attr->GetRenderer(this, row, col); - attr->DecRef(); - - return renderer; + return GetCellAttrPtr(row, col)->GetRenderer(this, row, col); } wxGridCellEditor* wxGrid::GetCellEditor(int row, int col) const { - wxGridCellAttr* attr = GetCellAttr(row, col); - wxGridCellEditor* editor = attr->GetEditor(this, row, col); - attr->DecRef(); - - return editor; + return GetCellAttrPtr(row, col)->GetEditor(this, row, col); } bool wxGrid::IsReadOnly(int row, int col) const { - wxGridCellAttr* attr = GetCellAttr(row, col); - bool isReadOnly = attr->IsReadOnly(); - attr->DecRef(); - - return isReadOnly; + return GetCellAttrPtr(row, col)->IsReadOnly(); } // ---------------------------------------------------------------------------- @@ -8932,9 +8879,7 @@ void wxGrid::SetCellBackgroundColour( int row, int col, const wxColour& colour ) { if ( CanHaveAttributes() ) { - wxGridCellAttr *attr = GetOrCreateCellAttr(row, col); - attr->SetBackgroundColour(colour); - attr->DecRef(); + GetOrCreateCellAttrPtr(row, col)->SetBackgroundColour(colour); } } @@ -8942,9 +8887,7 @@ void wxGrid::SetCellTextColour( int row, int col, const wxColour& colour ) { if ( CanHaveAttributes() ) { - wxGridCellAttr *attr = GetOrCreateCellAttr(row, col); - attr->SetTextColour(colour); - attr->DecRef(); + GetOrCreateCellAttrPtr(row, col)->SetTextColour(colour); } } @@ -8952,9 +8895,7 @@ void wxGrid::SetCellFont( int row, int col, const wxFont& font ) { if ( CanHaveAttributes() ) { - wxGridCellAttr *attr = GetOrCreateCellAttr(row, col); - attr->SetFont(font); - attr->DecRef(); + GetOrCreateCellAttrPtr(row, col)->SetFont(font); } } @@ -8962,9 +8903,7 @@ void wxGrid::SetCellAlignment( int row, int col, int horiz, int vert ) { if ( CanHaveAttributes() ) { - wxGridCellAttr *attr = GetOrCreateCellAttr(row, col); - attr->SetAlignment(horiz, vert); - attr->DecRef(); + GetOrCreateCellAttrPtr(row, col)->SetAlignment(horiz, vert); } } @@ -8972,9 +8911,7 @@ void wxGrid::SetCellFitMode( int row, int col, wxGridFitMode fitMode ) { if ( CanHaveAttributes() ) { - wxGridCellAttr *attr = GetOrCreateCellAttr(row, col); - attr->SetFitMode(fitMode); - attr->DecRef(); + GetOrCreateCellAttrPtr(row, col)->SetFitMode(fitMode); } } @@ -8984,10 +8921,9 @@ void wxGrid::SetCellSize( int row, int col, int num_rows, int num_cols ) { int cell_rows, cell_cols; - wxGridCellAttr *attr = GetOrCreateCellAttr(row, col); + wxGridCellAttrPtr attr = GetOrCreateCellAttrPtr(row, col); attr->GetSize(&cell_rows, &cell_cols); attr->SetSize(num_rows, num_cols); - attr->DecRef(); // Cannot set the size of a cell to 0 or negative values // While it is perfectly legal to do that, this function cannot @@ -9008,9 +8944,7 @@ void wxGrid::SetCellSize( int row, int col, int num_rows, int num_cols ) { if ((i != col) || (j != row)) { - wxGridCellAttr *attr_stub = GetOrCreateCellAttr(j, i); - attr_stub->SetSize( 1, 1 ); - attr_stub->DecRef(); + GetOrCreateCellAttrPtr(j, i)->SetSize( 1, 1 ); } } } @@ -9027,9 +8961,7 @@ void wxGrid::SetCellSize( int row, int col, int num_rows, int num_cols ) { if ((i != col) || (j != row)) { - wxGridCellAttr *attr_stub = GetOrCreateCellAttr(j, i); - attr_stub->SetSize( row - j, col - i ); - attr_stub->DecRef(); + GetOrCreateCellAttrPtr(j, i)->SetSize( row - j, col - i ); } } } @@ -9041,9 +8973,7 @@ void wxGrid::SetCellRenderer(int row, int col, wxGridCellRenderer *renderer) { if ( CanHaveAttributes() ) { - wxGridCellAttr *attr = GetOrCreateCellAttr(row, col); - attr->SetRenderer(renderer); - attr->DecRef(); + GetOrCreateCellAttrPtr(row, col)->SetRenderer(renderer); } } @@ -9051,9 +8981,7 @@ void wxGrid::SetCellEditor(int row, int col, wxGridCellEditor* editor) { if ( CanHaveAttributes() ) { - wxGridCellAttr *attr = GetOrCreateCellAttr(row, col); - attr->SetEditor(editor); - attr->DecRef(); + GetOrCreateCellAttrPtr(row, col)->SetEditor(editor); } } @@ -9061,9 +8989,7 @@ void wxGrid::SetReadOnly(int row, int col, bool isReadOnly) { if ( CanHaveAttributes() ) { - wxGridCellAttr *attr = GetOrCreateCellAttr(row, col); - attr->SetReadOnly(isReadOnly); - attr->DecRef(); + GetOrCreateCellAttrPtr(row, col)->SetReadOnly(isReadOnly); } } @@ -9548,7 +9474,7 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction) } // get cell ( main cell if CellSpan_Inside ) renderer best size - wxGridCellAttr *attr = GetCellAttr(row, col); + wxGridCellAttrPtr attr = GetCellAttrPtr(row, col); wxGridCellRenderer *renderer = attr->GetRenderer(this, row, col); if ( renderer ) { @@ -9575,8 +9501,6 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction) renderer->DecRef(); } - - attr->DecRef(); } // now also compare with the column label extent