nss: upgrade to release 3.73
[LibreOffice.git] / sw / source / core / SwNumberTree / SwNodeNum.cxx
blobc433a4e36351d5ed24426a505fc5ee39f1acbd9a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <osl/diagnose.h>
21 #include <svl/stritem.hxx>
22 #include <numrule.hxx>
23 #include <SwNodeNum.hxx>
24 #include <ndtxt.hxx>
25 #include <pam.hxx>
26 #include <IDocumentListItems.hxx>
27 #include <doc.hxx>
29 SwNodeNum::SwNodeNum(SwTextNode* pTextNode, bool const isHiddenRedlines)
30 : mpTextNode( pTextNode )
31 , mpNumRule( nullptr )
32 , m_isHiddenRedlines(isHiddenRedlines)
36 SwNodeNum::SwNodeNum( SwNumRule* pNumRule )
37 : mpTextNode( nullptr )
38 , mpNumRule( pNumRule )
39 , m_isHiddenRedlines(false)
43 SwNodeNum::~SwNodeNum()
48 void SwNodeNum::ChangeNumRule( SwNumRule& rNumRule )
50 OSL_ENSURE( GetNumRule() && GetTextNode(),
51 "<SwNodeNum::ChangeNumRule(..)> - missing list style and/or text node. Serious defect -> please inform OD." );
52 if ( GetNumRule() && GetTextNode() )
54 GetNumRule()->RemoveTextNode( *(GetTextNode()) );
57 mpNumRule = &rNumRule;
59 if ( GetNumRule() && GetTextNode() )
61 GetNumRule()->AddTextNode( *(GetTextNode()) );
65 SwPosition SwNodeNum::GetPosition() const
67 OSL_ENSURE( GetTextNode(),
68 "<SwNodeNum::GetPosition()> - no text node set at <SwNodeNum> instance" );
69 return SwPosition(*mpTextNode);
72 SwNumberTreeNode * SwNodeNum::Create() const
74 SwNodeNum * pResult = new SwNodeNum( GetNumRule() );
76 return pResult;
79 void SwNodeNum::PreAdd()
81 OSL_ENSURE( GetTextNode(),
82 "<SwNodeNum::PreAdd()> - no text node set at <SwNodeNum> instance" );
83 if ( !GetNumRule() && GetTextNode() )
85 mpNumRule = GetTextNode()->GetNumRule();
87 OSL_ENSURE( GetNumRule(),
88 "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" );
89 if (!m_isHiddenRedlines && GetNumRule() && GetTextNode())
91 GetNumRule()->AddTextNode( *(GetTextNode()) );
94 if (!m_isHiddenRedlines)
96 if ( GetTextNode() &&
97 GetTextNode()->GetNodes().IsDocNodes() )
99 GetTextNode()->getIDocumentListItems().addListItem( *this );
104 void SwNodeNum::PostRemove()
106 OSL_ENSURE( GetTextNode(),
107 "<SwNodeNum::PostRemove()> - no text node set at <SwNodeNum> instance" );
108 OSL_ENSURE( GetNumRule(),
109 "<SwNodeNum::PostRemove()> - no list style set at <SwNodeNum> instance" );
111 if (!m_isHiddenRedlines && GetTextNode())
113 GetTextNode()->getIDocumentListItems().removeListItem( *this );
116 if ( GetNumRule() )
118 if (!m_isHiddenRedlines && GetTextNode())
120 GetNumRule()->RemoveTextNode( *(GetTextNode()) );
122 mpNumRule = nullptr;
126 bool SwNodeNum::IsNotifiable() const
128 bool aResult = true;
130 if ( GetTextNode() )
131 aResult = GetTextNode()->IsNotifiable();
133 return aResult;
136 bool SwNodeNum::IsNotificationEnabled() const
138 bool aResult = true;
140 if ( GetTextNode() )
141 aResult = GetTextNode()->IsNotificationEnabled();
143 return aResult;
146 bool SwNodeNum::IsContinuous() const
148 bool aResult = false;
150 // #i64311#
151 if ( GetNumRule() )
153 aResult = mpNumRule->IsContinusNum();
155 else if ( GetParent() )
157 aResult = GetParent()->IsContinuous();
159 else
161 OSL_FAIL( "<SwNodeNum::IsContinuous()> - OD debug" );
164 return aResult;
167 bool SwNodeNum::IsCounted() const
169 bool aResult = false;
171 if ( GetTextNode() )
173 // #i59559#
174 // <SwTextNode::IsCounted()> determines, if a text node is counted for numbering
175 aResult = GetTextNode()->IsCountedInList();
177 else
178 aResult = SwNumberTreeNode::IsCounted();
180 return aResult;
183 // #i64010#
184 bool SwNodeNum::HasCountedChildren() const
186 return std::any_of(mChildren.begin(), mChildren.end(),
187 [](SwNumberTreeNode* pNode) {
188 SwNodeNum* pChild( dynamic_cast<SwNodeNum*>(pNode) );
189 OSL_ENSURE( pChild, "<SwNodeNum::HasCountedChildren()> - unexpected type of child" );
190 return pChild && (pChild->IsCountedForNumbering() || pChild->HasCountedChildren());
193 // #i64010#
194 bool SwNodeNum::IsCountedForNumbering() const
196 return IsCounted() &&
197 ( IsPhantom() || // phantoms
198 !GetTextNode() || // root node
199 GetTextNode()->HasNumber() || // text node
200 GetTextNode()->HasBullet() ); // text node
203 void SwNodeNum::NotifyNode()
205 ValidateMe();
207 if (mpTextNode)
209 mpTextNode->NumRuleChgd();
213 bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
215 bool bResult = false;
216 const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);
218 if (mpTextNode == nullptr && rTmpNode.mpTextNode != nullptr)
219 bResult = true;
220 else if (mpTextNode != nullptr && rTmpNode.mpTextNode != nullptr)
222 // #i83479# - refactoring
223 // simplify comparison by comparing the indexes of the text nodes
224 bResult = ( mpTextNode->GetIndex() < rTmpNode.mpTextNode->GetIndex() );
227 return bResult;
230 bool SwNodeNum::IsRestart() const
232 bool bIsRestart = false;
234 if ( GetTextNode() )
236 bIsRestart = GetTextNode()->IsListRestart();
239 return bIsRestart;
242 bool SwNodeNum::IsCountPhantoms() const
244 bool bResult = true;
246 // #i64311#
247 // phantoms aren't counted in consecutive numbering rules
248 if ( mpNumRule )
249 bResult = !mpNumRule->IsContinusNum() &&
250 mpNumRule->IsCountPhantoms();
251 else
253 OSL_FAIL( "<SwNodeNum::IsCountPhantoms(): missing numbering rule" );
256 return bResult;
259 SwNumberTree::tSwNumTreeNumber SwNodeNum::GetStartValue() const
261 SwNumberTree::tSwNumTreeNumber aResult = 1;
263 if ( IsRestart() && GetTextNode() )
265 aResult = GetTextNode()->GetActualListStartValue();
267 else
269 SwNumRule * pRule = GetNumRule();
271 if (pRule)
273 int nLevel = GetParent() ? GetLevelInListTree() : 0;
275 if (nLevel >= 0 && nLevel < MAXLEVEL)
277 const SwNumFormat * pFormat = pRule->GetNumFormat( static_cast<sal_uInt16>(nLevel));
279 if (pFormat)
280 aResult = pFormat->GetStart();
285 return aResult;
288 void SwNodeNum::HandleNumberTreeRootNodeDelete( SwNodeNum& rNodeNum )
290 SwNodeNum* pRootNode = rNodeNum.GetParent()
291 ? dynamic_cast<SwNodeNum*>(rNodeNum.GetRoot())
292 : &rNodeNum;
293 if ( !pRootNode )
295 // no root node -> nothing do.
296 return;
299 // unregister all number tree node entries, which correspond to a text node,
300 // about the deletion of the number tree root node.
301 UnregisterMeAndChildrenDueToRootDelete( *pRootNode );
304 void SwNodeNum::UnregisterMeAndChildrenDueToRootDelete( SwNodeNum& rNodeNum )
306 const bool bIsPhantom( rNodeNum.IsPhantom() );
307 tSwNumberTreeChildren::size_type nAllowedChildCount( 0 );
308 bool bDone( false );
309 while ( !bDone &&
310 rNodeNum.GetChildCount() > nAllowedChildCount )
312 SwNodeNum* pChildNode( dynamic_cast<SwNodeNum*>((*rNodeNum.mChildren.begin())) );
313 if ( !pChildNode )
315 OSL_FAIL( "<SwNodeNum::UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
316 ++nAllowedChildCount;
317 continue;
320 // Unregistering the last child of a phantom will destroy the phantom.
321 // Thus <rNodeNum> will be destroyed and access on <rNodeNum> has to
322 // be suppressed.
323 if ( bIsPhantom && rNodeNum.GetChildCount() == 1 )
325 bDone = true;
328 UnregisterMeAndChildrenDueToRootDelete( *pChildNode );
331 if ( bIsPhantom )
332 return;
334 SwTextNode* pTextNode( rNodeNum.GetTextNode() );
335 if ( !pTextNode )
336 return;
338 pTextNode->RemoveFromList();
339 // --> clear all list attributes and the list style
340 o3tl::sorted_vector<sal_uInt16> aResetAttrsArray;
341 aResetAttrsArray.insert( RES_PARATR_LIST_ID );
342 aResetAttrsArray.insert( RES_PARATR_LIST_LEVEL );
343 aResetAttrsArray.insert( RES_PARATR_LIST_ISRESTART );
344 aResetAttrsArray.insert( RES_PARATR_LIST_RESTARTVALUE );
345 aResetAttrsArray.insert( RES_PARATR_LIST_ISCOUNTED );
346 aResetAttrsArray.insert( RES_PARATR_NUMRULE );
347 SwPaM aPam( *pTextNode );
348 pTextNode->GetDoc().ResetAttrs( aPam, false,
349 aResetAttrsArray,
350 false );
353 // #i81002#
354 const SwNodeNum* SwNodeNum::GetPrecedingNodeNumOf( const SwTextNode& rTextNode ) const
356 const SwNodeNum* pPrecedingNodeNum( nullptr );
358 // #i83479#
359 SwNodeNum aNodeNumForTextNode( const_cast<SwTextNode*>(&rTextNode), false/*doesn't matter*/ );
361 pPrecedingNodeNum = dynamic_cast<const SwNodeNum*>(
362 GetRoot()
363 ? GetRoot()->GetPrecedingNodeOf( aNodeNumForTextNode )
364 : GetPrecedingNodeOf( aNodeNumForTextNode ) );
366 return pPrecedingNodeNum;
369 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */