reportdesign/inc/RptObject.hxx | 8 +++++++- reportdesign/source/core/sdr/RptObject.cxx | 25 +++++++++++++++++++------ reportdesign/source/core/sdr/RptPage.cxx | 7 +++++++ svx/source/unodraw/unoprov.cxx | 2 +- 4 files changed, 34 insertions(+), 8 deletions(-)
New commits: commit 521d438c41b2ac59bffc94763d1a2cb568ff9a60 Author: Noel Grandin <[email protected]> AuthorDate: Fri Sep 9 11:37:57 2022 +0200 Commit: Noel Grandin <[email protected]> CommitDate: Fri Sep 9 14:45:52 2022 +0200 tdf#150732 ReportBuilder: Moving fields from one section to another crashes regression from commit 8611f6e259b807b4f19c8dc0eab86ca648891ce3 Author: Noel Grandin <[email protected]> Date: Thu May 27 10:27:46 2021 +0200 ref-count SdrObject Fixes 2 issues (1) where I removed some code that we need (2) where the OUnoObject constructor was deleting the object is was constructing Note that this only fixes the crash that Julien saw, not the underlying problem that this tdf bug reports. That bug appears to predate my commit. Change-Id: I3878ef460dedc3c2a6c86b88fce9d155e79bc0b8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139714 Tested-by: Julien Nabet <[email protected]> Reviewed-by: Julien Nabet <[email protected]> Tested-by: Jenkins Reviewed-by: Noel Grandin <[email protected]> diff --git a/reportdesign/inc/RptObject.hxx b/reportdesign/inc/RptObject.hxx index 566dc20a13fc..c2ffe7176331 100644 --- a/reportdesign/inc/RptObject.hxx +++ b/reportdesign/inc/RptObject.hxx @@ -66,6 +66,7 @@ protected: mutable rtl::Reference<OPropertyMediator> m_xMediator; mutable css::uno::Reference< css::beans::XPropertyChangeListener> m_xPropertyChangeListener; mutable css::uno::Reference< css::report::XReportComponent> m_xReportComponent; + css::uno::Reference< css::uno::XInterface > m_xKeepShapeAlive; OUString m_sComponentName; bool m_bIsListening; @@ -82,7 +83,7 @@ protected: /** called by instances of derived classes to implement their overriding of getUnoShape */ - static css::uno::Reference< css::drawing::XShape > + css::uno::Reference< css::drawing::XShape > getUnoShapeOf( SdrObject& _rSdrObject ); public: @@ -102,6 +103,10 @@ public: css::uno::Reference< css::report::XSection> getSection() const; const OUString& getServiceName() const { return m_sComponentName; } + /** releases the reference to our UNO shape (m_xKeepShapeAlive) + */ + void releaseUnoShape() { m_xKeepShapeAlive.clear(); } + static rtl::Reference<SdrObject> createObject( SdrModel& rTargetModel, const css::uno::Reference< css::report::XReportComponent>& _xComponent); @@ -263,6 +268,7 @@ public: virtual rtl::Reference<SdrObject> CloneSdrObject(SdrModel& rTargetModel) const override; private: + virtual void setUnoShape( const css::uno::Reference< css::drawing::XShape >& rxUnoShape ) override; void impl_initializeModel_nothrow(); }; diff --git a/reportdesign/source/core/sdr/RptObject.cxx b/reportdesign/source/core/sdr/RptObject.cxx index dde0896855b2..e54db1ee3fe1 100644 --- a/reportdesign/source/core/sdr/RptObject.cxx +++ b/reportdesign/source/core/sdr/RptObject.cxx @@ -423,6 +423,7 @@ uno::Reference< drawing::XShape > OObjectBase::getUnoShapeOf( SdrObject& _rSdrOb if ( !xShape.is() ) return xShape; + m_xKeepShapeAlive = xShape; return xShape; } @@ -540,6 +541,7 @@ uno::Reference< drawing::XShape > OCustomShape::getUnoShape() void OCustomShape::setUnoShape( const uno::Reference< drawing::XShape >& rxUnoShape ) { SdrObjCustomShape::setUnoShape( rxUnoShape ); + releaseUnoShape(); m_xReportComponent.clear(); } @@ -566,12 +568,16 @@ OUnoObject::OUnoObject( // tdf#119067 ,m_bSetDefaultLabel(rSource.m_bSetDefaultLabel) { - if ( !rSource.getUnoControlModelTypeName().isEmpty() ) - impl_initializeModel_nothrow(); - Reference<XPropertySet> xSource(const_cast<OUnoObject&>(rSource).getUnoShape(), uno::UNO_QUERY); - Reference<XPropertySet> xDest(getUnoShape(), uno::UNO_QUERY); - if ( xSource.is() && xDest.is() ) - comphelper::copyProperties(xSource, xDest); + osl_atomic_increment(&m_refCount); // getUnoShape will ref-count thiss + { + if ( !rSource.getUnoControlModelTypeName().isEmpty() ) + impl_initializeModel_nothrow(); + Reference<XPropertySet> xSource(const_cast<OUnoObject&>(rSource).getUnoShape(), uno::UNO_QUERY); + Reference<XPropertySet> xDest(getUnoShape(), uno::UNO_QUERY); + if ( xSource.is() && xDest.is() ) + comphelper::copyProperties(xSource, xDest); + } + osl_atomic_decrement(&m_refCount); } OUnoObject::OUnoObject( @@ -867,6 +873,12 @@ uno::Reference< drawing::XShape > OUnoObject::getUnoShape() return OObjectBase::getUnoShapeOf( *this ); } +void OUnoObject::setUnoShape( const uno::Reference< drawing::XShape >& rxUnoShape ) +{ + SdrUnoObj::setUnoShape( rxUnoShape ); + releaseUnoShape(); +} + rtl::Reference<SdrObject> OUnoObject::CloneSdrObject(SdrModel& rTargetModel) const { return new OUnoObject(rTargetModel, *this); @@ -1060,6 +1072,7 @@ uno::Reference< drawing::XShape > OOle2Obj::getUnoShape() void OOle2Obj::setUnoShape( const uno::Reference< drawing::XShape >& rxUnoShape ) { SdrOle2Obj::setUnoShape( rxUnoShape ); + releaseUnoShape(); m_xReportComponent.clear(); } diff --git a/reportdesign/source/core/sdr/RptPage.cxx b/reportdesign/source/core/sdr/RptPage.cxx index 0132ccf725a2..98b8ef8741bb 100644 --- a/reportdesign/source/core/sdr/RptPage.cxx +++ b/reportdesign/source/core/sdr/RptPage.cxx @@ -178,6 +178,13 @@ void OReportPage::NbcInsertObject(SdrObject* pObj, size_t nPos) reportdesign::OSection* pSection = comphelper::getFromUnoTunnel<reportdesign::OSection>(m_xSection); uno::Reference< drawing::XShape> xShape(pObj->getUnoShape(),uno::UNO_QUERY); pSection->notifyElementAdded(xShape); + + // now that the shape is inserted into its structures, we can allow the OObjectBase + // to release the reference to it + OObjectBase* pObjectBase = dynamic_cast< OObjectBase* >( pObj ); + OSL_ENSURE( pObjectBase, "OReportPage::NbcInsertObject: what is being inserted here?" ); + if ( pObjectBase ) + pObjectBase->releaseUnoShape(); } } // rptui diff --git a/svx/source/unodraw/unoprov.cxx b/svx/source/unodraw/unoprov.cxx index 074d584566db..7eaa1053f9e5 100644 --- a/svx/source/unodraw/unoprov.cxx +++ b/svx/source/unodraw/unoprov.cxx @@ -838,7 +838,7 @@ OUString UHashMap::getNameFromId(SdrObjKind nId) [nId](const UHashMapImpl::value_type& rEntry) { return rEntry.second == nId; }); if (it != rMap.end()) return it->first; - OSL_FAIL("[CL] unknown SdrObject identifier"); + SAL_WARN("svx", "[CL] unknown SdrObjKind identifier " << static_cast<int>(nId)); return OUString(); }
