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 = CreateIterator( 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 SfxStyleSheetIterator* SfxStyleSheetBasePool::CreateIterator 672 ( 673 SfxStyleFamily eFam, 674 sal_uInt16 mask 675 ) 676 { 677 return new SfxStyleSheetIterator(this,eFam,mask); 678 } 679 680 681 SfxStyleSheetBase* SfxStyleSheetBasePool::Create 682 ( 683 const XubString& rName, 684 SfxStyleFamily eFam, 685 sal_uInt16 mask 686 ) 687 { 688 return new SfxStyleSheetBase( rName, *this, eFam, mask ); 689 } 690 691 SfxStyleSheetBase* SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r ) 692 { 693 return new SfxStyleSheetBase( r ); 694 } 695 696 SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const XubString& rName, SfxStyleFamily eFam, sal_uInt16 mask, sal_uInt16 nPos) 697 { 698 DBG_ASSERT( eFam != SFX_STYLE_FAMILY_ALL, "svl::SfxStyleSheetBasePool::Make(), FamilyAll is not a allowed Familie" ); 699 700 SfxStyleSheetIterator aIter(this, eFam, mask); 701 rtl::Reference< SfxStyleSheetBase > xStyle( aIter.Find( rName ) ); 702 DBG_ASSERT( !xStyle.is(), "svl::SfxStyleSheetBasePool::Make(), StyleSheet already exists" ); 703 SfxStyleSheetIterator& rIter = GetIterator_Impl(); 704 705 if( !xStyle.is() ) 706 { 707 xStyle = Create( rName, eFam, mask ); 708 if(0xffff == nPos || nPos == aStyles.size() || nPos == rIter.Count()) 709 { 710 aStyles.push_back( xStyle ); 711 } 712 else 713 { 714 rIter[nPos]; 715 aStyles.insert( aStyles.begin() + rIter.GetPos(), xStyle ); 716 } 717 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *xStyle.get() ) ); 718 } 719 return *xStyle.get(); 720 } 721 722 /////////////////////////////// Kopieren /////////////////////////////////// 723 724 // Hilfsroutine: Falls eine Vorlage dieses Namens existiert, wird 725 // sie neu erzeugt. Alle Vorlagen, die diese Vorlage zum Parent haben, 726 // werden umgehaengt. 727 728 SfxStyleSheetBase& SfxStyleSheetBasePool::Add( SfxStyleSheetBase& rSheet ) 729 { 730 SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), nMask); 731 SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() ); 732 Remove( pOld ); 733 rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) ); 734 aStyles.push_back( xNew ); 735 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CHANGED, *xNew.get() ) ); 736 return *xNew.get(); 737 } 738 739 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r ) 740 { 741 if( &r != this ) 742 { 743 Clear(); 744 *this += r; 745 } 746 return *this; 747 } 748 749 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r ) 750 { 751 if( &r != this ) 752 { 753 SfxStyles::const_iterator aIter( r.aStyles.begin() ); 754 while( aIter != r.aStyles.end() ) 755 { 756 Add(*(*aIter++).get()); 757 } 758 } 759 return *this; 760 } 761 762 //////////////////////////////// Suchen //////////////////////////////////// 763 764 sal_uInt16 SfxStyleSheetBasePool::Count() 765 { 766 return GetIterator_Impl().Count(); 767 } 768 769 SfxStyleSheetBase *SfxStyleSheetBasePool::operator[](sal_uInt16 nIdx) 770 { 771 return GetIterator_Impl()[nIdx]; 772 } 773 774 SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const XubString& rName, 775 SfxStyleFamily eFam, 776 sal_uInt16 mask) 777 { 778 SfxStyleSheetIterator aIter(this,eFam,mask); 779 return aIter.Find(rName); 780 } 781 782 const SfxStyles& SfxStyleSheetBasePool::GetStyles() 783 { 784 return aStyles; 785 } 786 787 SfxStyleSheetBase* SfxStyleSheetBasePool::First() 788 { 789 return GetIterator_Impl().First(); 790 } 791 792 SfxStyleSheetBase* SfxStyleSheetBasePool::Next() 793 { 794 return GetIterator_Impl().Next(); 795 } 796 797 //////////////////////////////// Loeschen ///////////////////////////////// 798 799 void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p ) 800 { 801 if( p ) 802 { 803 SfxStyles::iterator aIter( std::find( aStyles.begin(), aStyles.end(), rtl::Reference< SfxStyleSheetBase >( p ) ) ); 804 if( aIter != aStyles.end() ) 805 { 806 // Alle Styles umsetzen, deren Parent dieser hier ist 807 ChangeParent( p->GetName(), p->GetParent() ); 808 809 // #120015# Do not dispose, the removed StyleSheet may still be used in 810 // existing SdrUndoAttrObj incarnations. Rely on refcounting for disposal, 811 // this works well under normal conditions (checked breaking and counting 812 // on SfxStyleSheetBase constructors and destructors) 813 // 814 // com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY ); 815 // if( xComp.is() ) try 816 // { 817 // xComp->dispose(); 818 // } 819 // catch( com::sun::star::uno::Exception& ) 820 // { 821 // } 822 823 aStyles.erase(aIter); 824 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) ); 825 } 826 } 827 } 828 829 void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p ) 830 { 831 DBG_ASSERT( p, "svl::SfxStyleSheetBasePool::Insert(), no stylesheet?" ); 832 833 SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask()); 834 SfxStyleSheetBase* pOld = aIter.Find( p->GetName() ); 835 DBG_ASSERT( !pOld, "svl::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" ); 836 if( p->GetParent().Len() ) 837 { 838 pOld = aIter.Find( p->GetParent() ); 839 DBG_ASSERT( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" ); 840 } 841 aStyles.push_back( rtl::Reference< SfxStyleSheetBase >( p ) ); 842 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *p ) ); 843 } 844 845 void SfxStyleSheetBasePool::Clear() 846 { 847 SfxStyles aClearStyles; 848 aClearStyles.swap( aStyles ); 849 850 SfxStyles::iterator aIter( aClearStyles.begin() ); 851 while( aIter != aClearStyles.end() ) 852 { 853 com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY ); 854 if( xComp.is() ) try 855 { 856 xComp->dispose(); 857 } 858 catch( com::sun::star::uno::Exception& ) 859 { 860 } 861 862 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *(*aIter++).get() ) ); 863 } 864 } 865 866 /////////////////////////// Parents umsetzen //////////////////////////////// 867 868 void SfxStyleSheetBasePool::ChangeParent(const XubString& rOld, 869 const XubString& rNew, 870 sal_Bool bVirtual) 871 { 872 const sal_uInt16 nTmpMask = GetSearchMask(); 873 SetSearchMask(GetSearchFamily(), 0xffff); 874 for( SfxStyleSheetBase* p = First(); p; p = Next() ) 875 { 876 if( p->GetParent().Equals( rOld ) ) 877 { 878 if(bVirtual) 879 p->SetParent( rNew ); 880 else 881 p->aParent = rNew; 882 } 883 } 884 SetSearchMask(GetSearchFamily(), nTmpMask); 885 } 886 887 /////////////////////////// Laden/Speichern ///////////////////////////////// 888 889 void SfxStyleSheetBase::Load( SvStream&, sal_uInt16 ) 890 { 891 } 892 893 void SfxStyleSheetBase::Store( SvStream& ) 894 { 895 } 896 897 898 sal_Bool SfxStyleSheetBasePool::Load( SvStream& rStream ) 899 { 900 // alte Version? 901 if ( !rPool.IsVer2_Impl() ) 902 return Load1_Impl( rStream ); 903 904 // gesamten StyleSheetPool in neuer Version aus einem MiniRecord lesen 905 SfxMiniRecordReader aPoolRec( &rStream, SFX_STYLES_REC ); 906 907 // Header-Record lesen 908 short nCharSet = 0; 909 if ( !rStream.GetError() ) 910 { 911 SfxSingleRecordReader aHeaderRec( &rStream, SFX_STYLES_REC_HEADER ); 912 if ( !aHeaderRec.IsValid() ) 913 return sal_False; 914 915 aAppName = rPool.GetName(); 916 rStream >> nCharSet; 917 } 918 919 // Styles-Record lesen 920 if ( !rStream.GetError() ) 921 { 922 SfxMultiRecordReader aStylesRec( &rStream, SFX_STYLES_REC_STYLES ); 923 if ( !aStylesRec.IsValid() ) 924 return sal_False; 925 926 rtl_TextEncoding eEnc = GetSOLoadTextEncoding( 927 (rtl_TextEncoding)nCharSet, 928 sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) ); 929 rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet(); 930 rStream.SetStreamCharSet( eEnc ); 931 932 sal_uInt16 nStyles; 933 for ( nStyles = 0; aStylesRec.GetContent(); nStyles++ ) 934 { 935 // kann nicht mehr weiterlesen? 936 if ( rStream.GetError() ) 937 break; 938 939 // Globale Teile 940 XubString aName, aParent, aFollow; 941 String aHelpFile; 942 sal_uInt16 nFamily, nStyleMask,nCount; 943 sal_uInt32 nHelpId; 944 rStream.ReadByteString(aName, eEnc ); 945 rStream.ReadByteString(aParent, eEnc ); 946 rStream.ReadByteString(aFollow, eEnc ); 947 rStream >> nFamily >> nStyleMask; 948 SfxPoolItem::readByteString(rStream, aHelpFile); 949 rStream >> nHelpId; 950 951 SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask); 952 rSheet.SetHelpId( aHelpFile, nHelpId ); 953 // Hier erst einmal Parent und Follow zwischenspeichern 954 rSheet.aParent = aParent; 955 rSheet.aFollow = aFollow; 956 sal_uInt32 nPos = rStream.Tell(); 957 rStream >> nCount; 958 if(nCount) 959 { 960 rStream.Seek( nPos ); 961 // Das Laden des ItemSets bedient sich der Methode GetItemSet(), 962 // damit eigene ItemSets untergeschoben werden koennen 963 SfxItemSet& rSet = rSheet.GetItemSet(); 964 rSet.ClearItem(); 965 //! SfxItemSet aTmpSet( *pTmpPool ); 966 /*!aTmpSet*/ rSet.Load( rStream ); 967 //! rSet.Put( aTmpSet ); 968 } 969 // Lokale Teile 970 sal_uInt32 nSize; 971 sal_uInt16 nVer; 972 rStream >> nVer >> nSize; 973 nPos = rStream.Tell() + nSize; 974 rSheet.Load( rStream, nVer ); 975 rStream.Seek( nPos ); 976 } 977 978 // #72939# only loop through the styles that were really inserted 979 sal_uLong n = aStyles.size(); 980 981 //! delete pTmpPool; 982 // Jetzt Parent und Follow setzen. Alle Sheets sind geladen. 983 // Mit Setxxx() noch einmal den String eintragen, da diese 984 // virtuellen Methoden evtl. ueberlagert sind. 985 for ( sal_uLong i = 0; i < n; i++ ) 986 { 987 SfxStyleSheetBase* p = aStyles[ i ].get(); 988 XubString aText = p->aParent; 989 p->aParent.Erase(); 990 p->SetParent( aText ); 991 aText = p->aFollow; 992 p->aFollow.Erase(); 993 p->SetFollow( aText ); 994 } 995 996 rStream.SetStreamCharSet( eOldEnc ); 997 } 998 999 // alles klar? 1000 return sal_Bool( rStream.GetError() == SVSTREAM_OK ); 1001 } 1002 1003 sal_Bool SfxStyleSheetBasePool::Load1_Impl( SvStream& rStream ) 1004 { 1005 aAppName = rPool.GetName(); 1006 sal_uInt16 nVersion; 1007 short nCharSet; 1008 rStream >> nVersion; 1009 1010 if(nVersion!=STYLESTREAM_VERSION) 1011 nCharSet=nVersion; 1012 else 1013 rStream >> nCharSet; 1014 1015 rtl_TextEncoding eEnc = GetSOLoadTextEncoding( 1016 (rtl_TextEncoding)nCharSet, 1017 sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) ); 1018 rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet(); 1019 rStream.SetStreamCharSet( eEnc ); 1020 1021 sal_uInt16 nStyles; 1022 rStream >> nStyles; 1023 sal_uInt16 i; 1024 for ( i = 0; i < nStyles; i++ ) 1025 { 1026 // kann nicht mehr weiterlesen? 1027 if ( rStream.GetError() ) 1028 { 1029 nStyles = i; 1030 break; 1031 } 1032 1033 // Globale Teile 1034 XubString aName, aParent, aFollow; 1035 String aHelpFile; 1036 sal_uInt16 nFamily, nStyleMask,nCount; 1037 sal_uInt32 nHelpId; 1038 rStream.ReadByteString(aName, eEnc ); 1039 rStream.ReadByteString(aParent, eEnc ); 1040 rStream.ReadByteString(aFollow, eEnc ); 1041 rStream >> nFamily >> nStyleMask; 1042 SfxPoolItem::readByteString(rStream, aHelpFile); 1043 if(nVersion!=STYLESTREAM_VERSION) 1044 { 1045 sal_uInt16 nTmpHelpId; 1046 rStream >> nTmpHelpId; 1047 nHelpId=nTmpHelpId; 1048 } 1049 else 1050 rStream >> nHelpId; 1051 1052 SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask); 1053 rSheet.SetHelpId( aHelpFile, nHelpId ); 1054 // Hier erst einmal Parent und Follow zwischenspeichern 1055 rSheet.aParent = aParent; 1056 rSheet.aFollow = aFollow; 1057 sal_uInt32 nPos = rStream.Tell(); 1058 rStream >> nCount; 1059 if(nCount) { 1060 rStream.Seek( nPos ); 1061 // Das Laden des ItemSets bedient sich der Methode GetItemSet(), 1062 // damit eigene ItemSets untergeschoben werden koennen 1063 SfxItemSet& rSet = rSheet.GetItemSet(); 1064 rSet.ClearItem(); 1065 //! SfxItemSet aTmpSet( *pTmpPool ); 1066 /*!aTmpSet*/ rSet.Load( rStream ); 1067 //! rSet.Put( aTmpSet ); 1068 } 1069 // Lokale Teile 1070 sal_uInt32 nSize; 1071 sal_uInt16 nVer; 1072 rStream >> nVer >> nSize; 1073 nPos = rStream.Tell() + nSize; 1074 rSheet.Load( rStream, nVer ); 1075 rStream.Seek( nPos ); 1076 } 1077 1078 //! delete pTmpPool; 1079 // Jetzt Parent und Follow setzen. Alle Sheets sind geladen. 1080 // Mit Setxxx() noch einmal den String eintragen, da diese 1081 // virtuellen Methoden evtl. ueberlagert sind. 1082 for ( i = 0; i < nStyles; i++ ) 1083 { 1084 SfxStyleSheetBase* p = aStyles[ i ].get(); 1085 XubString aText = p->aParent; 1086 p->aParent.Erase(); 1087 p->SetParent( aText ); 1088 aText = p->aFollow; 1089 p->aFollow.Erase(); 1090 p->SetFollow( aText ); 1091 } 1092 1093 rStream.SetStreamCharSet( eOldEnc ); 1094 1095 return sal_Bool( rStream.GetError() == SVSTREAM_OK ); 1096 } 1097 1098 sal_Bool SfxStyleSheetBasePool::Store( SvStream& rStream, sal_Bool bUsed ) 1099 { 1100 // den ganzen StyleSheet-Pool in einen Mini-Record 1101 SfxMiniRecordWriter aPoolRec( &rStream, SFX_STYLES_REC ); 1102 1103 // Erst einmal die Dummies rauszaehlen; die werden nicht gespeichert 1104 sal_uInt16 nCount = 0; 1105 for( SfxStyleSheetBase* p = First(); p; p = Next() ) 1106 { 1107 if(!bUsed || p->IsUsed()) 1108 nCount++; 1109 } 1110 1111 // einen Header-Record vorweg 1112 rtl_TextEncoding eEnc 1113 = ::GetSOStoreTextEncoding( 1114 rStream.GetStreamCharSet(), 1115 sal::static_int_cast< sal_uInt16 >(rStream.GetVersion()) ); 1116 rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet(); 1117 rStream.SetStreamCharSet( eEnc ); 1118 1119 { 1120 SfxSingleRecordWriter aHeaderRec( &rStream, 1121 SFX_STYLES_REC_HEADER, 1122 STYLESTREAM_VERSION ); 1123 rStream << (short) eEnc; 1124 } 1125 1126 // die StyleSheets in einen MultiVarRecord 1127 { 1128 // Bug 79478: 1129 // make a check loop, to be shure, that the converted names are also 1130 // unique like the originals! In other cases we get a loop. 1131 SvStringsSortDtor aSortOrigNames( 0, 128 ); 1132 SvStrings aOrigNames( 0, 128 ); 1133 SvByteStringsSortDtor aSortConvNames( 0, 128 ); 1134 SvByteStrings aConvNames( 0, 128 ); 1135 1136 { 1137 1138 for( SfxStyleSheetBase* p = First(); p; p = Next() ) 1139 { 1140 if(!bUsed || p->IsUsed()) 1141 { 1142 sal_uInt16 nFamily = (sal_uInt16)p->GetFamily(); 1143 String* pName = new String( p->GetName() ); 1144 ByteString* pConvName = new ByteString( *pName, eEnc ); 1145 1146 pName->Insert( (sal_Unicode)nFamily, 0 ); 1147 pConvName->Insert( " ", 0 ); 1148 pConvName->SetChar( 1149 0, 1150 sal::static_int_cast< char >(0xff & (nFamily >> 8)) ); 1151 pConvName->SetChar( 1152 1, sal::static_int_cast< char >(0xff & nFamily) ); 1153 1154 sal_uInt16 nInsPos, nAdd = aSortConvNames.Count(); 1155 while( !aSortConvNames.Insert( pConvName, nInsPos ) ) 1156 (pConvName->Append( '_' )).Append( 1157 ByteString::CreateFromInt32( nAdd++ )); 1158 aOrigNames.Insert( pName, nInsPos ); 1159 } 1160 } 1161 1162 // now we have the list of the names, sorted by convertede names 1163 // But now we need the sorted list of orignames. 1164 { 1165 sal_uInt16 nInsPos, nEnd = aOrigNames.Count(); 1166 const ByteStringPtr* ppB = aSortConvNames.GetData(); 1167 for( sal_uInt16 n = 0; n < nEnd; ++n, ++ppB ) 1168 { 1169 String* p = aOrigNames.GetObject( n ); 1170 aSortOrigNames.Insert( p, nInsPos ); 1171 aConvNames.Insert( *ppB, nInsPos ); 1172 } 1173 1174 } 1175 } 1176 1177 1178 ByteString sEmpty; 1179 sal_uInt16 nFndPos; 1180 String sNm; 1181 SfxMultiVarRecordWriter aStylesRec( &rStream, SFX_STYLES_REC_STYLES, 0 ); 1182 for( SfxStyleSheetBase* p = First(); p; p = Next() ) 1183 { 1184 if(!bUsed || p->IsUsed()) 1185 { 1186 aStylesRec.NewContent(); 1187 1188 // Globale Teile speichern 1189 String aHelpFile; 1190 sal_uInt32 nHelpId = p->GetHelpId( aHelpFile ); 1191 sal_uInt16 nFamily = sal::static_int_cast< sal_uInt16 >(p->GetFamily()); 1192 String sFamily( (sal_Unicode)nFamily ); 1193 1194 (sNm = sFamily) += p->GetName(); 1195 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos )) 1196 rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 )); 1197 else 1198 rStream.WriteByteString( sEmpty ); 1199 1200 (sNm = sFamily) += p->GetParent(); 1201 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos )) 1202 rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 )); 1203 else 1204 rStream.WriteByteString( sEmpty ); 1205 1206 (sNm = sFamily) += p->GetFollow(); 1207 if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos )) 1208 rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 )); 1209 else 1210 rStream.WriteByteString( sEmpty ); 1211 1212 rStream << nFamily << p->GetMask(); 1213 SfxPoolItem::writeByteString(rStream, aHelpFile); 1214 rStream << nHelpId; 1215 if(p->pSet) 1216 p->pSet->Store( rStream ); 1217 else 1218 rStream << (sal_uInt16)0; 1219 1220 // Lokale Teile speichern 1221 // Vor dem lokalen Teil wird die Laenge der lokalen Daten 1222 // als sal_uInt32 sowie die Versionsnummer gespeichert. 1223 rStream << (sal_uInt16) p->GetVersion(); 1224 sal_uLong nPos1 = rStream.Tell(); 1225 rStream << (sal_uInt32) 0; 1226 p->Store( rStream ); 1227 sal_uLong nPos2 = rStream.Tell(); 1228 rStream.Seek( nPos1 ); 1229 rStream << (sal_uInt32) ( nPos2 - nPos1 - sizeof( sal_uInt32 ) ); 1230 rStream.Seek( nPos2 ); 1231 if( rStream.GetError() != SVSTREAM_OK ) 1232 break; 1233 } 1234 } 1235 } 1236 1237 rStream.SetStreamCharSet( eOldEnc ); 1238 1239 return sal_Bool( rStream.GetError() == SVSTREAM_OK ); 1240 } 1241 1242 SfxItemPool& SfxStyleSheetBasePool::GetPool() 1243 { 1244 return rPool; 1245 } 1246 1247 const SfxItemPool& SfxStyleSheetBasePool::GetPool() const 1248 { 1249 return rPool; 1250 } 1251 1252 /////////////////////// SfxStyleSheet ///////////////////////////////// 1253 1254 SfxStyleSheet::SfxStyleSheet(const XubString &rName, 1255 const SfxStyleSheetBasePool& r_Pool, 1256 SfxStyleFamily eFam, 1257 sal_uInt16 mask ): 1258 SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool& >( r_Pool ), eFam, mask) 1259 {} 1260 1261 SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle) : 1262 SfxStyleSheetBase(rStyle), 1263 SfxListener( rStyle ), 1264 SfxBroadcaster( rStyle ) 1265 {} 1266 1267 SfxStyleSheet::SfxStyleSheet() 1268 { 1269 } 1270 1271 SfxStyleSheet::~SfxStyleSheet() 1272 { 1273 Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_INDESTRUCTION, *this ) ); 1274 } 1275 1276 1277 sal_Bool SfxStyleSheet::SetParent( const XubString& rName ) 1278 { 1279 if(aParent == rName) 1280 return sal_True; 1281 const XubString aOldParent(aParent); 1282 if(SfxStyleSheetBase::SetParent(rName)) { 1283 // aus der Benachrichtigungskette des alten 1284 // Parents gfs. austragen 1285 if(aOldParent.Len()) { 1286 SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aOldParent, nFamily, 0xffff); 1287 if(pParent) 1288 EndListening(*pParent); 1289 } 1290 // in die Benachrichtigungskette des neuen 1291 // Parents eintragen 1292 if(aParent.Len()) { 1293 SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aParent, nFamily, 0xffff); 1294 if(pParent) 1295 StartListening(*pParent); 1296 } 1297 return sal_True; 1298 } 1299 return sal_False; 1300 } 1301 1302 // alle Zuhoerer benachtichtigen 1303 1304 void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint ) 1305 { 1306 Forward(rBC, rHint); 1307 } 1308 1309 //////////////////////// SfxStyleSheetPool /////////////////////////////// 1310 1311 SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet) 1312 : SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) ) 1313 { 1314 } 1315 1316 /////////////////////////////////// Factory //////////////////////////////// 1317 1318 SfxStyleSheetBase* SfxStyleSheetPool::Create( const XubString& rName, 1319 SfxStyleFamily eFam, sal_uInt16 mask ) 1320 { 1321 return new SfxStyleSheet( rName, *this, eFam, mask ); 1322 } 1323 1324 SfxStyleSheetBase* SfxStyleSheetPool::Create( const SfxStyleSheet& r ) 1325 { 1326 return new SfxStyleSheet( r ); 1327 } 1328 /* 1329 sal_Bool SfxStyleSheetPool::CopyTo(SfxStyleSheetPool &, const String &) 1330 { 1331 return sal_False; 1332 } 1333 */ 1334 1335 // -------------------------------------------------------------------- 1336 // class SfxUnoStyleSheet 1337 // -------------------------------------------------------------------- 1338 1339 SfxUnoStyleSheet::SfxUnoStyleSheet( const UniString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, sal_uInt16 _nMaske ) 1340 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rName, _rPool, _eFamily, _nMaske ) 1341 { 1342 } 1343 1344 // -------------------------------------------------------------------- 1345 SfxUnoStyleSheet::SfxUnoStyleSheet( const SfxStyleSheet& _rSheet ) 1346 : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rSheet ) 1347 { 1348 } 1349 1350 // -------------------------------------------------------------------- 1351 1352 SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle ) 1353 { 1354 SfxUnoStyleSheet* pRet = dynamic_cast< SfxUnoStyleSheet* >( xStyle.get() ); 1355 if( !pRet ) 1356 { 1357 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xStyle, ::com::sun::star::uno::UNO_QUERY ); 1358 if( xUT.is() ) 1359 pRet = reinterpret_cast<SfxUnoStyleSheet*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SfxUnoStyleSheet::getIdentifier()))); 1360 } 1361 return pRet; 1362 } 1363 1364 // -------------------------------------------------------------------- 1365 // XUnoTunnel 1366 // -------------------------------------------------------------------- 1367 1368 ::sal_Int64 SAL_CALL SfxUnoStyleSheet::getSomething( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException) 1369 { 1370 if( rId.getLength() == 16 && 0 == rtl_compareMemory( getIdentifier().getConstArray(), rId.getConstArray(), 16 ) ) 1371 { 1372 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this)); 1373 } 1374 else 1375 { 1376 return 0; 1377 } 1378 } 1379 1380 // -------------------------------------------------------------------- 1381 1382 const ::com::sun::star::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getIdentifier() 1383 { 1384 static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0; 1385 if( !pSeq ) 1386 { 1387 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ); 1388 if( !pSeq ) 1389 { 1390 static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 ); 1391 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 1392 pSeq = &aSeq; 1393 } 1394 } 1395 return *pSeq; 1396 } 1397 1398 // -------------------------------------------------------------------- 1399