sw/inc/undobj.hxx | 12 ++++++------ sw/source/core/layout/frmtool.cxx | 10 ++++++++++ sw/source/core/text/widorp.cxx | 2 ++ sw/source/core/undo/undobj.cxx | 22 +++++++++------------- sw/source/core/undo/unins.cxx | 4 ++-- sw/source/core/undo/untblk.cxx | 6 +++--- 6 files changed, 32 insertions(+), 24 deletions(-)
New commits: commit e43f09bec7bc1d7f367a9b6f6a8ec001a102645d Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Wed Aug 2 13:26:39 2023 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Thu Aug 3 11:58:03 2023 +0200 tdf#156546 sw: fix infinite loop in SwUndoInsert::RedoImpl() The problem is that SwUndoSaveContent::MovePtBackward() sets the point of a shell cursor to the document body's start node, which is not a valid position for a shell cursor; FindParentText() then loops forever. The purpose of this appears to be to move the point temporarily somewhere where subsequent inserting operations won't move it further, so that it can be restored to the start of the inserted stuff. Refactor a bit to use a temporary SwNodeIndex instead, which should work as nothing should delete the node it's pointing to. (regression from commit d81379db730a163c5ff75d4f3a3cddbd7b5eddda) Change-Id: I471bcced1741c77c07239ed124d4fd39ff7a7515 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155227 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 2d96d69322ac18f53668b75397c8587f94cd043b) diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx index 71d9c511591d..42b14f7859e5 100644 --- a/sw/inc/undobj.hxx +++ b/sw/inc/undobj.hxx @@ -21,6 +21,7 @@ #include <vector> #include <memory> +#include <optional> #include <svl/undo.hxx> #include <tools/solar.h> @@ -177,12 +178,11 @@ protected: const sal_uLong* pEndNdIdx = nullptr, bool bForceCreateFrames = false); - // These two methods move the SPoint back/forth from PaM. With it - // a range can be spanned for Undo/Redo. (In this case the SPoint - // is before the manipulated range!!) - // The flag indicates if there is content before the SPoint. - static bool MovePtBackward( SwPaM& rPam ); - static void MovePtForward( SwPaM& rPam, bool bMvBkwrd ); + // These two methods save and restore the Point of PaM. + // If the point cannot be moved, a "backup" is created on the previous node. + // Either way, it will not be moved by inserting at its original position. + static ::std::optional<SwNodeIndex> MovePtBackward(SwPaM& rPam); + static void MovePtForward(SwPaM& rPam, ::std::optional<SwNodeIndex> && oMvBkwrd); // Before moving stuff into UndoNodes-Array care has to be taken that // the content-bearing attributes are removed from the nodes-array. diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx index 098c277d9155..b1ed15e3124d 100644 --- a/sw/source/core/undo/undobj.cxx +++ b/sw/source/core/undo/undobj.cxx @@ -798,30 +798,26 @@ void SwUndoSaveContent::MoveFromUndoNds( SwDoc& rDoc, sal_uLong nNodeIdx, } } -// These two methods move the Point of Pam backwards/forwards. With that, one -// can span an area for a Undo/Redo. (The Point is then positioned in front of -// the area to manipulate!) -// The flag indicates if there is still content in front of Point. -bool SwUndoSaveContent::MovePtBackward( SwPaM& rPam ) +// These two methods save and restore the Point of PaM. +// If the point cannot be moved, a "backup" is created on the previous node. +// Either way, returned, inserting at its original position will not move it. +::std::optional<SwNodeIndex> SwUndoSaveContent::MovePtBackward(SwPaM & rPam) { rPam.SetMark(); if( rPam.Move( fnMoveBackward )) - return true; + return {}; - // If there is no content onwards, set Point simply to the previous position - // (Node and Content, so that Content will be detached!) - --rPam.GetPoint()->nNode; - rPam.GetPoint()->nContent.Assign( nullptr, 0 ); - return false; + return { SwNodeIndex(rPam.GetPoint()->nNode, -1) }; } -void SwUndoSaveContent::MovePtForward( SwPaM& rPam, bool bMvBkwrd ) +void SwUndoSaveContent::MovePtForward(SwPaM& rPam, ::std::optional<SwNodeIndex> && oMvBkwrd) { // Was there content before this position? - if( bMvBkwrd ) + if (!oMvBkwrd) rPam.Move( fnMoveForward ); else { + *rPam.GetPoint() = SwPosition(*oMvBkwrd); ++rPam.GetPoint()->nNode; SwContentNode* pCNd = rPam.GetContentNode(); if( pCNd ) diff --git a/sw/source/core/undo/unins.cxx b/sw/source/core/undo/unins.cxx index f1f7f48188aa..ff3f4777329c 100644 --- a/sw/source/core/undo/unins.cxx +++ b/sw/source/core/undo/unins.cxx @@ -328,7 +328,7 @@ void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext) if( nLen ) { - const bool bMvBkwrd = MovePtBackward( *pPam ); + ::std::optional<SwNodeIndex> oMvBkwrd = MovePtBackward(*pPam); if (maText) { @@ -355,7 +355,7 @@ void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext) nNode = pPam->GetMark()->nNode.GetIndex(); nContent = pPam->GetMark()->nContent.GetIndex(); - MovePtForward( *pPam, bMvBkwrd ); + MovePtForward(*pPam, ::std::move(oMvBkwrd)); pPam->Exchange(); if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags() )) { diff --git a/sw/source/core/undo/untblk.cxx b/sw/source/core/undo/untblk.cxx index 449f41795697..01561018ec56 100644 --- a/sw/source/core/undo/untblk.cxx +++ b/sw/source/core/undo/untblk.cxx @@ -357,15 +357,15 @@ void SwUndoInserts::RedoImpl(::sw::UndoRedoContext & rContext) auto const pFlysAtInsPos(sw::GetFlysAnchoredAt(*pDoc, rPam.GetPoint()->nNode.GetIndex())); - const bool bMvBkwrd = MovePtBackward(rPam); + ::std::optional<SwNodeIndex> oMvBkwrd = MovePtBackward(rPam); // re-insert content again (first detach m_pUndoNodeIndex!) sal_uLong const nMvNd = m_pUndoNodeIndex->GetIndex(); m_pUndoNodeIndex.reset(); MoveFromUndoNds(*pDoc, nMvNd, *rPam.GetMark()); - if (m_nDeleteTextNodes != 0) + if (m_nDeleteTextNodes != 0 || oMvBkwrd) { - MovePtForward(rPam, bMvBkwrd); + MovePtForward(rPam, ::std::move(oMvBkwrd)); } rPam.Exchange(); commit ba44f7c2f4ee0c24bafa388e0c3885986e75c9a3 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Tue Jul 18 16:58:34 2023 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Thu Aug 3 11:58:02 2023 +0200 tdf#146258 sw: invalidate section frame for new text frame at start SwFlowFrame::CalcUpperSpace() uses the first text frame inside to compute the upper margin of section frames. Before commit 69d2d24b3579ad21fb1ba2746f81a02f8bbfb984 this was working because a temporary SwTextFrame for the new SwTextNode was created and then deleted again, but while it was alive the SvULSpace item was copied and then it invalidated the section frame: 1 SwFrame::InvalidatePrt_() 2 SwContentFrame::Modify() at libreoffice-6-1/sw/source/core/layout/wsfrm.cxx:2336 3 SwTextFrame::SwClientNotify() ... 7 SwTextNode::Modify() 8 SwContentNode::SetAttr() 9 SwTextNode::SetAttr() 10 SwAttrSet::CopyToModify() 11 SwTextNode::CopyText() 12 SwTextNode::CopyText() 13 SwTextNode::MakeCopy() 14 SwNodes::CopyNodes() 15 sw::DocumentContentOperationsManager::CopyWithFlyInFly() 16 SwIntrnlSectRefLink::DataChanged() Now however nothing invalidates the section frame, so do it in InsertCnt_(), hopefully it works for columned sections too. (regression from commit 166b5010b402a41b192b1659093a25acf9065fd9) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154594 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 34b607bb455bd30d3adf8e3f72182c7cc4d062ee) [commit 34b607bb455bd30d3adf8e3f72182c7cc4d062ee used wrong issue id] Change-Id: I339286ac37c9ee9a0bef730a73215bc139386514 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154614 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> (cherry picked from commit b81829dc7aa94e92818d2545cd28f1ef6c298395) diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index d425af7b8b64..764ce58c0098 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1557,6 +1557,16 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc, pPageMaker->CheckInsert( nIndex ); pFrame->InsertBehind( pLay, pPrv ); + if (!pPrv) + { + if (SwSectionFrame *const pSection = pLay->FindSctFrame()) + { + if (pSection && pSection->ContainsAny() == pFrame) + { // tdf#146258 section PrtArea depends on paragraph upper margin + pSection->InvalidatePrt(); + } + } + } // #i27138# // notify accessibility paragraphs objects about changed // CONTENT_FLOWS_FROM/_TO relation. commit 580e405f6fac9931c6d6e1ada37fd1ee9d576111 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Mon Jul 17 21:37:07 2023 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Thu Aug 3 11:58:02 2023 +0200 tdf#153319 sw: don't move footnotes to follow if portions in master SwTextFrameBreak::IsInside() may be called in different situations, during formatting it should be possible to move the footnotes, but when called from SwTextFrame::CalcPreps() this is problematic as it does not format the lines, it iterates over existing lines. The problem is that the footnote frame is moved to the follow's page, but the footnote portion remains on the master, and then the follow is joined while the footnote frame's mpReference still points to it. (regression from commit 391613785ae6fbb735cf7a86ea2f6a93161a8769) Change-Id: I4290dcd242a7f5292ad4f50c1407c9cd88e80a6a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154557 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 7e9b2b71db72b8c4c9c6ca83d08d3b6b05775ac8) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154545 Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> (cherry picked from commit f70f822532d96feebd24645009f0368405dac9e4) diff --git a/sw/source/core/text/widorp.cxx b/sw/source/core/text/widorp.cxx index df0c779d6dbb..43afbd1e45e6 100644 --- a/sw/source/core/text/widorp.cxx +++ b/sw/source/core/text/widorp.cxx @@ -138,6 +138,8 @@ bool SwTextFrameBreak::IsInside( SwTextMargin const &rLine ) const bFit = nDiff >= 0; if (!bFit && rLine.MaybeHasHints() && m_pFrame->GetFollow() + // tdf#153319 RemoveFootnote only works if this frame doesn't + && !rLine.GetNext() // contain the footnote portion // if using same footnote container as the follow, pointless to try? && m_pFrame->FindFootnoteBossFrame() != m_pFrame->GetFollow()->FindFootnoteBossFrame()) {