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