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 <hintids.hxx>
21 :
22 : #include <string.h>
23 : #include <vcl/font.hxx>
24 : #include <editeng/brshitem.hxx>
25 : #include <editeng/lrspitem.hxx>
26 : #include <editeng/numitem.hxx>
27 : #include <fmtornt.hxx>
28 : #include <doc.hxx>
29 : #include <pam.hxx>
30 : #include <charfmt.hxx>
31 : #include <paratr.hxx>
32 : #include <frmfmt.hxx>
33 : #include <ndtxt.hxx>
34 : #include <docary.hxx>
35 : #include <docsh.hxx>
36 : #include <SwStyleNameMapper.hxx>
37 :
38 : // Needed to load default bullet list configuration
39 : #include <unotools/configitem.hxx>
40 :
41 : #include <numrule.hxx>
42 : #include <SwNodeNum.hxx>
43 :
44 : #include <boost/unordered_map.hpp>
45 :
46 : #include <list.hxx>
47 : #include <algorithm>
48 :
49 : #include <unotools/saveopt.hxx>
50 :
51 : #include <IDocumentListsAccess.hxx>
52 :
53 : using namespace ::com::sun::star;
54 :
55 :
56 : sal_uInt16 SwNumRule::nRefCount = 0;
57 : SwNumFmt* SwNumRule::aBaseFmts[ RULE_END ][ MAXLEVEL ] = {
58 : {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
59 :
60 : SwNumFmt* SwNumRule::aLabelAlignmentBaseFmts[ RULE_END ][ MAXLEVEL ] = {
61 : {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
62 :
63 : char sOutline[] = "Outline";
64 : char* SwNumRule::pDefOutlineName = sOutline;
65 :
66 : sal_uInt16 SwNumRule::aDefNumIndents[ MAXLEVEL ] = {
67 : //inch: 0,5 1,0 1,5 2,0 2,5 3,0 3,5 4,0 4,5 5,0
68 : 1440/4, 1440/2, 1440*3/4, 1440, 1440*5/4, 1440*3/2, 1440*7/4, 1440*2,
69 : 1440*9/4, 1440*5/2
70 : };
71 :
72 45409 : const SwNumFmt& SwNumRule::Get( sal_uInt16 i ) const
73 : {
74 : OSL_ASSERT( i < MAXLEVEL && eRuleType < RULE_END );
75 45409 : return aFmts[ i ]
76 30372 : ? *aFmts[ i ]
77 : : ( meDefaultNumberFormatPositionAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
78 0 : ? *aBaseFmts[ eRuleType ][ i ]
79 121190 : : *aLabelAlignmentBaseFmts[ eRuleType ][ i ] );
80 : }
81 :
82 23575 : const SwNumFmt* SwNumRule::GetNumFmt( sal_uInt16 i ) const
83 : {
84 23575 : const SwNumFmt * pResult = NULL;
85 :
86 : OSL_ASSERT( i < MAXLEVEL && eRuleType < RULE_END );
87 23575 : if ( i < MAXLEVEL && eRuleType < RULE_END)
88 : {
89 23575 : pResult = aFmts[ i ];
90 : }
91 :
92 23575 : return pResult;
93 : }
94 :
95 : // #i91400#
96 753 : void SwNumRule::SetName( const String & rName,
97 : IDocumentListsAccess& rDocListAccess)
98 : {
99 753 : if ( sName != rName )
100 : {
101 12 : if (pNumRuleMap)
102 : {
103 10 : pNumRuleMap->erase(sName);
104 10 : (*pNumRuleMap)[rName] = this;
105 :
106 10 : if ( GetDefaultListId().Len() > 0 )
107 : {
108 10 : rDocListAccess.trackChangeOfListStyleName( sName, rName );
109 : }
110 : }
111 :
112 12 : sName = rName;
113 : }
114 753 : }
115 :
116 :
117 1626 : void SwNumRule::GetTxtNodeList( SwNumRule::tTxtNodeList& rTxtNodeList ) const
118 : {
119 1626 : rTxtNodeList = maTxtNodeList;
120 1626 : }
121 :
122 :
123 77 : SwNumRule::tTxtNodeList::size_type SwNumRule::GetTxtNodeListSize() const
124 : {
125 77 : return maTxtNodeList.size();
126 : }
127 :
128 :
129 2756 : void SwNumRule::AddTxtNode( SwTxtNode& rTxtNode )
130 : {
131 : tTxtNodeList::iterator aIter =
132 2756 : std::find( maTxtNodeList.begin(), maTxtNodeList.end(), &rTxtNode );
133 :
134 2756 : if ( aIter == maTxtNodeList.end() )
135 : {
136 2756 : maTxtNodeList.push_back( &rTxtNode );
137 : }
138 2756 : }
139 :
140 :
141 2694 : void SwNumRule::RemoveTxtNode( SwTxtNode& rTxtNode )
142 : {
143 : tTxtNodeList::iterator aIter =
144 2694 : std::find( maTxtNodeList.begin(), maTxtNodeList.end(), &rTxtNode );
145 :
146 2694 : if ( aIter != maTxtNodeList.end() )
147 : {
148 2694 : maTxtNodeList.erase( aIter );
149 : }
150 2694 : }
151 :
152 :
153 1197 : void SwNumRule::SetNumRuleMap(boost::unordered_map<String, SwNumRule *, StringHash> *
154 : _pNumRuleMap)
155 : {
156 1197 : pNumRuleMap = _pNumRuleMap;
157 1197 : }
158 :
159 1216 : sal_uInt16 SwNumRule::GetNumIndent( sal_uInt8 nLvl )
160 : {
161 : OSL_ENSURE( MAXLEVEL > nLvl, "NumLevel is out of range" );
162 1216 : return aDefNumIndents[ nLvl ];
163 : }
164 :
165 0 : sal_uInt16 SwNumRule::GetBullIndent( sal_uInt8 nLvl )
166 : {
167 : OSL_ENSURE( MAXLEVEL > nLvl, "NumLevel is out of range" );
168 0 : return aDefNumIndents[ nLvl ];
169 : }
170 :
171 830 : static void lcl_SetRuleChgd( SwTxtNode& rNd, sal_uInt8 nLevel )
172 : {
173 830 : if( rNd.GetActualListLevel() == nLevel )
174 279 : rNd.NumRuleChgd();
175 830 : }
176 :
177 4805 : SwNumFmt::SwNumFmt() :
178 : SvxNumberFormat(SVX_NUM_ARABIC),
179 : SwClient( 0 ),
180 4805 : pVertOrient(new SwFmtVertOrient( 0, text::VertOrientation::NONE))
181 : {
182 4805 : }
183 :
184 38998 : SwNumFmt::SwNumFmt( const SwNumFmt& rFmt) :
185 : SvxNumberFormat(rFmt),
186 : SwClient( rFmt.GetRegisteredInNonConst() ),
187 38998 : pVertOrient(new SwFmtVertOrient( 0, rFmt.GetVertOrient()))
188 : {
189 38998 : sal_Int16 eMyVertOrient = rFmt.GetVertOrient();
190 38998 : SetGraphicBrush( rFmt.GetBrush(), &rFmt.GetGraphicSize(),
191 38998 : &eMyVertOrient);
192 38998 : }
193 :
194 1700 : SwNumFmt::SwNumFmt(const SvxNumberFormat& rNumFmt, SwDoc* pDoc) :
195 : SvxNumberFormat(rNumFmt),
196 1700 : pVertOrient(new SwFmtVertOrient( 0, rNumFmt.GetVertOrient()))
197 : {
198 1700 : sal_Int16 eMyVertOrient = rNumFmt.GetVertOrient();
199 1700 : SetGraphicBrush( rNumFmt.GetBrush(), &rNumFmt.GetGraphicSize(),
200 1700 : &eMyVertOrient);
201 1700 : const String& rCharStyleName = rNumFmt.SvxNumberFormat::GetCharFmtName();
202 1700 : if( rCharStyleName.Len() )
203 : {
204 246 : SwCharFmt* pCFmt = pDoc->FindCharFmtByName( rCharStyleName );
205 246 : if( !pCFmt )
206 : {
207 : sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( rCharStyleName,
208 0 : nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
209 : pCFmt = nId != USHRT_MAX
210 0 : ? pDoc->GetCharFmtFromPool( nId )
211 0 : : pDoc->MakeCharFmt( rCharStyleName, 0 );
212 : }
213 246 : pCFmt->Add( this );
214 : }
215 1454 : else if( GetRegisteredIn() )
216 0 : GetRegisteredInNonConst()->Remove( this );
217 :
218 1700 : }
219 :
220 107313 : SwNumFmt::~SwNumFmt()
221 : {
222 43923 : delete pVertOrient;
223 63390 : }
224 :
225 0 : void SwNumFmt::NotifyGraphicArrived()
226 : {
227 0 : if( GetCharFmt() )
228 0 : UpdateNumNodes( (SwDoc*)GetCharFmt()->GetDoc() );
229 0 : }
230 :
231 : // #i22362#
232 1442 : sal_Bool SwNumFmt::IsEnumeration() const
233 : {
234 : // #i30655# native numbering did not work any longer
235 : // using this code. Therefore HBRINKM and I agreed upon defining
236 : // IsEnumeration() as !IsItemize()
237 1442 : return !IsItemize();
238 : }
239 :
240 :
241 2400 : sal_Bool SwNumFmt::IsItemize() const
242 : {
243 : sal_Bool bResult;
244 :
245 2400 : switch(GetNumberingType())
246 : {
247 : case SVX_NUM_CHAR_SPECIAL:
248 : case SVX_NUM_BITMAP:
249 135 : bResult = sal_True;
250 :
251 135 : break;
252 :
253 : default:
254 2265 : bResult = sal_False;
255 : }
256 :
257 2400 : return bResult;
258 :
259 : }
260 :
261 228 : SwNumFmt& SwNumFmt::operator=( const SwNumFmt& rNumFmt)
262 : {
263 228 : SvxNumberFormat::operator=(rNumFmt);
264 228 : if( rNumFmt.GetRegisteredIn() )
265 228 : rNumFmt.GetRegisteredInNonConst()->Add( this );
266 0 : else if( GetRegisteredIn() )
267 0 : GetRegisteredInNonConst()->Remove( this );
268 228 : return *this;
269 : }
270 :
271 15177 : sal_Bool SwNumFmt::operator==( const SwNumFmt& rNumFmt) const
272 : {
273 15177 : sal_Bool bRet = SvxNumberFormat::operator==(rNumFmt) &&
274 15177 : GetRegisteredIn() == rNumFmt.GetRegisteredIn();
275 15177 : return bRet;
276 : }
277 :
278 1195 : void SwNumFmt::SetCharFmt( SwCharFmt* pChFmt)
279 : {
280 1195 : if( pChFmt )
281 685 : pChFmt->Add( this );
282 510 : else if( GetRegisteredIn() )
283 0 : GetRegisteredInNonConst()->Remove( this );
284 1195 : }
285 :
286 1092 : void SwNumFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
287 : {
288 : // Look for the NumRules object in the Doc where this NumFormat is set.
289 : // The format does not need to exist!
290 1092 : const SwCharFmt* pFmt = 0;
291 1092 : sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
292 1092 : switch( nWhich )
293 : {
294 : case RES_ATTRSET_CHG:
295 : case RES_FMT_CHG:
296 1092 : pFmt = GetCharFmt();
297 1092 : break;
298 : }
299 :
300 1092 : if( pFmt && !pFmt->GetDoc()->IsInDtor() )
301 588 : UpdateNumNodes( (SwDoc*)pFmt->GetDoc() );
302 : else
303 504 : CheckRegistration( pOld, pNew );
304 1092 : }
305 :
306 296 : void SwNumFmt::SetCharFmtName(const String& rSet)
307 : {
308 296 : SvxNumberFormat::SetCharFmtName(rSet);
309 296 : }
310 :
311 0 : const String& SwNumFmt::GetCharFmtName() const
312 : {
313 0 : if((SwCharFmt*)GetRegisteredIn())
314 0 : return ((SwCharFmt*)GetRegisteredIn())->GetName();
315 : else
316 0 : return aEmptyStr;
317 : }
318 :
319 40698 : void SwNumFmt::SetGraphicBrush( const SvxBrushItem* pBrushItem, const Size* pSize,
320 : const sal_Int16* pOrient)
321 : {
322 40698 : if(pOrient)
323 40698 : pVertOrient->SetVertOrient( *pOrient );
324 40698 : SvxNumberFormat::SetGraphicBrush( pBrushItem, pSize, pOrient);
325 40698 : }
326 :
327 0 : void SwNumFmt::SetVertOrient(sal_Int16 eSet)
328 : {
329 0 : SvxNumberFormat::SetVertOrient(eSet);
330 0 : }
331 :
332 77996 : sal_Int16 SwNumFmt::GetVertOrient() const
333 : {
334 77996 : return SvxNumberFormat::GetVertOrient();
335 : }
336 :
337 588 : void SwNumFmt::UpdateNumNodes( SwDoc* pDoc )
338 : {
339 588 : sal_Bool bDocIsModified = pDoc->IsModified();
340 588 : bool bFnd = false;
341 : const SwNumRule* pRule;
342 3512 : for( sal_uInt16 n = pDoc->GetNumRuleTbl().size(); !bFnd && n; )
343 : {
344 2336 : pRule = pDoc->GetNumRuleTbl()[ --n ];
345 22139 : for( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
346 20355 : if( pRule->GetNumFmt( i ) == this )
347 : {
348 552 : SwNumRule::tTxtNodeList aTxtNodeList;
349 552 : pRule->GetTxtNodeList( aTxtNodeList );
350 4146 : for ( SwNumRule::tTxtNodeList::iterator aIter = aTxtNodeList.begin();
351 2764 : aIter != aTxtNodeList.end(); ++aIter )
352 : {
353 830 : lcl_SetRuleChgd( *(*aIter), i );
354 : }
355 552 : bFnd = true;
356 552 : break;
357 : }
358 : }
359 :
360 588 : if( bFnd && !bDocIsModified )
361 0 : pDoc->ResetModified();
362 588 : }
363 :
364 0 : const SwFmtVertOrient* SwNumFmt::GetGraphicOrientation() const
365 : {
366 0 : sal_Int16 eOrient = SvxNumberFormat::GetVertOrient();
367 0 : if(text::VertOrientation::NONE == eOrient)
368 0 : return 0;
369 : else
370 : {
371 0 : pVertOrient->SetVertOrient(eOrient);
372 0 : return pVertOrient;
373 : }
374 : }
375 :
376 :
377 : // handle new parameter <eDefaultNumberFormatPositionAndSpaceMode>
378 1195 : SwNumRule::SwNumRule( const String& rNm,
379 : const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode,
380 : SwNumRuleType eType,
381 : sal_Bool bAutoFlg )
382 : : maTxtNodeList(),
383 : maParagraphStyleList(),
384 : pNumRuleMap(0),
385 : sName( rNm ),
386 : eRuleType( eType ),
387 : nPoolFmtId( USHRT_MAX ),
388 : nPoolHelpId( USHRT_MAX ),
389 : nPoolHlpFileId( UCHAR_MAX ),
390 : bAutoRuleFlag( bAutoFlg ),
391 : bInvalidRuleFlag( sal_True ),
392 : bContinusNum( sal_False ),
393 : bAbsSpaces( sal_False ),
394 : bHidden( sal_False ),
395 : mbCountPhantoms( true ),
396 : meDefaultNumberFormatPositionAndSpaceMode( eDefaultNumberFormatPositionAndSpaceMode ),
397 1195 : msDefaultListId()
398 : {
399 1195 : if( !nRefCount++ ) // for the first time, initialize
400 : {
401 : SwNumFmt* pFmt;
402 : sal_uInt8 n;
403 :
404 : // numbering:
405 : // position-and-space mode LABEL_WIDTH_AND_POSITION:
406 1320 : for( n = 0; n < MAXLEVEL; ++n )
407 : {
408 1200 : pFmt = new SwNumFmt;
409 1200 : pFmt->SetIncludeUpperLevels( 1 );
410 1200 : pFmt->SetStart( 1 );
411 1200 : pFmt->SetLSpace( lNumIndent );
412 1200 : pFmt->SetAbsLSpace( lNumIndent + SwNumRule::GetNumIndent( n ) );
413 1200 : pFmt->SetFirstLineOffset( lNumFirstLineOffset );
414 1200 : pFmt->SetSuffix( aDotStr );
415 1200 : pFmt->SetBulletChar( numfunc::GetBulletChar(n));
416 1200 : SwNumRule::aBaseFmts[ NUM_RULE ][ n ] = pFmt;
417 : }
418 : // position-and-space mode LABEL_ALIGNMENT
419 : // first line indent of general numbering in inch: -0,25 inch
420 120 : const long cFirstLineIndent = -1440/4;
421 : // indent values of general numbering in inch:
422 : // 0,5 0,75 1,0 1,25 1,5
423 : // 1,75 2,0 2,25 2,5 2,75
424 : const long cIndentAt[ MAXLEVEL ] = {
425 : 1440/2, 1440*3/4, 1440, 1440*5/4, 1440*3/2,
426 120 : 1440*7/4, 1440*2, 1440*9/4, 1440*5/2, 1440*11/4 };
427 1320 : for( n = 0; n < MAXLEVEL; ++n )
428 : {
429 1200 : pFmt = new SwNumFmt;
430 1200 : pFmt->SetIncludeUpperLevels( 1 );
431 1200 : pFmt->SetStart( 1 );
432 1200 : pFmt->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT );
433 1200 : pFmt->SetLabelFollowedBy( SvxNumberFormat::LISTTAB );
434 1200 : pFmt->SetListtabPos( cIndentAt[ n ] );
435 1200 : pFmt->SetFirstLineIndent( cFirstLineIndent );
436 1200 : pFmt->SetIndentAt( cIndentAt[ n ] );
437 1200 : pFmt->SetSuffix( aDotStr );
438 1200 : pFmt->SetBulletChar( numfunc::GetBulletChar(n));
439 1200 : SwNumRule::aLabelAlignmentBaseFmts[ NUM_RULE ][ n ] = pFmt;
440 : }
441 :
442 : // outline:
443 : // position-and-space mode LABEL_WIDTH_AND_POSITION:
444 1320 : for( n = 0; n < MAXLEVEL; ++n )
445 : {
446 1200 : pFmt = new SwNumFmt;
447 1200 : pFmt->SetNumberingType(SVX_NUM_NUMBER_NONE);
448 1200 : pFmt->SetIncludeUpperLevels( MAXLEVEL );
449 1200 : pFmt->SetStart( 1 );
450 1200 : pFmt->SetCharTextDistance( lOutlineMinTextDistance );
451 1200 : pFmt->SetBulletChar( numfunc::GetBulletChar(n));
452 1200 : SwNumRule::aBaseFmts[ OUTLINE_RULE ][ n ] = pFmt;
453 : }
454 : // position-and-space mode LABEL_ALIGNMENT:
455 : // indent values of default outline numbering in inch:
456 : // 0,3 0,4 0,5 0,6 0,7
457 : // 0,8 0,9 1,0 1,1 1,2
458 : const long cOutlineIndentAt[ MAXLEVEL ] = {
459 : 1440*3/10, 1440*2/5, 1440/2, 1440*3/5, 1440*7/10,
460 120 : 1440*4/5, 1440*9/10, 1440, 1440*11/10, 1440*6/5 };
461 1320 : for( n = 0; n < MAXLEVEL; ++n )
462 : {
463 1200 : pFmt = new SwNumFmt;
464 1200 : pFmt->SetNumberingType(SVX_NUM_NUMBER_NONE);
465 1200 : pFmt->SetIncludeUpperLevels( MAXLEVEL );
466 1200 : pFmt->SetStart( 1 );
467 1200 : pFmt->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT );
468 1200 : pFmt->SetLabelFollowedBy( SvxNumberFormat::LISTTAB );
469 1200 : pFmt->SetListtabPos( cOutlineIndentAt[ n ] );
470 1200 : pFmt->SetFirstLineIndent( -cOutlineIndentAt[ n ] );
471 1200 : pFmt->SetIndentAt( cOutlineIndentAt[ n ] );
472 1200 : pFmt->SetBulletChar( numfunc::GetBulletChar(n));
473 1200 : SwNumRule::aLabelAlignmentBaseFmts[ OUTLINE_RULE ][ n ] = pFmt;
474 : }
475 : }
476 1195 : memset( aFmts, 0, sizeof( aFmts ));
477 : OSL_ENSURE( sName.Len(), "NumRule without a name!" );
478 1195 : }
479 :
480 1404 : SwNumRule::SwNumRule( const SwNumRule& rNumRule )
481 : : maTxtNodeList(),
482 : maParagraphStyleList(),
483 : pNumRuleMap(0),
484 : sName( rNumRule.sName ),
485 : eRuleType( rNumRule.eRuleType ),
486 1404 : nPoolFmtId( rNumRule.GetPoolFmtId() ),
487 1404 : nPoolHelpId( rNumRule.GetPoolHelpId() ),
488 1404 : nPoolHlpFileId( rNumRule.GetPoolHlpFileId() ),
489 : bAutoRuleFlag( rNumRule.bAutoRuleFlag ),
490 : bInvalidRuleFlag( sal_True ),
491 : bContinusNum( rNumRule.bContinusNum ),
492 : bAbsSpaces( rNumRule.bAbsSpaces ),
493 : bHidden( rNumRule.bHidden ),
494 : mbCountPhantoms( true ),
495 : meDefaultNumberFormatPositionAndSpaceMode( rNumRule.meDefaultNumberFormatPositionAndSpaceMode ),
496 5616 : msDefaultListId( rNumRule.msDefaultListId )
497 : {
498 1404 : ++nRefCount;
499 1404 : memset( aFmts, 0, sizeof( aFmts ));
500 15444 : for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
501 14040 : if( rNumRule.aFmts[ n ] )
502 7645 : Set( n, *rNumRule.aFmts[ n ] );
503 1404 : }
504 :
505 4078 : SwNumRule::~SwNumRule()
506 : {
507 22429 : for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
508 20390 : delete aFmts[ n ];
509 :
510 2039 : if (pNumRuleMap)
511 : {
512 637 : pNumRuleMap->erase(GetName());
513 : }
514 :
515 2039 : if( !--nRefCount ) // the last one closes the door (?)
516 : {
517 : // Numbering:
518 102 : SwNumFmt** ppFmts = (SwNumFmt**)SwNumRule::aBaseFmts;
519 : int n;
520 :
521 1122 : for( n = 0; n < MAXLEVEL; ++n, ++ppFmts )
522 1020 : delete *ppFmts, *ppFmts = 0;
523 :
524 : // Outline:
525 1122 : for( n = 0; n < MAXLEVEL; ++n, ++ppFmts )
526 1020 : delete *ppFmts, *ppFmts = 0;
527 :
528 102 : ppFmts = (SwNumFmt**)SwNumRule::aLabelAlignmentBaseFmts;
529 1122 : for( n = 0; n < MAXLEVEL; ++n, ++ppFmts )
530 1020 : delete *ppFmts, *ppFmts = 0;
531 1122 : for( n = 0; n < MAXLEVEL; ++n, ++ppFmts )
532 1020 : delete *ppFmts, *ppFmts = 0;
533 : }
534 :
535 2039 : maTxtNodeList.clear();
536 2039 : maParagraphStyleList.clear();
537 2039 : }
538 :
539 1074 : void SwNumRule::CheckCharFmts( SwDoc* pDoc )
540 : {
541 : SwCharFmt* pFmt;
542 11814 : for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
543 11230 : if( aFmts[ n ] && 0 != ( pFmt = aFmts[ n ]->GetCharFmt() ) &&
544 490 : pFmt->GetDoc() != pDoc )
545 : {
546 : // copy
547 0 : SwNumFmt* pNew = new SwNumFmt( *aFmts[ n ] );
548 0 : pNew->SetCharFmt( pDoc->CopyCharFmt( *pFmt ) );
549 0 : delete aFmts[ n ];
550 0 : aFmts[ n ] = pNew;
551 : }
552 1074 : }
553 :
554 825 : SwNumRule& SwNumRule::operator=( const SwNumRule& rNumRule )
555 : {
556 825 : if( this != &rNumRule )
557 : {
558 8371 : for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
559 7610 : Set( n, rNumRule.aFmts[ n ] );
560 :
561 761 : eRuleType = rNumRule.eRuleType;
562 761 : sName = rNumRule.sName;
563 761 : bAutoRuleFlag = rNumRule.bAutoRuleFlag;
564 761 : bInvalidRuleFlag = sal_True;
565 761 : bContinusNum = rNumRule.bContinusNum;
566 761 : bAbsSpaces = rNumRule.bAbsSpaces;
567 761 : bHidden = rNumRule.bHidden;
568 761 : nPoolFmtId = rNumRule.GetPoolFmtId();
569 761 : nPoolHelpId = rNumRule.GetPoolHelpId();
570 761 : nPoolHlpFileId = rNumRule.GetPoolHlpFileId();
571 : }
572 825 : return *this;
573 : }
574 :
575 79 : sal_Bool SwNumRule::operator==( const SwNumRule& rRule ) const
576 : {
577 : sal_Bool bRet = eRuleType == rRule.eRuleType &&
578 79 : sName == rRule.sName &&
579 : bAutoRuleFlag == rRule.bAutoRuleFlag &&
580 : bContinusNum == rRule.bContinusNum &&
581 : bAbsSpaces == rRule.bAbsSpaces &&
582 79 : nPoolFmtId == rRule.GetPoolFmtId() &&
583 79 : nPoolHelpId == rRule.GetPoolHelpId() &&
584 316 : nPoolHlpFileId == rRule.GetPoolHlpFileId();
585 79 : if( bRet )
586 : {
587 849 : for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
588 772 : if( !( rRule.Get( n ) == Get( n ) ))
589 : {
590 2 : bRet = sal_False;
591 2 : break;
592 : }
593 : }
594 79 : return bRet;
595 : }
596 :
597 17803 : void SwNumRule::Set( sal_uInt16 i, const SwNumFmt& rNumFmt )
598 : {
599 : OSL_ENSURE( i < MAXLEVEL, "Serious defect, please inform OD" );
600 17803 : if( i < MAXLEVEL )
601 : {
602 17803 : if( !aFmts[ i ] || !(rNumFmt == Get( i )) )
603 : {
604 13431 : delete aFmts[ i ];
605 13431 : aFmts[ i ] = new SwNumFmt( rNumFmt );
606 13431 : bInvalidRuleFlag = sal_True;
607 : }
608 : }
609 17803 : }
610 :
611 9094 : void SwNumRule::Set( sal_uInt16 i, const SwNumFmt* pNumFmt )
612 : {
613 : OSL_ENSURE( i < MAXLEVEL, "Serious defect, please inform OD" );
614 9094 : if( i >= MAXLEVEL )
615 9094 : return;
616 9094 : SwNumFmt* pOld = aFmts[ i ];
617 9094 : if( !pOld )
618 : {
619 2759 : if( pNumFmt )
620 : {
621 1116 : aFmts[ i ] = new SwNumFmt( *pNumFmt );
622 1116 : bInvalidRuleFlag = sal_True;
623 : }
624 : }
625 6335 : else if( !pNumFmt )
626 0 : delete pOld, aFmts[ i ] = 0, bInvalidRuleFlag = sal_True;
627 6335 : else if( *pOld != *pNumFmt )
628 228 : *pOld = *pNumFmt, bInvalidRuleFlag = sal_True;
629 : }
630 :
631 30 : String SwNumRule::MakeNumString( const SwNodeNum& rNum, sal_Bool bInclStrings,
632 : sal_Bool bOnlyArabic ) const
633 : {
634 30 : String aStr;
635 :
636 30 : if (rNum.IsCounted())
637 : aStr = MakeNumString(rNum.GetNumberVector(),
638 30 : bInclStrings, bOnlyArabic, MAXLEVEL);
639 :
640 30 : return aStr;
641 : }
642 :
643 862 : String SwNumRule::MakeNumString( const SwNumberTree::tNumberVector & rNumVector,
644 : const sal_Bool bInclStrings,
645 : const sal_Bool bOnlyArabic,
646 : const unsigned int _nRestrictToThisLevel,
647 : SwNumRule::Extremities* pExtremities ) const
648 : {
649 862 : String aStr;
650 :
651 862 : unsigned int nLevel = rNumVector.size() - 1;
652 :
653 862 : if ( pExtremities )
654 259 : pExtremities->nPrefixChars = pExtremities->nSuffixChars = 0;
655 :
656 862 : if ( nLevel > _nRestrictToThisLevel )
657 : {
658 0 : nLevel = _nRestrictToThisLevel;
659 : }
660 :
661 862 : if (nLevel < MAXLEVEL)
662 : {
663 862 : const SwNumFmt& rMyNFmt = Get( static_cast<sal_uInt16>(nLevel) );
664 :
665 : {
666 862 : sal_uInt8 i = static_cast<sal_uInt8>(nLevel);
667 :
668 2550 : if( !IsContinusNum() &&
669 : // - do not include upper levels, if level isn't numbered.
670 862 : rMyNFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE &&
671 826 : rMyNFmt.GetIncludeUpperLevels() ) // Just the own level?
672 : {
673 826 : sal_uInt8 n = rMyNFmt.GetIncludeUpperLevels();
674 826 : if( 1 < n )
675 : {
676 68 : if( i+1 >= n )
677 68 : i -= n - 1;
678 : else
679 0 : i = 0;
680 : }
681 : }
682 :
683 1819 : for( ; i <= nLevel; ++i )
684 : {
685 957 : const SwNumFmt& rNFmt = Get( i );
686 957 : if( SVX_NUM_NUMBER_NONE == rNFmt.GetNumberingType() )
687 : {
688 : // Should 1.1.1 --> 2. NoNum --> 1..1 or 1.1 ??
689 : // if( i != rNum.nMyLevel )
690 : // aStr += aDotStr;
691 36 : continue;
692 : }
693 :
694 921 : if( rNumVector[ i ] )
695 : {
696 921 : if( bOnlyArabic )
697 0 : aStr += String::CreateFromInt32( rNumVector[ i ] );
698 : else
699 921 : aStr += rNFmt.GetNumStr( rNumVector[ i ] );
700 : }
701 : else
702 0 : aStr += '0'; // all 0 level are a 0
703 921 : if( i != nLevel && aStr.Len() )
704 95 : aStr += aDotStr;
705 : }
706 :
707 : // The type doesn't have any number, so don't append
708 : // the post-/prefix string
709 2586 : if( bInclStrings && !bOnlyArabic &&
710 862 : SVX_NUM_CHAR_SPECIAL != rMyNFmt.GetNumberingType() &&
711 862 : SVX_NUM_BITMAP != rMyNFmt.GetNumberingType() )
712 : {
713 862 : String const &rPrefix = rMyNFmt.GetPrefix();
714 862 : String const &rSuffix = rMyNFmt.GetSuffix();
715 :
716 862 : aStr.Insert( rPrefix, 0 );
717 862 : aStr += rSuffix;
718 862 : if ( pExtremities )
719 : {
720 259 : pExtremities->nPrefixChars = rPrefix.Len();
721 259 : pExtremities->nSuffixChars = rSuffix.Len();
722 862 : }
723 : }
724 : }
725 : }
726 :
727 862 : return aStr;
728 : }
729 :
730 :
731 120 : String SwNumRule::MakeRefNumString( const SwNodeNum& rNodeNum,
732 : const bool bInclSuperiorNumLabels,
733 : const sal_uInt8 nRestrictInclToThisLevel ) const
734 : {
735 120 : String aRefNumStr;
736 :
737 120 : if ( rNodeNum.GetLevelInListTree() >= 0 )
738 : {
739 120 : bool bOldHadPrefix = true;
740 120 : bool bFirstIteration = true;
741 120 : ::rtl::OUString sOldPrefix;
742 :
743 120 : const SwNodeNum* pWorkingNodeNum( &rNodeNum );
744 582 : do
745 : {
746 303 : bool bMakeNumStringForPhantom( false );
747 303 : if ( pWorkingNodeNum->IsPhantom() )
748 : {
749 0 : SwNumFmt aFmt( Get( static_cast<sal_uInt16>(pWorkingNodeNum->GetLevelInListTree()) ) );
750 0 : bMakeNumStringForPhantom = aFmt.IsEnumeration() &&
751 0 : SVX_NUM_NUMBER_NONE != aFmt.GetNumberingType();
752 :
753 : }
754 1212 : if ( bMakeNumStringForPhantom ||
755 303 : ( !pWorkingNodeNum->IsPhantom() &&
756 303 : pWorkingNodeNum->GetTxtNode() &&
757 303 : pWorkingNodeNum->GetTxtNode()->HasNumber() ) )
758 : {
759 : Extremities aExtremities;
760 : String aPrevStr = MakeNumString( pWorkingNodeNum->GetNumberVector(),
761 : sal_True, sal_False, MAXLEVEL,
762 259 : &aExtremities);
763 259 : int nStrip = 0;
764 : sal_Unicode c;
765 :
766 :
767 683 : while ( nStrip < aExtremities.nPrefixChars &&
768 165 : ( '\t' == ( c = aPrevStr.GetChar( nStrip ) ) ||
769 : ' ' == c) )
770 : {
771 0 : ++nStrip;
772 : }
773 :
774 259 : if (nStrip)
775 : {
776 0 : aPrevStr.Erase( 0, nStrip );
777 0 : aExtremities.nPrefixChars -= nStrip;
778 : }
779 :
780 518 : if ((bFirstIteration || bOldHadPrefix) &&
781 : aExtremities.nSuffixChars &&
782 259 : !aExtremities.nPrefixChars
783 : )
784 : {
785 94 : int nStrip2 = aPrevStr.Len();
786 248 : while (aPrevStr.Len() - nStrip2 < aExtremities.nSuffixChars)
787 : {
788 94 : char const cur = aPrevStr.GetChar(nStrip2);
789 94 : if (!bFirstIteration && '\t' != cur && ' ' != cur)
790 : {
791 34 : break;
792 : }
793 60 : --nStrip2;
794 : }
795 94 : if (nStrip2 < aPrevStr.Len())
796 : {
797 60 : aPrevStr.Erase(nStrip2, aPrevStr.Len() - nStrip2);
798 94 : }
799 : }
800 165 : else if (sOldPrefix.getLength())
801 : {
802 0 : aRefNumStr.Insert(sOldPrefix, 0);
803 : }
804 259 : sOldPrefix = ::rtl::OUString();
805 :
806 259 : bOldHadPrefix = ( aExtremities.nPrefixChars > 0);
807 :
808 259 : aRefNumStr.Insert( aPrevStr, 0 );
809 : }
810 44 : else if ( aRefNumStr.Len() > 0 )
811 : {
812 44 : sOldPrefix += " ";
813 44 : bOldHadPrefix = true;
814 : }
815 :
816 303 : if ( bInclSuperiorNumLabels && pWorkingNodeNum->GetLevelInListTree() > 0 )
817 : {
818 194 : sal_uInt8 n = Get( static_cast<sal_uInt16>(pWorkingNodeNum->GetLevelInListTree()) ).GetIncludeUpperLevels();
819 194 : pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
820 : // skip parents, whose list label is already contained in the actual list label.
821 388 : while ( pWorkingNodeNum && n > 1 )
822 : {
823 0 : pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
824 0 : --n;
825 : }
826 : }
827 : else
828 : {
829 109 : break;
830 : }
831 194 : bFirstIteration = false;
832 : } while ( pWorkingNodeNum &&
833 194 : pWorkingNodeNum->GetLevelInListTree() >= 0 &&
834 314 : static_cast<sal_uInt8>(pWorkingNodeNum->GetLevelInListTree()) >= nRestrictInclToThisLevel );
835 : }
836 :
837 120 : return aRefNumStr;
838 : }
839 :
840 : // ----- Copy method of SwNumRule ------
841 :
842 : // A kind of copy constructor, so that the num formats are attached
843 : // to the right CharFormats of a Document.
844 : // Copies the NumFormats and returns itself.
845 0 : SwNumRule& SwNumRule::CopyNumRule( SwDoc* pDoc, const SwNumRule& rNumRule )
846 : {
847 0 : for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
848 : {
849 0 : Set( n, rNumRule.aFmts[ n ] );
850 0 : if( aFmts[ n ] && aFmts[ n ]->GetCharFmt() &&
851 0 : !pDoc->GetCharFmts()->Contains( aFmts[n]->GetCharFmt() ))
852 : // If we copy across different Documents, then copy the
853 : // corresponding CharFormat into the new Document.
854 0 : aFmts[n]->SetCharFmt( pDoc->CopyCharFmt( *aFmts[n]->
855 0 : GetCharFmt() ) );
856 : }
857 0 : eRuleType = rNumRule.eRuleType;
858 0 : sName = rNumRule.sName;
859 0 : bAutoRuleFlag = rNumRule.bAutoRuleFlag;
860 0 : nPoolFmtId = rNumRule.GetPoolFmtId();
861 0 : nPoolHelpId = rNumRule.GetPoolHelpId();
862 0 : nPoolHlpFileId = rNumRule.GetPoolHlpFileId();
863 0 : bInvalidRuleFlag = sal_True;
864 0 : return *this;
865 : }
866 :
867 170 : void SwNumRule::SetSvxRule(const SvxNumRule& rNumRule, SwDoc* pDoc)
868 : {
869 1870 : for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
870 : {
871 1700 : const SvxNumberFormat* pSvxFmt = rNumRule.Get(n);
872 1700 : delete aFmts[n];
873 1700 : aFmts[n] = pSvxFmt ? new SwNumFmt(*pSvxFmt, pDoc) : 0;
874 : }
875 :
876 170 : bInvalidRuleFlag = sal_True;
877 170 : bContinusNum = rNumRule.IsContinuousNumbering();
878 170 : }
879 :
880 191 : SvxNumRule SwNumRule::MakeSvxNumRule() const
881 : {
882 : SvxNumRule aRule(NUM_CONTINUOUS|NUM_CHAR_TEXT_DISTANCE|NUM_CHAR_STYLE|
883 : NUM_ENABLE_LINKED_BMP|NUM_ENABLE_EMBEDDED_BMP,
884 : MAXLEVEL, bContinusNum,
885 : eRuleType ==
886 : NUM_RULE ?
887 : SVX_RULETYPE_NUMBERING :
888 191 : SVX_RULETYPE_OUTLINE_NUMBERING );
889 2101 : for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
890 : {
891 1910 : SwNumFmt aNumFmt = Get(n);
892 1910 : if(aNumFmt.GetCharFmt())
893 296 : aNumFmt.SetCharFmtName(aNumFmt.GetCharFmt()->GetName());
894 1910 : aRule.SetLevel(n, aNumFmt, aFmts[n] != 0);
895 1910 : }
896 191 : return aRule;
897 : }
898 :
899 3731 : void SwNumRule::SetInvalidRule(sal_Bool bFlag)
900 : {
901 3731 : if (bFlag)
902 : {
903 1631 : std::set< SwList* > aLists;
904 1631 : tTxtNodeList::iterator aIter;
905 2610 : for ( aIter = maTxtNodeList.begin(); aIter != maTxtNodeList.end(); ++aIter )
906 : {
907 979 : const SwTxtNode* pTxtNode = *aIter;
908 : // #i111681# - applying patch from cmc
909 979 : SwList* pList = pTxtNode->GetDoc()->getListByName( pTxtNode->GetListId() );
910 : OSL_ENSURE( pList, "<SwNumRule::SetInvalidRule(..)> - list at which the text node is registered at does not exist. This is a serious issue --> please inform OD.");
911 979 : if ( pList )
912 : {
913 979 : aLists.insert( pList );
914 : }
915 : }
916 : std::for_each( aLists.begin(), aLists.end(),
917 1631 : std::mem_fun( &SwList::InvalidateListTree ) );
918 : }
919 :
920 3731 : bInvalidRuleFlag = bFlag;
921 3731 : }
922 :
923 :
924 : // change indent of all list levels by given difference
925 0 : void SwNumRule::ChangeIndent( const short nDiff )
926 : {
927 0 : for ( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
928 : {
929 0 : SwNumFmt aTmpNumFmt( Get(i) );
930 :
931 : const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
932 0 : aTmpNumFmt.GetPositionAndSpaceMode() );
933 0 : if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
934 : {
935 : short nNewIndent = nDiff +
936 0 : aTmpNumFmt.GetAbsLSpace();
937 0 : if ( nNewIndent < 0 )
938 : {
939 0 : nNewIndent = 0;
940 : }
941 0 : aTmpNumFmt.SetAbsLSpace( nNewIndent );
942 : }
943 0 : else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
944 : {
945 : // adjust also the list tab position, if a list tab stop is applied
946 0 : if ( aTmpNumFmt.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
947 : {
948 0 : const long nNewListTab = aTmpNumFmt.GetListtabPos() + nDiff;
949 0 : aTmpNumFmt.SetListtabPos( nNewListTab );
950 : }
951 :
952 : const long nNewIndent = nDiff +
953 0 : aTmpNumFmt.GetIndentAt();
954 0 : aTmpNumFmt.SetIndentAt( nNewIndent );
955 : }
956 :
957 0 : Set( i, aTmpNumFmt );
958 0 : }
959 :
960 0 : SetInvalidRule( sal_True );
961 0 : }
962 :
963 : // set indent of certain list level to given value
964 0 : void SwNumRule::SetIndent( const short nNewIndent,
965 : const sal_uInt16 nListLevel )
966 : {
967 0 : SwNumFmt aTmpNumFmt( Get(nListLevel) );
968 :
969 : const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
970 0 : aTmpNumFmt.GetPositionAndSpaceMode() );
971 0 : if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
972 : {
973 0 : aTmpNumFmt.SetAbsLSpace( nNewIndent );
974 : }
975 0 : else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
976 : {
977 : // adjust also the list tab position, if a list tab stop is applied
978 0 : if ( aTmpNumFmt.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
979 : {
980 0 : const long nNewListTab = aTmpNumFmt.GetListtabPos() +
981 0 : ( nNewIndent - aTmpNumFmt.GetIndentAt() );
982 0 : aTmpNumFmt.SetListtabPos( nNewListTab );
983 : }
984 :
985 0 : aTmpNumFmt.SetIndentAt( nNewIndent );
986 : }
987 :
988 0 : SetInvalidRule( sal_True );
989 0 : }
990 :
991 : // set indent of first list level to given value and change other list level's
992 : // indents accordingly
993 0 : void SwNumRule::SetIndentOfFirstListLevelAndChangeOthers( const short nNewIndent )
994 : {
995 0 : SwNumFmt aTmpNumFmt( Get(0) );
996 :
997 0 : short nDiff( 0 );
998 : const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
999 0 : aTmpNumFmt.GetPositionAndSpaceMode() );
1000 0 : if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1001 : {
1002 : nDiff = nNewIndent
1003 0 : - aTmpNumFmt.GetFirstLineOffset()
1004 0 : - aTmpNumFmt.GetAbsLSpace();
1005 : }
1006 0 : else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1007 : {
1008 : nDiff = static_cast<short>(nNewIndent
1009 0 : - aTmpNumFmt.GetIndentAt());
1010 : }
1011 0 : if ( nDiff != 0 )
1012 : {
1013 0 : ChangeIndent( nDiff );
1014 0 : }
1015 0 : }
1016 :
1017 :
1018 2100 : void SwNumRule::Validate()
1019 : {
1020 2100 : std::set< SwList* > aLists;
1021 2100 : tTxtNodeList::iterator aIter;
1022 3079 : for ( aIter = maTxtNodeList.begin(); aIter != maTxtNodeList.end(); ++aIter )
1023 : {
1024 979 : const SwTxtNode* pTxtNode = *aIter;
1025 979 : aLists.insert( pTxtNode->GetDoc()->getListByName( pTxtNode->GetListId() ) );
1026 : }
1027 : std::for_each( aLists.begin(), aLists.end(),
1028 2100 : std::mem_fun( &SwList::ValidateListTree ) );
1029 :
1030 :
1031 2100 : SetInvalidRule(sal_False);
1032 2100 : }
1033 :
1034 :
1035 601 : bool SwNumRule::IsCountPhantoms() const
1036 : {
1037 601 : return mbCountPhantoms;
1038 : }
1039 :
1040 :
1041 576 : void SwNumRule::SetCountPhantoms(bool bCountPhantoms)
1042 : {
1043 576 : mbCountPhantoms = bCountPhantoms;
1044 576 : }
1045 :
1046 :
1047 75 : SwNumRule::tParagraphStyleList::size_type SwNumRule::GetParagraphStyleListSize() const
1048 : {
1049 75 : return maParagraphStyleList.size();
1050 : }
1051 :
1052 :
1053 388 : void SwNumRule::AddParagraphStyle( SwTxtFmtColl& rTxtFmtColl )
1054 : {
1055 : tParagraphStyleList::iterator aIter =
1056 388 : std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTxtFmtColl );
1057 :
1058 388 : if ( aIter == maParagraphStyleList.end() )
1059 : {
1060 266 : maParagraphStyleList.push_back( &rTxtFmtColl );
1061 : }
1062 388 : }
1063 :
1064 :
1065 50 : void SwNumRule::RemoveParagraphStyle( SwTxtFmtColl& rTxtFmtColl )
1066 : {
1067 : tParagraphStyleList::iterator aIter =
1068 50 : std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTxtFmtColl );
1069 :
1070 50 : if ( aIter != maParagraphStyleList.end() )
1071 : {
1072 50 : maParagraphStyleList.erase( aIter );
1073 : }
1074 50 : }
1075 :
1076 :
1077 : namespace numfunc
1078 : {
1079 : /** class containing default bullet list configuration data
1080 :
1081 : @author OD
1082 : */
1083 : class SwDefBulletConfig : private utl::ConfigItem
1084 : {
1085 : public:
1086 : static SwDefBulletConfig& getInstance();
1087 :
1088 0 : inline const String& GetFontname() const
1089 : {
1090 0 : return msFontname;
1091 : }
1092 :
1093 0 : inline bool IsFontnameUserDefined() const
1094 : {
1095 0 : return mbUserDefinedFontname;
1096 : }
1097 :
1098 13 : inline const Font& GetFont() const
1099 : {
1100 13 : return *mpFont;
1101 : }
1102 :
1103 : inline short GetFontWeight() const
1104 : {
1105 : return static_cast<short>(meFontWeight);
1106 : }
1107 :
1108 : inline short GetFontItalic() const
1109 : {
1110 : return static_cast<short>(meFontItalic);
1111 : }
1112 4800 : inline sal_Unicode GetChar( sal_uInt8 p_nListLevel ) const
1113 : {
1114 4800 : if (p_nListLevel >= MAXLEVEL)
1115 : {
1116 0 : p_nListLevel = MAXLEVEL - 1;
1117 : }
1118 :
1119 4800 : return mnLevelChars[p_nListLevel];
1120 : }
1121 :
1122 : SwDefBulletConfig();
1123 : ~SwDefBulletConfig();
1124 : private:
1125 :
1126 : /** sets internal default bullet configuration data to default values
1127 :
1128 : @author OD
1129 : */
1130 : void SetToDefault();
1131 :
1132 : /** returns sequence of default bullet configuration property names
1133 :
1134 : @author OD
1135 : */
1136 : uno::Sequence<rtl::OUString> GetPropNames() const;
1137 :
1138 : /** loads default bullet configuration properties and applies
1139 : values to internal data
1140 :
1141 : @author OD
1142 : */
1143 : void LoadConfig();
1144 :
1145 : /** initialize font instance for default bullet list
1146 :
1147 : @author OD
1148 : */
1149 : void InitFont();
1150 :
1151 : /** catches notification about changed default bullet configuration data
1152 :
1153 : @author OD
1154 : */
1155 : virtual void Notify( const uno::Sequence<rtl::OUString>& aPropertyNames );
1156 : virtual void Commit();
1157 :
1158 : // default bullet list configuration data
1159 : String msFontname;
1160 : bool mbUserDefinedFontname;
1161 : FontWeight meFontWeight;
1162 : FontItalic meFontItalic;
1163 : sal_Unicode mnLevelChars[MAXLEVEL];
1164 :
1165 : // default bullet list font instance
1166 : Font* mpFont;
1167 : };
1168 :
1169 : namespace
1170 : {
1171 : class theSwDefBulletConfig
1172 : : public rtl::Static<SwDefBulletConfig, theSwDefBulletConfig>{};
1173 : }
1174 :
1175 4813 : SwDefBulletConfig& SwDefBulletConfig::getInstance()
1176 : {
1177 4813 : return theSwDefBulletConfig::get();
1178 : }
1179 :
1180 24 : SwDefBulletConfig::SwDefBulletConfig()
1181 : : ConfigItem( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Writer/Numbering/DefaultBulletList")) ),
1182 : // default bullet font is now OpenSymbol
1183 : msFontname( rtl::OUString("OpenSymbol") ),
1184 : mbUserDefinedFontname( false ),
1185 : meFontWeight( WEIGHT_DONTKNOW ),
1186 : meFontItalic( ITALIC_NONE ),
1187 24 : mpFont( 0 )
1188 : {
1189 24 : SetToDefault();
1190 24 : LoadConfig();
1191 24 : InitFont();
1192 :
1193 : // enable notification for changes on default bullet configuration change
1194 24 : EnableNotification( GetPropNames() );
1195 24 : }
1196 :
1197 48 : SwDefBulletConfig::~SwDefBulletConfig()
1198 : {
1199 24 : delete mpFont;
1200 24 : }
1201 :
1202 24 : void SwDefBulletConfig::SetToDefault()
1203 : {
1204 24 : msFontname = rtl::OUString("OpenSymbol");
1205 24 : mbUserDefinedFontname = false;
1206 24 : meFontWeight = WEIGHT_DONTKNOW;
1207 24 : meFontItalic = ITALIC_NONE;
1208 :
1209 24 : mnLevelChars[0] = 0x2022;
1210 24 : mnLevelChars[1] = 0x25e6;
1211 24 : mnLevelChars[2] = 0x25aa;
1212 24 : mnLevelChars[3] = 0x2022;
1213 24 : mnLevelChars[4] = 0x25e6;
1214 24 : mnLevelChars[5] = 0x25aa;
1215 24 : mnLevelChars[6] = 0x2022;
1216 24 : mnLevelChars[7] = 0x25e6;
1217 24 : mnLevelChars[8] = 0x25aa;
1218 24 : mnLevelChars[9] = 0x2022;
1219 24 : }
1220 :
1221 48 : uno::Sequence<rtl::OUString> SwDefBulletConfig::GetPropNames() const
1222 : {
1223 48 : uno::Sequence<rtl::OUString> aPropNames(13);
1224 48 : rtl::OUString* pNames = aPropNames.getArray();
1225 48 : pNames[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletFont/FontFamilyname"));
1226 48 : pNames[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletFont/FontWeight"));
1227 48 : pNames[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletFont/FontItalic"));
1228 48 : pNames[3] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletCharLvl1"));
1229 48 : pNames[4] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletCharLvl2"));
1230 48 : pNames[5] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletCharLvl3"));
1231 48 : pNames[6] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletCharLvl4"));
1232 48 : pNames[7] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletCharLvl5"));
1233 48 : pNames[8] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletCharLvl6"));
1234 48 : pNames[9] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletCharLvl7"));
1235 48 : pNames[10] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletCharLvl8"));
1236 48 : pNames[11] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletCharLvl9"));
1237 48 : pNames[12] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BulletCharLvl10"));
1238 :
1239 48 : return aPropNames;
1240 : }
1241 :
1242 24 : void SwDefBulletConfig::LoadConfig()
1243 : {
1244 24 : uno::Sequence<rtl::OUString> aPropNames = GetPropNames();
1245 : uno::Sequence<uno::Any> aValues =
1246 24 : GetProperties( aPropNames );
1247 24 : const uno::Any* pValues = aValues.getConstArray();
1248 : OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1249 : "<SwDefBulletConfig::SwDefBulletConfig()> - GetProperties failed");
1250 24 : if ( aValues.getLength() == aPropNames.getLength() )
1251 : {
1252 336 : for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1253 : {
1254 312 : if ( pValues[nProp].hasValue() )
1255 : {
1256 0 : switch ( nProp )
1257 : {
1258 : case 0:
1259 : {
1260 0 : rtl::OUString aStr;
1261 0 : pValues[nProp] >>= aStr;
1262 0 : msFontname = aStr;
1263 0 : mbUserDefinedFontname = true;
1264 : }
1265 0 : break;
1266 : case 1:
1267 : case 2:
1268 : {
1269 0 : sal_uInt8 nTmp = 0;
1270 0 : pValues[nProp] >>= nTmp;
1271 0 : if ( nProp == 1 )
1272 0 : meFontWeight = static_cast<FontWeight>(nTmp);
1273 0 : else if ( nProp == 2 )
1274 0 : meFontItalic = static_cast<FontItalic>(nTmp);
1275 : }
1276 0 : break;
1277 : case 3:
1278 : case 4:
1279 : case 5:
1280 : case 6:
1281 : case 7:
1282 : case 8:
1283 : case 9:
1284 : case 10:
1285 : case 11:
1286 : case 12:
1287 : {
1288 0 : sal_Unicode cChar = sal_Unicode();
1289 0 : pValues[nProp] >>= cChar;
1290 0 : mnLevelChars[nProp-3] = cChar;
1291 : }
1292 0 : break;
1293 : }
1294 : }
1295 : }
1296 24 : }
1297 :
1298 24 : }
1299 :
1300 24 : void SwDefBulletConfig::InitFont()
1301 : {
1302 24 : delete mpFont;
1303 :
1304 24 : mpFont = new Font( msFontname, aEmptyStr, Size( 0, 14 ) );
1305 24 : mpFont->SetWeight( meFontWeight );
1306 24 : mpFont->SetItalic( meFontItalic );
1307 24 : }
1308 :
1309 0 : void SwDefBulletConfig::Notify( const uno::Sequence<rtl::OUString>& )
1310 : {
1311 0 : SetToDefault();
1312 0 : LoadConfig();
1313 0 : InitFont();
1314 0 : }
1315 :
1316 0 : void SwDefBulletConfig::Commit()
1317 : {
1318 0 : }
1319 :
1320 0 : const String& GetDefBulletFontname()
1321 : {
1322 0 : return SwDefBulletConfig::getInstance().GetFontname();
1323 : }
1324 :
1325 0 : bool IsDefBulletFontUserDefined()
1326 : {
1327 0 : return SwDefBulletConfig::getInstance().IsFontnameUserDefined();
1328 : }
1329 :
1330 13 : const Font& GetDefBulletFont()
1331 : {
1332 13 : return SwDefBulletConfig::getInstance().GetFont();
1333 : }
1334 :
1335 4800 : sal_Unicode GetBulletChar( sal_uInt8 nLevel )
1336 : {
1337 4800 : return SwDefBulletConfig::getInstance().GetChar( nLevel );
1338 : }
1339 :
1340 : /** class containing configuration data about user interface behavior
1341 : regarding lists and list items.
1342 : configuration item about behavior of <TAB>/<SHIFT-TAB>-key at first
1343 : position of first list item
1344 :
1345 : @author OD
1346 : */
1347 0 : class SwNumberingUIBehaviorConfig : private utl::ConfigItem
1348 : {
1349 : public:
1350 : static SwNumberingUIBehaviorConfig& getInstance();
1351 :
1352 0 : inline sal_Bool ChangeIndentOnTabAtFirstPosOfFirstListItem() const
1353 : {
1354 0 : return mbChangeIndentOnTabAtFirstPosOfFirstListItem;
1355 : }
1356 :
1357 : SwNumberingUIBehaviorConfig();
1358 :
1359 : private:
1360 :
1361 : /** sets internal configuration data to default values
1362 :
1363 : @author OD
1364 : */
1365 : void SetToDefault();
1366 :
1367 : /** returns sequence of configuration property names
1368 :
1369 : @author OD
1370 : */
1371 : com::sun::star::uno::Sequence<rtl::OUString> GetPropNames() const;
1372 :
1373 : /** loads configuration properties and applies values to internal data
1374 :
1375 : @author OD
1376 : */
1377 : void LoadConfig();
1378 :
1379 : /** catches notification about changed configuration data
1380 :
1381 : @author OD
1382 : */
1383 : virtual void Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames );
1384 : virtual void Commit();
1385 :
1386 : // configuration data
1387 : sal_Bool mbChangeIndentOnTabAtFirstPosOfFirstListItem;
1388 : };
1389 :
1390 : namespace
1391 : {
1392 : class theSwNumberingUIBehaviorConfig : public rtl::Static<SwNumberingUIBehaviorConfig, theSwNumberingUIBehaviorConfig>{};
1393 : }
1394 :
1395 0 : SwNumberingUIBehaviorConfig& SwNumberingUIBehaviorConfig::getInstance()
1396 : {
1397 0 : return theSwNumberingUIBehaviorConfig::get();
1398 : }
1399 :
1400 0 : SwNumberingUIBehaviorConfig::SwNumberingUIBehaviorConfig()
1401 : : ConfigItem( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Writer/Numbering/UserInterfaceBehavior")) ),
1402 0 : mbChangeIndentOnTabAtFirstPosOfFirstListItem( sal_True )
1403 : {
1404 0 : SetToDefault();
1405 0 : LoadConfig();
1406 :
1407 : // enable notification for changes on configuration change
1408 0 : EnableNotification( GetPropNames() );
1409 0 : }
1410 :
1411 0 : void SwNumberingUIBehaviorConfig::SetToDefault()
1412 : {
1413 0 : mbChangeIndentOnTabAtFirstPosOfFirstListItem = sal_True;
1414 0 : }
1415 :
1416 0 : com::sun::star::uno::Sequence<rtl::OUString> SwNumberingUIBehaviorConfig::GetPropNames() const
1417 : {
1418 0 : com::sun::star::uno::Sequence<rtl::OUString> aPropNames(1);
1419 0 : rtl::OUString* pNames = aPropNames.getArray();
1420 0 : pNames[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ChangeIndentOnTabAtFirstPosOfFirstListItem"));
1421 :
1422 0 : return aPropNames;
1423 : }
1424 :
1425 0 : void SwNumberingUIBehaviorConfig::Commit() {}
1426 :
1427 0 : void SwNumberingUIBehaviorConfig::LoadConfig()
1428 : {
1429 0 : com::sun::star::uno::Sequence<rtl::OUString> aPropNames = GetPropNames();
1430 : com::sun::star::uno::Sequence<com::sun::star::uno::Any> aValues =
1431 0 : GetProperties( aPropNames );
1432 0 : const com::sun::star::uno::Any* pValues = aValues.getConstArray();
1433 : OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1434 : "<SwNumberingUIBehaviorConfig::LoadConfig()> - GetProperties failed");
1435 0 : if ( aValues.getLength() == aPropNames.getLength() )
1436 : {
1437 0 : for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1438 : {
1439 0 : if ( pValues[nProp].hasValue() )
1440 : {
1441 0 : switch ( nProp )
1442 : {
1443 : case 0:
1444 : {
1445 0 : pValues[nProp] >>= mbChangeIndentOnTabAtFirstPosOfFirstListItem;
1446 : }
1447 0 : break;
1448 : default:
1449 : {
1450 : OSL_FAIL( "<SwNumberingUIBehaviorConfig::LoadConfig()> - unknown configuration property");
1451 : }
1452 : }
1453 : }
1454 : }
1455 0 : }
1456 0 : }
1457 :
1458 0 : void SwNumberingUIBehaviorConfig::Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames )
1459 : {
1460 : (void) aPropertyNames;
1461 0 : SetToDefault();
1462 0 : LoadConfig();
1463 0 : }
1464 :
1465 0 : sal_Bool ChangeIndentOnTabAtFirstPosOfFirstListItem()
1466 : {
1467 0 : return SwNumberingUIBehaviorConfig::getInstance().ChangeIndentOnTabAtFirstPosOfFirstListItem();
1468 : }
1469 :
1470 725 : SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
1471 : {
1472 : SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode;
1473 725 : SvtSaveOptions aSaveOptions;
1474 725 : switch ( aSaveOptions.GetODFDefaultVersion() )
1475 : {
1476 : case SvtSaveOptions::ODFVER_010:
1477 : case SvtSaveOptions::ODFVER_011:
1478 : {
1479 0 : ePosAndSpaceMode = SvxNumberFormat::LABEL_WIDTH_AND_POSITION;
1480 : }
1481 0 : break;
1482 : default: // ODFVER_UNKNOWN or ODFVER_012
1483 : {
1484 725 : ePosAndSpaceMode = SvxNumberFormat::LABEL_ALIGNMENT;
1485 : }
1486 : }
1487 :
1488 725 : return ePosAndSpaceMode;
1489 : }
1490 : }
1491 :
1492 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|