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 .
21 #include <UndoSection.hxx>
23 #include <editeng/protitem.hxx>
24 #include <osl/diagnose.h>
25 #include <comphelper/scopeguard.hxx>
26 #include <sfx2/linkmgr.hxx>
27 #include <fmtcntnt.hxx>
29 #include <IDocumentLinksAdministration.hxx>
30 #include <IDocumentRedlineAccess.hxx>
31 #include <IDocumentFieldsAccess.hxx>
32 #include <IDocumentLayoutAccess.hxx>
33 #include <IDocumentStylePoolAccess.hxx>
34 #include <poolfmt.hxx>
39 #include <UndoCore.hxx>
40 #include <section.hxx>
42 #include <redline.hxx>
45 #include <rootfrm.hxx>
47 /// OD 04.10.2002 #102894#
48 /// class Calc needed for calculation of the hidden condition of a section.
51 static std::optional
<SfxItemSet
> lcl_GetAttrSet( const SwSection
& rSect
)
53 // save attributes of the format (columns, color, ...)
54 // Content and Protect items are not interesting since they are already
55 // stored in Section, thus delete them.
56 std::optional
<SfxItemSet
> oAttr
;
57 if( rSect
.GetFormat() )
60 if( rSect
.IsProtect() )
63 if( nCnt
< rSect
.GetFormat()->GetAttrSet().Count() )
65 oAttr
.emplace( rSect
.GetFormat()->GetAttrSet() );
66 oAttr
->ClearItem( RES_PROTECT
);
67 oAttr
->ClearItem( RES_CNTNT
);
77 SwUndoInsSection::SwUndoInsSection(
78 SwPaM
const& rPam
, SwSectionData
const& rNewData
,
79 SfxItemSet
const*const pSet
,
80 std::tuple
<SwTOXBase
const*, sw::RedlineMode
, sw::FieldmarkMode
, sw::ParagraphBreakMode
> const*const pTOXBase
)
81 : SwUndo( SwUndoId::INSSECTION
, &rPam
.GetDoc() ), SwUndRng( rPam
)
82 , m_pSectionData(new SwSectionData(rNewData
))
83 , m_pAttrSet( (pSet
&& pSet
->Count()) ? new SfxItemSet( *pSet
) : nullptr )
84 , m_nSectionNodePos(0)
85 , m_bSplitAtStart(false)
86 , m_bSplitAtEnd(false)
87 , m_bUpdateFootnote(false)
91 std::make_unique
<SwTOXBase
>(*std::get
<0>(*pTOXBase
)),
92 std::get
<1>(*pTOXBase
),
93 std::get
<2>(*pTOXBase
),
94 std::get
<3>(*pTOXBase
));
96 SwDoc
& rDoc
= rPam
.GetDoc();
97 if( rDoc
.getIDocumentRedlineAccess().IsRedlineOn() )
99 m_pRedlData
.reset(new SwRedlineData( RedlineType::Insert
,
100 rDoc
.getIDocumentRedlineAccess().GetRedlineAuthor() ));
101 SetRedlineFlags( rDoc
.getIDocumentRedlineAccess().GetRedlineFlags() );
103 m_pRedlineSaveData
.reset( new SwRedlineSaveDatas
);
104 if( !FillSaveData( rPam
, *m_pRedlineSaveData
, false ))
105 m_pRedlineSaveData
.reset();
110 const SwContentNode
* pCNd
= rPam
.GetPoint()->GetNode().GetContentNode();
111 if( pCNd
&& pCNd
->HasSwAttrSet() && (
112 !rPam
.GetPoint()->GetContentIndex() ||
113 rPam
.GetPoint()->GetContentIndex() == pCNd
->Len() ))
115 SfxItemSet
aBrkSet( rDoc
.GetAttrPool(), aBreakSetRange
);
116 aBrkSet
.Put( *pCNd
->GetpSwAttrSet() );
117 if( aBrkSet
.Count() )
119 m_pHistory
.reset( new SwHistory
);
120 m_pHistory
->CopyFormatAttr( aBrkSet
, pCNd
->GetIndex() );
125 SwUndoInsSection::~SwUndoInsSection()
129 void SwUndoInsSection::UndoImpl(::sw::UndoRedoContext
& rContext
)
131 SwDoc
& rDoc
= rContext
.GetDoc();
133 RemoveIdxFromSection( rDoc
, m_nSectionNodePos
);
135 SwSectionNode
*const pNd
=
136 rDoc
.GetNodes()[ m_nSectionNodePos
]->GetSectionNode();
137 OSL_ENSURE( pNd
, "where is my SectionNode?" );
139 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags() ))
140 rDoc
.getIDocumentRedlineAccess().DeleteRedline( *pNd
, true, RedlineType::Any
);
143 SwNodeIndex
aIdx( *pNd
);
144 if( ( !m_nEndNode
&& COMPLETE_STRING
== m_nEndContent
) ||
145 ( m_nSttNode
== m_nEndNode
&& m_nSttContent
== m_nEndContent
))
146 // delete simply all nodes
147 rDoc
.GetNodes().Delete( aIdx
, pNd
->EndOfSectionIndex() -
150 // just delete format, rest happens automatically
151 rDoc
.DelSectionFormat( pNd
->GetSection().GetFormat() );
153 // do we need to consolidate?
156 Join( rDoc
, m_nSttNode
);
161 Join( rDoc
, m_nEndNode
);
166 m_pHistory
->TmpRollback( &rDoc
, 0, false );
169 if (m_bUpdateFootnote
)
171 rDoc
.GetFootnoteIdxs().UpdateFootnote( aIdx
.GetNode() );
174 AddUndoRedoPaM(rContext
);
176 if (m_pRedlineSaveData
)
177 SetSaveData( rDoc
, *m_pRedlineSaveData
);
180 void SwUndoInsSection::RedoImpl(::sw::UndoRedoContext
& rContext
)
182 SwDoc
& rDoc
= rContext
.GetDoc();
183 SwPaM
& rPam( AddUndoRedoPaM(rContext
) );
185 const SwTOXBaseSection
* pUpdateTOX
= nullptr;
188 SwRootFrame
const* pLayout(nullptr);
189 SwRootFrame
* pLayoutToReset(nullptr);
190 sw::FieldmarkMode eFieldmarkMode
{};
191 sw::ParagraphBreakMode eParagraphBreakMode
{};
192 comphelper::ScopeGuard
g([&]() {
195 pLayoutToReset
->SetHideRedlines(std::get
<1>(*m_xTOXBase
) == sw::RedlineMode::Shown
);
196 pLayoutToReset
->SetFieldmarkMode(eFieldmarkMode
, eParagraphBreakMode
);
199 o3tl::sorted_vector
<SwRootFrame
*> layouts(rDoc
.GetAllLayouts());
200 for (SwRootFrame
const*const p
: layouts
)
202 if ((std::get
<1>(*m_xTOXBase
) == sw::RedlineMode::Hidden
) == p
->IsHideRedlines()
203 && std::get
<2>(*m_xTOXBase
) == p
->GetFieldmarkMode()
204 && std::get
<3>(*m_xTOXBase
) == p
->GetParagraphBreakMode())
212 assert(!layouts
.empty()); // must have one layout
213 pLayoutToReset
= *layouts
.begin();
214 eFieldmarkMode
= pLayoutToReset
->GetFieldmarkMode();
215 eParagraphBreakMode
= pLayoutToReset
->GetParagraphBreakMode();
216 pLayoutToReset
->SetHideRedlines(std::get
<1>(*m_xTOXBase
) == sw::RedlineMode::Hidden
);
217 pLayoutToReset
->SetFieldmarkMode(std::get
<2>(*m_xTOXBase
), std::get
<3>(*m_xTOXBase
));
218 pLayout
= pLayoutToReset
;
220 pUpdateTOX
= rDoc
.InsertTableOf( *rPam
.GetPoint(),
221 // don't expand: will be done by SwUndoUpdateIndex::RedoImpl()
222 *std::get
<0>(*m_xTOXBase
), m_pAttrSet
.get(), false, pLayout
);
226 rDoc
.InsertSwSection(rPam
, *m_pSectionData
, nullptr, m_pAttrSet
.get());
231 m_pHistory
->SetTmpEnd( m_pHistory
->Count() );
234 SwSectionNode
*const pSectNd
=
235 rDoc
.GetNodes()[ m_nSectionNodePos
]->GetSectionNode();
237 IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags()))
239 RedlineFlags eOld
= rDoc
.getIDocumentRedlineAccess().GetRedlineFlags();
240 rDoc
.getIDocumentRedlineAccess().SetRedlineFlags_intern(eOld
& ~RedlineFlags::Ignore
);
242 SwPaM
aPam( *pSectNd
->EndOfSectionNode(), *pSectNd
, SwNodeOffset(1) );
243 rDoc
.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( *m_pRedlData
, aPam
), true);
244 rDoc
.getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld
);
246 else if( !( RedlineFlags::Ignore
& GetRedlineFlags() ) &&
247 !rDoc
.getIDocumentRedlineAccess().GetRedlineTable().empty() )
249 SwPaM
aPam( *pSectNd
->EndOfSectionNode(), *pSectNd
, SwNodeOffset(1) );
250 rDoc
.getIDocumentRedlineAccess().SplitRedline( aPam
);
255 // initiate formatting
256 if (SwEditShell
* pESh
= rDoc
.GetEditShell())
259 // insert page numbers
260 const_cast<SwTOXBaseSection
*>(pUpdateTOX
)->UpdatePageNum();
264 void SwUndoInsSection::RepeatImpl(::sw::RepeatContext
& rContext
)
266 SwDoc
& rDoc
= rContext
.GetDoc();
269 rDoc
.InsertTableOf(*rContext
.GetRepeatPaM().GetPoint(),
270 *std::get
<0>(*m_xTOXBase
), m_pAttrSet
.get(), true,
271 rDoc
.getIDocumentLayoutAccess().GetCurrentLayout()); // TODO add shell to RepeatContext?
275 rDoc
.InsertSwSection(rContext
.GetRepeatPaM(),
276 *m_pSectionData
, nullptr, m_pAttrSet
.get());
280 void SwUndoInsSection::Join( SwDoc
& rDoc
, SwNodeOffset nNode
)
282 SwNodeIndex
aIdx( rDoc
.GetNodes(), nNode
);
283 SwTextNode
* pTextNd
= aIdx
.GetNode().GetTextNode();
284 OSL_ENSURE( pTextNd
, "Where is my TextNode?" );
289 SwPosition( aIdx
, pTextNd
, pTextNd
->GetText().getLength() ) );
294 pTextNd
->RstTextAttr( 0, pTextNd
->Len(), 0, nullptr, true );
298 SwUndoInsSection::SaveSplitNode(SwTextNode
*const pTextNd
, bool const bAtStart
)
300 if( pTextNd
->GetpSwpHints() )
304 m_pHistory
.reset( new SwHistory
);
306 m_pHistory
->CopyAttr( pTextNd
->GetpSwpHints(), pTextNd
->GetIndex(), 0,
307 pTextNd
->GetText().getLength(), false );
312 m_bSplitAtStart
= true;
316 m_bSplitAtEnd
= true;
320 class SwUndoDelSection
324 std::unique_ptr
<SwSectionData
> const m_pSectionData
; /// section not TOX
325 std::unique_ptr
<SwTOXBase
> const m_pTOXBase
; /// set iff section is TOX
326 std::optional
<SfxItemSet
> const m_oAttrSet
;
327 std::shared_ptr
< ::sfx2::MetadatableUndo
> const m_pMetadataUndo
;
328 SwNodeOffset
const m_nStartNode
;
329 SwNodeOffset
const m_nEndNode
;
333 SwSectionFormat
const&, SwSection
const&, SwNodeIndex
const*const);
335 virtual void UndoImpl( ::sw::UndoRedoContext
& ) override
;
336 virtual void RedoImpl( ::sw::UndoRedoContext
& ) override
;
339 std::unique_ptr
<SwUndo
> MakeUndoDelSection(SwSectionFormat
const& rFormat
)
341 return std::make_unique
<SwUndoDelSection
>(rFormat
, *rFormat
.GetSection(),
342 rFormat
.GetContent().GetContentIdx());
345 SwUndoDelSection::SwUndoDelSection(
346 SwSectionFormat
const& rSectionFormat
, SwSection
const& rSection
,
347 SwNodeIndex
const*const pIndex
)
348 : SwUndo( SwUndoId::DELSECTION
, rSectionFormat
.GetDoc() )
349 , m_pSectionData( new SwSectionData(rSection
) )
350 , m_pTOXBase( dynamic_cast<const SwTOXBaseSection
*>( &rSection
) != nullptr
351 ? new SwTOXBase(static_cast<SwTOXBaseSection
const&>(rSection
))
353 , m_oAttrSet( ::lcl_GetAttrSet(rSection
) )
354 , m_pMetadataUndo( rSectionFormat
.CreateUndo() )
355 , m_nStartNode( pIndex
->GetIndex() )
356 , m_nEndNode( pIndex
->GetNode().EndOfSectionIndex() )
360 void SwUndoDelSection::UndoImpl(::sw::UndoRedoContext
& rContext
)
362 SwDoc
& rDoc
= rContext
.GetDoc();
366 // sw_redlinehide: this should work as-is; there will be another undo for the update
367 rDoc
.InsertTableOf(m_nStartNode
, m_nEndNode
-2, *m_pTOXBase
,
368 m_oAttrSet
? &*m_oAttrSet
: nullptr);
372 SwNodeIndex
aStt( rDoc
.GetNodes(), m_nStartNode
);
373 SwNodeIndex
aEnd( rDoc
.GetNodes(), m_nEndNode
-2 );
374 SwSectionFormat
* pFormat
= rDoc
.MakeSectionFormat();
377 pFormat
->SetFormatAttr( *m_oAttrSet
);
380 /// OD 04.10.2002 #102894#
381 /// remember inserted section node for further calculations
382 SwSectionNode
* pInsertedSectNd
= rDoc
.GetNodes().InsertTextSection(
383 aStt
.GetNode(), *pFormat
, *m_pSectionData
, nullptr, & aEnd
.GetNode() );
385 if( SfxItemState::SET
== pFormat
->GetItemState( RES_FTN_AT_TXTEND
) ||
386 SfxItemState::SET
== pFormat
->GetItemState( RES_END_AT_TXTEND
))
388 rDoc
.GetFootnoteIdxs().UpdateFootnote( aStt
.GetNode() );
391 /// OD 04.10.2002 #102894#
392 /// consider that section is hidden by condition.
393 /// If section is hidden by condition,
394 /// recalculate condition and update hidden condition flag.
395 /// Recalculation is necessary, because fields, on which the hide
396 /// condition depends, can be changed - fields changes aren't undoable.
397 /// NOTE: setting hidden condition flag also creates/deletes corresponding
398 /// frames, if the hidden condition flag changes.
399 SwSection
& aInsertedSect
= pInsertedSectNd
->GetSection();
400 if ( aInsertedSect
.IsHidden() &&
401 !aInsertedSect
.GetCondition().isEmpty() )
403 SwCalc
aCalc( rDoc
);
404 rDoc
.getIDocumentFieldsAccess().FieldsToCalc(aCalc
, pInsertedSectNd
->GetIndex(), SAL_MAX_INT32
);
405 bool bRecalcCondHidden
=
406 aCalc
.Calculate( aInsertedSect
.GetCondition() ).GetBool();
407 aInsertedSect
.SetCondHidden( bRecalcCondHidden
);
410 pFormat
->RestoreMetadata(m_pMetadataUndo
);
414 void SwUndoDelSection::RedoImpl(::sw::UndoRedoContext
& rContext
)
416 SwDoc
& rDoc
= rContext
.GetDoc();
418 SwSectionNode
*const pNd
=
419 rDoc
.GetNodes()[ m_nStartNode
]->GetSectionNode();
420 OSL_ENSURE( pNd
, "Where is my SectionNode?" );
421 // just delete format, rest happens automatically
422 rDoc
.DelSectionFormat( pNd
->GetSection().GetFormat() );
427 class SwUndoUpdateSection
431 std::unique_ptr
<SwSectionData
> m_pSectionData
;
432 std::optional
<SfxItemSet
> m_oAttrSet
;
433 SwNodeOffset
const m_nStartNode
;
434 bool const m_bOnlyAttrChanged
;
438 SwSection
const&, SwNodeIndex
const*const, bool const bOnlyAttr
);
440 virtual void UndoImpl( ::sw::UndoRedoContext
& ) override
;
441 virtual void RedoImpl( ::sw::UndoRedoContext
& ) override
;
446 std::unique_ptr
<SwUndo
>
447 MakeUndoUpdateSection(SwSectionFormat
const& rFormat
, bool const bOnlyAttr
)
449 return std::make_unique
<SwUndoUpdateSection
>(*rFormat
.GetSection(),
450 rFormat
.GetContent().GetContentIdx(), bOnlyAttr
);
453 SwUndoUpdateSection::SwUndoUpdateSection(
454 SwSection
const& rSection
, SwNodeIndex
const*const pIndex
,
455 bool const bOnlyAttr
)
456 : SwUndo( SwUndoId::CHGSECTION
, &pIndex
->GetNode().GetDoc() )
457 , m_pSectionData( new SwSectionData(rSection
) )
458 , m_oAttrSet( ::lcl_GetAttrSet(rSection
) )
459 , m_nStartNode( pIndex
->GetIndex() )
460 , m_bOnlyAttrChanged( bOnlyAttr
)
464 void SwUndoUpdateSection::UndoImpl(::sw::UndoRedoContext
& rContext
)
466 SwDoc
& rDoc
= rContext
.GetDoc();
467 SwSectionNode
*const pSectNd
=
468 rDoc
.GetNodes()[ m_nStartNode
]->GetSectionNode();
469 OSL_ENSURE( pSectNd
, "Where is my SectionNode?" );
471 SwSection
& rNdSect
= pSectNd
->GetSection();
472 SwFormat
* pFormat
= rNdSect
.GetFormat();
474 std::optional
<SfxItemSet
> oCur
= ::lcl_GetAttrSet( rNdSect
);
477 // The Content and Protect items must persist
478 m_oAttrSet
->Put( pFormat
->GetFormatAttr( RES_CNTNT
));
479 if( const SvxProtectItem
* pItem
= pFormat
->GetItemIfSet( RES_PROTECT
))
481 m_oAttrSet
->Put( *pItem
);
483 pFormat
->DelDiffs( *m_oAttrSet
);
484 m_oAttrSet
->ClearItem( RES_CNTNT
);
485 pFormat
->SetFormatAttr( *m_oAttrSet
);
489 // than the old ones need to be deleted
490 pFormat
->ResetFormatAttr( RES_FRMATR_BEGIN
, RES_BREAK
);
491 pFormat
->ResetFormatAttr( RES_HEADER
, RES_OPAQUE
);
492 pFormat
->ResetFormatAttr( RES_SURROUND
, RES_FRMATR_END
-1 );
495 m_oAttrSet
.emplace(std::move(*oCur
));
499 if (m_bOnlyAttrChanged
)
503 (!rNdSect
.IsLinkType() && m_pSectionData
->IsLinkType())
504 || ( !m_pSectionData
->GetLinkFileName().isEmpty()
505 && (m_pSectionData
->GetLinkFileName() !=
506 rNdSect
.GetLinkFileName()));
508 // swap stored section data with live section data
509 SwSectionData
*const pOld( new SwSectionData(rNdSect
) );
510 rNdSect
.SetSectionData(*m_pSectionData
);
511 m_pSectionData
.reset(pOld
);
514 rNdSect
.CreateLink( LinkCreateType::Update
);
515 else if( SectionType::Content
== rNdSect
.GetType() && rNdSect
.IsConnected() )
517 rNdSect
.Disconnect();
518 rDoc
.getIDocumentLinksAdministration().GetLinkManager().Remove( &rNdSect
.GetBaseLink() );
522 void SwUndoUpdateSection::RedoImpl(::sw::UndoRedoContext
& rContext
)
528 SwUndoUpdateIndex::SwUndoUpdateIndex(SwTOXBaseSection
& rTOX
)
529 : SwUndo(SwUndoId::INSSECTION
, rTOX
.GetFormat()->GetDoc())
530 , m_pSaveSectionOriginal(new SwUndoSaveSection
)
531 , m_pSaveSectionUpdated(new SwUndoSaveSection
)
532 , m_nStartIndex(rTOX
.GetFormat()->GetSectionNode()->GetIndex() + 1)
534 SwDoc
& rDoc(*rTOX
.GetFormat()->GetDoc());
535 assert(rDoc
.GetNodes()[m_nStartIndex
-1]->IsSectionNode());
536 assert(rDoc
.GetNodes()[rDoc
.GetNodes()[m_nStartIndex
]->EndOfSectionIndex()-1]->IsTextNode()); // -1 for extra empty node
537 // note: title is optional
538 assert(rDoc
.GetNodes()[m_nStartIndex
]->IsTextNode()
539 || rDoc
.GetNodes()[m_nStartIndex
]->IsSectionNode());
540 SwNodeIndex
const first(rDoc
.GetNodes(), m_nStartIndex
);
541 if (first
.GetNode().IsSectionNode())
543 SwSectionFormat
& rSectionFormat(*first
.GetNode().GetSectionNode()->GetSection().GetFormat());
544 // note: DelSectionFormat will create & append SwUndoDelSection!
545 rDoc
.DelSectionFormat(& rSectionFormat
); // remove inner section nodes
547 assert(first
.GetNode().IsTextNode()); // invariant: ToX section is *never* empty
548 SwNodeIndex
const last(rDoc
.GetNodes(), rDoc
.GetNodes()[m_nStartIndex
]->EndOfSectionIndex() - 2); // skip empty node
549 assert(last
.GetNode().IsTextNode());
550 m_pSaveSectionOriginal
->SaveSection(SwNodeRange(first
, last
), false);
553 SwUndoUpdateIndex::~SwUndoUpdateIndex() = default;
555 void SwUndoUpdateIndex::TitleSectionInserted(SwSectionFormat
& rFormat
)
558 SwNodeIndex
const tmp(rFormat
.GetDoc()->GetNodes(), m_nStartIndex
); // title inserted before empty node
559 assert(tmp
.GetNode().IsSectionNode());
560 assert(tmp
.GetNode().GetSectionNode()->GetSection().GetFormat() == &rFormat
);
562 m_pTitleSectionUpdated
.reset(static_cast<SwUndoDelSection
*>(MakeUndoDelSection(rFormat
).release()));
565 void SwUndoUpdateIndex::UndoImpl(::sw::UndoRedoContext
& rContext
)
567 SwDoc
& rDoc(rContext
.GetDoc());
568 if (m_pTitleSectionUpdated
)
570 m_pTitleSectionUpdated
->RedoImpl(rContext
);
572 SwNodeIndex
const first(rDoc
.GetNodes(), m_nStartIndex
);
573 assert(first
.GetNode().IsTextNode()); // invariant: ToX section is *never* empty
574 SwNodeIndex
const last(rDoc
.GetNodes(), rDoc
.GetNodes()[m_nStartIndex
]->EndOfSectionIndex() - 1);
575 assert(last
.GetNode().IsTextNode());
576 // dummy node so that SaveSection doesn't remove ToX section...
577 SwTextNode
*const pDeletionPrevention
= rDoc
.GetNodes().MakeTextNode(
578 *rDoc
.GetNodes()[m_nStartIndex
]->EndOfSectionNode(),
579 rDoc
.getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_TEXT
));
580 m_pSaveSectionUpdated
->SaveSection(SwNodeRange(first
, last
), false);
581 m_pSaveSectionOriginal
->RestoreSection(&rDoc
, first
.GetNode(), true);
582 // delete before restoring nested undo, so its node indexes match
583 SwNodeIndex
const del(*pDeletionPrevention
);
584 SwDoc::CorrAbs(del
, del
, SwPosition(*rDoc
.GetNodes()[m_nStartIndex
]->EndOfSectionNode(), SwNodeOffset(0)), true);
585 rDoc
.GetNodes().Delete(del
);
586 // original title section will be restored by next Undo, see ctor!
589 void SwUndoUpdateIndex::RedoImpl(::sw::UndoRedoContext
& rContext
)
591 SwDoc
& rDoc(rContext
.GetDoc());
592 // original title section was deleted by previous Undo, see ctor!
593 SwNodeIndex
const first(rDoc
.GetNodes(), m_nStartIndex
);
594 assert(first
.GetNode().IsTextNode()); // invariant: ToX section is *never* empty
595 SwNodeIndex
const last(rDoc
.GetNodes(), rDoc
.GetNodes()[m_nStartIndex
]->EndOfSectionIndex() - 1);
596 assert(last
.GetNode().IsTextNode());
597 // dummy node so that SaveSection doesn't remove ToX section...
598 SwTextNode
*const pDeletionPrevention
= rDoc
.GetNodes().MakeTextNode(
599 *rDoc
.GetNodes()[m_nStartIndex
]->EndOfSectionNode(),
600 rDoc
.getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_TEXT
));
601 m_pSaveSectionOriginal
->SaveSection(SwNodeRange(first
, last
), false);
602 m_pSaveSectionUpdated
->RestoreSection(&rDoc
, first
.GetNode(), true);
603 // delete before restoring nested undo, so its node indexes match
604 SwNodeIndex
const del(*pDeletionPrevention
);
605 SwDoc::CorrAbs(del
, del
, SwPosition(*rDoc
.GetNodes()[m_nStartIndex
]->EndOfSectionNode(), SwNodeOffset(0)), true);
606 rDoc
.GetNodes().Delete(del
);
607 if (m_pTitleSectionUpdated
)
609 m_pTitleSectionUpdated
->UndoImpl(rContext
);
613 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */