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