1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <utility>
23 
24 #include <UndoAttribute.hxx>
25 #include <svl/itemiter.hxx>
26 #include <editeng/tstpitem.hxx>
27 #include <svx/svdobj.hxx>
28 #include <osl/diagnose.h>
29 #include <hintids.hxx>
30 #include <fmtflcnt.hxx>
31 #include <txtftn.hxx>
32 #include <fmtanchr.hxx>
33 #include <fmtfsize.hxx>
34 #include <frmfmt.hxx>
35 #include <fmtcntnt.hxx>
36 #include <ftnidx.hxx>
37 #include <doc.hxx>
38 #include <IDocumentLayoutAccess.hxx>
39 #include <IDocumentRedlineAccess.hxx>
40 #include <IShellCursorSupplier.hxx>
41 #include <docary.hxx>
42 #include <swundo.hxx>
43 #include <pam.hxx>
44 #include <ndtxt.hxx>
45 #include <swtable.hxx>
46 #include <swtblfmt.hxx>
47 #include <UndoCore.hxx>
48 #include <hints.hxx>
49 #include <rolbck.hxx>
50 #include <ndnotxt.hxx>
51 #include <ftninfo.hxx>
52 #include <redline.hxx>
53 #include <section.hxx>
54 #include <charfmt.hxx>
55 #include <calbck.hxx>
56 #include <frameformats.hxx>
57 
SwUndoFormatAttrHelper(SwFormat & rFormat,bool bSvDrwPt)58 SwUndoFormatAttrHelper::SwUndoFormatAttrHelper(SwFormat& rFormat, bool bSvDrwPt)
59     : SwClient(&rFormat)
60     , m_rFormat(rFormat)
61     , m_bSaveDrawPt(bSvDrwPt)
62 {
63 }
64 
SwClientNotify(const SwModify &,const SfxHint & rHint)65 void SwUndoFormatAttrHelper::SwClientNotify(const SwModify&, const SfxHint& rHint)
66 {
67     if (rHint.GetId() != SfxHintId::SwLegacyModify)
68         return;
69     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
70     if(!pLegacy->m_pOld)
71         return;
72     assert(pLegacy->m_pOld->Which() != RES_OBJECTDYING);
73     if(!pLegacy->m_pNew)
74         return;
75     const SwDoc& rDoc = *m_rFormat.GetDoc();
76     auto pOld = pLegacy->m_pOld;
77     if(POOLATTR_END >= pLegacy->m_pOld->Which()) {
78         if(!GetUndo())
79             m_pUndo.reset(new SwUndoFormatAttr(*pOld, m_rFormat, m_bSaveDrawPt));
80         else
81             m_pUndo->PutAttr(*pOld, rDoc);
82     } else if(RES_ATTRSET_CHG == pOld->Which()) {
83         auto& rChgSet = *static_cast<const SwAttrSetChg*>(pOld)->GetChgSet();
84         if(!GetUndo())
85             m_pUndo.reset(new SwUndoFormatAttr(rChgSet, m_rFormat, m_bSaveDrawPt));
86         else {
87             SfxItemIter aIter(rChgSet);
88             for(auto pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
89                 m_pUndo->PutAttr(*pItem, rDoc);
90         }
91     }
92 }
93 
SwUndoFormatAttr(const SfxItemSet & rOldSet,SwFormat & rChgFormat,bool bSaveDrawPt)94 SwUndoFormatAttr::SwUndoFormatAttr( const SfxItemSet& rOldSet,
95                               SwFormat& rChgFormat,
96                               bool bSaveDrawPt )
97     : SwUndo( SwUndoId::INSFMTATTR, rChgFormat.GetDoc() )
98     , m_sFormatName ( rChgFormat.GetName() )
99     // #i56253#
100     , m_pOldSet( new SfxItemSet( rOldSet ) )
101     , m_nNodeIndex( 0 )
102     , m_nFormatWhich( rChgFormat.Which() )
103     , m_bSaveDrawPt( bSaveDrawPt )
104 {
105     assert(m_sFormatName.getLength());
106 
107     Init( rChgFormat );
108 }
109 
SwUndoFormatAttr(const SfxPoolItem & rItem,SwFormat & rChgFormat,bool bSaveDrawPt)110 SwUndoFormatAttr::SwUndoFormatAttr( const SfxPoolItem& rItem, SwFormat& rChgFormat,
111                               bool bSaveDrawPt )
112     : SwUndo( SwUndoId::INSFMTATTR, rChgFormat.GetDoc() )
113     , m_sFormatName(rChgFormat.GetName())
114     , m_pOldSet( rChgFormat.GetAttrSet().Clone( false ) )
115     , m_nNodeIndex( 0 )
116     , m_nFormatWhich( rChgFormat.Which() )
117     , m_bSaveDrawPt( bSaveDrawPt )
118 {
119     assert(m_sFormatName.getLength());
120 
121     m_pOldSet->Put( rItem );
122     Init( rChgFormat );
123 }
124 
Init(const SwFormat & rFormat)125 void SwUndoFormatAttr::Init( const SwFormat & rFormat )
126 {
127     // tdf#126017 never save SwNodeIndex, it will go stale
128     m_pOldSet->ClearItem(RES_CNTNT);
129     // treat change of anchor specially
130     if ( SfxItemState::SET == m_pOldSet->GetItemState( RES_ANCHOR, false )) {
131         SaveFlyAnchor( &rFormat, m_bSaveDrawPt );
132     } else if ( RES_FRMFMT == m_nFormatWhich ) {
133         const SwDoc* pDoc = rFormat.GetDoc();
134         if (pDoc->GetTableFrameFormats()->ContainsFormat(dynamic_cast<const SwFrameFormat&>(rFormat)))
135         {
136             // Table Format: save table position, table formats are volatile!
137             SwTable * pTable = SwIterator<SwTable,SwFormat>( rFormat ).First();
138             if ( pTable ) {
139                 m_nNodeIndex = pTable->GetTabSortBoxes()[ 0 ]->GetSttNd()
140                                ->FindTableNode()->GetIndex();
141             }
142         } else if (pDoc->GetSections().ContainsFormat(&rFormat)) {
143             m_nNodeIndex = rFormat.GetContent().GetContentIdx()->GetIndex();
144         } else if ( dynamic_cast< const SwTableBoxFormat* >( &rFormat ) !=  nullptr ) {
145             SwTableBox * pTableBox = SwIterator<SwTableBox,SwFormat>( rFormat ).First();
146             if ( pTableBox ) {
147                 m_nNodeIndex = pTableBox->GetSttIdx();
148             }
149         }
150     }
151 }
152 
~SwUndoFormatAttr()153 SwUndoFormatAttr::~SwUndoFormatAttr()
154 {
155 }
156 
UndoImpl(::sw::UndoRedoContext & rContext)157 void SwUndoFormatAttr::UndoImpl(::sw::UndoRedoContext & rContext)
158 {
159     // OD 2004-10-26 #i35443#
160     // Important note: <Undo(..)> also called by <ReDo(..)>
161 
162     if (!m_pOldSet)
163         return;
164 
165     SwFormat * pFormat = GetFormat(rContext.GetDoc());
166     if (!pFormat)
167         return;
168 
169     // #i35443# - If anchor attribute has been successful
170     // restored, all other attributes are also restored.
171     // Thus, keep track of its restoration
172     bool bAnchorAttrRestored( false );
173     if ( SfxItemState::SET == m_pOldSet->GetItemState( RES_ANCHOR, false )) {
174         bAnchorAttrRestored = RestoreFlyAnchor(rContext);
175         if ( bAnchorAttrRestored ) {
176             // Anchor attribute successful restored.
177             // Thus, keep anchor position for redo
178             SaveFlyAnchor(pFormat);
179         } else {
180             // Anchor attribute not restored due to invalid anchor position.
181             // Thus, delete anchor attribute.
182             m_pOldSet->ClearItem( RES_ANCHOR );
183         }
184     }
185 
186     if ( bAnchorAttrRestored )        return;
187 
188     SwUndoFormatAttrHelper aTmp( *pFormat, m_bSaveDrawPt );
189     pFormat->SetFormatAttr( *m_pOldSet );
190     if ( aTmp.GetUndo() ) {
191         // transfer ownership of helper object's old set
192         m_pOldSet = std::move(aTmp.GetUndo()->m_pOldSet);
193     } else {
194         m_pOldSet->ClearItem();
195     }
196 
197     if ( RES_FLYFRMFMT == m_nFormatWhich || RES_DRAWFRMFMT == m_nFormatWhich ) {
198         rContext.SetSelections(static_cast<SwFrameFormat*>(pFormat), nullptr);
199     }
200 }
201 
202 // Check if it is still in Doc
GetFormat(const SwDoc & rDoc)203 SwFormat* SwUndoFormatAttr::GetFormat( const SwDoc& rDoc )
204 {
205     switch (m_nFormatWhich)
206     {
207     case RES_TXTFMTCOLL:
208     case RES_CONDTXTFMTCOLL:
209         return rDoc.FindTextFormatCollByName(m_sFormatName);
210 
211     case RES_GRFFMTCOLL:
212         return SwDoc::FindFormatByName(*rDoc.GetGrfFormatColls(), m_sFormatName);
213 
214     case RES_CHRFMT:
215         return rDoc.FindCharFormatByName(m_sFormatName);
216 
217     case RES_FRMFMT:
218         if (m_nNodeIndex && (m_nNodeIndex < rDoc.GetNodes().Count()))
219         {
220             SwNode* pNd = rDoc.GetNodes()[m_nNodeIndex];
221             if (pNd->IsTableNode())
222             {
223                 return static_cast<SwTableNode*>(pNd)->GetTable().GetFrameFormat();
224             }
225             else if (pNd->IsSectionNode())
226             {
227                 return static_cast<SwSectionNode*>(pNd)->GetSection().GetFormat();
228             }
229             else if (pNd->IsStartNode() && (SwTableBoxStartNode ==
230                 static_cast<SwStartNode*>(pNd)->GetStartNodeType()))
231             {
232                 SwTableNode* pTableNode = pNd->FindTableNode();
233                 if (pTableNode)
234                 {
235                     SwTableBox* pBox = pTableNode->GetTable().GetTableBox(m_nNodeIndex);
236                     if (pBox)
237                     {
238                         return pBox->GetFrameFormat();
239                     }
240                 }
241             }
242         }
243         [[fallthrough]];
244     case RES_DRAWFRMFMT:
245     case RES_FLYFRMFMT:
246         {
247             SwFormat * pFormat = SwDoc::FindFormatByName(*rDoc.GetSpzFrameFormats(), m_sFormatName);
248             if (pFormat)
249                 return pFormat;
250             pFormat = SwDoc::FindFormatByName(*rDoc.GetFrameFormats(), m_sFormatName);
251             if (pFormat)
252                 return pFormat;
253         }
254         break;
255     }
256 
257     return nullptr;
258 }
259 
RedoImpl(::sw::UndoRedoContext & rContext)260 void SwUndoFormatAttr::RedoImpl(::sw::UndoRedoContext & rContext)
261 {
262     // #i35443# - Because the undo stores the attributes for
263     // redo, the same code as for <Undo(..)> can be applied for <Redo(..)>
264     UndoImpl(rContext);
265 }
266 
RepeatImpl(::sw::RepeatContext & rContext)267 void SwUndoFormatAttr::RepeatImpl(::sw::RepeatContext & rContext)
268 {
269     if (!m_pOldSet)
270         return;
271 
272     SwDoc & rDoc(rContext.GetDoc());
273 
274     SwFormat * pFormat = GetFormat(rDoc);
275     if (!pFormat)
276         return;
277 
278     switch ( m_nFormatWhich ) {
279     case RES_GRFFMTCOLL: {
280         SwNoTextNode *const pNd =
281             rContext.GetRepeatPaM().GetNode().GetNoTextNode();
282         if( pNd ) {
283             rDoc.SetAttr( pFormat->GetAttrSet(), *pNd->GetFormatColl() );
284         }
285     }
286     break;
287 
288     case RES_TXTFMTCOLL:
289     case RES_CONDTXTFMTCOLL:
290     {
291         SwTextNode *const pNd =
292             rContext.GetRepeatPaM().GetNode().GetTextNode();
293         if( pNd ) {
294             rDoc.SetAttr( pFormat->GetAttrSet(), *pNd->GetFormatColl() );
295         }
296     }
297     break;
298 
299     case RES_FLYFRMFMT: {
300         // Check if the cursor is in a flying frame
301         // Steps: search in all FlyFrameFormats for the FlyContent attribute
302         // and validate if the cursor is in the respective section
303         SwFrameFormat *const pFly =
304             rContext.GetRepeatPaM().GetNode().GetFlyFormat();
305         if( pFly ) {
306             // Bug 43672: do not set all attributes!
307             if (SfxItemState::SET ==
308                 pFormat->GetAttrSet().GetItemState( RES_CNTNT )) {
309                 SfxItemSet aTmpSet( pFormat->GetAttrSet() );
310                 aTmpSet.ClearItem( RES_CNTNT );
311                 if( aTmpSet.Count() ) {
312                     rDoc.SetAttr( aTmpSet, *pFly );
313                 }
314             } else {
315                 rDoc.SetAttr( pFormat->GetAttrSet(), *pFly );
316             }
317         }
318         break;
319     }
320     }
321 }
322 
GetRewriter() const323 SwRewriter SwUndoFormatAttr::GetRewriter() const
324 {
325     SwRewriter aRewriter;
326 
327     aRewriter.AddRule(UndoArg1, m_sFormatName);
328 
329     return aRewriter;
330 }
331 
PutAttr(const SfxPoolItem & rItem,const SwDoc & rDoc)332 void SwUndoFormatAttr::PutAttr( const SfxPoolItem& rItem, const SwDoc& rDoc )
333 {
334     if (RES_CNTNT == rItem.Which())
335     {
336         return; // tdf#126017 never save SwNodeIndex, it will go stale
337     }
338     m_pOldSet->Put( rItem );
339     if ( RES_ANCHOR == rItem.Which() )
340     {
341         SwFormat * pFormat = GetFormat( rDoc );
342         SaveFlyAnchor( pFormat, m_bSaveDrawPt );
343     }
344 }
345 
SaveFlyAnchor(const SwFormat * pFormat,bool bSvDrwPt)346 void SwUndoFormatAttr::SaveFlyAnchor( const SwFormat * pFormat, bool bSvDrwPt )
347 {
348     // Format is valid, otherwise you would not reach this point here
349     if( bSvDrwPt ) {
350         if ( RES_DRAWFRMFMT == pFormat->Which() ) {
351             Point aPt( static_cast<const SwFrameFormat*>(pFormat)->FindSdrObject()
352                        ->GetRelativePos() );
353             // store old value as attribute, to keep SwUndoFormatAttr small
354             m_pOldSet->Put( SwFormatFrameSize( SwFrameSize::Variable, aPt.X(), aPt.Y() ) );
355         }
356     }
357 
358     const SwFormatAnchor& rAnchor =
359         m_pOldSet->Get( RES_ANCHOR, false );
360     if( !rAnchor.GetContentAnchor() )
361         return;
362 
363     sal_Int32 nContent = 0;
364     switch( rAnchor.GetAnchorId() ) {
365     case RndStdIds::FLY_AS_CHAR:
366     case RndStdIds::FLY_AT_CHAR:
367         nContent = rAnchor.GetContentAnchor()->nContent.GetIndex();
368         [[fallthrough]];
369     case RndStdIds::FLY_AT_PARA:
370     case RndStdIds::FLY_AT_FLY:
371         m_nNodeIndex = rAnchor.GetContentAnchor()->nNode.GetIndex();
372         break;
373     default:
374         return;
375     }
376 
377     SwFormatAnchor aAnchor( rAnchor.GetAnchorId(), nContent );
378     m_pOldSet->Put( aAnchor );
379 }
380 
381 // #i35443# - Add return value, type <bool>.
382 // Return value indicates, if anchor attribute is restored.
383 // Note: If anchor attribute is restored, all other existing attributes
384 //       are also restored.
RestoreFlyAnchor(::sw::UndoRedoContext & rContext)385 bool SwUndoFormatAttr::RestoreFlyAnchor(::sw::UndoRedoContext & rContext)
386 {
387     SwDoc *const pDoc = & rContext.GetDoc();
388     SwFrameFormat* pFrameFormat = static_cast<SwFrameFormat*>( GetFormat( *pDoc ) );
389     const SwFormatAnchor& rAnchor =
390         m_pOldSet->Get( RES_ANCHOR, false );
391 
392     SwFormatAnchor aNewAnchor( rAnchor.GetAnchorId() );
393     if (RndStdIds::FLY_AT_PAGE != rAnchor.GetAnchorId()) {
394         SwNode* pNd = pDoc->GetNodes()[ m_nNodeIndex  ];
395 
396         if (  (RndStdIds::FLY_AT_FLY == rAnchor.GetAnchorId())
397               ? ( !pNd->IsStartNode() || (SwFlyStartNode !=
398                                           static_cast<SwStartNode*>(pNd)->GetStartNodeType()) )
399               : !pNd->IsTextNode() ) {
400             // #i35443# - invalid position.
401             // Thus, anchor attribute not restored
402             return false;
403         }
404 
405         SwPosition aPos( *pNd );
406         if ((RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()) ||
407             (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId())) {
408             aPos.nContent.Assign( static_cast<SwTextNode*>(pNd), rAnchor.GetPageNum() );
409             if ( aPos.nContent.GetIndex() > pNd->GetTextNode()->GetText().getLength()) {
410                 // #i35443# - invalid position.
411                 // Thus, anchor attribute not restored
412                 return false;
413             }
414         }
415         aNewAnchor.SetAnchor( &aPos );
416     } else
417         aNewAnchor.SetPageNum( rAnchor.GetPageNum() );
418 
419     Point aDrawSavePt, aDrawOldPt;
420     if( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() ) {
421         if( RES_DRAWFRMFMT == pFrameFormat->Which() ) {
422             // get the old cached value
423             const SwFormatFrameSize& rOldSize = m_pOldSet->Get( RES_FRM_SIZE );
424             aDrawSavePt.setX( rOldSize.GetWidth() );
425             aDrawSavePt.setY( rOldSize.GetHeight() );
426             m_pOldSet->ClearItem( RES_FRM_SIZE );
427 
428             // write the current value into cache
429             aDrawOldPt = pFrameFormat->FindSdrObject()->GetRelativePos();
430         } else {
431             pFrameFormat->DelFrames();         // delete Frames
432         }
433     }
434 
435     const SwFormatAnchor &rOldAnch = pFrameFormat->GetAnchor();
436     // #i54336#
437     // Consider case, that as-character anchored object has moved its anchor position.
438     if (RndStdIds::FLY_AS_CHAR == rOldAnch.GetAnchorId()) {
439         // With InContents it's tricky: the text attribute needs to be deleted.
440         // Unfortunately, this not only destroys the Frames but also the format.
441         // To prevent that, first detach the connection between attribute and
442         // format.
443         const SwPosition *pPos = rOldAnch.GetContentAnchor();
444         SwTextNode *pTextNode = static_cast<SwTextNode*>(&pPos->nNode.GetNode());
445         OSL_ENSURE( pTextNode->HasHints(), "Missing FlyInCnt-Hint." );
446         const sal_Int32 nIdx = pPos->nContent.GetIndex();
447         SwTextAttr * const pHint =
448             pTextNode->GetTextAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
449         assert(pHint && "Missing Hint.");
450         OSL_ENSURE( pHint->Which() == RES_TXTATR_FLYCNT,
451                     "Missing FlyInCnt-Hint." );
452         OSL_ENSURE( pHint->GetFlyCnt().GetFrameFormat() == pFrameFormat,
453                     "Wrong TextFlyCnt-Hint." );
454         const_cast<SwFormatFlyCnt&>(pHint->GetFlyCnt()).SetFlyFormat();
455 
456         // Connection is now detached, therefore the attribute can be deleted
457         pTextNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
458     }
459 
460     {
461         m_pOldSet->Put( aNewAnchor );
462         SwUndoFormatAttrHelper aTmp( *pFrameFormat, m_bSaveDrawPt );
463         pFrameFormat->SetFormatAttr( *m_pOldSet );
464         if ( aTmp.GetUndo() ) {
465             m_nNodeIndex = aTmp.GetUndo()->m_nNodeIndex;
466             // transfer ownership of helper object's old set
467             m_pOldSet = std::move(aTmp.GetUndo()->m_pOldSet);
468         } else {
469             m_pOldSet->ClearItem();
470         }
471     }
472 
473     if ( RES_DRAWFRMFMT == pFrameFormat->Which() )
474     {
475         // The Draw model also prepared an Undo object for its right positioning
476         // which unfortunately is relative. Therefore block here a position
477         // change of the Contact object by setting the anchor.
478         pFrameFormat->CallSwClientNotify(sw::RestoreFlyAnchorHint(aDrawSavePt));
479         // cache the old value again
480         m_pOldSet->Put(SwFormatFrameSize(SwFrameSize::Variable, aDrawOldPt.X(), aDrawOldPt.Y()));
481     }
482 
483     if (RndStdIds::FLY_AS_CHAR == aNewAnchor.GetAnchorId()) {
484         const SwPosition* pPos = aNewAnchor.GetContentAnchor();
485         SwTextNode* pTextNd = pPos->nNode.GetNode().GetTextNode();
486         OSL_ENSURE( pTextNd, "no Text Node at position." );
487         SwFormatFlyCnt aFormat( pFrameFormat );
488         pTextNd->InsertItem( aFormat, pPos->nContent.GetIndex(), 0 );
489     }
490 
491     if (RES_DRAWFRMFMT != pFrameFormat->Which())
492         pFrameFormat->MakeFrames();
493     else
494     {
495         pFrameFormat->CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::POST_RESTORE_FLY_ANCHOR));
496     }
497 
498     rContext.SetSelections(pFrameFormat, nullptr);
499 
500     // #i35443# - anchor attribute restored.
501     return true;
502 }
503 
SwUndoFormatResetAttr(SwFormat & rChangedFormat,const sal_uInt16 nWhichId)504 SwUndoFormatResetAttr::SwUndoFormatResetAttr( SwFormat& rChangedFormat,
505                                         const sal_uInt16 nWhichId )
506     : SwUndo( SwUndoId::RESETATTR, rChangedFormat.GetDoc() )
507     , m_pChangedFormat( &rChangedFormat )
508     , m_nWhichId( nWhichId )
509 {
510     const SfxPoolItem* pItem = nullptr;
511     if (rChangedFormat.GetItemState(nWhichId, false, &pItem ) == SfxItemState::SET && pItem) {
512         m_pOldItem.reset( pItem->Clone() );
513     }
514 }
515 
~SwUndoFormatResetAttr()516 SwUndoFormatResetAttr::~SwUndoFormatResetAttr()
517 {
518 }
519 
UndoImpl(::sw::UndoRedoContext &)520 void SwUndoFormatResetAttr::UndoImpl(::sw::UndoRedoContext &)
521 {
522     if (m_pOldItem)
523     {
524         m_pChangedFormat->SetFormatAttr( *m_pOldItem );
525     }
526 }
527 
RedoImpl(::sw::UndoRedoContext &)528 void SwUndoFormatResetAttr::RedoImpl(::sw::UndoRedoContext &)
529 {
530     if (m_pOldItem)
531     {
532         m_pChangedFormat->ResetFormatAttr( m_nWhichId );
533     }
534 }
535 
SwUndoResetAttr(const SwPaM & rRange,sal_uInt16 nFormatId)536 SwUndoResetAttr::SwUndoResetAttr( const SwPaM& rRange, sal_uInt16 nFormatId )
537     : SwUndo( SwUndoId::RESETATTR, &rRange.GetDoc() ), SwUndRng( rRange )
538     , m_pHistory( new SwHistory )
539     , m_nFormatId( nFormatId )
540 {
541 }
542 
SwUndoResetAttr(const SwPosition & rPos,sal_uInt16 nFormatId)543 SwUndoResetAttr::SwUndoResetAttr( const SwPosition& rPos, sal_uInt16 nFormatId )
544     : SwUndo( SwUndoId::RESETATTR, &rPos.GetDoc() )
545     , m_pHistory( new SwHistory )
546     , m_nFormatId( nFormatId )
547 {
548     m_nSttNode = m_nEndNode = rPos.nNode.GetIndex();
549     m_nSttContent = m_nEndContent = rPos.nContent.GetIndex();
550 }
551 
~SwUndoResetAttr()552 SwUndoResetAttr::~SwUndoResetAttr()
553 {
554 }
555 
UndoImpl(::sw::UndoRedoContext & rContext)556 void SwUndoResetAttr::UndoImpl(::sw::UndoRedoContext & rContext)
557 {
558     // reset old values
559     SwDoc & rDoc = rContext.GetDoc();
560     m_pHistory->TmpRollback( &rDoc, 0 );
561     m_pHistory->SetTmpEnd( m_pHistory->Count() );
562 
563     if ((RES_CONDTXTFMTCOLL == m_nFormatId) &&
564         (m_nSttNode == m_nEndNode) && (m_nSttContent == m_nEndContent)) {
565         SwTextNode* pTNd = rDoc.GetNodes()[ m_nSttNode ]->GetTextNode();
566         if( pTNd ) {
567             SwIndex aIdx( pTNd, m_nSttContent );
568             pTNd->DontExpandFormat( aIdx, false );
569         }
570     }
571 
572     AddUndoRedoPaM(rContext);
573 }
574 
RedoImpl(::sw::UndoRedoContext & rContext)575 void SwUndoResetAttr::RedoImpl(::sw::UndoRedoContext & rContext)
576 {
577     SwDoc & rDoc = rContext.GetDoc();
578     SwPaM & rPam = AddUndoRedoPaM(rContext);
579 
580     switch ( m_nFormatId ) {
581     case RES_CHRFMT:
582         rDoc.RstTextAttrs(rPam);
583         break;
584     case RES_TXTFMTCOLL:
585         rDoc.ResetAttrs(rPam, false, m_Ids );
586         break;
587     case RES_CONDTXTFMTCOLL:
588         rDoc.ResetAttrs(rPam, true, m_Ids );
589 
590         break;
591     case RES_TXTATR_TOXMARK:
592         // special treatment for TOXMarks
593     {
594         SwTOXMarks aArr;
595         SwNodeIndex aIdx( rDoc.GetNodes(), m_nSttNode );
596         SwPosition aPos( aIdx, SwIndex( aIdx.GetNode().GetContentNode(),
597                                         m_nSttContent ));
598 
599         sal_uInt16 nCnt = SwDoc::GetCurTOXMark( aPos, aArr );
600         if( nCnt ) {
601             if( 1 < nCnt ) {
602                 // search for the right one
603                 SwHistoryHint* pHHint = (GetHistory())[ 0 ];
604                 if( pHHint && HSTRY_SETTOXMARKHNT == pHHint->Which() ) {
605                     while( nCnt ) {
606                         if ( static_cast<SwHistorySetTOXMark*>(pHHint)
607                              ->IsEqual( *aArr[ --nCnt ] ) ) {
608                             ++nCnt;
609                             break;
610                         }
611                     }
612                 } else
613                     nCnt = 0;
614             }
615             // found one, thus delete it
616             if( nCnt-- ) {
617                 rDoc.DeleteTOXMark( aArr[ nCnt ] );
618             }
619         }
620     }
621     break;
622     }
623 }
624 
RepeatImpl(::sw::RepeatContext & rContext)625 void SwUndoResetAttr::RepeatImpl(::sw::RepeatContext & rContext)
626 {
627     if (m_nFormatId < RES_FMT_BEGIN) {
628         return;
629     }
630 
631     switch ( m_nFormatId ) {
632     case RES_CHRFMT:
633         rContext.GetDoc().RstTextAttrs(rContext.GetRepeatPaM());
634         break;
635     case RES_TXTFMTCOLL:
636         rContext.GetDoc().ResetAttrs(rContext.GetRepeatPaM(), false, m_Ids);
637         break;
638     case RES_CONDTXTFMTCOLL:
639         rContext.GetDoc().ResetAttrs(rContext.GetRepeatPaM(), true, m_Ids);
640         break;
641     }
642 }
643 
SetAttrs(const o3tl::sorted_vector<sal_uInt16> & rAttrs)644 void SwUndoResetAttr::SetAttrs( const o3tl::sorted_vector<sal_uInt16> &rAttrs )
645 {
646     m_Ids = rAttrs;
647 }
648 
SwUndoAttr(const SwPaM & rRange,const SfxPoolItem & rAttr,const SetAttrMode nFlags)649 SwUndoAttr::SwUndoAttr( const SwPaM& rRange, const SfxPoolItem& rAttr,
650                         const SetAttrMode nFlags )
651     : SwUndo( SwUndoId::INSATTR, &rRange.GetDoc() ), SwUndRng( rRange )
652     , m_AttrSet( rRange.GetDoc().GetAttrPool(), {{rAttr.Which(), rAttr.Which()}} )
653     , m_pHistory( new SwHistory )
654     , m_nNodeIndex( ULONG_MAX )
655     , m_nInsertFlags( nFlags )
656 {
657     m_AttrSet.Put( rAttr );
658 
659     // Save character style as a style name, not as a reference
660     const SfxPoolItem* pItem = m_AttrSet.GetItem(RES_TXTATR_CHARFMT);
661     if (pItem)
662     {
663         uno::Any aValue;
664         pItem->QueryValue(aValue, RES_TXTATR_CHARFMT);
665         aValue >>= m_aChrFormatName;
666     }
667 }
668 
SwUndoAttr(const SwPaM & rRange,const SfxItemSet & rSet,const SetAttrMode nFlags)669 SwUndoAttr::SwUndoAttr( const SwPaM& rRange, const SfxItemSet& rSet,
670                         const SetAttrMode nFlags )
671     : SwUndo( SwUndoId::INSATTR, &rRange.GetDoc() ), SwUndRng( rRange )
672     , m_AttrSet( rSet )
673     , m_pHistory( new SwHistory )
674     , m_nNodeIndex( ULONG_MAX )
675     , m_nInsertFlags( nFlags )
676 {
677     // Save character style as a style name, not as a reference
678     const SfxPoolItem* pItem = m_AttrSet.GetItem(RES_TXTATR_CHARFMT);
679     if (pItem)
680     {
681         uno::Any aValue;
682         pItem->QueryValue(aValue, RES_TXTATR_CHARFMT);
683         aValue >>= m_aChrFormatName;
684     }
685 }
686 
~SwUndoAttr()687 SwUndoAttr::~SwUndoAttr()
688 {
689 }
690 
SaveRedlineData(const SwPaM & rPam,bool bIsContent)691 void SwUndoAttr::SaveRedlineData( const SwPaM& rPam, bool bIsContent )
692 {
693     SwDoc& rDoc = rPam.GetDoc();
694     if ( rDoc.getIDocumentRedlineAccess().IsRedlineOn() ) {
695         m_pRedlineData.reset( new SwRedlineData( bIsContent
696                               ? RedlineType::Insert
697                               : RedlineType::Format,
698                               rDoc.getIDocumentRedlineAccess().GetRedlineAuthor() ) );
699     }
700 
701     m_pRedlineSaveData.reset( new SwRedlineSaveDatas );
702     if ( !FillSaveDataForFormat( rPam, *m_pRedlineSaveData ))
703         m_pRedlineSaveData.reset();
704 
705     SetRedlineFlags( rDoc.getIDocumentRedlineAccess().GetRedlineFlags() );
706     if ( bIsContent ) {
707         m_nNodeIndex = rPam.GetPoint()->nNode.GetIndex();
708     }
709 }
710 
UndoImpl(::sw::UndoRedoContext & rContext)711 void SwUndoAttr::UndoImpl(::sw::UndoRedoContext & rContext)
712 {
713     SwDoc *const pDoc = & rContext.GetDoc();
714 
715     RemoveIdx( *pDoc );
716 
717     if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags() ) ) {
718         SwPaM aPam(pDoc->GetNodes().GetEndOfContent());
719         if ( ULONG_MAX != m_nNodeIndex ) {
720             aPam.DeleteMark();
721             aPam.GetPoint()->nNode = m_nNodeIndex;
722             aPam.GetPoint()->nContent.Assign( aPam.GetContentNode(), m_nSttContent );
723             aPam.SetMark();
724             ++aPam.GetPoint()->nContent;
725             pDoc->getIDocumentRedlineAccess().DeleteRedline(aPam, false, RedlineType::Any);
726         } else {
727             // remove all format redlines, will be recreated if needed
728             SetPaM(aPam);
729             pDoc->getIDocumentRedlineAccess().DeleteRedline(aPam, false, RedlineType::Format);
730             if (m_pRedlineSaveData)
731             {
732                 SetSaveData( *pDoc, *m_pRedlineSaveData );
733             }
734         }
735     }
736 
737     const bool bToLast =  (1 == m_AttrSet.Count())
738                           && (RES_TXTATR_FIELD <= *m_AttrSet.GetRanges())
739                           && (*m_AttrSet.GetRanges() <= RES_TXTATR_ANNOTATION);
740 
741     // restore old values
742     m_pHistory->TmpRollback( pDoc, 0, !bToLast );
743     m_pHistory->SetTmpEnd( m_pHistory->Count() );
744 
745     // set cursor onto Undo area
746     AddUndoRedoPaM(rContext);
747 }
748 
RepeatImpl(::sw::RepeatContext & rContext)749 void SwUndoAttr::RepeatImpl(::sw::RepeatContext & rContext)
750 {
751     // RefMarks are not repeat capable
752     if ( SfxItemState::SET != m_AttrSet.GetItemState( RES_TXTATR_REFMARK, false ) ) {
753         rContext.GetDoc().getIDocumentContentOperations().InsertItemSet( rContext.GetRepeatPaM(),
754                 m_AttrSet, m_nInsertFlags );
755     } else if ( 1 < m_AttrSet.Count() ) {
756         SfxItemSet aTmpSet( m_AttrSet );
757         aTmpSet.ClearItem( RES_TXTATR_REFMARK );
758         rContext.GetDoc().getIDocumentContentOperations().InsertItemSet( rContext.GetRepeatPaM(),
759                 aTmpSet, m_nInsertFlags );
760     }
761 }
762 
RedoImpl(::sw::UndoRedoContext & rContext)763 void SwUndoAttr::RedoImpl(::sw::UndoRedoContext & rContext)
764 {
765     SwDoc & rDoc = rContext.GetDoc();
766     SwPaM & rPam = AddUndoRedoPaM(rContext);
767 
768     // Restore pointer to char format from name
769     if (!m_aChrFormatName.isEmpty())
770     {
771         SwCharFormat* pCharFormat = rDoc.FindCharFormatByName(m_aChrFormatName);
772         if (pCharFormat)
773         {
774             SwFormatCharFormat aFormat(pCharFormat);
775             m_AttrSet.Put(aFormat);
776         }
777     }
778 
779     if ( m_pRedlineData &&
780          IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags() ) ) {
781         RedlineFlags eOld = rDoc.getIDocumentRedlineAccess().GetRedlineFlags();
782         rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld & ~RedlineFlags::Ignore );
783         rDoc.getIDocumentContentOperations().InsertItemSet( rPam, m_AttrSet, m_nInsertFlags );
784 
785         if ( ULONG_MAX != m_nNodeIndex ) {
786             rPam.SetMark();
787             if ( rPam.Move( fnMoveBackward ) ) {
788                 rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( *m_pRedlineData, rPam ),
789                         true);
790             }
791             rPam.DeleteMark();
792         } else {
793             rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( *m_pRedlineData, rPam ), true);
794         }
795 
796         rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld );
797     } else {
798         rDoc.getIDocumentContentOperations().InsertItemSet( rPam, m_AttrSet, m_nInsertFlags );
799     }
800 }
801 
RemoveIdx(SwDoc & rDoc)802 void SwUndoAttr::RemoveIdx( SwDoc& rDoc )
803 {
804     if ( SfxItemState::SET != m_AttrSet.GetItemState( RES_TXTATR_FTN, false ))
805         return ;
806 
807     SwNodes& rNds = rDoc.GetNodes();
808     for ( sal_uInt16 n = 0; n < m_pHistory->Count(); ++n ) {
809         sal_Int32 nContent = 0;
810         sal_uLong nNode = 0;
811         SwHistoryHint* pHstHint = (*m_pHistory)[ n ];
812         switch ( pHstHint->Which() ) {
813         case HSTRY_RESETTXTHNT: {
814             SwHistoryResetText * pHistoryHint
815                 = static_cast<SwHistoryResetText*>(pHstHint);
816             if ( RES_TXTATR_FTN == pHistoryHint->GetWhich() ) {
817                 nNode = pHistoryHint->GetNode();
818                 nContent = pHistoryHint->GetContent();
819             }
820         }
821         break;
822 
823         default:
824             break;
825         }
826 
827         if( nNode ) {
828             SwTextNode* pTextNd = rNds[ nNode ]->GetTextNode();
829             if( pTextNd ) {
830                 SwTextAttr *const pTextHt =
831                     pTextNd->GetTextAttrForCharAt(nContent, RES_TXTATR_FTN);
832                 if( pTextHt ) {
833                     // ok, so get values
834                     SwTextFootnote* pFootnote = static_cast<SwTextFootnote*>(pTextHt);
835                     RemoveIdxFromSection( rDoc, pFootnote->GetStartNode()->GetIndex() );
836                     return ;
837                 }
838             }
839         }
840     }
841 }
842 
SwUndoDefaultAttr(const SfxItemSet & rSet,const SwDoc & rDoc)843 SwUndoDefaultAttr::SwUndoDefaultAttr( const SfxItemSet& rSet, const SwDoc& rDoc )
844     : SwUndo( SwUndoId::SETDEFTATTR, &rDoc )
845 {
846     const SfxPoolItem* pItem;
847     if( SfxItemState::SET == rSet.GetItemState( RES_PARATR_TABSTOP, false, &pItem ) ) {
848         // store separately, because it may change!
849         m_pTabStop.reset( static_cast<SvxTabStopItem*>(pItem->Clone()) );
850         if ( 1 != rSet.Count() ) { // are there more attributes?
851             m_pOldSet.reset( new SfxItemSet( rSet ) );
852         }
853     } else {
854         m_pOldSet.reset( new SfxItemSet( rSet ) );
855     }
856 }
857 
~SwUndoDefaultAttr()858 SwUndoDefaultAttr::~SwUndoDefaultAttr()
859 {
860 }
861 
UndoImpl(::sw::UndoRedoContext & rContext)862 void SwUndoDefaultAttr::UndoImpl(::sw::UndoRedoContext & rContext)
863 {
864     SwDoc & rDoc = rContext.GetDoc();
865     if (m_pOldSet)
866     {
867         SwUndoFormatAttrHelper aTmp(
868             *rDoc.GetDfltTextFormatColl() );
869         rDoc.SetDefault( *m_pOldSet );
870         m_pOldSet.reset();
871         if ( aTmp.GetUndo() ) {
872             // transfer ownership of helper object's old set
873             m_pOldSet = std::move(aTmp.GetUndo()->m_pOldSet);
874         }
875     }
876     if (m_pTabStop)
877     {
878         std::unique_ptr<SvxTabStopItem> pOld(rDoc.GetDefault(RES_PARATR_TABSTOP).Clone());
879         rDoc.SetDefault( *m_pTabStop );
880         m_pTabStop = std::move( pOld );
881     }
882 }
883 
RedoImpl(::sw::UndoRedoContext & rContext)884 void SwUndoDefaultAttr::RedoImpl(::sw::UndoRedoContext & rContext)
885 {
886     UndoImpl(rContext);
887 }
888 
SwUndoMoveLeftMargin(const SwPaM & rPam,bool bFlag,bool bMod)889 SwUndoMoveLeftMargin::SwUndoMoveLeftMargin(
890     const SwPaM& rPam, bool bFlag, bool bMod )
891     : SwUndo( bFlag ? SwUndoId::INC_LEFTMARGIN : SwUndoId::DEC_LEFTMARGIN, &rPam.GetDoc() )
892     , SwUndRng( rPam )
893     , m_pHistory( new SwHistory )
894     , m_bModulus( bMod )
895 {
896 }
897 
~SwUndoMoveLeftMargin()898 SwUndoMoveLeftMargin::~SwUndoMoveLeftMargin()
899 {
900 }
901 
UndoImpl(::sw::UndoRedoContext & rContext)902 void SwUndoMoveLeftMargin::UndoImpl(::sw::UndoRedoContext & rContext)
903 {
904     SwDoc & rDoc = rContext.GetDoc();
905 
906     // restore old values
907     m_pHistory->TmpRollback( & rDoc, 0 );
908     m_pHistory->SetTmpEnd( m_pHistory->Count() );
909 
910     AddUndoRedoPaM(rContext);
911 }
912 
RedoImpl(::sw::UndoRedoContext & rContext)913 void SwUndoMoveLeftMargin::RedoImpl(::sw::UndoRedoContext & rContext)
914 {
915     SwDoc & rDoc = rContext.GetDoc();
916     SwPaM & rPam = AddUndoRedoPaM(rContext);
917 
918     rDoc.MoveLeftMargin( rPam,
919                          GetId() == SwUndoId::INC_LEFTMARGIN, m_bModulus,
920                          rDoc.getIDocumentLayoutAccess().GetCurrentLayout() );
921 }
922 
RepeatImpl(::sw::RepeatContext & rContext)923 void SwUndoMoveLeftMargin::RepeatImpl(::sw::RepeatContext & rContext)
924 {
925     SwDoc & rDoc = rContext.GetDoc();
926     rDoc.MoveLeftMargin(rContext.GetRepeatPaM(), GetId() == SwUndoId::INC_LEFTMARGIN,
927                         m_bModulus, rDoc.getIDocumentLayoutAccess().GetCurrentLayout());
928 }
929 
SwUndoChangeFootNote(const SwPaM & rRange,const OUString & rText,bool const bIsEndNote)930 SwUndoChangeFootNote::SwUndoChangeFootNote(
931     const SwPaM& rRange, const OUString& rText,
932         bool const bIsEndNote)
933     : SwUndo( SwUndoId::CHGFTN, &rRange.GetDoc() ), SwUndRng( rRange )
934     , m_pHistory( new SwHistory() )
935     , m_Text( rText )
936     , m_bEndNote( bIsEndNote )
937 {
938 }
939 
~SwUndoChangeFootNote()940 SwUndoChangeFootNote::~SwUndoChangeFootNote()
941 {
942 }
943 
UndoImpl(::sw::UndoRedoContext & rContext)944 void SwUndoChangeFootNote::UndoImpl(::sw::UndoRedoContext & rContext)
945 {
946     SwDoc & rDoc = rContext.GetDoc();
947 
948     m_pHistory->TmpRollback( &rDoc, 0 );
949     m_pHistory->SetTmpEnd( m_pHistory->Count() );
950 
951     rDoc.GetFootnoteIdxs().UpdateAllFootnote();
952 
953     AddUndoRedoPaM(rContext);
954 }
955 
RedoImpl(::sw::UndoRedoContext & rContext)956 void SwUndoChangeFootNote::RedoImpl(::sw::UndoRedoContext & rContext)
957 {
958     SwDoc & rDoc( rContext.GetDoc() );
959     SwPaM & rPaM = AddUndoRedoPaM(rContext);
960     rDoc.SetCurFootnote(rPaM, m_Text, m_bEndNote);
961     SetPaM(rPaM);
962 }
963 
RepeatImpl(::sw::RepeatContext & rContext)964 void SwUndoChangeFootNote::RepeatImpl(::sw::RepeatContext & rContext)
965 {
966     SwDoc & rDoc = rContext.GetDoc();
967     rDoc.SetCurFootnote(rContext.GetRepeatPaM(), m_Text, m_bEndNote);
968 }
969 
SwUndoFootNoteInfo(const SwFootnoteInfo & rInfo,const SwDoc & rDoc)970 SwUndoFootNoteInfo::SwUndoFootNoteInfo( const SwFootnoteInfo &rInfo, const SwDoc& rDoc )
971     : SwUndo( SwUndoId::FTNINFO, &rDoc )
972     , m_pFootNoteInfo( new SwFootnoteInfo( rInfo ) )
973 {
974 }
975 
~SwUndoFootNoteInfo()976 SwUndoFootNoteInfo::~SwUndoFootNoteInfo()
977 {
978 }
979 
UndoImpl(::sw::UndoRedoContext & rContext)980 void SwUndoFootNoteInfo::UndoImpl(::sw::UndoRedoContext & rContext)
981 {
982     SwDoc & rDoc = rContext.GetDoc();
983     SwFootnoteInfo *pInf = new SwFootnoteInfo( rDoc.GetFootnoteInfo() );
984     rDoc.SetFootnoteInfo( *m_pFootNoteInfo );
985     m_pFootNoteInfo.reset( pInf );
986 }
987 
RedoImpl(::sw::UndoRedoContext & rContext)988 void SwUndoFootNoteInfo::RedoImpl(::sw::UndoRedoContext & rContext)
989 {
990     SwDoc & rDoc = rContext.GetDoc();
991     SwFootnoteInfo *pInf = new SwFootnoteInfo( rDoc.GetFootnoteInfo() );
992     rDoc.SetFootnoteInfo( *m_pFootNoteInfo );
993     m_pFootNoteInfo.reset( pInf );
994 }
995 
SwUndoEndNoteInfo(const SwEndNoteInfo & rInfo,const SwDoc & rDoc)996 SwUndoEndNoteInfo::SwUndoEndNoteInfo( const SwEndNoteInfo &rInfo, const SwDoc& rDoc )
997     : SwUndo( SwUndoId::FTNINFO, &rDoc )
998     , m_pEndNoteInfo( new SwEndNoteInfo( rInfo ) )
999 {
1000 }
1001 
~SwUndoEndNoteInfo()1002 SwUndoEndNoteInfo::~SwUndoEndNoteInfo()
1003 {
1004 }
1005 
UndoImpl(::sw::UndoRedoContext & rContext)1006 void SwUndoEndNoteInfo::UndoImpl(::sw::UndoRedoContext & rContext)
1007 {
1008     SwDoc & rDoc = rContext.GetDoc();
1009     SwEndNoteInfo *pInf = new SwEndNoteInfo( rDoc.GetEndNoteInfo() );
1010     rDoc.SetEndNoteInfo( *m_pEndNoteInfo );
1011     m_pEndNoteInfo.reset( pInf );
1012 }
1013 
RedoImpl(::sw::UndoRedoContext & rContext)1014 void SwUndoEndNoteInfo::RedoImpl(::sw::UndoRedoContext & rContext)
1015 {
1016     SwDoc & rDoc = rContext.GetDoc();
1017     SwEndNoteInfo *pInf = new SwEndNoteInfo( rDoc.GetEndNoteInfo() );
1018     rDoc.SetEndNoteInfo( *m_pEndNoteInfo );
1019     m_pEndNoteInfo.reset( pInf );
1020 }
1021 
SwUndoDontExpandFormat(const SwPosition & rPos)1022 SwUndoDontExpandFormat::SwUndoDontExpandFormat( const SwPosition& rPos )
1023     : SwUndo( SwUndoId::DONTEXPAND, &rPos.GetDoc() )
1024     , m_nNodeIndex( rPos.nNode.GetIndex() )
1025     , m_nContentIndex( rPos.nContent.GetIndex() )
1026 {
1027 }
1028 
UndoImpl(::sw::UndoRedoContext & rContext)1029 void SwUndoDontExpandFormat::UndoImpl(::sw::UndoRedoContext & rContext)
1030 {
1031     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
1032     SwDoc *const pDoc = & rContext.GetDoc();
1033 
1034     SwPosition& rPos = *pPam->GetPoint();
1035     rPos.nNode = m_nNodeIndex;
1036     rPos.nContent.Assign( rPos.nNode.GetNode().GetContentNode(), m_nContentIndex);
1037     pDoc->DontExpandFormat( rPos, false );
1038 }
1039 
RedoImpl(::sw::UndoRedoContext & rContext)1040 void SwUndoDontExpandFormat::RedoImpl(::sw::UndoRedoContext & rContext)
1041 {
1042     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
1043     SwDoc *const pDoc = & rContext.GetDoc();
1044 
1045     SwPosition& rPos = *pPam->GetPoint();
1046     rPos.nNode = m_nNodeIndex;
1047     rPos.nContent.Assign( rPos.nNode.GetNode().GetContentNode(), m_nContentIndex);
1048     pDoc->DontExpandFormat( rPos );
1049 }
1050 
RepeatImpl(::sw::RepeatContext & rContext)1051 void SwUndoDontExpandFormat::RepeatImpl(::sw::RepeatContext & rContext)
1052 {
1053     SwPaM & rPam = rContext.GetRepeatPaM();
1054     SwDoc & rDoc = rContext.GetDoc();
1055     rDoc.DontExpandFormat( *rPam.GetPoint() );
1056 }
1057 
1058 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1059