summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2020-11-13 18:29:20 +0100
committerRegina Henschel <rb.henschel@t-online.de>2020-11-15 09:04:14 +0100
commit670d10f2b06656973a61e956956b149bae01721f (patch)
tree69957606b15501692cbb9c7eed9a9bb98b08b5a1 /sc
parent42a691933429dbb315de2bd7ba2724993c60411f (diff)
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.henschel@t-online.de>
Diffstat (limited to 'sc')
-rw-r--r--sc/qa/unit/data/ods/hideColsShow.odsbin0 -> 9425 bytes
-rw-r--r--sc/qa/unit/scshapetest.cxx59
-rw-r--r--sc/source/ui/view/drawvie3.cxx18
3 files changed, 75 insertions, 2 deletions
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
--- /dev/null
+++ b/sc/qa/unit/data/ods/hideColsShow.ods
Binary files 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)