svx/source/svdraw/svdobj.cxx | 7 +++++++ svx/source/unodraw/unopage.cxx | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+)
New commits: commit ea916073d89eddffd3231d8e4a4ffe1a671d5fe5 Author: Armin Le Grand <[email protected]> Date: Thu Apr 5 20:01:28 2018 +0200 SOSAW080: Solve UNO API calls that move SvxShapes to other Model 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 diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index d1dc3a339ac0..ee59161c757c 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 ); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
