tdf#122624 XLSX OLE in DOCX: import view positions

of the visible sheet of an embedded spreadsheet,
instead of showing always the first column and row.

Change-Id: I7b712d97f152da3cecf8371e21cf0a82ef21f199
Reviewed-on: https://gerrit.libreoffice.org/67867
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 646e2b4..f2b8f1c 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -463,6 +463,8 @@
    sal_uInt16              nFormulaTrackCount;
    HardRecalcState         eHardRecalcState;               // off, temporary, eternal
    SCTAB                   nVisibleTab;                    // for OLE etc., don't use inside ScDocument
    SCCOL                   nPosLeft;                       // for OLE etc., don't use inside ScDocument
    SCROW                   nPosTop;                        // for OLE etc., don't use inside ScDocument

    ScLkUpdMode         eLinkMode;

@@ -830,6 +832,10 @@

    SCTAB             GetVisibleTab() const       { return nVisibleTab; }
    SC_DLLPUBLIC void SetVisibleTab(SCTAB nTab)   { nVisibleTab = nTab; }
    SCCOL             GetPosLeft() const          { return nPosLeft; }
    SC_DLLPUBLIC void SetPosLeft(SCCOL nCol)      { nPosLeft = nCol; }
    SCROW             GetPosTop() const           { return nPosTop; }
    SC_DLLPUBLIC void SetPosTop(SCROW nRow)       { nPosTop = nRow; }

    SC_DLLPUBLIC bool HasTable( SCTAB nTab ) const;
    SC_DLLPUBLIC bool GetHashCode( SCTAB nTab, sal_Int64& rHashCode) const;
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index d2395cd..321c453 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -114,6 +114,8 @@
        nFormulaTrackCount(0),
        eHardRecalcState(HardRecalcState::OFF),
        nVisibleTab( 0 ),
        nPosLeft( 0 ),
        nPosTop( 0 ),
        eLinkMode(LM_UNKNOWN),
        bAutoCalc( eMode == SCDOCMODE_DOCUMENT || eMode == SCDOCMODE_FUNCTIONACCESS ),
        bAutoCalcShellDisabled( false ),
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index 5aa60f2..1ed50e0 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -720,7 +720,7 @@
        getScDocument().SetCalcConfig(aCalcConfig);
    }

    // set selected sheet
    // set selected sheet and positionleft/positiontop for OLE objects
    Reference<XViewDataSupplier> xViewDataSupplier(getDocument(), UNO_QUERY);
    if (xViewDataSupplier.is())
    {
@@ -730,20 +730,47 @@
            Sequence< PropertyValue > aSeq;
            if (xIndexAccess->getByIndex(0) >>= aSeq)
            {
                OUString sTabName;
                Reference< XNameAccess > xSheetsNC;
                sal_Int32 nCount (aSeq.getLength());
                for (sal_Int32 i = 0; i < nCount; ++i)
                {
                    OUString sName(aSeq[i].Name);
                    if (sName == SC_ACTIVETABLE)
                    {
                        OUString sTabName;
                        if(aSeq[i].Value >>= sTabName)
                        {
                            SCTAB nTab(0);
                            if (getScDocument().GetTable(sTabName, nTab))
                            {
                                getScDocument().SetVisibleTab(nTab);
                                i = nCount;
                        }
                    }
                    else if (sName == SC_TABLES)
                    {
                        aSeq[i].Value >>= xSheetsNC;
                    }
                }
                if (xSheetsNC.is() && xSheetsNC->hasByName(sTabName))
                {
                    Sequence<PropertyValue> aProperties;
                    Any aAny = xSheetsNC->getByName(sTabName);
                    if ( aAny >>= aProperties )
                    {
                        nCount = aProperties.getLength();
                        for (sal_Int32 i = 0; i < nCount; ++i)
                        {
                            OUString sName(aProperties[i].Name);
                            if (sName == SC_POSITIONLEFT)
                            {
                                SCCOL nPosLeft;
                                aProperties[i].Value >>= nPosLeft;
                                getScDocument().SetPosLeft(nPosLeft);
                            }
                            else if (sName == SC_POSITIONTOP)
                            {
                                SCROW nPosTop;
                                aProperties[i].Value >>= nPosTop;
                                getScDocument().SetPosTop(nPosTop);
                            }
                        }
                    }
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index 2069884..0c73fb1 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -2044,12 +2044,15 @@
    }
    else
    {
        tools::Rectangle aBoundRect = SfxObjectShell::GetVisArea();
        tools::Rectangle aOldArea = SfxObjectShell::GetVisArea();
        tools::Rectangle aNewArea = aOldArea;
        ScViewData aTmpData( this, nullptr );
        aTmpData.SetTabNo(nVisTab);
        SnapVisArea( aBoundRect );
        aTmpData.SetScreen( aBoundRect );
        ScPrintFunc::DrawToDev( &m_aDocument, pDev, 1.0, aBoundRect, &aTmpData, true );
        SnapVisArea( aNewArea );
        if ( aNewArea != aOldArea && (m_aDocument.GetPosLeft() > 0 || m_aDocument.GetPosTop() > 0) )
            SfxObjectShell::SetVisArea( aNewArea );
        aTmpData.SetScreen( aNewArea );
        ScPrintFunc::DrawToDev( &m_aDocument, pDev, 1.0, aNewArea, &aTmpData, true );
    }

    pDev->SetLayoutMode( nOldLayoutMode );
@@ -2186,19 +2189,25 @@
void ScDocShell::SnapVisArea( tools::Rectangle& rRect ) const
{
    SCTAB nTab = m_aDocument.GetVisibleTab();
    long nOrigTop = rRect.Top();
    long nOrigLeft = rRect.Left();
    bool bNegativePage = m_aDocument.IsNegativePage( nTab );
    if ( bNegativePage )
        ScDrawLayer::MirrorRectRTL( rRect );        // calculate with positive (LTR) values

    SCCOL nCol = 0;
    rRect.SetLeft( SnapHorizontal( m_aDocument, nTab, rRect.Left(), nCol ) );
    SCCOL nCol = m_aDocument.GetPosLeft();
    long nSetLeft = SnapHorizontal( m_aDocument, nTab, rRect.Left(), nCol );
    rRect.SetLeft( nSetLeft );
    ++nCol;                                         // at least one column
    rRect.SetRight( SnapHorizontal( m_aDocument, nTab, rRect.Right(), nCol ) );
    long nCorrectionLeft = (nOrigLeft == 0 && nCol > 0) ? nSetLeft : 0; // initial correction
    rRect.SetRight( SnapHorizontal( m_aDocument, nTab, rRect.Right() + nCorrectionLeft, nCol ));

    SCROW nRow = 0;
    rRect.SetTop( SnapVertical( m_aDocument, nTab, rRect.Top(), nRow ) );
    SCROW nRow = m_aDocument.GetPosTop();
    long nSetTop = SnapVertical( m_aDocument, nTab, rRect.Top(), nRow );
    rRect.SetTop( nSetTop );
    ++nRow;                                         // at least one row
    rRect.SetBottom( SnapVertical( m_aDocument, nTab, rRect.Bottom(), nRow ) );
    long nCorrectionTop = (nOrigTop == 0 && nRow > 0) ? nSetTop : 0; // initial correction
    rRect.SetBottom( SnapVertical( m_aDocument, nTab, rRect.Bottom() + nCorrectionTop, nRow ));

    if ( bNegativePage )
        ScDrawLayer::MirrorRectRTL( rRect );        // back to real rectangle
diff --git a/sc/source/ui/docshell/docsh6.cxx b/sc/source/ui/docshell/docsh6.cxx
index 9a3d7ac..26e3fe5 100644
--- a/sc/source/ui/docshell/docsh6.cxx
+++ b/sc/source/ui/docshell/docsh6.cxx
@@ -175,7 +175,11 @@

        bool bNegativePage = m_aDocument.IsNegativePage( nTab );
        SCCOL nX = pViewData->GetPosX(SC_SPLIT_LEFT);
        if ( nX != m_aDocument.GetPosLeft() )
            m_aDocument.SetPosLeft( nX );
        SCROW nY = pViewData->GetPosY(SC_SPLIT_BOTTOM);
        if ( nY != m_aDocument.GetPosTop() )
            m_aDocument.SetPosTop( nY );
        tools::Rectangle aMMRect = m_aDocument.GetMMRect( nX,nY, nX,nY, nTab );
        if (bNegativePage)
            lcl_SetTopRight( aNewArea, aMMRect.TopRight() );