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 if( !pDoc
->Move( aRg
, aIdx
, IDocumentContentOperations::DOC_MOVEDEFAULT
) )
215 SwPaM
aPam( aIdx
.GetNode(), nDestSttCntnt
,
216 *pDoc
->GetNodes()[ nDestEndNode
], nDestEndCntnt
);
218 // #i17764# if redlines are to be moved, we may not remove them before
219 // pDoc->Move gets a chance to handle them
220 if( ! bMoveRedlines
)
221 RemoveIdxFromRange( aPam
, FALSE
);
223 SwPosition
aPos( *pDoc
->GetNodes()[ nInsPosNode
] );
224 SwCntntNode
* pCNd
= aPos
.nNode
.GetNode().GetCntntNode();
225 aPos
.nContent
.Assign( pCNd
, nInsPosCntnt
);
227 if( pCNd
->HasSwAttrSet() )
228 pCNd
->ResetAllAttr();
230 if( pCNd
->IsTxtNode() && ((SwTxtNode
*)pCNd
)->GetpSwpHints() )
231 ((SwTxtNode
*)pCNd
)->ClearSwpHintsArr( false );
233 // an der InsertPos erstmal alle Attribute entfernen,
234 if( !pDoc
->Move( aPam
, aPos
, ( bMoveRedlines
? IDocumentContentOperations::DOC_MOVEREDLINES
: IDocumentContentOperations::DOC_MOVEDEFAULT
) ) )
239 // pDoc->ResetAttr( aPam, FALSE );
240 if( aPam
.GetNode()->IsCntntNode() )
241 aPam
.GetNode()->GetCntntNode()->ResetAllAttr();
242 // der Pam wird jetzt aufgegeben.
245 SwTxtNode
* pTxtNd
= aIdx
.GetNode().GetTxtNode();
249 RemoveIdxRel( aIdx
.GetIndex() + 1, SwPosition( aIdx
,
250 SwIndex( pTxtNd
, pTxtNd
->GetTxt().Len() ) ) );
252 // sind keine Pams mehr im naechsten TextNode
256 if( bJoinPrev
&& pTxtNd
->CanJoinPrev( &aIdx
) )
258 // ?? sind keine Pams mehr im naechsten TextNode ??
259 pTxtNd
= aIdx
.GetNode().GetTxtNode();
261 RemoveIdxRel( aIdx
.GetIndex() + 1, SwPosition( aIdx
,
262 SwIndex( pTxtNd
, pTxtNd
->GetTxt().Len() ) ) );
271 if( nFtnStt
!= pHistory
->Count() )
272 pHistory
->Rollback( pDoc
, nFtnStt
);
273 pHistory
->TmpRollback( pDoc
, 0 );
274 pHistory
->SetTmpEnd( pHistory
->Count() );
277 pDoc
->DoUndo( bUndo
);
279 // setze noch den Cursor auf den Undo-Bereich
285 void SwUndoMove::Redo( SwUndoIter
& rUndoIter
)
287 SwPaM
* pPam
= rUndoIter
.pAktPam
;
288 SwDoc
& rDoc
= *pPam
->GetDoc();
290 SwNodes
& rNds
= rDoc
.GetNodes();
291 SwNodeIndex
aIdx( rNds
, nMvDestNode
);
295 // nur ein Move mit SwRange
296 SwNodeRange
aRg( rNds
, nSttNode
, rNds
, nEndNode
);
297 rDoc
.Move( aRg
, aIdx
, ( bMoveRedlines
? IDocumentContentOperations::DOC_MOVEREDLINES
: IDocumentContentOperations::DOC_MOVEDEFAULT
) );
301 SwPaM
aPam( *pPam
->GetPoint() );
303 SwPosition
aMvPos( aIdx
, SwIndex( aIdx
.GetNode().GetCntntNode(),
307 RemoveIdxFromRange( aPam
, FALSE
);
309 aIdx
= aPam
.Start()->nNode
;
310 BOOL bJoinTxt
= aIdx
.GetNode().IsTxtNode();
313 rDoc
.Move( aPam
, aMvPos
, IDocumentContentOperations::DOC_MOVEDEFAULT
);
315 if( nSttNode
!= nEndNode
&& bJoinTxt
)
318 SwTxtNode
* pTxtNd
= aIdx
.GetNode().GetTxtNode();
319 if( pTxtNd
&& pTxtNd
->CanJoinNext() )
322 RemoveIdxRel( aIdx
.GetIndex() + 1, SwPosition( aIdx
,
323 SwIndex( pTxtNd
, pTxtNd
->GetTxt().Len() ) ) );
328 *pPam
->GetPoint() = *aPam
.GetPoint();
330 *pPam
->GetMark() = *aPam
.GetMark();
335 void SwUndoMove::DelFtn( const SwPaM
& rRange
)
337 // wird aus dem CntntBereich in den Sonderbereich verschoben ?
338 SwDoc
* pDoc
= rRange
.GetDoc();
339 ULONG nCntntStt
= pDoc
->GetNodes().GetEndOfAutotext().GetIndex();
340 if( nMvDestNode
< nCntntStt
&&
341 rRange
.GetPoint()->nNode
.GetIndex() >= nCntntStt
)
343 // loesche alle Fussnoten. Diese sind dort nicht erwuenscht.
344 DelCntntIndex( *rRange
.GetMark(), *rRange
.GetPoint(),
345 nsDelCntntType::DELCNT_FTN
);
347 if( pHistory
&& !pHistory
->Count() )
348 delete pHistory
, pHistory
= 0;
352 void SwUndoMove::AddTblMrgFlyHstry( SwHistory
& rHstr
)
355 pHistory
= new SwHistory
;
357 USHORT nInsPos
= nFtnStt
;
358 nFtnStt
= nFtnStt
+ rHstr
.Count();
359 pHistory
->Move( nInsPos
, &rHstr
);