Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / sw / source / core / undo / unmove.cxx
blob6ff417ddc45a860e78aec9379815b991100a4fe1
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 <IDocumentUndoRedo.hxx>
23 #include <pam.hxx>
24 #include <swundo.hxx>
25 #include <ndtxt.hxx>
26 #include <UndoCore.hxx>
27 #include <rolbck.hxx>
29 // MOVE
30 SwUndoMove::SwUndoMove( const SwPaM& rRange, const SwPosition& rMvPos )
31 : SwUndo( UNDO_MOVE ), SwUndRng( rRange ),
32 nMvDestNode( rMvPos.nNode.GetIndex() ),
33 nMvDestCntnt( rMvPos.nContent.GetIndex() ),
34 bMoveRedlines( false )
36 bMoveRange = bJoinNext = bJoinPrev = sal_False;
38 // get StartNode from footnotes before delete!
39 SwDoc* pDoc = rRange.GetDoc();
40 SwTxtNode* pTxtNd = pDoc->GetNodes()[ nSttNode ]->GetTxtNode();
41 SwTxtNode* pEndTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode();
43 pHistory = new SwHistory;
45 if( pTxtNd )
47 pHistory->Add( pTxtNd->GetTxtColl(), nSttNode, ND_TEXTNODE );
48 if ( pTxtNd->GetpSwpHints() )
50 pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode,
51 0, pTxtNd->GetTxt().Len(), false );
53 if( pTxtNd->HasSwAttrSet() )
54 pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode );
56 if( pEndTxtNd && pEndTxtNd != pTxtNd )
58 pHistory->Add( pEndTxtNd->GetTxtColl(), nEndNode, ND_TEXTNODE );
59 if ( pEndTxtNd->GetpSwpHints() )
61 pHistory->CopyAttr( pEndTxtNd->GetpSwpHints(), nEndNode,
62 0, pEndTxtNd->GetTxt().Len(), false );
64 if( pEndTxtNd->HasSwAttrSet() )
65 pHistory->CopyFmtAttr( *pEndTxtNd->GetpSwAttrSet(), nEndNode );
68 pTxtNd = rMvPos.nNode.GetNode().GetTxtNode();
69 if (0 != pTxtNd)
71 pHistory->Add( pTxtNd->GetTxtColl(), nMvDestNode, ND_TEXTNODE );
72 if ( pTxtNd->GetpSwpHints() )
74 pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nMvDestNode,
75 0, pTxtNd->GetTxt().Len(), false );
77 if( pTxtNd->HasSwAttrSet() )
78 pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nMvDestNode );
81 nFtnStt = pHistory->Count();
82 DelFtn( rRange );
84 if( pHistory && !pHistory->Count() )
85 DELETEZ( pHistory );
88 SwUndoMove::SwUndoMove( SwDoc* pDoc, const SwNodeRange& rRg,
89 const SwNodeIndex& rMvPos )
90 : SwUndo( UNDO_MOVE ),
91 nMvDestNode( rMvPos.GetIndex() ),
92 bMoveRedlines( false )
94 bMoveRange = sal_True;
95 bJoinNext = bJoinPrev = sal_False;
97 nSttCntnt = nEndCntnt = nMvDestCntnt = STRING_MAXLEN;
99 nSttNode = rRg.aStart.GetIndex();
100 nEndNode = rRg.aEnd.GetIndex();
102 // DelFtn( rRange );
103 // FIXME: duplication of the method body of DelFtn below
105 // is the current move from CntntArea into the special section?
106 sal_uLong nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
107 if( nMvDestNode < nCntntStt && rRg.aStart.GetIndex() > nCntntStt )
109 // delete all footnotes since they are undesired there
110 SwPosition aPtPos( rRg.aEnd );
111 SwCntntNode* pCNd = rRg.aEnd.GetNode().GetCntntNode();
112 if( pCNd )
113 aPtPos.nContent.Assign( pCNd, pCNd->Len() );
114 SwPosition aMkPos( rRg.aStart );
115 if( 0 != ( pCNd = aMkPos.nNode.GetNode().GetCntntNode() ))
116 aMkPos.nContent.Assign( pCNd, 0 );
118 DelCntntIndex( aMkPos, aPtPos, nsDelCntntType::DELCNT_FTN );
120 if( pHistory && !pHistory->Count() )
121 DELETEZ( pHistory );
124 nFtnStt = 0;
127 void SwUndoMove::SetDestRange( const SwPaM& rRange,
128 const SwPosition& rInsPos,
129 sal_Bool bJoin, sal_Bool bCorrPam )
131 const SwPosition *pStt = rRange.Start(),
132 *pEnd = rRange.GetPoint() == pStt
133 ? rRange.GetMark()
134 : rRange.GetPoint();
136 nDestSttNode = pStt->nNode.GetIndex();
137 nDestSttCntnt = pStt->nContent.GetIndex();
138 nDestEndNode = pEnd->nNode.GetIndex();
139 nDestEndCntnt = pEnd->nContent.GetIndex();
141 nInsPosNode = rInsPos.nNode.GetIndex();
142 nInsPosCntnt = rInsPos.nContent.GetIndex();
144 if( bCorrPam )
146 nDestSttNode--;
147 nDestEndNode--;
150 bJoinNext = nDestSttNode != nDestEndNode &&
151 pStt->nNode.GetNode().GetTxtNode() &&
152 pEnd->nNode.GetNode().GetTxtNode();
153 bJoinPrev = bJoin;
156 void SwUndoMove::SetDestRange( const SwNodeIndex& rStt,
157 const SwNodeIndex& rEnd,
158 const SwNodeIndex& rInsPos )
160 nDestSttNode = rStt.GetIndex();
161 nDestEndNode = rEnd.GetIndex();
162 if( nDestSttNode > nDestEndNode )
164 nDestSttNode = nDestEndNode;
165 nDestEndNode = rStt.GetIndex();
167 nInsPosNode = rInsPos.GetIndex();
169 nDestSttCntnt = nDestEndCntnt = nInsPosCntnt = STRING_MAXLEN;
172 void SwUndoMove::UndoImpl(::sw::UndoRedoContext & rContext)
174 SwDoc *const pDoc = & rContext.GetDoc();
176 // Block so that we can jump out of it
177 do {
178 // create index position and section based on the existing values
179 SwNodeIndex aIdx( pDoc->GetNodes(), nDestSttNode );
181 if( bMoveRange )
183 // only a move with SwRange
184 SwNodeRange aRg( aIdx, aIdx );
185 aRg.aEnd = nDestEndNode;
186 aIdx = nInsPosNode;
187 bool bSuccess = pDoc->MoveNodeRange( aRg, aIdx,
188 IDocumentContentOperations::DOC_MOVEDEFAULT );
189 if (!bSuccess)
190 break;
192 else
194 SwPaM aPam( aIdx.GetNode(), nDestSttCntnt,
195 *pDoc->GetNodes()[ nDestEndNode ], nDestEndCntnt );
197 // #i17764# if redlines are to be moved, we may not remove them
198 // before pDoc->Move gets a chance to handle them
199 if( ! bMoveRedlines )
200 RemoveIdxFromRange( aPam, sal_False );
202 SwPosition aPos( *pDoc->GetNodes()[ nInsPosNode] );
203 SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
204 aPos.nContent.Assign( pCNd, nInsPosCntnt );
206 if( pCNd->HasSwAttrSet() )
207 pCNd->ResetAllAttr();
209 if( pCNd->IsTxtNode() && ((SwTxtNode*)pCNd)->GetpSwpHints() )
210 ((SwTxtNode*)pCNd)->ClearSwpHintsArr( false );
212 // first delete all attributes at InsertPos
213 const bool bSuccess = pDoc->MoveRange( aPam, aPos, (bMoveRedlines)
214 ? IDocumentContentOperations::DOC_MOVEREDLINES
215 : IDocumentContentOperations::DOC_MOVEDEFAULT );
216 if (!bSuccess)
217 break;
219 aPam.Exchange();
220 aPam.DeleteMark();
221 if( aPam.GetNode()->IsCntntNode() )
222 aPam.GetNode()->GetCntntNode()->ResetAllAttr();
223 // the Pam will be dropped now
226 SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
227 if( bJoinNext )
230 RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
231 SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
233 // Are there any Pams in the next TextNode?
234 pTxtNd->JoinNext();
237 if( bJoinPrev && pTxtNd->CanJoinPrev( &aIdx ) )
239 // Are there any Pams in the next TextNode?
240 pTxtNd = aIdx.GetNode().GetTxtNode();
242 RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
243 SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
245 pTxtNd->JoinNext();
248 } while( sal_False );
250 if( pHistory )
252 if( nFtnStt != pHistory->Count() )
253 pHistory->Rollback( pDoc, nFtnStt );
254 pHistory->TmpRollback( pDoc, 0 );
255 pHistory->SetTmpEnd( pHistory->Count() );
258 // set the cursor onto Undo area
259 if( !bMoveRange )
261 AddUndoRedoPaM(rContext);
265 void SwUndoMove::RedoImpl(::sw::UndoRedoContext & rContext)
267 SwPaM *const pPam = & AddUndoRedoPaM(rContext);
268 SwDoc & rDoc = rContext.GetDoc();
270 SwNodes& rNds = rDoc.GetNodes();
271 SwNodeIndex aIdx( rNds, nMvDestNode );
273 if( bMoveRange )
275 // only a move with SwRange
276 SwNodeRange aRg( rNds, nSttNode, rNds, nEndNode );
277 rDoc.MoveNodeRange( aRg, aIdx, (bMoveRedlines)
278 ? IDocumentContentOperations::DOC_MOVEREDLINES
279 : IDocumentContentOperations::DOC_MOVEDEFAULT );
281 else
283 SwPaM aPam( *pPam->GetPoint() );
284 SetPaM( aPam );
285 SwPosition aMvPos( aIdx, SwIndex( aIdx.GetNode().GetCntntNode(),
286 nMvDestCntnt ));
288 DelFtn( aPam );
289 RemoveIdxFromRange( aPam, sal_False );
291 aIdx = aPam.Start()->nNode;
292 sal_Bool bJoinTxt = aIdx.GetNode().IsTxtNode();
294 aIdx--;
295 rDoc.MoveRange( aPam, aMvPos,
296 IDocumentContentOperations::DOC_MOVEDEFAULT );
298 if( nSttNode != nEndNode && bJoinTxt )
300 ++aIdx;
301 SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode();
302 if( pTxtNd && pTxtNd->CanJoinNext() )
305 RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
306 SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
308 pTxtNd->JoinNext();
311 *pPam->GetPoint() = *aPam.GetPoint();
312 pPam->SetMark();
313 *pPam->GetMark() = *aPam.GetMark();
317 void SwUndoMove::DelFtn( const SwPaM& rRange )
319 // is the current move from CntntArea into the special section?
320 SwDoc* pDoc = rRange.GetDoc();
321 sal_uLong nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
322 if( nMvDestNode < nCntntStt &&
323 rRange.GetPoint()->nNode.GetIndex() >= nCntntStt )
325 // delete all footnotes since they are undesired there
326 DelCntntIndex( *rRange.GetMark(), *rRange.GetPoint(),
327 nsDelCntntType::DELCNT_FTN );
329 if( pHistory && !pHistory->Count() )
330 delete pHistory, pHistory = 0;
334 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */