summaryrefslogtreecommitdiff
path: root/reportdesign
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2022-09-09 11:37:57 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2022-09-09 14:45:52 +0200
commit521d438c41b2ac59bffc94763d1a2cb568ff9a60 (patch)
tree846fb05a51d217a703c44083a8dc44b296c5a3a7 /reportdesign
parentfabfa4bd23e89a2d5b6e232cd2eab61996534659 (diff)
tdf#150732 ReportBuilder: Moving fields from one section to another crashes
regression from commit 8611f6e259b807b4f19c8dc0eab86ca648891ce3 Author: Noel Grandin <noel.grandin@collabora.co.uk> 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 <serval2412@yahoo.fr> Reviewed-by: Julien Nabet <serval2412@yahoo.fr> Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'reportdesign')
-rw-r--r--reportdesign/inc/RptObject.hxx8
-rw-r--r--reportdesign/source/core/sdr/RptObject.cxx25
-rw-r--r--reportdesign/source/core/sdr/RptPage.cxx7
3 files changed, 33 insertions, 7 deletions
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