1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
28 #include <IDocumentListItems.hxx>
31 SwNodeNum::SwNodeNum( SwTxtNode
* pTxtNode
)
33 mpTxtNode( pTxtNode
),
38 SwNodeNum::SwNodeNum( SwNumRule
* pNumRule
)
45 SwNodeNum::~SwNodeNum()
49 SwTxtNode
* SwNodeNum::GetTxtNode() const
54 SwNumRule
* SwNodeNum::GetNumRule() const
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() );
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()) );
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" );
124 GetTxtNode()->getIDocumentListItems().removeListItem( *this );
131 GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
137 bool SwNodeNum::IsNotifiable() const
142 aResult
= GetTxtNode()->IsNotifiable();
147 bool SwNodeNum::IsNotificationEnabled() const
152 aResult
= GetTxtNode()->IsNotificationEnabled();
157 bool SwNodeNum::IsContinuous() const
159 bool aResult
= false;
164 aResult
= mpNumRule
->IsContinusNum();
166 else if ( GetParent() )
168 aResult
= GetParent()->IsContinuous();
172 OSL_FAIL( "<SwNodeNum::IsContinuous()> - OD debug" );
178 bool SwNodeNum::IsCounted() const
180 bool aResult
= false;
185 // <SwTxtNode::IsCounted()> determines, if a text node is counted for numbering
186 aResult
= GetTxtNode()->IsCountedInList();
189 aResult
= SwNumberTreeNode::IsCounted();
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
) );
205 "<SwNodeNum::HasCountedChildren()> - unexcepted type of child -> please inform OD" );
207 ( pChild
->IsCountedForNumbering() ||
208 pChild
->HasCountedChildren() ) )
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()
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
)
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;
256 bool SwNodeNum::IsRestart() const
258 bool bIsRestart
= false;
262 bIsRestart
= GetTxtNode()->IsListRestart();
268 bool SwNodeNum::IsCountPhantoms() const
273 // phantoms aren't counted in consecutive numbering rules
275 bResult
= !mpNumRule
->IsContinusNum() &&
276 mpNumRule
->IsCountPhantoms();
279 OSL_FAIL( "<SwNodeNum::IsCountPhantoms(): missing numbering rule - please inform OD" );
285 SwNumberTree::tSwNumTreeNumber
SwNodeNum::GetStartValue() const
287 SwNumberTree::tSwNumTreeNumber aResult
= 1;
289 if ( IsRestart() && GetTxtNode() )
291 aResult
= GetTxtNode()->GetActualListStartValue();
295 SwNumRule
* pRule
= GetNumRule();
299 int nLevel
= GetParent() ? GetLevelInListTree() : 0;
301 if (nLevel
>= 0 && nLevel
< MAXLEVEL
)
303 const SwNumFmt
* pFmt
= pRule
->GetNumFmt( static_cast<sal_uInt16
>(nLevel
));
306 aResult
= pFmt
->GetStart();
314 void SwNodeNum::HandleNumberTreeRootNodeDelete( SwNodeNum
& rNodeNum
)
316 SwNodeNum
* pRootNode
= rNodeNum
.GetParent()
317 ? dynamic_cast<SwNodeNum
*>(rNodeNum
.GetRoot())
321 // no root node -> nothing do.
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 );
336 rNodeNum
.GetChildCount() > nAllowedChildCount
)
338 SwNodeNum
* pChildNode( dynamic_cast<SwNodeNum
*>((*rNodeNum
.mChildren
.begin())) );
341 OSL_FAIL( "<SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
342 ++nAllowedChildCount
;
346 // Unregistering the last child of a phantom will destroy the phantom.
347 // Thus <rNodeNum> will be destroyed and access on <rNodeNum> has to
349 if ( bIsPhantom
&& rNodeNum
.GetChildCount() == 1 )
354 _UnregisterMeAndChildrenDueToRootDelete( *pChildNode
);
359 SwTxtNode
* pTxtNode( rNodeNum
.GetTxtNode() );
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,
380 const SwNodeNum
* SwNodeNum::GetPrecedingNodeNumOf( const SwTxtNode
& rTxtNode
) const
382 const SwNodeNum
* pPrecedingNodeNum( 0 );
385 SwNodeNum
aNodeNumForTxtNode( const_cast<SwTxtNode
*>(&rTxtNode
) );
387 pPrecedingNodeNum
= dynamic_cast<const SwNodeNum
*>(
389 ? GetRoot()->GetPrecedingNodeOf( aNodeNumForTxtNode
)
390 : GetPrecedingNodeOf( aNodeNumForTxtNode
) );
392 return pPrecedingNodeNum
;
395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */