sc/inc/document.hxx               |    1 
 sc/inc/table.hxx                  |    1 
 sc/qa/unit/data/ods/tdf154005.ods |binary
 sc/qa/unit/scshapetest.cxx        |   47 ++++++++++++++++++++++++++++++++++++++
 sc/source/core/data/document.cxx  |    8 ++++++
 sc/source/core/data/drwlayer.cxx  |   16 +++++++++++-
 sc/source/core/data/table5.cxx    |   22 +++++++++++++++++
 7 files changed, 93 insertions(+), 2 deletions(-)

New commits:
commit 1d9c9ebd552b9394a025fbb9e692451ba9d3460c
Author:     Balazs Varga <balazs.varga.ext...@allotropia.de>
AuthorDate: Sun Mar 12 17:49:53 2023 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Thu Mar 16 01:51:29 2023 +0000

    tdf#154005 sc ods fileopen: fix dropdown form control size
    
    Dropdown form control size was increased by the size of hidden
    rows or columns.
    
    Regression from commit: 1f0b3c7a40edfa81bbc7a58d123a6a2dfd83e4ca
    (Improve 'resize with cell' handling)
    
    Change-Id: Ic903a488cab22286f95cfdf4ee559013fd7bfa02
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148738
    Tested-by: Thorsten Behrens <thorsten.behr...@allotropia.de>
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148874

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 4cc98b01096e..03a4345ead15 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1919,6 +1919,7 @@ public:
     SC_DLLPUBLIC SCROW          FirstVisibleRow(SCROW nStartRow, SCROW 
nEndRow, SCTAB nTab) const;
     SC_DLLPUBLIC SCROW          LastVisibleRow(SCROW nStartRow, SCROW nEndRow, 
SCTAB nTab) const;
     SCROW                       CountVisibleRows(SCROW nStartRow, SCROW 
nEndRow, SCTAB nTab) const;
+    SCCOL                       CountVisibleCols(SCROW nStartCol, SCROW 
nEndCol, SCTAB nTab) const;
 
     bool                        RowFiltered(SCROW nRow, SCTAB nTab, SCROW* 
pFirstRow = nullptr, SCROW* pLastRow = nullptr) const;
     bool                        HasFilteredRows(SCROW nStartRow, SCROW 
nEndRow, SCTAB nTab) const;
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index e1e21588278d..cc90bd31b980 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -905,6 +905,7 @@ public:
     SCROW       FirstVisibleRow(SCROW nStartRow, SCROW nEndRow) const;
     SCROW       LastVisibleRow(SCROW nStartRow, SCROW nEndRow) const;
     SCROW       CountVisibleRows(SCROW nStartRow, SCROW nEndRow) const;
+    SCCOL       CountVisibleCols(SCCOL nStartCol, SCCOL nEndCol) const;
     sal_uInt32  GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow, bool 
bHiddenAsZero = true) const;
 
     SCCOLROW    LastHiddenColRow(SCCOLROW nPos, bool bCol) const;
diff --git a/sc/qa/unit/data/ods/tdf154005.ods 
b/sc/qa/unit/data/ods/tdf154005.ods
new file mode 100644
index 000000000000..1b52a4dba556
Binary files /dev/null and b/sc/qa/unit/data/ods/tdf154005.ods differ
diff --git a/sc/qa/unit/scshapetest.cxx b/sc/qa/unit/scshapetest.cxx
index 7f2d762bc34d..55a2b0a8537c 100644
--- a/sc/qa/unit/scshapetest.cxx
+++ b/sc/qa/unit/scshapetest.cxx
@@ -12,6 +12,7 @@
 #include <sfx2/dispatch.hxx>
 #include <svx/svdoashp.hxx>
 #include <svx/svdpage.hxx>
+#include <svx/svdouno.hxx>
 
 #include <docsh.hxx>
 #include <drwlayer.hxx>
@@ -33,10 +34,12 @@ public:
 
     void testFitToCellSize();
     void testCustomShapeCellAnchoredRotatedShape();
+    void testFormSizeWithHiddenCol();
 
     CPPUNIT_TEST_SUITE(ScShapeTest);
     CPPUNIT_TEST(testFitToCellSize);
     CPPUNIT_TEST(testCustomShapeCellAnchoredRotatedShape);
+    CPPUNIT_TEST(testFormSizeWithHiddenCol);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -171,6 +174,50 @@ void ScShapeTest::testCustomShapeCellAnchoredRotatedShape()
     pDocSh->DoClose();
 }
 
