diff options
author | Armin Le Grand <Armin.Le.Grand@cib.de> | 2018-04-05 20:01:28 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@cib.de> | 2018-04-06 18:21:36 +0200 |
commit | 7da1d824837c48aa4f53ae0c3fb344616d8b0284 (patch) | |
tree | e6e05acb31b92e29ac3faa36d336daaa3f0c142a | |
parent | SOSAW080: Free SdrObjects when SdrModel goes down (diff) | |
download | core-feature/SOSAW080.tar.gz core-feature/SOSAW080.zip |
SOSAW080: Solve UNO API calls that move SvxShapes to other Model
feature/SOSAW080
Due to UNO API tests I got a call to insert an xShape to a
xDrawPage which was constructed in another Model, this has now to
be done by Cloning the SdrObject to the new SdrModel, getting
rid of the old one and getting all the UNO implementation
stuff right (referemces SdrObject <-> xShape).
Change-Id: Ibf097ee7467895823fbd158a2a9543da3b5a5078
-rw-r--r-- | svx/source/svdraw/svdobj.cxx | 7 | ||||
-rw-r--r-- | svx/source/unodraw/unopage.cxx | 31 |
2 files changed, 38 insertions, 0 deletions
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index b5dd038d5622..490af4051362 100644 --- a/svx/source/svdraw/svdobj.cxx +++ b/svx/source/svdraw/svdobj.cxx @@ -438,6 +438,13 @@ void SdrObject::SetPage(SdrPage* pNewPage) // If the page is changing to another page with the same model, we // assume they create compatible UNO shape objects so we shouldn't have // to invalidate. + // TTTT: This causes quite some problems in SvxDrawPage::add when used + // e.g. from Writer - the SdrObject may be cloned to target model, and + // the xShape was added to it by purpose (see there). Thus it will be + // good to think about if this is really needed - it *seems* to be intended + // for a xShape being a on-demand-creatable resource - wit hthe argument that + // the SdrPage/UnoPage used influences the SvxShape creation. This uses + // ressources and would be nice to get rid of anyways. if (pOldPage != pPage && !(pOldPage && pPage && pOldModel == &getSdrModelFromSdrObject())) { SvxShape* const pShape(getSvxShape()); diff --git a/svx/source/unodraw/unopage.cxx b/svx/source/unodraw/unopage.cxx index f35a104f6da5..3dc69e899965 100644 --- a/svx/source/unodraw/unopage.cxx +++ b/svx/source/unodraw/unopage.cxx @@ -191,6 +191,24 @@ void SAL_CALL SvxDrawPage::add( const uno::Reference< drawing::XShape >& xShape return; SdrObject *pObj = pShape->GetSdrObject(); + bool bNeededToClone(false); + + if(nullptr != pObj && &pObj->getSdrModelFromSdrObject() != &mpPage->getSdrModelFromSdrPage()) + { + // TTTT UNO API tries to add an existing SvxShape to this SvxDrawPage, + // but these use different SdrModels. It was possible before to completely + // 'change' a SdrObject to another SdrModel (including dangerous MigrateItemPool + // stuff), but is no longer. We need to Clone the SdrObject to the target model + // and ::Create a new SvxShape (set SdrObject there, take obver values, ...) + SdrObject* pClonedSdrShape(pObj->Clone(&mpPage->getSdrModelFromSdrPage())); + pObj->setUnoShape(nullptr); + pClonedSdrShape->setUnoShape(xShape); + // pShape->InvalidateSdrObject(); + // pShape->Create(pClonedSdrShape, this); + SdrObject::Free(pObj); + pObj = pClonedSdrShape; + bNeededToClone = true; + } if(!pObj) { @@ -200,6 +218,19 @@ void SAL_CALL SvxDrawPage::add( const uno::Reference< drawing::XShape >& xShape else if ( !pObj->IsInserted() ) { mpPage->InsertObject( pObj ); + + if(bNeededToClone) + { + // TTTT Unfortunately in SdrObject::SetPage (see there) the + // xShape/UnoShape at the newly cloned SDrObject is *removed* again, + // so re-set it here, the caller *may need it* (e.g. Writer) + uno::Reference< uno::XInterface > xShapeCheck(pObj->getWeakUnoShape()); + + if( !xShapeCheck.is() ) + { + pObj->setUnoShape(xShape); + } + } } pShape->Create( pObj, this ); |