1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svl.hxx" 26 27 #ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ 28 #include <com/sun/star/lang/XComponent.hpp> 29 #endif 30 31 #define _SVSTDARR_STRINGS 32 #define _SVSTDARR_STRINGSSORTDTOR 33 #define _SVSTDARR_BYTESTRINGS 34 #define _SVSTDARR_BYTESTRINGSSORTDTOR 35 36 #include <rtl/uuid.h> 37 #include <tools/tenccvt.hxx> 38 #include <comphelper/processfactory.hxx> 39 #include <unotools/intlwrapper.hxx> 40 #include <svl/smplhint.hxx> 41 #include <svl/poolitem.hxx> 42 #include <svl/itemset.hxx> 43 #include <svl/itempool.hxx> 44 #include <poolio.hxx> 45 #include <svl/filerec.hxx> 46 #include <svl/itemiter.hxx> 47 #include <svl/style.hxx> 48 #include <svl/svstdarr.hxx> 49 #include <unotools/syslocale.hxx> 50 #include <algorithm> 51 52 #define STYLESTREAM "SfxStyleSheets" 53 #define STYLESTREAM_VERSION sal_uInt16(50) 54 55 #ifdef DBG_UTIL 56 class DbgStyleSheetReferences 57 { 58 public: 59 DbgStyleSheetReferences() : mnStyles(0), mnPools(0) {} 60 ~DbgStyleSheetReferences() 61 { 62 OSL_TRACE("DbgStyleSheetReferences\nSfxStyleSheetBase left %ld\nSfxStyleSheetBasePool left %ld\n", mnStyles, mnPools ); 63 } 64 65 sal_uInt32 mnStyles; 66 sal_uInt32 mnPools; 67 } 68 aDbgStyleSheetReferences; 69 70 #endif 71 72 TYPEINIT0(SfxStyleSheetBase) 73 74 TYPEINIT3(SfxStyleSheet, SfxStyleSheetBase, SfxListener, SfxBroadcaster) 75 76 77 //========================================================================= 78 79 TYPEINIT1(SfxStyleSheetHint, SfxHint); 80 TYPEINIT1(SfxStyleSheetHintExtended, SfxStyleSheetHint); 81 TYPEINIT1(SfxStyleSheetPoolHint, SfxHint); 82 83 SfxStyleSheetHintExtended::SfxStyleSheetHintExtended 84 ( 85 sal_uInt16 nAction, // SFX_STYLESHEET_... (s.o.) 86 const String& rOldName 87 ) 88 : SfxStyleSheetHint( nAction ), 89 aName( rOldName ) 90 {} 91 SfxStyleSheetHintExtended::SfxStyleSheetHintExtended 92 ( 93 sal_uInt16 nAction, // SFX_STYLESHEET_... (s.o.) 94 const String& rOldName, 95 SfxStyleSheetBase& rStyleSheet // geh"ort weiterhin dem Aufrufer 96 ) 97 : SfxStyleSheetHint( nAction, rStyleSheet ), 98 aName( rOldName ) 99 {} 100 101 //------------------------------------------------------------------------- 102 103 SfxStyleSheetHint::SfxStyleSheetHint 104 ( 105 sal_uInt16 nAction, // SFX_STYLESHEET_... (s.o.) 106 SfxStyleSheetBase& rStyleSheet // geh"ort weiterhin dem Aufrufer 107 ) 108 : pStyleSh( &rStyleSheet ), 109 nHint( nAction ) 110 {} 111 112 SfxStyleSheetHint::SfxStyleSheetHint 113 ( 114 sal_uInt16 nAction // SFX_STYLESHEET_... (s.o.) 115 ) 116 : pStyleSh( NULL ), 117 nHint( nAction ) 118 {} 119 120 //========================================================================= 121 122 class SfxStyleSheetBasePool_Impl 123 { 124 public: 125 SfxStyles aStyles; 126 SfxStyleSheetIteratorPtr pIter; 127 }; 128 129 130 //////////////////////////// SfxStyleSheetBase /////////////////////////////// 131 132 // Konstruktoren 133 134 SfxStyleSheetBase::SfxStyleSheetBase( const XubString& rName, SfxStyleSheetBasePool& r, SfxStyleFamily eFam, sal_uInt16 mask ) 135 : rPool( r ) 136 , nFamily( eFam ) 137 , aName( rName ) 138 , aParent() 139 , aFollow( rName ) 140 , pSet( NULL ) 141 , nMask(mask) 142 , nHelpId( 0 ) 143 , bMySet( sal_False ) 144 { 145 #ifdef DBG_UTIL 146 aDbgStyleSheetReferences.mnStyles++; 147 #endif 148 } 149 150 SfxStyleSheetBase::SfxStyleSheetBase( const SfxStyleSheetBase& r ) 151 : comphelper::OWeakTypeObject() 152 , rPool( r.rPool ) 153 , nFamily( r.nFamily ) 154 , aName( r.aName ) 155 , aParent( r.aParent ) 156 , aFollow( r.aFollow ) 157 , aHelpFile( r.aHelpFile ) 158 , nMask( r.nMask ) 159 , nHelpId( r.nHelpId ) 160 , bMySet( r.bMySet ) 161 { 162 #ifdef DBG_UTIL 163 aDbgStyleSheetReferences.mnStyles++; 164 #endif 165 if( r.pSet ) 166 pSet = bMySet ? new SfxItemSet( *r.pSet ) : r.pSet; 167 else 168 pSet = NULL; 169 } 170 171 static SfxStyleSheetBasePool& implGetStaticPool() 172 { 173 static SfxStyleSheetBasePool* pSheetPool = 0; 174 static SfxItemPool* pBasePool = 0; 175 if( !pSheetPool ) 176 { 177 UniString aName; 178 pBasePool = new SfxItemPool( aName, 0, 0, 0 ); 179 pSheetPool = new SfxStyleSheetBasePool(*pBasePool); 180 } 181 return *pSheetPool; 182 } 183 184 SfxStyleSheetBase::SfxStyleSheetBase() 185 : comphelper::OWeakTypeObject() 186 , rPool( implGetStaticPool() ) 187 { 188 } 189 190 SfxStyleSheetBase::~SfxStyleSheetBase() 191 { 192 #ifdef DBG_UTIL 193 --aDbgStyleSheetReferences.mnStyles; 194 #endif 195 196 if( bMySet ) 197 { 198 delete pSet; 199 pSet = 0; 200 } 201 } 202 203 sal_uInt16 SfxStyleSheetBase::GetVersion() const 204 { 205 return 0x0000; 206 } 207 208 // Namen aendern 209 210 const XubString& SfxStyleSheetBase::GetName() const 211 { 212 return aName; 213 } 214 215 sal_Bool SfxStyleSheetBase::SetName( const XubString& rName ) 216 { 217 if(rName.Len() == 0) 218 return sal_False; 219 if( aName != rName ) 220 { 221 String aOldName = aName; 222 SfxStyleSheetBase *pOther = rPool.Find( rName, nFamily ) ; 223 if ( pOther && pOther != this ) 224 return sal_False; 225 226 SfxStyleFamily eTmpFam=rPool.GetSearchFamily(); 227 sal_uInt16 nTmpMask=rPool.GetSearchMask(); 228 229 rPool.SetSearchMask(nFamily); 230 231 if ( aName.Len() ) 232 rPool.ChangeParent( aName, rName, sal_False ); 233 if ( aFollow.Equals( aName ) ) 234 aFollow = rName; 235 aName = rName; 236 rPool.SetSearchMask(eTmpFam, nTmpMask); 237 rPool.Broadcast( SfxStyleSheetHintExtended( 238 SFX_STYLESHEET_MODIFIED, aOldName, *this ) ); 239 } 240 return sal_True; 241 } 242 243 rtl::OUString SfxStyleSheetBase::GetDisplayName() const 244 { 245 if( maDisplayName.getLength() == 0 ) 246 { 247 return aName; 248 } 249 else 250 { 251 return maDisplayName; 252 } 253 } 254 255 void SfxStyleSheetBase::SetDisplayName( const rtl::OUString& rDisplayName ) 256 { 257 maDisplayName = rDisplayName; 258 } 259 260 // Parent aendern 261 262 const XubString& SfxStyleSheetBase::GetParent() const 263 { 264 return aParent; 265 } 266 267 sal_Bool SfxStyleSheetBase::SetParent( const XubString& rName ) 268 { 269 if ( rName == aName ) 270 return sal_False; 271 272 if( aParent != rName ) 273 { 274 SfxStyleSheetBase* pIter = rPool.Find(rName, nFamily); 275 if( rName.Len() && !pIter ) 276 { 277 DBG_ERROR( "StyleSheet-Parent nicht gefunden" ); 278 return sal_False; 279 } 280 // rekursive Verknuepfungen verhindern 281 if( aName.Len() ) 282 while(pIter) 283 { 284 if(pIter->GetName() == aName && aName != rName) 285 return sal_False; 286 pIter = rPool.Find(pIter->GetParent(), nFamily); 287 } 288 aParent = rName; 289 } 290 rPool.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED, *this ) ); 291 return sal_True; 292 } 293 294 // Follow aendern 295 296 const XubString& SfxStyleSheetBase::GetFollow() const 297 { 298 return aFollow; 299 } 300 301 sal_Bool SfxStyleSheetBase::SetFollow( const XubString& rName ) 302 { 303 if( aFollow != rName ) 304 { 305 if( !rPool.Find( rName, nFamily ) ) 306 { 307 DBG_ERROR( "StyleSheet-Follow nicht gefunden" ); 308 return sal_False; 309 } 310 aFollow = rName; 311 } 312 rPool.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED, *this ) ); 313 return sal_True; 314 } 315 316 // Itemset setzen. Die Dflt-Implementation legt ein neues Set an. 317 318 SfxItemSet& SfxStyleSheetBase::GetItemSet() 319 { 320 if( !pSet ) 321 { 322 pSet = new SfxItemSet( rPool.GetPool() ); 323 bMySet = sal_True; 324 } 325 return *pSet; 326 } 327 328 // Hilfe-Datei und -ID setzen und abfragen 329 330 sal_uLong SfxStyleSheetBase::GetHelpId( String& rFile ) 331 { 332 rFile = aHelpFile; 333 return nHelpId; 334 } 335 336 void SfxStyleSheetBase::SetHelpId( const String& rFile, sal_uLong nId ) 337 { 338 aHelpFile = rFile; 339 nHelpId = nId; 340 } 341 342 // Folgevorlage m"oglich? Default: Ja 343 344 sal_Bool SfxStyleSheetBase::HasFollowSupport() const 345 { 346 return sal_True; 347 } 348 349 // Basisvorlage m"oglich? Default: Ja 350 351 sal_Bool SfxStyleSheetBase::HasParentSupport() const 352 { 353 return sal_True; 354 } 355 356 // Basisvorlage uf NULL setzen m"oglich? Default: Nein 357 358 sal_Bool SfxStyleSheetBase::HasClearParentSupport() const 359 { 360 return sal_False; 361 } 362 363 // Defaultmaessig sind alle StyleSheets Used 364 365 sal_Bool SfxStyleSheetBase::IsUsed() const 366 { 367 return sal_True; 368 } 369 370 // eingestellte Attribute ausgeben 371 372 373 XubString SfxStyleSheetBase::GetDescription() 374 { 375 return GetDescription( SFX_MAPUNIT_CM ); 376 } 377 378 // eingestellte Attribute ausgeben 379 380 XubString SfxStyleSheetBase::GetDescription( SfxMapUnit eMetric ) 381 { 382 SfxItemIter aIter( GetItemSet() ); 383 XubString aDesc; 384 const SfxPoolItem* pItem = aIter.FirstItem(); 385 386 IntlWrapper aIntlWrapper(comphelper::getProcessServiceFactory(), 387 SvtSysLocale().GetLanguage()); 388 while ( pItem ) 389 { 390 XubString aItemPresentation; 391 392 if ( !IsInvalidItem( pItem ) && 393 rPool.GetPool().GetPresentation( 394 *pItem, SFX_ITEM_PRESENTATION_COMPLETE, 395 eMetric, aItemPresentation, &aIntlWrapper ) ) 396 { 397 if ( aDesc.Len() && aItemPresentation.Len() ) 398 aDesc.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" + ")); 399 if ( aItemPresentation.Len() ) 400 aDesc += aItemPresentation; 401 } 402 pItem = aIter.NextItem(); 403 } 404 return aDesc; 405 } 406 407 /////////////////////////// SfxStyleSheetIterator /////////////////////////////// 408 409 SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const 410 { 411 return nSearchFamily; 412 } 413 414 inline sal_Bool SfxStyleSheetIterator::IsTrivialSearch() 415 { 416 return nMask == 0xFFFF && GetSearchFamily() == SFX_STYLE_FAMILY_ALL; 417 } 418 419 sal_Bool SfxStyleSheetIterator::DoesStyleMatch(SfxStyleSheetBase *pStyle) 420 { 421 return ((GetSearchFamily() == SFX_STYLE_FAMILY_ALL) || 422 ( pStyle->GetFamily() == GetSearchFamily() )) 423 && (( pStyle->GetMask() & ( GetSearchMask() & ~SFXSTYLEBIT_USED )) || 424 ( bSearchUsed ? pStyle->IsUsed() : sal_False ) || 425 GetSearchMask() == SFXSTYLEBIT_ALL ); 426 } 427 428 429 SfxStyleSheetIterator::SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase, 430 SfxStyleFamily eFam, sal_uInt16 n) 431 { 432 pBasePool=pBase; 433 nSearchFamily=eFam; 434 bSearchUsed=sal_False; 435 if((n != SFXSTYLEBIT_ALL ) && ((n & SFXSTYLEBIT_USED) == SFXSTYLEBIT_USED)) 436 { 437 bSearchUsed = sal_True; 438 n &= ~SFXSTYLEBIT_USED; 439 } 440 nMask=n; 441 } 442 443 SfxStyleSheetIterator::~SfxStyleSheetIterator() 444 { 445 } 446 447 448 sal_uInt16 SfxStyleSheetIterator::Count() 449 { 450 sal_uInt16 n = 0; 451 if( IsTrivialSearch()) 452 n = (sal_uInt16) pBasePool->aStyles.size(); 453 else 454 for(sal_uInt16 i=0; i<pBasePool->aStyles.size(); i++) 455 { 456 SfxStyleSheetBase* pStyle = pBasePool->aStyles[i].get(); 457 if(DoesStyleMatch(pStyle)) 458 n++; 459 } 460 return n; 461 } 462 463 SfxStyleSheetBase* SfxStyleSheetIterator::operator[](sal_uInt16 nIdx) 464 { 465 if( IsTrivialSearch()) 466 return pBasePool->aStyles[nIdx].get(); 467 468 sal_uInt16 z = 0; 469 for(sal_uInt16 n=0; n<pBasePool->aStyles.size(); n++) 470 { 471 SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get(); 472 if( DoesStyleMatch(pStyle)) 473 { 474 if(z == nIdx) 475 { 476 nAktPosition=n; 477 return pAktStyle=pStyle; 478 } 479 ++z; 480 } 481 } 482 DBG_ERROR("falscher Index"); 483 return 0; 484 } 485 486 SfxStyleSheetBase* SfxStyleSheetIterator::First() 487 { 488 sal_Int32 nIdx = -1; 489 490 if ( IsTrivialSearch() && pBasePool->aStyles.size() ) 491 nIdx = 0; 492 else 493 for( sal_uInt16 n = 0; n < pBasePool->aStyles.size(); n++ ) 494 { 495 SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get(); 496 497 if ( DoesStyleMatch( pStyle ) ) 498 { 499 nIdx = n; 500 break; 501 } 502 } 503 504 if ( nIdx != -1 ) 505 { 506 nAktPosition = (sal_uInt16)nIdx; 507 return pAktStyle = pBasePool->aStyles[nIdx].get(); 508 } 509 return 0; 510 } 511 512 513 SfxStyleSheetBase* SfxStyleSheetIterator::Next() 514 { 515 sal_Int32 nIdx = -1; 516 517 if ( IsTrivialSearch() && 518 (sal_uInt16)pBasePool->aStyles.size() > nAktPosition + 1 ) 519 nIdx = nAktPosition + 1; 520 else 521 for( sal_uInt16 n = nAktPosition + 1; n < pBasePool->aStyles.size(); n++ ) 522 { 523 SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get(); 524 525 if ( DoesStyleMatch( pStyle ) ) 526 { 527 nIdx = n; 528 break; 529 } 530 } 531 532 if ( nIdx != -1 ) 533 { 534 nAktPosition = (sal_uInt16)nIdx; 535 return pAktStyle = pBasePool->aStyles[nIdx].get(); 536 } 537 return 0; 538 } 539 540 541 SfxStyleSheetBase* SfxStyleSheetIterator::Find(const XubString& rStr) 542 { 543 for ( sal_uInt16 n = 0; n < pBasePool->aStyles.size(); n++ ) 544 { 545 SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get(); 546 547 // #98454# performance: in case of bSearchUsed==sal_True it may be 548 // significant to first compare the name and only if it matches to call 549 // the style sheet IsUsed() method in DoesStyleMatch(). 550 if ( pStyle->GetName().Equals( rStr ) && DoesStyleMatch( pStyle ) ) 551 { 552 nAktPosition = n; 553 return pAktStyle = pStyle; 554 } 555 } 556 return 0; 557 } 558 559 560 sal_uInt16 SfxStyleSheetIterator::GetSearchMask() const 561 { 562 sal_uInt16 mask = nMask; 563 564 if ( bSearchUsed ) 565 mask |= SFXSTYLEBIT_USED; 566 return mask; 567 } 568 569 /////////////////////////// SfxStyleSheetBasePool /////////////////////////////// 570 571 void SfxStyleSheetBasePool::Replace( 572 SfxStyleSheetBase& rSource, SfxStyleSheetBase& rTarget ) 573 { 574 rTarget.SetFollow( rSource.GetFollow() ); 575 rTarget.SetParent( rSource.GetParent() ); 576 SfxItemSet& rSourceSet = rSource.GetItemSet(); 577 SfxItemSet& rTargetSet = rTarget.GetItemSet(); 578 rTargetSet.Intersect( rSourceSet ); 579 rTargetSet.Put( rSourceSet ); 580 } 581 582 SfxStyleSheetIterator& SfxStyleSheetBasePool::GetIterator_Impl() 583 { 584 if( !pImp->pIter || (pImp->pIter->GetSearchMask() != nMask) || (pImp->pIter->GetSearchFamily() != nSearchFamily) ) 585 { 586 pImp->pIter = CreateIterator( nSearchFamily, nMask ); 587 } 588 589 return *pImp->pIter; 590 } 591 592 593 SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r ) 594 : aAppName(r.GetName()) 595 , rPool(r) 596 , nSearchFamily(SFX_STYLE_FAMILY_PARA) 597 , nMask(0xFFFF) 598 { 599 #ifdef DBG_UTIL 600 aDbgStyleSheetReferences.mnPools++; 601 #endif 602 603 pImp = new SfxStyleSheetBasePool_Impl; 604 } 605 606 SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r ) 607 : SfxBroadcaster( r ) 608 , comphelper::OWeakTypeObject() 609 , aAppName(r.aAppName) 610 , rPool(r.rPool) 611 , nSearchFamily(r.nSearchFamily) 612 , nMask( r.nMask ) 613 { 614 #ifdef DBG_UTIL 615 aDbgStyleSheetReferences.mnPools++; 616 #endif 617 618 pImp = new SfxStyleSheetBasePool_Impl; 619 *this += r; 620 } 621 622 SfxStyleSheetBasePool::~SfxStyleSheetBasePool() 623 { 624 #ifdef DBG_UTIL 625 aDbgStyleSheetReferences.mnPools--; 626 #endif 627 628 Broadcast( SfxSimpleHint(SFX_HINT_DYING) ); 629 Clear(); 630 delete pImp; 631 } 632 633 sal_Bool SfxStyleSheetBasePool::SetParent(SfxStyleFamily eFam, const XubString& rStyle, const XubString& rParent) 634 { 635 SfxStyleSheetIterator aIter(this,eFam,SFXSTYLEBIT_ALL); 636 SfxStyleSheetBase *pStyle = 637 aIter.Find(rStyle); 638 DBG_ASSERT(pStyle, "Vorlage nicht gefunden. Writer mit Solar <2541??"); 639 if(pStyle) 640 return pStyle->SetParent(rParent); 641 else 642 return sal_False; 643 } 644 645 646 void SfxStyleSheetBasePool::SetSearchMask(SfxStyleFamily eFam, sal_uInt16 n) 647 { 648 nSearchFamily = eFam; nMask = n; 649 } 650 651 sal_uInt16 SfxStyleSheetBasePool::GetSearchMask() const 652 { 653 return nMask; 654 } 655 656 657 // Der Name des Streams 658 659 String SfxStyleSheetBasePool::GetStreamName() 660 { 661 return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STYLESTREAM)); 662 } 663 664 /////////////////////////////////// Factory //////////////////////////////// 665 666 667 668 SfxStyleSheetIteratorPtr SfxStyleSheetBasePool::CreateIterator 669 ( 670 SfxStyleFamily eFam, 671 sal_uInt16 mask 672 ) 673 { 674 return SfxStyleSheetIteratorPtr(new SfxStyleSheetIterator(this,eFam,mask)); 675 } 676 677 678 SfxStyleSheetBase* SfxStyleSheetBasePool::Create 679 ( 680 const XubString& rName, 681 SfxStyleFamily eFam, 682 sal_uInt16 mask 683 ) 684 { 685 return new SfxStyleSheetBase( rName, *this, eFam, mask ); 686 } 687 688 SfxStyleSheetBase* SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r ) 689 { 690 return new SfxStyleSheetBase( r ); 691 } 692 693 SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const XubString& rName, SfxStyleFamily eFam, sal_uInt16 mask, sal_uInt16 nPos) 694 { 695 DBG_ASSERT( eFam != SFX_STYLE_FAMILY_ALL, "svl::SfxStyleSheetBasePool::Make(), FamilyAll is not a allowed Familie" ); 696 697 SfxStyleSheetIterator aIter(this, eFam, mask); 698 rtl::Reference< SfxStyleSheetBase > xStyle( aIter.Find( rName ) ); 699 DBG_ASSERT( !xStyle.is(), "svl::SfxStyleSheetBasePool::Make(), StyleSheet already exists" ); 700 SfxStyleSheetIterator& rIter = GetIterator_Impl(); 701 702 if( !xStyle.is() ) 703 { 704 xStyle = Create( rName, eFam, mask ); 705 if(0xffff == nPos || nPos == aStyles.size() || nPos == rIter.Count()) 706 { 707 aStyles.push_back( xStyle ); 708 } 709 else 710 { 711 rIter[nPos]; 712 aStyles.insert( aStyles.begin() + rIter.GetPos(), xStyle ); 713 } 714 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *xStyle.get() ) ); 715 } 716 return *xStyle.get(); 717 } 718 719 /////////////////////////////// Kopieren /////////////////////////////////// 720 721 // Hilfsroutine: Falls eine Vorlage dieses Namens existiert, wird 722 // sie neu erzeugt. Alle Vorlagen, die diese Vorlage zum Parent haben, 723 // werden umgehaengt. 724 725 SfxStyleSheetBase& SfxStyleSheetBasePool::Add( SfxStyleSheetBase& rSheet ) 726 { 727 SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), nMask); 728 SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() ); 729 Remove( pOld ); 730 rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) ); 731 aStyles.push_back( xNew ); 732 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CHANGED, *xNew.get() ) ); 733 return *xNew.get(); 734 } 735 736 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r ) 737 { 738 if( &r != this ) 739 { 740 Clear(); 741 *this += r; 742 } 743 return *this; 744 } 745 746 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r ) 747 { 748 if( &r != this ) 749 { 750 SfxStyles::const_iterator aIter( r.aStyles.begin() ); 751 while( aIter != r.aStyles.end() ) 752 { 753 Add(*(*aIter++).get()); 754 } 755 } 756 return *this; 757 } 758 759 //////////////////////////////// Suchen //////////////////////////////////// 760 761 sal_uInt16 SfxStyleSheetBasePool::Count() 762 { 763 return GetIterator_Impl().Count(); 764 } 765 766 SfxStyleSheetBase *SfxStyleSheetBasePool::operator[](sal_uInt16 nIdx) 767 { 768 return GetIterator_Impl()[nIdx]; 769 } 770 771 SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const XubString& rName, 772 SfxStyleFamily eFam, 773 sal_uInt16 mask) 774 { 775 SfxStyleSheetIterator aIter(this,eFam,mask); 776 return aIter.Find(rName); 777 } 778 779 const SfxStyles& SfxStyleSheetBasePool::GetStyles() 780 { 781 return aStyles; 782 } 783 784 SfxStyleSheetBase* SfxStyleSheetBasePool::First() 785 { 786 return GetIterator_Impl().First(); 787 } 788 789 SfxStyleSheetBase* SfxStyleSheetBasePool::Next() 790 { 791 return GetIterator_Impl().Next(); 792 } 793 794 //////////////////////////////// Loeschen ///////////////////////////////// 795 796 void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p ) 797 { 798 if( p ) 799 { 800 SfxStyles::iterator aIter( std::find( aStyles.begin(), aStyles.end(), rtl::Reference< SfxStyleSheetBase >( p ) ) ); 801 if( aIter != aStyles.end() ) 802 { 803 // Alle Styles umsetzen, deren Parent dieser hier ist 804 ChangeParent( p->GetName(), p->GetParent() ); 805 806 // #120015# Do not dispose, the removed StyleSheet may still be used in 807 // existing SdrUndoAttrObj incarnations. Rely on refcounting for disposal, 808 // this works well under normal conditions (checked breaking and counting 809 // on SfxStyleSheetBase constructors and destructors) 810 // 811 // com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY ); 812 // if( xComp.is() ) try 813 // { 814 // xComp->dispose(); 815 // } 816 // catch( com::sun::star::uno::Exception& ) 817 // { 818 // } 819 820 aStyles.erase(aIter); 821 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) ); 822 } 823 } 824 } 825 826 void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p ) 827 { 828 DBG_ASSERT( p, "svl::SfxStyleSheetBasePool::Insert(), no stylesheet?" ); 829 830 SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask()); 831 SfxStyleSheetBase* pOld = aIter.Find( p->GetName() ); 832 DBG_ASSERT( !pOld, "svl::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" ); 833 if( p->GetParent().Len() ) 834 { 835 pOld = aIter.Find( p->GetParent() ); 836 DBG_ASSERT( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" ); 837 } 838 aStyles.push_back( rtl::Reference< SfxStyleSheetBase >( p ) ); 839 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *p ) ); 840 } 841 842 void SfxStyleSheetBasePool::Clear() 843 { 844 SfxStyles aClearStyles; 845 aClearStyles.swap( aStyles ); 846 847 SfxStyles::iterator aIter( aClearStyles.begin() ); 848 while( aIter != aClearStyles.end() ) 849 { 850 com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY ); 851 if( xComp.is() ) try 852 { 853 xComp->dispose(); 854 } 855 catch( com::sun::star::uno::Exception& ) 856 { 857 } 858 859 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *(*aIter++).get() ) ); 860 } 861 } 862 863 /////////////////////////// Parents umsetzen //////////////////////////////// 864 865 void SfxStyleSheetBasePool::ChangeParent(const XubString& rOld, 866 const XubString& rNew, 867 sal_Bool bVirtual) 868 { 869 const sal_uInt16 nTmpMask = GetSearchMask(); 870 SetSearchMask(GetSearchFamily(), 0xffff); 871 for( SfxStyleSheetBase* p = First(); p; p = Next() ) 872 { 873 if( p->GetParent().Equals( rOld ) ) 874 { 875 if(bVirtual) 876 p->SetParent( rNew ); 877 else 878 p->aParent = rNew; 879 } 880 } 881 SetSearchMask(GetSearchFamily(), nTmpMask); 882 } 883 884 /////////////////////////// Laden/Speichern ///////////////////////////////// 885 886 void SfxStyleSheetBase::Load( SvStream&, sal_uInt16 ) 887 { 888 } 889 890 void SfxStyleSheetBase::Store( SvStream& ) 891 { 892 } 893 894 895 sal_Bool SfxStyleSheetBasePool::Load( SvStream& rStream ) 896 { 897 // alte Version? 898 if ( !rPool.IsVer2_Impl() ) 899 return Load1_Impl( rStream ); 900 901 // gesamten StyleSheetPool in neuer Version aus einem MiniRecord lesen 902 SfxMiniRecordReader aPoolRec( &rStream, SFX_STYLES_REC ); 903 904 // Header-Record lesen 905 short nCharSet = 0; 906 if ( !rStream.GetError() ) 907 { 908 SfxSingleRecordReader aHeaderRec( &rStream, SFX_STYLES_REC_HEADER ); 909 if ( !aHeaderRec.IsValid() ) 910 return sal_False; 911 912 aAppName = rPool.GetName(); 913 rStream >> nCharSet; 914 } 915 916 // Styles-Record lesen 917 if ( !rStream.GetError() ) 918 { 919 SfxMultiRecordReader aStylesRec( &rStream, SFX_STYLES_REC_STYLES ); 920 if ( !aStylesRec.IsValid() ) 921 return sal_False; 922 923 rtl_TextEncoding eEnc = GetSOLoadTextEncoding( 924 (rtl_TextEncoding)nCharSet, 925 sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) ); 926 rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet(); 927 rStream.SetStreamCharSet( eEnc ); 928 929 sal_uInt16 nStyles; 930 for ( nStyles = 0; aStylesRec.GetContent(); nStyles++ ) 931 { 932 // kann nicht mehr weiterlesen? 933 if ( rStream.GetError() ) 934 break; 935 936 // Globale Teile 937 XubString aName, aParent, aFollow; 938 String aHelpFile; 939 sal_uInt16 nFamily, nStyleMask,nCount; 940 sal_uInt32 nHelpId; 941 rStream.ReadByteString(aName, eEnc ); 942 rStream.ReadByteString(aParent, eEnc ); 943 rStream.ReadByteString(aFollow, eEnc ); 944 rStream >> nFamily >> nStyleMask; 945 SfxPoolItem::readByteString(rStream, aHelpFile); 946 rStream >> nHelpId; 947 948 SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask); 949 rSheet.SetHelpId( aHelpFile, nHelpId ); 950 // Hier erst einmal Parent und Follow zwischenspeichern 951 rSheet.aParent = aParent; 952 rSheet.aFollow = aFollow; 953 sal_uInt32 nPos = rStream.Tell(); 954 rStream >> nCount; 955 if(nCount) 956 { 957 rStream.Seek( nPos ); 958 // Das Laden des ItemSets bedient sich der Methode GetItemSet(), 959 // damit eigene ItemSets untergeschoben werden koennen 960 SfxItemSet& rSet = rSheet.GetItemSet(); 961 rSet.ClearItem(); 962 //! SfxItemSet aTmpSet( *pTmpPool ); 963 /*!aTmpSet*/ rSet.Load( rStream ); 964 //! rSet.Put( aTmpSet ); 965 } 966 // Lokale Teile 967 sal_uInt32 nSize; 968 sal_uInt16 nVer; 969 rStream >> nVer >> nSize; 970 nPos = rStream.Tell() + nSize; 971 rSheet.Load( rStream, nVer ); 972 rStream.Seek( nPos ); 973 } 974 975 // #72939# only loop through the styles that were really inserted 976 sal_uLong n = aStyles.size(); 977 978 //! delete pTmpPool; 979 // Jetzt Parent und Follow setzen. Alle Sheets sind geladen. 980 // Mit Setxxx() noch einmal den String eintragen, da diese 981 // virtuellen Methoden evtl. ueberlagert sind. 982 for ( sal_uLong i = 0; i < n; i++ ) 983 { 984 SfxStyleSheetBase* p = aStyles[ i ].get(); 985 XubString aText = p->aParent; 986 p->aParent.Erase(); 987 p->SetParent( aText ); 988 aText = p->aFollow; 989 p->aFollow.Erase(); 990 p->SetFollow( aText ); 991 } 992 993 rStream.SetStreamCharSet( eOldEnc ); 994 } 995 996 // alles klar? 997 return sal_Bool( rStream.GetError() == SVSTREAM_OK ); 998 } 999 1000 sal_Bool SfxStyleSheetBasePool::Load1_Impl( SvStream& rStream ) 1001 { 1002 aAppName = rPool.GetName(); 1003 sal_uInt16 nVersion; 1004 short nCharSet; 1005 rStream >> nVersion; 1006 1007 if(nVersion!=STYLESTREAM_VERSION) 1008 nCharSet=nVersion; 1009 else 1010 rStream >> nCharSet; 1011 1012 rtl_TextEncoding eEnc = GetSOLoadTextEncoding( 1013 (rtl_TextEncoding)nCharSet, 1014 sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) ); 1015 rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet(); 1016 rStream.SetStreamCharSet( eEnc ); 1017 1018 sal_uInt16 nStyles; 1019 rStream >> nStyles; 1020 sal_uInt16 i; 1021 for ( i = 0; i < nStyles; i++ ) 1022 { 1023 // kann nicht mehr weiterlesen? 1024 if ( rStream.GetError() ) 1025 { 1026 nStyles = i; 1027 break; 1028 } 1029 1030 // Globale Teile 1031 XubString aName, aParent, aFollow; 1032 String aHelpFile; 1033 sal_uInt16 nFamily, nStyleMask,nCount; 1034 sal_uInt32 nHelpId; 1035 rStream.ReadByteString(aName, eEnc ); 1036 rStream.ReadByteString(aParent, eEnc ); 1037 rStream.ReadByteString(aFollow, eEnc ); 1038 rStream >> nFamily >> nStyleMask; 1039 SfxPoolItem::readByteString(rStream, aHelpFile); 1040 if(nVersion!=STYLESTREAM_VERSION) 1041 { 1042 sal_uInt16 nTmpHelpId; 1043 rStream >> nTmpHelpId; 1044 nHelpId=nTmpHelpId; 1045 } 1046 else 1047 rStream >> nHelpId; 1048 1049 SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask); 1050 rSheet.SetHelpId( aHelpFile, nHelpId ); 1051 // Hier erst einmal Parent und Follow zwischenspeichern 1052 rSheet.aParent = aParent; 1053 rSheet.aFollow = aFollow; 1054 sal_uInt32 nPos = rStream.Tell(); 1055 rStream >> nCount; 1056 if(nCount) { 1057 rStream.Seek( nPos ); 1058 // Das Laden des ItemSets bedient sich der Methode GetItemSet(), 1059 // damit eigene ItemSets untergeschoben werden koennen 1060 SfxItemSet& rSet = rSheet.GetItemSet(); 1061 rSet.ClearItem(); 1062 //! SfxItemSet aTmpSet( *pTmpPool ); 1063 /*!aTmpSet*/ rSet.Load( rStream ); 1064 //! rSet.Put( aTmpSet ); 1065 } 1066 // Lokale Teile 1067 sal_uInt32 nSize; 1068 sal_uInt16 nVer; 1069 rStream >> nVer >> nSize; 1070 nPos = rStream.Tell() + nSize; 1071 rSheet.Load( rStream, nVer ); 1072 rStream.Seek( nPos ); 1073 } 1074 1075 //! delete pTmpPool; 1076 // Jetzt Parent und Follow setzen. Alle Sheets sind geladen. 1077 // Mit Setxxx() noch einmal den String eintragen, da diese 1078 // virtuellen Methoden evtl. ueberlagert sind. 1079 for ( i = 0; i < nStyles; i++ ) 1080 { 1081 SfxStyleSheetBase* p = aStyles[ i ].get(); 1082 XubString aText = p->aParent; 1083 p->aParent.Erase(); 1084 p->SetParent( aText ); 1085 aText = p->aFollow; 1086 p->aFollow.Erase(); 1087 p->SetFollow( aText ); 1088 } 1089 1090 rStream.SetStreamCharSet( eOldEnc ); 1091 1092 return sal_Bool( rStream.GetError() == SVSTREAM_OK ); 1093 } 1094 1095 sal_Bool SfxStyleSheetBasePool::Store( SvStream& rStream, sal_Bool bUsed ) 1096 { 1097 // den ganzen StyleSheet-Pool in einen Mini-Record 1098 SfxMiniRecordWriter aPoolRec( &rStream, SFX_STYLES_REC ); 1099 1100 // Erst einmal die Dummies rauszaehlen; die werden nicht gespeichert 1101 sal_uInt16 nCount = 0; 1102 for( SfxStyleSheetBase* p = First(); p; p = Next() ) 1103 { 1104 if(!bUsed || p->IsUsed()) 1105 nCount++; 1106 } 1107 1108 // einen Header-Record vorweg 1109 rtl_TextEncoding eEnc 1110 = ::GetSOStoreTextEncoding( 1111 rStream.GetStreamCharSet(), 1112 sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) ); 1113 rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet(); 1114 rStream.SetStreamCharSet( eEnc ); 1115 1116 { 1117 SfxSingleRecordWriter aHeaderRec( &rStream, 1118 SFX_STYLES_REC_HEADER, 1119 STYLESTREAM_VERSION ); 1120 rStream << (short) eEnc; 1121 } 1122 1123 // die StyleSheets in einen MultiVarRecord 1124 { 1125 // Bug 79478: 1126 // make a check loop, to be shure, that the converted names are also 1127 // unique like the originals! In other cases we get a loop. 1128 SvStringsSortDtor aSortOrigNames( 0, 128 ); 1129 SvStrings aOrigNames( 0, 128 ); 1130 SvByteStringsSortDtor aSortConvNames( 0, 128 ); 1131 SvByteStrings aConvNames( 0, 128 ); 1132 1133 { 1134 1135 for( SfxStyleSheetBase* p = First(); p; p = Next() ) 1136 { 1137 if(!bUsed || p->IsUsed()) 1138 { 1139 sal_uInt16 nFamily = (sal_uInt16)p->GetFamily(); 1140 String* pName = new String( p->GetName() ); 1141 ByteString* pConvName = new ByteString( *pName, eEnc ); 1142 1143 pName->Insert( (sal_Unicode)nFamily, 0 ); 1144 pConvName->Insert( " ", 0 ); 1145 pConvName->SetChar( 1146 0, 1147 sal::static_int_cast< char >(0xff & (nFamily >> 8)) ); 1148 pConvName->SetChar( 1149 1, sal::static_int_cast< char >(0xff & nFamily) ); 1150 1151 sal_uInt16 nInsPos, nAdd = aSortConvNames.Count(); 1152 while( !aSortConvNames.Insert( pConvName, nInsPos ) ) 1153 (pConvName->Append( '_' )).Append( 1154 ByteString::CreateFromInt32( nAdd++ )); 1155 aOrigNames.Insert( pName, nInsPos ); 1156 } 1157 } 1158 1159 // now we have the list of the names, sorted by convertede names 1160 // But now we need the sorted list of orignames. 1161 { 1162 sal_uInt16 nInsPos, nEnd = aOrigNames.Count(); 1163 const ByteStringPtr* ppB = aSortConvNames.GetData(); 1164 for( sal_uInt16 n = 0; n < nEnd; ++n, ++ppB ) 1165 { 1166 String* p = aOrigNames.GetObject( n ); 1167 aSortOrigNames.Insert( p, nInsPos ); 1168 aConvNames.Insert( *ppB, nInsPos ); 1169 } 1170 1171 } 1172 } 1173 1174 1175 ByteString sEmpty; 1176 sal_uInt16 nFndPos; 1177 String sNm; 1178 SfxMultiVarRecordWriter aStylesRec( &rStream, SFX_STYLES_REC_STYLES, 0 ); 1179 for( SfxStyleSheetBase* p = First(); p; p = Next() ) 1180 { 1181 if(!bUsed || p->IsUsed()) 1182 { 1183 aStylesRec.NewContent(); 1184 1185 // Globale Teile speichern 1186 String aHelpFile; 1187 sal_uInt32 nHelpId = p->GetHelpId( aHelpFile ); 1188 sal_uInt16 nFamily = sal::static_int_cast< sal_uInt16 >(p->GetFamily()); 1189 String sFamily( (sal_Unicode)nFamily ); 1190 1191 (sNm = sFamily) += p->GetName(); 1192 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos )) 1193 rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 )); 1194 else 1195 rStream.WriteByteString( sEmpty ); 1196 1197 (sNm = sFamily) += p->GetParent(); 1198 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos )) 1199 rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 )); 1200 else 1201 rStream.WriteByteString( sEmpty ); 1202 1203 (sNm = sFamily) += p->GetFollow(); 1204 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos )) 1205 rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 )); 1206 else 1207 rStream.WriteByteString( sEmpty ); 1208 1209 rStream << nFamily << p->GetMask(); 1210 SfxPoolItem::writeByteString(rStream, aHelpFile); 1211 rStream << nHelpId; 1212 if(p->pSet) 1213 p->pSet->Store( rStream ); 1214 else 1215 rStream << (sal_uInt16)0; 1216 1217 // Lokale Teile speichern 1218 // Vor dem lokalen Teil wird die Laenge der lokalen Daten 1219 // als sal_uInt32 sowie die Versionsnummer gespeichert. 1220 rStream << (sal_uInt16) p->GetVersion(); 1221 sal_uLong nPos1 = rStream.Tell(); 1222 rStream << (sal_uInt32) 0; 1223 p->Store( rStream ); 1224 sal_uLong nPos2 = rStream.Tell(); 1225 rStream.Seek( nPos1 ); 1226 rStream << (sal_uInt32) ( nPos2 - nPos1 - sizeof( sal_uInt32 ) ); 1227 rStream.Seek( nPos2 ); 1228 if( rStream.GetError() != SVSTREAM_OK ) 1229 break; 1230 } 1231 } 1232 } 1233 1234 rStream.SetStreamCharSet( eOldEnc ); 1235 1236 return sal_Bool( rStream.GetError() == SVSTREAM_OK ); 1237 } 1238 1239 SfxItemPool& SfxStyleSheetBasePool::GetPool() 1240 { 1241 return rPool; 1242 } 1243 1244 const SfxItemPool& SfxStyleSheetBasePool::GetPool() const 1245 { 1246 return rPool; 1247 } 1248 1249 /////////////////////// SfxStyleSheet ///////////////////////////////// 1250 1251 SfxStyleSheet::SfxStyleSheet(const XubString &rName, 1252 const SfxStyleSheetBasePool& r_Pool, 1253 SfxStyleFamily eFam, 1254 sal_uInt16 mask ): 1255 SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool& >( r_Pool ), eFam, mask) 1256 {} 1257 1258 SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle) : 1259 SfxStyleSheetBase(rStyle), 1260 SfxListener( rStyle ), 1261 SfxBroadcaster( rStyle ) 1262 {} 1263 1264 SfxStyleSheet::SfxStyleSheet() 1265 { 1266 } 1267 1268 SfxStyleSheet::~SfxStyleSheet() 1269 { 1270 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_INDESTRUCTION, *this ) ); 1271 } 1272 1273 1274 sal_Bool SfxStyleSheet::SetParent( const XubString& rName ) 1275 { 1276 if(aParent == rName) 1277 return sal_True; 1278 const XubString aOldParent(aParent); 1279 if(SfxStyleSheetBase::SetParent(rName)) { 1280 // aus der Benachrichtigungskette des alten 1281 // Parents gfs. austragen 1282 if(aOldParent.Len()) { 1283 SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aOldParent, nFamily, 0xffff); 1284 if(pParent) 1285 EndListening(*pParent); 1286 } 1287 // in die Benachrichtigungskette des neuen 1288 // Parents eintragen 1289 if(aParent.Len()) { 1290 SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aParent, nFamily, 0xffff); 1291 if(pParent) 1292 StartListening(*pParent); 1293 } 1294 return sal_True; 1295 } 1296 return sal_False; 1297 } 1298 1299 // alle Zuhoerer benachtichtigen 1300 1301 void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint ) 1302 { 1303 Forward(rBC, rHint); 1304 } 1305 1306 //////////////////////// SfxStyleSheetPool /////////////////////////////// 1307 1308 SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet) 1309 : SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) ) 1310 { 1311 } 1312 1313 /////////////////////////////////// Factory //////////////////////////////// 1314 1315 SfxStyleSheetBase* SfxStyleSheetPool::Create( const XubString& rName, 1316 SfxStyleFamily eFam, sal_uInt16 mask ) 1317 { 1318 return new SfxStyleSheet( rName, *this, eFam, mask ); 1319 } 1320 1321 SfxStyleSheetBase* SfxStyleSheetPool::Create( const SfxStyleSheet& r ) 1322 { 1323 return new SfxStyleSheet( r ); 1324 } 1325 /* 1326 sal_Bool SfxStyleSheetPool::CopyTo(SfxStyleSheetPool &, const String &) 1327 { 1328 return sal_False; 1329 } 1330 */ 1331 1332 // -------------------------------------------------------------------- 1333 // class SfxUnoStyleSheet 1334 // -------------------------------------------------------------------- 1335 1336 SfxUnoStyleSheet::SfxUnoStyleSheet( const UniString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, sal_uInt16 _nMaske ) 1337 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rName, _rPool, _eFamily, _nMaske ) 1338 { 1339 } 1340 1341 // -------------------------------------------------------------------- 1342 SfxUnoStyleSheet::SfxUnoStyleSheet( const SfxStyleSheet& _rSheet ) 1343 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rSheet ) 1344 { 1345 } 1346 1347 // -------------------------------------------------------------------- 1348 1349 SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle ) 1350 { 1351 SfxUnoStyleSheet* pRet = dynamic_cast< SfxUnoStyleSheet* >( xStyle.get() ); 1352 if( !pRet ) 1353 { 1354 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xStyle, ::com::sun::star::uno::UNO_QUERY ); 1355 if( xUT.is() ) 1356 pRet = reinterpret_cast<SfxUnoStyleSheet*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SfxUnoStyleSheet::getIdentifier()))); 1357 } 1358 return pRet; 1359 } 1360 1361 // -------------------------------------------------------------------- 1362 // XUnoTunnel 1363 // -------------------------------------------------------------------- 1364 1365 ::sal_Int64 SAL_CALL SfxUnoStyleSheet::getSomething( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException) 1366 { 1367 if( rId.getLength() == 16 && 0 == rtl_compareMemory( getIdentifier().getConstArray(), rId.getConstArray(), 16 ) ) 1368 { 1369 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this)); 1370 } 1371 else 1372 { 1373 return 0; 1374 } 1375 } 1376 1377 // -------------------------------------------------------------------- 1378 1379 const ::com::sun::star::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getIdentifier() 1380 { 1381 static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0; 1382 if( !pSeq ) 1383 { 1384 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ); 1385 if( !pSeq ) 1386 { 1387 static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 ); 1388 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 1389 pSeq = &aSeq; 1390 } 1391 } 1392 return *pSeq; 1393 } 1394 1395 // -------------------------------------------------------------------- 1396