update dev300-m58
[ooovba.git] / sw / source / core / undo / untblk.cxx
blob05f7afb921cbfb5006f5565b863aeb30eb5e0348
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
161 pTxtNd->Erase( pPos->nContent );
162 pPos->nNode++;
164 pPos->nContent.Assign( 0, 0 );
165 rUNds.Delete( pPos->nNode, rUNds.GetEndOfExtras().GetIndex() -
166 pPos->nNode.GetIndex() );
167 delete pPos;
169 delete pFrmFmts;
170 delete pFlyUndos;
171 delete pRedlData;
175 void SwUndoInserts::Undo( SwUndoIter& rUndoIter )
177 SwPaM * pPam = rUndoIter.pAktPam;
178 SwDoc* pDoc = pPam->GetDoc();
179 SetPaM( rUndoIter );
180 BOOL bUndo = pDoc->DoesUndo();
181 pDoc->DoUndo( FALSE );
183 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
184 pDoc->DeleteRedline( *pPam, true, USHRT_MAX );
186 // sind an Point/Mark 2 unterschiedliche TextNodes, dann muss ein
187 // JoinNext ausgefuehrt werden.
188 BOOL bJoinNext = nSttNode != nEndNode &&
189 pPam->GetMark()->nNode.GetNode().GetTxtNode() &&
190 pPam->GetPoint()->nNode.GetNode().GetTxtNode();
193 // gibts ueberhaupt Inhalt ? (laden von Zeichenvorlagen hat kein Inhalt!)
194 if( nSttNode != nEndNode || nSttCntnt != nEndCntnt )
196 if( nSttNode != nEndNode )
198 SwTxtNode* pTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode();
199 if( pTxtNd && pTxtNd->GetTxt().Len() == nEndCntnt )
200 pLastNdColl = pTxtNd->GetTxtColl();
203 RemoveIdxFromRange( *pPam, FALSE );
204 SetPaM( rUndoIter );
206 // sind Fussnoten oder CntntFlyFrames im Text ??
207 nSetPos = pHistory->Count();
208 nNdDiff = pPam->GetMark()->nNode.GetIndex();
209 DelCntntIndex( *pPam->GetMark(), *pPam->GetPoint() );
210 nNdDiff -= pPam->GetMark()->nNode.GetIndex();
212 if( *pPam->GetPoint() != *pPam->GetMark() )
214 pPos = new SwPosition( *pPam->GetPoint() );
215 MoveToUndoNds( *pPam, &pPos->nNode, &pPos->nContent );
217 if( !bSttWasTxtNd )
218 pPam->Move( fnMoveBackward, fnGoCntnt );
222 if( pFlyUndos )
224 ULONG nTmp = pPam->GetPoint()->nNode.GetIndex();
225 for( USHORT n = pFlyUndos->Count(); n; )
226 (*pFlyUndos)[ --n ]->Undo( rUndoIter );
227 nNdDiff += nTmp - pPam->GetPoint()->nNode.GetIndex();
230 SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
231 SwTxtNode* pTxtNode = rIdx.GetNode().GetTxtNode();
232 if( pTxtNode )
234 if( !pTxtFmtColl ) // falls 0, dann war hier auch kein TextNode,
235 { // dann muss dieser geloescht werden,
236 SwNodeIndex aDelIdx( rIdx );
237 rIdx++;
238 SwCntntNode* pCNd = rIdx.GetNode().GetCntntNode();
239 xub_StrLen nCnt = 0; if( pCNd ) nCnt = pCNd->Len();
240 pPam->GetPoint()->nContent.Assign( pCNd, nCnt );
241 pPam->SetMark();
242 pPam->DeleteMark();
244 RemoveIdxRel( aDelIdx.GetIndex(), *pPam->GetPoint() );
246 pDoc->GetNodes().Delete( aDelIdx, 1 );
248 else
250 pDoc->RstTxtAttrs( *pPam, TRUE );
251 if( bJoinNext && pTxtNode->CanJoinNext())
254 RemoveIdxRel( rIdx.GetIndex()+1, SwPosition( rIdx,
255 SwIndex( pTxtNode, pTxtNode->GetTxt().Len() )));
257 pTxtNode->JoinNext();
260 // setze alle Attribute im Node zurueck
261 pTxtNode->ResetAllAttr();
263 if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pTxtFmtColl ))
264 pTxtFmtColl = (SwTxtFmtColl*)pTxtNode->ChgFmtColl( pTxtFmtColl );
266 pHistory->SetTmpEnd( nSetPos );
267 pHistory->TmpRollback( pDoc, 0, false );
271 pDoc->DoUndo( bUndo );
272 if( pPam != rUndoIter.pAktPam )
273 delete pPam;
276 void SwUndoInserts::Redo( SwUndoIter& rUndoIter )
278 // setze noch den Cursor auf den Redo-Bereich
279 SwPaM* pPam = rUndoIter.pAktPam;
280 SwDoc* pDoc = pPam->GetDoc();
281 pPam->DeleteMark();
282 pPam->GetPoint()->nNode = nSttNode - nNdDiff;
283 SwCntntNode* pCNd = pPam->GetCntntNode();
284 pPam->GetPoint()->nContent.Assign( pCNd, nSttCntnt );
286 SwTxtFmtColl* pSavTxtFmtColl = pTxtFmtColl;
287 if( pTxtFmtColl && pCNd && pCNd->IsTxtNode() )
288 pSavTxtFmtColl = ((SwTxtNode*)pCNd)->GetTxtColl();
290 pHistory->SetTmpEnd( nSetPos );
291 pHistory->TmpRollback( pDoc, 0, false );
293 // alte Anfangs-Position fuers Rollback zurueckholen
294 if( ( nSttNode != nEndNode || nSttCntnt != nEndCntnt ) && pPos )
296 BOOL bMvBkwrd = MovePtBackward( *pPam );
298 // Inhalt wieder einfuegen. (erst pPos abmelden !!)
299 ULONG nMvNd = pPos->nNode.GetIndex();
300 xub_StrLen nMvCnt = pPos->nContent.GetIndex();
301 DELETEZ( pPos );
302 MoveFromUndoNds( *pDoc, nMvNd, nMvCnt, *pPam->GetMark() );
303 if( bSttWasTxtNd )
304 MovePtForward( *pPam, bMvBkwrd );
305 pPam->Exchange();
308 if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pTxtFmtColl ))
310 SwTxtNode* pTxtNd = pPam->GetMark()->nNode.GetNode().GetTxtNode();
311 if( pTxtNd )
312 pTxtNd->ChgFmtColl( pTxtFmtColl );
314 pTxtFmtColl = pSavTxtFmtColl;
316 if( pLastNdColl && USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pLastNdColl ) &&
317 pPam->GetPoint()->nNode != pPam->GetMark()->nNode )
319 SwTxtNode* pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode();
320 if( pTxtNd )
321 pTxtNd->ChgFmtColl( pLastNdColl );
324 if( pFlyUndos )
325 for( USHORT n = pFlyUndos->Count(); n; )
326 (*pFlyUndos)[ --n ]->Redo( rUndoIter );
328 pHistory->Rollback( pDoc, nSetPos );
330 if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
332 RedlineMode_t eOld = pDoc->GetRedlineMode();
333 pDoc->SetRedlineMode_intern((RedlineMode_t)( eOld & ~nsRedlineMode_t::REDLINE_IGNORE ));
334 pDoc->AppendRedline( new SwRedline( *pRedlData, *pPam ), true);
335 pDoc->SetRedlineMode_intern( eOld );
337 else if( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) &&
338 pDoc->GetRedlineTbl().Count() )
339 pDoc->SplitRedline( *pPam );
342 void SwUndoInserts::Repeat( SwUndoIter& rUndoIter )
344 if( GetId() == rUndoIter.GetLastUndoId() )
345 return;
347 SwPaM aPam( *rUndoIter.pAktPam->GetPoint() );
348 SetPaM( aPam );
349 aPam.GetDoc()->Copy( aPam, *rUndoIter.pAktPam->GetPoint(), false );
351 rUndoIter.pLastUndoObj = this;
355 /* \f */
358 SwUndoInsDoc::SwUndoInsDoc( const SwPaM& rPam )
359 : SwUndoInserts( UNDO_INSDOKUMENT, rPam )
363 SwUndoCpyDoc::SwUndoCpyDoc( const SwPaM& rPam )
364 : SwUndoInserts( UNDO_COPY, rPam )