diff options
Diffstat (limited to 'sw/source/core/txtnode/ndtxt.cxx')
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 118 |
1 files changed, 65 insertions, 53 deletions
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 3d721ebee00b..a1f17358efa5 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -64,6 +64,7 @@ #include <txtfrm.hxx> #include <ftnfrm.hxx> #include <ftnboss.hxx> +#include <pagefrm.hxx> #include <rootfrm.hxx> #include <pagedesc.hxx> #include <expfld.hxx> @@ -456,9 +457,7 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos, { // optimization for SplitNode: If a split is at the end of a node then // move the frames from the current to the new one and create new ones - // for the current one. As a result, no need for recreating the layout. - - LockModify(); // disable notifications + // for the current one. // If fly frames are moved, they don't need to destroy their layout // frames. Set a flag that is checked in SwTextFlyCnt::SetAnchor. @@ -566,28 +565,6 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos, SetInCache( false ); } - UnlockModify(); // enable notify again - - // If there is an accessible layout we must call modify even - // with length zero, because we have to notify about the changed - // text node. - const SwRootFrame *pRootFrame; - if ( (nTextLen != nSplitPos) || - ( (pRootFrame = pNode->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout()) != nullptr && - pRootFrame->IsAnyShellAccessible() ) ) - { - // tell the frames that something was "deleted" at the end - if( 1 == nTextLen - nSplitPos ) - { - SwDelChr aHint( nSplitPos ); - pNode->NotifyClients( nullptr, &aHint ); - } - else - { - SwDelText aHint( nSplitPos, nTextLen - nSplitPos ); - pNode->NotifyClients( nullptr, &aHint ); - } - } if ( HasHints() ) { MoveTextAttr_To_AttrSet(); @@ -690,9 +667,9 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos, // Update the extents with new node; also inits merge flag, // so the MakeFramesForAdjacentContentNode below respects it pFrame->RegisterToNode(*pNode); - if (pFrame->GetText().isEmpty()) + if (nSplitPos == 0) { - // turns out it's empty - in this case, it was not + // in this case, it was not // invalidated because Cut didn't sent it any hints, // so we have to invalidate it here! pFrame->Prepare(PREP_CLEAR, nullptr, false); @@ -918,9 +895,18 @@ void CheckResetRedlineMergeFlag(SwTextNode & rNode, Recreate const eRecreateMerg assert(rFirstNode.GetIndex() <= rNode.GetIndex()); pFrame->SetMergedPara(sw::CheckParaRedlineMerge( *pFrame, rFirstNode, eMode)); - assert(pFrame->GetMergedPara()); - assert(pFrame->GetMergedPara()->listener.IsListeningTo(&rNode)); - assert(rNode.GetIndex() <= pFrame->GetMergedPara()->pLastNode->GetIndex()); + // there is no merged para in case the deleted node had one but + // nothing was actually hidden + if (pFrame->GetMergedPara()) + { + assert(pFrame->GetMergedPara()->listener.IsListeningTo(&rNode)); + assert(rNode.GetIndex() <= pFrame->GetMergedPara()->pLastNode->GetIndex()); + // tdf#135978 Join: recreate fly frames anchored to subsequent nodes + if (eRecreateMerged == sw::Recreate::ThisNode) + { + AddRemoveFlysAnchoredToFrameStartingAtNode(*pFrame, rNode, nullptr); + } + } eMode = sw::FrameMode::New; // Existing is not idempotent! } } @@ -1031,14 +1017,29 @@ SwContentNode *SwTextNode::JoinNext() pDoc->CorrAbs( aIdx, SwPosition( *this ), nOldLen, true ); } SwNode::Merge const eOldMergeFlag(pTextNode->GetRedlineMergeFlag()); + auto eRecreateMerged(eOldMergeFlag == SwNode::Merge::First + ? sw::Recreate::ThisNode + : sw::Recreate::No); + if (eRecreateMerged == sw::Recreate::No) + { + // tdf#137318 if a delete is inside one node, flag is still None! + SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pTextNode); + for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next()) + { + if (pFrame->GetMergedPara()) + { + eRecreateMerged = sw::Recreate::ThisNode; + break; + } + } + } + rNds.Delete(aIdx); SetWrong( pList, false ); SetGrammarCheck( pList3, false ); SetSmartTags( pList2, false ); InvalidateNumRule(); - CheckResetRedlineMergeFlag(*this, eOldMergeFlag == SwNode::Merge::First - ? sw::Recreate::ThisNode - : sw::Recreate::No); + CheckResetRedlineMergeFlag(*this, eRecreateMerged); } else { OSL_FAIL( "No TextNode." ); @@ -1175,8 +1176,7 @@ void SwTextNode::NewAttrSet( SwAttrPool& rPool ) void SwTextNode::Update( SwIndex const & rPos, const sal_Int32 nChangeLen, - const bool bNegative, - const bool bDelete ) + UpdateMode const eMode) { SetAutoCompleteWordDirty( true ); @@ -1185,7 +1185,7 @@ void SwTextNode::Update( if ( HasHints() ) { - if ( bNegative ) + if (eMode & UpdateMode::Negative) { std::vector<SwTextInputField*> aTextInputFields; @@ -1357,7 +1357,7 @@ void SwTextNode::Update( bool bSortMarks = false; SwIndexReg aTmpIdxReg; - if ( !bNegative && !bDelete ) + if (!(eMode & UpdateMode::Negative) && !(eMode & UpdateMode::Delete)) { const SwRedlineTable& rTable = GetDoc()->getIDocumentRedlineAccess().GetRedlineTable(); for (SwRangeRedline* pRedl : rTable) @@ -1392,6 +1392,7 @@ void SwTextNode::Update( // Bookmarks must never grow to either side, when editing (directly) // to the left or right (i#29942)! Exception: if the bookmark has // 2 positions and start == end, then expand it (tdf#96479) + if (!(eMode & UpdateMode::Replace)) // Exception: Replace { bool bAtLeastOneBookmarkMoved = false; bool bAtLeastOneExpandedBookmarkAtInsertionPosition = false; @@ -1514,7 +1515,7 @@ void SwTextNode::Update( } // base class - SwIndexReg::Update( rPos, nChangeLen, bNegative, bDelete ); + SwIndexReg::Update(rPos, nChangeLen, eMode); if (pCollector) { @@ -1533,10 +1534,21 @@ void SwTextNode::Update( //Any drawing objects anchored into this text node may be sorted by their //anchor position which may have changed here, so resort them - SwContentFrame* pContentFrame = getLayoutFrame(GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout()); - SwSortedObjs* pSortedObjs = pContentFrame ? pContentFrame->GetDrawObjs() : nullptr; - if (pSortedObjs) - pSortedObjs->UpdateAll(); + SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> iter(*this); + for (SwTextFrame* pFrame = iter.First(); pFrame; pFrame = iter.Next()) + { + SwSortedObjs * pSortedObjs(pFrame->GetDrawObjs()); + if (pSortedObjs) + { + pSortedObjs->UpdateAll(); + } + // also sort the objs on the page frame + pSortedObjs = pFrame->FindPageFrame()->GetSortedObjs(); + if (pSortedObjs) // doesn't exist yet if called for inserting as-char fly + { + pSortedObjs->UpdateAll(); + } + } // Update the paragraph signatures. if (SwEditShell* pEditShell = GetDoc()->GetEditShell()) @@ -2311,7 +2323,7 @@ OUString SwTextNode::InsertText( const OUString & rStr, const SwIndex & rIdx, SetIgnoreDontExpand( true ); } - Update( rIdx, nLen ); // text content changed! + Update(rIdx, nLen, UpdateMode::Default); // text content changed! if (nMode & SwInsertFlags::FORCEHINTEXPAND) { @@ -2447,7 +2459,7 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart, if (bUpdate) { // Update all SwIndex - pDest->Update( rDestStart, nLen, false, false/*??? why was it true*/); + pDest->Update(rDestStart, nLen, UpdateMode::Default); } CHECK_SWPHINTS(pDest); @@ -2640,7 +2652,7 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart, ++nAttrCnt; } } - Update( rStart, nLen, true, true ); + Update(rStart, nLen, UpdateMode::Negative|UpdateMode::Delete); for (SwTextAttr* pHt : aArr) { @@ -2651,7 +2663,7 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart, } else { - Update( rStart, nLen, true, true ); + Update(rStart, nLen, UpdateMode::Negative|UpdateMode::Delete); } // set after moving hints @@ -2744,7 +2756,7 @@ void SwTextNode::EraseText(const SwIndex &rIdx, const sal_Int32 nCount, TryDeleteSwpHints(); - Update( rIdx, nCnt, true ); + Update(rIdx, nCnt, UpdateMode::Negative); if( 1 == nCnt ) { @@ -3094,11 +3106,11 @@ sal_uInt16 lcl_BoundListLevel(const int nActualLevel) } // -> #i29560# -bool SwTextNode::HasNumber() const +bool SwTextNode::HasNumber(SwRootFrame const*const pLayout) const { bool bResult = false; - const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : nullptr; + const SwNumRule *const pRule = GetNum(pLayout) ? GetNum(pLayout)->GetNumRule() : nullptr; if ( pRule ) { const SwNumFormat& aFormat(pRule->Get(lcl_BoundListLevel(GetActualListLevel()))); @@ -3732,19 +3744,19 @@ void SwTextNode::ReplaceText( const SwIndex& rStart, const sal_Int32 nDelLen, ++const_cast<SwIndex&>(rStart); m_Text = m_Text.replaceAt(rStart.GetIndex(), nLen - 1, ""); - Update( rStart, nLen - 1, true ); + Update(rStart, nLen - 1, UpdateMode::Negative); OUString aTmpText( sInserted.copy(1) ); m_Text = m_Text.replaceAt(rStart.GetIndex(), 0, aTmpText); - Update( rStart, aTmpText.getLength() ); + Update(rStart, aTmpText.getLength(), UpdateMode::Replace); } else { m_Text = m_Text.replaceAt(nStartPos, nLen, ""); - Update( rStart, nLen, true ); + Update(rStart, nLen, UpdateMode::Negative); m_Text = m_Text.replaceAt(nStartPos, 0, sInserted); - Update( rStart, sInserted.getLength() ); + Update(rStart, sInserted.getLength(), UpdateMode::Replace); } SetIgnoreDontExpand( bOldExpFlg ); |