Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <UndoSplitMove.hxx>
30 : : #include <doc.hxx>
31 : : #include <IDocumentUndoRedo.hxx>
32 : : #include <pam.hxx>
33 : : #include <swundo.hxx>
34 : : #include <ndtxt.hxx>
35 : : #include <UndoCore.hxx>
36 : : #include <rolbck.hxx>
37 : :
38 : : // MOVE
39 : 0 : SwUndoMove::SwUndoMove( const SwPaM& rRange, const SwPosition& rMvPos )
40 : : : SwUndo( UNDO_MOVE ), SwUndRng( rRange ),
41 : 0 : nMvDestNode( rMvPos.nNode.GetIndex() ),
42 : 0 : nMvDestCntnt( rMvPos.nContent.GetIndex() ),
43 [ # # ][ # # ]: 0 : bMoveRedlines( false )
44 : : {
45 : 0 : bMoveRange = bJoinNext = bJoinPrev = sal_False;
46 : :
47 : : // get StartNode from footnotes before delete!
48 : 0 : SwDoc* pDoc = rRange.GetDoc();
49 [ # # ][ # # ]: 0 : SwTxtNode* pTxtNd = pDoc->GetNodes()[ nSttNode ]->GetTxtNode();
50 [ # # ][ # # ]: 0 : SwTxtNode* pEndTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode();
51 : :
52 [ # # ][ # # ]: 0 : pHistory = new SwHistory;
53 : :
54 [ # # ]: 0 : if( pTxtNd )
55 : : {
56 [ # # ]: 0 : pHistory->Add( pTxtNd->GetTxtColl(), nSttNode, ND_TEXTNODE );
57 [ # # ]: 0 : if ( pTxtNd->GetpSwpHints() )
58 : : {
59 : : pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode,
60 [ # # ]: 0 : 0, pTxtNd->GetTxt().Len(), false );
61 : : }
62 [ # # ][ # # ]: 0 : if( pTxtNd->HasSwAttrSet() )
63 [ # # ][ # # ]: 0 : pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode );
64 : : }
65 [ # # ][ # # ]: 0 : if( pEndTxtNd && pEndTxtNd != pTxtNd )
66 : : {
67 [ # # ]: 0 : pHistory->Add( pEndTxtNd->GetTxtColl(), nEndNode, ND_TEXTNODE );
68 [ # # ]: 0 : if ( pEndTxtNd->GetpSwpHints() )
69 : : {
70 : : pHistory->CopyAttr( pEndTxtNd->GetpSwpHints(), nEndNode,
71 [ # # ]: 0 : 0, pEndTxtNd->GetTxt().Len(), false );
72 : : }
73 [ # # ][ # # ]: 0 : if( pEndTxtNd->HasSwAttrSet() )
74 [ # # ][ # # ]: 0 : pHistory->CopyFmtAttr( *pEndTxtNd->GetpSwAttrSet(), nEndNode );
75 : : }
76 : :
77 : 0 : pTxtNd = rMvPos.nNode.GetNode().GetTxtNode();
78 [ # # ]: 0 : if (0 != pTxtNd)
79 : : {
80 [ # # ]: 0 : pHistory->Add( pTxtNd->GetTxtColl(), nMvDestNode, ND_TEXTNODE );
81 [ # # ]: 0 : if ( pTxtNd->GetpSwpHints() )
82 : : {
83 : : pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nMvDestNode,
84 [ # # ]: 0 : 0, pTxtNd->GetTxt().Len(), false );
85 : : }
86 [ # # ][ # # ]: 0 : if( pTxtNd->HasSwAttrSet() )
87 [ # # ][ # # ]: 0 : pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nMvDestNode );
88 : : }
89 : :
90 : 0 : nFtnStt = pHistory->Count();
91 [ # # ]: 0 : DelFtn( rRange );
92 : :
93 [ # # ][ # # ]: 0 : if( pHistory && !pHistory->Count() )
[ # # ]
94 [ # # ][ # # ]: 0 : DELETEZ( pHistory );
95 : 0 : }
96 : :
97 : 0 : SwUndoMove::SwUndoMove( SwDoc* pDoc, const SwNodeRange& rRg,
98 : : const SwNodeIndex& rMvPos )
99 : : : SwUndo( UNDO_MOVE ),
100 : 0 : nMvDestNode( rMvPos.GetIndex() ),
101 [ # # ][ # # ]: 0 : bMoveRedlines( false )
102 : : {
103 : 0 : bMoveRange = sal_True;
104 : 0 : bJoinNext = bJoinPrev = sal_False;
105 : :
106 : 0 : nSttCntnt = nEndCntnt = nMvDestCntnt = STRING_MAXLEN;
107 : :
108 : 0 : nSttNode = rRg.aStart.GetIndex();
109 : 0 : nEndNode = rRg.aEnd.GetIndex();
110 : :
111 : : // DelFtn( rRange );
112 : : // FIXME: duplication of the method body of DelFtn below
113 : :
114 : : // is the current move from CntntArea into the special section?
115 [ # # ]: 0 : sal_uLong nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
116 [ # # ][ # # ]: 0 : if( nMvDestNode < nCntntStt && rRg.aStart.GetIndex() > nCntntStt )
[ # # ]
117 : : {
118 : : // delete all footnotes since they are undesired there
119 [ # # ]: 0 : SwPosition aPtPos( rRg.aEnd );
120 : 0 : SwCntntNode* pCNd = rRg.aEnd.GetNode().GetCntntNode();
121 [ # # ]: 0 : if( pCNd )
122 [ # # ][ # # ]: 0 : aPtPos.nContent.Assign( pCNd, pCNd->Len() );
[ # # ]
123 [ # # ]: 0 : SwPosition aMkPos( rRg.aStart );
124 [ # # ]: 0 : if( 0 != ( pCNd = aMkPos.nNode.GetNode().GetCntntNode() ))
125 [ # # ][ # # ]: 0 : aMkPos.nContent.Assign( pCNd, 0 );
126 : :
127 [ # # ]: 0 : DelCntntIndex( aMkPos, aPtPos, nsDelCntntType::DELCNT_FTN );
128 : :
129 [ # # ][ # # ]: 0 : if( pHistory && !pHistory->Count() )
[ # # ]
130 [ # # ][ # # ]: 0 : DELETEZ( pHistory );
[ # # ][ # # ]
131 : : }
132 : :
133 : 0 : nFtnStt = 0;
134 : 0 : }
135 : :
136 : 0 : void SwUndoMove::SetDestRange( const SwPaM& rRange,
137 : : const SwPosition& rInsPos,
138 : : sal_Bool bJoin, sal_Bool bCorrPam )
139 : : {
140 : 0 : const SwPosition *pStt = rRange.Start(),
141 : 0 : *pEnd = rRange.GetPoint() == pStt
142 : : ? rRange.GetMark()
143 [ # # ]: 0 : : rRange.GetPoint();
144 : :
145 : 0 : nDestSttNode = pStt->nNode.GetIndex();
146 : 0 : nDestSttCntnt = pStt->nContent.GetIndex();
147 : 0 : nDestEndNode = pEnd->nNode.GetIndex();
148 : 0 : nDestEndCntnt = pEnd->nContent.GetIndex();
149 : :
150 : 0 : nInsPosNode = rInsPos.nNode.GetIndex();
151 : 0 : nInsPosCntnt = rInsPos.nContent.GetIndex();
152 : :
153 [ # # ]: 0 : if( bCorrPam )
154 : : {
155 : 0 : nDestSttNode--;
156 : 0 : nDestEndNode--;
157 : : }
158 : :
159 : : bJoinNext = nDestSttNode != nDestEndNode &&
160 : 0 : pStt->nNode.GetNode().GetTxtNode() &&
161 [ # # # # ]: 0 : pEnd->nNode.GetNode().GetTxtNode();
[ # # ]
162 : 0 : bJoinPrev = bJoin;
163 : 0 : }
164 : :
165 : 0 : void SwUndoMove::SetDestRange( const SwNodeIndex& rStt,
166 : : const SwNodeIndex& rEnd,
167 : : const SwNodeIndex& rInsPos )
168 : : {
169 : 0 : nDestSttNode = rStt.GetIndex();
170 : 0 : nDestEndNode = rEnd.GetIndex();
171 [ # # ]: 0 : if( nDestSttNode > nDestEndNode )
172 : : {
173 : 0 : nDestSttNode = nDestEndNode;
174 : 0 : nDestEndNode = rStt.GetIndex();
175 : : }
176 : 0 : nInsPosNode = rInsPos.GetIndex();
177 : :
178 : 0 : nDestSttCntnt = nDestEndCntnt = nInsPosCntnt = STRING_MAXLEN;
179 : 0 : }
180 : :
181 : 0 : void SwUndoMove::UndoImpl(::sw::UndoRedoContext & rContext)
182 : : {
183 : 0 : SwDoc *const pDoc = & rContext.GetDoc();
184 : :
185 : : // Block so that we can jump out of it
186 : : do {
187 : : // create index position and section based on the existing values
188 [ # # ][ # # ]: 0 : SwNodeIndex aIdx( pDoc->GetNodes(), nDestSttNode );
189 : :
190 [ # # ]: 0 : if( bMoveRange )
191 : : {
192 : : // only a move with SwRange
193 [ # # ]: 0 : SwNodeRange aRg( aIdx, aIdx );
194 [ # # ]: 0 : aRg.aEnd = nDestEndNode;
195 [ # # ]: 0 : aIdx = nInsPosNode;
196 : : bool bSuccess = pDoc->MoveNodeRange( aRg, aIdx,
197 [ # # ]: 0 : IDocumentContentOperations::DOC_MOVEDEFAULT );
198 [ # # ]: 0 : if (!bSuccess)
199 [ # # ][ # # ]: 0 : break;
200 : : }
201 : : else
202 : : {
203 : 0 : SwPaM aPam( aIdx.GetNode(), nDestSttCntnt,
204 [ # # ]: 0 : *pDoc->GetNodes()[ nDestEndNode ], nDestEndCntnt );
[ # # # # ]
205 : :
206 : : // #i17764# if redlines are to be moved, we may not remove them
207 : : // before pDoc->Move gets a chance to handle them
208 [ # # ]: 0 : if( ! bMoveRedlines )
209 [ # # ]: 0 : RemoveIdxFromRange( aPam, sal_False );
210 : :
211 [ # # ][ # # ]: 0 : SwPosition aPos( *pDoc->GetNodes()[ nInsPosNode] );
[ # # ]
212 : 0 : SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
213 [ # # ][ # # ]: 0 : aPos.nContent.Assign( pCNd, nInsPosCntnt );
214 : :
215 [ # # ][ # # ]: 0 : if( pCNd->HasSwAttrSet() )
216 [ # # ]: 0 : pCNd->ResetAllAttr();
217 : :
218 [ # # ][ # # ]: 0 : if( pCNd->IsTxtNode() && ((SwTxtNode*)pCNd)->GetpSwpHints() )
[ # # ]
219 [ # # ]: 0 : ((SwTxtNode*)pCNd)->ClearSwpHintsArr( false );
220 : :
221 : : // first delete all attributes at InsertPos
222 : : const bool bSuccess = pDoc->MoveRange( aPam, aPos, (bMoveRedlines)
223 : : ? IDocumentContentOperations::DOC_MOVEREDLINES
224 [ # # ][ # # ]: 0 : : IDocumentContentOperations::DOC_MOVEDEFAULT );
225 [ # # ]: 0 : if (!bSuccess)
226 : : break;
227 : :
228 : 0 : aPam.Exchange();
229 [ # # ]: 0 : aPam.DeleteMark();
230 [ # # ]: 0 : if( aPam.GetNode()->IsCntntNode() )
231 [ # # ][ # # ]: 0 : aPam.GetNode()->GetCntntNode()->ResetAllAttr();
[ # # ][ # # ]
[ # # ]
232 : : // the Pam will be dropped now
233 : : }
234 : :
235 : 0 : SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
236 [ # # ]: 0 : if( bJoinNext )
237 : : {
238 : : {
239 : 0 : RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
240 [ # # ][ # # ]: 0 : SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
[ # # # # ]
[ # # ][ # # ]
241 : : }
242 : : // Are there any Pams in the next TextNode?
243 [ # # ]: 0 : pTxtNd->JoinNext();
244 : : }
245 : :
246 [ # # ][ # # ]: 0 : if( bJoinPrev && pTxtNd->CanJoinPrev( &aIdx ) )
[ # # ][ # # ]
247 : : {
248 : : // Are there any Pams in the next TextNode?
249 : 0 : pTxtNd = aIdx.GetNode().GetTxtNode();
250 : : {
251 : 0 : RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
252 [ # # ]: 0 : SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
[ # # # # ]
[ # # ][ # # ]
[ # # ]
253 : : }
254 [ # # ]: 0 : pTxtNd->JoinNext();
255 [ # # ][ # # ]: 0 : }
256 : :
257 : : } while( sal_False );
258 : :
259 [ # # ]: 0 : if( pHistory )
260 : : {
261 [ # # ]: 0 : if( nFtnStt != pHistory->Count() )
262 : 0 : pHistory->Rollback( pDoc, nFtnStt );
263 : 0 : pHistory->TmpRollback( pDoc, 0 );
264 : 0 : pHistory->SetTmpEnd( pHistory->Count() );
265 : : }
266 : :
267 : : // set the cursor onto Undo area
268 [ # # ]: 0 : if( !bMoveRange )
269 : : {
270 : 0 : AddUndoRedoPaM(rContext);
271 : : }
272 : 0 : }
273 : :
274 : 0 : void SwUndoMove::RedoImpl(::sw::UndoRedoContext & rContext)
275 : : {
276 [ # # ]: 0 : SwPaM *const pPam = & AddUndoRedoPaM(rContext);
277 : 0 : SwDoc & rDoc = rContext.GetDoc();
278 : :
279 [ # # ]: 0 : SwNodes& rNds = rDoc.GetNodes();
280 [ # # ]: 0 : SwNodeIndex aIdx( rNds, nMvDestNode );
281 : :
282 [ # # ]: 0 : if( bMoveRange )
283 : : {
284 : : // only a move with SwRange
285 [ # # ][ # # ]: 0 : SwNodeRange aRg( rNds, nSttNode, rNds, nEndNode );
[ # # ][ # # ]
[ # # ]
286 : : rDoc.MoveNodeRange( aRg, aIdx, (bMoveRedlines)
287 : : ? IDocumentContentOperations::DOC_MOVEREDLINES
288 [ # # ][ # # ]: 0 : : IDocumentContentOperations::DOC_MOVEDEFAULT );
[ # # ]
289 : : }
290 : : else
291 : : {
292 [ # # ]: 0 : SwPaM aPam( *pPam->GetPoint() );
293 [ # # ]: 0 : SetPaM( aPam );
294 : 0 : SwPosition aMvPos( aIdx, SwIndex( aIdx.GetNode().GetCntntNode(),
295 [ # # ][ # # ]: 0 : nMvDestCntnt ));
[ # # ][ # # ]
296 : :
297 [ # # ]: 0 : DelFtn( aPam );
298 [ # # ]: 0 : RemoveIdxFromRange( aPam, sal_False );
299 : :
300 [ # # ][ # # ]: 0 : aIdx = aPam.Start()->nNode;
301 : 0 : sal_Bool bJoinTxt = aIdx.GetNode().IsTxtNode();
302 : :
303 [ # # ]: 0 : aIdx--;
304 : : rDoc.MoveRange( aPam, aMvPos,
305 [ # # ]: 0 : IDocumentContentOperations::DOC_MOVEDEFAULT );
306 : :
307 [ # # ][ # # ]: 0 : if( nSttNode != nEndNode && bJoinTxt )
308 : : {
309 [ # # ]: 0 : aIdx++;
310 : 0 : SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode();
311 [ # # ][ # # ]: 0 : if( pTxtNd && pTxtNd->CanJoinNext() )
[ # # ][ # # ]
312 : : {
313 : : {
314 : 0 : RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx,
315 [ # # ][ # # ]: 0 : SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) );
[ # # # # ]
[ # # ][ # # ]
316 : : }
317 [ # # ]: 0 : pTxtNd->JoinNext();
318 : : }
319 : : }
320 [ # # ]: 0 : *pPam->GetPoint() = *aPam.GetPoint();
321 [ # # ]: 0 : pPam->SetMark();
322 [ # # ][ # # ]: 0 : *pPam->GetMark() = *aPam.GetMark();
[ # # ]
323 [ # # ]: 0 : }
324 : 0 : }
325 : :
326 : 0 : void SwUndoMove::DelFtn( const SwPaM& rRange )
327 : : {
328 : : // is the current move from CntntArea into the special section?
329 : 0 : SwDoc* pDoc = rRange.GetDoc();
330 : 0 : sal_uLong nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex();
331 [ # # ]: 0 : if( nMvDestNode < nCntntStt &&
[ # # # # ]
332 : 0 : rRange.GetPoint()->nNode.GetIndex() >= nCntntStt )
333 : : {
334 : : // delete all footnotes since they are undesired there
335 : 0 : DelCntntIndex( *rRange.GetMark(), *rRange.GetPoint(),
336 : 0 : nsDelCntntType::DELCNT_FTN );
337 : :
338 [ # # ][ # # ]: 0 : if( pHistory && !pHistory->Count() )
[ # # ]
339 [ # # ]: 0 : delete pHistory, pHistory = 0;
340 : : }
341 : 0 : }
342 : :
343 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|