Update ooo320-m1
[ooovba.git] / sw / source / core / undo / untblk.cxx
blobe6aad03906cb297facdb40c193a3bfc33df827b2
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: untblk.cxx,v $
10 * $Revision: 1.16 $
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"
35 #include <hintids.hxx>
36 #include <fmtanchr.hxx>
37 #include <frmfmt.hxx>
38 #include <doc.hxx>
39 #include <docary.hxx>
40 #include <swundo.hxx> // fuer die UndoIds
41 #include <pam.hxx>
42 #include <ndtxt.hxx>
43 #include <undobj.hxx>
44 #include <rolbck.hxx>
45 #include <redline.hxx>
49 SwUndoInserts::SwUndoInserts( SwUndoId nUndoId, const SwPaM& rPam )
50 : SwUndo( nUndoId ), SwUndRng( rPam ),
51 pTxtFmtColl( 0 ), pLastNdColl(0), pFrmFmts( 0 ), pFlyUndos(0), pRedlData( 0 ),
52 bSttWasTxtNd( TRUE ), nNdDiff( 0 ), pPos( 0 ), nSetPos( 0 )
54 pHistory = new SwHistory;
55 SwDoc* pDoc = (SwDoc*)rPam.GetDoc();
57 SwTxtNode* pTxtNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode();
58 if( pTxtNd )
60 pTxtFmtColl = pTxtNd->GetTxtColl();
61 pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode,
62 0, pTxtNd->GetTxt().Len(), false );
63 if( pTxtNd->HasSwAttrSet() )
64 pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode );
66 if( !nSttCntnt ) // dann werden Flys mitgenommen !!
68 USHORT nArrLen = pDoc->GetSpzFrmFmts()->Count();
69 for( USHORT n = 0; n < nArrLen; ++n )
71 SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[n];
72 const SwFmtAnchor* pAnchor = &pFmt->GetAnchor();
73 const SwPosition* pAPos;
74 if ( pAnchor->GetAnchorId() == FLY_AT_CNTNT &&
75 0 != ( pAPos = pAnchor->GetCntntAnchor()) &&
76 nSttNode == pAPos->nNode.GetIndex() )
78 if( !pFrmFmts )
79 pFrmFmts = new SvPtrarr;
80 pFrmFmts->Insert( pFmt, pFrmFmts->Count() );
85 // Redline beachten
86 if( pDoc->IsRedlineOn() )
88 pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT, pDoc->GetRedlineAuthor() );
89 SetRedlineMode( pDoc->GetRedlineMode() );
93 // setze den Destination-Bereich nach dem Einlesen.
95 void SwUndoInserts::SetInsertRange( const SwPaM& rPam, BOOL bScanFlys,
96 BOOL bSttIsTxtNd )
98 const SwPosition* pTmpPos = rPam.End();
99 nEndNode = pTmpPos->nNode.GetIndex();
100 nEndCntnt = pTmpPos->nContent.GetIndex();
101 if( rPam.HasMark() )
103 if( pTmpPos == rPam.GetPoint() )
104 pTmpPos = rPam.GetMark();
105 else
106 pTmpPos = rPam.GetPoint();
108 nSttNode = pTmpPos->nNode.GetIndex();
109 nSttCntnt = pTmpPos->nContent.GetIndex();
111 if( !bSttIsTxtNd ) // wird eine Tabellenselektion eingefuegt,
113 ++nSttNode; // dann stimmt der CopyPam nicht ganz
114 bSttWasTxtNd = FALSE;
118 if( bScanFlys && !nSttCntnt )
120 // dann alle neuen Flys zusammen sammeln !!
121 SwDoc* pDoc = (SwDoc*)rPam.GetDoc();
122 pFlyUndos = new SwUndos();
123 USHORT nFndPos, nArrLen = pDoc->GetSpzFrmFmts()->Count();
124 for( USHORT n = 0; n < nArrLen; ++n )
126 SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[n];
127 const SwFmtAnchor* pAnchor = &pFmt->GetAnchor();
128 const SwPosition* pAPos;
129 if( pAnchor->GetAnchorId() == FLY_AT_CNTNT &&
130 0 != ( pAPos = pAnchor->GetCntntAnchor()) &&
131 nSttNode == pAPos->nNode.GetIndex() )
133 if( !pFrmFmts ||
134 USHRT_MAX == ( nFndPos = pFrmFmts->GetPos( pFmt ) ) )
136 SwUndoInsLayFmt* pFlyUndo = new SwUndoInsLayFmt( pFmt,0,0 );
137 pFlyUndos->Insert( pFlyUndo, pFlyUndos->Count() );
139 else
140 pFrmFmts->Remove( nFndPos );
143 delete pFrmFmts, pFrmFmts = 0;
144 if( !pFlyUndos->Count() )
145 delete pFlyUndos, pFlyUndos = 0;
150 SwUndoInserts::~SwUndoInserts()
152 if( pPos ) // loesche noch den Bereich aus dem UndoNodes Array
154 // Insert speichert den Inhalt in der IconSection
155 SwNodes& rUNds = pPos->nNode.GetNodes();
156 if( pPos->nContent.GetIndex() ) // nicht den gesamten Node loeschen
158 SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
159 ASSERT( pTxtNd, "kein TextNode, aus dem geloescht werden soll" );
160 if( pTxtNd ) // Robust
162 pTxtNd->EraseText( pPos->nContent );
164 pPos->nNode++;
166 pPos->nContent.Assign( 0, 0 );
167 rUNds.Delete( pPos->nNode, rUNds.GetEndOfExtras().GetIndex() -
168 pPos->nNode.GetIndex() );
169 delete pPos;
171 delete pFrmFmts;
172 delete pFlyUndos;
173 delete pRedlData;
177 void SwUndoInserts::Undo( SwUndoIter& rUndoIter )
179 SwPaM * pPam = rUndoIter.pAktPam;
180 SwDoc* pDoc = pPam->GetDoc();
181 SetPaM( rUndoIter );
182 BOOL bUndo = pDoc->DoesUndo();
183 pDoc->DoUndo( FALSE );
185 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
186 pDoc->DeleteRedline( *pPam, true, USHRT_MAX );
188 // sind an Point/Mark 2 unterschiedliche TextNodes, dann muss ein
189 // JoinNext ausgefuehrt werden.
190 BOOL bJoinNext = nSttNode != nEndNode &&
191 pPam->GetMark()->nNode.GetNode().GetTxtNode() &&
192 pPam->GetPoint()->nNode.GetNode().GetTxtNode();
195 // gibts ueberhaupt Inhalt ? (laden von Zeichenvorlagen hat kein Inhalt!)
196 if( nSttNode != nEndNode || nSttCntnt != nEndCntnt )
198 if( nSttNode != nEndNode )
200 SwTxtNode* pTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode();
201 if( pTxtNd && pTxtNd->GetTxt().Len() == nEndCntnt )
202 pLastNdColl = pTxtNd->GetTxtColl();
205 RemoveIdxFromRange( *pPam, FALSE );
206 SetPaM( rUndoIter );
208 // sind Fussnoten oder CntntFlyFrames im Text ??
209 nSetPos = pHistory->Count();
210 nNdDiff = pPam->GetMark()->nNode.GetIndex();
211 DelCntntIndex( *pPam->GetMark(), *pPam->GetPoint() );
212 nNdDiff -= pPam->GetMark()->nNode.GetIndex();
214 if( *pPam->GetPoint() != *pPam->GetMark() )
216 pPos = new SwPosition( *pPam->GetPoint() );
217 MoveToUndoNds( *pPam, &pPos->nNode, &pPos->nContent );
219 if( !bSttWasTxtNd )
220 pPam->Move( fnMoveBackward, fnGoCntnt );
224 if( pFlyUndos )
226 ULONG nTmp = pPam->GetPoint()->nNode.GetIndex();
227 for( USHORT n = pFlyUndos->Count(); n; )
228 (*pFlyUndos)[ --n ]->Undo( rUndoIter );
229 nNdDiff += nTmp - pPam->GetPoint()->nNode.GetIndex();
232 SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
233 SwTxtNode* pTxtNode = rIdx.GetNode().GetTxtNode();
234 if( pTxtNode )
236 if( !pTxtFmtColl ) // falls 0, dann war hier auch kein TextNode,
237 { // dann muss dieser geloescht werden,
238 SwNodeIndex aDelIdx( rIdx );
239 rIdx++;
240 SwCntntNode* pCNd = rIdx.GetNode().GetCntntNode();
241 xub_StrLen nCnt = 0; if( pCNd ) nCnt = pCNd->Len();
242 pPam->GetPoint()->nContent.Assign( pCNd, nCnt );
243 pPam->SetMark();
244 pPam->DeleteMark();
246 RemoveIdxRel( aDelIdx.GetIndex(), *pPam->GetPoint() );
248 pDoc->GetNodes().Delete( aDelIdx, 1 );
250 else
252 if( bJoinNext && pTxtNode->CanJoinNext())
255 RemoveIdxRel( rIdx.GetIndex()+1, SwPosition( rIdx,
256 SwIndex( pTxtNode, pTxtNode->GetTxt().Len() )));
258 pTxtNode->JoinNext();
260 // reset all text attributes in the paragraph!
261 pTxtNode->RstAttr( SwIndex(pTxtNode, 0), pTxtNode->Len(),
262 0, 0, true );
264 // setze alle Attribute im Node zurueck
265 pTxtNode->ResetAllAttr();
267 if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pTxtFmtColl ))
268 pTxtFmtColl = (SwTxtFmtColl*)pTxtNode->ChgFmtColl( pTxtFmtColl );
270 pHistory->SetTmpEnd( nSetPos );
271 pHistory->TmpRollback( pDoc, 0, false );
275 pDoc->DoUndo( bUndo );
276 if( pPam != rUndoIter.pAktPam )
277 delete pPam;
280 void SwUndoInserts::Redo( SwUndoIter& rUndoIter )
282 // setze noch den Cursor auf den Redo-Bereich
283 SwPaM* pPam = rUndoIter.pAktPam;
284 SwDoc* pDoc = pPam->GetDoc();
285 pPam->DeleteMark();
286 pPam->GetPoint()->nNode = nSttNode - nNdDiff;
287 SwCntntNode* pCNd = pPam->GetCntntNode();
288 pPam->GetPoint()->nContent.Assign( pCNd, nSttCntnt );
290 SwTxtFmtColl* pSavTxtFmtColl = pTxtFmtColl;
291 if( pTxtFmtColl && pCNd && pCNd->IsTxtNode() )
292 pSavTxtFmtColl = ((SwTxtNode*)pCNd)->GetTxtColl();
294 pHistory->SetTmpEnd( nSetPos );
296 // alte Anfangs-Position fuers Rollback zurueckholen
297 if( ( nSttNode != nEndNode || nSttCntnt != nEndCntnt ) && pPos )
299 BOOL bMvBkwrd = MovePtBackward( *pPam );
301 // Inhalt wieder einfuegen. (erst pPos abmelden !!)
302 ULONG nMvNd = pPos->nNode.GetIndex();
303 xub_StrLen nMvCnt = pPos->nContent.GetIndex();
304 DELETEZ( pPos );
305 MoveFromUndoNds( *pDoc, nMvNd, nMvCnt, *pPam->GetMark() );
306 if( bSttWasTxtNd )
307 MovePtForward( *pPam, bMvBkwrd );
308 pPam->Exchange();
311 if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pTxtFmtColl ))
313 SwTxtNode* pTxtNd = pPam->GetMark()->nNode.GetNode().GetTxtNode();
314 if( pTxtNd )
315 pTxtNd->ChgFmtColl( pTxtFmtColl );
317 pTxtFmtColl = pSavTxtFmtColl;
319 if( pLastNdColl && USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pLastNdColl ) &&
320 pPam->GetPoint()->nNode != pPam->GetMark()->nNode )
322 SwTxtNode* pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode();
323 if( pTxtNd )
324 pTxtNd->ChgFmtColl( pLastNdColl );
327 if( pFlyUndos )
328 for( USHORT n = pFlyUndos->Count(); n; )
329 (*pFlyUndos)[ --n ]->Redo( rUndoIter );
331 pHistory->Rollback( pDoc, nSetPos );
333 if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
335 RedlineMode_t eOld = pDoc->GetRedlineMode();
336 pDoc->SetRedlineMode_intern((RedlineMode_t)( eOld & ~nsRedlineMode_t::REDLINE_IGNORE ));
337 pDoc->AppendRedline( new SwRedline( *pRedlData, *pPam ), true);
338 pDoc->SetRedlineMode_intern( eOld );
340 else if( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) &&
341 pDoc->GetRedlineTbl().Count() )
342 pDoc->SplitRedline( *pPam );
345 void SwUndoInserts::Repeat( SwUndoIter& rUndoIter )
347 if( GetId() == rUndoIter.GetLastUndoId() )
348 return;
350 SwPaM aPam( *rUndoIter.pAktPam->GetPoint() );
351 SetPaM( aPam );
352 aPam.GetDoc()->CopyRange( aPam, *rUndoIter.pAktPam->GetPoint(), false );
354 rUndoIter.pLastUndoObj = this;
358 /* \f */
361 SwUndoInsDoc::SwUndoInsDoc( const SwPaM& rPam )
362 : SwUndoInserts( UNDO_INSDOKUMENT, rPam )
366 SwUndoCpyDoc::SwUndoCpyDoc( const SwPaM& rPam )
367 : SwUndoInserts( UNDO_COPY, rPam )