sw/qa/extras/uiwriter/data/tdf135581.odt |binary sw/qa/extras/uiwriter/uiwriter3.cxx | 11 ++++++++ sw/source/core/doc/docfly.cxx | 38 +++++++++++++------------------ 3 files changed, 28 insertions(+), 21 deletions(-)
New commits: commit d68e428a2ab9f0027ff82d67ae2492d143364586 Author: Justin Luth <justin.l...@collabora.com> AuthorDate: Thu Mar 16 18:49:12 2023 -0400 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Mar 22 10:39:53 2023 +0000 tdf#135581 sw UI: keep image in place when changing anchor Changing the anchor type should not move an image around. The only time we have a prosition to fix AFAICS is when the anchor changes and the RelationOrient is no longer appropriate. In that case we always get a new p*OrientItem. If GetPos changed, then that means the user (or earlier algorithm) already adjusted for the change. If there is no difference in GetPos even though the relation changed, then that is the only time we (likely) need to recalculate. So the typical example requiring an adjustment would be a change from "to paragraph" at text position 0 to a "to page" anchor. In this case "page" has no relationship to "text margins" and thus needs to base the absolute position 0 on page instead of text, meaning that the margins would need to be added to the absolute position. This code is basically unchanged since initial import. I have no idea why it could possibly be good to change the position when there is no new information given (no pHoriOrientItem/pVertOrientItem). [I checked and "from top" and "from bottom" are both == NONE, as well of course as "from left".] make CppunitTest_sw_uiwriter3 CPPUNIT_TEST_NAME=testTdf135581 Change-Id: Ib89ad9ba26c8826ed43f6d4505a82502b9ad8af9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149012 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/extras/uiwriter/data/tdf135581.odt b/sw/qa/extras/uiwriter/data/tdf135581.odt new file mode 100644 index 000000000000..cbd678ba0f73 Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf135581.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx index dfcde8d7eaa7..40f02901de09 100644 --- a/sw/qa/extras/uiwriter/uiwriter3.cxx +++ b/sw/qa/extras/uiwriter/uiwriter3.cxx @@ -1759,6 +1759,17 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, TestAsCharTextBox) // Without the fix in place the two texboxes has been fallen apart, and asserts will broken. } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf135581) +{ + createSwDoc("tdf135581.odt"); + + selectShape(1); + dispatchCommand(mxComponent, ".uno:SetAnchorAtChar", {}); // this is "to char" + + // Without the fix, the image was moving when the anchor changed, letting text flow back. + CPPUNIT_ASSERT_EQUAL(2, getPages()); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf140975) { // Load the bugdoc diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx index 5ddc713ff4af..998f123ee6c0 100644 --- a/sw/source/core/doc/docfly.cxx +++ b/sw/source/core/doc/docfly.cxx @@ -363,26 +363,25 @@ sal_Int8 SwDoc::SetFlyFrameAnchor( SwFrameFormat& rFormat, SfxItemSet& rSet, boo case RndStdIds::FLY_AT_FLY: // LAYER_IMPL case RndStdIds::FLY_AT_PAGE: { - // If no position attributes are coming in, we correct the position in a way - // such that the fly's document coordinates are preserved. - // If only the alignment changes in the position attributes (text::RelOrientation::FRAME - // vs. text::RelOrientation::PRTAREA), we also correct the position. + // If only the anchor type has changed (char -> para -> page) and the absolute position + // is unchanged even though there is a new relative orientation + // (likely because the old orientation was not valid for the new anchor type), + // then adjust the position to account for the moved anchor position. const SwFormatHoriOrient* pHoriOrientItem = rSet.GetItemIfSet( RES_HORI_ORIENT, false ); SwFormatHoriOrient aOldH( rFormat.GetHoriOrient() ); bool bPutOldH(false); - if( text::HoriOrientation::NONE == aOldH.GetHoriOrient() && ( !pHoriOrientItem || - aOldH.GetPos() == pHoriOrientItem->GetPos() )) + if (text::HoriOrientation::NONE == aOldH.GetHoriOrient() && pHoriOrientItem + && text::HoriOrientation::NONE == pHoriOrientItem->GetHoriOrient() + && aOldH.GetPos() == pHoriOrientItem->GetPos()) { SwTwips nPos = (RndStdIds::FLY_AS_CHAR == nOld) ? 0 : aOldH.GetPos(); nPos += aOldAnchorPos.getX() - aNewAnchorPos.getX(); - if( pHoriOrientItem ) - { - aOldH.SetHoriOrient( pHoriOrientItem->GetHoriOrient() ); - aOldH.SetRelationOrient( pHoriOrientItem->GetRelationOrient() ); - } + assert(aOldH.GetRelationOrient() != pHoriOrientItem->GetRelationOrient()); + aOldH.SetRelationOrient(pHoriOrientItem->GetRelationOrient()); + aOldH.SetPos( nPos ); bPutOldH = true; } @@ -406,19 +405,16 @@ sal_Int8 SwDoc::SetFlyFrameAnchor( SwFrameFormat& rFormat, SfxItemSet& rSet, boo const SwFormatVertOrient* pVertOrientItem = rSet.GetItemIfSet( RES_VERT_ORIENT, false ); SwFormatVertOrient aOldV( rFormat.GetVertOrient() ); - // #i28922# - correction: compare <aOldV.GetVertOrient() with - // <text::VertOrientation::NONE> - if( text::VertOrientation::NONE == aOldV.GetVertOrient() && (!pVertOrientItem || - aOldV.GetPos() == pVertOrientItem->GetPos() ) ) + if (text::VertOrientation::NONE == aOldV.GetVertOrient() && pVertOrientItem + && text::VertOrientation::NONE == pVertOrientItem->GetVertOrient() + && aOldV.GetPos() == pVertOrientItem->GetPos()) { SwTwips nPos = (RndStdIds::FLY_AS_CHAR == nOld) ? 0 : aOldV.GetPos(); nPos += aOldAnchorPos.getY() - aNewAnchorPos.getY(); - if( pVertOrientItem ) - { - SwFormatVertOrient& rV = const_cast<SwFormatVertOrient&>(*pVertOrientItem); - aOldV.SetVertOrient( rV.GetVertOrient() ); - aOldV.SetRelationOrient( rV.GetRelationOrient() ); - } + + assert(aOldV.GetRelationOrient() != pVertOrientItem->GetRelationOrient()); + aOldV.SetRelationOrient(pVertOrientItem->GetRelationOrient()); + aOldV.SetPos( nPos ); rSet.Put( aOldV ); }