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 <numrule.hxx>
22 #include <SwNodeNum.hxx>
23 #include <ndtxt.hxx>
24 #include <pam.hxx>
25 #include <IDocumentListItems.hxx>
26 #include <doc.hxx>
27 
28 SwNodeNum::SwNodeNum(SwTextNode* pTextNode, bool const isHiddenRedlines)
29  : mpTextNode( pTextNode )
30  , mpNumRule( nullptr )
31  , m_isHiddenRedlines(isHiddenRedlines)
32 {
33 }
34 
36  : mpTextNode( nullptr )
37  , mpNumRule( pNumRule )
38  , m_isHiddenRedlines(false)
39 {
40 }
41 
43 {
44 }
45 
46 
48 {
49  OSL_ENSURE( GetNumRule() && GetTextNode(),
50  "<SwNodeNum::ChangeNumRule(..)> - missing list style and/or text node. Serious defect -> please inform OD." );
51  if ( GetNumRule() && GetTextNode() )
52  {
54  }
55 
56  mpNumRule = &rNumRule;
57 
58  if ( GetNumRule() && GetTextNode() )
59  {
61  }
62 }
63 
65 {
66  OSL_ENSURE( GetTextNode(),
67  "<SwNodeNum::GetPosition()> - no text node set at <SwNodeNum> instance" );
68  return SwPosition(*mpTextNode);
69 }
70 
72 {
73  SwNodeNum * pResult = new SwNodeNum( GetNumRule() );
74 
75  return pResult;
76 }
77 
79 {
80  OSL_ENSURE( GetTextNode(),
81  "<SwNodeNum::PreAdd()> - no text node set at <SwNodeNum> instance" );
82  if ( !GetNumRule() && GetTextNode() )
83  {
85  }
86  OSL_ENSURE( GetNumRule(),
87  "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" );
89  {
91  }
92 
93  if (!m_isHiddenRedlines)
94  {
95  if ( GetTextNode() &&
96  GetTextNode()->GetNodes().IsDocNodes() )
97  {
99  }
100  }
101 }
102 
104 {
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" );
109 
111  {
113  }
114 
115  if ( GetNumRule() )
116  {
118  {
120  }
121  mpNumRule = nullptr;
122  }
123 }
124 
126 {
127  bool aResult = true;
128 
129  if ( GetTextNode() )
130  aResult = GetTextNode()->IsNotifiable();
131 
132  return aResult;
133 }
134 
136 {
137  bool aResult = true;
138 
139  if ( GetTextNode() )
140  aResult = GetTextNode()->IsNotificationEnabled();
141 
142  return aResult;
143 }
144 
146 {
147  bool aResult = false;
148 
149  // #i64311#
150  if ( GetNumRule() )
151  {
152  aResult = mpNumRule->IsContinusNum();
153  }
154  else if ( GetParent() )
155  {
156  aResult = GetParent()->IsContinuous();
157  }
158  else
159  {
160  OSL_FAIL( "<SwNodeNum::IsContinuous()> - OD debug" );
161  }
162 
163  return aResult;
164 }
165 
167 {
168  bool aResult = false;
169 
170  if ( GetTextNode() )
171  {
172  // #i59559#
173  // <SwTextNode::IsCounted()> determines, if a text node is counted for numbering
174  aResult = GetTextNode()->IsCountedInList();
175  }
176  else
177  aResult = SwNumberTreeNode::IsCounted();
178 
179  return aResult;
180 }
181 
182 // #i64010#
184 {
185  return std::any_of(mChildren.begin(), mChildren.end(),
186  [](SwNumberTreeNode* pNode) {
187  SwNodeNum* pChild( dynamic_cast<SwNodeNum*>(pNode) );
188  OSL_ENSURE( pChild, "<SwNodeNum::HasCountedChildren()> - unexpected type of child" );
189  return pChild && (pChild->IsCountedForNumbering() || pChild->HasCountedChildren());
190  });
191 }
192 // #i64010#
194 {
195  return IsCounted() &&
196  ( IsPhantom() || // phantoms
197  !GetTextNode() || // root node
198  GetTextNode()->HasNumber() || // text node
199  GetTextNode()->HasBullet() ); // text node
200 }
201 
203 {
204  ValidateMe();
205 
206  if (mpTextNode)
207  {
209  }
210 }
211 
212 bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
213 {
214  bool bResult = false;
215  const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);
216 
217  if (mpTextNode == nullptr && rTmpNode.mpTextNode != nullptr)
218  bResult = true;
219  else if (mpTextNode != nullptr && rTmpNode.mpTextNode != nullptr)
220  {
221  // #i83479# - refactoring
222  // simplify comparison by comparing the indexes of the text nodes
223  bResult = ( mpTextNode->GetIndex() < rTmpNode.mpTextNode->GetIndex() );
224  }
225 
226  return bResult;
227 }
228 
230 {
231  bool bIsRestart = false;
232 
233  if ( GetTextNode() )
234  {
235  bIsRestart = GetTextNode()->IsListRestart();
236  }
237 
238  return bIsRestart;
239 }
240 
242 {
243  bool bResult = true;
244 
245  // #i64311#
246  // phantoms aren't counted in consecutive numbering rules
247  if ( mpNumRule )
248  bResult = !mpNumRule->IsContinusNum() &&
250  else
251  {
252  OSL_FAIL( "<SwNodeNum::IsCountPhantoms(): missing numbering rule" );
253  }
254 
255  return bResult;
256 }
257 
259 {
260  SwNumberTree::tSwNumTreeNumber aResult = 1;
261 
262  if ( IsRestart() && GetTextNode() )
263  {
264  aResult = GetTextNode()->GetActualListStartValue();
265  }
266  else
267  {
268  SwNumRule * pRule = GetNumRule();
269 
270  if (pRule)
271  {
272  int nLevel = GetParent() ? GetLevelInListTree() : 0;
273 
274  if (nLevel >= 0 && nLevel < MAXLEVEL)
275  {
276  const SwNumFormat * pFormat = pRule->GetNumFormat( static_cast<sal_uInt16>(nLevel));
277 
278  if (pFormat)
279  aResult = pFormat->GetStart();
280  }
281  }
282  }
283 
284  return aResult;
285 }
286 
288 {
289  SwNodeNum* pRootNode = rNodeNum.GetParent()
290  ? dynamic_cast<SwNodeNum*>(rNodeNum.GetRoot())
291  : &rNodeNum;
292  if ( !pRootNode )
293  {
294  // no root node -> nothing do.
295  return;
296  }
297 
298  // unregister all number tree node entries, which correspond to a text node,
299  // about the deletion of the number tree root node.
301 }
302 
304 {
305  const bool bIsPhantom( rNodeNum.IsPhantom() );
306  tSwNumberTreeChildren::size_type nAllowedChildCount( 0 );
307  bool bDone( false );
308  while ( !bDone &&
309  rNodeNum.GetChildCount() > nAllowedChildCount )
310  {
311  SwNodeNum* pChildNode( dynamic_cast<SwNodeNum*>((*rNodeNum.mChildren.begin())) );
312  if ( !pChildNode )
313  {
314  OSL_FAIL( "<SwNodeNum::UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
315  ++nAllowedChildCount;
316  continue;
317  }
318 
319  // Unregistering the last child of a phantom will destroy the phantom.
320  // Thus <rNodeNum> will be destroyed and access on <rNodeNum> has to
321  // be suppressed.
322  if ( bIsPhantom && rNodeNum.GetChildCount() == 1 )
323  {
324  bDone = true;
325  }
326 
328  }
329 
330  if ( bIsPhantom )
331  return;
332 
333  SwTextNode* pTextNode( rNodeNum.GetTextNode() );
334  if ( !pTextNode )
335  return;
336 
337  pTextNode->RemoveFromList();
338  // --> clear all list attributes and the list style
339  const o3tl::sorted_vector<sal_uInt16> aResetAttrsArray{
342  };
343  SwPaM aPam( *pTextNode );
344  pTextNode->GetDoc().ResetAttrs( aPam, false,
345  aResetAttrsArray,
346  false );
347 }
348 
349 // #i81002#
350 const SwNodeNum* SwNodeNum::GetPrecedingNodeNumOf( const SwTextNode& rTextNode ) const
351 {
352  const SwNodeNum* pPrecedingNodeNum( nullptr );
353 
354  // #i83479#
355  SwNodeNum aNodeNumForTextNode( const_cast<SwTextNode*>(&rTextNode), false/*doesn't matter*/ );
356 
357  pPrecedingNodeNum = dynamic_cast<const SwNodeNum*>(
358  GetRoot()
359  ? GetRoot()->GetPrecedingNodeOf( aNodeNumForTextNode )
360  : GetPrecedingNodeOf( aNodeNumForTextNode ) );
361 
362  return pPrecedingNodeNum;
363 }
364 
365 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void removeListItem(const SwNodeNum &rNodeNum)=0
static void HandleNumberTreeRootNodeDelete(SwNodeNum &rNodeNum)
Definition: SwNodeNum.cxx:287
sal_uLong GetIndex() const
Definition: node.hxx:291
bool HasBullet() const
Returns if this text node has a bullet.
Definition: ndtxt.cxx:3103
SwNodeNum(SwTextNode *pTextNode, bool isHiddenRedlines)
Definition: SwNodeNum.cxx:28
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:64
constexpr TypedWhichId< SfxInt16Item > RES_PARATR_LIST_RESTARTVALUE(85)
IDocumentListItems & getIDocumentListItems()
Provides access to the document's numbered items interface.
Definition: node.cxx:2104
virtual bool IsRestart() const override
Return if numbering is restarted at this node.
Definition: SwNodeNum.cxx:229
virtual bool IsCounted() const override
Return if this node is counted.
Definition: SwNodeNum.cxx:166
bool m_isHiddenRedlines
Definition: SwNodeNum.hxx:86
virtual SwNumberTree::tSwNumTreeNumber GetStartValue() const override
Return start value.
Definition: SwNodeNum.cxx:258
bool HasNumber() const
Returns if this text node has a number.
Definition: ndtxt.cxx:3086
bool IsListRestart() const
Definition: ndtxt.cxx:4129
SwTextNode * GetTextNode() const
Definition: SwNodeNum.hxx:40
virtual bool IsNotifiable() const override
Return if this node is notifiable.
Definition: SwNodeNum.cxx:125
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:135
bool IsContinusNum() const
Definition: numrule.hxx:236
virtual void PostRemove() override
Definition: SwNodeNum.cxx:103
virtual bool LessThan(const SwNumberTreeNode &rNode) const override
Returns if this node is less than another node.
Definition: SwNodeNum.cxx:212
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
void RemoveFromList()
Definition: ndtxt.cxx:4323
bool IsCountPhantoms() const
Definition: numrule.hxx:244
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:4193
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:2813
virtual bool IsContinuous() const =0
Return if this node is counted continuous.
sal_uInt16 GetStart() const
virtual bool HasCountedChildren() const override
Definition: SwNodeNum.cxx:183
void ValidateMe()
Validates this node.
virtual void NotifyNode() override
Notifies the node.
Definition: SwNodeNum.cxx:202
virtual ~SwNodeNum() override
Definition: SwNodeNum.cxx:42
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
virtual bool IsCountedForNumbering() const override
Definition: SwNodeNum.cxx:193
virtual bool IsContinuous() const override
Return if this node is counted continuous.
Definition: SwNodeNum.cxx:145
bool IsCountedInList() const
Definition: ndtxt.cxx:4244
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:47
const SwNodeNum * GetPrecedingNodeNumOf(const SwTextNode &rTextNode) const
determines the instance, which is preceding the given text node
Definition: SwNodeNum.cxx:350
void NumRuleChgd()
Notify this textnode that its numbering rule has changed.
Definition: ndtxt.cxx:2853
virtual bool IsCounted() const
Return if this node is counted.
bool IsNotifiable() const
Checks a temporary notification blocker and the global conditions of IsNotificationEnabled() ...
Definition: ndtxt.cxx:4218
virtual void PreAdd() override
Definition: SwNodeNum.cxx:78
virtual SwNumberTreeNode * Create() const override
Creates a new node of the same class.
Definition: SwNodeNum.cxx:71
bool IsNotificationEnabled() const
Checks some global conditions like loading or destruction of document to economize notifications...
Definition: ndtxt.cxx:4223
virtual bool IsCountPhantoms() const override
Return if phantoms are counted.
Definition: SwNodeNum.cxx:241
constexpr TypedWhichId< SfxStringItem > RES_PARATR_LIST_ID(RES_PARATR_LIST_BEGIN)
static void UnregisterMeAndChildrenDueToRootDelete(SwNodeNum &rNodeNum)
Definition: SwNodeNum.cxx:303