diff options
author | David Tardon <dtardon@redhat.com> | 2013-05-16 15:27:08 +0200 |
---|---|---|
committer | David Tardon <dtardon@redhat.com> | 2013-05-24 12:47:13 +0200 |
commit | 02d03eb4ad6e64744659c5fe04282b25b66c28d8 (patch) | |
tree | 6bf0d1ca1157276a340a0018bd2227967c9ca162 /svx | |
parent | 9ae9b2f665b3caa9cc584512c26dfa899e1d2d45 (diff) |
fdo#64279 do not crash opening report for editing
There are two problems:
1) The classes derived from SdrObject cache their SvxShape, but do not
implement impl_setUnoShape().
2) There is a lifetime issue in association of a SdrObject and its
SvxShape. SvxDrawPage::CreateSdrObject not only creates a new SdrObject
for a shape, but also inserts it into the page. At this point, the shape
has not been attached to the object yet. That means that the object
creates another shape at one point during the InsertObject call,
which is then destroyed again. But reportdesign shapes own their
objects, which means that destuction of the shape causes destruction
of the object too...
My first idea was to disable the insertion in
SvxDrawPage::CreateSdrObject, but it has been there since the dawn of
time, so I did not gather the courage to do that. Instead, I put in a
hack to allow to skip the insertion.
Change-Id: I888a54067be1934578434d8b476a13a7ff8d02b3
Diffstat (limited to 'svx')
-rw-r--r-- | svx/source/svdraw/svdobj.cxx | 19 | ||||
-rw-r--r-- | svx/source/unodraw/unopage.cxx | 14 |
2 files changed, 30 insertions, 3 deletions
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index 7052004d5242..0577860bc0bf 100644 --- a/svx/source/svdraw/svdobj.cxx +++ b/svx/source/svdraw/svdobj.cxx @@ -423,6 +423,7 @@ SdrObject::SdrObject() ,mnLayerID(0) ,mpSvxShape( NULL ) ,maWeakUnoShape() + ,mbDoNotInsertIntoPageAutomatically(false) { DBG_CTOR(SdrObject,NULL); bVirtObj =false; @@ -497,6 +498,8 @@ SdrObject::~SdrObject() delete mpViewContact; mpViewContact = 0L; } + + mnLayerID = static_cast<SdrLayerID>(0xdead); } void SdrObject::Free( SdrObject*& _rpObject ) @@ -585,7 +588,11 @@ void SdrObject::SetPage(SdrPage* pNewPage) // assume they create compatible UNO shape objects so we shouldn't have // to invalidate. if (pOldPage != pPage && !(pOldPage && pPage && pOldModel == pModel)) - setUnoShape(NULL); + { + SvxShape* const pShape(getSvxShape()); + if (pShape && !pShape->HasSdrObjectOwnership()) + setUnoShape(NULL); + } } SdrPage* SdrObject::GetPage() const @@ -3223,6 +3230,16 @@ void SdrObject::SetContextWritingMode( const sal_Int16 /*_nContextWritingMode*/ // this base class does not support different writing modes, so ignore the call } +void SdrObject::SetDoNotInsertIntoPageAutomatically(const bool bSet) +{ + mbDoNotInsertIntoPageAutomatically = bSet; +} + +bool SdrObject::IsDoNotInsertIntoPageAutomatically() const +{ + return mbDoNotInsertIntoPageAutomatically; +} + SdrObjFactory::SdrObjFactory(sal_uInt32 nInvent, sal_uInt16 nIdent, SdrPage* pNewPage, SdrModel* pNewModel) { diff --git a/svx/source/unodraw/unopage.cxx b/svx/source/unodraw/unopage.cxx index df6e8ba547a1..4cd98006ff1e 100644 --- a/svx/source/unodraw/unopage.cxx +++ b/svx/source/unodraw/unopage.cxx @@ -242,6 +242,12 @@ void SAL_CALL SvxDrawPage::add( const uno::Reference< drawing::XShape >& xShape pShape->Create( pObj, this ); OSL_ENSURE( pShape->GetSdrObject() == pObj, "SvxDrawPage::add: shape does not know about its newly created SdrObject!" ); + if ( !pObj->IsInserted() ) + { + pObj->SetModel(mpModel); + mpPage->InsertObject( pObj ); + } + mpModel->SetChanged(); } @@ -835,8 +841,12 @@ Reference< drawing::XShape > SvxDrawPage::_CreateShape( SdrObject *pObj ) const SdrObject *SvxDrawPage::CreateSdrObject( const Reference< drawing::XShape > & xShape ) throw() { SdrObject* pObj = _CreateSdrObject( xShape ); - if( pObj && !pObj->IsInserted() ) - mpPage->InsertObject( pObj ); + if( pObj) + { + pObj->SetModel(mpModel); + if ( !pObj->IsInserted() && !pObj->IsDoNotInsertIntoPageAutomatically() ) + mpPage->InsertObject( pObj ); + } return pObj; } |