xref: /aoo41x/main/sw/source/core/doc/number.cxx (revision efeef26f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 #include <hintids.hxx>
29 
30 #include <string.h>
31 #include <vcl/font.hxx>
32 #include <editeng/brshitem.hxx>
33 #include <editeng/lrspitem.hxx>
34 #include <editeng/numitem.hxx>
35 #include <fmtornt.hxx>
36 #include <doc.hxx>
37 #include <pam.hxx>
38 #include <charfmt.hxx>
39 #include <paratr.hxx>
40 #include <frmfmt.hxx>
41 #include <ndtxt.hxx>
42 #include <docary.hxx>
43 #ifndef _DOCSH_HXX
44 #include <docsh.hxx>
45 #endif
46 #include <SwStyleNameMapper.hxx>
47 // --> OD 2006-06-28 #b6440955#
48 // Needed to load default bullet list configuration
49 #include <unotools/configitem.hxx>
50 // <--
51 #include <numrule.hxx>
52 #include <SwNodeNum.hxx>
53 
54 #include <hash_map>
55 // --> OD 2008-02-19 #refactorlists#
56 #include <list.hxx>
57 #include <algorithm>
58 // <--
59 // --> OD 2008-06-06 #i89178#
60 #include <unotools/saveopt.hxx>
61 // <--
62 // --> OD 2008-07-08 #i91400#
63 #include <IDocumentListsAccess.hxx>
64 // <--
65 
66 using namespace ::com::sun::star;
67 
68 
69 sal_uInt16 SwNumRule::nRefCount = 0;
70 SwNumFmt* SwNumRule::aBaseFmts[ RULE_END ][ MAXLEVEL ] = {
71     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
72 // --> OD 2008-02-11 #newlistlevelattrs#
73 SwNumFmt* SwNumRule::aLabelAlignmentBaseFmts[ RULE_END ][ MAXLEVEL ] = {
74     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
75 
76 char sOutline[] = "Outline";
77 char* SwNumRule::pDefOutlineName = sOutline;
78 
79 // #i30312#
80 sal_uInt16 SwNumRule::aDefNumIndents[ MAXLEVEL ] = {
81 //inch:   0,5  1,0  1,5  2,0   2,5   3,0   3,5   4,0   4,5   5,0
82 		1440/4, 1440/2, 1440*3/4, 1440, 1440*5/4, 1440*3/2, 1440*7/4, 1440*2,
83         1440*9/4, 1440*5/2
84 };
85 
86 const SwNumFmt& SwNumRule::Get( sal_uInt16 i ) const
87 {
88 	ASSERT_ID( i < MAXLEVEL && eRuleType < RULE_END, ERR_NUMLEVEL);
89     return aFmts[ i ]
90            ? *aFmts[ i ]
91            // --> OD 2008-02-11 #newlistlevelattrs#
92            : ( meDefaultNumberFormatPositionAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
93                ? *aBaseFmts[ eRuleType ][ i ]
94                : *aLabelAlignmentBaseFmts[ eRuleType ][ i ] );
95            // <--
96 }
97 
98 const SwNumFmt* SwNumRule::GetNumFmt( sal_uInt16 i ) const
99 {
100     const SwNumFmt * pResult = NULL;
101 
102     ASSERT_ID( i < MAXLEVEL && eRuleType < RULE_END, ERR_NUMLEVEL);
103     if ( i < MAXLEVEL && eRuleType < RULE_END)
104     {
105         pResult = aFmts[ i ];
106     }
107 
108     return pResult;
109 }
110 
111 // --> OD 2008-07-08 #i91400#
112 void SwNumRule::SetName( const String & rName,
113                          IDocumentListsAccess& rDocListAccess)
114 // <--
115 {
116     if ( sName != rName )
117     {
118         if (pNumRuleMap)
119         {
120             pNumRuleMap->erase(sName);
121             (*pNumRuleMap)[rName] = this;
122 
123             // --> OD 2008-07-08 #i91400#
124             if ( GetDefaultListId().Len() > 0 )
125             {
126                 rDocListAccess.trackChangeOfListStyleName( sName, rName );
127             }
128             // <--
129         }
130 
131         sName = rName;
132     }
133 }
134 
135 // --> OD 2008-02-19 #refactorlists#
136 void SwNumRule::GetTxtNodeList( SwNumRule::tTxtNodeList& rTxtNodeList ) const
137 {
138     rTxtNodeList = maTxtNodeList;
139 }
140 
141 SwNumRule::tTxtNodeList::size_type SwNumRule::GetTxtNodeListSize() const
142 {
143     return maTxtNodeList.size();
144 }
145 
146 void SwNumRule::AddTxtNode( SwTxtNode& rTxtNode )
147 {
148     tTxtNodeList::iterator aIter =
149         std::find( maTxtNodeList.begin(), maTxtNodeList.end(), &rTxtNode );
150 
151     if ( aIter == maTxtNodeList.end() )
152     {
153         maTxtNodeList.push_back( &rTxtNode );
154     }
155 }
156 
157 void SwNumRule::RemoveTxtNode( SwTxtNode& rTxtNode )
158 {
159     tTxtNodeList::iterator aIter =
160         std::find( maTxtNodeList.begin(), maTxtNodeList.end(), &rTxtNode );
161 
162     if ( aIter != maTxtNodeList.end() )
163     {
164         maTxtNodeList.erase( aIter );
165     }
166 }
167 // <--
168 
169 void SwNumRule::SetNumRuleMap(std::hash_map<String, SwNumRule *, StringHash> *
170                               _pNumRuleMap)
171 {
172     pNumRuleMap = _pNumRuleMap;
173 }
174 
175 sal_uInt16 SwNumRule::GetNumIndent( sal_uInt8 nLvl )
176 {
177 	ASSERT( MAXLEVEL > nLvl, "NumLevel is out of range" );
178 	return aDefNumIndents[ nLvl ];
179 }
180 
181 sal_uInt16 SwNumRule::GetBullIndent( sal_uInt8 nLvl )
182 {
183 	ASSERT( MAXLEVEL > nLvl, "NumLevel is out of range" );
184 	return aDefNumIndents[ nLvl ];
185 }
186 
187 
188 
189 static void lcl_SetRuleChgd( SwTxtNode& rNd, sal_uInt8 nLevel )
190 {
191     if( rNd.GetActualListLevel() == nLevel )
192 		rNd.NumRuleChgd();
193 }
194 /* -----------------------------22.02.01 13:41--------------------------------
195 
196  ---------------------------------------------------------------------------*/
197 SwNumFmt::SwNumFmt() :
198 	SvxNumberFormat(SVX_NUM_ARABIC),
199 	SwClient( 0 ),
200     pVertOrient(new SwFmtVertOrient( 0, text::VertOrientation::NONE))
201 {
202 }
203 /* -----------------------------22.02.01 13:42--------------------------------
204 
205  ---------------------------------------------------------------------------*/
206 SwNumFmt::SwNumFmt( const SwNumFmt& rFmt) :
207 	SvxNumberFormat(rFmt),
208 	SwClient( rFmt.GetRegisteredInNonConst() ),
209     pVertOrient(new SwFmtVertOrient( 0, rFmt.GetVertOrient()))
210 {
211     sal_Int16 eMyVertOrient = rFmt.GetVertOrient();
212 	SetGraphicBrush( rFmt.GetBrush(), &rFmt.GetGraphicSize(),
213 												&eMyVertOrient);
214 }
215 /* -----------------------------22.02.01 13:58--------------------------------
216 
217  ---------------------------------------------------------------------------*/
218 SwNumFmt::SwNumFmt(const SvxNumberFormat& rNumFmt, SwDoc* pDoc) :
219 	SvxNumberFormat(rNumFmt),
220     pVertOrient(new SwFmtVertOrient( 0, rNumFmt.GetVertOrient()))
221 {
222     sal_Int16 eMyVertOrient = rNumFmt.GetVertOrient();
223     SetGraphicBrush( rNumFmt.GetBrush(), &rNumFmt.GetGraphicSize(),
224 												&eMyVertOrient);
225     const String& rCharStyleName = rNumFmt.SvxNumberFormat::GetCharFmtName();
226 	if( rCharStyleName.Len() )
227 	{
228 		SwCharFmt* pCFmt = pDoc->FindCharFmtByName( rCharStyleName );
229 		if( !pCFmt )
230 		{
231 			sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( rCharStyleName,
232 											nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
233 			pCFmt = nId != USHRT_MAX
234 						? pDoc->GetCharFmtFromPool( nId )
235 						: pDoc->MakeCharFmt( rCharStyleName, 0 );
236 		}
237 		pCFmt->Add( this );
238 	}
239 	else if( GetRegisteredIn() )
240 		GetRegisteredInNonConst()->Remove( this );
241 
242 }
243 /* -----------------------------22.02.01 13:42--------------------------------
244 
245  ---------------------------------------------------------------------------*/
246 SwNumFmt::~SwNumFmt()
247 {
248 	delete pVertOrient;
249 }
250 /* -----------------------------02.07.01 15:37--------------------------------
251 
252  ---------------------------------------------------------------------------*/
253 void SwNumFmt::NotifyGraphicArrived()
254 {
255     if( GetCharFmt() )
256         UpdateNumNodes( (SwDoc*)GetCharFmt()->GetDoc() );
257 }
258 
259 // #i22362#
260 sal_Bool SwNumFmt::IsEnumeration() const
261 {
262     // --> FME 2004-08-12 #i30655# native numbering did not work any longer
263     // using this code. Therefore HBRINKM and I agreed upon defining
264     // IsEnumeration() as !IsItemize()
265     return !IsItemize();
266     // <--
267 
268     /*
269     sal_Bool bResult;
270 
271     switch(GetNumberingType())
272     {
273     case SVX_NUM_CHARS_UPPER_LETTER:
274 	case SVX_NUM_CHARS_LOWER_LETTER:
275 	case SVX_NUM_ROMAN_UPPER:
276 	case SVX_NUM_ROMAN_LOWER:
277 	case SVX_NUM_ARABIC:
278 	case SVX_NUM_PAGEDESC:
279 	case SVX_NUM_CHARS_UPPER_LETTER_N:
280     case SVX_NUM_CHARS_LOWER_LETTER_N:
281         bResult = sal_True;
282 
283         break;
284 
285     default:
286         bResult = sal_False;
287     }
288 
289     return bResult;
290      */
291 }
292 
293 // #i29560#
294 sal_Bool SwNumFmt::IsItemize() const
295 {
296     sal_Bool bResult;
297 
298     switch(GetNumberingType())
299     {
300 	case SVX_NUM_CHAR_SPECIAL:
301 	case SVX_NUM_BITMAP:
302         bResult = sal_True;
303 
304         break;
305 
306     default:
307         bResult = sal_False;
308     }
309 
310     return bResult;
311 
312 }
313 
314 
315 /* -----------------------------23.02.01 09:28--------------------------------
316 
317  ---------------------------------------------------------------------------*/
318 SwNumFmt& SwNumFmt::operator=( const SwNumFmt& rNumFmt)
319 {
320 	SvxNumberFormat::operator=(rNumFmt);
321 	if( rNumFmt.GetRegisteredIn() )
322 		rNumFmt.GetRegisteredInNonConst()->Add( this );
323 	else if( GetRegisteredIn() )
324 		GetRegisteredInNonConst()->Remove( this );
325 	return *this;
326 }
327 /* -----------------------------23.02.01 09:28--------------------------------
328 
329  ---------------------------------------------------------------------------*/
330 sal_Bool SwNumFmt::operator==( const SwNumFmt& rNumFmt) const
331 {
332 	sal_Bool bRet = SvxNumberFormat::operator==(rNumFmt) &&
333 		GetRegisteredIn() == rNumFmt.GetRegisteredIn();
334     return bRet;
335 }
336 
337 /* -----------------------------22.02.01 13:44--------------------------------
338 
339  ---------------------------------------------------------------------------*/
340 void SwNumFmt::SetCharFmt( SwCharFmt* pChFmt)
341 {
342 	if( pChFmt )
343 		pChFmt->Add( this );
344 	else if( GetRegisteredIn() )
345 		GetRegisteredInNonConst()->Remove( this );
346 }
347 /* -----------------------------22.02.01 13:45--------------------------------
348 
349  ---------------------------------------------------------------------------*/
350 void SwNumFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
351 {
352 	// dann suche mal in dem Doc nach dem NumRules-Object, in dem dieses
353 	// NumFormat gesetzt ist. Das Format muss es nicht geben!
354 	const SwCharFmt* pFmt = 0;
355     sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
356 	switch( nWhich )
357 	{
358 	case RES_ATTRSET_CHG:
359 	case RES_FMT_CHG:
360 		pFmt = GetCharFmt();
361 		break;
362 	}
363 
364 	if( pFmt && !pFmt->GetDoc()->IsInDtor() )
365 		UpdateNumNodes( (SwDoc*)pFmt->GetDoc() );
366 	else
367 		CheckRegistration( pOld, pNew );
368 }
369 /* -----------------------------23.02.01 11:08--------------------------------
370 
371  ---------------------------------------------------------------------------*/
372 void SwNumFmt::SetCharFmtName(const String& rSet)
373 {
374 	SvxNumberFormat::SetCharFmtName(rSet);
375 }
376 /* -----------------------------22.02.01 13:47--------------------------------
377 
378  ---------------------------------------------------------------------------*/
379 const String&	SwNumFmt::GetCharFmtName() const
380 {
381 	if((SwCharFmt*)GetRegisteredIn())
382 		return ((SwCharFmt*)GetRegisteredIn())->GetName();
383 	else
384 		return aEmptyStr;
385 }
386 
387 void SwNumFmt::ForgetCharFmt()
388 {
389     if ( GetRegisteredIn() )
390         GetRegisteredInNonConst()->Remove( this );
391 }
392 
393 /* -----------------------------22.02.01 16:05--------------------------------
394 
395  ---------------------------------------------------------------------------*/
396 void	SwNumFmt::SetGraphicBrush( const SvxBrushItem* pBrushItem, const Size* pSize,
397     const sal_Int16* pOrient)
398 {
399     if(pOrient)
400         pVertOrient->SetVertOrient( *pOrient );
401 	SvxNumberFormat::SetGraphicBrush( pBrushItem, pSize, pOrient);
402 }
403 /* -----------------------------22.02.01 16:05--------------------------------
404 
405  ---------------------------------------------------------------------------*/
406 void    SwNumFmt::SetVertOrient(sal_Int16 eSet)
407 {
408 	SvxNumberFormat::SetVertOrient(eSet);
409 }
410 /* -----------------------------22.02.01 16:05--------------------------------
411 
412  ---------------------------------------------------------------------------*/
413 sal_Int16   SwNumFmt::GetVertOrient() const
414 {
415     return SvxNumberFormat::GetVertOrient();
416 }
417 /* -----------------------------22.02.01 13:54--------------------------------
418 
419  ---------------------------------------------------------------------------*/
420 void SwNumFmt::UpdateNumNodes( SwDoc* pDoc )
421 {
422 	sal_Bool bDocIsModified = pDoc->IsModified();
423 	sal_Bool bFnd = sal_False;
424 	const SwNumRule* pRule;
425 	for( sal_uInt16 n = pDoc->GetNumRuleTbl().Count(); !bFnd && n; )
426 	{
427 		pRule = pDoc->GetNumRuleTbl()[ --n ];
428 		for( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
429 			if( pRule->GetNumFmt( i ) == this )
430 			{
431                 // --> OD 2008-02-19 #refactorlists#
432 //                const String& rRuleNm = pRule->GetName();
433 
434 //                SwModify* pMod;
435 //                const SfxPoolItem* pItem;
436 //                sal_uInt16 k, nMaxItems = pDoc->GetAttrPool().GetItemCount(
437 //                                                    RES_PARATR_NUMRULE );
438 //                for( k = 0; k < nMaxItems; ++k )
439 //                    if( 0 != (pItem = pDoc->GetAttrPool().GetItem(
440 //                        RES_PARATR_NUMRULE, k ) ) &&
441 //                        0 != ( pMod = (SwModify*)((SwNumRuleItem*)pItem)->
442 //                                GetDefinedIn()) &&
443 //                        ((SwNumRuleItem*)pItem)->GetValue() == rRuleNm )
444 //                    {
445 //                        if( pMod->IsA( TYPE( SwFmt )) )
446 //                        {
447 //                            SwNumRuleInfo aInfo( rRuleNm );
448 //                            pMod->GetInfo( aInfo );
449 
450 //                            for( sal_uLong nFirst = 0, nLast = aInfo.GetList().Count();
451 //                                nFirst < nLast; ++nFirst )
452 //                                lcl_SetRuleChgd(
453 //                                    *aInfo.GetList().GetObject( nFirst ), i );
454 //                        }
455 //                        else if( ((SwTxtNode*)pMod)->GetNodes().IsDocNodes() )
456 //                            lcl_SetRuleChgd( *(SwTxtNode*)pMod, i );
457 //                    }
458                 SwNumRule::tTxtNodeList aTxtNodeList;
459                 pRule->GetTxtNodeList( aTxtNodeList );
460                 for ( SwNumRule::tTxtNodeList::iterator aIter = aTxtNodeList.begin();
461                       aIter != aTxtNodeList.end(); ++aIter )
462                 {
463                     lcl_SetRuleChgd( *(*aIter), i );
464                 }
465                 // <--
466 				bFnd = sal_True;
467 				break;
468 			}
469 	}
470 
471 	if( bFnd && !bDocIsModified )
472 		pDoc->ResetModified();
473 }
474 /* -----------------------------31.05.01 16:08--------------------------------
475 
476  ---------------------------------------------------------------------------*/
477 const SwFmtVertOrient*      SwNumFmt::GetGraphicOrientation() const
478 {
479     sal_Int16  eOrient = SvxNumberFormat::GetVertOrient();
480     if(text::VertOrientation::NONE == eOrient)
481         return 0;
482     else
483     {
484         pVertOrient->SetVertOrient(eOrient);
485         return pVertOrient;
486     }
487 }
488 
489 #ifdef DBG_UTIL
490 long int SwNumRule::nInstances = 0;
491 #endif
492 
493 // --> OD 2008-02-11 #newlistlevelattrs#
494 // handle new parameter <eDefaultNumberFormatPositionAndSpaceMode>
495 SwNumRule::SwNumRule( const String& rNm,
496                       const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode,
497                       SwNumRuleType eType,
498                       sal_Bool bAutoFlg )
499     : maTxtNodeList(),
500       // --> OD 2008-03-03 #refactorlists#
501       maParagraphStyleList(),
502       // <--
503     pNumRuleMap(0),
504     sName( rNm ),
505     eRuleType( eType ),
506 	nPoolFmtId( USHRT_MAX ),
507 	nPoolHelpId( USHRT_MAX ),
508     nPoolHlpFileId( UCHAR_MAX ),
509 	bAutoRuleFlag( bAutoFlg ),
510 	bInvalidRuleFlag( sal_True ),
511 	bContinusNum( sal_False ),
512 	bAbsSpaces( sal_False ),
513     // --> OD 2005-10-21 - initialize member <mbCountPhantoms>
514     mbCountPhantoms( true ),
515     // <--
516     // --> OD 2008-02-11 #newlistlevelattrs#
517     meDefaultNumberFormatPositionAndSpaceMode( eDefaultNumberFormatPositionAndSpaceMode ),
518     // <--
519     // --> OD 2008-04-03 #refactorlists#
520     msDefaultListId()
521     // <--
522 {
523 #ifdef DBG_UTIL
524     nSerial = nInstances++;
525 #endif
526 
527 	if( !nRefCount++ )			// zum erstmal, also initialisiern
528 	{
529 		SwNumFmt* pFmt;
530 		sal_uInt8 n;
531 
532         // numbering:
533         // position-and-space mode LABEL_WIDTH_AND_POSITION:
534         for( n = 0; n < MAXLEVEL; ++n )
535         {
536             pFmt = new SwNumFmt;
537             pFmt->SetIncludeUpperLevels( 1 );
538             pFmt->SetStart( 1 );
539             pFmt->SetLSpace( lNumIndent );
540             pFmt->SetAbsLSpace( lNumIndent + SwNumRule::GetNumIndent( n ) );
541             pFmt->SetFirstLineOffset( lNumFirstLineOffset );
542             pFmt->SetSuffix( aDotStr );
543             // --> OD 2006-06-29 #b6440955#
544             pFmt->SetBulletChar( numfunc::GetBulletChar(n));
545             // <--
546             SwNumRule::aBaseFmts[ NUM_RULE ][ n ] = pFmt;
547         }
548         // --> OD 2008-02-11 #newlistlevelattrs#
549         // position-and-space mode LABEL_ALIGNMENT
550         // first line indent of general numbering in inch: -0,25 inch
551         const long cFirstLineIndent = -1440/4;
552         // indent values of general numbering in inch:
553         //  0,5         0,75        1,0         1,25        1,5
554         //  1,75        2,0         2,25        2,5         2,75
555         const long cIndentAt[ MAXLEVEL ] = {
556             1440/2,     1440*3/4,   1440,       1440*5/4,   1440*3/2,
557             1440*7/4,   1440*2,     1440*9/4,   1440*5/2,   1440*11/4 };
558 		for( n = 0; n < MAXLEVEL; ++n )
559 		{
560 			pFmt = new SwNumFmt;
561 			pFmt->SetIncludeUpperLevels( 1 );
562 			pFmt->SetStart( 1 );
563             // --> OD 2008-01-15 #newlistlevelattrs#
564             pFmt->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT );
565             pFmt->SetLabelFollowedBy( SvxNumberFormat::LISTTAB );
566             pFmt->SetListtabPos( cIndentAt[ n ] );
567             pFmt->SetFirstLineIndent( cFirstLineIndent );
568             pFmt->SetIndentAt( cIndentAt[ n ] );
569             // <--
570             pFmt->SetSuffix( aDotStr );
571             pFmt->SetBulletChar( numfunc::GetBulletChar(n));
572             SwNumRule::aLabelAlignmentBaseFmts[ NUM_RULE ][ n ] = pFmt;
573 		}
574         // <--
575 
576         // outline:
577         // position-and-space mode LABEL_WIDTH_AND_POSITION:
578         for( n = 0; n < MAXLEVEL; ++n )
579         {
580             pFmt = new SwNumFmt;
581             pFmt->SetNumberingType(SVX_NUM_NUMBER_NONE);
582             pFmt->SetIncludeUpperLevels( MAXLEVEL );
583             pFmt->SetStart( 1 );
584             pFmt->SetCharTextDistance( lOutlineMinTextDistance );
585             // --> OD 2006-06-29 #b6440955#
586             pFmt->SetBulletChar( numfunc::GetBulletChar(n));
587             // <--
588             SwNumRule::aBaseFmts[ OUTLINE_RULE ][ n ] = pFmt;
589         }
590         // --> OD 2008-02-11 #newlistlevelattrs#
591         // position-and-space mode LABEL_ALIGNMENT:
592         // indent values of default outline numbering in inch:
593         //  0,3         0,4         0,5         0,6         0,7
594         //  0,8         0,9         1,0         1,1         1,2
595         const long cOutlineIndentAt[ MAXLEVEL ] = {
596             1440*3/10,  1440*2/5,   1440/2,     1440*3/5,   1440*7/10,
597             1440*4/5,   1440*9/10,  1440,       1440*11/10, 1440*6/5 };
598 		for( n = 0; n < MAXLEVEL; ++n )
599 		{
600 			pFmt = new SwNumFmt;
601 			pFmt->SetNumberingType(SVX_NUM_NUMBER_NONE);
602 			pFmt->SetIncludeUpperLevels( MAXLEVEL );
603 			pFmt->SetStart( 1 );
604             pFmt->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT );
605             pFmt->SetLabelFollowedBy( SvxNumberFormat::LISTTAB );
606             pFmt->SetListtabPos( cOutlineIndentAt[ n ] );
607             pFmt->SetFirstLineIndent( -cOutlineIndentAt[ n ] );
608             pFmt->SetIndentAt( cOutlineIndentAt[ n ] );
609             pFmt->SetBulletChar( numfunc::GetBulletChar(n));
610             SwNumRule::aLabelAlignmentBaseFmts[ OUTLINE_RULE ][ n ] = pFmt;
611 		}
612         // <--
613 	}
614 	memset( aFmts, 0, sizeof( aFmts ));
615 	ASSERT( sName.Len(), "NumRule ohne Namen!" );
616 }
617 
618 SwNumRule::SwNumRule( const SwNumRule& rNumRule )
619     : maTxtNodeList(),
620       // --> OD 2008-03-03 #refactorlists#
621       maParagraphStyleList(),
622       // <--
623       pNumRuleMap(0),
624       sName( rNumRule.sName ),
625       eRuleType( rNumRule.eRuleType ),
626       nPoolFmtId( rNumRule.GetPoolFmtId() ),
627       nPoolHelpId( rNumRule.GetPoolHelpId() ),
628       nPoolHlpFileId( rNumRule.GetPoolHlpFileId() ),
629       bAutoRuleFlag( rNumRule.bAutoRuleFlag ),
630       bInvalidRuleFlag( sal_True ),
631       bContinusNum( rNumRule.bContinusNum ),
632       bAbsSpaces( rNumRule.bAbsSpaces ),
633       // --> OD 2005-10-21 - initialize member <mbCountPhantoms>
634       mbCountPhantoms( true ),
635       // <--
636       // --> OD 2008-02-11 #newlistlevelattrs#
637       meDefaultNumberFormatPositionAndSpaceMode( rNumRule.meDefaultNumberFormatPositionAndSpaceMode ),
638       // <--
639       // --> OD 2008-04-03 #refactorlists#
640       msDefaultListId( rNumRule.msDefaultListId )
641       // <--
642 {
643 #ifdef DBG_UTIL
644     nSerial = nInstances++;
645 #endif
646 
647 	++nRefCount;
648 	memset( aFmts, 0, sizeof( aFmts ));
649 	for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
650 		if( rNumRule.aFmts[ n ] )
651 			Set( n, *rNumRule.aFmts[ n ] );
652 }
653 
654 SwNumRule::~SwNumRule()
655 {
656 	for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
657 		delete aFmts[ n ];
658 
659     if (pNumRuleMap)
660     {
661         pNumRuleMap->erase(GetName());
662     }
663 
664 	if( !--nRefCount )			// der letzte macht die Tuer zu
665 	{
666 			// Nummerierung:
667 			SwNumFmt** ppFmts = (SwNumFmt**)SwNumRule::aBaseFmts;
668 			int n;
669 
670 			for( n = 0; n < MAXLEVEL; ++n, ++ppFmts )
671 				delete *ppFmts, *ppFmts = 0;
672 
673 			// Gliederung:
674 			for( n = 0; n < MAXLEVEL; ++n, ++ppFmts )
675 				delete *ppFmts, *ppFmts = 0;
676 
677             // --> OD 2008-02-11 #newlistlevelattrs#
678             ppFmts = (SwNumFmt**)SwNumRule::aLabelAlignmentBaseFmts;
679             for( n = 0; n < MAXLEVEL; ++n, ++ppFmts )
680                 delete *ppFmts, *ppFmts = 0;
681             for( n = 0; n < MAXLEVEL; ++n, ++ppFmts )
682                 delete *ppFmts, *ppFmts = 0;
683             // <--
684     }
685 
686     // --> OD 2008-02-19 #refactorlists#
687     maTxtNodeList.clear();
688     maParagraphStyleList.clear();
689     // <--
690 }
691 
692 void SwNumRule::CheckCharFmts( SwDoc* pDoc )
693 {
694 	SwCharFmt* pFmt;
695 	for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
696 		if( aFmts[ n ] && 0 != ( pFmt = aFmts[ n ]->GetCharFmt() ) &&
697 			pFmt->GetDoc() != pDoc )
698 		{
699 			// dann kopieren!
700 			SwNumFmt* pNew = new SwNumFmt( *aFmts[ n ] );
701 			pNew->SetCharFmt( pDoc->CopyCharFmt( *pFmt ) );
702 			delete aFmts[ n ];
703 			aFmts[ n ] = pNew;
704 		}
705 }
706 
707 SwNumRule& SwNumRule::operator=( const SwNumRule& rNumRule )
708 {
709 	if( this != &rNumRule )
710 	{
711 		for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
712 			Set( n, rNumRule.aFmts[ n ] );
713 
714 		eRuleType = rNumRule.eRuleType;
715 		sName = rNumRule.sName;
716 		bAutoRuleFlag = rNumRule.bAutoRuleFlag;
717 		bInvalidRuleFlag = sal_True;
718 		bContinusNum = rNumRule.bContinusNum;
719 		bAbsSpaces = rNumRule.bAbsSpaces;
720 		nPoolFmtId = rNumRule.GetPoolFmtId();
721 		nPoolHelpId = rNumRule.GetPoolHelpId();
722 		nPoolHlpFileId = rNumRule.GetPoolHlpFileId();
723 	}
724 	return *this;
725 }
726 
727 
728 sal_Bool SwNumRule::operator==( const SwNumRule& rRule ) const
729 {
730 	sal_Bool bRet = eRuleType == rRule.eRuleType &&
731 				sName == rRule.sName &&
732 				bAutoRuleFlag == rRule.bAutoRuleFlag &&
733 				bContinusNum == rRule.bContinusNum &&
734 				bAbsSpaces == rRule.bAbsSpaces &&
735 				nPoolFmtId == rRule.GetPoolFmtId() &&
736 				nPoolHelpId == rRule.GetPoolHelpId() &&
737 				nPoolHlpFileId == rRule.GetPoolHlpFileId();
738 	if( bRet )
739 	{
740 		for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
741 			if( !( rRule.Get( n ) == Get( n ) ))
742 			{
743 				bRet = sal_False;
744 				break;
745 			}
746 	}
747 	return bRet;
748 }
749 
750 
751 void SwNumRule::Set( sal_uInt16 i, const SwNumFmt& rNumFmt )
752 {
753     ASSERT( i < MAXLEVEL, "Serious defect, please inform OD" )
754     if( i < MAXLEVEL )
755     {
756         if( !aFmts[ i ] || !(rNumFmt == Get( i )) )
757         {
758             delete aFmts[ i ];
759             aFmts[ i ] = new SwNumFmt( rNumFmt );
760             bInvalidRuleFlag = sal_True;
761         }
762 	}
763 }
764 
765 void SwNumRule::Set( sal_uInt16 i, const SwNumFmt* pNumFmt )
766 {
767     ASSERT( i < MAXLEVEL, "Serious defect, please inform OD" )
768     if( i >= MAXLEVEL )
769         return;
770 	SwNumFmt* pOld = aFmts[ i ];
771 	if( !pOld )
772 	{
773 		if( pNumFmt )
774 		{
775 			aFmts[ i ] = new SwNumFmt( *pNumFmt );
776 			bInvalidRuleFlag = sal_True;
777 		}
778 	}
779 	else if( !pNumFmt )
780 		delete pOld, aFmts[ i ] = 0, bInvalidRuleFlag = sal_True;
781 	else if( *pOld != *pNumFmt )
782 		*pOld = *pNumFmt, bInvalidRuleFlag = sal_True;
783 }
784 
785 
786 String SwNumRule::MakeNumString( const SwNodeNum& rNum, sal_Bool bInclStrings,
787 								sal_Bool bOnlyArabic ) const
788 {
789     String aStr;
790 
791     if (rNum.IsCounted())
792         aStr = MakeNumString(rNum.GetNumberVector(),
793                              bInclStrings, bOnlyArabic, MAXLEVEL);
794 
795     return aStr;
796 }
797 
798 String SwNumRule::MakeNumString( const SwNumberTree::tNumberVector & rNumVector,
799                                  const sal_Bool bInclStrings,
800                                  const sal_Bool bOnlyArabic,
801                                  const unsigned int _nRestrictToThisLevel ) const
802 {
803 	String aStr;
804 
805     unsigned int nLevel = rNumVector.size() - 1;
806     // --> OD 2005-10-17 #126238#
807     if ( nLevel > _nRestrictToThisLevel )
808     {
809         nLevel = _nRestrictToThisLevel;
810     }
811     // <--
812 
813     if (nLevel < MAXLEVEL)
814     {
815         const SwNumFmt& rMyNFmt = Get( static_cast<sal_uInt16>(nLevel) );
816         // --> OD 2006-06-02 #b6432095#
817         // - levels with numbering none has to provide prefix and suffix string
818 //        if( SVX_NUM_NUMBER_NONE != rMyNFmt.GetNumberingType() )
819         // <--
820         {
821             sal_uInt8 i = static_cast<sal_uInt8>(nLevel);
822 
823             if( !IsContinusNum() &&
824                 // --> OD 2006-09-19 #i69672#
825                 // - do not include upper levels, if level isn't numbered.
826                 rMyNFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE &&
827                 // <--
828                 rMyNFmt.GetIncludeUpperLevels() )  // nur der eigene Level ?
829             {
830                 sal_uInt8 n = rMyNFmt.GetIncludeUpperLevels();
831                 if( 1 < n )
832                 {
833                     if( i+1 >= n )
834                         i -= n - 1;
835                     else
836                         i = 0;
837                 }
838             }
839 
840             for( ; i <= nLevel; ++i )
841             {
842                 const SwNumFmt& rNFmt = Get( i );
843                 if( SVX_NUM_NUMBER_NONE == rNFmt.GetNumberingType() )
844                 {
845                     // Soll aus 1.1.1 --> 2. NoNum --> 1..1 oder 1.1 ??
846                     //                 if( i != rNum.nMyLevel )
847                     //                    aStr += aDotStr;
848                     continue;
849                 }
850 
851                 if( rNumVector[ i ] )
852                 {
853                     if( bOnlyArabic )
854                         aStr += String::CreateFromInt32( rNumVector[ i ] );
855                     else
856                         aStr += rNFmt.GetNumStr( rNumVector[ i ] );
857                 }
858                 else
859                     aStr += '0';		// alle 0-Level sind eine 0
860                 if( i != nLevel && aStr.Len() )
861                     aStr += aDotStr;
862             }
863 
864             //JP 14.12.99: the type dont have any number, so dont append
865             //				the Post-/Prefix String
866             if( bInclStrings && !bOnlyArabic &&
867                 SVX_NUM_CHAR_SPECIAL != rMyNFmt.GetNumberingType() &&
868                 SVX_NUM_BITMAP != rMyNFmt.GetNumberingType() )
869             {
870                 aStr.Insert( rMyNFmt.GetPrefix(), 0 );
871                 aStr += rMyNFmt.GetSuffix();
872             }
873         }
874     }
875 
876 	return aStr;
877 }
878 
879 // --> OD 2007-09-07 #i81002#
880 String SwNumRule::MakeRefNumString( const SwNodeNum& rNodeNum,
881                                     const bool bInclSuperiorNumLabels,
882                                     const sal_uInt8 nRestrictInclToThisLevel ) const
883 {
884     String aRefNumStr;
885 
886     if ( rNodeNum.GetLevelInListTree() >= 0 )
887     {
888         const SwNodeNum* pWorkingNodeNum( &rNodeNum );
889         do
890         {
891             bool bMakeNumStringForPhantom( false );
892             if ( pWorkingNodeNum->IsPhantom() )
893             {
894                 SwNumFmt aFmt( Get( static_cast<sal_uInt16>(pWorkingNodeNum->GetLevelInListTree()) ) );
895                 bMakeNumStringForPhantom = aFmt.IsEnumeration() &&
896                                            SVX_NUM_NUMBER_NONE != aFmt.GetNumberingType();
897 
898             }
899             if ( bMakeNumStringForPhantom ||
900                  ( !pWorkingNodeNum->IsPhantom() &&
901                    pWorkingNodeNum->GetTxtNode() &&
902                    pWorkingNodeNum->GetTxtNode()->HasNumber() ) )
903             {
904                 aRefNumStr.Insert( MakeNumString( pWorkingNodeNum->GetNumberVector() ), 0 );
905             }
906             else if ( aRefNumStr.Len() > 0 )
907             {
908                 aRefNumStr.Insert( String::CreateFromAscii(" "), 0 );
909             }
910 
911             if ( bInclSuperiorNumLabels && pWorkingNodeNum->GetLevelInListTree() > 0 )
912             {
913                 sal_uInt8 n = Get( static_cast<sal_uInt16>(pWorkingNodeNum->GetLevelInListTree()) ).GetIncludeUpperLevels();
914                 pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
915                 // skip parents, whose list label is already contained in the actual list label.
916                 while ( pWorkingNodeNum && n > 1 )
917                 {
918                     pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
919                     --n;
920                 }
921             }
922             else
923             {
924                 break;
925             }
926         } while ( pWorkingNodeNum &&
927                   pWorkingNodeNum->GetLevelInListTree() >= 0 &&
928                   static_cast<sal_uInt8>(pWorkingNodeNum->GetLevelInListTree()) >= nRestrictInclToThisLevel );
929     }
930 
931     return aRefNumStr;
932 }
933 
934 //  ----- Copy-Methode vom SwNumRule ------
935 
936 	// eine Art Copy-Constructor, damit die Num-Formate auch an den
937 	// richtigen CharFormaten eines Dokumentes haengen !!
938 	// (Kopiert die NumFormate und returnt sich selbst)
939 
940 SwNumRule& SwNumRule::CopyNumRule( SwDoc* pDoc, const SwNumRule& rNumRule )
941 {
942 	for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
943 	{
944 		Set( n, rNumRule.aFmts[ n ] );
945 		if( aFmts[ n ] && aFmts[ n ]->GetCharFmt() &&
946 			USHRT_MAX == pDoc->GetCharFmts()->GetPos( aFmts[n]->GetCharFmt() ))
947 			// ueber unterschiedliche Dokumente kopieren, dann
948 			// kopiere das entsprechende Char-Format ins neue
949 			// Dokument.
950 			aFmts[n]->SetCharFmt( pDoc->CopyCharFmt( *aFmts[n]->
951 										GetCharFmt() ) );
952 	}
953 	eRuleType = rNumRule.eRuleType;
954 	sName = rNumRule.sName;
955 	bAutoRuleFlag = rNumRule.bAutoRuleFlag;
956 	nPoolFmtId = rNumRule.GetPoolFmtId();
957 	nPoolHelpId = rNumRule.GetPoolHelpId();
958 	nPoolHlpFileId = rNumRule.GetPoolHlpFileId();
959 	bInvalidRuleFlag = sal_True;
960 	return *this;
961 }
962 /* -----------------30.10.98 08:33-------------------
963  *
964  * --------------------------------------------------*/
965 void SwNumRule::SetSvxRule(const SvxNumRule& rNumRule, SwDoc* pDoc)
966 {
967 	for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
968 	{
969 		const SvxNumberFormat* pSvxFmt = rNumRule.Get(n);
970 		delete aFmts[n];
971 		aFmts[n] = pSvxFmt ? new SwNumFmt(*pSvxFmt, pDoc) : 0;
972 	}
973 
974 	bInvalidRuleFlag = sal_True;
975 	bContinusNum = rNumRule.IsContinuousNumbering();
976 }
977 /* -----------------30.10.98 08:33-------------------
978  *
979  * --------------------------------------------------*/
980 SvxNumRule SwNumRule::MakeSvxNumRule() const
981 {
982 	SvxNumRule aRule(NUM_CONTINUOUS|NUM_CHAR_TEXT_DISTANCE|NUM_CHAR_STYLE|
983 						NUM_ENABLE_LINKED_BMP|NUM_ENABLE_EMBEDDED_BMP,
984 						MAXLEVEL, bContinusNum,
985 						eRuleType ==
986 							NUM_RULE ?
987 								SVX_RULETYPE_NUMBERING :
988 									SVX_RULETYPE_OUTLINE_NUMBERING );
989 	for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
990 	{
991         SwNumFmt aNumFmt = Get(n);
992         if(aNumFmt.GetCharFmt())
993             aNumFmt.SetCharFmtName(aNumFmt.GetCharFmt()->GetName());
994         aRule.SetLevel(n, aNumFmt, aFmts[n] != 0);
995 	}
996 	return aRule;
997 }
998 
999 void SwNumRule::SetInvalidRule(sal_Bool bFlag)
1000 {
1001     if (bFlag)
1002     {
1003         // --> OD 2008-03-13 #refactorlists#
1004 //        tPamAndNums::iterator aIt;
1005 //        for (aIt = aNumberRanges.begin(); aIt != aNumberRanges.end(); aIt++)
1006 //            (*aIt).second->InvalidateTree();
1007         std::set< SwList* > aLists;
1008         tTxtNodeList::iterator aIter;
1009         for ( aIter = maTxtNodeList.begin(); aIter != maTxtNodeList.end(); ++aIter )
1010         {
1011             const SwTxtNode* pTxtNode = *aIter;
1012             // --> OD 2010-06-04 #i111681# - applying patch from cmc
1013 //            aLists.insert( pTxtNode->GetDoc()->getListByName( pTxtNode->GetListId() ) );
1014             SwList* pList = pTxtNode->GetDoc()->getListByName( pTxtNode->GetListId() );
1015             ASSERT( pList, "<SwNumRule::SetInvalidRule(..)> - list at which the text node is registered at does not exist. This is a serious issue --> please inform OD.");
1016             if ( pList )
1017             {
1018                 aLists.insert( pList );
1019             }
1020             // <--
1021         }
1022         std::for_each( aLists.begin(), aLists.end(),
1023                        std::mem_fun( &SwList::InvalidateListTree ) );
1024         // <--
1025     }
1026 
1027     bInvalidRuleFlag = bFlag;
1028 }
1029 
1030 // --> OD 2008-06-16 #i90078#
1031 // #i23725#, #i23726#
1032 //void SwNumRule::Indent(short nAmount, int nLevel, int nReferenceLevel,
1033 //                       sal_Bool bRelative, sal_Bool bFirstLine, sal_Bool bCheckGtZero)
1034 //{
1035 //    int nStartLevel = 0;
1036 //    int nEndLevel = MAXLEVEL - 1;
1037 //    sal_Bool bGotInvalid = sal_False;
1038 
1039 //    if (nLevel >= 0)
1040 //        nStartLevel = nEndLevel = nLevel;
1041 
1042 //    int i;
1043 //    short nRealAmount =  nAmount;
1044 
1045 //    if (! bRelative)
1046 //    {
1047 //        if (bFirstLine)
1048 //        {
1049 //            if (nReferenceLevel >= 0)
1050 //                nAmount = nAmount - Get(static_cast<sal_uInt16>(nReferenceLevel)).GetFirstLineOffset();
1051 //            else
1052 //                nAmount = nAmount - Get(static_cast<sal_uInt16>(nStartLevel)).GetFirstLineOffset();
1053 //        }
1054 
1055 //        sal_Bool bFirst = sal_True;
1056 
1057 //        if (nReferenceLevel >= 0)
1058 //            nRealAmount = nAmount - Get(static_cast<sal_uInt16>(nReferenceLevel)).GetAbsLSpace();
1059 //        else
1060 //            for (i = nStartLevel; i < nEndLevel + 1; i++)
1061 //            {
1062 //                short nTmp = nAmount - Get(static_cast<sal_uInt16>(i)).GetAbsLSpace();
1063 
1064 //                if (bFirst || nTmp > nRealAmount)
1065 //                {
1066 //                    nRealAmount = nTmp;
1067 //                    bFirst = sal_False;
1068 //                }
1069 //            }
1070 //    }
1071 
1072 //    if (nRealAmount < 0)
1073 //        for (i = nStartLevel; i < nEndLevel + 1; i++)
1074 //            if (Get(static_cast<sal_uInt16>(i)).GetAbsLSpace() + nRealAmount < 0)
1075 //                nRealAmount = -Get(static_cast<sal_uInt16>(i)).GetAbsLSpace();
1076 
1077 //    for (i = nStartLevel; i < nEndLevel + 1; i++)
1078 //    {
1079 //        short nNew = Get(static_cast<sal_uInt16>(i)).GetAbsLSpace() + nRealAmount;
1080 
1081 //        if (bCheckGtZero && nNew < 0)
1082 //            nNew = 0;
1083 
1084 //        SwNumFmt aTmpNumFmt(Get(static_cast<sal_uInt16>(i)));
1085 //        aTmpNumFmt.SetAbsLSpace(nNew);
1086 
1087 //        Set(static_cast<sal_uInt16>(i), aTmpNumFmt);
1088 
1089 //        bGotInvalid = sal_True;
1090 //    }
1091 
1092 //    if (bGotInvalid)
1093 //        SetInvalidRule(bGotInvalid);
1094 //}
1095 
1096 // change indent of all list levels by given difference
1097 void SwNumRule::ChangeIndent( const short nDiff )
1098 {
1099     for ( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
1100     {
1101         SwNumFmt aTmpNumFmt( Get(i) );
1102 
1103         const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
1104                                         aTmpNumFmt.GetPositionAndSpaceMode() );
1105         if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1106         {
1107             short nNewIndent = nDiff +
1108                                aTmpNumFmt.GetAbsLSpace();
1109             if ( nNewIndent < 0 )
1110             {
1111                 nNewIndent = 0;
1112             }
1113             aTmpNumFmt.SetAbsLSpace( nNewIndent );
1114         }
1115         else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1116         {
1117             // --> OD 2009-01-20 #i93399#
1118             // adjust also the list tab position, if a list tab stop is applied
1119             if ( aTmpNumFmt.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
1120             {
1121                 const long nNewListTab = aTmpNumFmt.GetListtabPos() +  nDiff;
1122                 aTmpNumFmt.SetListtabPos( nNewListTab );
1123             }
1124             // <--
1125             const long nNewIndent = nDiff +
1126                               aTmpNumFmt.GetIndentAt();
1127             aTmpNumFmt.SetIndentAt( nNewIndent );
1128         }
1129 
1130         Set( i, aTmpNumFmt );
1131     }
1132 
1133     SetInvalidRule( sal_True );
1134 }
1135 
1136 // set indent of certain list level to given value
1137 void SwNumRule::SetIndent( const short nNewIndent,
1138                            const sal_uInt16 nListLevel )
1139 {
1140     SwNumFmt aTmpNumFmt( Get(nListLevel) );
1141 
1142     const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
1143                                         aTmpNumFmt.GetPositionAndSpaceMode() );
1144     if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1145     {
1146         aTmpNumFmt.SetAbsLSpace( nNewIndent );
1147     }
1148     else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1149     {
1150         // --> OD 2009-01-20 #i93399#
1151         // adjust also the list tab position, if a list tab stop is applied
1152         if ( aTmpNumFmt.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
1153         {
1154             const long nNewListTab = aTmpNumFmt.GetListtabPos() +
1155                                      ( nNewIndent - aTmpNumFmt.GetIndentAt() );
1156             aTmpNumFmt.SetListtabPos( nNewListTab );
1157         }
1158         // <--
1159         aTmpNumFmt.SetIndentAt( nNewIndent );
1160     }
1161 
1162     SetInvalidRule( sal_True );
1163 }
1164 
1165 // set indent of first list level to given value and change other list level's
1166 // indents accordingly
1167 void SwNumRule::SetIndentOfFirstListLevelAndChangeOthers( const short nNewIndent )
1168 {
1169     SwNumFmt aTmpNumFmt( Get(0) );
1170 
1171     short nDiff( 0 );
1172     const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
1173                                         aTmpNumFmt.GetPositionAndSpaceMode() );
1174     if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1175     {
1176         nDiff = nNewIndent
1177                 - aTmpNumFmt.GetFirstLineOffset()
1178                 - aTmpNumFmt.GetAbsLSpace();
1179     }
1180     else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1181     {
1182         nDiff = static_cast<short>(nNewIndent
1183                                    - aTmpNumFmt.GetIndentAt());
1184     }
1185     if ( nDiff != 0  )
1186     {
1187         ChangeIndent( nDiff );
1188     }
1189 }
1190 // <--
1191 
1192 void SwNumRule::Validate()
1193 {
1194     // --> OD 2008-03-13 #refactorlists#
1195 //    tPamAndNums::iterator aIt;
1196 //    for (aIt = aNumberRanges.begin(); aIt != aNumberRanges.end(); aIt++)
1197 //        (*aIt).second->NotifyInvalidChildren();
1198     std::set< SwList* > aLists;
1199     tTxtNodeList::iterator aIter;
1200     for ( aIter = maTxtNodeList.begin(); aIter != maTxtNodeList.end(); ++aIter )
1201     {
1202         const SwTxtNode* pTxtNode = *aIter;
1203         aLists.insert( pTxtNode->GetDoc()->getListByName( pTxtNode->GetListId() ) );
1204     }
1205     std::for_each( aLists.begin(), aLists.end(),
1206                    std::mem_fun( &SwList::ValidateListTree ) );
1207     // <--
1208 
1209     SetInvalidRule(sal_False);
1210 }
1211 
1212 bool SwNumRule::IsCountPhantoms() const
1213 {
1214     return mbCountPhantoms;
1215 }
1216 
1217 void SwNumRule::SetCountPhantoms(bool bCountPhantoms)
1218 {
1219     mbCountPhantoms = bCountPhantoms;
1220 }
1221 
1222 // --> OD 2008-03-03 #refactorlists#
1223 SwNumRule::tParagraphStyleList::size_type SwNumRule::GetParagraphStyleListSize() const
1224 {
1225     return maParagraphStyleList.size();
1226 }
1227 
1228 void SwNumRule::AddParagraphStyle( SwTxtFmtColl& rTxtFmtColl )
1229 {
1230     tParagraphStyleList::iterator aIter =
1231         std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTxtFmtColl );
1232 
1233     if ( aIter == maParagraphStyleList.end() )
1234     {
1235         maParagraphStyleList.push_back( &rTxtFmtColl );
1236     }
1237 }
1238 
1239 void SwNumRule::RemoveParagraphStyle( SwTxtFmtColl& rTxtFmtColl )
1240 {
1241     tParagraphStyleList::iterator aIter =
1242         std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTxtFmtColl );
1243 
1244     if ( aIter != maParagraphStyleList.end() )
1245     {
1246         maParagraphStyleList.erase( aIter );
1247     }
1248 }
1249 // <--
1250 
1251 // --> OD 2006-06-27 #b6440955#
1252 namespace numfunc
1253 {
1254     /** class containing default bullet list configuration data
1255 
1256         @author OD
1257     */
1258     class SwDefBulletConfig : private utl::ConfigItem
1259     {
1260         public:
1261             static SwDefBulletConfig* getInstance()
1262             {
1263                 if ( mpInstance == 0 )
1264                 {
1265                     mpInstance = new SwDefBulletConfig;
1266                 }
1267 
1268                 return mpInstance;
1269             }
1270 
1271             inline const String& GetFontname() const
1272             {
1273                 return msFontname;
1274             }
1275             // --> OD 2008-06-02 #i63395#
1276             inline bool IsFontnameUserDefined() const
1277             {
1278                 return mbUserDefinedFontname;
1279             }
1280             // <--
1281             inline const Font& GetFont() const
1282             {
1283                 return *mpFont;
1284             }
1285             inline short GetFontWeight() const
1286             {
1287                 return static_cast<short>(meFontWeight);
1288             }
1289             inline short GetFontItalic() const
1290             {
1291                 return static_cast<short>(meFontItalic);
1292             }
1293             inline sal_Unicode GetChar( sal_uInt8 p_nListLevel ) const
1294             {
1295                 if ( p_nListLevel > MAXLEVEL )
1296                 {
1297                     p_nListLevel = MAXLEVEL;
1298                 }
1299 
1300                 return mnLevelChars[p_nListLevel];
1301             }
1302 
1303         private:
1304             SwDefBulletConfig();
1305 
1306             /** sets internal default bullet configuration data to default values
1307 
1308                 @author OD
1309             */
1310             void SetToDefault();
1311 
1312             /** returns sequence of default bullet configuration property names
1313 
1314                 @author OD
1315             */
1316             uno::Sequence<rtl::OUString> GetPropNames() const;
1317 
1318             /** loads default bullet configuration properties and applies
1319                 values to internal data
1320 
1321                 @author OD
1322             */
1323             void LoadConfig();
1324 
1325             /** initialize font instance for default bullet list
1326 
1327                 @author OD
1328             */
1329             void InitFont();
1330 
1331             /** catches notification about changed default bullet configuration data
1332 
1333                 @author OD
1334             */
1335             virtual void Notify( const uno::Sequence<rtl::OUString>& aPropertyNames );
1336 			virtual void Commit();
1337 
1338             static SwDefBulletConfig* mpInstance;
1339 
1340             // default bullet list configuration data
1341             String msFontname;
1342             // --> OD 2008-06-02 #i63395#
1343             bool mbUserDefinedFontname;
1344             // <--
1345             FontWeight meFontWeight;
1346             FontItalic meFontItalic;
1347             sal_Unicode mnLevelChars[MAXLEVEL];
1348 
1349             // default bullet list font instance
1350             Font* mpFont;
1351     };
1352 
1353     SwDefBulletConfig* SwDefBulletConfig::mpInstance = 0;
1354 
1355     SwDefBulletConfig::SwDefBulletConfig()
1356         : ConfigItem( rtl::OUString::createFromAscii("Office.Writer/Numbering/DefaultBulletList") ),
1357           // --> OD 2008-06-02 #i63395#
1358           // default bullet font is now OpenSymbol
1359           msFontname( String::CreateFromAscii("OpenSymbol") ),
1360           mbUserDefinedFontname( false ),
1361           // <--
1362           meFontWeight( WEIGHT_DONTKNOW ),
1363           meFontItalic( ITALIC_NONE ),
1364           mpFont( 0 )
1365     {
1366         SetToDefault();
1367         LoadConfig();
1368         InitFont();
1369 
1370         // enable notification for changes on default bullet configuration change
1371         EnableNotification( GetPropNames() );
1372     }
1373 
1374     void SwDefBulletConfig::SetToDefault()
1375     {
1376         // --> OD 2008-06-02 #i63395#
1377         // default bullet font name is now OpenSymbol
1378 //        msFontname = String::CreateFromAscii("StarSymbol");
1379         msFontname = String::CreateFromAscii("OpenSymbol");
1380         mbUserDefinedFontname = false;
1381         // <--
1382         meFontWeight = WEIGHT_DONTKNOW;
1383         meFontItalic = ITALIC_NONE;
1384 
1385         // --> OD 2008-06-03 #i63395#
1386         // new bullet characters
1387 //        mnLevelChars[0] = 0x25cf;
1388 //        mnLevelChars[1] = 0x25cb;
1389 //        mnLevelChars[2] = 0x25a0;
1390 //        mnLevelChars[3] = 0x25cf;
1391 //        mnLevelChars[4] = 0x25cb;
1392 //        mnLevelChars[5] = 0x25a0;
1393 //        mnLevelChars[6] = 0x25cf;
1394 //        mnLevelChars[7] = 0x25cb;
1395 //        mnLevelChars[8] = 0x25a0;
1396 //        mnLevelChars[9] = 0x25cf;
1397         mnLevelChars[0] = 0x2022;
1398         mnLevelChars[1] = 0x25e6;
1399         mnLevelChars[2] = 0x25aa;
1400         mnLevelChars[3] = 0x2022;
1401         mnLevelChars[4] = 0x25e6;
1402         mnLevelChars[5] = 0x25aa;
1403         mnLevelChars[6] = 0x2022;
1404         mnLevelChars[7] = 0x25e6;
1405         mnLevelChars[8] = 0x25aa;
1406         mnLevelChars[9] = 0x2022;
1407         // <--
1408     }
1409 
1410     uno::Sequence<rtl::OUString> SwDefBulletConfig::GetPropNames() const
1411     {
1412         uno::Sequence<rtl::OUString> aPropNames(13);
1413         rtl::OUString* pNames = aPropNames.getArray();
1414         pNames[0] = rtl::OUString::createFromAscii("BulletFont/FontFamilyname");
1415         pNames[1] = rtl::OUString::createFromAscii("BulletFont/FontWeight");
1416         pNames[2] = rtl::OUString::createFromAscii("BulletFont/FontItalic");
1417         pNames[3] = rtl::OUString::createFromAscii("BulletCharLvl1");
1418         pNames[4] = rtl::OUString::createFromAscii("BulletCharLvl2");
1419         pNames[5] = rtl::OUString::createFromAscii("BulletCharLvl3");
1420         pNames[6] = rtl::OUString::createFromAscii("BulletCharLvl4");
1421         pNames[7] = rtl::OUString::createFromAscii("BulletCharLvl5");
1422         pNames[8] = rtl::OUString::createFromAscii("BulletCharLvl6");
1423         pNames[9] = rtl::OUString::createFromAscii("BulletCharLvl7");
1424         pNames[10] = rtl::OUString::createFromAscii("BulletCharLvl8");
1425         pNames[11] = rtl::OUString::createFromAscii("BulletCharLvl9");
1426         pNames[12] = rtl::OUString::createFromAscii("BulletCharLvl10");
1427 
1428         return aPropNames;
1429     }
1430 
1431     void SwDefBulletConfig::LoadConfig()
1432     {
1433         uno::Sequence<rtl::OUString> aPropNames = GetPropNames();
1434         uno::Sequence<uno::Any> aValues =
1435                                                     GetProperties( aPropNames );
1436         const uno::Any* pValues = aValues.getConstArray();
1437         ASSERT( aValues.getLength() == aPropNames.getLength(),
1438                 "<SwDefBulletConfig::SwDefBulletConfig()> - GetProperties failed")
1439         if ( aValues.getLength() == aPropNames.getLength() )
1440         {
1441             for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1442             {
1443                 if ( pValues[nProp].hasValue() )
1444                 {
1445                     switch ( nProp )
1446                     {
1447                         case 0:
1448                         {
1449                             rtl::OUString aStr;
1450                             pValues[nProp] >>= aStr;
1451                             msFontname = aStr;
1452                             // --> OD 2008-06-02 #i63395#
1453                             mbUserDefinedFontname = true;
1454                             // <--
1455                         }
1456                         break;
1457                         case 1:
1458                         case 2:
1459                         {
1460                             sal_uInt8 nTmp = 0;
1461                             pValues[nProp] >>= nTmp;
1462                             if ( nProp == 1 )
1463                                 meFontWeight = static_cast<FontWeight>(nTmp);
1464                             else if ( nProp == 2 )
1465                                 meFontItalic = static_cast<FontItalic>(nTmp);
1466                         }
1467                         break;
1468                         case 3:
1469                         case 4:
1470                         case 5:
1471                         case 6:
1472                         case 7:
1473                         case 8:
1474                         case 9:
1475                         case 10:
1476                         case 11:
1477                         case 12:
1478                         {
1479                             sal_Unicode cChar = sal_Unicode();
1480                             pValues[nProp] >>= cChar;
1481                             mnLevelChars[nProp-3] = cChar;
1482                         }
1483                         break;
1484                     }
1485                 }
1486             }
1487         }
1488 
1489     }
1490 
1491     void SwDefBulletConfig::InitFont()
1492     {
1493         delete mpFont;
1494 
1495         mpFont = new Font( msFontname, aEmptyStr, Size( 0, 14 ) );
1496         mpFont->SetWeight( meFontWeight );
1497         mpFont->SetItalic( meFontItalic );
1498     }
1499 
1500     void SwDefBulletConfig::Notify( const uno::Sequence<rtl::OUString>& )
1501     {
1502         SetToDefault();
1503         LoadConfig();
1504         InitFont();
1505     }
1506 
1507 	void SwDefBulletConfig::Commit()
1508 	{
1509 	}
1510 
1511     const String& GetDefBulletFontname()
1512     {
1513         return SwDefBulletConfig::getInstance()->GetFontname();
1514     }
1515 
1516     // --> OD 2008-06-02 #i63395#
1517     bool IsDefBulletFontUserDefined()
1518     {
1519         return SwDefBulletConfig::getInstance()->IsFontnameUserDefined();
1520     }
1521     // <--
1522 
1523     const Font& GetDefBulletFont()
1524     {
1525         return SwDefBulletConfig::getInstance()->GetFont();
1526     }
1527 
1528     sal_Unicode GetBulletChar( sal_uInt8 nLevel )
1529     {
1530         return SwDefBulletConfig::getInstance()->GetChar( nLevel );
1531     }
1532 
1533     /** class containing configuration data about user interface behavior
1534         regarding lists and list items.
1535 
1536         OD 2007-10-01 #b660435#
1537         configuration item about behavior of <TAB>/<SHIFT-TAB>-key at first
1538         position of first list item
1539 
1540         @author OD
1541     */
1542     class SwNumberingUIBehaviorConfig : private utl::ConfigItem
1543     {
1544         public:
1545             static SwNumberingUIBehaviorConfig* getInstance()
1546             {
1547                 if ( mpInstance == 0 )
1548                 {
1549                     mpInstance = new SwNumberingUIBehaviorConfig();
1550                 }
1551 
1552                 return mpInstance;
1553             }
1554 
1555             inline sal_Bool ChangeIndentOnTabAtFirstPosOfFirstListItem() const
1556             {
1557                 return mbChangeIndentOnTabAtFirstPosOfFirstListItem;
1558             }
1559 
1560         private:
1561             SwNumberingUIBehaviorConfig();
1562 
1563             /** sets internal configuration data to default values
1564 
1565                 @author OD
1566             */
1567             void SetToDefault();
1568 
1569             /** returns sequence of configuration property names
1570 
1571                 @author OD
1572             */
1573             com::sun::star::uno::Sequence<rtl::OUString> GetPropNames() const;
1574 
1575             /** loads configuration properties and applies values to internal data
1576 
1577                 @author OD
1578             */
1579             void LoadConfig();
1580 
1581             /** catches notification about changed configuration data
1582 
1583                 @author OD
1584             */
1585             virtual void Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames );
1586 			virtual void Commit();
1587 
1588             static SwNumberingUIBehaviorConfig* mpInstance;
1589 
1590             // configuration data
1591             sal_Bool mbChangeIndentOnTabAtFirstPosOfFirstListItem;
1592     };
1593 
1594     SwNumberingUIBehaviorConfig* SwNumberingUIBehaviorConfig::mpInstance = 0;
1595 
1596     SwNumberingUIBehaviorConfig::SwNumberingUIBehaviorConfig()
1597         : ConfigItem( rtl::OUString::createFromAscii("Office.Writer/Numbering/UserInterfaceBehavior") ),
1598           mbChangeIndentOnTabAtFirstPosOfFirstListItem( sal_True )
1599     {
1600         SetToDefault();
1601         LoadConfig();
1602 
1603         // enable notification for changes on configuration change
1604         EnableNotification( GetPropNames() );
1605     }
1606 
1607     void SwNumberingUIBehaviorConfig::SetToDefault()
1608     {
1609         mbChangeIndentOnTabAtFirstPosOfFirstListItem = sal_True;
1610     }
1611 
1612     com::sun::star::uno::Sequence<rtl::OUString> SwNumberingUIBehaviorConfig::GetPropNames() const
1613     {
1614         com::sun::star::uno::Sequence<rtl::OUString> aPropNames(1);
1615         rtl::OUString* pNames = aPropNames.getArray();
1616         pNames[0] = rtl::OUString::createFromAscii("ChangeIndentOnTabAtFirstPosOfFirstListItem");
1617 
1618         return aPropNames;
1619     }
1620 
1621 	void SwNumberingUIBehaviorConfig::Commit() {}
1622 
1623     void SwNumberingUIBehaviorConfig::LoadConfig()
1624     {
1625         com::sun::star::uno::Sequence<rtl::OUString> aPropNames = GetPropNames();
1626         com::sun::star::uno::Sequence<com::sun::star::uno::Any> aValues =
1627                                                     GetProperties( aPropNames );
1628         const com::sun::star::uno::Any* pValues = aValues.getConstArray();
1629         ASSERT( aValues.getLength() == aPropNames.getLength(),
1630                 "<SwNumberingUIBehaviorConfig::LoadConfig()> - GetProperties failed")
1631         if ( aValues.getLength() == aPropNames.getLength() )
1632         {
1633             for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1634             {
1635                 if ( pValues[nProp].hasValue() )
1636                 {
1637                     switch ( nProp )
1638                     {
1639                         case 0:
1640                         {
1641                             pValues[nProp] >>= mbChangeIndentOnTabAtFirstPosOfFirstListItem;
1642                         }
1643                         break;
1644                         default:
1645                         {
1646                             ASSERT( false,
1647                                     "<SwNumberingUIBehaviorConfig::LoadConfig()> - unknown configuration property")
1648                         }
1649                     }
1650                 }
1651             }
1652         }
1653     }
1654 
1655     void SwNumberingUIBehaviorConfig::Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames )
1656     {
1657         (void) aPropertyNames;
1658         SetToDefault();
1659         LoadConfig();
1660     }
1661 
1662     sal_Bool ChangeIndentOnTabAtFirstPosOfFirstListItem()
1663     {
1664         return SwNumberingUIBehaviorConfig::getInstance()->ChangeIndentOnTabAtFirstPosOfFirstListItem();
1665     }
1666 
1667     // --> OD 2008-06-06 #i89178#
1668     SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
1669     {
1670         SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode;
1671         SvtSaveOptions aSaveOptions;
1672         switch ( aSaveOptions.GetODFDefaultVersion() )
1673         {
1674             case SvtSaveOptions::ODFVER_010:
1675             case SvtSaveOptions::ODFVER_011:
1676             {
1677                 ePosAndSpaceMode = SvxNumberFormat::LABEL_WIDTH_AND_POSITION;
1678             }
1679             break;
1680             default: // ODFVER_UNKNOWN or ODFVER_012
1681             {
1682                 ePosAndSpaceMode = SvxNumberFormat::LABEL_ALIGNMENT;
1683             }
1684         }
1685 
1686         return ePosAndSpaceMode;
1687     }
1688     // <--
1689 }
1690 // <--
1691