sw/inc/node.hxx | 8 ++--- sw/source/core/docnode/ndsect.cxx | 2 - sw/source/core/docnode/ndtbl.cxx | 4 +- sw/source/core/docnode/node.cxx | 8 ++++- sw/source/core/inc/ftnfrm.hxx | 10 +++++++ sw/source/core/inc/txtfrm.hxx | 3 +- sw/source/core/layout/ssfrm.cxx | 3 +- sw/source/core/layout/wsfrm.cxx | 24 ++++++++++++++--- sw/source/core/text/atrstck.cxx | 13 ++++++++- sw/source/core/text/itratr.cxx | 23 +++++++++-------- sw/source/core/text/itrcrsr.cxx | 10 +++---- sw/source/core/text/pormulti.cxx | 2 - sw/source/core/text/redlnitr.cxx | 51 +++++++++++++++++++++++++++++++++++--- sw/source/core/text/txtfrm.cxx | 38 +++++++++++++++++++++++----- sw/source/core/txtnode/ndtxt.cxx | 2 - 15 files changed, 155 insertions(+), 46 deletions(-)
New commits: commit 6a993ec62f7b4165a3d6077ab5cd4f63f297aa17 Author: Michael Stahl <[email protected]> AuthorDate: Tue Jul 31 19:11:16 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Tue Jul 31 19:11:16 2018 +0200 sw_redlinehide_2: add layout parameter to *Node::DelFrames A trivial patch to remove some FIXMEs; unfortunately one new FIXME because the SwSectionNode case isn't entirely trivial. Change-Id: I94f11ffd19b189b165ad1fb05488ba8617e81357 diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx index ecc7ab109d0a..0c5ee9a9f309 100644 --- a/sw/inc/node.hxx +++ b/sw/inc/node.hxx @@ -418,10 +418,8 @@ public: /** Method deletes all views of document for the node. The content- frames are removed from the respective layout. - - Add an input param to identify if acc table should be disposed */ - void DelFrames( bool bIsAccTableDispose = true ); + void DelFrames(SwRootFrame const* pLayout = nullptr); /** @return count of elements of node content. Default is 1. There are differences between text node and formula node. */ @@ -508,7 +506,7 @@ public: /** Method deletes all views of document for the node. The content frames are removed from the respective layout. */ - void DelFrames(); + void DelFrames(SwRootFrame const* pLayout = nullptr); /** Method creates all views of the document for the previous node. The content frames that are created are put into the respective layout. */ @@ -556,7 +554,7 @@ public: /** Method deletes all views of document for the node. The content frames are removed from the respective layout. */ - void DelFrames(); + void DelFrames(SwRootFrame const* pLayout = nullptr); /** Method creates all views of document for the previous node. The content frames created are put into the respective layout. */ diff --git a/sw/source/core/docnode/ndsect.cxx b/sw/source/core/docnode/ndsect.cxx index 360722fd6f04..ec6ac343b797 100644 --- a/sw/source/core/docnode/ndsect.cxx +++ b/sw/source/core/docnode/ndsect.cxx @@ -1150,7 +1150,7 @@ void SwSectionNode::MakeOwnFrames(SwNodeIndex* pIdxBehind, SwNodeIndex* pEndIdx) } } -void SwSectionNode::DelFrames() +void SwSectionNode::DelFrames(SwRootFrame const*const /*FIXME TODO*/) { sal_uLong nStt = GetIndex()+1, nEnd = EndOfSectionIndex(); if( nStt >= nEnd ) diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx index 2f2a135d0d39..d5b62a198d0a 100644 --- a/sw/source/core/docnode/ndtbl.cxx +++ b/sw/source/core/docnode/ndtbl.cxx @@ -2425,7 +2425,7 @@ void SwTableNode::MakeOwnFrames(SwNodeIndex* pIdxBehind) } } -void SwTableNode::DelFrames() +void SwTableNode::DelFrames(SwRootFrame const*const pLayout) { /* For a start, cut out and delete the TabFrames (which will also delete the Columns and Rows) The TabFrames are attached to the FrameFormat of the SwTable. @@ -2437,7 +2437,7 @@ void SwTableNode::DelFrames() { bool bAgain = false; { - if ( !pFrame->IsFollow() ) + if (!pFrame->IsFollow() && (!pLayout || pLayout == pFrame->getRootFrame())) { while ( pFrame->HasFollow() ) pFrame->JoinAndDelFollows(); diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx index b3a5ecc27438..7812c94fdc43 100644 --- a/sw/source/core/docnode/node.cxx +++ b/sw/source/core/docnode/node.cxx @@ -1016,7 +1016,7 @@ SwContentNode::~SwContentNode() // Thus, we need to delete all Frames in the dependency list. if (!IsTextNode()) // see ~SwTextNode { - DelFrames(false); + DelFrames(nullptr); } m_aCondCollListener.EndListeningAll(); @@ -1310,7 +1310,7 @@ void SwContentNode::MakeFramesForAdjacentContentNode(SwContentNode& rNode) * * An input param to identify if the acc table should be disposed. */ -void SwContentNode::DelFrames(bool /*removeme*/) +void SwContentNode::DelFrames(SwRootFrame const*const pLayout) { if( !HasWriterListeners() ) return; @@ -1318,6 +1318,10 @@ void SwContentNode::DelFrames(bool /*removeme*/) SwIterator<SwContentFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aIter(*this); for( SwContentFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next() ) { + if (pLayout && pLayout != pFrame->getRootFrame()) + { + continue; // skip it + } if (pFrame->IsTextFrame()) { if (sw::MergedPara const* pMerged = diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index 04c1cff769e8..68d9e1e418f1 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -4228,15 +4228,15 @@ static void UnHideRedlines(SwRootFrame & rLayout, if (rNode.IsContentNode()) { // note: no-op for NonFirst nodes, only Hidden will delete - static_cast<SwContentNode&>(rNode).DelFrames(); // FIXME only those in this layout? + static_cast<SwContentNode&>(rNode).DelFrames(&rLayout); } else if (rNode.IsTableNode()) { - static_cast<SwTableNode&>(rNode).DelFrames(); // FIXME only those in this layout? + static_cast<SwTableNode&>(rNode).DelFrames(&rLayout); } else if (rNode.IsSectionNode()) { - static_cast<SwSectionNode&>(rNode).DelFrames(); // FIXME only those in this layout? + static_cast<SwSectionNode&>(rNode).DelFrames(&rLayout); } } else diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx index b9d7afb7da55..5bcb4d1b4350 100644 --- a/sw/source/core/text/redlnitr.cxx +++ b/sw/source/core/text/redlnitr.cxx @@ -149,7 +149,7 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, // otherwise footnotes cannot be deleted by SwTextFootnote::DelFrames! for (auto iter = ++nodes.begin(); iter != nodes.end(); ++iter) { - (**iter).DelFrames(); // FIXME only those in this layout? + (**iter).DelFrames(rFrame.getRootFrame()); } } auto pRet(o3tl::make_unique<sw::MergedPara>(rFrame, std::move(extents), diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index d2901a640e11..880ce8ea14a3 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -263,7 +263,7 @@ SwTextNode::~SwTextNode() InitSwParaStatistics( false ); - DelFrames(false); // must be called here while it's still a SwTextNode + DelFrames(nullptr); // must be called here while it's still a SwTextNode DelFrames_TextNodePart(); } commit 3422abf611892c9829f271bddea8802ad6571bef Author: Michael Stahl <[email protected]> AuthorDate: Tue Jul 31 18:39:36 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Tue Jul 31 18:39:36 2018 +0200 sw_redlinehide_2: show/hide footnotes in redlines This requires some manual work to delete the footnote frames. Change-Id: I2c5efccdd1e97f26e18402b809ca4f893147cba1 diff --git a/sw/source/core/inc/ftnfrm.hxx b/sw/source/core/inc/ftnfrm.hxx index 7f964d654d4d..c0848948848f 100644 --- a/sw/source/core/inc/ftnfrm.hxx +++ b/sw/source/core/inc/ftnfrm.hxx @@ -23,12 +23,22 @@ #include "layfrm.hxx" class SwContentFrame; +class SwTextFrame; +class SwTextNode; class SwTextFootnote; class SwBorderAttrs; class SwFootnoteFrame; void sw_RemoveFootnotes( SwFootnoteBossFrame* pBoss, bool bPageOnly, bool bEndNotes ); +namespace sw { + +void RemoveFootnotesForNode( + SwTextFrame const& rTextFrame, SwTextNode const& rTextNode, + std::vector<std::pair<sal_Int32, sal_Int32>> const*const pExtents); + +} + // There exists a special section on a page for footnotes. It's called // SwFootnoteContFrame. Each footnote is separated by a SwFootnoteFrame which contains // the paragraphs of a footnote. SwFootnoteFrame can be splitted and will then diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index d5a38e17a455..3b6860cb4691 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -93,7 +93,8 @@ struct MergedPara; std::pair<SwTextNode*, sal_Int32> MapViewToModel(MergedPara const&, TextFrameIndex nIndex); TextFrameIndex MapModelToView(MergedPara const&, SwTextNode const* pNode, sal_Int32 nIndex); -std::unique_ptr<sw::MergedPara> CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode); +enum class FrameMode { New, Existing }; +std::unique_ptr<sw::MergedPara> CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, FrameMode eMode); bool FrameContainsNode(SwContentFrame const& rFrame, sal_uLong nNodeIndex); diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx index b16643c3e767..d847bf6f21bd 100644 --- a/sw/source/core/layout/ssfrm.cxx +++ b/sw/source/core/layout/ssfrm.cxx @@ -443,7 +443,8 @@ SwContentFrame::~SwContentFrame() void SwTextFrame::RegisterToNode(SwTextNode & rNode) { assert(&rNode != GetDep()); - m_pMergedPara = sw::CheckParaRedlineMerge(*this, rNode); + // sw_redlinehide: use New here, because the only caller also calls lcl_ChangeFootnoteRef + m_pMergedPara = sw::CheckParaRedlineMerge(*this, rNode, sw::FrameMode::New); if (!m_pMergedPara) { rNode.Add(this); diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index f009ce124281..04c1cff769e8 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -4193,14 +4193,27 @@ static void UnHideRedlines(SwRootFrame & rLayout, rNode.GetRedlineMergeFlag() == SwNode::Merge::NonFirst); if (rNode.IsCreateFrameWhenHidingRedlines()) { - pFrame->SetMergedPara(CheckParaRedlineMerge(*pFrame, rTextNode)); + pFrame->SetMergedPara(CheckParaRedlineMerge(*pFrame, + rTextNode, sw::FrameMode::Existing)); // ??? TODO flys etc. } } else { - if (pFrame->GetMergedPara()) + if (auto const& pMergedPara = pFrame->GetMergedPara()) { + // the new text frames don't exist yet, so at this point + // we can only delete the footnote frames so they don't + // point to the merged SwTextFrame any more... + SwTextNode const* pNode(&rTextNode); + for (auto const& rExtent : pMergedPara->extents) + { + if (rExtent.pNode != pNode) + { + sw::RemoveFootnotesForNode(*pFrame, *rExtent.pNode, nullptr); + pNode = rExtent.pNode; + } + } pFrame->SetMergedPara(nullptr); // ??? TODO flys etc. // ??? TODO recreate? or is invalidate enough? @@ -4214,6 +4227,7 @@ static void UnHideRedlines(SwRootFrame & rLayout, { if (rNode.IsContentNode()) { + // note: no-op for NonFirst nodes, only Hidden will delete static_cast<SwContentNode&>(rNode).DelFrames(); // FIXME only those in this layout? } else if (rNode.IsTableNode()) diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx index aba968a8740f..b9d7afb7da55 100644 --- a/sw/source/core/text/redlnitr.cxx +++ b/sw/source/core/text/redlnitr.cxx @@ -36,6 +36,7 @@ #include <vcl/commandevent.hxx> #include <vcl/settings.hxx> #include <txtfrm.hxx> +#include <ftnfrm.hxx> #include <vcl/svapp.hxx> #include "redlnitr.hxx" #include <extinput.hxx> @@ -47,7 +48,8 @@ using namespace ::com::sun::star; namespace sw { std::unique_ptr<sw::MergedPara> -CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode) +CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, + FrameMode const eMode) { IDocumentRedlineAccess const& rIDRA = rTextNode.getIDocumentRedlineAccess(); if (!rFrame.getRootFrame()->IsHideRedlines()) @@ -117,6 +119,39 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode) assert(!mergedText.isEmpty()); pParaPropsNode = extents.begin()->pNode; // para props from first node that isn't empty } + if (eMode == FrameMode::Existing) + { + // remove existing footnote frames for first node; + // for non-first notes, DelFrames will remove all + // (could possibly call lcl_ChangeFootnoteRef, not sure if worth it) + // note: must be done *before* changing listeners! + sal_Int32 nLast(0); + std::vector<std::pair<sal_Int32, sal_Int32>> hidden; + for (auto const& rExtent : extents) + { + if (rExtent.pNode != &rTextNode) + { + break; + } + if (rExtent.nStart != 0) + { + assert(rExtent.nStart != nLast); + hidden.emplace_back(nLast, rExtent.nStart); + } + nLast = rExtent.nEnd; + } + if (nLast != rTextNode.Len()) + { + hidden.emplace_back(nLast, rTextNode.Len()); + } + sw::RemoveFootnotesForNode(rFrame, rTextNode, &hidden); + // unfortunately DelFrames() must be done before StartListening too, + // otherwise footnotes cannot be deleted by SwTextFootnote::DelFrames! + for (auto iter = ++nodes.begin(); iter != nodes.end(); ++iter) + { + (**iter).DelFrames(); // FIXME only those in this layout? + } + } auto pRet(o3tl::make_unique<sw::MergedPara>(rFrame, std::move(extents), mergedText.makeStringAndClear(), pParaPropsNode, &rTextNode)); for (SwTextNode * pTmp : nodes) diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index d5913ba9b3b4..a548c55ed2cc 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -612,7 +612,7 @@ SwTextFrame::SwTextFrame(SwTextNode * const pNode, SwFrame* pSib ) , mnHeightOfLastLine( 0 ) , mnAdditionalFirstLineOffset( 0 ) // note: this may change this->pRegisteredIn to m_pMergedPara->listeners - , m_pMergedPara(CheckParaRedlineMerge(*this, *pNode)) // ensure it is inited + , m_pMergedPara(CheckParaRedlineMerge(*this, *pNode, sw::FrameMode::New)) // ensure it is inited , mnOffset( 0 ) , mnCacheIndex( USHRT_MAX ) , mbLocked( false ) @@ -631,9 +631,16 @@ SwTextFrame::SwTextFrame(SwTextNode * const pNode, SwFrame* pSib ) mnFrameType = SwFrameType::Txt; } -static void RemoveFootnotesForNode( - SwTextFrame const& rTextFrame, SwTextNode const& rTextNode) +namespace sw { + +void RemoveFootnotesForNode( + SwTextFrame const& rTextFrame, SwTextNode const& rTextNode, + std::vector<std::pair<sal_Int32, sal_Int32>> const*const pExtents) { + if (pExtents && pExtents->empty()) + { + return; // nothing to do + } const SwFootnoteIdxs &rFootnoteIdxs = rTextNode.GetDoc()->GetFootnoteIdxs(); size_t nPos = 0; sal_uLong const nIndex = rTextNode.GetIndex(); @@ -645,16 +652,33 @@ static void RemoveFootnotesForNode( if (nPos || &rTextNode != &(rFootnoteIdxs[ nPos ]->GetTextNode())) ++nPos; } - while (nPos < rFootnoteIdxs.size()) + size_t iter(0); + for ( ; nPos < rFootnoteIdxs.size(); ++nPos) { SwTextFootnote* pTextFootnote = rFootnoteIdxs[ nPos ]; if (pTextFootnote->GetTextNode().GetIndex() > nIndex) break; + if (pExtents) + { + while ((*pExtents)[iter].second <= pTextFootnote->GetStart()) + { + ++iter; + if (iter == pExtents->size()) + { + return; + } + } + if (pTextFootnote->GetStart() < (*pExtents)[iter].first) + { + continue; + } + } pTextFootnote->DelFrames( &rTextFrame ); - ++nPos; } } +} // namespace sw + void SwTextFrame::DestroyImpl() { // Remove associated SwParaPortion from s_pTextCache @@ -674,7 +698,7 @@ void SwTextFrame::DestroyImpl() // sw_redlinehide: not sure if it's necessary to check // if the nodes are still alive here, which would require // accessing WriterMultiListener::m_vDepends - RemoveFootnotesForNode(*this, *pNode); + sw::RemoveFootnotesForNode(*this, *pNode, nullptr); } } } @@ -683,7 +707,7 @@ void SwTextFrame::DestroyImpl() SwTextNode *const pNode(static_cast<SwTextNode*>(GetDep())); if (pNode) { - RemoveFootnotesForNode(*this, *pNode); + sw::RemoveFootnotesForNode(*this, *pNode, nullptr); } } } commit b5f994b199f6956db8857fecb58902bf94d61afe Author: Michael Stahl <[email protected]> AuthorDate: Tue Jul 31 17:51:54 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Tue Jul 31 17:51:54 2018 +0200 sw_redlinehide_2: invalid position from SwTextCursor::GetCursorOfst() The problem here is that nCurrStart is incremented, but then the early return isn't taken, so a position of nCurrStart + nLength is returned, and if the portion is the last in the line it will be beyond the end of the paragraph. (regression from CWS smarttags3) Change-Id: I58a0591202bd664a89c395ea06098eb939a7ed93 diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx index 4103b8505b77..ea544492a358 100644 --- a/sw/source/core/text/itrcrsr.cxx +++ b/sw/source/core/text/itrcrsr.cxx @@ -1477,8 +1477,10 @@ TextFrameIndex SwTextCursor::GetCursorOfst( SwPosition *pPos, const Point &rPoin { if ( nWidth ) { - // Else we may not enter the character-supplying frame... - if( !( bChgNode && pPos && pPor->IsFlyCntPortion() ) ) + // no quick return for as-character frames, we want to peek inside + if (!(bChgNode && pPos && pPor->IsFlyCntPortion()) + // if we want to get the position inside the field, we should not return + && (!pCMS || !pCMS->m_pSpecialPos)) { if ( pPor->InFieldGrp() || ( pPor->IsMultiPortion() && @@ -1507,9 +1509,7 @@ TextFrameIndex SwTextCursor::GetCursorOfst( SwPosition *pPos, const Point &rPoin && ( bRightAllowed || !bLastHyph )) ++nCurrStart; - // if we want to get the position inside the field, we should not return - if ( !pCMS || !pCMS->m_pSpecialPos ) - return nCurrStart; + return nCurrStart; } } else commit adf9f83edfeba1dc59f7c5ec9ff02a4a361fe6c9 Author: Michael Stahl <[email protected]> AuthorDate: Tue Jul 31 15:20:00 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Tue Jul 31 15:20:00 2018 +0200 sw_redlinehide_2: fix use-after-free of SwFont SwTextSizeInfo::m_pFnt may be an alias of either SwAttrIter or SwAttrHandler's SwFont members; keep these alive if they exist when re-initialising from SwAttrIter::Seek(). Change-Id: I8fcbcf3aa339dfc6fa33b5439facadc6034c8cf5 diff --git a/sw/source/core/text/atrstck.cxx b/sw/source/core/text/atrstck.cxx index 345400cede4f..ecae4e4a8385 100644 --- a/sw/source/core/text/atrstck.cxx +++ b/sw/source/core/text/atrstck.cxx @@ -401,8 +401,17 @@ void SwAttrHandler::Init( const SfxPoolItem** pPoolItem, const SwAttrSet* pAS, } // It is possible, that Init is called more than once, e.g., in a - // SwTextFrame::FormatOnceMore situation. - m_pFnt.reset( new SwFont(rFnt) ); + // SwTextFrame::FormatOnceMore situation or (since sw_redlinehide) + // from SwAttrIter::Seek(); in the latter case SwTextSizeInfo::m_pFnt + // is an alias of m_pFnt so it must not be deleted! + if (m_pFnt) + { + *m_pFnt = rFnt; + } + else + { + m_pFnt.reset(new SwFont(rFnt)); + } } void SwAttrHandler::Reset( ) diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx index 0d2a39f5fdad..aba968a8740f 100644 --- a/sw/source/core/text/redlnitr.cxx +++ b/sw/source/core/text/redlnitr.cxx @@ -135,8 +135,18 @@ void SwAttrIter::InitFontAndAttrHandler(SwTextNode const& rTextNode, { // Build a font matching the default paragraph style: SwFontAccess aFontAccess( &rTextNode.GetAnyFormatColl(), m_pViewShell ); - delete m_pFont; - m_pFont = new SwFont( aFontAccess.Get()->GetFont() ); + // It is possible that Init is called more than once, e.g., in a + // SwTextFrame::FormatOnceMore situation or (since sw_redlinehide) + // from SwAttrIter::Seek(); in the latter case SwTextSizeInfo::m_pFnt + // is an alias of m_pFont so it must not be deleted! + if (m_pFont) + { + *m_pFont = aFontAccess.Get()->GetFont(); + } + else + { + m_pFont = new SwFont( aFontAccess.Get()->GetFont() ); + } // set font to vertical if frame layout is vertical // if it's a re-init, the vert flag never changes commit 48d8ec80e9fef1e9c617e1b363793112f2f3b8b3 Author: Michael Stahl <[email protected]> AuthorDate: Tue Jul 31 15:17:14 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Tue Jul 31 15:17:14 2018 +0200 sw_redlinehide_2: fix crash in SwAttrIter::Seek() There aren't necessarily hints in every merged node. Change-Id: Id83319d8846602b65d9d25b850a8254daf8c54ff diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx index bdc4d88b9f13..0eeeff080669 100644 --- a/sw/source/core/text/itratr.cxx +++ b/sw/source/core/text/itratr.cxx @@ -308,20 +308,23 @@ bool SwAttrIter::Seek(TextFrameIndex const nNewPos) { // Skipping to a different node - first seek until the end of this node // to get rid of all hint items - sal_Int32 nPos(m_nPosition); - do + if (m_pTextNode->GetpSwpHints()) { - nPos = GetNextAttrImpl(m_pTextNode, m_nStartIndex, m_nEndIndex, nPos); - if (nPos <= m_pTextNode->Len()) - { - SeekFwd(nPos); - } - else + sal_Int32 nPos(m_nPosition); + do { - SeekFwd(m_pTextNode->Len()); + nPos = GetNextAttrImpl(m_pTextNode, m_nStartIndex, m_nEndIndex, nPos); + if (nPos <= m_pTextNode->Len()) + { + SeekFwd(nPos); + } + else + { + SeekFwd(m_pTextNode->Len()); + } } + while (nPos < m_pTextNode->Len()); } - while (nPos < m_pTextNode->Len()); assert(m_nChgCnt == 0); // should have reset it all? there cannot be ExtOn() inside of a Delete redline, surely? // Unapply current para items: // the SwAttrHandler doesn't appear to be capable of *unapplying* commit 191614ff99ba1e26727a264c7610f754a2d6905b Author: Michael Stahl <[email protected]> AuthorDate: Tue Jul 31 15:14:23 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Tue Jul 31 15:14:23 2018 +0200 sw_redlinehide_2: incorrect node returned by MergedAttrIterMulti Change-Id: I0aa83b5902b2e0e4d0c5371cdbf6ce6dccbf6e74 diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx index 13b7207b71d9..80982dd5dcc6 100644 --- a/sw/source/core/text/pormulti.cxx +++ b/sw/source/core/text/pormulti.cxx @@ -875,7 +875,7 @@ namespace sw { rExtent.pNode != m_pMerged->extents[m_CurrentExtent].pNode) { m_CurrentHint = 0; // reset - rpNode = rExtent.pNode; + rpNode = m_pMerged->extents[m_CurrentExtent].pNode; return nullptr; } } _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
