docthemes: Save themes def. to a file when added to ColorSets
[LibreOffice.git] / sw / source / core / SwNumberTree / SwNodeNum.cxx
blob9c160d3c0fc21c0d1deecba37a7726755e0bfe07
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 <numrule.hxx>
22 #include <SwNodeNum.hxx>
23 #include <ndtxt.hxx>
24 #include <pam.hxx>
25 #include <IDocumentListItems.hxx>
26 #include <doc.hxx>
28 SwNodeNum::SwNodeNum(SwTextNode* pTextNode, bool const isHiddenRedlines)
29 : mpTextNode( pTextNode )
30 , mpNumRule( nullptr )
31 , m_isHiddenRedlines(isHiddenRedlines)
35 SwNodeNum::SwNodeNum( SwNumRule* pNumRule )
36 : mpTextNode( nullptr )
37 , mpNumRule( pNumRule )
38 , m_isHiddenRedlines(false)
42 SwNodeNum::~SwNodeNum()
47 void SwNodeNum::ChangeNumRule( SwNumRule& rNumRule )
49 OSL_ENSURE( GetNumRule() && GetTextNode(),
50 "<SwNodeNum::ChangeNumRule(..)> - missing list style and/or text node. Serious defect -> please inform OD." );
51 if ( GetNumRule() && GetTextNode() )
53 GetNumRule()->RemoveTextNode( *(GetTextNode()) );
56 mpNumRule = &rNumRule;
58 if ( GetNumRule() && GetTextNode() )
60 GetNumRule()->AddTextNode( *(GetTextNode()) );
64 SwPosition SwNodeNum::GetPosition() const
66 OSL_ENSURE( GetTextNode(),
67 "<SwNodeNum::GetPosition()> - no text node set at <SwNodeNum> instance" );
68 return SwPosition(*mpTextNode);
71 SwNumberTreeNode * SwNodeNum::Create() const
73 SwNodeNum * pResult = new SwNodeNum( GetNumRule() );
75 return pResult;
78 void SwNodeNum::PreAdd()
80 OSL_ENSURE( GetTextNode(),
81 "<SwNodeNum::PreAdd()> - no text node set at <SwNodeNum> instance" );
82 if ( !GetNumRule() && GetTextNode() )
84 mpNumRule = GetTextNode()->GetNumRule();
86 OSL_ENSURE( GetNumRule(),
87 "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" );
88 if (!m_isHiddenRedlines && GetNumRule() && GetTextNode())
90 GetNumRule()->AddTextNode( *(GetTextNode()) );
93 if (!m_isHiddenRedlines)
95 if ( GetTextNode() &&
96 GetTextNode()->GetNodes().IsDocNodes() )
98 GetTextNode()->getIDocumentListItems().addListItem( *this );
103 void SwNodeNum::PostRemove()
105 OSL_ENSURE( GetTextNode(),
106 "<SwNodeNum::PostRemove()> - no text node set at <SwNodeNum> instance" );
107 OSL_ENSURE( GetNumRule(),
108 "<SwNodeNum::PostRemove()> - no list style set at <SwNodeNum> instance" );
110 if (!m_isHiddenRedlines && GetTextNode())
112 GetTextNode()->getIDocumentListItems().removeListItem( *this );
115 if ( GetNumRule() )
117 if (!m_isHiddenRedlines && GetTextNode())
119 GetNumRule()->RemoveTextNode( *(GetTextNode()) );
121 mpNumRule = nullptr;
125 bool SwNodeNum::IsNotifiable(const SwDoc& rDoc) const
127 bool aResult;
129 if (const SwTextNode* pTextNode = GetTextNode())
130 aResult = pTextNode->IsNotifiable();
131 else
132 aResult = IsNotificationEnabled(rDoc);
134 return aResult;
137 bool SwNodeNum::IsNotificationEnabled(const SwDoc& rDoc) const
139 bool aResult;
141 if (const SwTextNode* pTextNode = GetTextNode())
142 aResult = pTextNode->IsNotificationEnabled();
143 else
144 aResult = !rDoc.IsInReading() && !rDoc.IsInDtor();
146 return aResult;
149 bool SwNodeNum::IsContinuous() const
151 bool aResult = false;
153 // #i64311#
154 if ( GetNumRule() )
156 aResult = mpNumRule->IsContinusNum();
158 else if ( GetParent() )
160 aResult = GetParent()->IsContinuous();
162 else
164 OSL_FAIL( "<SwNodeNum::IsContinuous()> - OD debug" );
167 return aResult;
170 bool SwNodeNum::IsCounted() const
172 bool aResult = false;
174 if ( GetTextNode() )
176 // #i59559#
177 // <SwTextNode::IsCounted()> determines, if a text node is counted for numbering
178 aResult = GetTextNode()->IsCountedInList();
180 else
181 aResult = SwNumberTreeNode::IsCounted();
183 return aResult;
186 // #i64010#
187 bool SwNodeNum::HasCountedChildren() const
189 return std::any_of(mChildren.begin(), mChildren.end(),
190 [](SwNumberTreeNode* pNode) {
191 SwNodeNum* pChild( dynamic_cast<SwNodeNum*>(pNode) );
192 OSL_ENSURE( pChild, "<SwNodeNum::HasCountedChildren()> - unexpected type of child" );
193 return pChild && (pChild->IsCountedForNumbering() || pChild->HasCountedChildren());
196 // #i64010#
197 bool SwNodeNum::IsCountedForNumbering() const
199 return IsCounted() &&
200 ( IsPhantom() || // phantoms
201 !GetTextNode() || // root node
202 GetTextNode()->HasNumber() || // text node
203 GetTextNode()->HasBullet() ); // text node
206 void SwNodeNum::NotifyNode()
208 ValidateMe();
210 if (mpTextNode)
212 mpTextNode->NumRuleChgd();
216 bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
218 bool bResult = false;
219 const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);
221 if (mpTextNode == nullptr && rTmpNode.mpTextNode != nullptr)
222 bResult = true;
223 else if (mpTextNode != nullptr && rTmpNode.mpTextNode != nullptr)
225 // #i83479# - refactoring
226 // simplify comparison by comparing the indexes of the text nodes
227 bResult = ( mpTextNode->GetIndex() < rTmpNode.mpTextNode->GetIndex() );
230 return bResult;
233 bool SwNodeNum::IsRestart() const
235 bool bIsRestart = false;
237 if ( GetTextNode() )
239 bIsRestart = GetTextNode()->IsListRestart();
242 return bIsRestart;
245 bool SwNodeNum::IsCountPhantoms() const
247 bool bResult = true;
249 // #i64311#
250 // phantoms aren't counted in consecutive numbering rules
251 if ( mpNumRule )
252 bResult = !mpNumRule->IsContinusNum() &&
253 mpNumRule->IsCountPhantoms();
254 else
256 OSL_FAIL( "<SwNodeNum::IsCountPhantoms(): missing numbering rule" );
259 return bResult;
262 SwNumberTree::tSwNumTreeNumber SwNodeNum::GetStartValue() const
264 SwNumberTree::tSwNumTreeNumber aResult = 1;
266 if ( IsRestart() && GetTextNode() )
268 aResult = GetTextNode()->GetActualListStartValue();
270 else
272 SwNumRule * pRule = GetNumRule();
274 if (pRule)
276 int nLevel = GetParent() ? GetLevelInListTree() : 0;
278 if (nLevel >= 0 && nLevel < MAXLEVEL)
280 const SwNumFormat * pFormat = pRule->GetNumFormat( o3tl::narrowing<sal_uInt16>(nLevel));
282 if (pFormat)
283 aResult = pFormat->GetStart();
288 return aResult;
291 void SwNodeNum::HandleNumberTreeRootNodeDelete( SwNodeNum& rNodeNum )
293 SwNodeNum* pRootNode = rNodeNum.GetParent()
294 ? dynamic_cast<SwNodeNum*>(rNodeNum.GetRoot())
295 : &rNodeNum;
296 if ( !pRootNode )
298 // no root node -> nothing do.
299 return;
302 // unregister all number tree node entries, which correspond to a text node,
303 // about the deletion of the number tree root node.
304 UnregisterMeAndChildrenDueToRootDelete( *pRootNode );
307 void SwNodeNum::UnregisterMeAndChildrenDueToRootDelete( SwNodeNum& rNodeNum )
309 const bool bIsPhantom( rNodeNum.IsPhantom() );
310 tSwNumberTreeChildren::size_type nAllowedChildCount( 0 );
311 bool bDone( false );
312 while ( !bDone &&
313 rNodeNum.GetChildCount() > nAllowedChildCount )
315 SwNodeNum* pChildNode( dynamic_cast<SwNodeNum*>((*rNodeNum.mChildren.begin())) );
316 if ( !pChildNode )
318 OSL_FAIL( "<SwNodeNum::UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
319 ++nAllowedChildCount;
320 continue;
323 // Unregistering the last child of a phantom will destroy the phantom.
324 // Thus <rNodeNum> will be destroyed and access on <rNodeNum> has to
325 // be suppressed.
326 if ( bIsPhantom && rNodeNum.GetChildCount() == 1 )
328 bDone = true;
331 UnregisterMeAndChildrenDueToRootDelete( *pChildNode );
334 if ( bIsPhantom )
335 return;
337 SwTextNode* pTextNode( rNodeNum.GetTextNode() );
338 if ( !pTextNode )
339 return;
341 pTextNode->RemoveFromList();
342 // --> clear all list attributes and the list style
343 const o3tl::sorted_vector<sal_uInt16> aResetAttrsArray{
344 RES_PARATR_LIST_ID, RES_PARATR_LIST_LEVEL, RES_PARATR_LIST_ISRESTART,
345 RES_PARATR_LIST_RESTARTVALUE, RES_PARATR_LIST_ISCOUNTED, 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: */