1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <UndoNumbering.hxx>
25 #include <UndoCore.hxx>
28 #include <osl/diagnose.h>
30 SwUndoInsNum::SwUndoInsNum( const SwNumRule
& rOldRule
,
31 const SwNumRule
& rNewRule
,
34 : SwUndo( nUndoId
, &rDoc
),
35 m_aNumRule( rNewRule
),
36 m_pOldNumRule( new SwNumRule( rOldRule
)), m_nLRSavePos( 0 )
40 SwUndoInsNum::SwUndoInsNum( const SwPaM
& rPam
, const SwNumRule
& rRule
)
41 : SwUndo( SwUndoId::INSNUM
, &rPam
.GetDoc() ), SwUndRng( rPam
),
47 SwUndoInsNum::SwUndoInsNum( const SwPosition
& rPos
, const SwNumRule
& rRule
,
48 OUString aReplaceRule
)
49 : SwUndo( SwUndoId::INSNUM
, &rPos
.GetNode().GetDoc() ),
51 m_sReplaceRule(std::move( aReplaceRule
)), m_nLRSavePos( 0 )
54 m_nEndNode
= SwNodeOffset(0);
55 m_nEndContent
= COMPLETE_STRING
;
56 m_nSttNode
= rPos
.GetNodeIndex();
57 m_nSttContent
= rPos
.GetContentIndex();
60 SwUndoInsNum::~SwUndoInsNum()
63 m_pOldNumRule
.reset();
66 SwRewriter
SwUndoInsNum::GetRewriter() const
69 if( SwUndoId::INSFMTATTR
== GetId() )
70 aResult
.AddRule(UndoArg1
, m_aNumRule
.GetName());
74 void SwUndoInsNum::UndoImpl(::sw::UndoRedoContext
& rContext
)
76 SwDoc
& rDoc
= rContext
.GetDoc();
79 rDoc
.ChgNumRuleFormats( *m_pOldNumRule
);
85 // Update immediately so that potential "old" LRSpaces will be valid again.
86 m_pHistory
->TmpRollback( &rDoc
, m_nLRSavePos
);
89 m_pHistory
->TmpRollback( &rDoc
, 0 );
90 m_pHistory
->SetTmpEnd( m_pHistory
->Count() );
95 AddUndoRedoPaM(rContext
);
99 void SwUndoInsNum::RedoImpl(::sw::UndoRedoContext
& rContext
)
101 SwDoc
& rDoc
= rContext
.GetDoc();
104 rDoc
.ChgNumRuleFormats( m_aNumRule
);
105 else if ( m_pHistory
)
107 SwPaM
& rPam( AddUndoRedoPaM(rContext
) );
108 if( !m_sReplaceRule
.isEmpty() )
110 rDoc
.ReplaceNumRule( *rPam
.GetPoint(), m_sReplaceRule
, m_aNumRule
.GetName() );
114 // #i42921# - adapt to changed signature
115 rDoc
.SetNumRule(rPam
, m_aNumRule
, false);
120 void SwUndoInsNum::SetLRSpaceEndPos()
123 m_nLRSavePos
= m_pHistory
->Count();
126 void SwUndoInsNum::RepeatImpl(::sw::RepeatContext
& rContext
)
128 SwDoc
& rDoc( rContext
.GetDoc() );
131 if( m_sReplaceRule
.isEmpty() )
133 // #i42921# - adapt to changed signature
134 rDoc
.SetNumRule(rContext
.GetRepeatPaM(), m_aNumRule
, false);
139 rDoc
.ChgNumRuleFormats( m_aNumRule
);
143 SwHistory
* SwUndoInsNum::GetHistory()
146 m_pHistory
.reset(new SwHistory
);
147 return m_pHistory
.get();
150 void SwUndoInsNum::SaveOldNumRule( const SwNumRule
& rOld
)
153 m_pOldNumRule
.reset(new SwNumRule( rOld
));
156 SwUndoDelNum::SwUndoDelNum( const SwPaM
& rPam
)
157 : SwUndo( SwUndoId::DELNUM
, &rPam
.GetDoc() ), SwUndRng( rPam
)
159 if (m_nEndNode
> m_nSttNode
)
160 m_aNodes
.reserve( std::min
<sal_Int32
>(sal_Int32(m_nEndNode
- m_nSttNode
), 255) );
161 m_pHistory
.reset( new SwHistory
);
164 SwUndoDelNum::~SwUndoDelNum()
168 void SwUndoDelNum::UndoImpl(::sw::UndoRedoContext
& rContext
)
170 SwDoc
& rDoc
= rContext
.GetDoc();
172 m_pHistory
->TmpRollback( &rDoc
, 0 );
173 m_pHistory
->SetTmpEnd( m_pHistory
->Count() );
175 for( const auto& rNode
: m_aNodes
)
177 SwTextNode
* pNd
= rDoc
.GetNodes()[ rNode
.index
]->GetTextNode();
178 OSL_ENSURE( pNd
, "Where has the TextNode gone?" );
179 pNd
->SetAttrListLevel( rNode
.level
);
181 if( pNd
->GetCondFormatColl() )
185 AddUndoRedoPaM(rContext
);
188 void SwUndoDelNum::RedoImpl(::sw::UndoRedoContext
& rContext
)
190 SwPaM
& rPam( AddUndoRedoPaM(rContext
) );
191 rContext
.GetDoc().DelNumRules(rPam
);
194 void SwUndoDelNum::RepeatImpl(::sw::RepeatContext
& rContext
)
196 rContext
.GetDoc().DelNumRules(rContext
.GetRepeatPaM());
199 void SwUndoDelNum::AddNode( const SwTextNode
& rNd
)
201 if( rNd
.GetNumRule() )
203 m_aNodes
.emplace_back( rNd
.GetIndex(), rNd
.GetActualListLevel() );
207 SwUndoMoveNum::SwUndoMoveNum( const SwPaM
& rPam
, SwNodeOffset nOff
, bool bIsOutlMv
)
208 : SwUndo( bIsOutlMv
? SwUndoId::OUTLINE_UD
: SwUndoId::MOVENUM
, &rPam
.GetDoc() ),
210 m_nNewStart( 0 ), m_nOffset( nOff
)
212 // nOffset: Down => 1
216 void SwUndoMoveNum::UndoImpl(::sw::UndoRedoContext
& rContext
)
218 SwNodeOffset nTmpStt
= m_nSttNode
, nTmpEnd
= m_nEndNode
;
220 if (m_nEndNode
|| m_nEndContent
!= COMPLETE_STRING
) // section?
222 if( m_nNewStart
< m_nSttNode
) // moved forwards
223 m_nEndNode
= m_nEndNode
- ( m_nSttNode
- m_nNewStart
);
225 m_nEndNode
= m_nEndNode
+ ( m_nNewStart
- m_nSttNode
);
227 m_nSttNode
= m_nNewStart
;
229 SwPaM
& rPam( AddUndoRedoPaM(rContext
) );
230 rContext
.GetDoc().MoveParagraph( rPam
, -m_nOffset
,
231 SwUndoId::OUTLINE_UD
== GetId() );
232 m_nSttNode
= nTmpStt
;
233 m_nEndNode
= nTmpEnd
;
236 void SwUndoMoveNum::RedoImpl(::sw::UndoRedoContext
& rContext
)
238 SwPaM
& rPam( AddUndoRedoPaM(rContext
) );
239 rContext
.GetDoc().MoveParagraph(rPam
, m_nOffset
, SwUndoId::OUTLINE_UD
== GetId());
242 void SwUndoMoveNum::RepeatImpl(::sw::RepeatContext
& rContext
)
244 SwDoc
& rDoc
= rContext
.GetDoc();
245 if( SwUndoId::OUTLINE_UD
== GetId() )
247 rDoc
.MoveOutlinePara(rContext
.GetRepeatPaM(),
248 SwNodeOffset(0) < m_nOffset
? 1 : -1 );
252 rDoc
.MoveParagraph(rContext
.GetRepeatPaM(), m_nOffset
);
256 SwUndoNumUpDown::SwUndoNumUpDown( const SwPaM
& rPam
, short nOff
)
257 : SwUndo( nOff
> 0 ? SwUndoId::NUMUP
: SwUndoId::NUMDOWN
, &rPam
.GetDoc() ),
261 // nOffset: Down => 1
265 void SwUndoNumUpDown::UndoImpl(::sw::UndoRedoContext
& rContext
)
267 SwPaM
& rPam( AddUndoRedoPaM(rContext
) );
268 rContext
.GetDoc().NumUpDown(rPam
, 1 != m_nOffset
);
271 void SwUndoNumUpDown::RedoImpl(::sw::UndoRedoContext
& rContext
)
273 SwPaM
& rPam( AddUndoRedoPaM(rContext
) );
274 rContext
.GetDoc().NumUpDown(rPam
, 1 == m_nOffset
);
277 void SwUndoNumUpDown::RepeatImpl(::sw::RepeatContext
& rContext
)
279 rContext
.GetDoc().NumUpDown(rContext
.GetRepeatPaM(), 1 == m_nOffset
);
282 SwUndoNumOrNoNum::SwUndoNumOrNoNum( const SwNode
& rIdx
, bool bOldNum
,
284 : SwUndo( SwUndoId::NUMORNONUM
, &rIdx
.GetDoc() ),
285 m_nIndex( rIdx
.GetIndex() ), mbNewNum(bNewNum
),
290 // #115901#, #i40034#
291 void SwUndoNumOrNoNum::UndoImpl(::sw::UndoRedoContext
& rContext
)
293 SwNodeIndex
aIdx( rContext
.GetDoc().GetNodes(), m_nIndex
);
294 SwTextNode
* pTextNd
= aIdx
.GetNode().GetTextNode();
296 if (nullptr != pTextNd
)
298 pTextNd
->SetCountedInList(mbOldNum
);
302 // #115901#, #i40034#
303 void SwUndoNumOrNoNum::RedoImpl(::sw::UndoRedoContext
& rContext
)
305 SwNodeIndex
aIdx( rContext
.GetDoc().GetNodes(), m_nIndex
);
306 SwTextNode
* pTextNd
= aIdx
.GetNode().GetTextNode();
308 if (nullptr != pTextNd
)
310 pTextNd
->SetCountedInList(mbNewNum
);
314 void SwUndoNumOrNoNum::RepeatImpl(::sw::RepeatContext
& rContext
)
316 SwDoc
& rDoc
= rContext
.GetDoc();
317 if (mbOldNum
&& ! mbNewNum
)
319 rDoc
.NumOrNoNum(rContext
.GetRepeatPaM().GetPoint()->GetNode());
321 else if ( ! mbOldNum
&& mbNewNum
)
323 rDoc
.NumOrNoNum(rContext
.GetRepeatPaM().GetPoint()->GetNode(), true);
327 SwUndoNumRuleStart::SwUndoNumRuleStart( const SwPosition
& rPos
, bool bFlg
)
328 : SwUndo( SwUndoId::SETNUMRULESTART
, &rPos
.GetDoc() ),
329 m_nIndex( rPos
.GetNodeIndex() ), m_nOldStart( USHRT_MAX
),
330 m_nNewStart( USHRT_MAX
), m_bSetStartValue( false ), m_bFlag( bFlg
)
334 SwUndoNumRuleStart::SwUndoNumRuleStart( const SwPosition
& rPos
, sal_uInt16 nStt
)
335 : SwUndo(SwUndoId::SETNUMRULESTART
, &rPos
.GetDoc())
336 , m_nIndex(rPos
.GetNodeIndex())
337 , m_nOldStart(USHRT_MAX
)
339 , m_bSetStartValue(true)
342 SwTextNode
* pTextNd
= rPos
.GetNode().GetTextNode();
345 if ( pTextNd
->HasAttrListRestartValue() )
347 m_nOldStart
= o3tl::narrowing
<sal_uInt16
>(pTextNd
->GetAttrListRestartValue());
351 m_nOldStart
= USHRT_MAX
; // indicating, that the list restart value is not set
356 void SwUndoNumRuleStart::UndoImpl(::sw::UndoRedoContext
& rContext
)
358 SwDoc
& rDoc
= rContext
.GetDoc();
359 SwPosition
const aPos( *rDoc
.GetNodes()[ m_nIndex
] );
360 if( m_bSetStartValue
)
362 rDoc
.SetNodeNumStart( aPos
, m_nOldStart
);
366 rDoc
.SetNumRuleStart( aPos
, !m_bFlag
);
370 void SwUndoNumRuleStart::RedoImpl(::sw::UndoRedoContext
& rContext
)
372 SwDoc
& rDoc
= rContext
.GetDoc();
373 SwPosition
const aPos( *rDoc
.GetNodes()[ m_nIndex
] );
374 if( m_bSetStartValue
)
376 rDoc
.SetNodeNumStart( aPos
, m_nNewStart
);
380 rDoc
.SetNumRuleStart( aPos
, m_bFlag
);
384 void SwUndoNumRuleStart::RepeatImpl(::sw::RepeatContext
& rContext
)
386 SwDoc
& rDoc
= rContext
.GetDoc();
387 if( m_bSetStartValue
)
389 rDoc
.SetNodeNumStart(*rContext
.GetRepeatPaM().GetPoint(), m_nNewStart
);
393 rDoc
.SetNumRuleStart(*rContext
.GetRepeatPaM().GetPoint(), m_bFlag
);
397 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */