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 
125 bool SwNodeNum::IsNotifiable(const SwDoc& rDoc) const
126 {
127  bool aResult;
128 
129  if (const SwTextNode* pTextNode = GetTextNode())
130  aResult = pTextNode->IsNotifiable();
131  else
132  aResult = IsNotificationEnabled(rDoc);
133 
134  return aResult;
135 }
136 
138 {
139  bool aResult;
140 
141  if (const SwTextNode* pTextNode = GetTextNode())
142  aResult = pTextNode->IsNotificationEnabled();
143  else
144  aResult = !rDoc.IsInReading() && !rDoc.IsInDtor();
145 
146  return aResult;
147 }
148 
150 {
151  bool aResult = false;
152 
153  // #i64311#
154  if ( GetNumRule() )
155  {
156  aResult = mpNumRule->IsContinusNum();
157  }
158  else if ( GetParent() )
159  {
160  aResult = GetParent()->IsContinuous();
161  }
162  else
163  {
164  OSL_FAIL( "<SwNodeNum::IsContinuous()> - OD debug" );
165  }
166 
167  return aResult;
168 }
169 
171 {
172  bool aResult = false;
173 
174  if ( GetTextNode() )
175  {
176  // #i59559#
177  // <SwTextNode::IsCounted()> determines, if a text node is counted for numbering
178  aResult = GetTextNode()->IsCountedInList();
179  }
180  else
181  aResult = SwNumberTreeNode::IsCounted();
182 
183  return aResult;
184 }
185 
186 // #i64010#
188 {
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());
194  });
195 }
196 // #i64010#
198 {
199  return IsCounted() &&
200  ( IsPhantom() || // phantoms
201  !GetTextNode() || // root node
202  GetTextNode()->HasNumber() || // text node
203  GetTextNode()->HasBullet() ); // text node
204 }
205 
207 {
208  ValidateMe();
209 
210  if (mpTextNode)
211  {
213  }
214 }
215 
216 bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
217 {
218  bool bResult = false;
219  const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);
220 
221  if (mpTextNode == nullptr && rTmpNode.mpTextNode != nullptr)
222  bResult = true;
223  else if (mpTextNode != nullptr && rTmpNode.mpTextNode != nullptr)
224  {
225  // #i83479# - refactoring
226  // simplify comparison by comparing the indexes of the text nodes
227  bResult = ( mpTextNode->GetIndex() < rTmpNode.mpTextNode->GetIndex() );
228  }
229 
230  return bResult;
231 }
232 
234 {
235  bool bIsRestart = false;
236 
237  if ( GetTextNode() )
238  {
239  bIsRestart = GetTextNode()->IsListRestart();
240  }
241 
242  return bIsRestart;
243 }
244 
246 {
247  bool bResult = true;
248 
249  // #i64311#
250  // phantoms aren't counted in consecutive numbering rules
251  if ( mpNumRule )
252  bResult = !mpNumRule->IsContinusNum() &&
254  else
255  {
256  OSL_FAIL( "<SwNodeNum::IsCountPhantoms(): missing numbering rule" );
257  }
258 
259  return bResult;
260 }
261 
263 {
264  SwNumberTree::tSwNumTreeNumber aResult = 1;
265 
266  if ( IsRestart() && GetTextNode() )
267  {
268  aResult = GetTextNode()->GetActualListStartValue();
269  }
270  else
271  {
272  SwNumRule * pRule = GetNumRule();
273 
274  if (pRule)
275  {
276  int nLevel = GetParent() ? GetLevelInListTree() : 0;
277 
278  if (nLevel >= 0 && nLevel < MAXLEVEL)
279  {
280  const SwNumFormat * pFormat = pRule->GetNumFormat( o3tl::narrowing<sal_uInt16>(nLevel));
281 
282  if (pFormat)
283  aResult = pFormat->GetStart();
284  }
285  }
286  }
287 
288  return aResult;
289 }
290 
292 {
293  SwNodeNum* pRootNode = rNodeNum.GetParent()
294  ? dynamic_cast<SwNodeNum*>(rNodeNum.GetRoot())
295  : &rNodeNum;
296  if ( !pRootNode )
297  {
298  // no root node -> nothing do.
299  return;
300  }
301 
302  // unregister all number tree node entries, which correspond to a text node,
303  // about the deletion of the number tree root node.
305 }
306 
308 {
309  const bool bIsPhantom( rNodeNum.IsPhantom() );
310  tSwNumberTreeChildren::size_type nAllowedChildCount( 0 );
311  bool bDone( false );
312  while ( !bDone &&
313  rNodeNum.GetChildCount() > nAllowedChildCount )
314  {
315  SwNodeNum* pChildNode( dynamic_cast<SwNodeNum*>((*rNodeNum.mChildren.begin())) );
316  if ( !pChildNode )
317  {
318  OSL_FAIL( "<SwNodeNum::UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
319  ++nAllowedChildCount;
320  continue;
321  }
322 
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 )
327  {
328  bDone = true;
329  }
330 
332  }
333 
334  if ( bIsPhantom )
335  return;
336 
337  SwTextNode* pTextNode( rNodeNum.GetTextNode() );
338  if ( !pTextNode )
339  return;
340 
341  pTextNode->RemoveFromList();
342  // --> clear all list attributes and the list style
343  const o3tl::sorted_vector<sal_uInt16> aResetAttrsArray{
346  };
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:291
sal_uLong GetIndex() const
Definition: node.hxx:291
bool HasBullet() const
Returns if this text node has a bullet.
Definition: ndtxt.cxx:3088
SwNodeNum(SwTextNode *pTextNode, bool isHiddenRedlines)
Definition: SwNodeNum.cxx:28
Marks a position in the document model.
Definition: pam.hxx:35
virtual bool IsNotifiable(const SwDoc &rDoc) const override
Return if this node is notifiable.
Definition: SwNodeNum.cxx:125
A tree of numbered nodes.
SwTextNode *const mpTextNode
Definition: SwNodeNum.hxx:83
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:2105
Definition: doc.hxx:188
virtual bool IsRestart() const override
Return if numbering is restarted at this node.
Definition: SwNodeNum.cxx:233
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:90
virtual bool IsNotificationEnabled(const SwDoc &rDoc) const override
Return if the notification is not disabled on global conditions.
Definition: SwNodeNum.cxx:137
virtual bool IsCounted() const override
Return if this node is counted.
Definition: SwNodeNum.cxx:170
bool m_isHiddenRedlines
Definition: SwNodeNum.hxx:85
virtual SwNumberTree::tSwNumTreeNumber GetStartValue() const override
Return start value.
Definition: SwNodeNum.cxx:262
bool HasNumber() const
Returns if this text node has a number.
Definition: ndtxt.cxx:3071
bool IsListRestart() const
Definition: ndtxt.cxx:4110
SwTextNode * GetTextNode() const
Definition: SwNodeNum.hxx:40
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)
tSwNumberTreeChildren mChildren
the children
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:216
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
void RemoveFromList()
Definition: ndtxt.cxx:4304
bool IsCountPhantoms() const
Definition: numrule.hxx:244
SwNumRule * mpNumRule
Definition: SwNodeNum.hxx:84
bool IsPhantom() const
Return if this node is a phantom.
SwNumRule * GetNumRule() const
Definition: SwNodeNum.hxx:38
SwNumberTree::tSwNumTreeNumber GetActualListStartValue() const
Definition: ndtxt.cxx:4174
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:2798
virtual bool IsContinuous() const =0
Return if this node is counted continuous.
sal_uInt16 GetStart() const
virtual bool HasCountedChildren() const override
Definition: SwNodeNum.cxx:187
bool IsInReading() const
Definition: doc.hxx:954
void ValidateMe()
Validates this node.
virtual void NotifyNode() override
Notifies the node.
Definition: SwNodeNum.cxx:206
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:197
virtual bool IsContinuous() const override
Return if this node is counted continuous.
Definition: SwNodeNum.cxx:149
bool IsCountedInList() const
Definition: ndtxt.cxx:4225
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:354
bool IsInDtor() const
Definition: doc.hxx:404
void NumRuleChgd()
Notify this textnode that its numbering rule has changed.
Definition: ndtxt.cxx:2838
virtual bool IsCounted() const
Return if this node is counted.
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
virtual bool IsCountPhantoms() const override
Return if phantoms are counted.
Definition: SwNodeNum.cxx:245
constexpr TypedWhichId< SfxStringItem > RES_PARATR_LIST_ID(RES_PARATR_LIST_BEGIN)
static void UnregisterMeAndChildrenDueToRootDelete(SwNodeNum &rNodeNum)
Definition: SwNodeNum.cxx:307