sc/qa/unit/data/ods/hideColsShow.ods |binary sc/qa/unit/scshapetest.cxx | 59 +++++++++++++++++++++++++++++++++++ sc/source/ui/view/drawvie3.cxx | 18 +++++++++- 3 files changed, 75 insertions(+), 2 deletions(-)
New commits: commit 670d10f2b06656973a61e956956b149bae01721f Author: Regina Henschel <rb.hensc...@t-online.de> AuthorDate: Fri Nov 13 18:29:20 2020 +0100 Commit: Regina Henschel <rb.hensc...@t-online.de> CommitDate: Sun Nov 15 09:04:14 2020 +0100 Avoid changing anchor on visibility change of cell This is an addition to commit 1f0b3c7a40edfa81bbc7a58d123a6a2dfd83e4ca The following scenario had produced a wrong object size: The object is anchored to cell. Some columns containing this cell were hidden and then shown again. ScDrawLayer::SetCellAnchoredFromPosition was called in this case and had produced the wrong size. When the column of the object anchor is shown, object becomes visible. This gives an 'object change' event, sent to ScDrawView::Notify, which calls adjustAnchoredPosition. That had a test pAnchor->getShapeRect() == pObj->GetSnapRect() that should prevent calling SetCellAnchoredFromPosition. But exact equality fails due to +-1 differencies because of Twips<->Hmm conversions. Change-Id: I0bd3684b7a5eda62b578275c02a5ac839ce58e2c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105802 Tested-by: Jenkins Reviewed-by: Regina Henschel <rb.hensc...@t-online.de> diff --git a/sc/qa/unit/data/ods/hideColsShow.ods b/sc/qa/unit/data/ods/hideColsShow.ods new file mode 100644 index 000000000000..acfea8f1ef98 Binary files /dev/null and b/sc/qa/unit/data/ods/hideColsShow.ods differ diff --git a/sc/qa/unit/scshapetest.cxx b/sc/qa/unit/scshapetest.cxx index d31a3ce03a1e..6eac2bc2b859 100644 --- a/sc/qa/unit/scshapetest.cxx +++ b/sc/qa/unit/scshapetest.cxx @@ -33,6 +33,7 @@ public: ScShapeTest(); void saveAndReload(css::uno::Reference<css::lang::XComponent>& xComponent, const OUString& rFilter); + void testHideColsShow(); void testTdf138138_MoveCellWithRotatedShape(); void testLoadVerticalFlip(); void testTdf117948_CollapseBeforeShape(); @@ -42,6 +43,7 @@ public: void testCustomShapeCellAnchoredRotatedShape(); CPPUNIT_TEST_SUITE(ScShapeTest); + CPPUNIT_TEST(testHideColsShow); CPPUNIT_TEST(testTdf138138_MoveCellWithRotatedShape); CPPUNIT_TEST(testLoadVerticalFlip); CPPUNIT_TEST(testTdf117948_CollapseBeforeShape); @@ -101,6 +103,63 @@ static void lcl_AssertRectEqualWithTolerance(const OString& sInfo, labs(rExpected.GetHeight() - rActual.GetHeight()) <= nTolerance); } +void ScShapeTest::testHideColsShow() +{ + // The document contains a shape anchored "To Cell (resive with cell)" with starts in cell C3 and + //ends in cell D5. Error was, that hiding cols C and D and then show them again extends the shape + // to column E + + OUString aFileURL; + createFileURL("hideColsShow.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 document and shape + ScDocument& rDoc = pDocSh->GetDocument(); + ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer(); + CPPUNIT_ASSERT_MESSAGE("No ScDrawLayer", pDrawLayer); + const SdrPage* pPage = pDrawLayer->GetPage(0); + CPPUNIT_ASSERT_MESSAGE("No draw page", pPage); + SdrObject* pObj = pPage->GetObj(0); + CPPUNIT_ASSERT_MESSAGE("No object found", pObj); + CPPUNIT_ASSERT_MESSAGE("Load: Object should be visible", pObj->IsVisible()); + tools::Rectangle aSnapRectOrig(pObj->GetSnapRect()); + + // Hide cols C and D. + uno::Sequence<beans::PropertyValue> aPropertyValues = { + comphelper::makePropertyValue("ToPoint", OUString("$C$1:$D$1")), + }; + dispatchCommand(xComponent, ".uno:GoToCell", aPropertyValues); + + ScTabViewShell* pViewShell = pDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT_MESSAGE("No ScTabViewShell", pViewShell); + pViewShell->GetViewData().GetDispatcher().Execute(FID_COL_HIDE); + + // Check object is invisible + CPPUNIT_ASSERT_MESSAGE("Hide: Object should be invisible", !pObj->IsVisible()); + + // Show cols C and D + aPropertyValues = { + comphelper::makePropertyValue("ToPoint", OUString("$C$1:$D$1")), + }; + dispatchCommand(xComponent, ".uno:GoToCell", aPropertyValues); + pViewShell->GetViewData().GetDispatcher().Execute(FID_COL_SHOW); + + // Check object is visible and has old size + CPPUNIT_ASSERT_MESSAGE("Show: Object should be visible", pObj->IsVisible()); + tools::Rectangle aSnapRectShow(pObj->GetSnapRect()); + lcl_AssertRectEqualWithTolerance("Show: Object geometry should not change", aSnapRectOrig, + aSnapRectShow, 1); + + pDocSh->DoClose(); +} + void ScShapeTest::testTdf138138_MoveCellWithRotatedShape() { // The document contains a 90deg rotated, cell-anchored rectangle in column D. Insert 2 columns diff --git a/sc/source/ui/view/drawvie3.cxx b/sc/source/ui/view/drawvie3.cxx index 2305083b4739..1d3c476ee0fb 100644 --- a/sc/source/ui/view/drawvie3.cxx +++ b/sc/source/ui/view/drawvie3.cxx @@ -138,6 +138,21 @@ ScAnchorType ScDrawView::GetAnchorType() const namespace { +bool lcl_AreRectanglesApproxEqual(const tools::Rectangle& rRectA, const tools::Rectangle& rRectB) +{ + // Twips <-> Hmm conversions introduce +-1 differences although the rectangles should actually + // be equal. Therefore test with == is not appropriate in some cases. + if (std::labs(rRectA.Left() - rRectB.Left()) > 1) + return false; + if (std::labs(rRectA.Top() - rRectB.Top()) > 1) + return false; + if (std::labs(rRectA.Right() - rRectB.Right()) > 1) + return false; + if (std::labs(rRectA.Bottom() - rRectB.Bottom()) > 1) + return false; + return true; +} + /** * Updated the anchors of any non-note object that is cell anchored which * has been moved since the last anchors for its position was calculated. @@ -157,8 +172,7 @@ void adjustAnchoredPosition(const SdrHint& rHint, const ScDocument& rDoc, SCTAB if (pAnchor->meType == ScDrawObjData::CellNote) return; - - if (pAnchor->getShapeRect() == pObj->GetSnapRect()) + if (lcl_AreRectanglesApproxEqual(pAnchor->getShapeRect(), pObj->GetSnapRect())) return; if (pAnchor->maStart.Tab() != nTab) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits