1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
28 #include <fmtornt.hxx>
29 #include <fmtanchr.hxx>
30 #include <fmtfsize.hxx>
32 #include <fmtcntnt.hxx>
35 #include <IDocumentUndoRedo.hxx>
36 #include <IShellCursorSupplier.hxx>
41 #include <swtable.hxx>
42 #include <swtblfmt.hxx>
43 #include <UndoCore.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
)
57 , m_bSaveDrawPt( bSvDrwPt
)
61 void SwUndoFmtAttrHelper::Modify( const SfxPoolItem
* pOld
, const SfxPoolItem
* pNew
)
65 if ( pOld
->Which() == RES_OBJECTDYING
)
67 CheckRegistration( pOld
, pNew
);
71 if( POOLATTR_END
>= pOld
->Which() )
75 m_pUndo
->PutAttr( *pOld
);
79 m_pUndo
.reset( new SwUndoFmtAttr( *pOld
,
80 *static_cast<SwFmt
*>(GetRegisteredInNonConst()), m_bSaveDrawPt
) );
83 else if ( RES_ATTRSET_CHG
== pOld
->Which() )
88 *(static_cast<const SwAttrSetChg
*>(pOld
))->GetChgSet() );
89 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
92 m_pUndo
->PutAttr( *pItem
);
95 pItem
= aIter
.NextItem();
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
,
112 : SwUndo( UNDO_INSFMTATTR
)
115 , m_pOldSet( new SfxItemSet( rOldSet
) )
117 , m_nFmtWhich( rChgFmt
.Which() )
118 , m_bSaveDrawPt( bSaveDrawPt
)
123 SwUndoFmtAttr::SwUndoFmtAttr( const SfxPoolItem
& rItem
, SwFmt
& rChgFmt
,
125 : SwUndo( UNDO_INSFMTATTR
)
127 , m_pOldSet( m_pFmt
->GetAttrSet().Clone( sal_False
) )
129 , m_nFmtWhich( rChgFmt
.Which() )
130 , m_bSaveDrawPt( bSaveDrawPt
)
132 m_pOldSet
->Put( rItem
);
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
);
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
);
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() ))
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
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
;
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
)
233 nPos
= pDoc
->GetTxtFmtColls()->GetPos(
234 static_cast<const SwTxtFmtColl
*>(m_pFmt
) );
238 nPos
= pDoc
->GetGrfFmtColls()->GetPos(
239 static_cast<const SwGrfFmtColl
*>(m_pFmt
) );
243 nPos
= pDoc
->GetCharFmts()->GetPos(
244 static_cast<SwCharFmt
*>(m_pFmt
) );
248 if ( m_nNodeIndex
&& (m_nNodeIndex
< pDoc
->GetNodes().Count()) )
250 SwNode
* pNd
= pDoc
->GetNodes()[ m_nNodeIndex
];
251 if ( pNd
->IsTableNode() )
254 static_cast<SwTableNode
*>(pNd
)->GetTable().GetFrmFmt();
258 else if ( pNd
->IsSectionNode() )
261 static_cast<SwSectionNode
*>(pNd
)->GetSection().GetFmt();
265 else if ( pNd
->IsStartNode() && (SwTableBoxStartNode
==
266 static_cast< SwStartNode
* >(pNd
)->GetStartNodeType()) )
268 SwTableNode
* pTblNode
= pNd
->FindTableNode();
272 pTblNode
->GetTable().GetTblBox( m_nNodeIndex
);
275 m_pFmt
= pBox
->GetFrmFmt();
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
) );
295 if ( USHRT_MAX
== nPos
)
297 // Format does not exist; reset
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(..)>
317 void SwUndoFmtAttr::RepeatImpl(::sw::RepeatContext
& rContext
)
319 if ( !m_pOldSet
.get() )
322 SwDoc
& rDoc(rContext
.GetDoc());
324 switch ( m_nFmtWhich
)
328 SwNoTxtNode
*const pNd
=
329 rContext
.GetRepeatPaM().GetNode()->GetNoTxtNode();
332 rDoc
.SetAttr( m_pFmt
->GetAttrSet(), *pNd
->GetFmtColl() );
339 SwTxtNode
*const pNd
=
340 rContext
.GetRepeatPaM().GetNode()->GetTxtNode();
343 rDoc
.SetAttr( m_pFmt
->GetAttrSet(), *pNd
->GetFmtColl() );
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();
357 // Bug 43672: do not set all attributes!
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
);
370 rDoc
.SetAttr( m_pFmt
->GetAttrSet(), *pFly
);
378 SwRewriter
SwUndoFmtAttr::GetRewriter() const
380 SwRewriter aRewriter
;
384 aRewriter
.AddRule(UndoArg1
, m_pFmt
->GetName());
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
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() )
418 xub_StrLen nCntnt
= 0;
419 switch( rAnchor
.GetAnchorId() )
423 nCntnt
= rAnchor
.GetCntntAnchor()->nContent
.GetIndex();
426 m_nNodeIndex
= rAnchor
.GetCntntAnchor()->nNode
.GetIndex();
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
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
475 aNewAnchor
.SetAnchor( &aPos
);
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();
497 pFrmFmt
->DelFrms(); // delete Frms
501 const SwFmtAnchor
&rOldAnch
= pFrmFmt
->GetAnchor();
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
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
;
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
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() )
576 rContext
.SetSelections(pFrmFmt
, 0);
578 // #i35443# - anchor attribute restored.
582 SwUndoFmtResetAttr::SwUndoFmtResetAttr( SwFmt
& rChangedFormat
,
583 const sal_uInt16 nWhichId
)
584 : SwUndo( UNDO_RESETATTR
)
585 , m_pChangedFormat( &rChangedFormat
)
586 , m_nWhichId( nWhichId
)
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
)
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();
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
)
665 rDoc
.RstTxtAttrs(rPam
);
668 rDoc
.ResetAttrs(rPam
, false, m_Ids
);
670 case RES_CONDTXTFMTCOLL
:
671 rDoc
.ResetAttrs(rPam
, true, m_Ids
);
674 case RES_TXTATR_TOXMARK
:
675 // special treatment for TOXMarks
678 SwNodeIndex
aIdx( rDoc
.GetNodes(), nSttNode
);
679 SwPosition
aPos( aIdx
, SwIndex( aIdx
.GetNode().GetCntntNode(),
682 sal_uInt16 nCnt
= rDoc
.GetCurTOXMark( aPos
, aArr
);
687 // search for the right one
688 SwHistoryHint
* pHHint
= (GetHistory())[ 0 ];
689 if( pHHint
&& HSTRY_SETTOXMARKHNT
== pHHint
->Which() )
693 if ( static_cast<SwHistorySetTOXMark
*>(pHHint
)
694 ->IsEqual( *aArr
[ --nCnt
] ) )
704 // found one, thus delete it
707 rDoc
.DeleteTOXMark( aArr
[ nCnt
] );
715 void SwUndoResetAttr::RepeatImpl(::sw::RepeatContext
& rContext
)
717 if (m_nFormatId
< RES_FMT_BEGIN
)
722 switch ( m_nFormatId
)
725 rContext
.GetDoc().RstTxtAttrs(rContext
.GetRepeatPaM());
728 rContext
.GetDoc().ResetAttrs(rContext
.GetRepeatPaM(), false, m_Ids
);
730 case RES_CONDTXTFMTCOLL
:
731 rContext
.GetDoc().ResetAttrs(rContext
.GetRepeatPaM(), true, m_Ids
);
737 void SwUndoResetAttr::SetAttrs( const std::set
<sal_uInt16
> &rAttrs
)
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
)
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() );
792 m_nNodeIndex
= rPam
.GetPoint()->nNode
.GetIndex();
796 void SwUndoAttr::UndoImpl(::sw::UndoRedoContext
& rContext
)
798 SwDoc
*const pDoc
= & rContext
.GetDoc();
802 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
804 SwPaM
aPam(pDoc
->GetNodes().GetEndOfContent());
805 if ( ULONG_MAX
!= m_nNodeIndex
)
808 aPam
.GetPoint()->nNode
= m_nNodeIndex
;
809 aPam
.GetPoint()->nContent
.Assign( aPam
.GetCntntNode(), nSttCntnt
);
811 aPam
.GetPoint()->nContent
++;
812 pDoc
->DeleteRedline(aPam
, false, USHRT_MAX
);
816 // remove all format redlines, will be recreated if needed
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
)
871 if ( rPam
.Move( fnMoveBackward
) )
873 rDoc
.AppendRedline( new SwRedline( *m_pRedlineData
, rPam
),
880 rDoc
.AppendRedline( new SwRedline( *m_pRedlineData
, rPam
), true);
883 rDoc
.SetRedlineMode_intern( eOld
);
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
))
896 SwHistoryHint
* pHstHnt
;
897 SwNodes
& rNds
= rDoc
.GetNodes();
898 for ( sal_uInt16 n
= 0; n
< m_pHistory
->Count(); ++n
)
900 xub_StrLen nCntnt
= 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();
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();
943 SwTxtNode
* pTxtNd
= rNds
[ nNode
]->GetTxtNode();
946 SwTxtAttr
*const pTxtHt
=
947 pTxtNd
->GetTxtAttrForCharAt(nCntnt
, RES_TXTATR_FTN
);
951 SwTxtFtn
* pFtn
= static_cast<SwTxtFtn
*>(pTxtHt
);
952 RemoveIdxFromSection( rDoc
, pFtn
->GetStartNode()->GetIndex() );
960 SwUndoDefaultAttr::SwUndoDefaultAttr( const SfxItemSet
& rSet
)
961 : SwUndo( UNDO_SETDEFTATTR
)
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
) );
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
)
1014 SwUndoMoveLeftMargin::SwUndoMoveLeftMargin(
1015 const SwPaM
& rPam
, sal_Bool bFlag
, bool bMod
)
1016 : SwUndo( bFlag
? UNDO_INC_LEFTMARGIN
: UNDO_DEC_LEFTMARGIN
)
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
,
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() )
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
);
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: */