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 33 34 #include <hintids.hxx> 35 #include <svl/urihelper.hxx> 36 #include <unotools/pathoptions.hxx> 37 #include <tools/stream.hxx> 38 #ifndef _SFX_INIMGR_HXX 39 #endif 40 #include <sfx2/docfile.hxx> 41 #include <svl/itemiter.hxx> 42 #include <editeng/brshitem.hxx> 43 44 45 #include <tools/resid.hxx> 46 #include <fmtornt.hxx> 47 #include <swtypes.hxx> // Leerstring 48 #include <wrtsh.hxx> 49 #include <uinums.hxx> 50 #include <poolfmt.hxx> 51 #include <charfmt.hxx> 52 #include <frmatr.hxx> 53 54 #include <unomid.h> 55 56 using namespace ::com::sun::star; 57 58 59 #define VERSION_30B ((sal_uInt16)250) 60 #define VERSION_31B ((sal_uInt16)326) 61 #define VERSION_40A ((sal_uInt16)364) 62 #define VERSION_50A ((sal_uInt16)373) 63 #define VERSION_53A ((sal_uInt16)596) 64 #define ACT_NUM_VERSION VERSION_53A 65 66 #define NUMRULE_FILENAME "numrule.cfg" 67 #define CHAPTER_FILENAME "chapter.cfg" 68 69 /*------------------------------------------------------------------------ 70 Beschreibung: Ops. zum Laden / Speichern 71 ------------------------------------------------------------------------*/ 72 73 74 SV_IMPL_PTRARR( _SwNumFmtsAttrs, SfxPoolItem* ) 75 76 77 // SwNumRulesWithName ---------------------------------------------------- 78 // PUBLIC METHODES ------------------------------------------------------- 79 /*------------------------------------------------------------------------ 80 Beschreibung: Speichern einer Regel 81 Parameter: rCopy -- die zu speichernde Regel 82 nIdx -- Position, an der die Regel zu speichern ist. 83 Eine alte Regel an dieser Position wird ueberschrieben. 84 ------------------------------------------------------------------------*/ 85 86 SwBaseNumRules::SwBaseNumRules( const String& rFileName ) 87 : 88 sFileName( rFileName ), 89 nVersion(0), 90 bModified( sal_False ) 91 { 92 Init(); 93 } 94 95 /*-----------------26.06.97 08.30------------------- 96 97 --------------------------------------------------*/ 98 SwBaseNumRules::~SwBaseNumRules() 99 { 100 if( bModified ) 101 { 102 SvtPathOptions aPathOpt; 103 String sNm( aPathOpt.GetUserConfigPath() ); 104 sNm += INET_PATH_TOKEN; 105 sNm += sFileName; 106 INetURLObject aTempObj(sNm); 107 sNm = aTempObj.GetFull(); 108 SfxMedium aStrm( sNm, STREAM_WRITE | STREAM_TRUNC | 109 STREAM_SHARE_DENYALL, sal_True ); 110 Store( *aStrm.GetOutStream() ); 111 } 112 113 for( sal_uInt16 i = 0; i < nMaxRules; ++i ) 114 delete pNumRules[i]; 115 } 116 117 /*------------------------------------------------------------------------ 118 Beschreibung: 119 ------------------------------------------------------------------------*/ 120 void SwBaseNumRules::Init() 121 { 122 for(sal_uInt16 i = 0; i < nMaxRules; ++i ) 123 pNumRules[i] = 0; 124 125 String sNm( sFileName ); 126 SvtPathOptions aOpt; 127 if( aOpt.SearchFile( sNm, SvtPathOptions::PATH_USERCONFIG )) 128 { 129 SfxMedium aStrm( sNm, STREAM_STD_READ, sal_True ); 130 Load( *aStrm.GetInStream() ); 131 } 132 } 133 134 /*-----------------26.06.97 08.30------------------- 135 136 --------------------------------------------------*/ 137 138 void SwBaseNumRules::ApplyNumRules(const SwNumRulesWithName &rCopy, sal_uInt16 nIdx) 139 { 140 ASSERT(nIdx < nMaxRules, Array der NumRules ueberindiziert.); 141 if( !pNumRules[nIdx] ) 142 pNumRules[nIdx] = new SwNumRulesWithName( rCopy ); 143 else 144 *pNumRules[nIdx] = rCopy; 145 } 146 147 // PROTECTED METHODES ---------------------------------------------------- 148 /*------------------------------------------------------------------------ 149 Beschreibung: Speichern 150 ------------------------------------------------------------------------*/ 151 152 sal_Bool /**/ SwBaseNumRules::Store(SvStream &rStream) 153 { 154 rStream << ACT_NUM_VERSION; 155 // Schreiben, welche Positionen durch eine Regel belegt sind 156 // Anschliessend Schreiben der einzelnen Rules 157 for(sal_uInt16 i = 0; i < nMaxRules; ++i) 158 { 159 if(pNumRules[i]) 160 { 161 rStream << (unsigned char) sal_True; 162 pNumRules[i]->Store( rStream ); 163 } 164 else 165 rStream << (unsigned char) sal_False; 166 } 167 return sal_True; 168 } 169 170 171 172 /*------------------------------------------------------------------------ 173 Beschreibung: Speichern / Laden 174 ------------------------------------------------------------------------*/ 175 176 177 int SwBaseNumRules::Load(SvStream &rStream) 178 { 179 int rc = 0; 180 181 rStream >> nVersion; 182 183 // wegen eines kleinen aber schweren Fehlers schreibt die PreFinal die 184 // gleiche VERSION_40A wie das SP2 #55402# 185 if(VERSION_40A == nVersion) 186 { 187 DBG_ERROR("Version 364 ist nicht eindeutig #55402#"); 188 } 189 else if( VERSION_30B == nVersion || VERSION_31B == nVersion || 190 ACT_NUM_VERSION >= nVersion ) 191 { 192 unsigned char bRule = sal_False; 193 for(sal_uInt16 i = 0; i < nMaxRules; ++i) 194 { 195 rStream >> bRule; 196 if(bRule) 197 pNumRules[i] = new SwNumRulesWithName( rStream, nVersion ); 198 } 199 } 200 else 201 { 202 rc = 1; 203 } 204 205 return rc; 206 } 207 208 /*-----------------26.06.97 08.34------------------- 209 210 --------------------------------------------------*/ 211 212 /*------------------------------------------------------------------------*/ 213 214 215 SwChapterNumRules::SwChapterNumRules() : 216 SwBaseNumRules(C2S(CHAPTER_FILENAME)) 217 { 218 } 219 220 /*------------------------------------------------------------------------*/ 221 222 SwChapterNumRules::~SwChapterNumRules() 223 { 224 } 225 226 /*-----------------26.06.97 08.23------------------- 227 228 --------------------------------------------------*/ 229 void SwChapterNumRules::ApplyNumRules(const SwNumRulesWithName &rCopy, sal_uInt16 nIdx) 230 { 231 bModified = sal_True; 232 SwBaseNumRules::ApplyNumRules(rCopy, nIdx); 233 } 234 235 /*------------------------------------------------------------------------*/ 236 237 SwNumRulesWithName::SwNumRulesWithName( const SwNumRule &rCopy, 238 const String &rName ) 239 : aName(rName) 240 { 241 for( sal_uInt16 n = 0; n < MAXLEVEL; ++n ) 242 { 243 const SwNumFmt* pFmt = rCopy.GetNumFmt( n ); 244 if( pFmt ) 245 aFmts[ n ] = new _SwNumFmtGlobal( *pFmt ); 246 else 247 aFmts[ n ] = 0; 248 } 249 } 250 251 /*------------------------------------------------------------------------ 252 Beschreibung: 253 ------------------------------------------------------------------------*/ 254 SwNumRulesWithName::SwNumRulesWithName( const SwNumRulesWithName& rCopy ) 255 { 256 memset( aFmts, 0, sizeof( aFmts )); 257 *this = rCopy; 258 } 259 260 261 /*------------------------------------------------------------------------ 262 Beschreibung: 263 ------------------------------------------------------------------------*/ 264 SwNumRulesWithName::~SwNumRulesWithName() 265 { 266 for( int n = 0; n < MAXLEVEL; ++n ) 267 delete aFmts[ n ]; 268 } 269 270 /*------------------------------------------------------------------------ 271 Beschreibung: 272 ------------------------------------------------------------------------*/ 273 const SwNumRulesWithName& SwNumRulesWithName::operator=(const SwNumRulesWithName &rCopy) 274 { 275 if( this != &rCopy ) 276 { 277 aName = rCopy.aName; 278 for( int n = 0; n < MAXLEVEL; ++n ) 279 { 280 delete aFmts[ n ]; 281 282 _SwNumFmtGlobal* pFmt = rCopy.aFmts[ n ]; 283 if( pFmt ) 284 aFmts[ n ] = new _SwNumFmtGlobal( *pFmt ); 285 else 286 aFmts[ n ] = 0; 287 } 288 } 289 return *this; 290 } 291 292 /*------------------------------------------------------------------------ 293 Beschreibung: 294 ------------------------------------------------------------------------*/ 295 SwNumRulesWithName::SwNumRulesWithName( SvStream &rStream, sal_uInt16 nVersion ) 296 { 297 CharSet eEncoding = gsl_getSystemTextEncoding(); 298 rStream.ReadByteString(aName, eEncoding); 299 300 char c; 301 for(sal_uInt16 n = 0; n < MAXLEVEL; ++n ) 302 { 303 if( VERSION_30B == nVersion ) 304 c = 1; 305 // wegen eines kleinen aber schweren Fehlers schreibt die PreFinal die 306 // gleiche VERSION_40A wie das SP2 #55402# 307 else if(nVersion < VERSION_40A && n > 5) 308 // else if(nVersion < VERSION_50A && n > 5) 309 c = 0; 310 else 311 rStream >> c; 312 313 if( c ) 314 aFmts[ n ] = new _SwNumFmtGlobal( rStream, nVersion ); 315 else 316 aFmts[ n ] = 0; 317 } 318 } 319 320 /*------------------------------------------------------------------------ 321 Beschreibung: 322 ------------------------------------------------------------------------*/ 323 324 void SwNumRulesWithName::MakeNumRule( SwWrtShell& rSh, SwNumRule& rChg ) const 325 { 326 // --> OD 2008-02-11 #newlistlevelattrs# 327 // --> OD 2008-06-06 #i89178# 328 rChg = SwNumRule( aName, numfunc::GetDefaultPositionAndSpaceMode() ); 329 // <-- 330 rChg.SetAutoRule( sal_False ); 331 _SwNumFmtGlobal* pFmt; 332 for( sal_uInt16 n = 0; n < MAXLEVEL; ++n ) 333 if( 0 != ( pFmt = aFmts[ n ] ) ) 334 { 335 SwNumFmt aNew; 336 pFmt->ChgNumFmt( rSh, aNew ); 337 rChg.Set( n, aNew ); 338 } 339 } 340 341 /*------------------------------------------------------------------------ 342 Beschreibung: 343 ------------------------------------------------------------------------*/ 344 void SwNumRulesWithName::Store( SvStream &rStream ) 345 { 346 CharSet eEncoding = gsl_getSystemTextEncoding(); 347 rStream.WriteByteString(aName, eEncoding); 348 349 for( sal_uInt16 n = 0; n < MAXLEVEL; ++n ) 350 { 351 _SwNumFmtGlobal* pFmt = aFmts[ n ]; 352 if( pFmt ) 353 { 354 rStream << (char)1; 355 pFmt->Store( rStream ); 356 } 357 else 358 rStream << (char)0; 359 } 360 } 361 /*------------------------------------------------------------------------ 362 Beschreibung: 363 ------------------------------------------------------------------------*/ 364 365 366 SwNumRulesWithName::_SwNumFmtGlobal::_SwNumFmtGlobal( const SwNumFmt& rFmt ) 367 : aFmt( rFmt ), nCharPoolId( USHRT_MAX ) 368 { 369 // relative Abstaende ????? 370 371 SwCharFmt* pFmt = rFmt.GetCharFmt(); 372 if( pFmt ) 373 { 374 sCharFmtName = pFmt->GetName(); 375 nCharPoolId = pFmt->GetPoolFmtId(); 376 if( pFmt->GetAttrSet().Count() ) 377 { 378 SfxItemIter aIter( pFmt->GetAttrSet() ); 379 const SfxPoolItem *pCurr = aIter.GetCurItem(); 380 while( sal_True ) 381 { 382 aItems.Insert( pCurr->Clone(), aItems.Count() ); 383 if( aIter.IsAtEnd() ) 384 break; 385 pCurr = aIter.NextItem(); 386 } 387 } 388 389 aFmt.SetCharFmt( 0 ); 390 } 391 } 392 393 /*------------------------------------------------------------------------ 394 Beschreibung: 395 ------------------------------------------------------------------------*/ 396 397 SwNumRulesWithName::_SwNumFmtGlobal::_SwNumFmtGlobal( const _SwNumFmtGlobal& rFmt ) 398 : 399 aFmt( rFmt.aFmt ), 400 sCharFmtName( rFmt.sCharFmtName ), 401 nCharPoolId( rFmt.nCharPoolId ) 402 { 403 for( sal_uInt16 n = rFmt.aItems.Count(); n; ) 404 aItems.Insert( rFmt.aItems[ --n ]->Clone(), aItems.Count() ); 405 } 406 407 /*------------------------------------------------------------------------ 408 Beschreibung: 409 ------------------------------------------------------------------------*/ 410 411 SwNumRulesWithName::_SwNumFmtGlobal::_SwNumFmtGlobal( SvStream& rStream, 412 sal_uInt16 nVersion ) 413 : nCharPoolId( USHRT_MAX ) 414 { 415 CharSet eEncoding = gsl_getSystemTextEncoding(); 416 { 417 sal_uInt16 nUS; 418 sal_Char cChar; 419 short nShort; 420 sal_Bool bFlag; 421 String sStr; 422 423 rStream >> nUS; aFmt.SetNumberingType((sal_Int16)nUS ); 424 if( VERSION_53A > nVersion ) 425 { 426 rStream >> cChar; aFmt.SetBulletChar( cChar ); 427 } 428 else 429 { 430 rStream >> nUS; aFmt.SetBulletChar( nUS ); 431 } 432 433 rStream >> bFlag; aFmt.SetIncludeUpperLevels( bFlag ); 434 435 if( VERSION_30B == nVersion ) 436 { 437 long nL; 438 rStream >> cChar; aFmt.SetStart( (sal_uInt16)cChar ); 439 440 rStream.ReadByteString(sStr, eEncoding); 441 aFmt.SetPrefix( sStr ); 442 rStream.ReadByteString(sStr, eEncoding); 443 aFmt.SetSuffix( sStr ); 444 rStream >> nUS; aFmt.SetNumAdjust( SvxAdjust( nUS ) ); 445 rStream >> nL; aFmt.SetLSpace( lNumIndent ); 446 rStream >> nL; aFmt.SetFirstLineOffset( (short)nL ); 447 } 448 else // alter StartWert war ein Byte 449 { 450 rStream >> nUS; aFmt.SetStart( nUS ); 451 rStream.ReadByteString(sStr, eEncoding); 452 aFmt.SetPrefix( sStr ); 453 rStream.ReadByteString(sStr, eEncoding); 454 aFmt.SetSuffix( sStr ); 455 rStream >> nUS; aFmt.SetNumAdjust( SvxAdjust( nUS ) ); 456 rStream >> nUS; aFmt.SetAbsLSpace( nUS ); 457 rStream >> nShort; aFmt.SetFirstLineOffset( nShort ); 458 rStream >> nUS; aFmt.SetCharTextDistance( nUS ); 459 rStream >> nShort; aFmt.SetLSpace( nShort ); 460 rStream >> bFlag; 461 } 462 463 sal_uInt16 nFamily; 464 sal_uInt16 nCharSet; 465 short nWidth; 466 short nHeight; 467 sal_uInt16 nPitch; 468 String aName; 469 470 rStream.ReadByteString(aName, eEncoding); 471 rStream >> nFamily >> nCharSet >> nWidth >> nHeight >> nPitch; 472 473 if( aName.Len() ) 474 { 475 Font aFont( nFamily, Size( nWidth, nHeight ) ); 476 aFont.SetName( aName ); 477 aFont.SetCharSet( (CharSet)nCharSet ); 478 aFont.SetPitch( (FontPitch)nPitch ); 479 480 aFmt.SetBulletFont( &aFont ); 481 } 482 else 483 nCharSet = RTL_TEXTENCODING_SYMBOL; 484 485 if( VERSION_53A > nVersion ) 486 aFmt.SetBulletChar( ByteString::ConvertToUnicode( 487 sal_Char(aFmt.GetBulletChar()), nCharSet )); 488 } 489 490 if( VERSION_30B != nVersion ) 491 { 492 sal_uInt16 nItemCount; 493 rStream >> nCharPoolId; 494 rStream.ReadByteString(sCharFmtName, eEncoding); 495 rStream >> nItemCount; 496 497 while( nItemCount-- ) 498 { 499 sal_uInt16 nWhich, nVers; 500 rStream >> nWhich >> nVers; 501 aItems.Insert( GetDfltAttr( nWhich )->Create( rStream, nVers ), 502 aItems.Count() ); 503 } 504 } 505 506 if( VERSION_40A == nVersion && SVX_NUM_BITMAP == aFmt.GetNumberingType() ) 507 { 508 sal_uInt8 cF; 509 Size aSz; 510 511 rStream >> aSz.Width() >> aSz.Height(); 512 513 rStream >> cF; 514 if( cF ) 515 { 516 SvxBrushItem* pBrush = 0; 517 SwFmtVertOrient* pVOrient = 0; 518 sal_uInt16 nVer; 519 520 if( cF & 1 ) 521 { 522 rStream >> nVer; 523 pBrush = (SvxBrushItem*)GetDfltAttr( RES_BACKGROUND ) 524 ->Create( rStream, nVer ); 525 } 526 527 if( cF & 2 ) 528 { 529 rStream >> nVer; 530 pVOrient = (SwFmtVertOrient*)GetDfltAttr( RES_VERT_ORIENT ) 531 ->Create( rStream, nVer ); 532 } 533 sal_Int16 eOrient = text::VertOrientation::NONE; 534 if(pVOrient) 535 eOrient = (sal_Int16)pVOrient->GetVertOrient(); 536 aFmt.SetGraphicBrush( pBrush, &aSz, pVOrient ? &eOrient : 0 ); 537 } 538 } 539 } 540 541 542 /*------------------------------------------------------------------------ 543 Beschreibung: 544 ------------------------------------------------------------------------*/ 545 546 SwNumRulesWithName::_SwNumFmtGlobal::~_SwNumFmtGlobal() 547 { 548 } 549 /*------------------------------------------------------------------------ 550 Beschreibung: 551 ------------------------------------------------------------------------*/ 552 553 554 void SwNumRulesWithName::_SwNumFmtGlobal::Store( SvStream& rStream ) 555 { 556 CharSet eEncoding = gsl_getSystemTextEncoding(); 557 { 558 String aName; 559 sal_uInt16 nFamily = FAMILY_DONTKNOW, nCharSet = 0, nPitch = 0; 560 short nWidth = 0, nHeight = 0; 561 562 const Font* pFnt = aFmt.GetBulletFont(); 563 if( pFnt ) 564 { 565 aName = pFnt->GetName(); 566 nFamily = (sal_uInt16)pFnt->GetFamily(); 567 nCharSet = (sal_uInt16)pFnt->GetCharSet(); 568 nWidth = (short)pFnt->GetSize().Width(); 569 nHeight = (short)pFnt->GetSize().Height(); 570 nPitch = (sal_uInt16)pFnt->GetPitch(); 571 } 572 573 rStream << sal_uInt16(aFmt.GetNumberingType()) 574 << aFmt.GetBulletChar() 575 << (aFmt.GetIncludeUpperLevels() > 0) 576 << aFmt.GetStart(); 577 rStream.WriteByteString( aFmt.GetPrefix(), eEncoding ); 578 rStream.WriteByteString( aFmt.GetSuffix(), eEncoding ); 579 rStream << sal_uInt16( aFmt.GetNumAdjust() ) 580 << aFmt.GetAbsLSpace() 581 << aFmt.GetFirstLineOffset() 582 << aFmt.GetCharTextDistance() 583 << aFmt.GetLSpace() 584 << sal_False;//aFmt.IsRelLSpace(); 585 rStream.WriteByteString( aName, eEncoding ); 586 rStream << nFamily 587 << nCharSet 588 << nWidth 589 << nHeight 590 << nPitch; 591 } 592 rStream << nCharPoolId; 593 rStream.WriteByteString( sCharFmtName, eEncoding ); 594 rStream << aItems.Count(); 595 596 for( sal_uInt16 n = aItems.Count(); n; ) 597 { 598 SfxPoolItem* pItem = aItems[ --n ]; 599 sal_uInt16 nIVers = pItem->GetVersion( SOFFICE_FILEFORMAT_50 ); 600 ASSERT( nIVers != USHRT_MAX, 601 "Was'n das: Item-Version USHRT_MAX in der aktuellen Version" ); 602 rStream << pItem->Which() 603 << nIVers; 604 pItem->Store( rStream, nIVers ); 605 } 606 607 // Erweiterungen fuer Version 40A 608 609 if( SVX_NUM_BITMAP == aFmt.GetNumberingType() ) 610 { 611 rStream << (sal_Int32)aFmt.GetGraphicSize().Width() 612 << (sal_Int32)aFmt.GetGraphicSize().Height(); 613 sal_uInt8 cFlg = ( 0 != aFmt.GetBrush() ? 1 : 0 ) + 614 ( 0 != aFmt.GetGraphicOrientation() ? 2 : 0 ); 615 rStream << cFlg; 616 617 if( aFmt.GetBrush() ) 618 { 619 sal_uInt16 nVersion = aFmt.GetBrush()->GetVersion( SOFFICE_FILEFORMAT_50 ); 620 rStream << nVersion; 621 aFmt.GetBrush()->Store( rStream, nVersion ); 622 } 623 if( aFmt.GetGraphicOrientation() ) 624 { 625 sal_uInt16 nVersion = aFmt.GetGraphicOrientation()->GetVersion( SOFFICE_FILEFORMAT_50 ); 626 rStream << nVersion; 627 aFmt.GetGraphicOrientation()->Store( rStream, nVersion ); 628 } 629 } 630 } 631 632 /*------------------------------------------------------------------------ 633 Beschreibung: 634 ------------------------------------------------------------------------*/ 635 636 void SwNumRulesWithName::_SwNumFmtGlobal::ChgNumFmt( SwWrtShell& rSh, 637 SwNumFmt& rNew ) const 638 { 639 SwCharFmt* pFmt = 0; 640 if( sCharFmtName.Len() ) 641 { 642 // suche erstmal ueber den Namen 643 sal_uInt16 nArrLen = rSh.GetCharFmtCount(); 644 for( sal_uInt16 i = 1; i < nArrLen; ++i ) 645 { 646 pFmt = &rSh.GetCharFmt( i ); 647 if( COMPARE_EQUAL == pFmt->GetName().CompareTo( sCharFmtName )) 648 // ist vorhanden, also belasse die Attribute wie sie sind! 649 break; 650 pFmt = 0; 651 } 652 653 if( !pFmt ) 654 { 655 if( IsPoolUserFmt( nCharPoolId ) ) 656 { 657 pFmt = rSh.MakeCharFmt( sCharFmtName ); 658 pFmt->SetAuto( sal_False ); 659 } 660 else 661 pFmt = rSh.GetCharFmtFromPool( nCharPoolId ); 662 663 if( !pFmt->GetDepends() ) // Attribute setzen 664 for( sal_uInt16 n = aItems.Count(); n; ) 665 pFmt->SetFmtAttr( *aItems[ --n ] ); 666 } 667 } 668 ((SwNumFmt&)aFmt).SetCharFmt( pFmt ); 669 rNew = aFmt; 670 if( pFmt ) 671 ((SwNumFmt&)aFmt).SetCharFmt( 0 ); 672 } 673 674