summaryrefslogtreecommitdiff
path: root/sw/source/core/undo/untblk.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/undo/untblk.cxx')
-rw-r--r--sw/source/core/undo/untblk.cxx136
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 );
}