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