Update ooo320-m1
[ooovba.git] / sw / source / core / undo / unmove.cxx
bloba7491da0c8e4bb19350f30e0d9f2aaf32ad11f25
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unmove.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <doc.hxx>
36 #include <pam.hxx>
37 #include <swundo.hxx> // fuer die UndoIds
38 #include <ndtxt.hxx>
39 #include <undobj.hxx>
40 #include <rolbck.hxx>
43 inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
45 // MOVE
47 SwUndoMove::SwUndoMove( const SwPaM& rRange, const SwPosition& rMvPos )
48 : SwUndo( UNDO_MOVE ), SwUndRng( rRange ),
49 nMvDestNode( rMvPos.nNode.GetIndex() ),
50 nMvDestCntnt( rMvPos.nContent.GetIndex() ),
51 bMoveRedlines( false )
53 bMoveRange = bJoinNext = bJoinPrev = FALSE;
55 // StartNode vorm loeschen von Fussnoten besorgen!
56 SwDoc* pDoc = rRange.GetDoc();
57 SwTxtNode* pTxtNd = pDoc->GetNodes()[ nSttNode ]->GetTxtNode();
58 SwTxtNode* pEndTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode();
60 pHistory = new SwHistory;
62 if( pTxtNd )
64 pHistory->Add( pTxtNd->GetTxtColl(), nSttNode, ND_TEXTNODE );
65 if ( pTxtNd->GetpSwpHints() )
67 pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode,
68 0, pTxtNd->GetTxt().Len(), false );
70 if( pTxtNd->HasSwAttrSet() )
71 pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode );
73 if( pEndTxtNd && pEndTxtNd != pTxtNd )
75 pHistory->Add( pEndTxtNd->GetTxtColl(), nEndNode, ND_TEXTNODE );
76 if ( pEndTxtNd->GetpSwpHints() )
78 pHistory->CopyAttr( pEndTxtNd->GetpSwpHints(), nEndNode,
79 0, pEndTxtNd->GetTxt().Len(), false );
81 if( pEndTxtNd->HasSwAttrSet() )
82 pHistory->CopyFmtAttr( *pEndTxtNd->GetpSwAttrSet(), nEndNode );
85 if( 0 != (pTxtNd = rRange.GetDoc()->GetNodes()[ rMvPos.nNode ]->GetTxtNode() ))
87 pHistory->Add( pTxtNd->GetTxtColl(), nMvDestNode, ND_TEXTNODE );
88 if ( pTxtNd->GetpSwpHints() )
90 pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nMvDestNode,
91 0, pTxtNd->GetTxt().Len(), false );
93 if( pTxtNd->HasSwAttrSet() )
94 pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nMvDestNode );
98 nFtnStt = pHistory->Count();
99 DelFtn( rRange );
101 if( pHistory && !pHistory->Count() )
102 DELETEZ( pHistory );
106 SwUndoMove::SwUndoMove( SwDoc* pDoc, const SwNodeRange& rRg,
107 const SwNodeIndex& rMvPos )
108 : SwUndo( UNDO_MOVE ),
109 nMvDestNode( rMvPos.GetIndex() ),
110 bMoveRedlines( false )
112 bMoveRange = TRUE;
113 bJoinNext = bJoinPrev = FALSE;
115 nSttCntnt = nEndCntnt = nMvDestCntnt = STRING_MAXLEN;
117 nSttNode = rRg.aStart.GetIndex();
118 nEndNode = rRg.aEnd.GetIndex();
120 // DelFtn( rRange );
122 // wird aus dem CntntBereich in den Sonderbereich verschoben ?
123 ULONG nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
124 if( nMvDestNode < nCntntStt && rRg.aStart.GetIndex() > nCntntStt )
126 // loesche alle Fussnoten. Diese sind dort nicht erwuenscht.
127 SwPosition aPtPos( rRg.aEnd );
128 SwCntntNode* pCNd = rRg.aEnd.GetNode().GetCntntNode();
129 if( pCNd )
130 aPtPos.nContent.Assign( pCNd, pCNd->Len() );
131 SwPosition aMkPos( rRg.aStart );
132 if( 0 != ( pCNd = aMkPos.nNode.GetNode().GetCntntNode() ))
133 aMkPos.nContent.Assign( pCNd, 0 );
135 DelCntntIndex( aMkPos, aPtPos, nsDelCntntType::DELCNT_FTN );
137 if( pHistory && !pHistory->Count() )
138 DELETEZ( pHistory );
141 nFtnStt = 0;
146 void SwUndoMove::SetDestRange( const SwPaM& rRange,
147 const SwPosition& rInsPos,
148 BOOL bJoin, BOOL bCorrPam )
150 const SwPosition *pStt = rRange.Start(),
151 *pEnd = rRange.GetPoint() == pStt
152 ? rRange.GetMark()
153 : rRange.GetPoint();
155 nDestSttNode = pStt->nNode.GetIndex();
156 nDestSttCntnt = pStt->nContent.GetIndex();
157 nDestEndNode = pEnd->nNode.GetIndex();
158 nDestEndCntnt = pEnd->nContent.GetIndex();
160 nInsPosNode = rInsPos.nNode.GetIndex();
161 nInsPosCntnt = rInsPos.nContent.GetIndex();
163 if( bCorrPam )
165 nDestSttNode--;
166 nDestEndNode--;
169 bJoinNext = nDestSttNode != nDestEndNode &&
170 pStt->nNode.GetNode().GetTxtNode() &&
171 pEnd->nNode.GetNode().GetTxtNode();
172 bJoinPrev = bJoin;
176 void SwUndoMove::SetDestRange( const SwNodeIndex& rStt,
177 const SwNodeIndex& rEnd,
178 const SwNodeIndex& rInsPos )
180 nDestSttNode = rStt.GetIndex();
181 nDestEndNode = rEnd.GetIndex();
182 if( nDestSttNode > nDestEndNode )
184 nDestSttNode = nDestEndNode;
185 nDestEndNode = rStt.GetIndex();
187 nInsPosNode = rInsPos.GetIndex();
189 nDestSttCntnt = nDestEndCntnt = nInsPosCntnt = STRING_MAXLEN;
193 void SwUndoMove::Undo( SwUndoIter& rUndoIter )
195 SwDoc* pDoc = &rUndoIter.GetDoc();
196 BOOL bUndo = pDoc->DoesUndo();
197 pDoc->DoUndo( FALSE );
199 // Block, damit aus diesem gesprungen werden kann
200 do {
201 // erzeuge aus den Werten die Insert-Position und den Bereich
202 SwNodeIndex aIdx( pDoc->GetNodes(), nDestSttNode );
204 if( bMoveRange )
206 // nur ein Move mit SwRange
207 SwNodeRange aRg( aIdx, aIdx );
208 aRg.aEnd = nDestEndNode;
209 aIdx = nInsPosNode;
210 bool bSuccess = pDoc->MoveNodeRange( aRg, aIdx,
211 IDocumentContentOperations::DOC_MOVEDEFAULT );
212 if (!bSuccess)
213 break;
215 else
217 SwPaM aPam( aIdx.GetNode(), nDestSttCntnt,
218 *pDoc->GetNodes()[ nDestEndNode ], nDestEndCntnt );
220 // #i17764# if redlines are to be moved, we may not remove them before
221 // pDoc->Move gets a chance to handle them
222 if( ! bMoveRedlines )
223 RemoveIdxFromRange( aPam, FALSE );
225 SwPosition aPos( *pDoc->GetNodes()[ nInsPosNode] );
226 SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
227 aPos.nContent.Assign( pCNd, nInsPosCntnt );
229 if( pCNd->HasSwAttrSet() )
230 pCNd->ResetAllAttr();
232 if( pCNd->IsTxtNode() && ((SwTxtNode*)pCNd)->GetpSwpHints() )
233 ((SwTxtNode*)pCNd)->ClearSwpHintsArr( false );
235 // an der InsertPos erstmal alle Attribute entfernen,
236 const bool bSuccess = pDoc->MoveRange( aPam, aPos, (bMoveRedlines)
237 ? IDocumentContentOperations::DOC_MOVEREDLINES
238 : IDocumentContentOperations::DOC_MOVEDEFAULT );
239 if (!bSuccess)
240 break;
242 aPam.Exchange();
243 aPam.DeleteMark();
244 // pDoc->ResetAttr( aPam, FALSE );
245 if( aPam.GetNode()->IsCntntNode() )
246 aPam.GetNode()->GetCntntNode()->ResetAllAttr();
247 // der Pam wird jetzt aufgegeben.
250 SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
251 if( bJoinNext )
254 RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
255 SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
257 // sind keine Pams mehr im naechsten TextNode
258 pTxtNd->JoinNext();
261 if( bJoinPrev && pTxtNd->CanJoinPrev( &aIdx ) )
263 // ?? sind keine Pams mehr im naechsten TextNode ??
264 pTxtNd = aIdx.GetNode().GetTxtNode();
266 RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
267 SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
269 pTxtNd->JoinNext();
272 } while( FALSE );
274 if( pHistory )
276 if( nFtnStt != pHistory->Count() )
277 pHistory->Rollback( pDoc, nFtnStt );
278 pHistory->TmpRollback( pDoc, 0 );
279 pHistory->SetTmpEnd( pHistory->Count() );
282 pDoc->DoUndo( bUndo );
284 // setze noch den Cursor auf den Undo-Bereich
285 if( !bMoveRange )
286 SetPaM( rUndoIter );
290 void SwUndoMove::Redo( SwUndoIter& rUndoIter )
292 SwPaM* pPam = rUndoIter.pAktPam;
293 SwDoc& rDoc = *pPam->GetDoc();
295 SwNodes& rNds = rDoc.GetNodes();
296 SwNodeIndex aIdx( rNds, nMvDestNode );
298 if( bMoveRange )
300 // nur ein Move mit SwRange
301 SwNodeRange aRg( rNds, nSttNode, rNds, nEndNode );
302 rDoc.MoveNodeRange( aRg, aIdx, (bMoveRedlines)
303 ? IDocumentContentOperations::DOC_MOVEREDLINES
304 : IDocumentContentOperations::DOC_MOVEDEFAULT );
306 else
308 SwPaM aPam( *pPam->GetPoint() );
309 SetPaM( aPam );
310 SwPosition aMvPos( aIdx, SwIndex( aIdx.GetNode().GetCntntNode(),
311 nMvDestCntnt ));
313 DelFtn( aPam );
314 RemoveIdxFromRange( aPam, FALSE );
316 aIdx = aPam.Start()->nNode;
317 BOOL bJoinTxt = aIdx.GetNode().IsTxtNode();
319 aIdx--;
320 rDoc.MoveRange( aPam, aMvPos,
321 IDocumentContentOperations::DOC_MOVEDEFAULT );
323 if( nSttNode != nEndNode && bJoinTxt )
325 aIdx++;
326 SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode();
327 if( pTxtNd && pTxtNd->CanJoinNext() )
330 RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
331 SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
333 pTxtNd->JoinNext();
336 *pPam->GetPoint() = *aPam.GetPoint();
337 pPam->SetMark();
338 *pPam->GetMark() = *aPam.GetMark();
343 void SwUndoMove::DelFtn( const SwPaM& rRange )
345 // wird aus dem CntntBereich in den Sonderbereich verschoben ?
346 SwDoc* pDoc = rRange.GetDoc();
347 ULONG nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
348 if( nMvDestNode < nCntntStt &&
349 rRange.GetPoint()->nNode.GetIndex() >= nCntntStt )
351 // loesche alle Fussnoten. Diese sind dort nicht erwuenscht.
352 DelCntntIndex( *rRange.GetMark(), *rRange.GetPoint(),
353 nsDelCntntType::DELCNT_FTN );
355 if( pHistory && !pHistory->Count() )
356 delete pHistory, pHistory = 0;
360 void SwUndoMove::AddTblMrgFlyHstry( SwHistory& rHstr )
362 if( !pHistory )
363 pHistory = new SwHistory;
365 USHORT nInsPos = nFtnStt;
366 nFtnStt = nFtnStt + rHstr.Count();
367 pHistory->Move( nInsPos, &rHstr );