diff --git a/sw/qa/extras/uiwriter/data/demo91.fodt b/sw/qa/extras/uiwriter/data/demo91.fodt new file mode 100644 index 000000000000..de27c587a35d --- /dev/null +++ b/sw/qa/extras/uiwriter/data/demo91.fodt @@ -0,0 +1,156 @@ + + + 2022-06-16T15:27:43.487415219PT29M32LibreOfficeDev/7.6.0.0.alpha0$Linux_X86_64 LibreOffice_project/fc6bd4f18ea90f789a1425e2c830f4b42457012e2022-06-22T20:18:58.711000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + yellow + + + at endorange + + + + + + diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index c6a56fe84daa..bc539e810c90 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -58,6 +58,8 @@ #include #include #include +#include +#include #include #include @@ -208,6 +210,79 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testThreadedException) CPPUNIT_ASSERT(!bRes); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf149595) +{ + createSwDoc("demo91.fodt"); + SwDoc* pDoc = getSwDoc(); + + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + // all 4 shapes are on the 2nd paragraph + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr); + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr); + CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size()); + + { + pWrtShell->Down(false); + pWrtShell->EndPara(/*bSelect=*/true); + rtl::Reference pTransfer = new SwTransferable(*pWrtShell); + pTransfer->Cut(); + + // one shape is anchored in the middle, others at the start/end/at-para + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr); + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr); + CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size()); + + pWrtShell->Up(false); + TransferableDataHelper aHelper(pTransfer); + SwTransferable::Paste(*pWrtShell, aHelper); + + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() != nullptr); + CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs()->size()); + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr); + CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size()); + + pWrtShell->Undo(); + pWrtShell->Undo(); + + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr); + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr); + CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size()); + } + + // now try the same with redlining enabled - should be the same result + dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {}); + dispatchCommand(mxComponent, ".uno:TrackChanges", {}); + { + pWrtShell->Down(false); + pWrtShell->SttPara(/*bSelect=*/false); + pWrtShell->EndPara(/*bSelect=*/true); + rtl::Reference pTransfer = new SwTransferable(*pWrtShell); + pTransfer->Cut(); + + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr); + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr); + // problem was that this deleted all at-char flys, even at the start/end + CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size()); + + pWrtShell->Up(false); + TransferableDataHelper aHelper(pTransfer); + SwTransferable::Paste(*pWrtShell, aHelper); + + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() != nullptr); + CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs()->size()); + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr); + CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size()); + + pWrtShell->Undo(); + pWrtShell->Undo(); + + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr); + CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr); + CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size()); + } +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testBookmarkCopy) { createSwDoc(); diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index 08097467c237..0bae8e422e81 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1122,6 +1122,12 @@ static bool IsShown(SwNodeOffset const nIndex, assert(pFirstNode); assert(pLastNode); assert(rAnch.GetAnchorId() != RndStdIds::FLY_AT_FLY); + if (*pIter == *pEnd && rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) + { // tdf#149595 special case - it *could* be shown if first == last + return !IsDestroyFrameAnchoredAtChar(*rAnch.GetContentAnchor(), + SwPosition(*pFirstNode, 0), + SwPosition(*pLastNode, pLastNode->Len())); + } for (auto iter = *pIter; iter != *pEnd; ++iter) { assert(iter->nStart != iter->nEnd); // TODO possible?