LibreOffice Module sw (master)  1
SwNodeNum.cxx
Go to the documentation of this file.
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 <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>
28 
29 SwNodeNum::SwNodeNum(SwTextNode* pTextNode, bool const isHiddenRedlines)
30  : mpTextNode( pTextNode )
31  , mpNumRule( nullptr )
32  , m_isHiddenRedlines(isHiddenRedlines)
33 {
34 }
35 
37  : mpTextNode( nullptr )
38  , mpNumRule( pNumRule )
39  , m_isHiddenRedlines(false)
40 {
41 }
42 
44 {
45 }
46 
47 
49 {
50  OSL_ENSURE( GetNumRule() && GetTextNode(),
51  "<SwNodeNum::ChangeNumRule(..)> - missing list style and/or text node. Serious defect -> please inform OD." );
52  if ( GetNumRule() && GetTextNode() )
53  {
55  }
56 
57  mpNumRule = &rNumRule;
58 
59  if ( GetNumRule() && GetTextNode() )
60  {
62  }
63 }
64 
66 {
67  OSL_ENSURE( GetTextNode(),
68  "<SwNodeNum::GetPosition()> - no text node set at <SwNodeNum> instance" );
69  return SwPosition(*mpTextNode);
70 }
71 
73 {
74  SwNodeNum * pResult = new SwNodeNum( GetNumRule() );
75 
76  return pResult;
77 }
78 
80 {
81  OSL_ENSURE( GetTextNode(),
82  "<SwNodeNum::PreAdd()> - no text node set at <SwNodeNum> instance" );
83  if ( !GetNumRule() && GetTextNode() )
84  {
86  }
87  OSL_ENSURE( GetNumRule(),
88  "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" );
90  {
92  }
93 
94  if (!m_isHiddenRedlines)
95  {
96  if ( GetTextNode() &&
97  GetTextNode()->GetNodes().IsDocNodes() )
98  {
100  }
101  }
102 }
103 
105 {
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" );
110 
112  {
114  }
115 
116  if ( GetNumRule() )
117  {
119  {
121  }
122  mpNumRule = nullptr;
123  }
124 }
125 
127 {
128  bool aResult = true;
129 
130  if ( GetTextNode() )
131  aResult = GetTextNode()->IsNotifiable();
132 
133  return aResult;
134 }
135 
137 {
138  bool aResult = true;
139 
140  if ( GetTextNode() )
141  aResult = GetTextNode()->IsNotificationEnabled();
142 
143  return aResult;
144 }
145 
147 {
148  bool aResult = false;
149 
150  // #i64311#
151  if ( GetNumRule() )
152  {
153  aResult = mpNumRule->IsContinusNum();
154  }
155  else if ( GetParent() )
156  {
157  aResult = GetParent()->IsContinuous();
158  }
159  else
160  {
161  OSL_FAIL( "<SwNodeNum::IsContinuous()> - OD debug" );
162  }
163 
164  return aResult;
165 }
166 
168 {
169  bool aResult = false;
170 
171  if ( GetTextNode() )
172  {
173  // #i59559#
174  // <SwTextNode::IsCounted()> determines, if a text node is counted for numbering
175  aResult = GetTextNode()->IsCountedInList();
176  }
177  else
178  aResult = SwNumberTreeNode::IsCounted();
179 
180  return aResult;
181 }
182 
183 // #i64010#
185 {
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());
191  });
192 }
193 // #i64010#
195 {
196  return IsCounted() &&
197  ( IsPhantom() || // phantoms
198  !GetTextNode() || // root node
199  GetTextNode()->HasNumber() || // text node
200  GetTextNode()->HasBullet() ); // text node
201 }
202 
204 {
205  ValidateMe();
206 
207  if (mpTextNode)
208  {
210  }
211 }
212 
213 bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
214 {
215  bool bResult = false;
216  const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);
217 
218  if (mpTextNode == nullptr && rTmpNode.mpTextNode != nullptr)
219  bResult = true;
220  else if (mpTextNode != nullptr && rTmpNode.mpTextNode != nullptr)
221  {
222  // #i83479# - refactoring
223  // simplify comparison by comparing the indexes of the text nodes
224  bResult = ( mpTextNode->GetIndex() < rTmpNode.mpTextNode->GetIndex() );
225  }
226 
227  return bResult;
228 }
229 
231 {
232  bool bIsRestart = false;
233 
234  if ( GetTextNode() )
235  {
236  bIsRestart = GetTextNode()->IsListRestart();
237  }
238 
239  return bIsRestart;
240 }
241 
243 {
244  bool bResult = true;
245 
246  // #i64311#
247  // phantoms aren't counted in consecutive numbering rules
248  if ( mpNumRule )
249  bResult = !mpNumRule->IsContinusNum() &&
251  else
252  {
253  OSL_FAIL( "<SwNodeNum::IsCountPhantoms(): missing numbering rule" );
254  }
255 
256  return bResult;
257 }
258 
260 {
261  SwNumberTree::tSwNumTreeNumber aResult = 1;
262 
263  if ( IsRestart() && GetTextNode() )
264  {
265  aResult = GetTextNode()->GetActualListStartValue();
266  }
267  else
268  {
269  SwNumRule * pRule = GetNumRule();
270 
271  if (pRule)
272  {
273  int nLevel = GetParent() ? GetLevelInListTree() : 0;
274 
275  if (nLevel >= 0 && nLevel < MAXLEVEL)
276  {
277  const SwNumFormat * pFormat = pRule->GetNumFormat( static_cast<sal_uInt16>(nLevel));
278 
279  if (pFormat)
280  aResult = pFormat->GetStart();
281  }
282  }
283  }
284 
285  return aResult;
286 }
287 
289 {
290  SwNodeNum* pRootNode = rNodeNum.GetParent()
291  ? dynamic_cast<SwNodeNum*>(rNodeNum.GetRoot())
292  : &rNodeNum;
293  if ( !pRootNode )
294  {
295  // no root node -> nothing do.
296  return;
297  }
298 
299  // unregister all number tree node entries, which correspond to a text node,
300  // about the deletion of the number tree root node.
302 }
303 
305 {
306  const bool bIsPhantom( rNodeNum.IsPhantom() );
307  tSwNumberTreeChildren::size_type nAllowedChildCount( 0 );
308  bool bDone( false );
309  while ( !bDone &&
310  rNodeNum.GetChildCount() > nAllowedChildCount )
311  {
312  SwNodeNum* pChildNode( dynamic_cast<SwNodeNum*>((*rNodeNum.mChildren.begin())) );
313  if ( !pChildNode )
314  {
315  OSL_FAIL( "<SwNodeNum::UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
316  ++nAllowedChildCount;
317  continue;
318  }
319 
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 )
324  {
325  bDone = true;
326  }
327 
329  }
330 
331  if ( bIsPhantom )
332  return;
333 
334  SwTextNode* pTextNode( rNodeNum.GetTextNode() );
335  if ( !pTextNode )
336  return;
337 
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 );
351 }
352 
353 // #i81002#
354 const SwNodeNum* SwNodeNum::GetPrecedingNodeNumOf( const SwTextNode& rTextNode ) const
355 {
356  const SwNodeNum* pPrecedingNodeNum( nullptr );
357 
358  // #i83479#
359  SwNodeNum aNodeNumForTextNode( const_cast<SwTextNode*>(&rTextNode), false/*doesn't matter*/ );
360 
361  pPrecedingNodeNum = dynamic_cast<const SwNodeNum*>(
362  GetRoot()
363  ? GetRoot()->GetPrecedingNodeOf( aNodeNumForTextNode )
364  : GetPrecedingNodeOf( aNodeNumForTextNode ) );
365 
366  return pPrecedingNodeNum;
367 }
368 
369 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void removeListItem(const SwNodeNum &rNodeNum)=0
static void HandleNumberTreeRootNodeDelete(SwNodeNum &rNodeNum)
Definition: SwNodeNum.cxx:288
sal_uLong GetIndex() const
Definition: node.hxx:290
bool HasBullet() const
Returns if this text node has a bullet.
Definition: ndtxt.cxx:3075
SwNodeNum(SwTextNode *pTextNode, bool isHiddenRedlines)
Definition: SwNodeNum.cxx:29
Marks a position in the document model.
Definition: pam.hxx:35
A tree of numbered nodes.
SwTextNode *const mpTextNode
Definition: SwNodeNum.hxx:84
const SwNumberTreeNode * GetPrecedingNodeOf(const SwNumberTreeNode &rNode) const
determines the node, which is preceding the node
virtual void addListItem(const SwNodeNum &rNodeNum)=0
const SwNumFormat * GetNumFormat(sal_uInt16 i) const
Definition: number.cxx:89
constexpr TypedWhichId< SwNumRuleItem > RES_PARATR_NUMRULE(72)
void AddTextNode(SwTextNode &rTextNode)
Definition: number.cxx:133
SwNumberTreeNode * GetParent() const
Returns the parent of this node.
SwPosition GetPosition() const
Definition: SwNodeNum.cxx:65
constexpr TypedWhichId< SfxInt16Item > RES_PARATR_LIST_RESTARTVALUE(85)
IDocumentListItems & getIDocumentListItems()
Provides access to the document's numbered items interface.
Definition: node.cxx:2130
virtual bool IsRestart() const override
Return if numbering is restarted at this node.
Definition: SwNodeNum.cxx:230
virtual bool IsCounted() const override
Return if this node is counted.
Definition: SwNodeNum.cxx:167
bool m_isHiddenRedlines
Definition: SwNodeNum.hxx:86
virtual SwNumberTree::tSwNumTreeNumber GetStartValue() const override
Return start value.
Definition: SwNodeNum.cxx:259
bool HasNumber() const
Returns if this text node has a number.
Definition: ndtxt.cxx:3058
bool IsListRestart() const
Definition: ndtxt.cxx:4105
SwTextNode * GetTextNode() const
Definition: SwNodeNum.hxx:40
virtual bool IsNotifiable() const override
Return if this node is notifiable.
Definition: SwNodeNum.cxx:126
int GetLevelInListTree() const
Return level of this node.
constexpr TypedWhichId< SfxBoolItem > RES_PARATR_LIST_ISRESTART(84)
SwNumberTreeNode * GetRoot() const
Returns the root node of the tree this node is part of.
constexpr TypedWhichId< SfxInt16Item > RES_PARATR_LIST_LEVEL(83)
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
tSwNumberTreeChildren mChildren
the children
virtual bool IsNotificationEnabled() const override
Return if the notification is not disabled on global conditions.
Definition: SwNodeNum.cxx:136
bool IsContinusNum() const
Definition: numrule.hxx:234
virtual void PostRemove() override
Definition: SwNodeNum.cxx:104
virtual bool LessThan(const SwNumberTreeNode &rNode) const override
Returns if this node is less than another node.
Definition: SwNodeNum.cxx:213
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
void RemoveFromList()
Definition: ndtxt.cxx:4299
bool IsCountPhantoms() const
Definition: numrule.hxx:242
SwNumRule * mpNumRule
Definition: SwNodeNum.hxx:85
bool IsPhantom() const
Return if this node is a phantom.
SwNumRule * GetNumRule() const
Definition: SwNodeNum.hxx:38
SwNumberTree::tSwNumTreeNumber GetActualListStartValue() const
Definition: ndtxt.cxx:4169
tools::Long tSwNumTreeNumber
void RemoveTextNode(SwTextNode &rTextNode)
Definition: number.cxx:144
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2776
virtual bool IsContinuous() const =0
Return if this node is counted continuous.
sal_uInt16 GetStart() const
virtual bool HasCountedChildren() const override
Definition: SwNodeNum.cxx:184
void ValidateMe()
Validates this node.
virtual void NotifyNode() override
Notifies the node.
Definition: SwNodeNum.cxx:203
virtual ~SwNodeNum() override
Definition: SwNodeNum.cxx:43
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
virtual bool IsCountedForNumbering() const override
Definition: SwNodeNum.cxx:194
virtual bool IsContinuous() const override
Return if this node is counted continuous.
Definition: SwNodeNum.cxx:146
bool IsCountedInList() const
Definition: ndtxt.cxx:4220
constexpr TypedWhichId< SfxBoolItem > RES_PARATR_LIST_ISCOUNTED(86)
tSwNumberTreeChildren::size_type GetChildCount() const
Returns how many children this node has got.
void ChangeNumRule(SwNumRule &rNumRule)
Definition: SwNodeNum.cxx:48
const SwNodeNum * GetPrecedingNodeNumOf(const SwTextNode &rTextNode) const
determines the instance, which is preceding the given text node
Definition: SwNodeNum.cxx:354
void NumRuleChgd()
Notify this textnode that its numbering rule has changed.
Definition: ndtxt.cxx:2816
virtual bool IsCounted() const
Return if this node is counted.
std::pair< const_iterator, bool > insert(Value &&x)
bool IsNotifiable() const
Checks a temporary notification blocker and the global conditions of IsNotificationEnabled() ...
Definition: ndtxt.cxx:4194
virtual void PreAdd() override
Definition: SwNodeNum.cxx:79
virtual SwNumberTreeNode * Create() const override
Creates a new node of the same class.
Definition: SwNodeNum.cxx:72
bool IsNotificationEnabled() const
Checks some global conditions like loading or destruction of document to economize notifications...
Definition: ndtxt.cxx:4199
virtual bool IsCountPhantoms() const override
Return if phantoms are counted.
Definition: SwNodeNum.cxx:242
constexpr TypedWhichId< SfxStringItem > RES_PARATR_LIST_ID(RES_PARATR_LIST_BEGIN)
static void UnregisterMeAndChildrenDueToRootDelete(SwNodeNum &rNodeNum)
Definition: SwNodeNum.cxx:304