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