Kaydet (Commit) 02d03eb4 authored tarafından David Tardon's avatar David Tardon

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
üst 9ae9b2f6
......@@ -1055,6 +1055,11 @@ public:
Rectangle GetBLIPSizeRectangle() const;
void SetBLIPSizeRectangle( const Rectangle& aRect );
/// @see mbDoNotInsertIntoPageAutomatically
void SetDoNotInsertIntoPageAutomatically(bool bSet);
/// @see mbDoNotInsertIntoPageAutomatically
bool IsDoNotInsertIntoPageAutomatically() const;
protected:
/** Sets a new UNO shape
*
......@@ -1082,6 +1087,11 @@ private:
SvxShape* mpSvxShape;
::com::sun::star::uno::WeakReference< ::com::sun::star::uno::XInterface >
maWeakUnoShape;
/** HACK: Do not automatically insert newly created object into a page.
*
* The user needs to do it manually later.
*/
bool mbDoNotInsertIntoPageAutomatically;
};
//************************************************************
......
......@@ -169,6 +169,9 @@ public:
virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getUnoShape();
virtual sal_uInt16 GetObjIdentifier() const;
virtual sal_uInt32 GetObjInventor() const;
private:
virtual void impl_setUnoShape( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxUnoShape );
};
//============================================================================
......@@ -182,6 +185,8 @@ class REPORTDESIGN_DLLPUBLIC OOle2Obj: public SdrOle2Obj , public OObjectBase
sal_uInt16 m_nType;
bool m_bOnlyOnce;
void impl_createDataProvider_nothrow( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel>& _xModel);
virtual void impl_setUnoShape( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxUnoShape );
public:
static OOle2Obj* Create( const ::com::sun::star::uno::Reference< ::com::sun::star::report::XReportComponent>& _xComponent,sal_uInt16 _nType )
{
......@@ -271,6 +276,7 @@ public:
OUnoObject& operator=(const OUnoObject& rObj);
private:
virtual void impl_setUnoShape( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxUnoShape );
void impl_setReportComponent_nothrow();
void impl_initializeModel_nothrow();
};
......
......@@ -166,6 +166,9 @@ SdrObject* OObjectBase::createObject(const uno::Reference< report::XReportCompon
break;
}
if ( pNewObj )
pNewObj->SetDoNotInsertIntoPageAutomatically( true );
ensureSdrObjectOwnership( _xComponent );
return pNewObj;
......@@ -609,6 +612,13 @@ uno::Reference< uno::XInterface > OCustomShape::getUnoShape()
return xShape;
}
void OCustomShape::impl_setUnoShape( const uno::Reference< uno::XInterface >& rxUnoShape )
{
SdrObjCustomShape::impl_setUnoShape( rxUnoShape );
releaseUnoShape();
m_xReportComponent.clear();
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
TYPEINIT1(OUnoObject, SdrUnoObj);
......@@ -932,6 +942,12 @@ uno::Reference< uno::XInterface > OUnoObject::getUnoShape()
return OObjectBase::getUnoShapeOf( *this );
}
void OUnoObject::impl_setUnoShape( const uno::Reference< uno::XInterface >& rxUnoShape )
{
SdrUnoObj::impl_setUnoShape( rxUnoShape );
releaseUnoShape();
}
OUnoObject& OUnoObject::operator=(const OUnoObject& rObj)
{
if( this == &rObj )
......@@ -1135,6 +1151,14 @@ uno::Reference< uno::XInterface > OOle2Obj::getUnoShape()
}
return xShape;
}
void OOle2Obj::impl_setUnoShape( const uno::Reference< uno::XInterface >& rxUnoShape )
{
SdrOle2Obj::impl_setUnoShape( rxUnoShape );
releaseUnoShape();
m_xReportComponent.clear();
}
// -----------------------------------------------------------------------------
uno::Reference< chart2::data::XDatabaseDataProvider > lcl_getDataProvider(const uno::Reference < embed::XEmbeddedObject >& _xObj)
{
......
......@@ -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)
{
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment