Line data Source code
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 <editeng/svxenum.hxx>
21 : #include <numrule.hxx>
22 : #include <SwNodeNum.hxx>
23 : #include <ndtxt.hxx>
24 : #include <pam.hxx>
25 : #include <stdio.h>
26 : #include <IDocumentListItems.hxx>
27 : #include <doc.hxx>
28 :
29 6812 : SwNodeNum::SwNodeNum( SwTxtNode* pTxtNode )
30 : : SwNumberTreeNode(),
31 : mpTxtNode( pTxtNode ),
32 6812 : mpNumRule( 0 )
33 : {
34 6812 : }
35 :
36 215078 : SwNodeNum::SwNodeNum( SwNumRule* pNumRule )
37 : : SwNumberTreeNode(),
38 : mpTxtNode( 0 ),
39 215078 : mpNumRule( pNumRule )
40 : {
41 215078 : }
42 :
43 443656 : SwNodeNum::~SwNodeNum()
44 : {
45 443656 : }
46 :
47 :
48 :
49 0 : void SwNodeNum::ChangeNumRule( SwNumRule& rNumRule )
50 : {
51 : OSL_ENSURE( GetNumRule() && GetTxtNode(),
52 : "<SwNodeNum::ChangeNumRule(..)> - missing list style and/or text node. Serious defect -> please informm OD." );
53 0 : if ( GetNumRule() && GetTxtNode() )
54 : {
55 0 : GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
56 : }
57 :
58 0 : mpNumRule = &rNumRule;
59 :
60 0 : if ( GetNumRule() && GetTxtNode() )
61 : {
62 0 : GetNumRule()->AddTxtNode( *(GetTxtNode()) );
63 : }
64 0 : }
65 :
66 6758 : SwPosition SwNodeNum::GetPosition() const
67 : {
68 : OSL_ENSURE( GetTxtNode(),
69 : "<SwNodeNum::GetPosition()> - no text node set at <SwNodeNum> instance" );
70 6758 : return SwPosition(*mpTxtNode);
71 : }
72 :
73 1848 : SwNumberTreeNode * SwNodeNum::Create() const
74 : {
75 1848 : SwNodeNum * pResult = new SwNodeNum( GetNumRule() );
76 :
77 1848 : return pResult;
78 : }
79 :
80 7670 : void SwNodeNum::PreAdd()
81 : {
82 : OSL_ENSURE( GetTxtNode(),
83 : "<SwNodeNum::PreAdd()> - no text node set at <SwNodeNum> instance" );
84 7670 : if ( !GetNumRule() && GetTxtNode() )
85 : {
86 7670 : mpNumRule = GetTxtNode()->GetNumRule();
87 : }
88 : OSL_ENSURE( GetNumRule(),
89 : "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" );
90 7670 : if ( GetNumRule() && GetTxtNode() )
91 : {
92 7670 : GetNumRule()->AddTxtNode( *(GetTxtNode()) );
93 : }
94 :
95 : {
96 15340 : if ( GetTxtNode() &&
97 7670 : GetTxtNode()->GetNodes().IsDocNodes() )
98 : {
99 7670 : GetTxtNode()->getIDocumentListItems().addListItem( *this );
100 : }
101 : }
102 7670 : }
103 :
104 7670 : void SwNodeNum::PostRemove()
105 : {
106 : OSL_ENSURE( GetTxtNode(),
107 : "<SwNodeNum::PostRemove()> - no text node set at <SwNodeNum> instance" );
108 : OSL_ENSURE( GetNumRule(),
109 : "<SwNodeNum::PostRemove()> - no list style set at <SwNodeNum> instance" );
110 :
111 7670 : if ( GetTxtNode() )
112 : {
113 7670 : GetTxtNode()->getIDocumentListItems().removeListItem( *this );
114 : }
115 :
116 7670 : if ( GetNumRule() )
117 : {
118 7670 : if ( GetTxtNode() )
119 : {
120 7670 : GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
121 : }
122 7670 : mpNumRule = 0;
123 : }
124 7670 : }
125 :
126 123434 : bool SwNodeNum::IsNotifiable() const
127 : {
128 123434 : bool aResult = true;
129 :
130 123434 : if ( GetTxtNode() )
131 112696 : aResult = GetTxtNode()->IsNotifiable();
132 :
133 123434 : return aResult;
134 : }
135 :
136 7670 : bool SwNodeNum::IsNotificationEnabled() const
137 : {
138 7670 : bool aResult = true;
139 :
140 7670 : if ( GetTxtNode() )
141 7670 : aResult = GetTxtNode()->IsNotificationEnabled();
142 :
143 7670 : return aResult;
144 : }
145 :
146 26138 : bool SwNodeNum::IsContinuous() const
147 : {
148 26138 : bool aResult = false;
149 :
150 : // #i64311#
151 26138 : if ( GetNumRule() )
152 : {
153 26138 : aResult = mpNumRule->IsContinusNum();
154 : }
155 0 : else if ( GetParent() )
156 : {
157 0 : aResult = GetParent()->IsContinuous();
158 : }
159 : else
160 : {
161 : OSL_FAIL( "<SwNodeNum::IsContinuous()> - OD debug" );
162 : }
163 :
164 26138 : return aResult;
165 : }
166 :
167 6860 : bool SwNodeNum::IsCounted() const
168 : {
169 6860 : bool aResult = false;
170 :
171 6860 : if ( GetTxtNode() )
172 : {
173 : // #i59559#
174 : // <SwTxtNode::IsCounted()> determines, if a text node is counted for numbering
175 5836 : aResult = GetTxtNode()->IsCountedInList();
176 : }
177 : else
178 1024 : aResult = SwNumberTreeNode::IsCounted();
179 :
180 6860 : return aResult;
181 : }
182 :
183 : // #i64010#
184 2044 : bool SwNodeNum::HasCountedChildren() const
185 : {
186 2044 : bool bResult = false;
187 :
188 2044 : tSwNumberTreeChildren::const_iterator aIt;
189 :
190 3446 : for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
191 : {
192 1530 : SwNodeNum* pChild( dynamic_cast<SwNodeNum*>(*aIt) );
193 : OSL_ENSURE( pChild,
194 : "<SwNodeNum::HasCountedChildren()> - unexpected type of child -> please inform OD" );
195 3188 : if ( pChild &&
196 2932 : ( pChild->IsCountedForNumbering() ||
197 1402 : pChild->HasCountedChildren() ) )
198 : {
199 128 : bResult = true;
200 :
201 128 : break;
202 : }
203 : }
204 :
205 2044 : return bResult;
206 : }
207 : // #i64010#
208 1530 : bool SwNodeNum::IsCountedForNumbering() const
209 : {
210 2824 : return IsCounted() &&
211 2308 : ( IsPhantom() || // phantoms
212 2284 : !GetTxtNode() || // root node
213 2186 : GetTxtNode()->HasNumber() || // text node
214 2574 : GetTxtNode()->HasBullet() ); // text node
215 : }
216 :
217 1884 : void SwNodeNum::NotifyNode()
218 : {
219 1884 : ValidateMe();
220 :
221 1884 : if (mpTxtNode)
222 : {
223 1878 : mpTxtNode->NumRuleChgd();
224 : }
225 1884 : }
226 :
227 304162 : bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
228 : {
229 304162 : bool bResult = false;
230 304162 : const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);
231 :
232 304162 : if (mpTxtNode == NULL && rTmpNode.mpTxtNode != NULL)
233 2498 : bResult = true;
234 301664 : else if (mpTxtNode != NULL && rTmpNode.mpTxtNode != NULL)
235 : {
236 : // #i83479# - refactoring
237 : // simplify comparison by comparing the indexes of the text nodes
238 283124 : bResult = ( mpTxtNode->GetIndex() < rTmpNode.mpTxtNode->GetIndex() );
239 : }
240 :
241 304162 : return bResult;
242 : }
243 :
244 2916 : bool SwNodeNum::IsRestart() const
245 : {
246 2916 : bool bIsRestart = false;
247 :
248 2916 : if ( GetTxtNode() )
249 : {
250 2834 : bIsRestart = GetTxtNode()->IsListRestart();
251 : }
252 :
253 2916 : return bIsRestart;
254 : }
255 :
256 614 : bool SwNodeNum::IsCountPhantoms() const
257 : {
258 614 : bool bResult = true;
259 :
260 : // #i64311#
261 : // phantoms aren't counted in consecutive numbering rules
262 614 : if ( mpNumRule )
263 1228 : bResult = !mpNumRule->IsContinusNum() &&
264 1228 : mpNumRule->IsCountPhantoms();
265 : else
266 : {
267 : OSL_FAIL( "<SwNodeNum::IsCountPhantoms(): missing numbering rule - please inform OD" );
268 : }
269 :
270 614 : return bResult;
271 : }
272 :
273 706 : SwNumberTree::tSwNumTreeNumber SwNodeNum::GetStartValue() const
274 : {
275 706 : SwNumberTree::tSwNumTreeNumber aResult = 1;
276 :
277 706 : if ( IsRestart() && GetTxtNode() )
278 : {
279 16 : aResult = GetTxtNode()->GetActualListStartValue();
280 : }
281 : else
282 : {
283 690 : SwNumRule * pRule = GetNumRule();
284 :
285 690 : if (pRule)
286 : {
287 690 : int nLevel = GetParent() ? GetLevelInListTree() : 0;
288 :
289 690 : if (nLevel >= 0 && nLevel < MAXLEVEL)
290 : {
291 690 : const SwNumFmt * pFmt = pRule->GetNumFmt( static_cast<sal_uInt16>(nLevel));
292 :
293 690 : if (pFmt)
294 554 : aResult = pFmt->GetStart();
295 : }
296 : }
297 : }
298 :
299 706 : return aResult;
300 : }
301 :
302 213195 : void SwNodeNum::HandleNumberTreeRootNodeDelete( SwNodeNum& rNodeNum )
303 : {
304 213195 : SwNodeNum* pRootNode = rNodeNum.GetParent()
305 0 : ? dynamic_cast<SwNodeNum*>(rNodeNum.GetRoot())
306 213195 : : &rNodeNum;
307 213195 : if ( !pRootNode )
308 : {
309 : // no root node -> nothing do.
310 213195 : return;
311 : }
312 :
313 : // unregister all number tree node entries, which correspond to a text node,
314 : // about the deletion of the number tree root node.
315 213195 : _UnregisterMeAndChildrenDueToRootDelete( *pRootNode );
316 : }
317 :
318 213195 : void SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete( SwNodeNum& rNodeNum )
319 : {
320 213195 : const bool bIsPhantom( rNodeNum.IsPhantom() );
321 213195 : tSwNumberTreeChildren::size_type nAllowedChildCount( 0 );
322 213195 : bool bDone( false );
323 639585 : while ( !bDone &&
324 213195 : rNodeNum.GetChildCount() > nAllowedChildCount )
325 : {
326 0 : SwNodeNum* pChildNode( dynamic_cast<SwNodeNum*>((*rNodeNum.mChildren.begin())) );
327 0 : if ( !pChildNode )
328 : {
329 : OSL_FAIL( "<SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
330 0 : ++nAllowedChildCount;
331 0 : continue;
332 : }
333 :
334 : // Unregistering the last child of a phantom will destroy the phantom.
335 : // Thus <rNodeNum> will be destroyed and access on <rNodeNum> has to
336 : // be suppressed.
337 0 : if ( bIsPhantom && rNodeNum.GetChildCount() == 1 )
338 : {
339 0 : bDone = true;
340 : }
341 :
342 0 : _UnregisterMeAndChildrenDueToRootDelete( *pChildNode );
343 : }
344 :
345 213195 : if ( !bIsPhantom )
346 : {
347 213195 : SwTxtNode* pTxtNode( rNodeNum.GetTxtNode() );
348 213195 : if ( pTxtNode )
349 : {
350 0 : pTxtNode->RemoveFromList();
351 : // --> clear all list attributes and the list style
352 0 : std::set<sal_uInt16> aResetAttrsArray;
353 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_ID );
354 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_LEVEL );
355 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_ISRESTART );
356 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_RESTARTVALUE );
357 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_LIST_ISCOUNTED );
358 0 : aResetAttrsArray.insert( aResetAttrsArray.end(), RES_PARATR_NUMRULE );
359 0 : SwPaM aPam( *pTxtNode );
360 : pTxtNode->GetDoc()->ResetAttrs( aPam, false,
361 : aResetAttrsArray,
362 0 : false );
363 : }
364 : }
365 213195 : }
366 :
367 : // #i81002#
368 54 : const SwNodeNum* SwNodeNum::GetPrecedingNodeNumOf( const SwTxtNode& rTxtNode ) const
369 : {
370 54 : const SwNodeNum* pPrecedingNodeNum( 0 );
371 :
372 : // #i83479#
373 54 : SwNodeNum aNodeNumForTxtNode( const_cast<SwTxtNode*>(&rTxtNode) );
374 :
375 : pPrecedingNodeNum = dynamic_cast<const SwNodeNum*>(
376 54 : GetRoot()
377 54 : ? GetRoot()->GetPrecedingNodeOf( aNodeNumForTxtNode )
378 108 : : GetPrecedingNodeOf( aNodeNumForTxtNode ) );
379 :
380 54 : return pPrecedingNodeNum;
381 270 : }
382 :
383 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|