summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/qa/core/undo/data/anchor-type-change-position.docxbin0 -> 49986 bytes
-rw-r--r--sw/qa/core/undo/undo.cxx30
-rw-r--r--sw/source/core/undo/unattr.cxx11
3 files changed, 40 insertions, 1 deletions
diff --git a/sw/qa/core/undo/data/anchor-type-change-position.docx b/sw/qa/core/undo/data/anchor-type-change-position.docx
new file mode 100644
index 000000000000..1a5d27b3f4b8
--- /dev/null
+++ b/sw/qa/core/undo/data/anchor-type-change-position.docx
Binary files differ
diff --git a/sw/qa/core/undo/undo.cxx b/sw/qa/core/undo/undo.cxx
index 221f2ba4ece7..7b68e1b3b259 100644
--- a/sw/qa/core/undo/undo.cxx
+++ b/sw/qa/core/undo/undo.cxx
@@ -146,6 +146,36 @@ CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testImagePropsCreateUndoAndModifyDoc)
CPPUNIT_ASSERT(!pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
}
+CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testAnchorTypeChangePosition)
+{
+ // Given a document with a textbox (draw + fly format pair) + an inner image:
+ createSwDoc("anchor-type-change-position.docx");
+ selectShape(1);
+ SwDoc* pDoc = getSwDoc();
+ const auto& rFormats = *pDoc->GetSpzFrameFormats();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), rFormats.size());
+ Point aOldPos;
+ {
+ const SwFormatHoriOrient& rHoriOrient = rFormats[0]->GetHoriOrient();
+ const SwFormatVertOrient& rVertOrient = rFormats[0]->GetVertOrient();
+ aOldPos = Point(rHoriOrient.GetPos(), rVertOrient.GetPos());
+ }
+
+ // When changing the anchor type + undo:
+ dispatchCommand(mxComponent, ".uno:SetAnchorToChar", {});
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ // Then make sure the old position is also restored:
+ const SwFormatHoriOrient& rHoriOrient = rFormats[0]->GetHoriOrient();
+ const SwFormatVertOrient& rVertOrient = rFormats[0]->GetVertOrient();
+ Point aNewPos(rHoriOrient.GetPos(), rVertOrient.GetPos());
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 789,213
+ // - Actual : 1578,3425
+ // i.e. there was a big, unexpected increase in the vertical position after undo.
+ CPPUNIT_ASSERT_EQUAL(aOldPos, aNewPos);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx
index ef729671d936..9b6a12a43707 100644
--- a/sw/source/core/undo/unattr.cxx
+++ b/sw/source/core/undo/unattr.cxx
@@ -505,7 +505,16 @@ bool SwUndoFormatAttr::RestoreFlyAnchor(::sw::UndoRedoContext & rContext)
// The Draw model also prepared an Undo object for its right positioning
// which unfortunately is relative. Therefore block here a position
// change of the Contact object by setting the anchor.
- pFrameFormat->CallSwClientNotify(sw::RestoreFlyAnchorHint(aDrawSavePt));
+ const SwFormatVertOrient& rVertOrient = pFrameFormat->GetVertOrient();
+ const SwFormatHoriOrient& rHoriOrient = pFrameFormat->GetHoriOrient();
+ Point aFormatPos(rHoriOrient.GetPos(), rVertOrient.GetPos());
+ if (aDrawSavePt != aFormatPos)
+ {
+ // If the position would be the same, then skip the call: either it would do nothing or
+ // it would just go wrong.
+ pFrameFormat->CallSwClientNotify(sw::RestoreFlyAnchorHint(aDrawSavePt));
+ }
+
// cache the old value again
m_oOldSet->Put(SwFormatFrameSize(SwFrameSize::Variable, aDrawOldPt.X(), aDrawOldPt.Y()));
}