diff options
-rw-r--r-- | sw/qa/core/undo/data/anchor-type-change-position.docx | bin | 0 -> 49986 bytes | |||
-rw-r--r-- | sw/qa/core/undo/undo.cxx | 30 | ||||
-rw-r--r-- | sw/source/core/undo/unattr.cxx | 11 |
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 Binary files differnew file mode 100644 index 000000000000..1a5d27b3f4b8 --- /dev/null +++ b/sw/qa/core/undo/data/anchor-type-change-position.docx 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())); } |