update credits
[LibreOffice.git] / sw / source / core / SwNumberTree / SwNodeNum.cxx
blobc3350f202180c227c5ef8efffe9f31b6f6b5fd35
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 .
21 #include <editeng/svxenum.hxx>
22 #include <numrule.hxx>
23 #include <SwNodeNum.hxx>
24 #include <ndtxt.hxx>
25 #include <pam.hxx>
26 #include <stdio.h>
27 // #i83479#
28 #include <IDocumentListItems.hxx>
29 #include <doc.hxx>
31 SwNodeNum::SwNodeNum( SwTxtNode* pTxtNode )
32 : SwNumberTreeNode(),
33 mpTxtNode( pTxtNode ),
34 mpNumRule( 0 )
38 SwNodeNum::SwNodeNum( SwNumRule* pNumRule )
39 : SwNumberTreeNode(),
40 mpTxtNode( 0 ),
41 mpNumRule( pNumRule )
45 SwNodeNum::~SwNodeNum()
49 SwTxtNode * SwNodeNum::GetTxtNode() const
51 return mpTxtNode;
54 SwNumRule * SwNodeNum::GetNumRule() const
56 return mpNumRule;
59 void SwNodeNum::ChangeNumRule( SwNumRule& rNumRule )
61 OSL_ENSURE( GetNumRule() && GetTxtNode(),
62 "<SwNodeNum::ChangeNumRule(..)> - missing list style and/or text node. Serious defect -> please informm OD." );
63 if ( GetNumRule() && GetTxtNode() )
65 GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
68 mpNumRule = &rNumRule;
70 if ( GetNumRule() && GetTxtNode() )
72 GetNumRule()->AddTxtNode( *(GetTxtNode()) );
76 SwPosition SwNodeNum::GetPosition() const
78 OSL_ENSURE( GetTxtNode(),
79 "<SwNodeNum::GetPosition()> - no text node set at <SwNodeNum> instance" );
80 return SwPosition(*mpTxtNode);
83 SwNumberTreeNode * SwNodeNum::Create() const
85 SwNodeNum * pResult = new SwNodeNum( GetNumRule() );
87 return pResult;
90 void SwNodeNum::PreAdd()
92 OSL_ENSURE( GetTxtNode(),
93 "<SwNodeNum::PreAdd()> - no text node set at <SwNodeNum> instance" );
94 if ( !GetNumRule() && GetTxtNode() )
96 mpNumRule = GetTxtNode()->GetNumRule();
98 OSL_ENSURE( GetNumRule(),
99 "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" );
100 if ( GetNumRule() && GetTxtNode() )
102 GetNumRule()->AddTxtNode( *(GetTxtNode()) );
107 if ( GetTxtNode() &&
108 GetTxtNode()->GetNodes().IsDocNodes() )
110 GetTxtNode()->getIDocumentListItems().addListItem( *this );
115 void SwNodeNum::PostRemove()
117 OSL_ENSURE( GetTxtNode(),
118 "<SwNodeNum::PostRemove()> - no text node set at <SwNodeNum> instance" );
119 OSL_ENSURE( GetNumRule(),
120 "<SwNodeNum::PostRemove()> - no list style set at <SwNodeNum> instance" );
122 if ( GetTxtNode() )
124 GetTxtNode()->getIDocumentListItems().removeListItem( *this );
127 if ( GetNumRule() )
129 if ( GetTxtNode() )
131 GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
133 mpNumRule = 0;
137 bool SwNodeNum::IsNotifiable() const
139 bool aResult = true;
141 if ( GetTxtNode() )
142 aResult = GetTxtNode()->IsNotifiable();
144 return aResult;
147 bool SwNodeNum::IsNotificationEnabled() const
149 bool aResult = true;
151 if ( GetTxtNode() )
152 aResult = GetTxtNode()->IsNotificationEnabled();
154 return aResult;
157 bool SwNodeNum::IsContinuous() const
159 bool aResult = false;
161 // #i64311#
162 if ( GetNumRule() )
164 aResult = mpNumRule->IsContinusNum();
166 else if ( GetParent() )
168 aResult = GetParent()->IsContinuous();
170 else
172 OSL_FAIL( "<SwNodeNum::IsContinuous()> - OD debug" );
175 return aResult;
178 bool SwNodeNum::IsCounted() const
180 bool aResult = false;
182 if ( GetTxtNode() )
184 // #i59559#
185 // <SwTxtNode::IsCounted()> determines, if a text node is counted for numbering
186 aResult = GetTxtNode()->IsCountedInList();
188 else
189 aResult = SwNumberTreeNode::IsCounted();
191 return aResult;
194 // #i64010#
195 bool SwNodeNum::HasCountedChildren() const
197 bool bResult = false;
199 tSwNumberTreeChildren::const_iterator aIt;
201 for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
203 SwNodeNum* pChild( dynamic_cast<SwNodeNum*>(*aIt) );
204 OSL_ENSURE( pChild,
205 "<SwNodeNum::HasCountedChildren()> - unexcepted type of child -> please inform OD" );
206 if ( pChild &&
207 ( pChild->IsCountedForNumbering() ||
208 pChild->HasCountedChildren() ) )
210 bResult = true;
212 break;
216 return bResult;
218 // #i64010#
219 bool SwNodeNum::IsCountedForNumbering() const
221 return IsCounted() &&
222 ( IsPhantom() || // phantoms
223 !GetTxtNode() || // root node
224 GetTxtNode()->HasNumber() || // text node
225 GetTxtNode()->HasBullet() ); // text node
229 void SwNodeNum::NotifyNode()
231 ValidateMe();
233 if (mpTxtNode)
235 mpTxtNode->NumRuleChgd();
239 bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
241 bool bResult = false;
242 const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);
244 if (mpTxtNode == NULL && rTmpNode.mpTxtNode != NULL)
245 bResult = true;
246 else if (mpTxtNode != NULL && rTmpNode.mpTxtNode != NULL)
248 // #i83479# - refactoring
249 // simplify comparison by comparing the indexes of the text nodes
250 bResult = ( mpTxtNode->GetIndex() < rTmpNode.mpTxtNode->GetIndex() ) ? true : false;
253 return bResult;
256 bool SwNodeNum::IsRestart() const
258 bool bIsRestart = false;
260 if ( GetTxtNode() )
262 bIsRestart = GetTxtNode()->IsListRestart();
265 return bIsRestart;
268 bool SwNodeNum::IsCountPhantoms() const
270 bool bResult = true;
272 // #i64311#
273 // phantoms aren't counted in consecutive numbering rules
274 if ( mpNumRule )
275 bResult = !mpNumRule->IsContinusNum() &&
276 mpNumRule->IsCountPhantoms();
277 else
279 OSL_FAIL( "<SwNodeNum::IsCountPhantoms(): missing numbering rule - please inform OD" );
282 return bResult;
285 SwNumberTree::tSwNumTreeNumber SwNodeNum::GetStartValue() const
287 SwNumberTree::tSwNumTreeNumber aResult = 1;
289 if ( IsRestart() && GetTxtNode() )
291 aResult = GetTxtNode()->GetActualListStartValue();
293 else
295 SwNumRule * pRule = GetNumRule();
297 if (pRule)
299 int nLevel = GetParent() ? GetLevelInListTree() : 0;
301 if (nLevel >= 0 && nLevel < MAXLEVEL)
303 const SwNumFmt * pFmt = pRule->GetNumFmt( static_cast<sal_uInt16>(nLevel));
305 if (pFmt)
306 aResult = pFmt->GetStart();
311 return aResult;
314 void SwNodeNum::HandleNumberTreeRootNodeDelete( SwNodeNum& rNodeNum )
316 SwNodeNum* pRootNode = rNodeNum.GetParent()
317 ? dynamic_cast<SwNodeNum*>(rNodeNum.GetRoot())
318 : &rNodeNum;
319 if ( !pRootNode )
321 // no root node -> nothing do.
322 return;
325 // unregister all number tree node entries, which correspond to a text node,
326 // about the deletion of the number tree root node.
327 _UnregisterMeAndChildrenDueToRootDelete( *pRootNode );
330 void SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete( SwNodeNum& rNodeNum )
332 const bool bIsPhantom( rNodeNum.IsPhantom() );
333 tSwNumberTreeChildren::size_type nAllowedChildCount( 0 );
334 bool bDone( false );
335 while ( !bDone &&
336 rNodeNum.GetChildCount() > nAllowedChildCount )
338 SwNodeNum* pChildNode( dynamic_cast<SwNodeNum*>((*rNodeNum.mChildren.begin())) );
339 if ( !pChildNode )
341 OSL_FAIL( "<SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
342 ++nAllowedChildCount;
343 continue;
346 // Unregistering the last child of a phantom will destroy the phantom.
347 // Thus <rNodeNum> will be destroyed and access on <rNodeNum> has to
348 // be suppressed.
349 if ( bIsPhantom && rNodeNum.GetChildCount() == 1 )
351 bDone = true;
354 _UnregisterMeAndChildrenDueToRootDelete( *pChildNode );
357 if ( !bIsPhantom )
359 SwTxtNode* pTxtNode( rNodeNum.GetTxtNode() );
360 if ( pTxtNode )
362 pTxtNode->RemoveFromList();
363 // --> clear all list attributes and the list style
364 std::set<sal_uInt16> aResetAttrsArray;
365 aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_ID );
366 aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_LEVEL );
367 aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_ISRESTART );
368 aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_RESTARTVALUE );
369 aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_ISCOUNTED );
370 aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_NUMRULE );
371 SwPaM aPam( *pTxtNode );
372 pTxtNode->GetDoc()->ResetAttrs( aPam, false,
373 aResetAttrsArray,
374 false );
379 // #i81002#
380 const SwNodeNum* SwNodeNum::GetPrecedingNodeNumOf( const SwTxtNode& rTxtNode ) const
382 const SwNodeNum* pPrecedingNodeNum( 0 );
384 // #i83479#
385 SwNodeNum aNodeNumForTxtNode( const_cast<SwTxtNode*>(&rTxtNode) );
387 pPrecedingNodeNum = dynamic_cast<const SwNodeNum*>(
388 GetRoot()
389 ? GetRoot()->GetPrecedingNodeOf( aNodeNumForTxtNode )
390 : GetPrecedingNodeOf( aNodeNumForTxtNode ) );
392 return pPrecedingNodeNum;
395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */