1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
22 #include <IDocumentUndoRedo.hxx>
26 #include <UndoCore.hxx>
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
;
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();
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();
84 if( pHistory
&& !pHistory
->Count() )
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();
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();
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() )
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
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();
150 bJoinNext
= nDestSttNode
!= nDestEndNode
&&
151 pStt
->nNode
.GetNode().GetTxtNode() &&
152 pEnd
->nNode
.GetNode().GetTxtNode();
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
178 // create index position and section based on the existing values
179 SwNodeIndex
aIdx( pDoc
->GetNodes(), nDestSttNode
);
183 // only a move with SwRange
184 SwNodeRange
aRg( aIdx
, aIdx
);
185 aRg
.aEnd
= nDestEndNode
;
187 bool bSuccess
= pDoc
->MoveNodeRange( aRg
, aIdx
,
188 IDocumentContentOperations::DOC_MOVEDEFAULT
);
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
);
221 if( aPam
.GetNode()->IsCntntNode() )
222 aPam
.GetNode()->GetCntntNode()->ResetAllAttr();
223 // the Pam will be dropped now
226 SwTxtNode
* pTxtNd
= aIdx
.GetNode().GetTxtNode();
230 RemoveIdxRel( aIdx
.GetIndex() + 1, SwPosition( aIdx
,
231 SwIndex( pTxtNd
, pTxtNd
->GetTxt().Len() ) ) );
233 // Are there any Pams in the next TextNode?
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() ) ) );
248 } while( sal_False
);
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
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
);
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
);
283 SwPaM
aPam( *pPam
->GetPoint() );
285 SwPosition
aMvPos( aIdx
, SwIndex( aIdx
.GetNode().GetCntntNode(),
289 RemoveIdxFromRange( aPam
, sal_False
);
291 aIdx
= aPam
.Start()->nNode
;
292 sal_Bool bJoinTxt
= aIdx
.GetNode().IsTxtNode();
295 rDoc
.MoveRange( aPam
, aMvPos
,
296 IDocumentContentOperations::DOC_MOVEDEFAULT
);
298 if( nSttNode
!= nEndNode
&& bJoinTxt
)
301 SwTxtNode
* pTxtNd
= aIdx
.GetNode().GetTxtNode();
302 if( pTxtNd
&& pTxtNd
->CanJoinNext() )
305 RemoveIdxRel( aIdx
.GetIndex() + 1, SwPosition( aIdx
,
306 SwIndex( pTxtNd
, pTxtNd
->GetTxt().Len() ) ) );
311 *pPam
->GetPoint() = *aPam
.GetPoint();
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: */