+void ScShapeTest::testFormSizeWithHiddenCol()
+{
+    // The document contains a form (Listbox) shape anchored "To Cell (resize 
with cell)" with starts in cell B5 and
+    // ends in cell D5. The error was the form shape was resized if there was 
hidden col/row.
+    OUString aFileURL;
+    createFileURL("tdf154005.ods", aFileURL);
+    uno::Reference<css::lang::XComponent> xComponent = 
loadFromDesktop(aFileURL);
+    CPPUNIT_ASSERT(xComponent.is());
+
+    // Get the document model
+    SfxObjectShell* pFoundShell = 
SfxObjectShell::GetShellFromComponent(xComponent);
+    CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
+
+    ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
+    CPPUNIT_ASSERT(pDocSh);
+
+    // Get the shape
+    ScDocument& rDoc = pDocSh->GetDocument();
+    ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
+    CPPUNIT_ASSERT(pDrawLayer);
+
+    const SdrPage* pPage = pDrawLayer->GetPage(0);
+    CPPUNIT_ASSERT(pPage);
+
+    SdrUnoObj* pObj = dynamic_cast<SdrUnoObj*>(pPage->GetObj(0));
+    CPPUNIT_ASSERT(pObj);
+
+    // Check Position and Size
+    rDoc.SetDrawPageSize(0); // trigger recalcpos
+    tools::Rectangle aRect(2432, 3981, 4932, 4631); // expected snap rect from 
values in file
+    const tools::Rectangle& rShapeRect(pObj->GetSnapRect());
+    const OUString sPosSizeErrors(lcl_compareRectWithTolerance(aRect, 
rShapeRect, 1));
+    CPPUNIT_ASSERT_EQUAL(OUString(), sPosSizeErrors);
+
+    // Check anchor
+    ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj);
+    CPPUNIT_ASSERT_MESSAGE("expected object meta data", pData);
+    const OUString sActual("start col " + 
OUString::number(pData->maStart.Col()) + " row "
+                           + OUString::number(pData->maStart.Row()) + " end 
col "
+                           + OUString::number(pData->maEnd.Col()) + " row "
+                           + OUString::number(pData->maEnd.Row()));
+    CPPUNIT_ASSERT_EQUAL(OUString("start col 1 row 4 end col 3 row 4"), 
sActual);
+}
+
 void ScShapeTest::tearDown()
 {
     if (mxComponent.is())
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 725f6918411a..a9c794fab7ec 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -4483,6 +4483,14 @@ SCROW ScDocument::CountVisibleRows(SCROW nStartRow, 
SCROW nEndRow, SCTAB nTab) c
     return maTabs[nTab]->CountVisibleRows(nStartRow, nEndRow);
 }
 
+SCCOL ScDocument::CountVisibleCols(SCROW nStartCol, SCROW nEndCol, SCTAB nTab) 
const
+{
+    if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || 
!maTabs[nTab])
+        return 0;
+
+    return maTabs[nTab]->CountVisibleCols(nStartCol, nEndCol);
+}
+
 bool ScDocument::RowFiltered(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* 
pLastRow) const
 {
     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || 
!maTabs[nTab])
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index ed1f9bdf4444..03d30c914dad 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -666,6 +666,18 @@ void lcl_SetLogicRectFromAnchor(SdrObject* pObj, 
ScDrawObjData& rAnchor, ScDocum
     if (!pObj || !pDoc || !rAnchor.maEnd.IsValid() || 
!rAnchor.maStart.IsValid())
         return;
 
+    SCROW nHiddenRows = 0;
+    SCCOL nHiddenCols = 0;
+    // tdf#154005: Handle hidden row/col: remove hidden row/cols size from the 
ScDrawObjData shape size in case of forms
+    if (pObj->GetObjIdentifier() == SdrObjKind::OBJ_UNO && 
pObj->GetObjInventor() == SdrInventor::FmForm)
+    {
+        nHiddenRows = ((rAnchor.maEnd.Row() - rAnchor.maStart.Row()) + 1) -
+            (pDoc->CountVisibleRows(rAnchor.maStart.Row(), 
rAnchor.maEnd.Row(), rAnchor.maStart.Tab()));
+
+        nHiddenCols = ((rAnchor.maEnd.Col() - rAnchor.maStart.Col()) + 1) -
+            (pDoc->CountVisibleCols(rAnchor.maStart.Col(), 
rAnchor.maEnd.Col(), rAnchor.maStart.Tab()));
+    }
+
     // In case of a vertical mirrored custom shape, LibreOffice uses 
internally an additional 180deg
     // in aGeo.nRotationAngle and in turn has a different logic rectangle 
position. We remove flip,
     // set the logic rectangle, and apply flip again. You cannot simple use a 
180deg-rotated
@@ -688,8 +700,8 @@ void lcl_SetLogicRectFromAnchor(SdrObject* pObj, 
ScDrawObjData& rAnchor, ScDocum
     aStartPoint.AdjustY(rAnchor.maStartOffset.getY());
 
     const tools::Rectangle aEndCellRect(
-        pDoc->GetMMRect(rAnchor.maEnd.Col(), rAnchor.maEnd.Row(), 
rAnchor.maEnd.Col(),
-                        rAnchor.maEnd.Row(), rAnchor.maEnd.Tab(), false 
/*bHiddenAsZero*/));
+        pDoc->GetMMRect(rAnchor.maEnd.Col() - nHiddenCols, rAnchor.maEnd.Row() 
- nHiddenRows, rAnchor.maEnd.Col() - nHiddenCols,
+                        rAnchor.maEnd.Row() - nHiddenRows, 
rAnchor.maEnd.Tab(), false /*bHiddenAsZero*/));
     Point aEndPoint(aEndCellRect.Left(), aEndCellRect.Top());
     aEndPoint.AdjustX(rAnchor.maEndOffset.getX());
     aEndPoint.AdjustY(rAnchor.maEndOffset.getY());
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index 5ae1e9999ab2..9756f13d8390 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -775,6 +775,28 @@ SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW 
nEndRow) const
     return nCount;
 }
 
+SCCOL ScTable::CountVisibleCols(SCCOL nStartCol, SCCOL nEndCol) const
+{
+    assert(nStartCol <= nEndCol);
+    SCCOL nCount = 0;
+    SCCOL nCol = nStartCol;
+    ScFlatBoolColSegments::RangeData aData;
+    while (nCol <= nEndCol)
+    {
+        if (!mpHiddenCols->getRangeData(nCol, aData))
+            break;
+
+        if (aData.mnCol2 > nEndCol)
+            aData.mnCol2 = nEndCol;
+
+        if (!aData.mbValue)
+            nCount += aData.mnCol2 - nCol + 1;
+
+        nCol = aData.mnCol2 + 1;
+    }
+    return nCount;
+}
+
 sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow, bool 
bHiddenAsZero ) const
 {
     sal_uInt32 nHeight = 0;

Reply via email to