tdf#142701 track changes: fix layout regression of image deletion
Commit d6322bcedc197a654abc7d64bfea8cf570f123bf
(tdf#59463 track changes: record deletion of images) converted
image anchors to AS_CHAR, which resulted loss of the original
layout during rejecting the tracked image deletion.
Now keep the original AT_CHAR (also AS_CHAR) anchorings, also convert
the AT_PARA and other anchoring types to AT_CHAR using the following
workaround: add an invisible text-based anchoring point with ZWJs.
Follow-up to commit 8726cf692299ea262a7455adcf6ec25451c7869d
(tdf#142700 DOCX: fix lost track changes of images).
Change-Id: I29d1e161b5f24c0fed51d40c9a8db82085918d0d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118747
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
(cherry picked from commit b50d386dfa70f7c1d4eb1a49091ec9dd782b767b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118800
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 5ad1acc..32e891f 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -3561,6 +3561,11 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTrackImageDeletion)
const SwRedlineTable& rTable = rIDRA.GetRedlineTable();
// this was 0 (missing recording of deletion of images)
CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), rTable.size());
uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
// tdf#142701 this was AS_CHARACTER (convert AT_PARA to AT_CHAR to keep the layout)
CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,
getProperty<text::TextContentAnchorType>(xShape, "AnchorType"));
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTrackImageInsertion)
diff --git a/sw/source/uibase/wrtsh/delete.cxx b/sw/source/uibase/wrtsh/delete.cxx
index 455b421..104d3c0 100644
--- a/sw/source/uibase/wrtsh/delete.cxx
+++ b/sw/source/uibase/wrtsh/delete.cxx
@@ -35,6 +35,7 @@
#include <rtl/character.hxx>
#include <osl/diagnose.h>
#include <doc.hxx>
#include <IDocumentRedlineAccess.hxx>
inline void SwWrtShell::OpenMark()
{
@@ -428,18 +429,20 @@ bool SwWrtShell::DelRight()
std::unique_ptr<SwPosition> pAnchor;
RndStdIds eAnchorId = RndStdIds::FLY_AT_PARA;
SwFlyFrame* pFly = GetSelectedFlyFrame();
SwFrameFormat* pFormat = nullptr;
if (pFly)
{
SwFrameFormat* pFormat = pFly->GetFormat();
pFormat = pFly->GetFormat();
if (pFormat)
{
eAnchorId = pFormat->GetAnchor().GetAnchorId();
// as-character anchor conversion at track changes
if ( IsRedlineOn() && eAnchorId != RndStdIds::FLY_AS_CHAR )
// to-character anchor conversion at track changes
if ( IsRedlineOn() && (eAnchorId != RndStdIds::FLY_AS_CHAR &&
eAnchorId != RndStdIds::FLY_AT_CHAR) )
{
SfxItemSet aSet(GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>{});
GetFlyFrameAttr(aSet);
SwFormatAnchor aAnch(RndStdIds::FLY_AS_CHAR);
SwFormatAnchor aAnch(RndStdIds::FLY_AT_CHAR);
aSet.Put(aAnch);
SetFlyFrameAttr(aSet);
eAnchorId = pFormat->GetAnchor().GetAnchorId();
@@ -455,12 +458,30 @@ bool SwWrtShell::DelRight()
}
}
// track changes: delete the anchor point of the image to record the deletion
if ( IsRedlineOn() && pAnchor && SelectionType::Graphic & nSelection
&& eAnchorId == RndStdIds::FLY_AS_CHAR )
// track changes: create redline at anchor point of the image to record the deletion
if ( IsRedlineOn() && pAnchor && SelectionType::Graphic & nSelection && pFormat &&
( eAnchorId == RndStdIds::FLY_AT_CHAR || eAnchorId == RndStdIds::FLY_AS_CHAR ) )
{
sal_Int32 nRedlineLength = 1;
// create a double ZWJ anchor point of the image to record the deletion, if needed
// (otherwise use the existing anchor point of the image anchored *as* character)
if ( eAnchorId == RndStdIds::FLY_AT_CHAR )
{
nRedlineLength = 2;
LeaveSelFrameMode();
UnSelectFrame();
RedlineFlags eOld = GetRedlineFlags();
SetRedlineFlags( eOld | RedlineFlags::Ignore );
Insert( OUString( u"" ) );
SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
SwCursorShell::Left(1, CRSR_SKIP_CHARS);
anchor.SetAnchor(GetCursor()->GetPoint());
GetDoc()->SetAttr(anchor, *pFormat);
SetRedlineFlags( eOld );
SwCursorShell::Left(1, CRSR_SKIP_CHARS);
}
OpenMark();
SwCursorShell::Right(1, CRSR_SKIP_CHARS);
SwCursorShell::Right(nRedlineLength, CRSR_SKIP_CHARS);
bRet = Delete();
CloseMark( bRet );
}