tdf#99631 DOCX import: keep zoom of embedded XLSX

OLE objects by importing their VisibleArea settings

This also reverts commit 5c1a6c9adb5ccfbb869a0a7ac730d8860a1bf405
"tdf#99631 DOCX import: set 1:1 scale in embedded XLSX".

Change-Id: I73dc945c86d0200e72767810b2ff39f233729080
Reviewed-on: https://gerrit.libreoffice.org/65343
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h
index d829c3d..28a13ea 100644
--- a/sw/inc/cmdid.h
+++ b/sw/inc/cmdid.h
@@ -599,6 +599,8 @@
#define FN_UNO_HIDDEN                       (FN_EXTRA2 + 122)
#define FN_UNO_STYLE_INTEROP_GRAB_BAG       (FN_EXTRA2 + 123)
#define FN_UNO_TABLE_TEMPLATE_NAME          (FN_EXTRA2 + 124)
#define FN_UNO_VISIBLE_AREA_WIDTH           (FN_EXTRA2 + 125)
#define FN_UNO_VISIBLE_AREA_HEIGHT          (FN_EXTRA2 + 126)

// Area: Help
// Region: Traveling & Selection
diff --git a/sw/inc/unoframe.hxx b/sw/inc/unoframe.hxx
index 41dc329..43876e9 100644
--- a/sw/inc/unoframe.hxx
+++ b/sw/inc/unoframe.hxx
@@ -72,6 +72,8 @@ private:
    std::unique_ptr<SwPaM>          m_pCopySource;

    sal_Int64                       m_nDrawAspect;
    sal_Int64                       m_nVisibleAreaWidth;
    sal_Int64                       m_nVisibleAreaHeight;

protected:
    css::uno::Reference< css::beans::XPropertySet > mxStyleData;
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 3e03839..b2de700d 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -822,6 +822,8 @@
#define UNO_NAME_RSID "Rsid"
#define UNO_NAME_PARRSID "ParRsid"
#define UNO_NAME_DRAW_ASPECT "DrawAspect"
#define UNO_NAME_VISIBLE_AREA_WIDTH "VisibleAreaWidth"
#define UNO_NAME_VISIBLE_AREA_HEIGHT "VisibleAreaHeight"

#define UNO_NAME_LINE_STYLE "LineStyle"
#define UNO_NAME_LINE_WIDTH "LineWidth"
diff --git a/sw/qa/extras/odfexport/data/tdf99631.docx b/sw/qa/extras/odfexport/data/tdf99631.docx
index 7fcb612..c72950b 100644
--- a/sw/qa/extras/odfexport/data/tdf99631.docx
+++ b/sw/qa/extras/odfexport/data/tdf99631.docx
Binary files differ
diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index c8468eb..8e3df22 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -2125,12 +2125,18 @@ DECLARE_ODFEXPORT_TEST(tdf118502, "tdf118502.odt")

DECLARE_ODFEXPORT_TEST(tdf99631, "tdf99631.docx")
{
    // File asserting while saving in LO.
    // check import of VisualArea settings of the embedded XLSX OLE objects
    xmlDocPtr pXmlDoc = parseExport("Object 1/settings.xml");
    if (!pXmlDoc)
        return;
    assertXPathContent(pXmlDoc, "//config:config-item[@config:name='VisibleAreaWidth']", "4515");
    assertXPathContent(pXmlDoc, "//config:config-item[@config:name='VisibleAreaHeight']", "903");

    xmlDocPtr pXmlDoc2 = parseExport("Object 2/settings.xml");
    if (!pXmlDoc2)
        return;
    assertXPathContent(pXmlDoc2, "//config:config-item[@config:name='VisibleAreaWidth']", "4515");
    assertXPathContent(pXmlDoc2, "//config:config-item[@config:name='VisibleAreaHeight']", "1354");
}
#endif

diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx
index a6edcfd..d63bd91 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -1138,7 +1138,9 @@ bool SwOLEProperties_Impl::AnyToItemSet(
{
    const ::uno::Any* pTemp;
    if(!GetProperty(FN_UNO_CLSID, 0, pTemp) && !GetProperty(FN_UNO_STREAM_NAME, 0, pTemp)
         && !GetProperty(FN_EMBEDDED_OBJECT, 0, pTemp) )
         && !GetProperty(FN_EMBEDDED_OBJECT, 0, pTemp)
         && !GetProperty(FN_UNO_VISIBLE_AREA_WIDTH, 0, pTemp)
         && !GetProperty(FN_UNO_VISIBLE_AREA_HEIGHT, 0, pTemp) )
        return false;
    SwFrameProperties_Impl::AnyToItemSet( pDoc, rFrameSet, rSet, rSizeFound);

@@ -1205,6 +1207,8 @@ SwXFrame::SwXFrame(FlyCntType eSet, const ::SfxItemPropertySet* pSet, SwDoc *pDo
    , eType(eSet)
    , bIsDescriptor(true)
    , m_nDrawAspect(embed::Aspects::MSOLE_CONTENT)
    , m_nVisibleAreaWidth(0)
    , m_nVisibleAreaHeight(0)
{
    // Register ourselves as a listener to the document (via the page descriptor)
    pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->Add(this);
@@ -1258,6 +1262,8 @@ SwXFrame::SwXFrame(SwFrameFormat& rFrameFormat, FlyCntType eSet, const ::SfxItem
    , eType(eSet)
    , bIsDescriptor(false)
    , m_nDrawAspect(embed::Aspects::MSOLE_CONTENT)
    , m_nVisibleAreaWidth(0)
    , m_nVisibleAreaHeight(0)
{
}

@@ -1960,6 +1966,18 @@ void SwXFrame::setPropertyValue(const OUString& rPropertyName, const ::uno::Any&
            else if (sAspect == "Content")
                m_nDrawAspect = embed::Aspects::MSOLE_CONTENT;
        }
        else if (FN_UNO_VISIBLE_AREA_WIDTH == pEntry->nWID)
        {
            OUString sAspect = "";
            aValue >>= sAspect;
            m_nVisibleAreaWidth = sAspect.toInt64();
        }
        else if (FN_UNO_VISIBLE_AREA_HEIGHT == pEntry->nWID)
        {
            OUString sAspect = "";
            aValue >>= sAspect;
            m_nVisibleAreaHeight = sAspect.toInt64();
        }
    }
    else
        throw uno::RuntimeException();
@@ -2856,6 +2874,21 @@ void SwXFrame::attachToRange(const uno::Reference< text::XTextRange > & xTextRan
            {
                UnoActionContext aAction(pDoc);
                pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);

                // tdf#99631 set imported VisibleArea settings of embedded XLSX OLE objects
                if ( m_nDrawAspect == embed::Aspects::MSOLE_CONTENT
                        && m_nVisibleAreaWidth && m_nVisibleAreaHeight )
                {
                    sal_Int64 nAspect = m_nDrawAspect;
                    MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xIPObj->getMapUnit( nAspect ) );
                    Size aSize( OutputDevice::LogicToLogic(Size( m_nVisibleAreaWidth, m_nVisibleAreaHeight),
                        MapMode(MapUnit::MapTwip), MapMode(aUnit)));
                    awt::Size aSz;
                    aSz.Width = aSize.Width();
                    aSz.Height = aSize.Height();
                    xIPObj->setVisualAreaSize(m_nDrawAspect, aSz);
                }

                if(!bSizeFound)
                {
                    //TODO/LATER: how do I transport it to the OLENode?
diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx
index 9dc0cce..6bb635b 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -900,6 +900,8 @@ const SfxItemPropertyMapEntry*  SwUnoPropertyMapProvider::GetEmbeddedPropertyMap
        { OUString(UNO_NAME_COMPONENT),FN_UNO_COMPONENT, cppu::UnoType<css::lang::XComponent>::get(), PropertyAttribute::READONLY, 0},
        { OUString(UNO_NAME_EMBEDDED_OBJECT),FN_EMBEDDED_OBJECT, cppu::UnoType<css::embed::XEmbeddedObject>::get(), PROPERTY_NONE, 0},
        { OUString(UNO_NAME_DRAW_ASPECT),FN_UNO_DRAW_ASPECT, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
        { OUString(UNO_NAME_VISIBLE_AREA_WIDTH),FN_UNO_VISIBLE_AREA_WIDTH, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
        { OUString(UNO_NAME_VISIBLE_AREA_HEIGHT),FN_UNO_VISIBLE_AREA_HEIGHT, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
        // added FillProperties for SW, same as FILL_PROPERTIES in svx
        // but need own defines in Writer due to later association of strings
        // and uno types (see loop at end of this method and definition of SW_PROP_NMID)
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 23319ad..57fb431 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -49,7 +49,6 @@
#include <sfx2/printer.hxx>
#include <unotools/charclass.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/classids.hxx>
#include <svx/svxdlg.hxx>
#include <svx/extrusionbar.hxx>
#include <svx/fontworkbar.hxx>
@@ -632,20 +631,11 @@ void SwWrtShell::CalcAndSetScale( svt::EmbeddedObjectRef& xObj,

    try
    {
        SvGlobalName aCLSID( xObj->getClassID() );
        // tdf#99631 VisibleArea settings of embedded XLSX haven't been imported in DOCX, yet:
        // set the 1:1 scale based on the OLE object size instead of bad scaling in non-modified documents
        bool bUpdateDOCXSheet = !GetDoc()->GetDocShell()->IsModified() &&
               // embedded spreadsheet
               aCLSID == SvGlobalName( SO3_SC_CLASSID_60 ) &&
               // in docx
               GetView().GetViewFrame()->GetFrame().GetCurrentDocument()->GetModel()->getURL().endsWithIgnoreAsciiCase(".docx");

        nMisc = xObj->getStatus( nAspect );

        // This can surely only be a non-active object, if desired they
        // get the new size set as VisArea (StarChart).
        if ((embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE & nMisc) || bUpdateDOCXSheet)
        if( embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE & nMisc )
        {
            // TODO/MBA: testing
            SwRect aRect( pFlyPrtRect ? *pFlyPrtRect
@@ -682,7 +672,6 @@ void SwWrtShell::CalcAndSetScale( svt::EmbeddedObjectRef& xObj,
                // nothing has been changed.
                // If the replacement graphic changes by this action, the document
                // will be already modified via other mechanisms.
                if (embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE & nMisc)
                {
                    bool bResetEnableSetModified(false);
                    if ( GetDoc()->GetDocShell()->IsEnableSetModified() )
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 1a0238e..2449693 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1753,6 +1753,14 @@ void DomainMapper_Impl::appendOLE( const OUString& rStreamName, const std::share
        xOLEProperties->setPropertyValue(getPropertyName( PROP_HEIGHT ),
                        uno::makeAny(aSize.Height));

        OUString aVisAreaWidth = pOLEHandler->GetVisAreaWidth();
        if(!aVisAreaWidth.isEmpty())
            xOLEProperties->setPropertyValue("VisibleAreaWidth", uno::makeAny(aVisAreaWidth));

        OUString aVisAreaHeight = pOLEHandler->GetVisAreaHeight();
        if(!aVisAreaHeight.isEmpty())
            xOLEProperties->setPropertyValue("VisibleAreaHeight", uno::makeAny(aVisAreaHeight));

        uno::Reference< graphic::XGraphic > xGraphic = pOLEHandler->getReplacement();
        xOLEProperties->setPropertyValue(getPropertyName( PROP_GRAPHIC ),
                        uno::makeAny(xGraphic));
diff --git a/writerfilter/source/dmapper/OLEHandler.cxx b/writerfilter/source/dmapper/OLEHandler.cxx
index dee9ceb..fad4494 100644
--- a/writerfilter/source/dmapper/OLEHandler.cxx
+++ b/writerfilter/source/dmapper/OLEHandler.cxx
@@ -95,8 +95,10 @@ void OLEHandler::lcl_attribute(Id rName, Value & rVal)
            rVal.getAny() >>= m_xInputStream;
        break;
        case NS_ooxml::LN_CT_Object_dxaOrig:
             m_sVisAreaWidth = sStringValue;
        break;
        case NS_ooxml::LN_CT_Object_dyaOrig:
             m_sVisAreaHeight = sStringValue;
        break;
        case NS_ooxml::LN_shape:
        {
@@ -262,6 +264,16 @@ OUString const & OLEHandler::GetDrawAspect() const
    return m_sDrawAspect;
}

OUString const & OLEHandler::GetVisAreaWidth() const
{
    return m_sVisAreaWidth;
}

OUString const & OLEHandler::GetVisAreaHeight() const
{
    return m_sVisAreaHeight;
}

OUString OLEHandler::copyOLEOStream(
        uno::Reference<text::XTextDocument> const& xTextDocument)
{
diff --git a/writerfilter/source/dmapper/OLEHandler.hxx b/writerfilter/source/dmapper/OLEHandler.hxx
index 6ba2fb3..b0aae53 100644
--- a/writerfilter/source/dmapper/OLEHandler.hxx
+++ b/writerfilter/source/dmapper/OLEHandler.hxx
@@ -52,6 +52,8 @@ class OLEHandler : public LoggedProperties
    OUString     m_sProgId;
    OUString     m_sShapeId;
    OUString     m_sDrawAspect;
    OUString     m_sVisAreaWidth;
    OUString     m_sVisAreaHeight;
    OUString     m_sObjectId;
    OUString     m_sr_id;
    /// The stream URL right after the import of the raw data.
@@ -90,6 +92,8 @@ public:
    OUString getCLSID(const css::uno::Reference<css::uno::XComponentContext>& xComponentContext) const;

    OUString const & GetDrawAspect() const;
    OUString const & GetVisAreaWidth() const;
    OUString const & GetVisAreaHeight() const;

    OUString copyOLEOStream(css::uno::Reference<css::text::XTextDocument> const& xTextDocument);