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