diff options
Diffstat (limited to 'sw/source/core/undo/untblk.cxx')
-rw-r--r-- | sw/source/core/undo/untblk.cxx | 136 |
1 files changed, 72 insertions, 64 deletions
diff --git a/sw/source/core/undo/untblk.cxx b/sw/source/core/undo/untblk.cxx index 5fd92fe63eca..55ae66b86fd9 100644 --- a/sw/source/core/undo/untblk.cxx +++ b/sw/source/core/undo/untblk.cxx @@ -25,6 +25,7 @@ #include <IDocumentRedlineAccess.hxx> #include <IShellCursorSupplier.hxx> #include <docary.hxx> +#include <swcrsr.hxx> #include <swundo.hxx> #include <pam.hxx> #include <mvsave.hxx> @@ -36,23 +37,24 @@ namespace sw { -std::unique_ptr<std::vector<SwFrameFormat*>> -GetFlysAnchoredAt(SwDoc & rDoc, sal_uLong const nSttNode) +std::optional<std::vector<SwFrameFormat*>> +GetFlysAnchoredAt(SwDoc & rDoc, SwNodeOffset const nSttNode, bool const isAtPageIncluded) { - std::unique_ptr<std::vector<SwFrameFormat*>> pFrameFormats; + std::optional<std::vector<SwFrameFormat*>> pFrameFormats; const size_t nArrLen = rDoc.GetSpzFrameFormats()->size(); for (size_t n = 0; n < nArrLen; ++n) { SwFrameFormat *const pFormat = (*rDoc.GetSpzFrameFormats())[n]; SwFormatAnchor const*const pAnchor = &pFormat->GetAnchor(); - SwPosition const*const pAPos = pAnchor->GetContentAnchor(); - if (pAPos - && nSttNode == pAPos->nNode.GetIndex() - && ((pAnchor->GetAnchorId() == RndStdIds::FLY_AT_PARA) - || (pAnchor->GetAnchorId() == RndStdIds::FLY_AT_CHAR))) + SwNode const*const pAnchorNode = pAnchor->GetAnchorNode(); + if ((pAnchorNode + && nSttNode == pAnchorNode->GetIndex() + && ((pAnchor->GetAnchorId() == RndStdIds::FLY_AT_PARA) + || (pAnchor->GetAnchorId() == RndStdIds::FLY_AT_CHAR))) + || (isAtPageIncluded && pAnchor->GetAnchorId() == RndStdIds::FLY_AT_PAGE)) { if (!pFrameFormats) - pFrameFormats.reset( new std::vector<SwFrameFormat*> ); + pFrameFormats.emplace(); pFrameFormats->push_back( pFormat ); } } @@ -74,7 +76,7 @@ SwUndoInserts::SwUndoInserts( SwUndoId nUndoId, const SwPaM& rPam ) m_pHistory.reset( new SwHistory ); SwDoc& rDoc = rPam.GetDoc(); - SwTextNode* pTextNd = rPam.GetPoint()->nNode.GetNode().GetTextNode(); + SwTextNode* pTextNd = rPam.GetPoint()->GetNode().GetTextNode(); if( pTextNd ) { m_pTextFormatColl = pTextNd->GetTextColl(); @@ -88,7 +90,7 @@ SwUndoInserts::SwUndoInserts( SwUndoId nUndoId, const SwPaM& rPam ) // These flys will be saved in pFrameFormats array (only flys which exist BEFORE insertion!) // Then in SwUndoInserts::SetInsertRange the flys saved in pFrameFormats will NOT create Undos. // m_FlyUndos will only be filled with newly inserted flys. - m_pFrameFormats = sw::GetFlysAnchoredAt(rDoc, m_nSttNode); + m_pFrameFormats = sw::GetFlysAnchoredAt(rDoc, m_nSttNode, true); } // consider Redline if( rDoc.getIDocumentRedlineAccess().IsRedlineOn() ) @@ -111,11 +113,11 @@ SwUndoInserts::SwUndoInserts( SwUndoId nUndoId, const SwPaM& rPam ) // Flys, anchored to any paragraph, but not first and last, are handled by DelContentIndex (see SwUndoInserts::UndoImpl) and are not stored in m_FlyUndos. void SwUndoInserts::SetInsertRange( const SwPaM& rPam, bool bScanFlys, - int const nDeleteTextNodes) + SwNodeOffset const nDeleteTextNodes) { const SwPosition* pTmpPos = rPam.End(); - m_nEndNode = pTmpPos->nNode.GetIndex(); - m_nEndContent = pTmpPos->nContent.GetIndex(); + m_nEndNode = pTmpPos->GetNodeIndex(); + m_nEndContent = pTmpPos->GetContentIndex(); if( rPam.HasMark() ) { if( pTmpPos == rPam.GetPoint() ) @@ -123,11 +125,11 @@ void SwUndoInserts::SetInsertRange( const SwPaM& rPam, bool bScanFlys, else pTmpPos = rPam.GetPoint(); - m_nSttNode = pTmpPos->nNode.GetIndex(); - m_nSttContent = pTmpPos->nContent.GetIndex(); + m_nSttNode = pTmpPos->GetNodeIndex(); + m_nSttContent = pTmpPos->GetContentIndex(); m_nDeleteTextNodes = nDeleteTextNodes; - if (m_nDeleteTextNodes == 0) // if a table selection is added... + if (m_nDeleteTextNodes == SwNodeOffset(0)) // if a table selection is added... { ++m_nSttNode; // ... then the CopyPam is not fully correct } @@ -152,7 +154,7 @@ void SwUndoInserts::SetInsertRange( const SwPaM& rPam, bool bScanFlys, m_pFrameFormats->end() == ( it = std::find( m_pFrameFormats->begin(), m_pFrameFormats->end(), pFormat ) ) ) { std::shared_ptr<SwUndoInsLayFormat> const pFlyUndo = - std::make_shared<SwUndoInsLayFormat>(pFormat, 0, 0); + std::make_shared<SwUndoInsLayFormat>(pFormat, SwNodeOffset(0), 0); m_FlyUndos.push_back(pFlyUndo); } else @@ -171,18 +173,23 @@ void SwUndoInserts::SetInsertRange( const SwPaM& rPam, bool bScanFlys, that the Undo/Redo run in inverse order. */ bool SwUndoInserts::IsCreateUndoForNewFly(SwFormatAnchor const& rAnchor, - sal_uLong const nStartNode, sal_uLong const nEndNode) + SwNodeOffset const nStartNode, SwNodeOffset const nEndNode) { assert(nStartNode <= nEndNode); + if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE) + { + return true; // needed for SwUndoInserts/SwReader::Read() + } + // check all at-char flys at the start/end nodes: // ExcludeFlyAtStartEnd will exclude them! - SwPosition const*const pAnchorPos = rAnchor.GetContentAnchor(); - return pAnchorPos != nullptr + SwNode const*const pAnchorNode = rAnchor.GetAnchorNode(); + return pAnchorNode != nullptr && ( rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR) - && ( nStartNode == pAnchorPos->nNode.GetIndex() - || nEndNode == pAnchorPos->nNode.GetIndex()); + && ( nStartNode == pAnchorNode->GetIndex() + || nEndNode == pAnchorNode->GetIndex()); } void SwUndoInserts::dumpAsXml(xmlTextWriterPtr pWriter) const @@ -220,13 +227,13 @@ void SwUndoInserts::dumpAsXml(xmlTextWriterPtr pWriter) const SwUndoInserts::~SwUndoInserts() { - if (m_pUndoNodeIndex) // delete also the section from UndoNodes array + if (m_oUndoNodeIndex) // delete also the section from UndoNodes array { // Insert saves content in IconSection - SwNodes& rUNds = m_pUndoNodeIndex->GetNodes(); - rUNds.Delete(*m_pUndoNodeIndex, - rUNds.GetEndOfExtras().GetIndex() - m_pUndoNodeIndex->GetIndex()); - m_pUndoNodeIndex.reset(); + SwNodes& rUNds = m_oUndoNodeIndex->GetNodes(); + rUNds.Delete(*m_oUndoNodeIndex, + rUNds.GetEndOfExtras().GetIndex() - m_oUndoNodeIndex->GetIndex()); + m_oUndoNodeIndex.reset(); } m_pFrameFormats.reset(); m_pRedlineData.reset(); @@ -257,15 +264,15 @@ void SwUndoInserts::UndoImpl(::sw::UndoRedoContext & rContext) SwDoc& rDoc = rContext.GetDoc(); SwPaM& rPam = AddUndoRedoPaM(rContext); - m_nNodeDiff = 0; + m_nNodeDiff = SwNodeOffset(0); if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags() )) rDoc.getIDocumentRedlineAccess().DeleteRedline(rPam, true, RedlineType::Any); // if Point and Mark are different text nodes so a JoinNext has to be done bool bJoinNext = m_nSttNode != m_nEndNode && - rPam.GetMark()->nNode.GetNode().GetTextNode() && - rPam.GetPoint()->nNode.GetNode().GetTextNode(); + rPam.GetMark()->GetNode().GetTextNode() && + rPam.GetPoint()->GetNode().GetTextNode(); // Is there any content? (loading from template does not have content) if( m_nSttNode != m_nEndNode || m_nSttContent != m_nEndContent ) @@ -292,51 +299,49 @@ void SwUndoInserts::UndoImpl(::sw::UndoRedoContext & rContext) // indexes if (!m_FlyUndos.empty()) { - sal_uLong nTmp = rPam.GetPoint()->nNode.GetIndex(); + SwNodeOffset nTmp = rPam.GetPoint()->GetNodeIndex(); for (size_t n = m_FlyUndos.size(); 0 < n; --n) { m_FlyUndos[ n-1 ]->UndoImpl(rContext); } - m_nNodeDiff += nTmp - rPam.GetPoint()->nNode.GetIndex(); + m_nNodeDiff += nTmp - rPam.GetPoint()->GetNodeIndex(); } if (m_nSttNode != m_nEndNode || m_nSttContent != m_nEndContent) { // are there Footnotes or ContentFlyFrames in text? m_nSetPos = m_pHistory->Count(); - sal_uLong nTmp = rPam.GetMark()->nNode.GetIndex(); + SwNodeOffset nTmp = rPam.GetMark()->GetNodeIndex(); DelContentIndex(*rPam.GetMark(), *rPam.GetPoint(), DelContentType::AllMask|DelContentType::ExcludeFlyAtStartEnd); - m_nNodeDiff += nTmp - rPam.GetMark()->nNode.GetIndex(); + m_nNodeDiff += nTmp - rPam.GetMark()->GetNodeIndex(); if( *rPam.GetPoint() != *rPam.GetMark() ) { - m_pUndoNodeIndex.reset( - new SwNodeIndex(rDoc.GetNodes().GetEndOfContent())); - MoveToUndoNds(rPam, m_pUndoNodeIndex.get()); + m_oUndoNodeIndex.emplace(rDoc.GetNodes().GetEndOfContent()); + MoveToUndoNds(rPam, &*m_oUndoNodeIndex); - if (m_nDeleteTextNodes == 0) + if (m_nDeleteTextNodes == SwNodeOffset(0)) { rPam.Move( fnMoveBackward, GoInContent ); } } } - SwNodeIndex& rIdx = rPam.GetPoint()->nNode; - SwTextNode* pTextNode = rIdx.GetNode().GetTextNode(); + SwTextNode* pTextNode = rPam.GetPoint()->GetNode().GetTextNode(); if( !pTextNode ) return; if( !m_pTextFormatColl ) // if 0 than it's no TextNode -> delete { - SwNodeIndex aDelIdx( rIdx ); - assert(0 < m_nDeleteTextNodes && m_nDeleteTextNodes < 3); - for (int i = 0; i < m_nDeleteTextNodes; ++i) + SwNodeIndex aDelIdx( *pTextNode ); + assert(SwNodeOffset(0) < m_nDeleteTextNodes && m_nDeleteTextNodes < SwNodeOffset(3)); + for (SwNodeOffset i(0); i < m_nDeleteTextNodes; ++i) { rPam.Move(fnMoveForward, GoInNode); } rPam.DeleteMark(); - for (int i = 0; i < m_nDeleteTextNodes; ++i) + for (SwNodeOffset i(0); i < m_nDeleteTextNodes; ++i) { RemoveIdxRel(aDelIdx.GetIndex() + i, *rPam.GetPoint()); } @@ -348,13 +353,13 @@ void SwUndoInserts::UndoImpl(::sw::UndoRedoContext & rContext) if( bJoinNext && pTextNode->CanJoinNext()) { { - RemoveIdxRel( rIdx.GetIndex()+1, SwPosition( rIdx, - SwIndex( pTextNode, pTextNode->GetText().getLength() ))); + RemoveIdxRel( pTextNode->GetIndex()+1, + SwPosition( *pTextNode, pTextNode, pTextNode->GetText().getLength() ) ); } pTextNode->JoinNext(); } // reset all text attributes in the paragraph! - pTextNode->RstTextAttr( SwIndex(pTextNode, 0), pTextNode->Len(), 0, nullptr, true ); + pTextNode->RstTextAttr( 0, pTextNode->Len(), 0, nullptr, true ); pTextNode->ResetAllAttr(); @@ -372,12 +377,11 @@ void SwUndoInserts::UndoImpl(::sw::UndoRedoContext & rContext) void SwUndoInserts::RedoImpl(::sw::UndoRedoContext & rContext) { // position cursor onto REDO section - SwPaM& rPam(rContext.GetCursorSupplier().CreateNewShellCursor()); + SwCursor& rPam(rContext.GetCursorSupplier().CreateNewShellCursor()); SwDoc& rDoc = rPam.GetDoc(); rPam.DeleteMark(); - rPam.GetPoint()->nNode = m_nSttNode - m_nNodeDiff; - SwContentNode* pCNd = rPam.GetContentNode(); - rPam.GetPoint()->nContent.Assign( pCNd, m_nSttContent ); + rPam.GetPoint()->Assign( m_nSttNode - m_nNodeDiff, m_nSttContent ); + SwContentNode* pCNd = rPam.GetPointContentNode(); SwTextFormatColl* pSavTextFormatColl = m_pTextFormatColl; if( m_pTextFormatColl && pCNd && pCNd->IsTextNode() ) @@ -386,26 +390,30 @@ void SwUndoInserts::RedoImpl(::sw::UndoRedoContext & rContext) m_pHistory->SetTmpEnd( m_nSetPos ); // retrieve start position for rollback - if( ( m_nSttNode != m_nEndNode || m_nSttContent != m_nEndContent ) && m_pUndoNodeIndex) + if( ( m_nSttNode != m_nEndNode || m_nSttContent != m_nEndContent ) && m_oUndoNodeIndex) { auto const pFlysAtInsPos(sw::GetFlysAnchoredAt(rDoc, - rPam.GetPoint()->nNode.GetIndex())); + rPam.GetPoint()->GetNodeIndex(), false)); - const bool bMvBkwrd = MovePtBackward(rPam); + ::std::optional<SwNodeIndex> oMvBkwrd = MovePtBackward(rPam); + bool const isMoveFlyAnchors(!oMvBkwrd // equivalent to bCanMoveBack + || m_oUndoNodeIndex->GetNode().IsTextNode() + || (oMvBkwrd->GetNode().IsStartNode() + && m_oUndoNodeIndex->GetNode().IsSectionNode())); - // re-insert content again (first detach m_pUndoNodeIndex!) - sal_uLong const nMvNd = m_pUndoNodeIndex->GetIndex(); - m_pUndoNodeIndex.reset(); + // re-insert content again (first detach m_oUndoNodeIndex!) + SwNodeOffset const nMvNd = m_oUndoNodeIndex->GetIndex(); + m_oUndoNodeIndex.reset(); MoveFromUndoNds(rDoc, nMvNd, *rPam.GetMark()); - if (m_nDeleteTextNodes != 0) + if (m_nDeleteTextNodes != SwNodeOffset(0) || oMvBkwrd) { - MovePtForward(rPam, bMvBkwrd); + MovePtForward(rPam, ::std::move(oMvBkwrd)); } rPam.Exchange(); // at-char anchors post SplitNode are on index 0 of 2nd node and will // remain there - move them back to the start (end would also work?) - if (pFlysAtInsPos) + if (pFlysAtInsPos && isMoveFlyAnchors) { for (SwFrameFormat * pFly : *pFlysAtInsPos) { @@ -422,16 +430,16 @@ void SwUndoInserts::RedoImpl(::sw::UndoRedoContext & rContext) if (m_pTextFormatColl && rDoc.GetTextFormatColls()->IsAlive(m_pTextFormatColl)) { - SwTextNode* pTextNd = rPam.GetMark()->nNode.GetNode().GetTextNode(); + SwTextNode* pTextNd = rPam.GetMark()->GetNode().GetTextNode(); if( pTextNd ) pTextNd->ChgFormatColl( m_pTextFormatColl ); } m_pTextFormatColl = pSavTextFormatColl; if (m_pLastNodeColl && rDoc.GetTextFormatColls()->IsAlive(m_pLastNodeColl) - && rPam.GetPoint()->nNode != rPam.GetMark()->nNode) + && rPam.GetPoint()->GetNode() != rPam.GetMark()->GetNode()) { - SwTextNode* pTextNd = rPam.GetPoint()->nNode.GetNode().GetTextNode(); + SwTextNode* pTextNd = rPam.GetPoint()->GetNode().GetTextNode(); if( pTextNd ) pTextNd->ChgFormatColl( m_pLastNodeColl ); } |