Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <editeng/svxenum.hxx>
31 : : #include <numrule.hxx>
32 : : #include <SwNodeNum.hxx>
33 : : #include <ndtxt.hxx>
34 : : #include <pam.hxx>
35 : : #include <stdio.h>
36 : : // #i83479#
37 : : #include <IDocumentListItems.hxx>
38 : : #include <doc.hxx>
39 : :
40 : 4104 : SwNodeNum::SwNodeNum( SwTxtNode* pTxtNode )
41 : : : SwNumberTreeNode(),
42 : : mpTxtNode( pTxtNode ),
43 : 4104 : mpNumRule( 0 )
44 : : {
45 : 4104 : }
46 : :
47 : 12886 : SwNodeNum::SwNodeNum( SwNumRule* pNumRule )
48 : : : SwNumberTreeNode(),
49 : : mpTxtNode( 0 ),
50 : 12886 : mpNumRule( pNumRule )
51 : : {
52 : 12886 : }
53 : :
54 : 16505 : SwNodeNum::~SwNodeNum()
55 : : {
56 [ - + ]: 32956 : }
57 : :
58 : 167360 : SwTxtNode * SwNodeNum::GetTxtNode() const
59 : : {
60 : 167360 : return mpTxtNode;
61 : : }
62 : :
63 : 66912 : SwNumRule * SwNodeNum::GetNumRule() const
64 : : {
65 : 66912 : return mpNumRule;
66 : : }
67 : :
68 : 0 : void SwNodeNum::ChangeNumRule( SwNumRule& rNumRule )
69 : : {
70 : : OSL_ENSURE( GetNumRule() && GetTxtNode(),
71 : : "<SwNodeNum::ChangeNumRule(..)> - missing list style and/or text node. Serious defect -> please informm OD." );
72 [ # # ][ # # ]: 0 : if ( GetNumRule() && GetTxtNode() )
[ # # ]
73 : : {
74 : 0 : GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
75 : : }
76 : :
77 : 0 : mpNumRule = &rNumRule;
78 : :
79 [ # # ][ # # ]: 0 : if ( GetNumRule() && GetTxtNode() )
[ # # ]
80 : : {
81 : 0 : GetNumRule()->AddTxtNode( *(GetTxtNode()) );
82 : : }
83 : 0 : }
84 : :
85 : 4050 : SwPosition SwNodeNum::GetPosition() const
86 : : {
87 : : OSL_ENSURE( GetTxtNode(),
88 : : "<SwNodeNum::GetPosition()> - no text node set at <SwNodeNum> instance" );
89 : 4050 : return SwPosition(*mpTxtNode);
90 : : }
91 : :
92 : 1051 : SwNumberTreeNode * SwNodeNum::Create() const
93 : : {
94 [ + - ]: 1051 : SwNodeNum * pResult = new SwNodeNum( GetNumRule() );
95 : :
96 : 1051 : return pResult;
97 : : }
98 : :
99 : 4143 : void SwNodeNum::PreAdd()
100 : : {
101 : : OSL_ENSURE( GetTxtNode(),
102 : : "<SwNodeNum::PreAdd()> - no text node set at <SwNodeNum> instance" );
103 [ + - ][ + - ]: 4143 : if ( !GetNumRule() && GetTxtNode() )
[ + - ]
104 : : {
105 : 4143 : mpNumRule = GetTxtNode()->GetNumRule();
106 : : }
107 : : OSL_ENSURE( GetNumRule(),
108 : : "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" );
109 [ + - ][ + - ]: 4143 : if ( GetNumRule() && GetTxtNode() )
[ + - ]
110 : : {
111 : 4143 : GetNumRule()->AddTxtNode( *(GetTxtNode()) );
112 : : }
113 : :
114 : :
115 : : {
116 [ + - + - ]: 8286 : if ( GetTxtNode() &&
[ + - ]
117 : 4143 : GetTxtNode()->GetNodes().IsDocNodes() )
118 : : {
119 : 4143 : GetTxtNode()->getIDocumentListItems().addListItem( *this );
120 : : }
121 : : }
122 : 4143 : }
123 : :
124 : 4143 : void SwNodeNum::PostRemove()
125 : : {
126 : : OSL_ENSURE( GetTxtNode(),
127 : : "<SwNodeNum::PostRemove()> - no text node set at <SwNodeNum> instance" );
128 : : OSL_ENSURE( GetNumRule(),
129 : : "<SwNodeNum::PostRemove()> - no list style set at <SwNodeNum> instance" );
130 : :
131 [ + - ]: 4143 : if ( GetTxtNode() )
132 : : {
133 : 4143 : GetTxtNode()->getIDocumentListItems().removeListItem( *this );
134 : : }
135 : :
136 [ + - ]: 4143 : if ( GetNumRule() )
137 : : {
138 [ + - ]: 4143 : if ( GetTxtNode() )
139 : : {
140 : 4143 : GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
141 : : }
142 : 4143 : mpNumRule = 0;
143 : : }
144 : 4143 : }
145 : :
146 : 44808 : bool SwNodeNum::IsNotifiable() const
147 : : {
148 : 44808 : bool aResult = true;
149 : :
150 [ + + ]: 44808 : if ( GetTxtNode() )
151 : 38654 : aResult = GetTxtNode()->IsNotifiable();
152 : :
153 : 44808 : return aResult;
154 : : }
155 : :
156 : 4143 : bool SwNodeNum::IsNotificationEnabled() const
157 : : {
158 : 4143 : bool aResult = true;
159 : :
160 [ + - ]: 4143 : if ( GetTxtNode() )
161 : 4143 : aResult = GetTxtNode()->IsNotificationEnabled();
162 : :
163 : 4143 : return aResult;
164 : : }
165 : :
166 : 14760 : bool SwNodeNum::IsContinuous() const
167 : : {
168 : 14760 : bool aResult = false;
169 : :
170 : : // #i64311#
171 [ + - ]: 14760 : if ( GetNumRule() )
172 : : {
173 : 14760 : aResult = mpNumRule->IsContinusNum();
174 : : }
175 [ # # ]: 0 : else if ( GetParent() )
176 : : {
177 : 0 : aResult = GetParent()->IsContinuous();
178 : : }
179 : : else
180 : : {
181 : : OSL_FAIL( "<SwNodeNum::IsContinuous()> - OD debug" );
182 : : }
183 : :
184 : 14760 : return aResult;
185 : : }
186 : :
187 : 5211 : bool SwNodeNum::IsCounted() const
188 : : {
189 : 5211 : bool aResult = false;
190 : :
191 [ + + ]: 5211 : if ( GetTxtNode() )
192 : : {
193 : : // #i59559#
194 : : // <SwTxtNode::IsCounted()> determines, if a text node is counted for numbering
195 : 4247 : aResult = GetTxtNode()->IsCountedInList();
196 : : }
197 : : else
198 : 964 : aResult = SwNumberTreeNode::IsCounted();
199 : :
200 : 5211 : return aResult;
201 : : }
202 : :
203 : : // #i64010#
204 : 2805 : bool SwNodeNum::HasCountedChildren() const
205 : : {
206 : 2805 : bool bResult = false;
207 : :
208 [ + - ]: 2805 : tSwNumberTreeChildren::const_iterator aIt;
209 : :
210 [ + - ][ + - ]: 4665 : for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
[ + + ]
211 : : {
212 [ + - ][ - + ]: 2043 : SwNodeNum* pChild( dynamic_cast<SwNodeNum*>(*aIt) );
213 : : OSL_ENSURE( pChild,
214 : : "<SwNodeNum::HasCountedChildren()> - unexcepted type of child -> please inform OD" );
215 [ + - ][ + + ]: 5946 : if ( pChild &&
[ - + ][ + + ]
216 [ + - ]: 2043 : ( pChild->IsCountedForNumbering() ||
217 [ + - ]: 1860 : pChild->HasCountedChildren() ) )
218 : : {
219 : 183 : bResult = true;
220 : :
221 : 183 : break;
222 : : }
223 : : }
224 : :
225 : 2805 : return bResult;
226 : : }
227 : : // #i64010#
228 : 2043 : bool SwNodeNum::IsCountedForNumbering() const
229 : : {
230 : 2043 : return IsCounted() &&
231 : 1506 : ( IsPhantom() || // phantoms
232 : 1470 : !GetTxtNode() || // root node
233 : 1470 : GetTxtNode()->HasNumber() || // text node
234 [ + + ][ + + : 6489 : GetTxtNode()->HasBullet() ); // text node
+ + + - +
+ ]
235 : : }
236 : :
237 : :
238 : 1620 : void SwNodeNum::NotifyNode()
239 : : {
240 : 1620 : ValidateMe();
241 : :
242 [ + + ]: 1620 : if (mpTxtNode)
243 : : {
244 : 1473 : mpTxtNode->NumRuleChgd();
245 : : }
246 : 1620 : }
247 : :
248 : 144224 : bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
249 : : {
250 : 144224 : bool bResult = false;
251 : 144224 : const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);
252 : :
253 [ + + ][ + + ]: 144224 : if (mpTxtNode == NULL && rTmpNode.mpTxtNode != NULL)
254 : 816 : bResult = true;
255 [ + + ][ + + ]: 143408 : else if (mpTxtNode != NULL && rTmpNode.mpTxtNode != NULL)
256 : : {
257 : : // #i83479# - refactoring
258 : : // simplify comparison by comparing the indexes of the text nodes
259 : 130008 : bResult = ( mpTxtNode->GetIndex() < rTmpNode.mpTxtNode->GetIndex() ) ? true : false;
260 : : }
261 : :
262 : 144224 : return bResult;
263 : : }
264 : :
265 : 1940 : bool SwNodeNum::IsRestart() const
266 : : {
267 : 1940 : bool bIsRestart = false;
268 : :
269 [ + + ]: 1940 : if ( GetTxtNode() )
270 : : {
271 : 1810 : bIsRestart = GetTxtNode()->IsListRestart();
272 : : }
273 : :
274 : 1940 : return bIsRestart;
275 : : }
276 : :
277 : 903 : bool SwNodeNum::IsCountPhantoms() const
278 : : {
279 : 903 : bool bResult = true;
280 : :
281 : : // #i64311#
282 : : // phantoms aren't counted in consecutive numbering rules
283 [ + - ]: 903 : if ( mpNumRule )
284 : 903 : bResult = !mpNumRule->IsContinusNum() &&
285 [ + - ][ + - ]: 903 : mpNumRule->IsCountPhantoms();
286 : : else
287 : : {
288 : : OSL_FAIL( "<SwNodeNum::IsCountPhantoms(): missing numbering rule - please inform OD" );
289 : : }
290 : :
291 : 903 : return bResult;
292 : : }
293 : :
294 : 483 : SwNumberTree::tSwNumTreeNumber SwNodeNum::GetStartValue() const
295 : : {
296 : 483 : SwNumberTree::tSwNumTreeNumber aResult = 1;
297 : :
298 [ + + ][ + - ]: 483 : if ( IsRestart() && GetTxtNode() )
[ + + ]
299 : : {
300 : 2 : aResult = GetTxtNode()->GetActualListStartValue();
301 : : }
302 : : else
303 : : {
304 : 481 : SwNumRule * pRule = GetNumRule();
305 : :
306 [ + - ]: 481 : if (pRule)
307 : : {
308 [ + + ]: 481 : int nLevel = GetParent() ? GetLevelInListTree() : 0;
309 : :
310 [ + - ][ + - ]: 481 : if (nLevel >= 0 && nLevel < MAXLEVEL)
311 : : {
312 : 481 : const SwNumFmt * pFmt = pRule->GetNumFmt( static_cast<sal_uInt16>(nLevel));
313 : :
314 [ + + ]: 481 : if (pFmt)
315 : 292 : aResult = pFmt->GetStart();
316 : : }
317 : : }
318 : : }
319 : :
320 : 483 : return aResult;
321 : : }
322 : :
323 : 11350 : void SwNodeNum::HandleNumberTreeRootNodeDelete( SwNodeNum& rNodeNum )
324 : : {
325 : 11350 : SwNodeNum* pRootNode = rNodeNum.GetParent()
326 : 0 : ? dynamic_cast<SwNodeNum*>(rNodeNum.GetRoot())
327 [ - + # # ]: 11350 : : &rNodeNum;
328 [ - + ]: 11350 : if ( !pRootNode )
329 : : {
330 : : // no root node -> nothing do.
331 : 11350 : return;
332 : : }
333 : :
334 : : // unregister all number tree node entries, which correspond to a text node,
335 : : // about the deletion of the number tree root node.
336 : 11350 : _UnregisterMeAndChildrenDueToRootDelete( *pRootNode );
337 : : }
338 : :
339 : 11350 : void SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete( SwNodeNum& rNodeNum )
340 : : {
341 : 11350 : const bool bIsPhantom( rNodeNum.IsPhantom() );
342 : 11350 : tSwNumberTreeChildren::size_type nAllowedChildCount( 0 );
343 : 11350 : bool bDone( false );
344 [ + - - + ]: 22700 : while ( !bDone &&
[ - + ]
345 : 11350 : rNodeNum.GetChildCount() > nAllowedChildCount )
346 : : {
347 [ # # ][ # # ]: 0 : SwNodeNum* pChildNode( dynamic_cast<SwNodeNum*>((*rNodeNum.mChildren.begin())) );
348 [ # # ]: 0 : if ( !pChildNode )
349 : : {
350 : : OSL_FAIL( "<SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
351 : 0 : ++nAllowedChildCount;
352 : 0 : continue;
353 : : }
354 : :
355 : : // Unregistering the last child of a phantom will destroy the phantom.
356 : : // Thus <rNodeNum> will be destroyed and access on <rNodeNum> has to
357 : : // be suppressed.
358 [ # # ][ # # ]: 0 : if ( bIsPhantom && rNodeNum.GetChildCount() == 1 )
[ # # ]
359 : : {
360 : 0 : bDone = true;
361 : : }
362 : :
363 : 0 : _UnregisterMeAndChildrenDueToRootDelete( *pChildNode );
364 : : }
365 : :
366 [ + - ]: 11350 : if ( !bIsPhantom )
367 : : {
368 : 11350 : SwTxtNode* pTxtNode( rNodeNum.GetTxtNode() );
369 [ - + ]: 11350 : if ( pTxtNode )
370 : : {
371 [ # # ]: 0 : pTxtNode->RemoveFromList();
372 : : // --> clear all list attributes and the list style
373 [ # # ]: 0 : std::set<sal_uInt16> aResetAttrsArray;
374 [ # # ]: 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_ID );
375 [ # # ]: 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_LEVEL );
376 [ # # ]: 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_ISRESTART );
377 [ # # ]: 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_RESTARTVALUE );
378 [ # # ]: 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_ISCOUNTED );
379 [ # # ]: 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_NUMRULE );
380 [ # # ]: 0 : SwPaM aPam( *pTxtNode );
381 : : pTxtNode->GetDoc()->ResetAttrs( aPam, sal_False,
382 : : aResetAttrsArray,
383 [ # # ][ # # ]: 0 : false );
384 : : }
385 : : }
386 : 11350 : }
387 : :
388 : : // #i81002#
389 : 54 : const SwNodeNum* SwNodeNum::GetPrecedingNodeNumOf( const SwTxtNode& rTxtNode ) const
390 : : {
391 : 54 : const SwNodeNum* pPrecedingNodeNum( 0 );
392 : :
393 : : // #i83479#
394 [ + - ]: 54 : SwNodeNum aNodeNumForTxtNode( const_cast<SwTxtNode*>(&rTxtNode) );
395 : :
396 : : pPrecedingNodeNum = dynamic_cast<const SwNodeNum*>(
397 [ + - ]: 54 : GetRoot()
398 [ + - ]: 54 : ? GetRoot()->GetPrecedingNodeOf( aNodeNumForTxtNode )
399 [ + - ][ + - ]: 108 : : GetPrecedingNodeOf( aNodeNumForTxtNode ) );
[ # # ][ - + ]
400 : :
401 [ + - ]: 54 : return pPrecedingNodeNum;
402 : : }
403 : :
404 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|