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;