sw/qa/core/doc/doc.cxx | 43 ++++++++++++++++++++++++++++++++++++++++++ sw/source/core/doc/doclay.cxx | 13 ++++-------- 2 files changed, 48 insertions(+), 8 deletions(-)
New commits: commit 6c761fa3b40d296444681d8d2f991e5a6b7e5b71 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Nov 13 08:49:43 2023 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Nov 13 10:24:26 2023 +0100 sw floattable, insert UI: fix missing undo/redo There were 3 problems here: 1) SwDoc::MakeFlyAndMove() declared that inserting fly frames is broken anyway, so just deleted the whole undo stack. Remove the DelAllUndoObj() call, so the underlying problem is visible. 2) MoveNodeRange() had a flag to create undo objects, but this flag wasn't used. 3) The empty text node after the table in the just created fly was removed using a call to SwNodes::Delete(), which is not undo-aware, so the table was inserted after the anchor (and not before the anchor) on undo. Fix this by going via sw::DocumentContentOperationsManager that knows how to delete while working with the undo. Do this unconditionally, because the 2 callers of this function is just SwFEShell::NewFlyFrame() (UI) and SwXFrame::attachToRange() (UNO API, mostly the DOCX import), probably both want proper undo support. Change-Id: I50011bf969ff5636c76a8a0b280193ac6d2b90dd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159354 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx index 2a9870660830..2fad46194174 100644 --- a/sw/qa/core/doc/doc.cxx +++ b/sw/qa/core/doc/doc.cxx @@ -40,6 +40,7 @@ #include <rootfrm.hxx> #include <pagefrm.hxx> #include <sortedobjs.hxx> +#include <itabenum.hxx> /// Covers sw/source/core/doc/ fixes. class SwCoreDocTest : public SwModelTestBase @@ -566,6 +567,48 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testSplitExpandGlossary) CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage2Objs.size()); } +CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testSplitFlyInsertUndo) +{ + // Given a document with an inline table, which is then turned into a floating one: + createSwDoc(); + SwDoc* pDoc = getSwDocShell()->GetDoc(); + sw::FrameFormats<sw::SpzFrameFormat*>& rFlyFormats = *pDoc->GetSpzFrameFormats(); + CPPUNIT_ASSERT(rFlyFormats.empty()); + // Insert a table: + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + SwInsertTableOptions aTableOptions(SwInsertTableFlags::DefaultBorder, 0); + pWrtShell->InsertTable(aTableOptions, /*nRows=*/2, /*nCols=*/1); + pWrtShell->MoveTable(GotoPrevTable, fnTableStart); + pWrtShell->GoPrevCell(); + pWrtShell->Insert("A1"); + pWrtShell->GoNextCell(); + pWrtShell->Insert("A2"); + // Select cell: + pWrtShell->SelAll(); + // Select table: + pWrtShell->SelAll(); + // Wrap the table in a text frame: + SwFlyFrameAttrMgr aMgr(true, pWrtShell, Frmmgr_Type::TEXT, nullptr); + pWrtShell->StartAllAction(); + aMgr.InsertFlyFrame(RndStdIds::FLY_AT_PARA, aMgr.GetPos(), aMgr.GetSize()); + pWrtShell->EndAllAction(); + CPPUNIT_ASSERT(!rFlyFormats.empty()); + + // When undoing the conversion to floating table: + pDoc->GetUndoManager().Undo(); + + // Then make sure we don't have a frame anymore: + // Without the accompanying fix in place, this test would have failed, there was no undo action + // to execute. + CPPUNIT_ASSERT(rFlyFormats.empty()); + + // And when redoing the conversion: + pDoc->GetUndoManager().Redo(); + + // Then make sure we again have a frame: + CPPUNIT_ASSERT(!rFlyFormats.empty()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx index 516d15aed8ec..2ecea30dc3be 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -389,7 +389,8 @@ SwFlyFrameFormat* SwDoc::MakeFlyAndMove( const SwPaM& rPam, const SfxItemSet& rS GetNodes().MakeTextNode( aRg.aStart.GetNode(), GetDfltTextFormatColl() ); - getIDocumentContentOperations().MoveNodeRange( aRg, oPos->GetNode(), SwMoveFlags::DEFAULT ); + // Create undo actions if undo is enabled. + getIDocumentContentOperations().MoveNodeRange( aRg, oPos->GetNode(), SwMoveFlags::CREATEUNDOOBJ ); } else { @@ -404,13 +405,9 @@ SwFlyFrameFormat* SwDoc::MakeFlyAndMove( const SwPaM& rPam, const SfxItemSet& rS OSL_ENSURE( aIndex.GetNode().GetTextNode(), "a TextNode should be here" ); oPos.reset(); // Deregister index! - GetNodes().Delete( aIndex ); - - // This is a hack: whilst FlyFrames/Headers/Footers are not undoable we delete all Undo objects - if( GetIDocumentUndoRedo().DoesUndo() ) - { - GetIDocumentUndoRedo().DelAllUndoObj(); - } + // Delete the empty paragraph after the table, in a way that undo is aware of this. + SwPaM aPaM(aIndex); + getIDocumentContentOperations().DelFullPara(aPaM); } else {