summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2021-07-30 23:18:39 +0200
committerRegina Henschel <rb.henschel@t-online.de>2021-08-02 19:22:10 +0200
commit0cff1aa48453ee0c05bafcac5360329fb6bf9557 (patch)
tree7f4767c4a5cd9e64d34ae07b43b9bef6f716b812
parentd5a100f59467d94945656b54563e5ecdde2ca724 (diff)
tdf#143619 validation circle anchor is special
For usual drawing objects, maStart in its Calc user data means the cell address of left/top of snapRect/logicRect. For validation circle it means 'address of cell to be validated'. Thus corrections might be needed, if a general method is used for validation circle. Here the method SetLogicRect() calls via broadcast ScDrawLayer::SetCellAnchoredFromPosition(), which calculates maStart from snapRect/logicRect. Because the circle is extended to cover a larger area than the to be validated cell, maStart got the cell address of the cell one left and one above of the to be validated cell. Now the old, correct address is backuped and restored. Change-Id: I9646da3f22fef45a6e47e59ef55a70307e2f9cc6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119715 Tested-by: Jenkins Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
-rw-r--r--sc/qa/unit/data/ods/tdf143619_validationCirclePos.odsbin0 -> 8367 bytes
-rw-r--r--sc/qa/unit/scshapetest.cxx34
-rw-r--r--sc/source/core/data/drwlayer.cxx7
3 files changed, 41 insertions, 0 deletions
diff --git a/sc/qa/unit/data/ods/tdf143619_validationCirclePos.ods b/sc/qa/unit/data/ods/tdf143619_validationCirclePos.ods
new file mode 100644
index 000000000000..6470d6a1f430
--- /dev/null
+++ b/sc/qa/unit/data/ods/tdf143619_validationCirclePos.ods
Binary files differ
diff --git a/sc/qa/unit/scshapetest.cxx b/sc/qa/unit/scshapetest.cxx
index fad81ddd0e6b..c178c28578a6 100644
--- a/sc/qa/unit/scshapetest.cxx
+++ b/sc/qa/unit/scshapetest.cxx
@@ -46,6 +46,7 @@ public:
ScShapeTest();
void saveAndReload(css::uno::Reference<css::lang::XComponent>& xComponent,
const OUString& rFilter);
+ void testTdf143619_validation_circle_pos();
void testTdf140252_DragCreateFormControl();
void testTdf134355_DragCreateCustomShape();
void testTdf140252_LayerOfControl();
@@ -72,6 +73,7 @@ public:
void testCustomShapeCellAnchoredRotatedShape();
CPPUNIT_TEST_SUITE(ScShapeTest);
+ CPPUNIT_TEST(testTdf143619_validation_circle_pos);
CPPUNIT_TEST(testTdf140252_DragCreateFormControl);
CPPUNIT_TEST(testTdf134355_DragCreateCustomShape);
CPPUNIT_TEST(testTdf140252_LayerOfControl);
@@ -204,6 +206,38 @@ static SdrObject* lcl_getSdrObjectWithAssert(ScDocument& rDoc, sal_uInt16 nObjNu
return pObj;
}
+void ScShapeTest::testTdf143619_validation_circle_pos()
+{
+ // Load a document, which has validation circle around cell E6.
+
+ OUString aFileURL;
+ createFileURL(u"tdf143619_validationCirclePos.ods", aFileURL);
+ uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL);
+
+ // Get document
+ ScDocShell* pDocSh = lcl_getScDocShellWithAssert(xComponent);
+ ScDocument& rDoc = pDocSh->GetDocument();
+
+ // Get shape. That is the validation circle.
+ SdrObject* pObj = lcl_getSdrObjectWithAssert(rDoc, 0);
+
+ // Error was, that deleting row and col before E6 does not move circle to D5, but to B3.
+ // Delete first row and first column.
+ uno::Sequence<beans::PropertyValue> aPropertyValues = {
+ comphelper::makePropertyValue("ToPoint", OUString("$A$1")),
+ };
+ dispatchCommand(xComponent, ".uno:GoToCell", aPropertyValues);
+ dispatchCommand(xComponent, ".uno:DeleteRows", {});
+ dispatchCommand(xComponent, ".uno:GoToCell", aPropertyValues);
+ dispatchCommand(xComponent, ".uno:DeleteColumns", {});
+
+ // Without fix in place the position was (2007, 833)
+ Point aPos = pObj->GetSnapRect().TopLeft();
+ lcl_AssertPointEqualWithTolerance("after row and col delete", Point(6523, 1736), aPos, 1);
+
+ pDocSh->DoClose();
+}
+
void ScShapeTest::testTdf140252_DragCreateFormControl()
{
// Error was, that drag-created form controls were initially not on layer 'controls' and thus
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 1174cb656019..79b52627e015 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -1049,6 +1049,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati
// Validation circle for detective.
rData.setShapeRect(GetDocument(), pObj->GetLogicRect());
+ // rData.maStart should contain the address of the be validated cell.
tools::Rectangle aRect = GetCellRect(*GetDocument(), rData.maStart, true);
aRect.AdjustLeft( -250 );
aRect.AdjustRight(250 );
@@ -1062,7 +1063,13 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati
if (bRecording)
AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *pObj ) );
rData.setShapeRect(GetDocument(), lcl_makeSafeRectangle(aRect));
+ // maStart has the meaning of "to be validated cell" in a validation circle. For usual
+ // drawing objects it has the meaning "left/top of logic/snap rect". Because the rectangle
+ // is expanded above, SetLogicRect() will set maStart to one cell left and one cell above
+ // of the to be validated cell. We need to backup the old value and restore it.
+ ScAddress aBackup(rData.maStart);
pObj->SetLogicRect(rData.getShapeRect());
+ rData.maStart = aBackup;
}
}
else if (rData.meType == ScDrawObjData::DetectiveArrow)