1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unattr.cxx,v $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_sw.hxx"
36 #define _SVSTDARR_USHORTS
37 #define _SVSTDARR_USHORTSSORT
38 #include <hintids.hxx>
39 #include <svx/svdmodel.hxx>
40 #include <svx/tstpitem.hxx>
41 #include <svx/svdpage.hxx>
42 #include <svtools/itemiter.hxx>
45 #include <fmtflcnt.hxx>
47 #include <fmtornt.hxx>
48 #include <fmtanchr.hxx>
49 #include <fmtfsize.hxx>
51 #include <fmtcntnt.hxx>
55 #include <swundo.hxx> // fuer die UndoIds
58 #include <swtable.hxx>
59 #include <swtblfmt.hxx>
62 #include <ndnotxt.hxx>
63 #include <dcontact.hxx>
64 #include <ftninfo.hxx>
65 #include <redline.hxx>
66 #include <section.hxx>
67 #include <charfmt.hxx>
71 inline SwDoc
& SwUndoIter::GetDoc() const
72 { return *pAktPam
->GetDoc(); }
74 // -----------------------------------------------------
76 SwUndoFmtAttrHelper::SwUndoFmtAttrHelper( SwFmt
& rFmt
, bool bSvDrwPt
)
79 , m_bSaveDrawPt( bSvDrwPt
)
83 void SwUndoFmtAttrHelper::Modify( SfxPoolItem
* pOld
, SfxPoolItem
* pNew
)
87 if( POOLATTR_END
>= pOld
->Which() )
91 m_pUndo
->PutAttr( *pOld
);
95 m_pUndo
.reset( new SwUndoFmtAttr( *pOld
,
96 *static_cast<SwFmt
*>(pRegisteredIn
), m_bSaveDrawPt
) );
99 else if ( RES_ATTRSET_CHG
== pOld
->Which() )
104 *(static_cast<SwAttrSetChg
*>(pOld
))->GetChgSet() );
105 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
108 m_pUndo
->PutAttr( *pItem
);
109 if( aIter
.IsAtEnd() )
111 pItem
= aIter
.NextItem();
116 m_pUndo
.reset( new SwUndoFmtAttr(
117 *static_cast<SwAttrSetChg
*>(pOld
)->GetChgSet(),
118 *static_cast<SwFmt
*>(pRegisteredIn
), m_bSaveDrawPt
) );
122 SwClient::Modify( pOld
, pNew
);
125 SwClient::Modify( pOld
, pNew
);
128 // -----------------------------------------------------
130 SwUndoFmtAttr::SwUndoFmtAttr( const SfxItemSet
& rOldSet
,
133 : SwUndo( UNDO_INSFMTATTR
)
135 // --> OD 2007-07-11 #i56253#
136 , m_pOldSet( new SfxItemSet( rOldSet
) )
139 , m_nFmtWhich( rChgFmt
.Which() )
140 , m_bSaveDrawPt( bSaveDrawPt
)
145 SwUndoFmtAttr::SwUndoFmtAttr( const SfxPoolItem
& rItem
, SwFmt
& rChgFmt
,
147 : SwUndo( UNDO_INSFMTATTR
)
149 , m_pOldSet( m_pFmt
->GetAttrSet().Clone( FALSE
) )
151 , m_nFmtWhich( rChgFmt
.Which() )
152 , m_bSaveDrawPt( bSaveDrawPt
)
154 m_pOldSet
->Put( rItem
);
158 void SwUndoFmtAttr::Init()
160 // treat change of anchor specially
161 if ( SFX_ITEM_SET
== m_pOldSet
->GetItemState( RES_ANCHOR
, FALSE
))
163 SaveFlyAnchor( m_bSaveDrawPt
);
165 else if ( RES_FRMFMT
== m_nFmtWhich
)
167 SwDoc
* pDoc
= m_pFmt
->GetDoc();
168 if (USHRT_MAX
!= pDoc
->GetTblFrmFmts()->GetPos(
169 static_cast<const SwFrmFmtPtr
>(m_pFmt
)))
171 // Table Format: save table position, table formats are volatile!
172 SwTable
* pTbl
= static_cast<SwTable
*>(
173 SwClientIter( *m_pFmt
).First( TYPE( SwTable
)) );
176 m_nNodeIndex
= pTbl
->GetTabSortBoxes()[ 0 ]->GetSttNd()
177 ->FindTableNode()->GetIndex();
180 else if (USHRT_MAX
!= pDoc
->GetSections().GetPos(
181 static_cast<const SwSectionFmtPtr
>(m_pFmt
)))
183 m_nNodeIndex
= m_pFmt
->GetCntnt().GetCntntIdx()->GetIndex();
185 else if ( 0 != dynamic_cast< SwTableBoxFmt
* >( m_pFmt
) )
187 SwTableBox
* pTblBox
= static_cast< SwTableBox
* >(
188 SwClientIter( *m_pFmt
).First( TYPE( SwTableBox
)));
191 m_nNodeIndex
= pTblBox
->GetSttIdx();
197 SwUndoFmtAttr::~SwUndoFmtAttr()
201 void SwUndoFmtAttr::Undo( SwUndoIter
& rUndoIter
)
203 // OD 2004-10-26 #i35443#
204 // Important note: <Undo(..)> also called by <ReDo(..)>
206 if ( !m_pOldSet
.get() || !m_pFmt
|| !IsFmtInDoc( &rUndoIter
.GetDoc() ))
209 // --> OD 2004-10-26 #i35443# - If anchor attribute has been successfull
210 // restored, all other attributes are also restored.
211 // Thus, keep track of its restoration
212 bool bAnchorAttrRestored( false );
213 if ( SFX_ITEM_SET
== m_pOldSet
->GetItemState( RES_ANCHOR
, FALSE
))
215 bAnchorAttrRestored
= RestoreFlyAnchor( rUndoIter
);
216 if ( bAnchorAttrRestored
)
218 // Anchor attribute successfull restored.
219 // Thus, keep anchor position for redo
224 // Anchor attribute not restored due to invalid anchor position.
225 // Thus, delete anchor attribute.
226 m_pOldSet
->ClearItem( RES_ANCHOR
);
230 if ( !bAnchorAttrRestored
)
233 SwUndoFmtAttrHelper
aTmp( *m_pFmt
, m_bSaveDrawPt
);
234 m_pFmt
->SetFmtAttr( *m_pOldSet
);
235 if ( aTmp
.GetUndo() )
237 // transfer ownership of helper object's old set
238 m_pOldSet
= aTmp
.GetUndo()->m_pOldSet
;
242 m_pOldSet
->ClearItem();
245 if ( RES_FLYFRMFMT
== m_nFmtWhich
|| RES_DRAWFRMFMT
== m_nFmtWhich
)
247 rUndoIter
.pSelFmt
= static_cast<SwFrmFmt
*>(m_pFmt
);
252 bool SwUndoFmtAttr::IsFmtInDoc( SwDoc
* pDoc
)
254 // search for the Format in the Document; if it does not exist any more,
255 // the attribute is not restored!
256 USHORT nPos
= USHRT_MAX
;
257 switch ( m_nFmtWhich
)
260 nPos
= pDoc
->GetTxtFmtColls()->GetPos(
261 static_cast<const SwTxtFmtCollPtr
>(m_pFmt
) );
265 nPos
= pDoc
->GetGrfFmtColls()->GetPos(
266 static_cast<const SwGrfFmtCollPtr
>(m_pFmt
) );
270 nPos
= pDoc
->GetCharFmts()->GetPos(
271 static_cast<SwCharFmtPtr
>(m_pFmt
) );
275 if ( m_nNodeIndex
&& (m_nNodeIndex
< pDoc
->GetNodes().Count()) )
277 SwNode
* pNd
= pDoc
->GetNodes()[ m_nNodeIndex
];
278 if ( pNd
->IsTableNode() )
281 static_cast<SwTableNode
*>(pNd
)->GetTable().GetFrmFmt();
285 else if ( pNd
->IsSectionNode() )
288 static_cast<SwSectionNode
*>(pNd
)->GetSection().GetFmt();
292 else if ( pNd
->IsStartNode() && (SwTableBoxStartNode
==
293 static_cast< SwStartNode
* >(pNd
)->GetStartNodeType()) )
295 SwTableNode
* pTblNode
= pNd
->FindTableNode();
299 pTblNode
->GetTable().GetTblBox( m_nNodeIndex
);
302 m_pFmt
= pBox
->GetFrmFmt();
312 nPos
= pDoc
->GetSpzFrmFmts()->GetPos(
313 static_cast<const SwFrmFmtPtr
>(m_pFmt
) );
314 if ( USHRT_MAX
== nPos
)
316 nPos
= pDoc
->GetFrmFmts()->GetPos(
317 static_cast<const SwFrmFmtPtr
>(m_pFmt
) );
322 if ( USHRT_MAX
== nPos
)
324 // Format does not exist; reset
331 // prueft, ob es noch im Doc ist!
332 SwFmt
* SwUndoFmtAttr::GetFmt( SwDoc
& rDoc
)
334 return m_pFmt
&& IsFmtInDoc( &rDoc
) ? m_pFmt
: 0;
337 void SwUndoFmtAttr::Redo( SwUndoIter
& rUndoIter
)
339 // --> OD 2004-10-26 #i35443# - Because the undo stores the attributes for
340 // redo, the same code as for <Undo(..)> can be applied for <Redo(..)>
345 void SwUndoFmtAttr::Repeat( SwUndoIter
& rUndoIter
)
347 if ( !m_pOldSet
.get() )
350 if ( UNDO_INSFMTATTR
== rUndoIter
.GetLastUndoId())
353 = static_cast<SwUndoFmtAttr
*>(rUndoIter
.pLastUndoObj
);
354 if (pLast
->m_pOldSet
.get() && pLast
->m_pFmt
)
360 switch ( m_nFmtWhich
)
364 SwNoTxtNode
* pNd
= rUndoIter
.pAktPam
->GetNode()->GetNoTxtNode();
367 rUndoIter
.GetDoc().SetAttr( m_pFmt
->GetAttrSet(),
368 *pNd
->GetFmtColl() );
375 SwTxtNode
* pNd
= rUndoIter
.pAktPam
->GetNode()->GetTxtNode();
378 rUndoIter
.GetDoc().SetAttr( m_pFmt
->GetAttrSet(),
379 *pNd
->GetFmtColl() );
389 // erstal pruefen, ob der Cursor ueberhaupt in einem fliegenden
390 // Rahmen steht. Der Weg ist: suche in allen FlyFrmFormaten
391 // nach dem FlyCntnt-Attribut und teste ob der Cursor in der
392 // entsprechenden Section liegt.
393 SwFrmFmt
* pFly
= rUndoIter
.pAktPam
->GetNode()->GetFlyFmt();
396 // Bug 43672: es duerfen nicht alle Attribute gesetzt werden!
398 m_pFmt
->GetAttrSet().GetItemState( RES_CNTNT
))
400 SfxItemSet
aTmpSet( m_pFmt
->GetAttrSet() );
401 aTmpSet
.ClearItem( RES_CNTNT
);
402 if( aTmpSet
.Count() )
403 rUndoIter
.GetDoc().SetAttr( aTmpSet
, *pFly
);
407 rUndoIter
.GetDoc().SetAttr( m_pFmt
->GetAttrSet(), *pFly
);
414 rUndoIter
.pLastUndoObj
= this;
417 SwRewriter
SwUndoFmtAttr::GetRewriter() const
419 SwRewriter aRewriter
;
423 aRewriter
.AddRule(UNDO_ARG1
, m_pFmt
->GetName());
429 void SwUndoFmtAttr::PutAttr( const SfxPoolItem
& rItem
)
431 m_pOldSet
->Put( rItem
);
432 if ( RES_ANCHOR
== rItem
.Which() )
434 SaveFlyAnchor( m_bSaveDrawPt
);
438 void SwUndoFmtAttr::SaveFlyAnchor( bool bSvDrwPt
)
440 // das Format ist gueltig, sonst wuerde man gar bis hier kommen
443 if ( RES_DRAWFRMFMT
== m_pFmt
->Which() )
445 Point
aPt( static_cast<SwFrmFmt
*>(m_pFmt
)->FindSdrObject()
446 ->GetRelativePos() );
447 // store old value as attribute, to keep SwUndoFmtAttr small
448 m_pOldSet
->Put( SwFmtFrmSize( ATT_VAR_SIZE
, aPt
.X(), aPt
.Y() ) );
452 pOldSet->Put( pFmt->GetVertOrient() );
453 pOldSet->Put( pFmt->GetHoriOrient() );
457 const SwFmtAnchor
& rAnchor
=
458 static_cast<const SwFmtAnchor
&>( m_pOldSet
->Get( RES_ANCHOR
, FALSE
) );
459 if( !rAnchor
.GetCntntAnchor() )
462 xub_StrLen nCntnt
= 0;
463 switch( rAnchor
.GetAnchorId() )
467 nCntnt
= rAnchor
.GetCntntAnchor()->nContent
.GetIndex();
470 m_nNodeIndex
= rAnchor
.GetCntntAnchor()->nNode
.GetIndex();
476 SwFmtAnchor
aAnchor( rAnchor
.GetAnchorId(), nCntnt
);
477 m_pOldSet
->Put( aAnchor
);
480 // --> OD 2004-10-26 #i35443# - Add return value, type <bool>.
481 // Return value indicates, if anchor attribute is restored.
482 // Note: If anchor attribute is restored, all other existing attributes
483 // are also restored.
484 bool SwUndoFmtAttr::RestoreFlyAnchor( SwUndoIter
& rIter
)
486 SwDoc
* pDoc
= &rIter
.GetDoc();
487 SwFlyFrmFmt
* pFrmFmt
= static_cast<SwFlyFrmFmt
*>(m_pFmt
);
488 const SwFmtAnchor
& rAnchor
=
489 static_cast<const SwFmtAnchor
&>( m_pOldSet
->Get( RES_ANCHOR
, FALSE
) );
491 SwFmtAnchor
aNewAnchor( rAnchor
.GetAnchorId() );
492 if( FLY_PAGE
!= rAnchor
.GetAnchorId() )
494 SwNode
* pNd
= pDoc
->GetNodes()[ m_nNodeIndex
];
496 if ( (FLY_AT_FLY
== rAnchor
.GetAnchorId())
497 ? ( !pNd
->IsStartNode() || (SwFlyStartNode
!=
498 static_cast<SwStartNode
*>(pNd
)->GetStartNodeType()) )
499 : !pNd
->IsTxtNode() )
501 // --> OD 2004-10-26 #i35443# - invalid position.
502 // Thus, anchor attribute not restored
507 SwPosition
aPos( *pNd
);
508 if( FLY_IN_CNTNT
== rAnchor
.GetAnchorId() ||
509 FLY_AUTO_CNTNT
== rAnchor
.GetAnchorId() )
511 aPos
.nContent
.Assign( (SwTxtNode
*)pNd
, rAnchor
.GetPageNum() );
512 if ( aPos
.nContent
.GetIndex() >
513 static_cast<SwTxtNode
*>(pNd
)->GetTxt().Len() )
515 // --> OD 2004-10-26 #i35443# - invalid position.
516 // Thus, anchor attribute not restored
521 aNewAnchor
.SetAnchor( &aPos
);
524 aNewAnchor
.SetPageNum( rAnchor
.GetPageNum() );
526 Point aDrawSavePt
, aDrawOldPt
;
527 if( pDoc
->GetRootFrm() )
529 if( RES_DRAWFRMFMT
== pFrmFmt
->Which() )
531 // den alten zwischengespeicherten Wert herausholen.
532 const SwFmtFrmSize
& rOldSize
= static_cast<const SwFmtFrmSize
&>(
533 m_pOldSet
->Get( RES_FRM_SIZE
) );
534 aDrawSavePt
.X() = rOldSize
.GetWidth();
535 aDrawSavePt
.Y() = rOldSize
.GetHeight();
536 m_pOldSet
->ClearItem( RES_FRM_SIZE
);
538 // den akt. wieder zwischenspeichern
539 aDrawOldPt
= pFrmFmt
->FindSdrObject()->GetRelativePos();
540 //JP 08.10.97: ist laut AMA/MA nicht mehr noetig
541 // pCont->DisconnectFromLayout();
545 pFrmFmt
->DelFrms(); // delete Frms
549 const SwFmtAnchor
&rOldAnch
= pFrmFmt
->GetAnchor();
550 // --> OD 2006-03-13 #i54336#
551 // Consider case, that as-character anchored object has moved its anchor position.
552 if ( FLY_IN_CNTNT
== rOldAnch
.GetAnchorId() )
555 //Bei InCntnt's wird es spannend: Das TxtAttribut muss vernichtet
556 //werden. Leider reisst dies neben den Frms auch noch das Format mit
557 //in sein Grab. Um dass zu unterbinden loesen wir vorher die
558 //Verbindung zwischen Attribut und Format.
559 const SwPosition
*pPos
= rOldAnch
.GetCntntAnchor();
560 SwTxtNode
*pTxtNode
= (SwTxtNode
*)&pPos
->nNode
.GetNode();
561 ASSERT( pTxtNode
->HasHints(), "Missing FlyInCnt-Hint." );
562 const xub_StrLen nIdx
= pPos
->nContent
.GetIndex();
563 SwTxtAttr
* const pHnt
=
564 pTxtNode
->GetTxtAttrForCharAt( nIdx
, RES_TXTATR_FLYCNT
);
565 ASSERT( pHnt
&& pHnt
->Which() == RES_TXTATR_FLYCNT
,
566 "Missing FlyInCnt-Hint." );
567 ASSERT( pHnt
&& pHnt
->GetFlyCnt().GetFrmFmt() == pFrmFmt
,
568 "Wrong TxtFlyCnt-Hint." );
569 const_cast<SwFmtFlyCnt
&>(pHnt
->GetFlyCnt()).SetFlyFmt();
571 //Die Verbindung ist geloest, jetzt muss noch das Attribut vernichtet
573 pTxtNode
->DeleteAttributes( RES_TXTATR_FLYCNT
, nIdx
, nIdx
);
577 m_pOldSet
->Put( aNewAnchor
);
578 SwUndoFmtAttrHelper
aTmp( *m_pFmt
, m_bSaveDrawPt
);
579 m_pFmt
->SetFmtAttr( *m_pOldSet
);
580 if ( aTmp
.GetUndo() )
582 m_nNodeIndex
= aTmp
.GetUndo()->m_nNodeIndex
;
583 // transfer ownership of helper object's old set
584 m_pOldSet
= aTmp
.GetUndo()->m_pOldSet
;
588 m_pOldSet
->ClearItem();
592 if ( RES_DRAWFRMFMT
== pFrmFmt
->Which() )
594 SwDrawContact
*pCont
=
595 static_cast<SwDrawContact
*>(pFrmFmt
->FindContactObj());
596 // das Draw-Model hat auch noch ein Undo-Object fuer die
597 // richtige Position vorbereitet; dieses ist aber relativ.
598 // Darum verhinder hier, das durch setzen des Ankers das
599 // Contact-Object seine Position aendert.
600 //JP 08.10.97: ist laut AMA/MA nicht mehr noetig
601 // pCont->ConnectToLayout();
602 SdrObject
* pObj
= pCont
->GetMaster();
604 if( pCont
->GetAnchorFrm() && !pObj
->IsInserted() )
606 ASSERT( pDoc
->GetDrawModel(), "RestoreFlyAnchor without DrawModel" );
607 pDoc
->GetDrawModel()->GetPage( 0 )->InsertObject( pObj
);
609 pObj
->SetRelativePos( aDrawSavePt
);
611 // den alten Wert wieder zwischenspeichern.
613 SwFmtFrmSize( ATT_VAR_SIZE
, aDrawOldPt
.X(), aDrawOldPt
.Y() ) );
616 if( FLY_IN_CNTNT
== aNewAnchor
.GetAnchorId() )
618 const SwPosition
* pPos
= aNewAnchor
.GetCntntAnchor();
619 SwTxtNode
* pTxtNd
= pPos
->nNode
.GetNode().GetTxtNode();
620 ASSERT( pTxtNd
, "no Text Node at position." );
621 SwFmtFlyCnt
aFmt( pFrmFmt
);
622 pTxtNd
->InsertItem( aFmt
, pPos
->nContent
.GetIndex(), 0 );
626 if( RES_DRAWFRMFMT
!= pFrmFmt
->Which() )
629 rIter
.pSelFmt
= pFrmFmt
;
631 // --> OD 2004-10-26 #i35443# - anchor attribute restored.
636 // -----------------------------------------------------
638 // --> OD 2008-02-12 #newlistlevelattrs#
639 SwUndoFmtResetAttr::SwUndoFmtResetAttr( SwFmt
& rChangedFormat
,
640 const USHORT nWhichId
)
641 : SwUndo( UNDO_RESETATTR
)
642 , m_pChangedFormat( &rChangedFormat
)
643 , m_nWhichId( nWhichId
)
646 const SfxPoolItem
* pItem
= 0;
647 if (rChangedFormat
.GetItemState( nWhichId
, FALSE
, &pItem
) == SFX_ITEM_SET
)
649 m_pOldItem
.reset( pItem
->Clone() );
653 SwUndoFmtResetAttr::~SwUndoFmtResetAttr()
657 void SwUndoFmtResetAttr::Undo( SwUndoIter
& )
659 if ( m_pOldItem
.get() )
661 m_pChangedFormat
->SetFmtAttr( *m_pOldItem
);
665 void SwUndoFmtResetAttr::Redo( SwUndoIter
& )
667 if ( m_pOldItem
.get() )
669 m_pChangedFormat
->ResetFmtAttr( m_nWhichId
);
674 // -----------------------------------------------------
676 SwUndoResetAttr::SwUndoResetAttr( const SwPaM
& rRange
, USHORT nFmtId
)
677 : SwUndo( UNDO_RESETATTR
), SwUndRng( rRange
)
678 , m_pHistory( new SwHistory
)
679 , m_nFormatId( nFmtId
)
683 SwUndoResetAttr::SwUndoResetAttr( const SwPosition
& rPos
, USHORT nFmtId
)
684 : SwUndo( UNDO_RESETATTR
)
685 , m_pHistory( new SwHistory
)
686 , m_nFormatId( nFmtId
)
688 nSttNode
= nEndNode
= rPos
.nNode
.GetIndex();
689 nSttCntnt
= nEndCntnt
= rPos
.nContent
.GetIndex();
692 SwUndoResetAttr::~SwUndoResetAttr()
696 void SwUndoResetAttr::Undo( SwUndoIter
& rUndoIter
)
699 SwDoc
& rDoc
= rUndoIter
.GetDoc();
700 m_pHistory
->TmpRollback( &rDoc
, 0 );
701 m_pHistory
->SetTmpEnd( m_pHistory
->Count() );
703 if ((RES_CONDTXTFMTCOLL
== m_nFormatId
) &&
704 (nSttNode
== nEndNode
) && (nSttCntnt
== nEndCntnt
))
706 SwTxtNode
* pTNd
= rDoc
.GetNodes()[ nSttNode
]->GetTxtNode();
709 SwIndex
aIdx( pTNd
, nSttCntnt
);
710 pTNd
->DontExpandFmt( aIdx
, FALSE
);
714 // setze noch den Cursor auf den Undo-Bereich
718 void SwUndoResetAttr::Redo( SwUndoIter
& rUndoIter
)
720 // setze Attribut in dem Bereich:
722 SwDoc
& rDoc
= rUndoIter
.GetDoc();
723 rUndoIter
.pLastUndoObj
= 0;
724 SvUShortsSort
* pIdArr
= m_Ids
.Count() ? &m_Ids
: 0;
726 switch ( m_nFormatId
)
729 rUndoIter
.GetDoc().RstTxtAttrs( *rUndoIter
.pAktPam
);
732 rUndoIter
.GetDoc().ResetAttrs( *rUndoIter
.pAktPam
, FALSE
, pIdArr
);
734 case RES_CONDTXTFMTCOLL
:
735 rUndoIter
.GetDoc().ResetAttrs( *rUndoIter
.pAktPam
, TRUE
, pIdArr
);
738 case RES_TXTATR_TOXMARK
:
739 // special treatment for TOXMarks
742 SwNodeIndex
aIdx( rDoc
.GetNodes(), nSttNode
);
743 SwPosition
aPos( aIdx
, SwIndex( aIdx
.GetNode().GetCntntNode(),
746 USHORT nCnt
= rDoc
.GetCurTOXMark( aPos
, aArr
);
751 // search for the right one
752 SwHistoryHint
* pHHint
= (GetHistory())[ 0 ];
753 if( pHHint
&& HSTRY_SETTOXMARKHNT
== pHHint
->Which() )
757 if ( static_cast<SwHistorySetTOXMark
*>(pHHint
)
758 ->IsEqual( *aArr
[ --nCnt
] ) )
768 // gefunden, also loeschen
771 rDoc
.DeleteTOXMark( aArr
[ nCnt
] );
777 rUndoIter
.pLastUndoObj
= 0;
780 void SwUndoResetAttr::Repeat( SwUndoIter
& rUndoIter
)
782 if ( (RES_FMT_BEGIN
> m_nFormatId
) ||
783 ( (UNDO_RESETATTR
== rUndoIter
.GetLastUndoId()) &&
784 (m_nFormatId
== static_cast<SwUndoResetAttr
*>(rUndoIter
.pLastUndoObj
)
790 SvUShortsSort
* pIdArr
= m_Ids
.Count() ? &m_Ids
: 0;
791 switch ( m_nFormatId
)
794 rUndoIter
.GetDoc().RstTxtAttrs( *rUndoIter
.pAktPam
);
797 rUndoIter
.GetDoc().ResetAttrs( *rUndoIter
.pAktPam
, FALSE
, pIdArr
);
799 case RES_CONDTXTFMTCOLL
:
800 rUndoIter
.GetDoc().ResetAttrs( *rUndoIter
.pAktPam
, TRUE
, pIdArr
);
803 rUndoIter
.pLastUndoObj
= this;
807 void SwUndoResetAttr::SetAttrs( const SvUShortsSort
& rArr
)
811 m_Ids
.Remove( 0, m_Ids
.Count() );
813 m_Ids
.Insert( &rArr
);
816 // -----------------------------------------------------
819 SwUndoAttr::SwUndoAttr( const SwPaM
& rRange
, const SfxPoolItem
& rAttr
,
820 const SetAttrMode nFlags
)
821 : SwUndo( UNDO_INSATTR
), SwUndRng( rRange
)
822 , m_AttrSet( rRange
.GetDoc()->GetAttrPool(), rAttr
.Which(), rAttr
.Which() )
823 , m_pHistory( new SwHistory
)
824 , m_pRedlineData( 0 )
825 , m_pRedlineSaveData( 0 )
826 , m_nNodeIndex( ULONG_MAX
)
827 , m_nInsertFlags( nFlags
)
829 m_AttrSet
.Put( rAttr
);
832 SwUndoAttr::SwUndoAttr( const SwPaM
& rRange
, const SfxItemSet
& rSet
,
833 const SetAttrMode nFlags
)
834 : SwUndo( UNDO_INSATTR
), SwUndRng( rRange
)
836 , m_pHistory( new SwHistory
)
837 , m_pRedlineData( 0 )
838 , m_pRedlineSaveData( 0 )
839 , m_nNodeIndex( ULONG_MAX
)
840 , m_nInsertFlags( nFlags
)
844 SwUndoAttr::~SwUndoAttr()
848 void SwUndoAttr::SaveRedlineData( const SwPaM
& rPam
, BOOL bIsCntnt
)
850 SwDoc
* pDoc
= rPam
.GetDoc();
851 if ( pDoc
->IsRedlineOn() )
853 m_pRedlineData
.reset( new SwRedlineData( bIsCntnt
854 ? nsRedlineType_t::REDLINE_INSERT
855 : nsRedlineType_t::REDLINE_FORMAT
,
856 pDoc
->GetRedlineAuthor() ) );
859 m_pRedlineSaveData
.reset( new SwRedlineSaveDatas
);
860 if ( !FillSaveDataForFmt( rPam
, *m_pRedlineSaveData
))
862 m_pRedlineSaveData
.reset(0);
865 SetRedlineMode( pDoc
->GetRedlineMode() );
868 m_nNodeIndex
= rPam
.GetPoint()->nNode
.GetIndex();
872 void SwUndoAttr::Undo( SwUndoIter
& rUndoIter
)
874 SwDoc
* pDoc
= &rUndoIter
.GetDoc();
878 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
880 SwPaM
& rPam
= *rUndoIter
.pAktPam
;
881 if ( ULONG_MAX
!= m_nNodeIndex
)
884 rPam
.GetPoint()->nNode
= m_nNodeIndex
;
885 rPam
.GetPoint()->nContent
.Assign( rPam
.GetCntntNode(), nSttCntnt
);
887 rPam
.GetPoint()->nContent
++;
888 pDoc
->DeleteRedline( rPam
, false, USHRT_MAX
);
892 // alle Format-Redlines entfernen, werden ggfs. neu gesetzt
894 pDoc
->DeleteRedline( rPam
, false, nsRedlineType_t::REDLINE_FORMAT
);
895 if ( m_pRedlineSaveData
.get() )
897 SetSaveData( *pDoc
, *m_pRedlineSaveData
);
902 const bool bToLast
= (1 == m_AttrSet
.Count())
903 && (RES_TXTATR_FIELD
<= *m_AttrSet
.GetRanges())
904 && (*m_AttrSet
.GetRanges() <= RES_TXTATR_FTN
);
906 // restore old values
907 m_pHistory
->TmpRollback( pDoc
, 0, !bToLast
);
908 m_pHistory
->SetTmpEnd( m_pHistory
->Count() );
910 // set cursor onto Undo area
914 int lcl_HasEqualItems( const SfxItemSet
& rSet1
, const SfxItemSet
& rSet2
)
917 SfxItemIter
aIter1( rSet1
), aIter2( rSet2
);
918 const SfxPoolItem
*pI1
= aIter1
.FirstItem(), *pI2
= aIter2
.FirstItem();
922 if( pI1
->Which() != pI2
->Which() ||
923 aIter1
.IsAtEnd() != aIter2
.IsAtEnd() )
928 if( aIter1
.IsAtEnd() )
930 pI1
= aIter1
.NextItem();
931 pI2
= aIter2
.NextItem();
936 void SwUndoAttr::Repeat( SwUndoIter
& rUndoIter
)
938 if ( UNDO_INSATTR
== rUndoIter
.GetLastUndoId() )
940 SwUndoAttr
* pLast
= static_cast<SwUndoAttr
*>(rUndoIter
.pLastUndoObj
);
941 if ((pLast
->m_AttrSet
.Count() == m_AttrSet
.Count()) &&
942 (pLast
->m_nInsertFlags
== m_nInsertFlags
) &&
943 lcl_HasEqualItems( m_AttrSet
, pLast
->m_AttrSet
))
950 // RefMarks are not repeat capable
951 if ( SFX_ITEM_SET
!= m_AttrSet
.GetItemState( RES_TXTATR_REFMARK
, FALSE
) )
953 rUndoIter
.GetDoc().InsertItemSet( *rUndoIter
.pAktPam
,
954 m_AttrSet
, m_nInsertFlags
);
956 else if ( 1 < m_AttrSet
.Count() )
958 SfxItemSet
aTmpSet( m_AttrSet
);
959 aTmpSet
.ClearItem( RES_TXTATR_REFMARK
);
960 rUndoIter
.GetDoc().InsertItemSet( *rUndoIter
.pAktPam
,
961 aTmpSet
, m_nInsertFlags
);
963 rUndoIter
.pLastUndoObj
= this;
966 void SwUndoAttr::Redo( SwUndoIter
& rUndoIter
)
968 // setze Attribut in dem Bereich:
970 SwPaM
& rPam
= *rUndoIter
.pAktPam
;
971 SwDoc
& rDoc
= rUndoIter
.GetDoc();
973 if ( m_pRedlineData
.get() &&
974 IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
976 RedlineMode_t eOld
= rDoc
.GetRedlineMode();
977 rDoc
.SetRedlineMode_intern(static_cast<RedlineMode_t
>(
978 eOld
& ~nsRedlineMode_t::REDLINE_IGNORE
));
979 rDoc
.InsertItemSet( rPam
, m_AttrSet
, m_nInsertFlags
);
981 if ( ULONG_MAX
!= m_nNodeIndex
)
984 if ( rPam
.Move( fnMoveBackward
) )
986 rDoc
.AppendRedline( new SwRedline( *m_pRedlineData
, rPam
),
993 rDoc
.AppendRedline( new SwRedline( *m_pRedlineData
, rPam
), true);
996 rDoc
.SetRedlineMode_intern( eOld
);
1000 rDoc
.InsertItemSet( rPam
, m_AttrSet
, m_nInsertFlags
);
1003 rUndoIter
.pLastUndoObj
= 0;
1007 void SwUndoAttr::RemoveIdx( SwDoc
& rDoc
)
1009 if ( SFX_ITEM_SET
!= m_AttrSet
.GetItemState( RES_TXTATR_FTN
, FALSE
))
1012 SwHistoryHint
* pHstHnt
;
1013 SwNodes
& rNds
= rDoc
.GetNodes();
1014 for ( USHORT n
= 0; n
< m_pHistory
->Count(); ++n
)
1016 xub_StrLen nCntnt
= 0;
1018 pHstHnt
= (*m_pHistory
)[ n
];
1019 switch ( pHstHnt
->Which() )
1021 case HSTRY_RESETTXTHNT
:
1023 SwHistoryResetTxt
* pHistoryHint
1024 = static_cast<SwHistoryResetTxt
*>(pHstHnt
);
1025 if ( RES_TXTATR_FTN
== pHistoryHint
->GetWhich() )
1027 nNode
= pHistoryHint
->GetNode();
1028 nCntnt
= pHistoryHint
->GetCntnt();
1033 case HSTRY_RESETATTRSET
:
1035 SwHistoryResetAttrSet
* pHistoryHint
1036 = static_cast<SwHistoryResetAttrSet
*>(pHstHnt
);
1037 nCntnt
= pHistoryHint
->GetCntnt();
1038 if ( STRING_MAXLEN
!= nCntnt
)
1040 const SvUShorts
& rArr
= pHistoryHint
->GetArr();
1041 for ( USHORT i
= rArr
.Count(); i
; )
1043 if ( RES_TXTATR_FTN
== rArr
[ --i
] )
1045 nNode
= pHistoryHint
->GetNode();
1059 SwTxtNode
* pTxtNd
= rNds
[ nNode
]->GetTxtNode();
1062 SwIndex
aIdx( pTxtNd
, nCntnt
);
1063 SwTxtAttr
* pTxtHt
= pTxtNd
->GetTxtAttr( aIdx
, RES_TXTATR_FTN
);
1066 // ok, dann hole mal die Werte
1067 SwTxtFtn
* pFtn
= static_cast<SwTxtFtn
*>(pTxtHt
);
1068 RemoveIdxFromSection( rDoc
, pFtn
->GetStartNode()->GetIndex() );
1076 // -----------------------------------------------------
1078 SwUndoDefaultAttr::SwUndoDefaultAttr( const SfxItemSet
& rSet
)
1079 : SwUndo( UNDO_SETDEFTATTR
)
1083 const SfxPoolItem
* pItem
;
1084 if( SFX_ITEM_SET
== rSet
.GetItemState( RES_PARATR_TABSTOP
, FALSE
, &pItem
) )
1086 // store separately, because it may change!
1087 m_pTabStop
.reset( static_cast<SvxTabStopItem
*>(pItem
->Clone()) );
1088 if ( 1 != rSet
.Count() ) // are there more attributes?
1090 m_pOldSet
.reset( new SfxItemSet( rSet
) );
1095 m_pOldSet
.reset( new SfxItemSet( rSet
) );
1099 SwUndoDefaultAttr::~SwUndoDefaultAttr()
1103 void SwUndoDefaultAttr::Undo( SwUndoIter
& rUndoIter
)
1105 SwDoc
& rDoc
= rUndoIter
.GetDoc();
1106 if ( m_pOldSet
.get() )
1108 SwUndoFmtAttrHelper
aTmp(
1109 *const_cast<SwTxtFmtColl
*>(rDoc
.GetDfltTxtFmtColl()) );
1110 rDoc
.SetDefault( *m_pOldSet
);
1111 m_pOldSet
.reset( 0 );
1112 if ( aTmp
.GetUndo() )
1114 // transfer ownership of helper object's old set
1115 m_pOldSet
= aTmp
.GetUndo()->m_pOldSet
;
1118 if ( m_pTabStop
.get() )
1120 SvxTabStopItem
* pOld
= static_cast<SvxTabStopItem
*>(
1121 rDoc
.GetDefault( RES_PARATR_TABSTOP
).Clone() );
1122 rDoc
.SetDefault( *m_pTabStop
);
1123 m_pTabStop
.reset( pOld
);
1127 void SwUndoDefaultAttr::Redo( SwUndoIter
& rUndoIter
)
1132 // -----------------------------------------------------
1134 SwUndoMoveLeftMargin::SwUndoMoveLeftMargin(
1135 const SwPaM
& rPam
, BOOL bFlag
, BOOL bMod
)
1136 : SwUndo( bFlag
? UNDO_INC_LEFTMARGIN
: UNDO_DEC_LEFTMARGIN
)
1138 , m_pHistory( new SwHistory
)
1139 , m_bModulus( bMod
)
1143 SwUndoMoveLeftMargin::~SwUndoMoveLeftMargin()
1147 void SwUndoMoveLeftMargin::Undo( SwUndoIter
& rIter
)
1149 SwDoc
* pDoc
= &rIter
.GetDoc();
1150 BOOL bUndo
= pDoc
->DoesUndo();
1151 pDoc
->DoUndo( FALSE
);
1153 // restore old values
1154 m_pHistory
->TmpRollback( pDoc
, 0 );
1155 m_pHistory
->SetTmpEnd( m_pHistory
->Count() );
1157 pDoc
->DoUndo( bUndo
);
1161 void SwUndoMoveLeftMargin::Redo( SwUndoIter
& rIter
)
1163 SwDoc
* pDoc
= &rIter
.GetDoc();
1165 pDoc
->MoveLeftMargin( *rIter
.pAktPam
, GetId() == UNDO_INC_LEFTMARGIN
,
1169 void SwUndoMoveLeftMargin::Repeat( SwUndoIter
& rIter
)
1171 SwDoc
* pDoc
= &rIter
.GetDoc();
1172 pDoc
->MoveLeftMargin( *rIter
.pAktPam
, GetId() == UNDO_INC_LEFTMARGIN
,
1174 rIter
.pLastUndoObj
= this;
1177 // -----------------------------------------------------
1179 SwUndoChangeFootNote::SwUndoChangeFootNote(
1180 const SwPaM
& rRange
, const String
& rTxt
,
1181 USHORT nNum
, bool bIsEndNote
)
1182 : SwUndo( UNDO_CHGFTN
), SwUndRng( rRange
)
1183 , m_pHistory( new SwHistory() )
1186 , m_bEndNote( bIsEndNote
)
1190 SwUndoChangeFootNote::~SwUndoChangeFootNote()
1194 void SwUndoChangeFootNote::Undo( SwUndoIter
& rIter
)
1196 SwDoc
& rDoc
= rIter
.GetDoc();
1199 BOOL bUndo
= rDoc
.DoesUndo();
1200 rDoc
.DoUndo( FALSE
);
1202 m_pHistory
->TmpRollback( &rDoc
, 0 );
1203 m_pHistory
->SetTmpEnd( m_pHistory
->Count() );
1205 rDoc
.GetFtnIdxs().UpdateAllFtn();
1208 rDoc
.DoUndo( bUndo
);
1211 void SwUndoChangeFootNote::Redo( SwUndoIter
& rIter
)
1214 rIter
.GetDoc().SetCurFtn( *rIter
.pAktPam
, m_Text
, m_nNumber
, m_bEndNote
);
1218 void SwUndoChangeFootNote::Repeat( SwUndoIter
& rIter
)
1220 SwDoc
& rDoc
= rIter
.GetDoc();
1221 rDoc
.SetCurFtn( *rIter
.pAktPam
, m_Text
, m_nNumber
, m_bEndNote
);
1222 rIter
.pLastUndoObj
= this;
1226 // -----------------------------------------------------
1229 SwUndoFootNoteInfo::SwUndoFootNoteInfo( const SwFtnInfo
&rInfo
)
1230 : SwUndo( UNDO_FTNINFO
)
1231 , m_pFootNoteInfo( new SwFtnInfo( rInfo
) )
1235 SwUndoFootNoteInfo::~SwUndoFootNoteInfo()
1239 void SwUndoFootNoteInfo::Undo( SwUndoIter
&rIter
)
1241 SwDoc
&rDoc
= rIter
.GetDoc();
1242 SwFtnInfo
*pInf
= new SwFtnInfo( rDoc
.GetFtnInfo() );
1243 rDoc
.SetFtnInfo( *m_pFootNoteInfo
);
1244 m_pFootNoteInfo
.reset( pInf
);
1247 void SwUndoFootNoteInfo::Redo( SwUndoIter
&rIter
)
1249 SwDoc
&rDoc
= rIter
.GetDoc();
1250 SwFtnInfo
*pInf
= new SwFtnInfo( rDoc
.GetFtnInfo() );
1251 rDoc
.SetFtnInfo( *m_pFootNoteInfo
);
1252 m_pFootNoteInfo
.reset( pInf
);
1256 // -----------------------------------------------------
1258 SwUndoEndNoteInfo::SwUndoEndNoteInfo( const SwEndNoteInfo
&rInfo
)
1259 : SwUndo( UNDO_FTNINFO
)
1260 , m_pEndNoteInfo( new SwEndNoteInfo( rInfo
) )
1264 SwUndoEndNoteInfo::~SwUndoEndNoteInfo()
1268 void SwUndoEndNoteInfo::Undo( SwUndoIter
&rIter
)
1270 SwDoc
&rDoc
= rIter
.GetDoc();
1271 SwEndNoteInfo
*pInf
= new SwEndNoteInfo( rDoc
.GetEndNoteInfo() );
1272 rDoc
.SetEndNoteInfo( *m_pEndNoteInfo
);
1273 m_pEndNoteInfo
.reset( pInf
);
1276 void SwUndoEndNoteInfo::Redo( SwUndoIter
&rIter
)
1278 SwDoc
&rDoc
= rIter
.GetDoc();
1279 SwEndNoteInfo
*pInf
= new SwEndNoteInfo( rDoc
.GetEndNoteInfo() );
1280 rDoc
.SetEndNoteInfo( *m_pEndNoteInfo
);
1281 m_pEndNoteInfo
.reset( pInf
);
1284 // -----------------------------------------------------
1286 SwUndoDontExpandFmt::SwUndoDontExpandFmt( const SwPosition
& rPos
)
1287 : SwUndo( UNDO_DONTEXPAND
)
1288 , m_nNodeIndex( rPos
.nNode
.GetIndex() )
1289 , m_nContentIndex( rPos
.nContent
.GetIndex() )
1293 void SwUndoDontExpandFmt::Undo( SwUndoIter
& rIter
)
1295 SwPaM
* pPam
= rIter
.pAktPam
;
1296 SwDoc
* pDoc
= pPam
->GetDoc();
1298 SwPosition
& rPos
= *pPam
->GetPoint();
1299 rPos
.nNode
= m_nNodeIndex
;
1300 rPos
.nContent
.Assign( rPos
.nNode
.GetNode().GetCntntNode(), m_nContentIndex
);
1301 pDoc
->DontExpandFmt( rPos
, FALSE
);
1305 void SwUndoDontExpandFmt::Redo( SwUndoIter
& rIter
)
1307 SwPaM
* pPam
= rIter
.pAktPam
;
1308 SwDoc
* pDoc
= pPam
->GetDoc();
1310 SwPosition
& rPos
= *pPam
->GetPoint();
1311 rPos
.nNode
= m_nNodeIndex
;
1312 rPos
.nContent
.Assign( rPos
.nNode
.GetNode().GetCntntNode(), m_nContentIndex
);
1313 pDoc
->DontExpandFmt( rPos
);
1316 void SwUndoDontExpandFmt::Repeat( SwUndoIter
& rIter
)
1318 SwPaM
* pPam
= rIter
.pAktPam
;
1319 SwDoc
* pDoc
= pPam
->GetDoc();
1320 pDoc
->DontExpandFmt( *pPam
->GetPoint() );