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 <hintids.hxx>
30 : : #include <fmtanchr.hxx>
31 : : #include <frmfmt.hxx>
32 : : #include <doc.hxx>
33 : : #include <IDocumentUndoRedo.hxx>
34 : : #include <IShellCursorSupplier.hxx>
35 : : #include <docary.hxx>
36 : : #include <swundo.hxx>
37 : : #include <pam.hxx>
38 : : #include <ndtxt.hxx>
39 : : #include <UndoCore.hxx>
40 : : #include <rolbck.hxx>
41 : : #include <redline.hxx>
42 : :
43 : 6 : SwUndoInserts::SwUndoInserts( SwUndoId nUndoId, const SwPaM& rPam )
44 : : : SwUndo( nUndoId ), SwUndRng( rPam ),
45 : : pTxtFmtColl( 0 ), pLastNdColl(0), pFrmFmts( 0 ), pRedlData( 0 ),
46 [ + - ][ + - ]: 6 : bSttWasTxtNd( sal_True ), nNdDiff( 0 ), pPos( 0 ), nSetPos( 0 )
[ + - ]
47 : : {
48 [ + - ][ + - ]: 6 : pHistory = new SwHistory;
49 : 6 : SwDoc* pDoc = (SwDoc*)rPam.GetDoc();
50 : :
51 : 6 : SwTxtNode* pTxtNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode();
52 [ + - ]: 6 : if( pTxtNd )
53 : : {
54 : 6 : pTxtFmtColl = pTxtNd->GetTxtColl();
55 : : pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode,
56 [ + - ]: 6 : 0, pTxtNd->GetTxt().Len(), false );
57 [ + - ][ - + ]: 6 : if( pTxtNd->HasSwAttrSet() )
58 [ # # ][ # # ]: 0 : pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode );
59 : :
60 [ + - ]: 6 : if( !nSttCntnt ) // than take the Flys along
61 : : {
62 : 6 : sal_uInt16 nArrLen = pDoc->GetSpzFrmFmts()->size();
63 [ - + ]: 6 : for( sal_uInt16 n = 0; n < nArrLen; ++n )
64 : : {
65 [ # # ]: 0 : SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[n];
66 [ # # ]: 0 : SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
67 [ # # ]: 0 : const SwPosition* pAPos = pAnchor->GetCntntAnchor();
68 [ # # # # : 0 : if (pAPos &&
# # ][ # # ]
69 : 0 : (pAnchor->GetAnchorId() == FLY_AT_PARA) &&
70 : 0 : nSttNode == pAPos->nNode.GetIndex() )
71 : : {
72 [ # # ]: 0 : if( !pFrmFmts )
73 [ # # ][ # # ]: 0 : pFrmFmts = new std::vector<SwFrmFmt*>;
74 [ # # ]: 0 : pFrmFmts->push_back( pFmt );
75 : : }
76 : : }
77 : : }
78 : : }
79 : : // consider Redline
80 [ + - ][ - + ]: 6 : if( pDoc->IsRedlineOn() )
81 : : {
82 [ # # ][ # # ]: 0 : pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT, pDoc->GetRedlineAuthor() );
[ # # ]
83 [ # # ]: 0 : SetRedlineMode( pDoc->GetRedlineMode() );
84 : : }
85 : 6 : }
86 : :
87 : : // set destination after reading input
88 : 6 : void SwUndoInserts::SetInsertRange( const SwPaM& rPam, sal_Bool bScanFlys,
89 : : sal_Bool bSttIsTxtNd )
90 : : {
91 : 6 : const SwPosition* pTmpPos = rPam.End();
92 : 6 : nEndNode = pTmpPos->nNode.GetIndex();
93 : 6 : nEndCntnt = pTmpPos->nContent.GetIndex();
94 [ + - ]: 6 : if( rPam.HasMark() )
95 : : {
96 [ + - ]: 6 : if( pTmpPos == rPam.GetPoint() )
97 : 6 : pTmpPos = rPam.GetMark();
98 : : else
99 : 0 : pTmpPos = rPam.GetPoint();
100 : :
101 : 6 : nSttNode = pTmpPos->nNode.GetIndex();
102 : 6 : nSttCntnt = pTmpPos->nContent.GetIndex();
103 : :
104 [ - + ]: 6 : if( !bSttIsTxtNd ) // if a table selection is added ...
105 : : {
106 : 0 : ++nSttNode; // ... than the CopyPam is not fully correct
107 : 0 : bSttWasTxtNd = sal_False;
108 : : }
109 : : }
110 : :
111 [ + - ][ + - ]: 6 : if( bScanFlys && !nSttCntnt )
112 : : {
113 : : // than collect all new Flys
114 : 6 : SwDoc* pDoc = (SwDoc*)rPam.GetDoc();
115 : 6 : sal_uInt16 nArrLen = pDoc->GetSpzFrmFmts()->size();
116 [ - + ]: 6 : for( sal_uInt16 n = 0; n < nArrLen; ++n )
117 : : {
118 [ # # ]: 0 : SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[n];
119 [ # # ]: 0 : SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
120 [ # # ]: 0 : SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
121 [ # # # # : 0 : if (pAPos &&
# # ][ # # ]
122 : 0 : (pAnchor->GetAnchorId() == FLY_AT_PARA) &&
123 : 0 : nSttNode == pAPos->nNode.GetIndex() )
124 : : {
125 : 0 : std::vector<SwFrmFmt*>::iterator it;
126 [ # # ][ # # ]: 0 : if( !pFrmFmts ||
[ # # ]
127 [ # # ][ # # ]: 0 : pFrmFmts->end() == ( it = std::find( pFrmFmts->begin(), pFrmFmts->end(), pFmt ) ) )
[ # # ][ # # ]
128 : : {
129 : : ::boost::shared_ptr<SwUndoInsLayFmt> const pFlyUndo(
130 [ # # ][ # # ]: 0 : new SwUndoInsLayFmt(pFmt, 0, 0));
[ # # ]
131 [ # # ][ # # ]: 0 : m_FlyUndos.push_back(pFlyUndo);
132 : : }
133 : : else
134 [ # # ]: 0 : pFrmFmts->erase( it );
135 : : }
136 : : }
137 [ - + ]: 6 : delete pFrmFmts, pFrmFmts = 0;
138 : : }
139 : 6 : }
140 : :
141 [ + - ]: 6 : SwUndoInserts::~SwUndoInserts()
142 : : {
143 [ - + ]: 6 : if( pPos ) // delete also the section from UndoNodes array
144 : : {
145 : : // Insert saves content in IconSection
146 : 0 : SwNodes& rUNds = pPos->nNode.GetNodes();
147 [ # # ]: 0 : if( pPos->nContent.GetIndex() ) // do not delete complete Node
148 : : {
149 : 0 : SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
150 : : OSL_ENSURE( pTxtNd, "no TextNode to delete from" );
151 [ # # ]: 0 : if( pTxtNd ) // robust
152 : : {
153 [ # # ]: 0 : pTxtNd->EraseText( pPos->nContent );
154 : : }
155 [ # # ]: 0 : pPos->nNode++;
156 : : }
157 [ # # ]: 0 : pPos->nContent.Assign( 0, 0 );
158 : 0 : rUNds.Delete( pPos->nNode, rUNds.GetEndOfExtras().GetIndex() -
159 [ # # ]: 0 : pPos->nNode.GetIndex() );
160 [ # # ][ # # ]: 0 : delete pPos;
161 : : }
162 [ - + ]: 6 : delete pFrmFmts;
163 [ - + ][ # # ]: 6 : delete pRedlData;
164 [ - + ]: 6 : }
165 : :
166 : 0 : void SwUndoInserts::UndoImpl(::sw::UndoRedoContext & rContext)
167 : : {
168 : 0 : SwDoc *const pDoc = & rContext.GetDoc();
169 : 0 : SwPaM *const pPam = & AddUndoRedoPaM(rContext);
170 : :
171 [ # # ]: 0 : if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
172 : 0 : pDoc->DeleteRedline( *pPam, true, USHRT_MAX );
173 : :
174 : : // if Point and Mark are different text nodes so a JoinNext has to be done
175 : : sal_Bool bJoinNext = nSttNode != nEndNode &&
176 : 0 : pPam->GetMark()->nNode.GetNode().GetTxtNode() &&
177 [ # # # # ]: 0 : pPam->GetPoint()->nNode.GetNode().GetTxtNode();
[ # # ]
178 : :
179 : :
180 : : // Is there any content? (loading from template does not have content)
181 [ # # ][ # # ]: 0 : if( nSttNode != nEndNode || nSttCntnt != nEndCntnt )
182 : : {
183 [ # # ]: 0 : if( nSttNode != nEndNode )
184 : : {
185 : 0 : SwTxtNode* pTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode();
186 [ # # ][ # # ]: 0 : if( pTxtNd && pTxtNd->GetTxt().Len() == nEndCntnt )
[ # # ]
187 : 0 : pLastNdColl = pTxtNd->GetTxtColl();
188 : : }
189 : :
190 : 0 : RemoveIdxFromRange( *pPam, sal_False );
191 : 0 : SetPaM(*pPam);
192 : :
193 : : // are there Footnotes or CntntFlyFrames in text?
194 : 0 : nSetPos = pHistory->Count();
195 : 0 : nNdDiff = pPam->GetMark()->nNode.GetIndex();
196 : 0 : DelCntntIndex( *pPam->GetMark(), *pPam->GetPoint() );
197 : 0 : nNdDiff -= pPam->GetMark()->nNode.GetIndex();
198 : :
199 [ # # ]: 0 : if( *pPam->GetPoint() != *pPam->GetMark() )
200 : : {
201 [ # # ]: 0 : pPos = new SwPosition( *pPam->GetPoint() );
202 : 0 : MoveToUndoNds( *pPam, &pPos->nNode, &pPos->nContent );
203 : :
204 [ # # ]: 0 : if( !bSttWasTxtNd )
205 : 0 : pPam->Move( fnMoveBackward, fnGoCntnt );
206 : : }
207 : : }
208 : :
209 [ # # ]: 0 : if (m_FlyUndos.size())
210 : : {
211 : 0 : sal_uLong nTmp = pPam->GetPoint()->nNode.GetIndex();
212 [ # # ]: 0 : for (size_t n = m_FlyUndos.size(); 0 < n; --n)
213 : : {
214 : 0 : m_FlyUndos[ n-1 ]->UndoImpl(rContext);
215 : : }
216 : 0 : nNdDiff += nTmp - pPam->GetPoint()->nNode.GetIndex();
217 : : }
218 : :
219 : 0 : SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
220 : 0 : SwTxtNode* pTxtNode = rIdx.GetNode().GetTxtNode();
221 [ # # ]: 0 : if( pTxtNode )
222 : : {
223 [ # # ]: 0 : if( !pTxtFmtColl ) // if 0 than it's no TextNode -> delete
224 : : {
225 [ # # ]: 0 : SwNodeIndex aDelIdx( rIdx );
226 [ # # ]: 0 : rIdx++;
227 : 0 : SwCntntNode* pCNd = rIdx.GetNode().GetCntntNode();
228 : 0 : xub_StrLen nCnt = 0;
229 [ # # ]: 0 : if( pCNd )
230 [ # # ]: 0 : nCnt = pCNd->Len();
231 [ # # ][ # # ]: 0 : pPam->GetPoint()->nContent.Assign( pCNd, nCnt );
232 [ # # ]: 0 : pPam->SetMark();
233 [ # # ]: 0 : pPam->DeleteMark();
234 : :
235 [ # # ]: 0 : RemoveIdxRel( aDelIdx.GetIndex(), *pPam->GetPoint() );
236 : :
237 [ # # ][ # # ]: 0 : pDoc->GetNodes().Delete( aDelIdx, 1 );
[ # # ]
238 : : }
239 : : else
240 : : {
241 [ # # ][ # # ]: 0 : if( bJoinNext && pTxtNode->CanJoinNext())
[ # # ]
242 : : {
243 : : {
244 : 0 : RemoveIdxRel( rIdx.GetIndex()+1, SwPosition( rIdx,
245 [ # # ]: 0 : SwIndex( pTxtNode, pTxtNode->GetTxt().Len() )));
[ # # # # ]
[ # # ]
246 : : }
247 : 0 : pTxtNode->JoinNext();
248 : : }
249 : : // reset all text attributes in the paragraph!
250 [ # # ]: 0 : pTxtNode->RstAttr( SwIndex(pTxtNode, 0), pTxtNode->Len(),
251 [ # # ]: 0 : 0, 0, true );
252 : :
253 : 0 : pTxtNode->ResetAllAttr();
254 : :
255 [ # # ]: 0 : if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pTxtFmtColl ))
256 : 0 : pTxtFmtColl = (SwTxtFmtColl*)pTxtNode->ChgFmtColl( pTxtFmtColl );
257 : :
258 : 0 : pHistory->SetTmpEnd( nSetPos );
259 : 0 : pHistory->TmpRollback( pDoc, 0, false );
260 : : }
261 : : }
262 : 0 : }
263 : :
264 : 0 : void SwUndoInserts::RedoImpl(::sw::UndoRedoContext & rContext)
265 : : {
266 : : // position cursor onto REDO section
267 : 0 : SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
268 : 0 : SwDoc* pDoc = pPam->GetDoc();
269 : 0 : pPam->DeleteMark();
270 : 0 : pPam->GetPoint()->nNode = nSttNode - nNdDiff;
271 : 0 : SwCntntNode* pCNd = pPam->GetCntntNode();
272 [ # # ]: 0 : pPam->GetPoint()->nContent.Assign( pCNd, nSttCntnt );
273 : :
274 : 0 : SwTxtFmtColl* pSavTxtFmtColl = pTxtFmtColl;
275 [ # # ][ # # ]: 0 : if( pTxtFmtColl && pCNd && pCNd->IsTxtNode() )
[ # # ][ # # ]
276 : 0 : pSavTxtFmtColl = ((SwTxtNode*)pCNd)->GetTxtColl();
277 : :
278 : 0 : pHistory->SetTmpEnd( nSetPos );
279 : :
280 : : // retrieve start position for rollback
281 [ # # ][ # # ]: 0 : if( ( nSttNode != nEndNode || nSttCntnt != nEndCntnt ) && pPos )
[ # # ]
282 : : {
283 : 0 : sal_Bool bMvBkwrd = MovePtBackward( *pPam );
284 : :
285 : : // re-insert content again (first detach pPos!)
286 : 0 : sal_uLong nMvNd = pPos->nNode.GetIndex();
287 : 0 : xub_StrLen nMvCnt = pPos->nContent.GetIndex();
288 [ # # ]: 0 : DELETEZ( pPos );
289 : 0 : MoveFromUndoNds( *pDoc, nMvNd, nMvCnt, *pPam->GetMark() );
290 [ # # ]: 0 : if( bSttWasTxtNd )
291 : 0 : MovePtForward( *pPam, bMvBkwrd );
292 : 0 : pPam->Exchange();
293 : : }
294 : :
295 [ # # ]: 0 : if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pTxtFmtColl ))
296 : : {
297 : 0 : SwTxtNode* pTxtNd = pPam->GetMark()->nNode.GetNode().GetTxtNode();
298 [ # # ]: 0 : if( pTxtNd )
299 : 0 : pTxtNd->ChgFmtColl( pTxtFmtColl );
300 : : }
301 : 0 : pTxtFmtColl = pSavTxtFmtColl;
302 : :
303 [ # # ]: 0 : if( pLastNdColl && USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pLastNdColl ) &&
[ # # # # ]
[ # # ]
304 : 0 : pPam->GetPoint()->nNode != pPam->GetMark()->nNode )
305 : : {
306 : 0 : SwTxtNode* pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode();
307 [ # # ]: 0 : if( pTxtNd )
308 : 0 : pTxtNd->ChgFmtColl( pLastNdColl );
309 : : }
310 : :
311 [ # # ]: 0 : for (size_t n = m_FlyUndos.size(); 0 < n; --n)
312 : : {
313 : 0 : m_FlyUndos[ n-1 ]->RedoImpl(rContext);
314 : : }
315 : :
316 : 0 : pHistory->Rollback( pDoc, nSetPos );
317 : :
318 [ # # ][ # # ]: 0 : if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
[ # # ]
319 : : {
320 : 0 : RedlineMode_t eOld = pDoc->GetRedlineMode();
321 : 0 : pDoc->SetRedlineMode_intern((RedlineMode_t)( eOld & ~nsRedlineMode_t::REDLINE_IGNORE ));
322 [ # # ]: 0 : pDoc->AppendRedline( new SwRedline( *pRedlData, *pPam ), true);
323 : 0 : pDoc->SetRedlineMode_intern( eOld );
324 : : }
325 [ # # # # ]: 0 : else if( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) &&
[ # # ]
326 : 0 : !pDoc->GetRedlineTbl().empty() )
327 : 0 : pDoc->SplitRedline( *pPam );
328 : 0 : }
329 : :
330 : 0 : void SwUndoInserts::RepeatImpl(::sw::RepeatContext & rContext)
331 : : {
332 [ # # ][ # # ]: 0 : SwPaM aPam( rContext.GetDoc().GetNodes().GetEndOfContent() );
333 [ # # ]: 0 : SetPaM( aPam );
334 : 0 : SwPaM & rRepeatPaM( rContext.GetRepeatPaM() );
335 [ # # ][ # # ]: 0 : aPam.GetDoc()->CopyRange( aPam, *rRepeatPaM.GetPoint(), false );
336 : 0 : }
337 : :
338 : 0 : SwUndoInsDoc::SwUndoInsDoc( const SwPaM& rPam )
339 : 0 : : SwUndoInserts( UNDO_INSDOKUMENT, rPam )
340 : : {
341 : 0 : }
342 : :
343 : 6 : SwUndoCpyDoc::SwUndoCpyDoc( const SwPaM& rPam )
344 : 6 : : SwUndoInserts( UNDO_COPY, rPam )
345 : : {
346 : 6 : }
347 : :
348 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|