Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / sw / source / core / undo / unattr.cxx
blob613b415f0db98b1df5641f4b068b14c72b12a83b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <UndoAttribute.hxx>
21 #include <svl/itemiter.hxx>
22 #include <editeng/tstpitem.hxx>
23 #include <svx/svdmodel.hxx>
24 #include <svx/svdpage.hxx>
25 #include <hintids.hxx>
26 #include <fmtflcnt.hxx>
27 #include <txtftn.hxx>
28 #include <fmtornt.hxx>
29 #include <fmtanchr.hxx>
30 #include <fmtfsize.hxx>
31 #include <frmfmt.hxx>
32 #include <fmtcntnt.hxx>
33 #include <ftnidx.hxx>
34 #include <doc.hxx>
35 #include <IDocumentUndoRedo.hxx>
36 #include <IShellCursorSupplier.hxx>
37 #include <docary.hxx>
38 #include <swundo.hxx>
39 #include <pam.hxx>
40 #include <ndtxt.hxx>
41 #include <swtable.hxx>
42 #include <swtblfmt.hxx>
43 #include <UndoCore.hxx>
44 #include <hints.hxx>
45 #include <rolbck.hxx>
46 #include <ndnotxt.hxx>
47 #include <dcontact.hxx>
48 #include <ftninfo.hxx>
49 #include <redline.hxx>
50 #include <section.hxx>
51 #include <charfmt.hxx>
52 #include <switerator.hxx>
54 SwUndoFmtAttrHelper::SwUndoFmtAttrHelper( SwFmt& rFmt, bool bSvDrwPt )
55 : SwClient( &rFmt )
56 , m_pUndo( 0 )
57 , m_bSaveDrawPt( bSvDrwPt )
61 void SwUndoFmtAttrHelper::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
63 if( pOld )
65 if ( pOld->Which() == RES_OBJECTDYING )
67 CheckRegistration( pOld, pNew );
69 else if ( pNew )
71 if( POOLATTR_END >= pOld->Which() )
73 if ( GetUndo() )
75 m_pUndo->PutAttr( *pOld );
77 else
79 m_pUndo.reset( new SwUndoFmtAttr( *pOld,
80 *static_cast<SwFmt*>(GetRegisteredInNonConst()), m_bSaveDrawPt ) );
83 else if ( RES_ATTRSET_CHG == pOld->Which() )
85 if ( GetUndo() )
87 SfxItemIter aIter(
88 *(static_cast<const SwAttrSetChg*>(pOld))->GetChgSet() );
89 const SfxPoolItem* pItem = aIter.GetCurItem();
90 while ( pItem )
92 m_pUndo->PutAttr( *pItem );
93 if( aIter.IsAtEnd() )
94 break;
95 pItem = aIter.NextItem();
98 else
100 m_pUndo.reset( new SwUndoFmtAttr(
101 *static_cast<const SwAttrSetChg*>(pOld)->GetChgSet(),
102 *static_cast<SwFmt*>(GetRegisteredInNonConst()), m_bSaveDrawPt ) );
109 SwUndoFmtAttr::SwUndoFmtAttr( const SfxItemSet& rOldSet,
110 SwFmt& rChgFmt,
111 bool bSaveDrawPt )
112 : SwUndo( UNDO_INSFMTATTR )
113 , m_pFmt( &rChgFmt )
114 // #i56253#
115 , m_pOldSet( new SfxItemSet( rOldSet ) )
116 , m_nNodeIndex( 0 )
117 , m_nFmtWhich( rChgFmt.Which() )
118 , m_bSaveDrawPt( bSaveDrawPt )
120 Init();
123 SwUndoFmtAttr::SwUndoFmtAttr( const SfxPoolItem& rItem, SwFmt& rChgFmt,
124 bool bSaveDrawPt )
125 : SwUndo( UNDO_INSFMTATTR )
126 , m_pFmt( &rChgFmt )
127 , m_pOldSet( m_pFmt->GetAttrSet().Clone( sal_False ) )
128 , m_nNodeIndex( 0 )
129 , m_nFmtWhich( rChgFmt.Which() )
130 , m_bSaveDrawPt( bSaveDrawPt )
132 m_pOldSet->Put( rItem );
133 Init();
136 void SwUndoFmtAttr::Init()
138 // treat change of anchor specially
139 if ( SFX_ITEM_SET == m_pOldSet->GetItemState( RES_ANCHOR, sal_False ))
141 SaveFlyAnchor( m_bSaveDrawPt );
143 else if ( RES_FRMFMT == m_nFmtWhich )
145 SwDoc* pDoc = m_pFmt->GetDoc();
146 if ( pDoc->GetTblFrmFmts()->Contains(static_cast<const SwFrmFmt*>(m_pFmt)))
148 // Table Format: save table position, table formats are volatile!
149 SwTable * pTbl = SwIterator<SwTable,SwFmt>::FirstElement( *m_pFmt );
150 if ( pTbl )
152 m_nNodeIndex = pTbl->GetTabSortBoxes()[ 0 ]->GetSttNd()
153 ->FindTableNode()->GetIndex();
156 else if ( pDoc->GetSections().Contains(static_cast<const SwSectionFmt*>(m_pFmt)))
158 m_nNodeIndex = m_pFmt->GetCntnt().GetCntntIdx()->GetIndex();
160 else if ( 0 != dynamic_cast< SwTableBoxFmt* >( m_pFmt ) )
162 SwTableBox * pTblBox = SwIterator<SwTableBox,SwFmt>::FirstElement( *m_pFmt );
163 if ( pTblBox )
165 m_nNodeIndex = pTblBox->GetSttIdx();
171 SwUndoFmtAttr::~SwUndoFmtAttr()
175 void SwUndoFmtAttr::UndoImpl(::sw::UndoRedoContext & rContext)
177 // OD 2004-10-26 #i35443#
178 // Important note: <Undo(..)> also called by <ReDo(..)>
180 if ( !m_pOldSet.get() || !m_pFmt || !IsFmtInDoc( &rContext.GetDoc() ))
181 return;
183 // #i35443# - If anchor attribute has been successfull
184 // restored, all other attributes are also restored.
185 // Thus, keep track of its restoration
186 bool bAnchorAttrRestored( false );
187 if ( SFX_ITEM_SET == m_pOldSet->GetItemState( RES_ANCHOR, sal_False ))
189 bAnchorAttrRestored = RestoreFlyAnchor(rContext);
190 if ( bAnchorAttrRestored )
192 // Anchor attribute successfull restored.
193 // Thus, keep anchor position for redo
194 SaveFlyAnchor();
196 else
198 // Anchor attribute not restored due to invalid anchor position.
199 // Thus, delete anchor attribute.
200 m_pOldSet->ClearItem( RES_ANCHOR );
204 if ( !bAnchorAttrRestored )
206 SwUndoFmtAttrHelper aTmp( *m_pFmt, m_bSaveDrawPt );
207 m_pFmt->SetFmtAttr( *m_pOldSet );
208 if ( aTmp.GetUndo() )
210 // transfer ownership of helper object's old set
211 m_pOldSet = aTmp.GetUndo()->m_pOldSet;
213 else
215 m_pOldSet->ClearItem();
218 if ( RES_FLYFRMFMT == m_nFmtWhich || RES_DRAWFRMFMT == m_nFmtWhich )
220 rContext.SetSelections(static_cast<SwFrmFmt*>(m_pFmt), 0);
225 bool SwUndoFmtAttr::IsFmtInDoc( SwDoc* pDoc )
227 // search for the Format in the Document; if it does not exist any more,
228 // the attribute is not restored!
229 sal_uInt16 nPos = USHRT_MAX;
230 switch ( m_nFmtWhich )
232 case RES_TXTFMTCOLL:
233 nPos = pDoc->GetTxtFmtColls()->GetPos(
234 static_cast<const SwTxtFmtColl*>(m_pFmt) );
235 break;
237 case RES_GRFFMTCOLL:
238 nPos = pDoc->GetGrfFmtColls()->GetPos(
239 static_cast<const SwGrfFmtColl*>(m_pFmt) );
240 break;
242 case RES_CHRFMT:
243 nPos = pDoc->GetCharFmts()->GetPos(
244 static_cast<SwCharFmt*>(m_pFmt) );
245 break;
247 case RES_FRMFMT:
248 if ( m_nNodeIndex && (m_nNodeIndex < pDoc->GetNodes().Count()) )
250 SwNode* pNd = pDoc->GetNodes()[ m_nNodeIndex ];
251 if ( pNd->IsTableNode() )
253 m_pFmt =
254 static_cast<SwTableNode*>(pNd)->GetTable().GetFrmFmt();
255 nPos = 0;
256 break;
258 else if ( pNd->IsSectionNode() )
260 m_pFmt =
261 static_cast<SwSectionNode*>(pNd)->GetSection().GetFmt();
262 nPos = 0;
263 break;
265 else if ( pNd->IsStartNode() && (SwTableBoxStartNode ==
266 static_cast< SwStartNode* >(pNd)->GetStartNodeType()) )
268 SwTableNode* pTblNode = pNd->FindTableNode();
269 if ( pTblNode )
271 SwTableBox* pBox =
272 pTblNode->GetTable().GetTblBox( m_nNodeIndex );
273 if ( pBox )
275 m_pFmt = pBox->GetFrmFmt();
276 nPos = 0;
277 break;
282 // no break!
283 case RES_DRAWFRMFMT:
284 case RES_FLYFRMFMT:
285 nPos = pDoc->GetSpzFrmFmts()->GetPos(
286 static_cast<const SwFrmFmt*>(m_pFmt) );
287 if ( USHRT_MAX == nPos )
289 nPos = pDoc->GetFrmFmts()->GetPos(
290 static_cast<const SwFrmFmt*>(m_pFmt) );
292 break;
295 if ( USHRT_MAX == nPos )
297 // Format does not exist; reset
298 m_pFmt = 0;
301 return 0 != m_pFmt;
304 // Check if it is still in Doc
305 SwFmt* SwUndoFmtAttr::GetFmt( SwDoc& rDoc )
307 return m_pFmt && IsFmtInDoc( &rDoc ) ? m_pFmt : 0;
310 void SwUndoFmtAttr::RedoImpl(::sw::UndoRedoContext & rContext)
312 // #i35443# - Because the undo stores the attributes for
313 // redo, the same code as for <Undo(..)> can be applied for <Redo(..)>
314 UndoImpl(rContext);
317 void SwUndoFmtAttr::RepeatImpl(::sw::RepeatContext & rContext)
319 if ( !m_pOldSet.get() )
320 return;
322 SwDoc & rDoc(rContext.GetDoc());
324 switch ( m_nFmtWhich )
326 case RES_GRFFMTCOLL:
328 SwNoTxtNode *const pNd =
329 rContext.GetRepeatPaM().GetNode()->GetNoTxtNode();
330 if( pNd )
332 rDoc.SetAttr( m_pFmt->GetAttrSet(), *pNd->GetFmtColl() );
335 break;
337 case RES_TXTFMTCOLL:
339 SwTxtNode *const pNd =
340 rContext.GetRepeatPaM().GetNode()->GetTxtNode();
341 if( pNd )
343 rDoc.SetAttr( m_pFmt->GetAttrSet(), *pNd->GetFmtColl() );
346 break;
348 case RES_FLYFRMFMT:
350 // Check if the cursor is in a flying frame
351 // Steps: search in all FlyFrmFormats for the FlyCntnt attribute
352 // and validate if the cursor is in the respective section
353 SwFrmFmt *const pFly =
354 rContext.GetRepeatPaM().GetNode()->GetFlyFmt();
355 if( pFly )
357 // Bug 43672: do not set all attributes!
358 if (SFX_ITEM_SET ==
359 m_pFmt->GetAttrSet().GetItemState( RES_CNTNT ))
361 SfxItemSet aTmpSet( m_pFmt->GetAttrSet() );
362 aTmpSet.ClearItem( RES_CNTNT );
363 if( aTmpSet.Count() )
365 rDoc.SetAttr( aTmpSet, *pFly );
368 else
370 rDoc.SetAttr( m_pFmt->GetAttrSet(), *pFly );
373 break;
378 SwRewriter SwUndoFmtAttr::GetRewriter() const
380 SwRewriter aRewriter;
382 if (m_pFmt)
384 aRewriter.AddRule(UndoArg1, m_pFmt->GetName());
387 return aRewriter;
390 void SwUndoFmtAttr::PutAttr( const SfxPoolItem& rItem )
392 m_pOldSet->Put( rItem );
393 if ( RES_ANCHOR == rItem.Which() )
395 SaveFlyAnchor( m_bSaveDrawPt );
399 void SwUndoFmtAttr::SaveFlyAnchor( bool bSvDrwPt )
401 // Format is valid, otherwise you would not reach this point here
402 if( bSvDrwPt )
404 if ( RES_DRAWFRMFMT == m_pFmt->Which() )
406 Point aPt( static_cast<SwFrmFmt*>(m_pFmt)->FindSdrObject()
407 ->GetRelativePos() );
408 // store old value as attribute, to keep SwUndoFmtAttr small
409 m_pOldSet->Put( SwFmtFrmSize( ATT_VAR_SIZE, aPt.X(), aPt.Y() ) );
413 const SwFmtAnchor& rAnchor =
414 static_cast<const SwFmtAnchor&>( m_pOldSet->Get( RES_ANCHOR, sal_False ) );
415 if( !rAnchor.GetCntntAnchor() )
416 return;
418 xub_StrLen nCntnt = 0;
419 switch( rAnchor.GetAnchorId() )
421 case FLY_AS_CHAR:
422 case FLY_AT_CHAR:
423 nCntnt = rAnchor.GetCntntAnchor()->nContent.GetIndex();
424 case FLY_AT_PARA:
425 case FLY_AT_FLY:
426 m_nNodeIndex = rAnchor.GetCntntAnchor()->nNode.GetIndex();
427 break;
428 default:
429 return;
432 SwFmtAnchor aAnchor( rAnchor.GetAnchorId(), nCntnt );
433 m_pOldSet->Put( aAnchor );
436 // #i35443# - Add return value, type <bool>.
437 // Return value indicates, if anchor attribute is restored.
438 // Note: If anchor attribute is restored, all other existing attributes
439 // are also restored.
440 bool SwUndoFmtAttr::RestoreFlyAnchor(::sw::UndoRedoContext & rContext)
442 SwDoc *const pDoc = & rContext.GetDoc();
443 SwFlyFrmFmt* pFrmFmt = static_cast<SwFlyFrmFmt*>(m_pFmt);
444 const SwFmtAnchor& rAnchor =
445 static_cast<const SwFmtAnchor&>( m_pOldSet->Get( RES_ANCHOR, sal_False ) );
447 SwFmtAnchor aNewAnchor( rAnchor.GetAnchorId() );
448 if (FLY_AT_PAGE != rAnchor.GetAnchorId())
450 SwNode* pNd = pDoc->GetNodes()[ m_nNodeIndex ];
452 if ( (FLY_AT_FLY == rAnchor.GetAnchorId())
453 ? ( !pNd->IsStartNode() || (SwFlyStartNode !=
454 static_cast<SwStartNode*>(pNd)->GetStartNodeType()) )
455 : !pNd->IsTxtNode() )
457 // #i35443# - invalid position.
458 // Thus, anchor attribute not restored
459 return false;
462 SwPosition aPos( *pNd );
463 if ((FLY_AS_CHAR == rAnchor.GetAnchorId()) ||
464 (FLY_AT_CHAR == rAnchor.GetAnchorId()))
466 aPos.nContent.Assign( (SwTxtNode*)pNd, rAnchor.GetPageNum() );
467 if ( aPos.nContent.GetIndex() >
468 static_cast<SwTxtNode*>(pNd)->GetTxt().Len() )
470 // #i35443# - invalid position.
471 // Thus, anchor attribute not restored
472 return false;
475 aNewAnchor.SetAnchor( &aPos );
477 else
478 aNewAnchor.SetPageNum( rAnchor.GetPageNum() );
480 Point aDrawSavePt, aDrawOldPt;
481 if( pDoc->GetCurrentViewShell() ) //swmod 071108//swmod 071225
483 if( RES_DRAWFRMFMT == pFrmFmt->Which() )
485 // get the old cached value
486 const SwFmtFrmSize& rOldSize = static_cast<const SwFmtFrmSize&>(
487 m_pOldSet->Get( RES_FRM_SIZE ) );
488 aDrawSavePt.X() = rOldSize.GetWidth();
489 aDrawSavePt.Y() = rOldSize.GetHeight();
490 m_pOldSet->ClearItem( RES_FRM_SIZE );
492 // write the current value into cache
493 aDrawOldPt = pFrmFmt->FindSdrObject()->GetRelativePos();
495 else
497 pFrmFmt->DelFrms(); // delete Frms
501 const SwFmtAnchor &rOldAnch = pFrmFmt->GetAnchor();
502 // #i54336#
503 // Consider case, that as-character anchored object has moved its anchor position.
504 if (FLY_AS_CHAR == rOldAnch.GetAnchorId())
506 // With InCntnts it's tricky: the text attribute needs to be deleted.
507 // Unfortunately, this not only destroys the Frms but also the format.
508 // To prevent that, first detach the connection between attribute and
509 // format.
510 const SwPosition *pPos = rOldAnch.GetCntntAnchor();
511 SwTxtNode *pTxtNode = (SwTxtNode*)&pPos->nNode.GetNode();
512 OSL_ENSURE( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
513 const xub_StrLen nIdx = pPos->nContent.GetIndex();
514 SwTxtAttr * const pHnt =
515 pTxtNode->GetTxtAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
516 OSL_ENSURE( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
517 "Missing FlyInCnt-Hint." );
518 OSL_ENSURE( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pFrmFmt,
519 "Wrong TxtFlyCnt-Hint." );
520 const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
522 // Connection is now detached, therefore the attribute can be deleted
523 pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
527 m_pOldSet->Put( aNewAnchor );
528 SwUndoFmtAttrHelper aTmp( *m_pFmt, m_bSaveDrawPt );
529 m_pFmt->SetFmtAttr( *m_pOldSet );
530 if ( aTmp.GetUndo() )
532 m_nNodeIndex = aTmp.GetUndo()->m_nNodeIndex;
533 // transfer ownership of helper object's old set
534 m_pOldSet = aTmp.GetUndo()->m_pOldSet;
536 else
538 m_pOldSet->ClearItem();
542 if ( RES_DRAWFRMFMT == pFrmFmt->Which() )
544 SwDrawContact *pCont =
545 static_cast<SwDrawContact*>(pFrmFmt->FindContactObj());
546 // The Draw model also prepared an Undo object for its right positioning
547 // which unfortunately is relative. Therefore block here a position
548 // change of the Contact object by setting the anchor.
549 SdrObject* pObj = pCont->GetMaster();
551 if( pCont->GetAnchorFrm() && !pObj->IsInserted() )
553 OSL_ENSURE( pDoc->GetDrawModel(), "RestoreFlyAnchor without DrawModel" );
554 pDoc->GetDrawModel()->GetPage( 0 )->InsertObject( pObj );
556 pObj->SetRelativePos( aDrawSavePt );
558 // cache the old value again
559 m_pOldSet->Put(
560 SwFmtFrmSize( ATT_VAR_SIZE, aDrawOldPt.X(), aDrawOldPt.Y() ) );
563 if (FLY_AS_CHAR == aNewAnchor.GetAnchorId())
565 const SwPosition* pPos = aNewAnchor.GetCntntAnchor();
566 SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
567 OSL_ENSURE( pTxtNd, "no Text Node at position." );
568 SwFmtFlyCnt aFmt( pFrmFmt );
569 pTxtNd->InsertItem( aFmt, pPos->nContent.GetIndex(), 0 );
573 if( RES_DRAWFRMFMT != pFrmFmt->Which() )
574 pFrmFmt->MakeFrms();
576 rContext.SetSelections(pFrmFmt, 0);
578 // #i35443# - anchor attribute restored.
579 return true;
582 SwUndoFmtResetAttr::SwUndoFmtResetAttr( SwFmt& rChangedFormat,
583 const sal_uInt16 nWhichId )
584 : SwUndo( UNDO_RESETATTR )
585 , m_pChangedFormat( &rChangedFormat )
586 , m_nWhichId( nWhichId )
587 , m_pOldItem( 0 )
589 const SfxPoolItem* pItem = 0;
590 if (rChangedFormat.GetItemState( nWhichId, sal_False, &pItem ) == SFX_ITEM_SET)
592 m_pOldItem.reset( pItem->Clone() );
596 SwUndoFmtResetAttr::~SwUndoFmtResetAttr()
600 void SwUndoFmtResetAttr::UndoImpl(::sw::UndoRedoContext &)
602 if ( m_pOldItem.get() )
604 m_pChangedFormat->SetFmtAttr( *m_pOldItem );
608 void SwUndoFmtResetAttr::RedoImpl(::sw::UndoRedoContext &)
610 if ( m_pOldItem.get() )
612 m_pChangedFormat->ResetFmtAttr( m_nWhichId );
616 SwUndoResetAttr::SwUndoResetAttr( const SwPaM& rRange, sal_uInt16 nFmtId )
617 : SwUndo( UNDO_RESETATTR ), SwUndRng( rRange )
618 , m_pHistory( new SwHistory )
619 , m_nFormatId( nFmtId )
623 SwUndoResetAttr::SwUndoResetAttr( const SwPosition& rPos, sal_uInt16 nFmtId )
624 : SwUndo( UNDO_RESETATTR )
625 , m_pHistory( new SwHistory )
626 , m_nFormatId( nFmtId )
628 nSttNode = nEndNode = rPos.nNode.GetIndex();
629 nSttCntnt = nEndCntnt = rPos.nContent.GetIndex();
632 SwUndoResetAttr::~SwUndoResetAttr()
636 void SwUndoResetAttr::UndoImpl(::sw::UndoRedoContext & rContext)
638 // reset old values
639 SwDoc & rDoc = rContext.GetDoc();
640 m_pHistory->TmpRollback( &rDoc, 0 );
641 m_pHistory->SetTmpEnd( m_pHistory->Count() );
643 if ((RES_CONDTXTFMTCOLL == m_nFormatId) &&
644 (nSttNode == nEndNode) && (nSttCntnt == nEndCntnt))
646 SwTxtNode* pTNd = rDoc.GetNodes()[ nSttNode ]->GetTxtNode();
647 if( pTNd )
649 SwIndex aIdx( pTNd, nSttCntnt );
650 pTNd->DontExpandFmt( aIdx, false );
654 AddUndoRedoPaM(rContext);
657 void SwUndoResetAttr::RedoImpl(::sw::UndoRedoContext & rContext)
659 SwDoc & rDoc = rContext.GetDoc();
660 SwPaM & rPam = AddUndoRedoPaM(rContext);
662 switch ( m_nFormatId )
664 case RES_CHRFMT:
665 rDoc.RstTxtAttrs(rPam);
666 break;
667 case RES_TXTFMTCOLL:
668 rDoc.ResetAttrs(rPam, false, m_Ids );
669 break;
670 case RES_CONDTXTFMTCOLL:
671 rDoc.ResetAttrs(rPam, true, m_Ids );
673 break;
674 case RES_TXTATR_TOXMARK:
675 // special treatment for TOXMarks
677 SwTOXMarks aArr;
678 SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );
679 SwPosition aPos( aIdx, SwIndex( aIdx.GetNode().GetCntntNode(),
680 nSttCntnt ));
682 sal_uInt16 nCnt = rDoc.GetCurTOXMark( aPos, aArr );
683 if( nCnt )
685 if( 1 < nCnt )
687 // search for the right one
688 SwHistoryHint* pHHint = (GetHistory())[ 0 ];
689 if( pHHint && HSTRY_SETTOXMARKHNT == pHHint->Which() )
691 while( nCnt )
693 if ( static_cast<SwHistorySetTOXMark*>(pHHint)
694 ->IsEqual( *aArr[ --nCnt ] ) )
696 ++nCnt;
697 break;
701 else
702 nCnt = 0;
704 // found one, thus delete it
705 if( nCnt-- )
707 rDoc.DeleteTOXMark( aArr[ nCnt ] );
711 break;
715 void SwUndoResetAttr::RepeatImpl(::sw::RepeatContext & rContext)
717 if (m_nFormatId < RES_FMT_BEGIN)
719 return;
722 switch ( m_nFormatId )
724 case RES_CHRFMT:
725 rContext.GetDoc().RstTxtAttrs(rContext.GetRepeatPaM());
726 break;
727 case RES_TXTFMTCOLL:
728 rContext.GetDoc().ResetAttrs(rContext.GetRepeatPaM(), false, m_Ids);
729 break;
730 case RES_CONDTXTFMTCOLL:
731 rContext.GetDoc().ResetAttrs(rContext.GetRepeatPaM(), true, m_Ids);
732 break;
737 void SwUndoResetAttr::SetAttrs( const std::set<sal_uInt16> &rAttrs )
739 m_Ids.clear();
740 m_Ids.insert( rAttrs.begin(), rAttrs.end() );
743 SwUndoAttr::SwUndoAttr( const SwPaM& rRange, const SfxPoolItem& rAttr,
744 const SetAttrMode nFlags )
745 : SwUndo( UNDO_INSATTR ), SwUndRng( rRange )
746 , m_AttrSet( rRange.GetDoc()->GetAttrPool(), rAttr.Which(), rAttr.Which() )
747 , m_pHistory( new SwHistory )
748 , m_pRedlineData( 0 )
749 , m_pRedlineSaveData( 0 )
750 , m_nNodeIndex( ULONG_MAX )
751 , m_nInsertFlags( nFlags )
753 m_AttrSet.Put( rAttr );
756 SwUndoAttr::SwUndoAttr( const SwPaM& rRange, const SfxItemSet& rSet,
757 const SetAttrMode nFlags )
758 : SwUndo( UNDO_INSATTR ), SwUndRng( rRange )
759 , m_AttrSet( rSet )
760 , m_pHistory( new SwHistory )
761 , m_pRedlineData( 0 )
762 , m_pRedlineSaveData( 0 )
763 , m_nNodeIndex( ULONG_MAX )
764 , m_nInsertFlags( nFlags )
768 SwUndoAttr::~SwUndoAttr()
772 void SwUndoAttr::SaveRedlineData( const SwPaM& rPam, sal_Bool bIsCntnt )
774 SwDoc* pDoc = rPam.GetDoc();
775 if ( pDoc->IsRedlineOn() )
777 m_pRedlineData.reset( new SwRedlineData( bIsCntnt
778 ? nsRedlineType_t::REDLINE_INSERT
779 : nsRedlineType_t::REDLINE_FORMAT,
780 pDoc->GetRedlineAuthor() ) );
783 m_pRedlineSaveData.reset( new SwRedlineSaveDatas );
784 if ( !FillSaveDataForFmt( rPam, *m_pRedlineSaveData ))
786 m_pRedlineSaveData.reset(0);
789 SetRedlineMode( pDoc->GetRedlineMode() );
790 if ( bIsCntnt )
792 m_nNodeIndex = rPam.GetPoint()->nNode.GetIndex();
796 void SwUndoAttr::UndoImpl(::sw::UndoRedoContext & rContext)
798 SwDoc *const pDoc = & rContext.GetDoc();
800 RemoveIdx( *pDoc );
802 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
804 SwPaM aPam(pDoc->GetNodes().GetEndOfContent());
805 if ( ULONG_MAX != m_nNodeIndex )
807 aPam.DeleteMark();
808 aPam.GetPoint()->nNode = m_nNodeIndex;
809 aPam.GetPoint()->nContent.Assign( aPam.GetCntntNode(), nSttCntnt );
810 aPam.SetMark();
811 aPam.GetPoint()->nContent++;
812 pDoc->DeleteRedline(aPam, false, USHRT_MAX);
814 else
816 // remove all format redlines, will be recreated if needed
817 SetPaM(aPam);
818 pDoc->DeleteRedline(aPam, false, nsRedlineType_t::REDLINE_FORMAT);
819 if ( m_pRedlineSaveData.get() )
821 SetSaveData( *pDoc, *m_pRedlineSaveData );
826 const bool bToLast = (1 == m_AttrSet.Count())
827 && (RES_TXTATR_FIELD <= *m_AttrSet.GetRanges())
828 && (*m_AttrSet.GetRanges() <= RES_TXTATR_FTN);
830 // restore old values
831 m_pHistory->TmpRollback( pDoc, 0, !bToLast );
832 m_pHistory->SetTmpEnd( m_pHistory->Count() );
834 // set cursor onto Undo area
835 AddUndoRedoPaM(rContext);
838 void SwUndoAttr::RepeatImpl(::sw::RepeatContext & rContext)
840 // RefMarks are not repeat capable
841 if ( SFX_ITEM_SET != m_AttrSet.GetItemState( RES_TXTATR_REFMARK, sal_False ) )
843 rContext.GetDoc().InsertItemSet( rContext.GetRepeatPaM(),
844 m_AttrSet, m_nInsertFlags );
846 else if ( 1 < m_AttrSet.Count() )
848 SfxItemSet aTmpSet( m_AttrSet );
849 aTmpSet.ClearItem( RES_TXTATR_REFMARK );
850 rContext.GetDoc().InsertItemSet( rContext.GetRepeatPaM(),
851 aTmpSet, m_nInsertFlags );
855 void SwUndoAttr::RedoImpl(::sw::UndoRedoContext & rContext)
857 SwDoc & rDoc = rContext.GetDoc();
858 SwPaM & rPam = AddUndoRedoPaM(rContext);
860 if ( m_pRedlineData.get() &&
861 IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
863 RedlineMode_t eOld = rDoc.GetRedlineMode();
864 rDoc.SetRedlineMode_intern(static_cast<RedlineMode_t>(
865 eOld & ~nsRedlineMode_t::REDLINE_IGNORE));
866 rDoc.InsertItemSet( rPam, m_AttrSet, m_nInsertFlags );
868 if ( ULONG_MAX != m_nNodeIndex )
870 rPam.SetMark();
871 if ( rPam.Move( fnMoveBackward ) )
873 rDoc.AppendRedline( new SwRedline( *m_pRedlineData, rPam ),
874 true);
876 rPam.DeleteMark();
878 else
880 rDoc.AppendRedline( new SwRedline( *m_pRedlineData, rPam ), true);
883 rDoc.SetRedlineMode_intern( eOld );
885 else
887 rDoc.InsertItemSet( rPam, m_AttrSet, m_nInsertFlags );
891 void SwUndoAttr::RemoveIdx( SwDoc& rDoc )
893 if ( SFX_ITEM_SET != m_AttrSet.GetItemState( RES_TXTATR_FTN, sal_False ))
894 return ;
896 SwHistoryHint* pHstHnt;
897 SwNodes& rNds = rDoc.GetNodes();
898 for ( sal_uInt16 n = 0; n < m_pHistory->Count(); ++n )
900 xub_StrLen nCntnt = 0;
901 sal_uLong nNode = 0;
902 pHstHnt = (*m_pHistory)[ n ];
903 switch ( pHstHnt->Which() )
905 case HSTRY_RESETTXTHNT:
907 SwHistoryResetTxt * pHistoryHint
908 = static_cast<SwHistoryResetTxt*>(pHstHnt);
909 if ( RES_TXTATR_FTN == pHistoryHint->GetWhich() )
911 nNode = pHistoryHint->GetNode();
912 nCntnt = pHistoryHint->GetCntnt();
915 break;
917 case HSTRY_RESETATTRSET:
919 SwHistoryResetAttrSet * pHistoryHint
920 = static_cast<SwHistoryResetAttrSet*>(pHstHnt);
921 nCntnt = pHistoryHint->GetCntnt();
922 if ( STRING_MAXLEN != nCntnt )
924 const std::vector<sal_uInt16>& rArr = pHistoryHint->GetArr();
925 for ( sal_uInt16 i = rArr.size(); i; )
927 if ( RES_TXTATR_FTN == rArr[ --i ] )
929 nNode = pHistoryHint->GetNode();
930 break;
935 break;
937 default:
938 break;
941 if( nNode )
943 SwTxtNode* pTxtNd = rNds[ nNode ]->GetTxtNode();
944 if( pTxtNd )
946 SwTxtAttr *const pTxtHt =
947 pTxtNd->GetTxtAttrForCharAt(nCntnt, RES_TXTATR_FTN);
948 if( pTxtHt )
950 // ok, so get values
951 SwTxtFtn* pFtn = static_cast<SwTxtFtn*>(pTxtHt);
952 RemoveIdxFromSection( rDoc, pFtn->GetStartNode()->GetIndex() );
953 return ;
960 SwUndoDefaultAttr::SwUndoDefaultAttr( const SfxItemSet& rSet )
961 : SwUndo( UNDO_SETDEFTATTR )
962 , m_pOldSet( 0 )
963 , m_pTabStop( 0 )
965 const SfxPoolItem* pItem;
966 if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_TABSTOP, sal_False, &pItem ) )
968 // store separately, because it may change!
969 m_pTabStop.reset( static_cast<SvxTabStopItem*>(pItem->Clone()) );
970 if ( 1 != rSet.Count() ) // are there more attributes?
972 m_pOldSet.reset( new SfxItemSet( rSet ) );
975 else
977 m_pOldSet.reset( new SfxItemSet( rSet ) );
981 SwUndoDefaultAttr::~SwUndoDefaultAttr()
985 void SwUndoDefaultAttr::UndoImpl(::sw::UndoRedoContext & rContext)
987 SwDoc & rDoc = rContext.GetDoc();
988 if ( m_pOldSet.get() )
990 SwUndoFmtAttrHelper aTmp(
991 *const_cast<SwTxtFmtColl*>(rDoc.GetDfltTxtFmtColl()) );
992 rDoc.SetDefault( *m_pOldSet );
993 m_pOldSet.reset( 0 );
994 if ( aTmp.GetUndo() )
996 // transfer ownership of helper object's old set
997 m_pOldSet = aTmp.GetUndo()->m_pOldSet;
1000 if ( m_pTabStop.get() )
1002 SvxTabStopItem* pOld = static_cast<SvxTabStopItem*>(
1003 rDoc.GetDefault( RES_PARATR_TABSTOP ).Clone() );
1004 rDoc.SetDefault( *m_pTabStop );
1005 m_pTabStop.reset( pOld );
1009 void SwUndoDefaultAttr::RedoImpl(::sw::UndoRedoContext & rContext)
1011 UndoImpl(rContext);
1014 SwUndoMoveLeftMargin::SwUndoMoveLeftMargin(
1015 const SwPaM& rPam, sal_Bool bFlag, bool bMod )
1016 : SwUndo( bFlag ? UNDO_INC_LEFTMARGIN : UNDO_DEC_LEFTMARGIN )
1017 , SwUndRng( rPam )
1018 , m_pHistory( new SwHistory )
1019 , m_bModulus( bMod )
1023 SwUndoMoveLeftMargin::~SwUndoMoveLeftMargin()
1027 void SwUndoMoveLeftMargin::UndoImpl(::sw::UndoRedoContext & rContext)
1029 SwDoc & rDoc = rContext.GetDoc();
1031 // restore old values
1032 m_pHistory->TmpRollback( & rDoc, 0 );
1033 m_pHistory->SetTmpEnd( m_pHistory->Count() );
1035 AddUndoRedoPaM(rContext);
1038 void SwUndoMoveLeftMargin::RedoImpl(::sw::UndoRedoContext & rContext)
1040 SwDoc & rDoc = rContext.GetDoc();
1041 SwPaM & rPam = AddUndoRedoPaM(rContext);
1043 rDoc.MoveLeftMargin( rPam,
1044 GetId() == UNDO_INC_LEFTMARGIN, m_bModulus );
1047 void SwUndoMoveLeftMargin::RepeatImpl(::sw::RepeatContext & rContext)
1049 SwDoc & rDoc = rContext.GetDoc();
1050 rDoc.MoveLeftMargin(rContext.GetRepeatPaM(), GetId() == UNDO_INC_LEFTMARGIN,
1051 m_bModulus );
1054 SwUndoChangeFootNote::SwUndoChangeFootNote(
1055 const SwPaM& rRange, const String& rTxt,
1056 sal_uInt16 nNum, bool bIsEndNote )
1057 : SwUndo( UNDO_CHGFTN ), SwUndRng( rRange )
1058 , m_pHistory( new SwHistory() )
1059 , m_Text( rTxt )
1060 , m_nNumber( nNum )
1061 , m_bEndNote( bIsEndNote )
1065 SwUndoChangeFootNote::~SwUndoChangeFootNote()
1069 void SwUndoChangeFootNote::UndoImpl(::sw::UndoRedoContext & rContext)
1071 SwDoc & rDoc = rContext.GetDoc();
1073 m_pHistory->TmpRollback( &rDoc, 0 );
1074 m_pHistory->SetTmpEnd( m_pHistory->Count() );
1076 rDoc.GetFtnIdxs().UpdateAllFtn();
1078 AddUndoRedoPaM(rContext);
1081 void SwUndoChangeFootNote::RedoImpl(::sw::UndoRedoContext & rContext)
1083 SwDoc & rDoc( rContext.GetDoc() );
1084 SwPaM & rPaM = AddUndoRedoPaM(rContext);
1085 rDoc.SetCurFtn(rPaM, m_Text, m_nNumber, m_bEndNote);
1086 SetPaM(rPaM);
1089 void SwUndoChangeFootNote::RepeatImpl(::sw::RepeatContext & rContext)
1091 SwDoc & rDoc = rContext.GetDoc();
1092 rDoc.SetCurFtn( rContext.GetRepeatPaM(), m_Text, m_nNumber, m_bEndNote );
1095 SwUndoFootNoteInfo::SwUndoFootNoteInfo( const SwFtnInfo &rInfo )
1096 : SwUndo( UNDO_FTNINFO )
1097 , m_pFootNoteInfo( new SwFtnInfo( rInfo ) )
1101 SwUndoFootNoteInfo::~SwUndoFootNoteInfo()
1105 void SwUndoFootNoteInfo::UndoImpl(::sw::UndoRedoContext & rContext)
1107 SwDoc & rDoc = rContext.GetDoc();
1108 SwFtnInfo *pInf = new SwFtnInfo( rDoc.GetFtnInfo() );
1109 rDoc.SetFtnInfo( *m_pFootNoteInfo );
1110 m_pFootNoteInfo.reset( pInf );
1113 void SwUndoFootNoteInfo::RedoImpl(::sw::UndoRedoContext & rContext)
1115 SwDoc & rDoc = rContext.GetDoc();
1116 SwFtnInfo *pInf = new SwFtnInfo( rDoc.GetFtnInfo() );
1117 rDoc.SetFtnInfo( *m_pFootNoteInfo );
1118 m_pFootNoteInfo.reset( pInf );
1121 SwUndoEndNoteInfo::SwUndoEndNoteInfo( const SwEndNoteInfo &rInfo )
1122 : SwUndo( UNDO_FTNINFO )
1123 , m_pEndNoteInfo( new SwEndNoteInfo( rInfo ) )
1127 SwUndoEndNoteInfo::~SwUndoEndNoteInfo()
1131 void SwUndoEndNoteInfo::UndoImpl(::sw::UndoRedoContext & rContext)
1133 SwDoc & rDoc = rContext.GetDoc();
1134 SwEndNoteInfo *pInf = new SwEndNoteInfo( rDoc.GetEndNoteInfo() );
1135 rDoc.SetEndNoteInfo( *m_pEndNoteInfo );
1136 m_pEndNoteInfo.reset( pInf );
1139 void SwUndoEndNoteInfo::RedoImpl(::sw::UndoRedoContext & rContext)
1141 SwDoc & rDoc = rContext.GetDoc();
1142 SwEndNoteInfo *pInf = new SwEndNoteInfo( rDoc.GetEndNoteInfo() );
1143 rDoc.SetEndNoteInfo( *m_pEndNoteInfo );
1144 m_pEndNoteInfo.reset( pInf );
1147 SwUndoDontExpandFmt::SwUndoDontExpandFmt( const SwPosition& rPos )
1148 : SwUndo( UNDO_DONTEXPAND )
1149 , m_nNodeIndex( rPos.nNode.GetIndex() )
1150 , m_nContentIndex( rPos.nContent.GetIndex() )
1154 void SwUndoDontExpandFmt::UndoImpl(::sw::UndoRedoContext & rContext)
1156 SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
1157 SwDoc *const pDoc = & rContext.GetDoc();
1159 SwPosition& rPos = *pPam->GetPoint();
1160 rPos.nNode = m_nNodeIndex;
1161 rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), m_nContentIndex);
1162 pDoc->DontExpandFmt( rPos, false );
1165 void SwUndoDontExpandFmt::RedoImpl(::sw::UndoRedoContext & rContext)
1167 SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
1168 SwDoc *const pDoc = & rContext.GetDoc();
1170 SwPosition& rPos = *pPam->GetPoint();
1171 rPos.nNode = m_nNodeIndex;
1172 rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), m_nContentIndex);
1173 pDoc->DontExpandFmt( rPos );
1176 void SwUndoDontExpandFmt::RepeatImpl(::sw::RepeatContext & rContext)
1178 SwPaM & rPam = rContext.GetRepeatPaM();
1179 SwDoc & rDoc = rContext.GetDoc();
1180 rDoc.DontExpandFmt( *rPam.GetPoint() );
1183 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */