1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unmove.cxx,v $
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"
37 #include <swundo.hxx> // fuer die UndoIds
43 inline SwDoc
& SwUndoIter::GetDoc() const { return *pAktPam
->GetDoc(); }
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
;
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();
101 if( pHistory
&& !pHistory
->Count() )
106 SwUndoMove::SwUndoMove( SwDoc
* pDoc
, const SwNodeRange
& rRg
,
107 const SwNodeIndex
& rMvPos
)
108 : SwUndo( UNDO_MOVE
),
109 nMvDestNode( rMvPos
.GetIndex() ),
110 bMoveRedlines( false )
113 bJoinNext
= bJoinPrev
= FALSE
;
115 nSttCntnt
= nEndCntnt
= nMvDestCntnt
= STRING_MAXLEN
;
117 nSttNode
= rRg
.aStart
.GetIndex();
118 nEndNode
= rRg
.aEnd
.GetIndex();
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();
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() )
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
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();
169 bJoinNext
= nDestSttNode
!= nDestEndNode
&&
170 pStt
->nNode
.GetNode().GetTxtNode() &&
171 pEnd
->nNode
.GetNode().GetTxtNode();
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
201 // erzeuge aus den Werten die Insert-Position und den Bereich
202 SwNodeIndex
aIdx( pDoc
->GetNodes(), nDestSttNode
);
206 // nur ein Move mit SwRange
207 SwNodeRange
aRg( aIdx
, aIdx
);
208 aRg
.aEnd
= nDestEndNode
;
210 bool bSuccess
= pDoc
->MoveNodeRange( aRg
, aIdx
,
211 IDocumentContentOperations::DOC_MOVEDEFAULT
);
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
);
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();
254 RemoveIdxRel( aIdx
.GetIndex() + 1, SwPosition( aIdx
,
255 SwIndex( pTxtNd
, pTxtNd
->GetTxt().Len() ) ) );
257 // sind keine Pams mehr im naechsten TextNode
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() ) ) );
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
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
);
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
);
308 SwPaM
aPam( *pPam
->GetPoint() );
310 SwPosition
aMvPos( aIdx
, SwIndex( aIdx
.GetNode().GetCntntNode(),
314 RemoveIdxFromRange( aPam
, FALSE
);
316 aIdx
= aPam
.Start()->nNode
;
317 BOOL bJoinTxt
= aIdx
.GetNode().IsTxtNode();
320 rDoc
.MoveRange( aPam
, aMvPos
,
321 IDocumentContentOperations::DOC_MOVEDEFAULT
);
323 if( nSttNode
!= nEndNode
&& bJoinTxt
)
326 SwTxtNode
* pTxtNd
= aIdx
.GetNode().GetTxtNode();
327 if( pTxtNd
&& pTxtNd
->CanJoinNext() )
330 RemoveIdxRel( aIdx
.GetIndex() + 1, SwPosition( aIdx
,
331 SwIndex( pTxtNd
, pTxtNd
->GetTxt().Len() ) ) );
336 *pPam
->GetPoint() = *aPam
.GetPoint();
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
)
363 pHistory
= new SwHistory
;
365 USHORT nInsPos
= nFtnStt
;
366 nFtnStt
= nFtnStt
+ rHstr
.Count();
367 pHistory
->Move( nInsPos
, &rHstr
);