xref: /aoo41x/main/sw/source/core/undo/unattr.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #define _SVSTDARR_USHORTS
32 #define _SVSTDARR_USHORTSSORT
33 #include <UndoAttribute.hxx>
34 
35 #include <svl/itemiter.hxx>
36 
37 #include <editeng/tstpitem.hxx>
38 
39 #include <svx/svdmodel.hxx>
40 #include <svx/svdpage.hxx>
41 
42 #include <hintids.hxx>
43 #include <fmtflcnt.hxx>
44 #include <txtftn.hxx>
45 #include <fmtornt.hxx>
46 #include <fmtanchr.hxx>
47 #include <fmtfsize.hxx>
48 #include <frmfmt.hxx>
49 #include <fmtcntnt.hxx>
50 #include <ftnidx.hxx>
51 #include <doc.hxx>
52 #include <IDocumentUndoRedo.hxx>
53 #include <IShellCursorSupplier.hxx>
54 #include <docary.hxx>
55 #include <swundo.hxx>			// fuer die UndoIds
56 #include <pam.hxx>
57 #include <ndtxt.hxx>
58 #include <swtable.hxx>
59 #include <swtblfmt.hxx>
60 #include <UndoCore.hxx>
61 #include <hints.hxx>
62 #include <rolbck.hxx>
63 #include <ndnotxt.hxx>
64 #include <dcontact.hxx>
65 #include <ftninfo.hxx>
66 #include <redline.hxx>
67 #include <section.hxx>
68 #include <charfmt.hxx>
69 #include <switerator.hxx>
70 
71 
72 // -----------------------------------------------------
73 
74 SwUndoFmtAttrHelper::SwUndoFmtAttrHelper( SwFmt& rFmt, bool bSvDrwPt )
75     : SwClient( &rFmt )
76     , m_pUndo( 0 )
77     , m_bSaveDrawPt( bSvDrwPt )
78 {
79 }
80 
81 void SwUndoFmtAttrHelper::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
82 {
83 	if( pOld )
84 	{
85         if ( pOld->Which() == RES_OBJECTDYING )
86         {
87             CheckRegistration( pOld, pNew );
88         }
89         else if ( pNew )
90         {
91 		    if( POOLATTR_END >= pOld->Which() )
92 		    {
93                 if ( GetUndo() )
94                 {
95                     m_pUndo->PutAttr( *pOld );
96                 }
97                 else
98                 {
99                     m_pUndo.reset( new SwUndoFmtAttr( *pOld,
100                             *static_cast<SwFmt*>(GetRegisteredInNonConst()), m_bSaveDrawPt ) );
101                 }
102             }
103             else if ( RES_ATTRSET_CHG == pOld->Which() )
104             {
105                 if ( GetUndo() )
106                 {
107                     SfxItemIter aIter(
108                             *(static_cast<const SwAttrSetChg*>(pOld))->GetChgSet() );
109                     const SfxPoolItem* pItem = aIter.GetCurItem();
110                     while ( pItem )
111                     {
112                         m_pUndo->PutAttr( *pItem );
113 					    if( aIter.IsAtEnd() )
114 						    break;
115 					    pItem = aIter.NextItem();
116 				    }
117                 }
118                 else
119                 {
120                     m_pUndo.reset( new SwUndoFmtAttr(
121                             *static_cast<const SwAttrSetChg*>(pOld)->GetChgSet(),
122                             *static_cast<SwFmt*>(GetRegisteredInNonConst()), m_bSaveDrawPt ) );
123                 }
124             }
125         }
126 	}
127 }
128 
129 // -----------------------------------------------------
130 
131 SwUndoFmtAttr::SwUndoFmtAttr( const SfxItemSet& rOldSet,
132                               SwFmt& rChgFmt,
133                               bool bSaveDrawPt )
134     : SwUndo( UNDO_INSFMTATTR )
135     , m_pFmt( &rChgFmt )
136       // --> OD 2007-07-11 #i56253#
137     , m_pOldSet( new SfxItemSet( rOldSet ) )
138       // <--
139     , m_nNodeIndex( 0 )
140     , m_nFmtWhich( rChgFmt.Which() )
141     , m_bSaveDrawPt( bSaveDrawPt )
142 {
143     Init();
144 }
145 
146 SwUndoFmtAttr::SwUndoFmtAttr( const SfxPoolItem& rItem, SwFmt& rChgFmt,
147                               bool bSaveDrawPt )
148     : SwUndo( UNDO_INSFMTATTR )
149     , m_pFmt( &rChgFmt )
150     , m_pOldSet( m_pFmt->GetAttrSet().Clone( sal_False ) )
151     , m_nNodeIndex( 0 )
152     , m_nFmtWhich( rChgFmt.Which() )
153     , m_bSaveDrawPt( bSaveDrawPt )
154 {
155     m_pOldSet->Put( rItem );
156     Init();
157 }
158 
159 void SwUndoFmtAttr::Init()
160 {
161     // treat change of anchor specially
162     if ( SFX_ITEM_SET == m_pOldSet->GetItemState( RES_ANCHOR, sal_False ))
163     {
164         SaveFlyAnchor( m_bSaveDrawPt );
165     }
166     else if ( RES_FRMFMT == m_nFmtWhich )
167     {
168         SwDoc* pDoc = m_pFmt->GetDoc();
169         if (USHRT_MAX != pDoc->GetTblFrmFmts()->GetPos(
170                             static_cast<const SwFrmFmtPtr>(m_pFmt)))
171         {
172             // Table Format: save table position, table formats are volatile!
173             SwTable * pTbl = SwIterator<SwTable,SwFmt>::FirstElement( *m_pFmt );
174             if ( pTbl )
175             {
176                 m_nNodeIndex = pTbl->GetTabSortBoxes()[ 0 ]->GetSttNd()
177                     ->FindTableNode()->GetIndex();
178             }
179         }
180         else if (USHRT_MAX != pDoc->GetSections().GetPos(
181                                 static_cast<const SwSectionFmtPtr>(m_pFmt)))
182         {
183             m_nNodeIndex = m_pFmt->GetCntnt().GetCntntIdx()->GetIndex();
184         }
185         else if ( 0 != dynamic_cast< SwTableBoxFmt* >( m_pFmt ) )
186         {
187             SwTableBox * pTblBox = SwIterator<SwTableBox,SwFmt>::FirstElement( *m_pFmt );
188             if ( pTblBox )
189             {
190                 m_nNodeIndex = pTblBox->GetSttIdx();
191             }
192         }
193     }
194 }
195 
196 SwUndoFmtAttr::~SwUndoFmtAttr()
197 {
198 }
199 
200 void SwUndoFmtAttr::UndoImpl(::sw::UndoRedoContext & rContext)
201 {
202     // OD 2004-10-26 #i35443#
203     // Important note: <Undo(..)> also called by <ReDo(..)>
204 
205     if ( !m_pOldSet.get() || !m_pFmt || !IsFmtInDoc( &rContext.GetDoc() ))
206         return;
207 
208     // --> OD 2004-10-26 #i35443# - If anchor attribute has been successfull
209     // restored, all other attributes are also restored.
210     // Thus, keep track of its restoration
211     bool bAnchorAttrRestored( false );
212     if ( SFX_ITEM_SET == m_pOldSet->GetItemState( RES_ANCHOR, sal_False ))
213     {
214         bAnchorAttrRestored = RestoreFlyAnchor(rContext);
215         if ( bAnchorAttrRestored )
216         {
217             // Anchor attribute successfull restored.
218             // Thus, keep anchor position for redo
219             SaveFlyAnchor();
220         }
221         else
222         {
223             // Anchor attribute not restored due to invalid anchor position.
224             // Thus, delete anchor attribute.
225             m_pOldSet->ClearItem( RES_ANCHOR );
226         }
227     }
228 
229     if ( !bAnchorAttrRestored )
230     // <--
231     {
232         SwUndoFmtAttrHelper aTmp( *m_pFmt, m_bSaveDrawPt );
233         m_pFmt->SetFmtAttr( *m_pOldSet );
234         if ( aTmp.GetUndo() )
235         {
236             // transfer ownership of helper object's old set
237             m_pOldSet = aTmp.GetUndo()->m_pOldSet;
238         }
239         else
240         {
241             m_pOldSet->ClearItem();
242         }
243 
244         if ( RES_FLYFRMFMT == m_nFmtWhich || RES_DRAWFRMFMT == m_nFmtWhich )
245         {
246             rContext.SetSelections(static_cast<SwFrmFmt*>(m_pFmt), 0);
247         }
248     }
249 }
250 
251 bool SwUndoFmtAttr::IsFmtInDoc( SwDoc* pDoc )
252 {
253     // search for the Format in the Document; if it does not exist any more,
254     // the attribute is not restored!
255     sal_uInt16 nPos = USHRT_MAX;
256     switch ( m_nFmtWhich )
257     {
258         case RES_TXTFMTCOLL:
259             nPos = pDoc->GetTxtFmtColls()->GetPos(
260                     static_cast<const SwTxtFmtCollPtr>(m_pFmt) );
261             break;
262 
263         case RES_GRFFMTCOLL:
264             nPos = pDoc->GetGrfFmtColls()->GetPos(
265                     static_cast<const SwGrfFmtCollPtr>(m_pFmt) );
266             break;
267 
268         case RES_CHRFMT:
269             nPos = pDoc->GetCharFmts()->GetPos(
270                     static_cast<SwCharFmtPtr>(m_pFmt) );
271             break;
272 
273         case RES_FRMFMT:
274             if ( m_nNodeIndex && (m_nNodeIndex < pDoc->GetNodes().Count()) )
275             {
276                 SwNode* pNd = pDoc->GetNodes()[ m_nNodeIndex ];
277                 if ( pNd->IsTableNode() )
278                 {
279                     m_pFmt =
280                         static_cast<SwTableNode*>(pNd)->GetTable().GetFrmFmt();
281                     nPos = 0;
282                     break;
283                 }
284                 else if ( pNd->IsSectionNode() )
285                 {
286                     m_pFmt =
287                         static_cast<SwSectionNode*>(pNd)->GetSection().GetFmt();
288                     nPos = 0;
289                     break;
290                 }
291                 else if ( pNd->IsStartNode() && (SwTableBoxStartNode ==
292                     static_cast< SwStartNode* >(pNd)->GetStartNodeType()) )
293                 {
294                     SwTableNode* pTblNode = pNd->FindTableNode();
295                     if ( pTblNode )
296                     {
297                         SwTableBox* pBox =
298                             pTblNode->GetTable().GetTblBox( m_nNodeIndex );
299                         if ( pBox )
300                         {
301                             m_pFmt = pBox->GetFrmFmt();
302                             nPos = 0;
303                             break;
304                         }
305                     }
306                 }
307             }
308             // no break!
309         case RES_DRAWFRMFMT:
310         case RES_FLYFRMFMT:
311             nPos = pDoc->GetSpzFrmFmts()->GetPos(
312                     static_cast<const SwFrmFmtPtr>(m_pFmt) );
313             if ( USHRT_MAX == nPos )
314             {
315                 nPos = pDoc->GetFrmFmts()->GetPos(
316                     static_cast<const SwFrmFmtPtr>(m_pFmt) );
317             }
318             break;
319     }
320 
321     if ( USHRT_MAX == nPos )
322     {
323         // Format does not exist; reset
324         m_pFmt = 0;
325     }
326 
327     return 0 != m_pFmt;
328 }
329 
330 // prueft, ob es noch im Doc ist!
331 SwFmt* SwUndoFmtAttr::GetFmt( SwDoc& rDoc )
332 {
333     return m_pFmt && IsFmtInDoc( &rDoc ) ? m_pFmt : 0;
334 }
335 
336 void SwUndoFmtAttr::RedoImpl(::sw::UndoRedoContext & rContext)
337 {
338     // --> OD 2004-10-26 #i35443# - Because the undo stores the attributes for
339     // redo, the same code as for <Undo(..)> can be applied for <Redo(..)>
340     UndoImpl(rContext);
341     // <--
342 }
343 
344 void SwUndoFmtAttr::RepeatImpl(::sw::RepeatContext & rContext)
345 {
346     if ( !m_pOldSet.get() )
347         return;
348 
349     SwDoc & rDoc(rContext.GetDoc());
350 
351     switch ( m_nFmtWhich )
352     {
353 	case RES_GRFFMTCOLL:
354 		{
355             SwNoTxtNode *const pNd =
356                 rContext.GetRepeatPaM().GetNode()->GetNoTxtNode();
357 			if( pNd )
358             {
359                 rDoc.SetAttr( m_pFmt->GetAttrSet(), *pNd->GetFmtColl() );
360             }
361         }
362 		break;
363 
364 	case RES_TXTFMTCOLL:
365 		{
366             SwTxtNode *const pNd =
367                 rContext.GetRepeatPaM().GetNode()->GetTxtNode();
368 			if( pNd )
369             {
370                 rDoc.SetAttr( m_pFmt->GetAttrSet(), *pNd->GetFmtColl() );
371             }
372         }
373 		break;
374 
375 //	case RES_CHRFMT:
376 //	case RES_FRMFMT:
377 
378 	case RES_FLYFRMFMT:
379 		{
380 			// erstal pruefen, ob der Cursor ueberhaupt in einem fliegenden
381 			// Rahmen steht. Der Weg ist: suche in allen FlyFrmFormaten
382 			// nach dem FlyCntnt-Attribut und teste ob der Cursor in der
383 			// entsprechenden Section liegt.
384             SwFrmFmt *const pFly =
385                 rContext.GetRepeatPaM().GetNode()->GetFlyFmt();
386 			if( pFly )
387 			{
388 				// Bug 43672: es duerfen nicht alle Attribute gesetzt werden!
389                 if (SFX_ITEM_SET ==
390                         m_pFmt->GetAttrSet().GetItemState( RES_CNTNT ))
391                 {
392                     SfxItemSet aTmpSet( m_pFmt->GetAttrSet() );
393 					aTmpSet.ClearItem( RES_CNTNT );
394 					if( aTmpSet.Count() )
395                     {
396 						rDoc.SetAttr( aTmpSet, *pFly );
397                     }
398                 }
399                 else
400                 {
401                     rDoc.SetAttr( m_pFmt->GetAttrSet(), *pFly );
402                 }
403             }
404 			break;
405 		}
406 	}
407 }
408 
409 SwRewriter SwUndoFmtAttr::GetRewriter() const
410 {
411     SwRewriter aRewriter;
412 
413     if (m_pFmt)
414     {
415         aRewriter.AddRule(UNDO_ARG1, m_pFmt->GetName());
416     }
417 
418     return aRewriter;
419 }
420 
421 void SwUndoFmtAttr::PutAttr( const SfxPoolItem& rItem )
422 {
423     m_pOldSet->Put( rItem );
424     if ( RES_ANCHOR == rItem.Which() )
425     {
426         SaveFlyAnchor( m_bSaveDrawPt );
427     }
428 }
429 
430 void SwUndoFmtAttr::SaveFlyAnchor( bool bSvDrwPt )
431 {
432 	// das Format ist gueltig, sonst wuerde man gar bis hier kommen
433 	if( bSvDrwPt )
434     {
435         if ( RES_DRAWFRMFMT == m_pFmt->Which() )
436         {
437             Point aPt( static_cast<SwFrmFmt*>(m_pFmt)->FindSdrObject()
438                             ->GetRelativePos() );
439             // store old value as attribute, to keep SwUndoFmtAttr small
440             m_pOldSet->Put( SwFmtFrmSize( ATT_VAR_SIZE, aPt.X(), aPt.Y() ) );
441         }
442 /*		else
443 		{
444 			pOldSet->Put( pFmt->GetVertOrient() );
445 			pOldSet->Put( pFmt->GetHoriOrient() );
446 		}
447 */	}
448 
449     const SwFmtAnchor& rAnchor =
450         static_cast<const SwFmtAnchor&>( m_pOldSet->Get( RES_ANCHOR, sal_False ) );
451 	if( !rAnchor.GetCntntAnchor() )
452 		return;
453 
454 	xub_StrLen nCntnt = 0;
455 	switch( rAnchor.GetAnchorId() )
456 	{
457     case FLY_AS_CHAR:
458     case FLY_AT_CHAR:
459 		nCntnt = rAnchor.GetCntntAnchor()->nContent.GetIndex();
460     case FLY_AT_PARA:
461     case FLY_AT_FLY:
462         m_nNodeIndex = rAnchor.GetCntntAnchor()->nNode.GetIndex();
463 		break;
464 	default:
465 		return;
466 	}
467 
468 	SwFmtAnchor aAnchor( rAnchor.GetAnchorId(), nCntnt );
469     m_pOldSet->Put( aAnchor );
470 }
471 
472 // --> OD 2004-10-26 #i35443# - Add return value, type <bool>.
473 // Return value indicates, if anchor attribute is restored.
474 // Note: If anchor attribute is restored, all other existing attributes
475 //       are also restored.
476 bool SwUndoFmtAttr::RestoreFlyAnchor(::sw::UndoRedoContext & rContext)
477 {
478     SwDoc *const pDoc = & rContext.GetDoc();
479     SwFlyFrmFmt* pFrmFmt = static_cast<SwFlyFrmFmt*>(m_pFmt);
480     const SwFmtAnchor& rAnchor =
481         static_cast<const SwFmtAnchor&>( m_pOldSet->Get( RES_ANCHOR, sal_False ) );
482 
483 	SwFmtAnchor aNewAnchor( rAnchor.GetAnchorId() );
484     if (FLY_AT_PAGE != rAnchor.GetAnchorId())
485     {
486         SwNode* pNd = pDoc->GetNodes()[ m_nNodeIndex  ];
487 
488         if (  (FLY_AT_FLY == rAnchor.GetAnchorId())
489             ? ( !pNd->IsStartNode() || (SwFlyStartNode !=
490                     static_cast<SwStartNode*>(pNd)->GetStartNodeType()) )
491             : !pNd->IsTxtNode() )
492         {
493             // --> OD 2004-10-26 #i35443# - invalid position.
494             // Thus, anchor attribute not restored
495             return false;
496             // <--
497         }
498 
499 		SwPosition aPos( *pNd );
500         if ((FLY_AS_CHAR == rAnchor.GetAnchorId()) ||
501             (FLY_AT_CHAR == rAnchor.GetAnchorId()))
502         {
503 			aPos.nContent.Assign( (SwTxtNode*)pNd, rAnchor.GetPageNum() );
504             if ( aPos.nContent.GetIndex() >
505                     static_cast<SwTxtNode*>(pNd)->GetTxt().Len() )
506             {
507                 // --> OD 2004-10-26 #i35443# - invalid position.
508                 // Thus, anchor attribute not restored
509                 return false;
510                 // <--
511             }
512 		}
513 		aNewAnchor.SetAnchor( &aPos );
514 	}
515 	else
516 		aNewAnchor.SetPageNum( rAnchor.GetPageNum() );
517 
518 	Point aDrawSavePt, aDrawOldPt;
519 	if( pDoc->GetCurrentViewShell() )	//swmod 071108//swmod 071225
520 	{
521 		if( RES_DRAWFRMFMT == pFrmFmt->Which() )
522 		{
523 			// den alten zwischengespeicherten Wert herausholen.
524             const SwFmtFrmSize& rOldSize = static_cast<const SwFmtFrmSize&>(
525                     m_pOldSet->Get( RES_FRM_SIZE ) );
526 			aDrawSavePt.X() = rOldSize.GetWidth();
527 			aDrawSavePt.Y() = rOldSize.GetHeight();
528             m_pOldSet->ClearItem( RES_FRM_SIZE );
529 
530 			// den akt. wieder zwischenspeichern
531 			aDrawOldPt = pFrmFmt->FindSdrObject()->GetRelativePos();
532 //JP 08.10.97: ist laut AMA/MA nicht mehr noetig
533 //			pCont->DisconnectFromLayout();
534         }
535         else
536         {
537             pFrmFmt->DelFrms();         // delete Frms
538         }
539     }
540 
541 	const SwFmtAnchor &rOldAnch = pFrmFmt->GetAnchor();
542     // --> OD 2006-03-13 #i54336#
543     // Consider case, that as-character anchored object has moved its anchor position.
544     if (FLY_AS_CHAR == rOldAnch.GetAnchorId())
545     // <--
546 	{
547 		//Bei InCntnt's wird es spannend: Das TxtAttribut muss vernichtet
548 		//werden. Leider reisst dies neben den Frms auch noch das Format mit
549 		//in sein Grab. Um dass zu unterbinden loesen wir vorher die
550 		//Verbindung zwischen Attribut und Format.
551 		const SwPosition *pPos = rOldAnch.GetCntntAnchor();
552 		SwTxtNode *pTxtNode = (SwTxtNode*)&pPos->nNode.GetNode();
553 		ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
554 		const xub_StrLen nIdx = pPos->nContent.GetIndex();
555         SwTxtAttr * const pHnt =
556             pTxtNode->GetTxtAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
557 		ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
558 					"Missing FlyInCnt-Hint." );
559 		ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pFrmFmt,
560 					"Wrong TxtFlyCnt-Hint." );
561         const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
562 
563 		//Die Verbindung ist geloest, jetzt muss noch das Attribut vernichtet
564 		//werden.
565         pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
566     }
567 
568     {
569         m_pOldSet->Put( aNewAnchor );
570         SwUndoFmtAttrHelper aTmp( *m_pFmt, m_bSaveDrawPt );
571         m_pFmt->SetFmtAttr( *m_pOldSet );
572         if ( aTmp.GetUndo() )
573         {
574             m_nNodeIndex = aTmp.GetUndo()->m_nNodeIndex;
575             // transfer ownership of helper object's old set
576             m_pOldSet = aTmp.GetUndo()->m_pOldSet;
577         }
578         else
579         {
580             m_pOldSet->ClearItem();
581         }
582     }
583 
584     if ( RES_DRAWFRMFMT == pFrmFmt->Which() )
585     {
586         SwDrawContact *pCont =
587             static_cast<SwDrawContact*>(pFrmFmt->FindContactObj());
588 		// das Draw-Model hat auch noch ein Undo-Object fuer die
589 		// richtige Position vorbereitet; dieses ist aber relativ.
590 		// Darum verhinder hier, das durch setzen des Ankers das
591 		// Contact-Object seine Position aendert.
592 //JP 08.10.97: ist laut AMA/MA nicht mehr noetig
593 //			pCont->ConnectToLayout();
594 		SdrObject* pObj = pCont->GetMaster();
595 
596         if( pCont->GetAnchorFrm() && !pObj->IsInserted() )
597 		{
598 			ASSERT( pDoc->GetDrawModel(), "RestoreFlyAnchor without DrawModel" );
599 			pDoc->GetDrawModel()->GetPage( 0 )->InsertObject( pObj );
600 		}
601 		pObj->SetRelativePos( aDrawSavePt );
602 
603 		// den alten Wert wieder zwischenspeichern.
604         m_pOldSet->Put(
605             SwFmtFrmSize( ATT_VAR_SIZE, aDrawOldPt.X(), aDrawOldPt.Y() ) );
606     }
607 
608     if (FLY_AS_CHAR == aNewAnchor.GetAnchorId())
609     {
610 		const SwPosition* pPos = aNewAnchor.GetCntntAnchor();
611 		SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
612         ASSERT( pTxtNd, "no Text Node at position." );
613         SwFmtFlyCnt aFmt( pFrmFmt );
614         pTxtNd->InsertItem( aFmt, pPos->nContent.GetIndex(), 0 );
615     }
616 
617 
618 	if( RES_DRAWFRMFMT != pFrmFmt->Which() )
619 		pFrmFmt->MakeFrms();
620 
621     rContext.SetSelections(pFrmFmt, 0);
622 
623     // --> OD 2004-10-26 #i35443# - anchor attribute restored.
624     return true;
625     // <--
626 }
627 
628 // -----------------------------------------------------
629 
630 // --> OD 2008-02-12 #newlistlevelattrs#
631 SwUndoFmtResetAttr::SwUndoFmtResetAttr( SwFmt& rChangedFormat,
632                                         const sal_uInt16 nWhichId )
633     : SwUndo( UNDO_RESETATTR )
634     , m_pChangedFormat( &rChangedFormat )
635     , m_nWhichId( nWhichId )
636     , m_pOldItem( 0 )
637 {
638     const SfxPoolItem* pItem = 0;
639     if (rChangedFormat.GetItemState( nWhichId, sal_False, &pItem ) == SFX_ITEM_SET)
640     {
641         m_pOldItem.reset( pItem->Clone() );
642     }
643 }
644 
645 SwUndoFmtResetAttr::~SwUndoFmtResetAttr()
646 {
647 }
648 
649 void SwUndoFmtResetAttr::UndoImpl(::sw::UndoRedoContext &)
650 {
651     if ( m_pOldItem.get() )
652     {
653         m_pChangedFormat->SetFmtAttr( *m_pOldItem );
654     }
655 }
656 
657 void SwUndoFmtResetAttr::RedoImpl(::sw::UndoRedoContext &)
658 {
659     if ( m_pOldItem.get() )
660     {
661         m_pChangedFormat->ResetFmtAttr( m_nWhichId );
662     }
663 }
664 // <--
665 
666 // -----------------------------------------------------
667 
668 SwUndoResetAttr::SwUndoResetAttr( const SwPaM& rRange, sal_uInt16 nFmtId )
669     : SwUndo( UNDO_RESETATTR ), SwUndRng( rRange )
670     , m_pHistory( new SwHistory )
671     , m_nFormatId( nFmtId )
672 {
673 }
674 
675 SwUndoResetAttr::SwUndoResetAttr( const SwPosition& rPos, sal_uInt16 nFmtId )
676     : SwUndo( UNDO_RESETATTR )
677     , m_pHistory( new SwHistory )
678     , m_nFormatId( nFmtId )
679 {
680     nSttNode = nEndNode = rPos.nNode.GetIndex();
681     nSttCntnt = nEndCntnt = rPos.nContent.GetIndex();
682 }
683 
684 SwUndoResetAttr::~SwUndoResetAttr()
685 {
686 }
687 
688 void SwUndoResetAttr::UndoImpl(::sw::UndoRedoContext & rContext)
689 {
690     // reset old values
691     SwDoc & rDoc = rContext.GetDoc();
692     m_pHistory->TmpRollback( &rDoc, 0 );
693     m_pHistory->SetTmpEnd( m_pHistory->Count() );
694 
695     if ((RES_CONDTXTFMTCOLL == m_nFormatId) &&
696         (nSttNode == nEndNode) && (nSttCntnt == nEndCntnt))
697     {
698 		SwTxtNode* pTNd = rDoc.GetNodes()[ nSttNode ]->GetTxtNode();
699 		if( pTNd )
700 		{
701 			SwIndex aIdx( pTNd, nSttCntnt );
702 			pTNd->DontExpandFmt( aIdx, sal_False );
703 		}
704 	}
705 
706     AddUndoRedoPaM(rContext);
707 }
708 
709 void SwUndoResetAttr::RedoImpl(::sw::UndoRedoContext & rContext)
710 {
711     SwDoc & rDoc = rContext.GetDoc();
712     SwPaM & rPam = AddUndoRedoPaM(rContext);
713     SvUShortsSort* pIdArr = m_Ids.Count() ? &m_Ids : 0;
714 
715     switch ( m_nFormatId )
716     {
717 	case RES_CHRFMT:
718         rDoc.RstTxtAttrs(rPam);
719 		break;
720 	case RES_TXTFMTCOLL:
721         rDoc.ResetAttrs(rPam, sal_False, pIdArr );
722 		break;
723 	case RES_CONDTXTFMTCOLL:
724         rDoc.ResetAttrs(rPam, sal_True, pIdArr );
725 
726 		break;
727 	case RES_TXTATR_TOXMARK:
728         // special treatment for TOXMarks
729         {
730 			SwTOXMarks aArr;
731 			SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );
732 			SwPosition aPos( aIdx, SwIndex( aIdx.GetNode().GetCntntNode(),
733 																nSttCntnt ));
734 
735 			sal_uInt16 nCnt = rDoc.GetCurTOXMark( aPos, aArr );
736 			if( nCnt )
737 			{
738 				if( 1 < nCnt )
739 				{
740                     // search for the right one
741                     SwHistoryHint* pHHint = (GetHistory())[ 0 ];
742 					if( pHHint && HSTRY_SETTOXMARKHNT == pHHint->Which() )
743 					{
744 						while( nCnt )
745                         {
746                             if ( static_cast<SwHistorySetTOXMark*>(pHHint)
747                                     ->IsEqual( *aArr[ --nCnt ] ) )
748                             {
749 								++nCnt;
750 								break;
751                             }
752                         }
753 					}
754 					else
755 						nCnt = 0;
756 				}
757 				// gefunden, also loeschen
758 				if( nCnt-- )
759                 {
760                     rDoc.DeleteTOXMark( aArr[ nCnt ] );
761                 }
762 			}
763 		}
764 		break;
765 	}
766 }
767 
768 void SwUndoResetAttr::RepeatImpl(::sw::RepeatContext & rContext)
769 {
770     if (m_nFormatId < RES_FMT_BEGIN)
771     {
772         return;
773     }
774 
775     SvUShortsSort* pIdArr = m_Ids.Count() ? &m_Ids : 0;
776     switch ( m_nFormatId )
777     {
778 	case RES_CHRFMT:
779         rContext.GetDoc().RstTxtAttrs(rContext.GetRepeatPaM());
780 		break;
781 	case RES_TXTFMTCOLL:
782         rContext.GetDoc().ResetAttrs(rContext.GetRepeatPaM(), false, pIdArr);
783 		break;
784 	case RES_CONDTXTFMTCOLL:
785         rContext.GetDoc().ResetAttrs(rContext.GetRepeatPaM(), true, pIdArr);
786 		break;
787 	}
788 }
789 
790 
791 void SwUndoResetAttr::SetAttrs( const SvUShortsSort& rArr )
792 {
793     if ( m_Ids.Count() )
794     {
795         m_Ids.Remove( 0, m_Ids.Count() );
796     }
797     m_Ids.Insert( &rArr );
798 }
799 
800 // -----------------------------------------------------
801 
802 
803 SwUndoAttr::SwUndoAttr( const SwPaM& rRange, const SfxPoolItem& rAttr,
804                         const SetAttrMode nFlags )
805     : SwUndo( UNDO_INSATTR ), SwUndRng( rRange )
806     , m_AttrSet( rRange.GetDoc()->GetAttrPool(), rAttr.Which(), rAttr.Which() )
807     , m_pHistory( new SwHistory )
808     , m_pRedlineData( 0 )
809     , m_pRedlineSaveData( 0 )
810     , m_nNodeIndex( ULONG_MAX )
811     , m_nInsertFlags( nFlags )
812 {
813     m_AttrSet.Put( rAttr );
814 }
815 
816 SwUndoAttr::SwUndoAttr( const SwPaM& rRange, const SfxItemSet& rSet,
817                         const SetAttrMode nFlags )
818     : SwUndo( UNDO_INSATTR ), SwUndRng( rRange )
819     , m_AttrSet( rSet )
820     , m_pHistory( new SwHistory )
821     , m_pRedlineData( 0 )
822     , m_pRedlineSaveData( 0 )
823     , m_nNodeIndex( ULONG_MAX )
824     , m_nInsertFlags( nFlags )
825 {
826 }
827 
828 SwUndoAttr::~SwUndoAttr()
829 {
830 }
831 
832 void SwUndoAttr::SaveRedlineData( const SwPaM& rPam, sal_Bool bIsCntnt )
833 {
834     SwDoc* pDoc = rPam.GetDoc();
835     if ( pDoc->IsRedlineOn() )
836     {
837         m_pRedlineData.reset( new SwRedlineData( bIsCntnt
838                                     ? nsRedlineType_t::REDLINE_INSERT
839                                     : nsRedlineType_t::REDLINE_FORMAT,
840                                 pDoc->GetRedlineAuthor() ) );
841     }
842 
843     m_pRedlineSaveData.reset( new SwRedlineSaveDatas );
844     if ( !FillSaveDataForFmt( rPam, *m_pRedlineSaveData ))
845     {
846         m_pRedlineSaveData.reset(0);
847     }
848 
849     SetRedlineMode( pDoc->GetRedlineMode() );
850     if ( bIsCntnt )
851     {
852         m_nNodeIndex = rPam.GetPoint()->nNode.GetIndex();
853     }
854 }
855 
856 void SwUndoAttr::UndoImpl(::sw::UndoRedoContext & rContext)
857 {
858     SwDoc *const pDoc = & rContext.GetDoc();
859 
860 	RemoveIdx( *pDoc );
861 
862 	if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
863 	{
864         SwPaM aPam(pDoc->GetNodes().GetEndOfContent());
865         if ( ULONG_MAX != m_nNodeIndex )
866         {
867             aPam.DeleteMark();
868             aPam.GetPoint()->nNode = m_nNodeIndex;
869             aPam.GetPoint()->nContent.Assign( aPam.GetCntntNode(), nSttCntnt );
870             aPam.SetMark();
871             aPam.GetPoint()->nContent++;
872             pDoc->DeleteRedline(aPam, false, USHRT_MAX);
873 		}
874 		else
875 		{
876 			// alle Format-Redlines entfernen, werden ggfs. neu gesetzt
877             SetPaM(aPam);
878             pDoc->DeleteRedline(aPam, false, nsRedlineType_t::REDLINE_FORMAT);
879             if ( m_pRedlineSaveData.get() )
880             {
881                 SetSaveData( *pDoc, *m_pRedlineSaveData );
882             }
883         }
884     }
885 
886     const bool bToLast =  (1 == m_AttrSet.Count())
887                        && (RES_TXTATR_FIELD <= *m_AttrSet.GetRanges())
888                        && (*m_AttrSet.GetRanges() <= RES_TXTATR_FTN);
889 
890     // restore old values
891     m_pHistory->TmpRollback( pDoc, 0, !bToLast );
892     m_pHistory->SetTmpEnd( m_pHistory->Count() );
893 
894     // set cursor onto Undo area
895     AddUndoRedoPaM(rContext);
896 }
897 
898 void SwUndoAttr::RepeatImpl(::sw::RepeatContext & rContext)
899 {
900     // RefMarks are not repeat capable
901     if ( SFX_ITEM_SET != m_AttrSet.GetItemState( RES_TXTATR_REFMARK, sal_False ) )
902     {
903         rContext.GetDoc().InsertItemSet( rContext.GetRepeatPaM(),
904                                            m_AttrSet, m_nInsertFlags );
905     }
906     else if ( 1 < m_AttrSet.Count() )
907     {
908         SfxItemSet aTmpSet( m_AttrSet );
909         aTmpSet.ClearItem( RES_TXTATR_REFMARK );
910         rContext.GetDoc().InsertItemSet( rContext.GetRepeatPaM(),
911                                            aTmpSet, m_nInsertFlags );
912     }
913 }
914 
915 void SwUndoAttr::RedoImpl(::sw::UndoRedoContext & rContext)
916 {
917     SwDoc & rDoc = rContext.GetDoc();
918     SwPaM & rPam = AddUndoRedoPaM(rContext);
919 
920     if ( m_pRedlineData.get() &&
921          IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
922     {
923         RedlineMode_t eOld = rDoc.GetRedlineMode();
924         rDoc.SetRedlineMode_intern(static_cast<RedlineMode_t>(
925                     eOld & ~nsRedlineMode_t::REDLINE_IGNORE));
926         rDoc.InsertItemSet( rPam, m_AttrSet, m_nInsertFlags );
927 
928         if ( ULONG_MAX != m_nNodeIndex )
929         {
930             rPam.SetMark();
931             if ( rPam.Move( fnMoveBackward ) )
932             {
933                 rDoc.AppendRedline( new SwRedline( *m_pRedlineData, rPam ),
934                         true);
935             }
936             rPam.DeleteMark();
937         }
938         else
939         {
940             rDoc.AppendRedline( new SwRedline( *m_pRedlineData, rPam ), true);
941         }
942 
943         rDoc.SetRedlineMode_intern( eOld );
944     }
945     else
946     {
947         rDoc.InsertItemSet( rPam, m_AttrSet, m_nInsertFlags );
948     }
949 }
950 
951 
952 void SwUndoAttr::RemoveIdx( SwDoc& rDoc )
953 {
954     if ( SFX_ITEM_SET != m_AttrSet.GetItemState( RES_TXTATR_FTN, sal_False ))
955 		return ;
956 
957     SwHistoryHint* pHstHnt;
958 	SwNodes& rNds = rDoc.GetNodes();
959     for ( sal_uInt16 n = 0; n < m_pHistory->Count(); ++n )
960     {
961 		xub_StrLen nCntnt = 0;
962 		sal_uLong nNode = 0;
963         pHstHnt = (*m_pHistory)[ n ];
964         switch ( pHstHnt->Which() )
965         {
966             case HSTRY_RESETTXTHNT:
967                 {
968                     SwHistoryResetTxt * pHistoryHint
969                         = static_cast<SwHistoryResetTxt*>(pHstHnt);
970                     if ( RES_TXTATR_FTN == pHistoryHint->GetWhich() )
971                     {
972                         nNode = pHistoryHint->GetNode();
973                         nCntnt = pHistoryHint->GetCntnt();
974                     }
975                 }
976                 break;
977 
978             case HSTRY_RESETATTRSET:
979                 {
980                     SwHistoryResetAttrSet * pHistoryHint
981                         = static_cast<SwHistoryResetAttrSet*>(pHstHnt);
982                     nCntnt = pHistoryHint->GetCntnt();
983                     if ( STRING_MAXLEN != nCntnt )
984                     {
985                         const SvUShorts& rArr = pHistoryHint->GetArr();
986                         for ( sal_uInt16 i = rArr.Count(); i; )
987                         {
988                             if ( RES_TXTATR_FTN == rArr[ --i ] )
989                             {
990                                 nNode = pHistoryHint->GetNode();
991                                 break;
992                             }
993                         }
994                     }
995                 }
996                 break;
997 
998             default:
999                 break;
1000         }
1001 
1002 		if( nNode )
1003 		{
1004 			SwTxtNode* pTxtNd = rNds[ nNode ]->GetTxtNode();
1005 			if( pTxtNd )
1006 			{
1007                 SwTxtAttr *const pTxtHt =
1008                     pTxtNd->GetTxtAttrForCharAt(nCntnt, RES_TXTATR_FTN);
1009 				if( pTxtHt )
1010 				{
1011 					// ok, dann hole mal die Werte
1012                     SwTxtFtn* pFtn = static_cast<SwTxtFtn*>(pTxtHt);
1013 					RemoveIdxFromSection( rDoc, pFtn->GetStartNode()->GetIndex() );
1014 					return ;
1015 				}
1016 			}
1017 		}
1018 	}
1019 }
1020 
1021 // -----------------------------------------------------
1022 
1023 SwUndoDefaultAttr::SwUndoDefaultAttr( const SfxItemSet& rSet )
1024     : SwUndo( UNDO_SETDEFTATTR )
1025     , m_pOldSet( 0 )
1026     , m_pTabStop( 0 )
1027 {
1028 	const SfxPoolItem* pItem;
1029 	if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_TABSTOP, sal_False, &pItem ) )
1030     {
1031         // store separately, because it may change!
1032         m_pTabStop.reset( static_cast<SvxTabStopItem*>(pItem->Clone()) );
1033         if ( 1 != rSet.Count() ) // are there more attributes?
1034         {
1035             m_pOldSet.reset( new SfxItemSet( rSet ) );
1036         }
1037     }
1038     else
1039     {
1040         m_pOldSet.reset( new SfxItemSet( rSet ) );
1041     }
1042 }
1043 
1044 SwUndoDefaultAttr::~SwUndoDefaultAttr()
1045 {
1046 }
1047 
1048 void SwUndoDefaultAttr::UndoImpl(::sw::UndoRedoContext & rContext)
1049 {
1050     SwDoc & rDoc = rContext.GetDoc();
1051     if ( m_pOldSet.get() )
1052     {
1053         SwUndoFmtAttrHelper aTmp(
1054                 *const_cast<SwTxtFmtColl*>(rDoc.GetDfltTxtFmtColl()) );
1055         rDoc.SetDefault( *m_pOldSet );
1056         m_pOldSet.reset( 0 );
1057         if ( aTmp.GetUndo() )
1058         {
1059             // transfer ownership of helper object's old set
1060             m_pOldSet = aTmp.GetUndo()->m_pOldSet;
1061         }
1062     }
1063     if ( m_pTabStop.get() )
1064     {
1065         SvxTabStopItem* pOld = static_cast<SvxTabStopItem*>(
1066                 rDoc.GetDefault( RES_PARATR_TABSTOP ).Clone() );
1067         rDoc.SetDefault( *m_pTabStop );
1068         m_pTabStop.reset( pOld );
1069     }
1070 }
1071 
1072 void SwUndoDefaultAttr::RedoImpl(::sw::UndoRedoContext & rContext)
1073 {
1074     UndoImpl(rContext);
1075 }
1076 
1077 // -----------------------------------------------------
1078 
1079 SwUndoMoveLeftMargin::SwUndoMoveLeftMargin(
1080             const SwPaM& rPam, sal_Bool bFlag, sal_Bool bMod )
1081     : SwUndo( bFlag ? UNDO_INC_LEFTMARGIN : UNDO_DEC_LEFTMARGIN )
1082     , SwUndRng( rPam )
1083     , m_pHistory( new SwHistory )
1084     , m_bModulus( bMod )
1085 {
1086 }
1087 
1088 SwUndoMoveLeftMargin::~SwUndoMoveLeftMargin()
1089 {
1090 }
1091 
1092 void SwUndoMoveLeftMargin::UndoImpl(::sw::UndoRedoContext & rContext)
1093 {
1094     SwDoc & rDoc = rContext.GetDoc();
1095 
1096     // restore old values
1097     m_pHistory->TmpRollback( & rDoc, 0 );
1098     m_pHistory->SetTmpEnd( m_pHistory->Count() );
1099 
1100     AddUndoRedoPaM(rContext);
1101 }
1102 
1103 void SwUndoMoveLeftMargin::RedoImpl(::sw::UndoRedoContext & rContext)
1104 {
1105     SwDoc & rDoc = rContext.GetDoc();
1106     SwPaM & rPam = AddUndoRedoPaM(rContext);
1107 
1108     rDoc.MoveLeftMargin( rPam,
1109             GetId() == UNDO_INC_LEFTMARGIN, m_bModulus );
1110 }
1111 
1112 void SwUndoMoveLeftMargin::RepeatImpl(::sw::RepeatContext & rContext)
1113 {
1114     SwDoc & rDoc = rContext.GetDoc();
1115     rDoc.MoveLeftMargin(rContext.GetRepeatPaM(), GetId() == UNDO_INC_LEFTMARGIN,
1116             m_bModulus );
1117 }
1118 
1119 // -----------------------------------------------------
1120 
1121 SwUndoChangeFootNote::SwUndoChangeFootNote(
1122             const SwPaM& rRange, const String& rTxt,
1123             sal_uInt16 nNum, bool bIsEndNote )
1124     : SwUndo( UNDO_CHGFTN ), SwUndRng( rRange )
1125     , m_pHistory( new SwHistory() )
1126     , m_Text( rTxt )
1127     , m_nNumber( nNum )
1128     , m_bEndNote( bIsEndNote )
1129 {
1130 }
1131 
1132 SwUndoChangeFootNote::~SwUndoChangeFootNote()
1133 {
1134 }
1135 
1136 void SwUndoChangeFootNote::UndoImpl(::sw::UndoRedoContext & rContext)
1137 {
1138     SwDoc & rDoc = rContext.GetDoc();
1139 
1140     m_pHistory->TmpRollback( &rDoc, 0 );
1141     m_pHistory->SetTmpEnd( m_pHistory->Count() );
1142 
1143 	rDoc.GetFtnIdxs().UpdateAllFtn();
1144 
1145     AddUndoRedoPaM(rContext);
1146 }
1147 
1148 void SwUndoChangeFootNote::RedoImpl(::sw::UndoRedoContext & rContext)
1149 {
1150     SwDoc & rDoc( rContext.GetDoc() );
1151     SwPaM & rPaM = AddUndoRedoPaM(rContext);
1152     rDoc.SetCurFtn(rPaM, m_Text, m_nNumber, m_bEndNote);
1153     SetPaM(rPaM);
1154 }
1155 
1156 void SwUndoChangeFootNote::RepeatImpl(::sw::RepeatContext & rContext)
1157 {
1158     SwDoc & rDoc = rContext.GetDoc();
1159     rDoc.SetCurFtn( rContext.GetRepeatPaM(), m_Text, m_nNumber, m_bEndNote );
1160 }
1161 
1162 
1163 // -----------------------------------------------------
1164 
1165 
1166 SwUndoFootNoteInfo::SwUndoFootNoteInfo( const SwFtnInfo &rInfo )
1167     : SwUndo( UNDO_FTNINFO )
1168     , m_pFootNoteInfo( new SwFtnInfo( rInfo ) )
1169 {
1170 }
1171 
1172 SwUndoFootNoteInfo::~SwUndoFootNoteInfo()
1173 {
1174 }
1175 
1176 void SwUndoFootNoteInfo::UndoImpl(::sw::UndoRedoContext & rContext)
1177 {
1178     SwDoc & rDoc = rContext.GetDoc();
1179 	SwFtnInfo *pInf = new SwFtnInfo( rDoc.GetFtnInfo() );
1180     rDoc.SetFtnInfo( *m_pFootNoteInfo );
1181     m_pFootNoteInfo.reset( pInf );
1182 }
1183 
1184 void SwUndoFootNoteInfo::RedoImpl(::sw::UndoRedoContext & rContext)
1185 {
1186     SwDoc & rDoc = rContext.GetDoc();
1187 	SwFtnInfo *pInf = new SwFtnInfo( rDoc.GetFtnInfo() );
1188     rDoc.SetFtnInfo( *m_pFootNoteInfo );
1189     m_pFootNoteInfo.reset( pInf );
1190 }
1191 
1192 
1193 // -----------------------------------------------------
1194 
1195 SwUndoEndNoteInfo::SwUndoEndNoteInfo( const SwEndNoteInfo &rInfo )
1196     : SwUndo( UNDO_FTNINFO )
1197     , m_pEndNoteInfo( new SwEndNoteInfo( rInfo ) )
1198 {
1199 }
1200 
1201 SwUndoEndNoteInfo::~SwUndoEndNoteInfo()
1202 {
1203 }
1204 
1205 void SwUndoEndNoteInfo::UndoImpl(::sw::UndoRedoContext & rContext)
1206 {
1207     SwDoc & rDoc = rContext.GetDoc();
1208 	SwEndNoteInfo *pInf = new SwEndNoteInfo( rDoc.GetEndNoteInfo() );
1209     rDoc.SetEndNoteInfo( *m_pEndNoteInfo );
1210     m_pEndNoteInfo.reset( pInf );
1211 }
1212 
1213 void SwUndoEndNoteInfo::RedoImpl(::sw::UndoRedoContext & rContext)
1214 {
1215     SwDoc & rDoc = rContext.GetDoc();
1216 	SwEndNoteInfo *pInf = new SwEndNoteInfo( rDoc.GetEndNoteInfo() );
1217     rDoc.SetEndNoteInfo( *m_pEndNoteInfo );
1218     m_pEndNoteInfo.reset( pInf );
1219 }
1220 
1221 // -----------------------------------------------------
1222 
1223 SwUndoDontExpandFmt::SwUndoDontExpandFmt( const SwPosition& rPos )
1224     : SwUndo( UNDO_DONTEXPAND )
1225     , m_nNodeIndex( rPos.nNode.GetIndex() )
1226     , m_nContentIndex( rPos.nContent.GetIndex() )
1227 {
1228 }
1229 
1230 void SwUndoDontExpandFmt::UndoImpl(::sw::UndoRedoContext & rContext)
1231 {
1232     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
1233     SwDoc *const pDoc = & rContext.GetDoc();
1234 
1235 	SwPosition& rPos = *pPam->GetPoint();
1236     rPos.nNode = m_nNodeIndex;
1237     rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), m_nContentIndex);
1238 	pDoc->DontExpandFmt( rPos, sal_False );
1239 }
1240 
1241 
1242 void SwUndoDontExpandFmt::RedoImpl(::sw::UndoRedoContext & rContext)
1243 {
1244     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
1245     SwDoc *const pDoc = & rContext.GetDoc();
1246 
1247 	SwPosition& rPos = *pPam->GetPoint();
1248     rPos.nNode = m_nNodeIndex;
1249     rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), m_nContentIndex);
1250 	pDoc->DontExpandFmt( rPos );
1251 }
1252 
1253 void SwUndoDontExpandFmt::RepeatImpl(::sw::RepeatContext & rContext)
1254 {
1255     SwPaM & rPam = rContext.GetRepeatPaM();
1256     SwDoc & rDoc = rContext.GetDoc();
1257     rDoc.DontExpandFmt( *rPam.GetPoint() );
1258 }
1259 
1260