ITEM: Refactor ItemType
[LibreOffice.git] / sw / source / core / undo / unmove.cxx
blob0ea6443f611a4078bd5d79d43da5fcb777b9636e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <UndoSplitMove.hxx>
21 #include <doc.hxx>
22 #include <pam.hxx>
23 #include <swundo.hxx>
24 #include <ndtxt.hxx>
25 #include <UndoCore.hxx>
26 #include <rolbck.hxx>
28 // MOVE
29 SwUndoMove::SwUndoMove( const SwPaM& rRange, const SwPosition& rMvPos )
30 : SwUndo( SwUndoId::MOVE, &rRange.GetDoc() )
31 , SwUndRng( rRange )
32 , m_nDestStartNode(0)
33 , m_nDestEndNode(0)
34 , m_nInsPosNode(0)
35 , m_nMoveDestNode(rMvPos.GetNodeIndex())
36 , m_nDestStartContent(0)
37 , m_nDestEndContent(0)
38 , m_nInsPosContent(0)
39 , m_nMoveDestContent(rMvPos.GetContentIndex())
40 , m_bJoinNext(false)
41 , m_bMoveRange(false)
42 , m_bMoveRedlines(false)
44 // get StartNode from footnotes before delete!
45 SwDoc& rDoc = rRange.GetDoc();
46 SwTextNode* pTextNd = rDoc.GetNodes()[ m_nSttNode ]->GetTextNode();
47 SwTextNode* pEndTextNd = rDoc.GetNodes()[ m_nEndNode ]->GetTextNode();
49 m_pHistory.reset( new SwHistory );
51 if( pTextNd )
53 m_pHistory->AddColl(pTextNd->GetTextColl(), m_nSttNode, SwNodeType::Text);
54 if ( pTextNd->GetpSwpHints() )
56 m_pHistory->CopyAttr( pTextNd->GetpSwpHints(), m_nSttNode,
57 0, pTextNd->GetText().getLength(), false );
59 if( pTextNd->HasSwAttrSet() )
60 m_pHistory->CopyFormatAttr( *pTextNd->GetpSwAttrSet(), m_nSttNode );
62 if( pEndTextNd && pEndTextNd != pTextNd )
64 m_pHistory->AddColl(pEndTextNd->GetTextColl(), m_nEndNode, SwNodeType::Text);
65 if ( pEndTextNd->GetpSwpHints() )
67 m_pHistory->CopyAttr( pEndTextNd->GetpSwpHints(), m_nEndNode,
68 0, pEndTextNd->GetText().getLength(), false );
70 if( pEndTextNd->HasSwAttrSet() )
71 m_pHistory->CopyFormatAttr( *pEndTextNd->GetpSwAttrSet(), m_nEndNode );
74 pTextNd = rMvPos.GetNode().GetTextNode();
75 if (nullptr != pTextNd)
77 m_pHistory->AddColl(pTextNd->GetTextColl(), m_nMoveDestNode, SwNodeType::Text);
78 if ( pTextNd->GetpSwpHints() )
80 m_pHistory->CopyAttr( pTextNd->GetpSwpHints(), m_nMoveDestNode,
81 0, pTextNd->GetText().getLength(), false );
83 if( pTextNd->HasSwAttrSet() )
84 m_pHistory->CopyFormatAttr( *pTextNd->GetpSwAttrSet(), m_nMoveDestNode );
87 m_nFootnoteStart = m_pHistory->Count();
88 DelFootnote( rRange );
90 if( m_pHistory && !m_pHistory->Count() )
91 m_pHistory.reset();
94 SwUndoMove::SwUndoMove( SwDoc& rDoc, const SwNodeRange& rRg,
95 const SwNode& rMvPos )
96 : SwUndo(SwUndoId::MOVE, &rDoc)
97 , m_nDestStartNode(0)
98 , m_nDestEndNode(0)
99 , m_nInsPosNode(0)
100 , m_nMoveDestNode(rMvPos.GetIndex())
101 , m_nDestStartContent(0)
102 , m_nDestEndContent(0)
103 , m_nInsPosContent(0)
104 , m_bMoveRedlines(false)
106 m_bMoveRange = true;
107 m_bJoinNext = false;
109 m_nSttContent = m_nEndContent = m_nMoveDestContent = COMPLETE_STRING;
111 m_nSttNode = rRg.aStart.GetIndex();
112 m_nEndNode = rRg.aEnd.GetIndex();
114 // DelFootnote( rRange );
115 // FIXME: duplication of the method body of DelFootnote below
117 // is the current move from ContentArea into the special section?
118 SwNodeOffset nContentStt = rDoc.GetNodes().GetEndOfAutotext().GetIndex();
119 if( m_nMoveDestNode < nContentStt && rRg.aStart.GetIndex() > nContentStt )
121 // delete all footnotes since they are undesired there
122 SwPosition aPtPos( rRg.aEnd );
123 SwContentNode* pCNd = rRg.aEnd.GetNode().GetContentNode();
124 if( pCNd )
125 aPtPos.SetContent( pCNd->Len() );
126 SwPosition aMkPos( rRg.aStart );
128 DelContentIndex( aMkPos, aPtPos, DelContentType::Ftn );
130 if( m_pHistory && !m_pHistory->Count() )
131 m_pHistory.reset();
134 m_nFootnoteStart = 0;
137 void SwUndoMove::SetDestRange( const SwNode& rStt,
138 const SwNode& rEnd,
139 const SwNodeIndex& rInsPos )
141 m_nDestStartNode = rStt.GetIndex();
142 m_nDestEndNode = rEnd.GetIndex();
143 if( m_nDestStartNode > m_nDestEndNode )
145 m_nDestStartNode = m_nDestEndNode;
146 m_nDestEndNode = rStt.GetIndex();
148 m_nInsPosNode = rInsPos.GetIndex();
150 m_nDestStartContent = m_nDestEndContent = m_nInsPosContent = COMPLETE_STRING;
153 void SwUndoMove::UndoImpl(::sw::UndoRedoContext & rContext)
155 SwDoc *const pDoc = & rContext.GetDoc();
157 // Block so that we can jump out of it
158 do {
159 // create index position and section based on the existing values
160 SwNodeIndex aIdx( pDoc->GetNodes(), m_nDestStartNode );
162 if( m_bMoveRange )
164 // only a move with SwRange
165 SwNodeRange aRg( aIdx, aIdx );
166 aRg.aEnd = m_nDestEndNode;
167 aIdx = m_nInsPosNode;
168 bool bSuccess = pDoc->getIDocumentContentOperations().MoveNodeRange( aRg, aIdx.GetNode(),
169 SwMoveFlags::DEFAULT );
170 if (!bSuccess)
171 break;
173 else
175 SwPaM aPam( aIdx.GetNode(), m_nDestStartContent,
176 *pDoc->GetNodes()[ m_nDestEndNode ], m_nDestEndContent );
178 // #i17764# if redlines are to be moved, we may not remove them
179 // before pDoc->Move gets a chance to handle them
180 if( ! m_bMoveRedlines )
181 RemoveIdxFromRange( aPam, false );
183 SwPosition aPos( *pDoc->GetNodes()[ m_nInsPosNode] );
184 SwContentNode* pCNd = aPos.GetNode().GetContentNode();
185 aPos.SetContent( m_nInsPosContent );
187 if( pCNd->HasSwAttrSet() )
188 pCNd->ResetAllAttr();
190 if( pCNd->IsTextNode() && static_cast<SwTextNode*>(pCNd)->GetpSwpHints() )
191 static_cast<SwTextNode*>(pCNd)->ClearSwpHintsArr( false );
193 // first delete all attributes at InsertPos
194 const bool bSuccess = pDoc->getIDocumentContentOperations().MoveRange( aPam, aPos, m_bMoveRedlines
195 ? SwMoveFlags::REDLINES
196 : SwMoveFlags::DEFAULT );
197 if (!bSuccess)
198 break;
200 aPam.Exchange();
201 aPam.DeleteMark();
202 if( aPam.GetPointNode().IsContentNode() )
203 aPam.GetPointNode().GetContentNode()->ResetAllAttr();
204 // the Pam will be dropped now
207 SwTextNode* pTextNd = aIdx.GetNode().GetTextNode();
208 if( m_bJoinNext )
211 RemoveIdxRel( aIdx.GetIndex() + 1,
212 SwPosition( aIdx, pTextNd, pTextNd->GetText().getLength()) );
214 // Are there any Pams in the next TextNode?
215 pTextNd->JoinNext();
218 } while( false );
220 if( m_pHistory )
222 if( m_nFootnoteStart != m_pHistory->Count() )
223 m_pHistory->Rollback( pDoc, m_nFootnoteStart );
224 m_pHistory->TmpRollback( pDoc, 0 );
225 m_pHistory->SetTmpEnd( m_pHistory->Count() );
228 // set the cursor onto Undo area
229 if( !m_bMoveRange )
231 AddUndoRedoPaM(rContext);
235 void SwUndoMove::RedoImpl(::sw::UndoRedoContext & rContext)
237 SwPaM& rPam = AddUndoRedoPaM(rContext);
238 SwDoc& rDoc = rContext.GetDoc();
240 SwNodes& rNds = rDoc.GetNodes();
241 SwNodeIndex aIdx( rNds, m_nMoveDestNode );
243 if( m_bMoveRange )
245 // only a move with SwRange
246 SwNodeRange aRg( rNds, m_nSttNode, m_nEndNode );
247 rDoc.getIDocumentContentOperations().MoveNodeRange( aRg, aIdx.GetNode(), m_bMoveRedlines
248 ? SwMoveFlags::REDLINES
249 : SwMoveFlags::DEFAULT );
251 else
253 SwPaM aPam(*rPam.GetPoint());
254 SetPaM( aPam );
255 SwPosition aMvPos( aIdx, aIdx.GetNode().GetContentNode(), m_nMoveDestContent );
257 DelFootnote( aPam );
258 RemoveIdxFromRange( aPam, false );
260 aIdx = aPam.Start()->GetNode();
261 bool bJoinText = aIdx.GetNode().IsTextNode();
263 --aIdx;
264 rDoc.getIDocumentContentOperations().MoveRange( aPam, aMvPos,
265 SwMoveFlags::DEFAULT );
267 if( m_nSttNode != m_nEndNode && bJoinText )
269 ++aIdx;
270 SwTextNode * pTextNd = aIdx.GetNode().GetTextNode();
271 if( pTextNd && pTextNd->CanJoinNext() )
274 RemoveIdxRel( aIdx.GetIndex() + 1,
275 SwPosition( *pTextNd, pTextNd->GetText().getLength()) );
277 pTextNd->JoinNext();
280 *rPam.GetPoint() = *aPam.GetPoint();
281 rPam.SetMark();
282 *rPam.GetMark() = *aPam.GetMark();
286 void SwUndoMove::DelFootnote( const SwPaM& rRange )
288 // is the current move from ContentArea into the special section?
289 SwDoc& rDoc = rRange.GetDoc();
290 SwNodeOffset nContentStt = rDoc.GetNodes().GetEndOfAutotext().GetIndex();
291 if( m_nMoveDestNode < nContentStt &&
292 rRange.GetPoint()->GetNodeIndex() >= nContentStt )
294 // delete all footnotes since they are undesired there
295 DelContentIndex( *rRange.GetMark(), *rRange.GetPoint(),
296 DelContentType::Ftn );
298 if( m_pHistory && !m_pHistory->Count() )
300 m_pHistory.reset();
305 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */