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);
             }

Reply via email to