include/svx/svdoole2.hxx | 2 ++ sd/qa/unit/export-tests-ooxml4.cxx | 12 ++++++++++++ svx/source/svdraw/svdoole2.cxx | 5 ++++- svx/source/unodraw/unoshape.cxx | 10 ++++++++++ xmloff/source/draw/ximpshap.cxx | 8 ++++++++ 5 files changed, 36 insertions(+), 1 deletion(-)
New commits: commit 7d89a348fbd4a7705fe03688041fff0a27398afe Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Sat Nov 30 16:00:05 2024 +0500 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Sat Nov 30 14:23:22 2024 +0100 tdf#164101: avoid incorrect OLE object scaling during loading Use an internal property for that, alowing to pass the option from the import site to SdrOle2Obj::AddOwnLightClient. Maybe there is some more proper way to do this, but I couldn't find it. Change-Id: I74c881c5c35689a7b58d44d8d65c1010d202c98d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177586 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/include/svx/svdoole2.hxx b/include/svx/svdoole2.hxx index aa56e05f3e0c..f116765a16ce 100644 --- a/include/svx/svdoole2.hxx +++ b/include/svx/svdoole2.hxx @@ -185,6 +185,8 @@ public: virtual rtl::Reference<SdrObject> DoConvertToPolyObj(bool bBezier, bool bAddText) const override; virtual bool IsSdrOle2Obj() const final { return true; } + + void SetIgnoreOLEObjectScale(bool val); }; class SVXCORE_DLLPUBLIC SdrEmbedObjectLink final : public sfx2::SvBaseLink diff --git a/sd/qa/unit/export-tests-ooxml4.cxx b/sd/qa/unit/export-tests-ooxml4.cxx index b2d95ec8b06e..9513b3ae5e61 100644 --- a/sd/qa/unit/export-tests-ooxml4.cxx +++ b/sd/qa/unit/export-tests-ooxml4.cxx @@ -1216,6 +1216,12 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testTdf163483_export_math_fallback) auto xProps = getShapeFromPage(0, 0); auto xInfo = xProps->getPropertyValue(u"Model"_ustr).queryThrow<css::lang::XServiceInfo>(); CPPUNIT_ASSERT(xInfo->supportsService(u"com.sun.star.formula.FormulaProperties"_ustr)); + + // tdf#164101: check that the size is imported correctly + css::awt::Size formulaSize = xProps.queryThrow<css::drawing::XShape>()->getSize(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1553), formulaSize.Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(528), formulaSize.Height); + CPPUNIT_ASSERT_THROW(getShapeFromPage(0, 1), css::lang::IndexOutOfBoundsException); // Only one shape on page } @@ -1229,6 +1235,12 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testTdf163483_export_math_fallback) // and no shape got imported. auto xInfo = getShapeFromPage(0, 0).queryThrow<css::lang::XServiceInfo>(); CPPUNIT_ASSERT(xInfo->supportsService(u"com.sun.star.drawing.CustomShape"_ustr)); + + css::awt::Size formulaSize = xInfo.queryThrow<css::drawing::XShape>()->getSize(); + // The fallback image size after the roundtrip may be a bit different - allow some tolerance + CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(1553), formulaSize.Width, 1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(528), formulaSize.Height, 1); + CPPUNIT_ASSERT_THROW(getShapeFromPage(0, 1), css::lang::IndexOutOfBoundsException); // Only one shape on page } diff --git a/svx/source/svdraw/svdoole2.cxx b/svx/source/svdraw/svdoole2.cxx index 2d123a6a360e..9e87d9be3b74 100644 --- a/svx/source/svdraw/svdoole2.cxx +++ b/svx/source/svdraw/svdoole2.cxx @@ -638,6 +638,7 @@ public: mutable bool mbIsChart:1; bool mbLoadingOLEObjectFailed:1; // New local var to avoid repeated loading if load of OLE2 fails bool mbConnected:1; + bool mbIgnoreOLEObjectScale : 1 = false; // See SdXMLObjectShapeContext::createFastChildContext sfx2::SvBaseLink* mpObjectLink; OUString maLinkURL; @@ -1948,6 +1949,8 @@ bool SdrOle2Obj::CalculateNewScaling( Fraction& aScaleWidth, Fraction& aScaleHei return true; } +void SdrOle2Obj::SetIgnoreOLEObjectScale(bool val) { mpImpl->mbIgnoreOLEObjectScale = val; } + bool SdrOle2Obj::AddOwnLightClient() { // The Own Light Client must be registered in object only using this method! @@ -1956,7 +1959,7 @@ bool SdrOle2Obj::AddOwnLightClient() { Connect(); - if ( mpImpl->mxObjRef.is() && mpImpl->mxLightClient.is() ) + if (!mpImpl->mbIgnoreOLEObjectScale && mpImpl->mxObjRef.is() && mpImpl->mxLightClient.is()) { Fraction aScaleWidth; Fraction aScaleHeight; diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx index 04171a9ae81b..9ae9b9d69e09 100644 --- a/svx/source/unodraw/unoshape.cxx +++ b/svx/source/unodraw/unoshape.cxx @@ -1504,6 +1504,16 @@ void SvxShape::_setPropertyValue( const OUString& rPropertyName, const uno::Any& return; } + // A hack to avoid taking incomplete OLE object's size into account when loading + // see SdXMLObjectShapeContext::createFastChildContext + if (rPropertyName == "IgnoreOLEObjectScale") + { + if (auto pOleObj = DynCastSdrOle2Obj(GetSdrObject())) + if (bool bVal; rVal >>= bVal) + pOleObj->SetIgnoreOLEObjectScale(bVal); + return; + } + if (!pMap) throw beans::UnknownPropertyException( rPropertyName, getXWeak()); diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx index 79117cc9fe8f..dbaefd30b95c 100644 --- a/xmloff/source/draw/ximpshap.cxx +++ b/xmloff/source/draw/ximpshap.cxx @@ -2789,8 +2789,16 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLObjectShapeContex { xPropSet->setPropertyValue(u"CLSID"_ustr, uno::Any( maCLSID ) ); + // A hack: getting the model of newly created OLE object will eventually call + // SdrOle2Obj::AddOwnLightClient, which will try to update scaling, using the + // incomplete object data. Avoid that by setting the special property. + xPropSet->setPropertyValue(u"IgnoreOLEObjectScale"_ustr, uno::Any(true)); + uno::Reference< lang::XComponent > xComp; xPropSet->getPropertyValue(u"Model"_ustr) >>= xComp; + + xPropSet->setPropertyValue(u"IgnoreOLEObjectScale"_ustr, uno::Any(false)); + SAL_WARN_IF( !xComp.is(), "xmloff", "no xModel for own OLE format" ); xEContext->SetComponent(xComp); }