sw/qa/extras/uiwriter/data/tdf135056.odt |binary sw/qa/extras/uiwriter/uiwriter.cxx | 25 +++++++++++++++ sw/source/core/layout/fly.cxx | 49 +++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 2 deletions(-)
New commits: commit fc67a79cd9268795f8049aea79c8f94d7165de8a Author: Michael Stahl <[email protected]> AuthorDate: Thu Oct 22 19:17:24 2020 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Wed Oct 28 08:19:36 2020 +0100 tdf#131679 sw: fix crash when copying fly via context menu sw::DocumentContentOperationsManager::CopyImplImpl() is called with a rPam that's on an SwOLENode. The problem (which i can't reproduce in --enable-dbgutil build, presumably for timing reasons) is that after the context menu pops up, some idle layout runs and reformats the document and deletes a SwFlyFrame and that calls SdrMarkView::UnmarkAllObj(). Then when SwFEShell::Copy() is called, it finds IsFrameSelected() returns false, and it tries to copy normal text when the cursor is on an SwOLENode. Fix this in SwFlyFrame::FinitDrawObj() by first moving the cursor out of any selected flys. (regression from 81ec0039b2085faab49380c7a56af0c562d4c9e4 - previously CopyImplImpl() would return early) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104697 Tested-by: Jenkins Reviewed-by: Michael Stahl <[email protected]> (cherry picked from commit 40bff2567fa4a3fa8ec4445182cbbe3547c17410) tdf#131679 sw: follow-up: Unmark before SetSelection() Backporting this to 6.4, it crashes in CppunitTest_desktop_lib because some sidebar is loaded from SwView::AttrChangedNotify()/SelectShell() and that ends up calling SwView::StateTabWin() about 40 stack frames later and this calls SwFEShell::GetAnyCurRect() which gets the still selected fly but its page frame is null. So make sure shells don't see the deleted fly. Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104815 Tested-by: Jenkins Reviewed-by: Michael Stahl <[email protected]> (cherry picked from commit f63afb95b5c2d80d33a35820ef1d9abd9e70d3ca) Change-Id: Id135fcc002c03c07c34fbdc0355f2895d8b6565b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104683 Tested-by: Michael Stahl <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index b5f364511f6e..190e799dbc56 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -377,6 +377,32 @@ void SwFlyFrame::InitDrawObj() : nHellId ); } +static SwPosition ResolveFlyAnchor(SwFrameFormat const& rFlyFrame) +{ + SwFormatAnchor const& rAnch(rFlyFrame.GetAnchor()); + if (rAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE) + { // arbitrarily pick last node + return SwPosition(SwNodeIndex(rFlyFrame.GetDoc()->GetNodes().GetEndOfContent(), -1)); + } + else + { + SwPosition const*const pPos(rAnch.GetContentAnchor()); + assert(pPos); + if (SwFrameFormat const*const pParent = pPos->nNode.GetNode().GetFlyFormat()) + { + return ResolveFlyAnchor(*pParent); + } + else if (pPos->nContent.GetIdxReg()) + { + return *pPos; + } + else + { + return SwPosition(*pPos->nNode.GetNode().GetContentNode(), 0); + } + } +} + void SwFlyFrame::FinitDrawObj() { if(!GetVirtDrawObj() ) @@ -391,8 +417,27 @@ void SwFlyFrame::FinitDrawObj() for(SwViewShell& rCurrentShell : p1St->GetRingContainer()) { // At the moment the Drawing can do just do an Unmark on everything, // as the Object was already removed - if(rCurrentShell.HasDrawView() ) - rCurrentShell.Imp()->GetDrawView()->UnmarkAll(); + if (rCurrentShell.HasDrawView() && + rCurrentShell.Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()) + { + if (SwFEShell *const pFEShell = dynamic_cast<SwFEShell*>(&rCurrentShell)) + { // tdf#131679 move any cursor out of fly + SwFlyFrame const*const pOldSelFly = ::GetFlyFromMarked(nullptr, pFEShell); + rCurrentShell.Imp()->GetDrawView()->UnmarkAll(); + if (pOldSelFly) + { + SwPosition const pos(ResolveFlyAnchor(*pOldSelFly->GetFormat())); + SwPaM const temp(pos); + pFEShell->SetSelection(temp); + // could also call SetCursor() like SwFEShell::SelectObj() + // does, but that would access layout a bit much... + } + } + else + { + rCurrentShell.Imp()->GetDrawView()->UnmarkAll(); + } + } } } } commit c64995d1e550b49a226d8f170b2e5533a59bb987 Author: Xisco Fauli <[email protected]> AuthorDate: Wed Sep 2 18:35:54 2020 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Wed Oct 28 08:19:24 2020 +0100 tdf#135056: sw_uiwriter: Add unittest Change-Id: I933537a44b9493adc89516bccb189003cf4f132f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101950 Tested-by: Jenkins Reviewed-by: Xisco Fauli <[email protected]> (cherry picked from commit bc46ff73d6f79d850253f9e1896643eb73238ebb) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104826 Tested-by: Michael Stahl <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/sw/qa/extras/uiwriter/data/tdf135056.odt b/sw/qa/extras/uiwriter/data/tdf135056.odt new file mode 100644 index 000000000000..bd94317d07d4 Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf135056.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 0bd769d2b121..b98a12d0e90c 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -4364,6 +4364,31 @@ void SwUiWriterTest::testDocModState() CPPUNIT_ASSERT(!(pShell->IsModified())); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf135056) +{ + load(DATA_DIRECTORY, "tdf135056.odt"); + + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + + SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + + CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), pWrtShell->GetTOXCount()); + + const SwTOXBase* pTOX = pWrtShell->GetTOX(0); + CPPUNIT_ASSERT(pTOX); + + //Without the fix in place, it would have hung here + pWrtShell->DeleteTOX(*pTOX, true); + + CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), pWrtShell->GetTOXCount()); + + lcl_dispatchCommand(mxComponent, ".uno:Undo", {}); + + CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), pWrtShell->GetTOXCount()); +} + void SwUiWriterTest::testTdf94804() { //create new writer document _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
