1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #define ENABLE_BYTESTRING_STREAM_OPERATORS 32 33 #include <tools/vcompat.hxx> 34 #include <ucbhelper/content.hxx> 35 #include <unotools/ucbstreamhelper.hxx> 36 #include <unotools/pathoptions.hxx> 37 #include <sfx2/docfile.hxx> 38 #include "svx/gallery.hxx" 39 #include "gallery.hrc" 40 #include "svx/galmisc.hxx" 41 #include "svx/galtheme.hxx" 42 #include "svx/gallery1.hxx" 43 #include <com/sun/star/sdbc/XResultSet.hpp> 44 #include <com/sun/star/ucb/XContentAccess.hpp> 45 46 #define ENABLE_BYTESTRING_STREAM_OPERATORS 47 48 // -------------- 49 // - Namespaces - 50 // -------------- 51 52 using namespace ::rtl; 53 using namespace ::com::sun::star; 54 55 // --------------------- 56 // - GalleryThemeEntry - 57 // --------------------- 58 59 GalleryThemeEntry::GalleryThemeEntry( const INetURLObject& rBaseURL, const String& rName, 60 sal_uInt32 _nFileNumber, sal_Bool _bReadOnly, sal_Bool _bImported, 61 sal_Bool _bNewFile, sal_uInt32 _nId, sal_Bool _bThemeNameFromResource ) : 62 nFileNumber ( _nFileNumber ), 63 nId ( _nId ), 64 bReadOnly ( _bReadOnly || _bImported ), 65 bImported ( _bImported ), 66 bThemeNameFromResource ( _bThemeNameFromResource ) 67 { 68 INetURLObject aURL( rBaseURL ); 69 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); 70 String aFileName( String( RTL_CONSTASCII_USTRINGPARAM( "sg" ) ) ); 71 72 aURL.Append( ( aFileName += String::CreateFromInt32( nFileNumber ) ) += String( RTL_CONSTASCII_USTRINGPARAM( ".thm" ) ) ); 73 aThmURL = ImplGetURLIgnoreCase( aURL ); 74 75 aURL.setExtension( String( RTL_CONSTASCII_USTRINGPARAM( "sdg" ) ) ); 76 aSdgURL = ImplGetURLIgnoreCase( aURL ); 77 78 aURL.setExtension( String( RTL_CONSTASCII_USTRINGPARAM( "sdv" ) ) ); 79 aSdvURL = ImplGetURLIgnoreCase( aURL ); 80 81 SetModified( _bNewFile ); 82 83 if( nId && bThemeNameFromResource ) 84 aName = String( GAL_RESID( RID_GALLERYSTR_THEME_START + (sal_uInt16) nId ) ); 85 86 if( !aName.Len() ) 87 aName = rName; 88 } 89 90 // ----------------------------------------------------------------------------- 91 92 INetURLObject GalleryThemeEntry::ImplGetURLIgnoreCase( const INetURLObject& rURL ) const 93 { 94 INetURLObject aURL( rURL ); 95 String aFileName; 96 sal_Bool bExists = sal_False; 97 98 // check original file name 99 if( FileExists( aURL ) ) 100 bExists = sal_True; 101 else 102 { 103 // check upper case file name 104 aURL.setName( aURL.getName().toAsciiUpperCase() ); 105 106 if( FileExists( aURL ) ) 107 bExists = sal_True; 108 else 109 { 110 // check lower case file name 111 aURL.setName( aURL.getName().toAsciiLowerCase() ); 112 113 if( FileExists( aURL ) ) 114 bExists = sal_True; 115 } 116 } 117 118 return aURL; 119 } 120 121 // ----------------------------------------------------------------------------- 122 123 void GalleryThemeEntry::SetName( const String& rNewName ) 124 { 125 if( aName != rNewName ) 126 { 127 aName = rNewName; 128 SetModified( sal_True ); 129 bThemeNameFromResource = sal_False; 130 } 131 } 132 133 // ----------------------------------------------------------------------------- 134 135 void GalleryThemeEntry::SetId( sal_uInt32 nNewId, sal_Bool bResetThemeName ) 136 { 137 nId = nNewId; 138 SetModified( sal_True ); 139 bThemeNameFromResource = ( nId && bResetThemeName ); 140 } 141 142 // --------------------------- 143 // - GalleryImportThemeEntry - 144 // --------------------------- 145 146 SvStream& operator<<( SvStream& rOut, const GalleryImportThemeEntry& rEntry ) 147 { 148 ByteString aDummy; 149 150 rOut << ByteString( rEntry.aThemeName, RTL_TEXTENCODING_UTF8 ) << 151 ByteString( rEntry.aUIName, RTL_TEXTENCODING_UTF8 ) << 152 ByteString( String(rEntry.aURL.GetMainURL( INetURLObject::NO_DECODE )), RTL_TEXTENCODING_UTF8 ) << 153 ByteString( rEntry.aImportName, RTL_TEXTENCODING_UTF8 ) << 154 aDummy; 155 156 return rOut; 157 } 158 159 // ------------------------------------------------------------------------ 160 161 SvStream& operator>>( SvStream& rIn, GalleryImportThemeEntry& rEntry ) 162 { 163 ByteString aTmpStr; 164 165 rIn >> aTmpStr; rEntry.aThemeName = String( aTmpStr, RTL_TEXTENCODING_UTF8 ); 166 rIn >> aTmpStr; rEntry.aUIName = String( aTmpStr, RTL_TEXTENCODING_UTF8 ); 167 rIn >> aTmpStr; rEntry.aURL = INetURLObject( String( aTmpStr, RTL_TEXTENCODING_UTF8 ) ); 168 rIn >> aTmpStr; rEntry.aImportName = String( aTmpStr, RTL_TEXTENCODING_UTF8 ); 169 rIn >> aTmpStr; 170 171 return rIn; 172 } 173 174 // -------------------------- 175 // - GalleryThemeCacheEntry - 176 // -------------------------- 177 178 class GalleryThemeCacheEntry; 179 DBG_NAME(GalleryThemeCacheEntry) 180 class GalleryThemeCacheEntry 181 { 182 private: 183 184 const GalleryThemeEntry* mpThemeEntry; 185 GalleryTheme* mpTheme; 186 187 public: 188 189 GalleryThemeCacheEntry( const GalleryThemeEntry* pThemeEntry, GalleryTheme* pTheme ) : 190 mpThemeEntry( pThemeEntry ), mpTheme( pTheme ) {DBG_CTOR(GalleryThemeCacheEntry,NULL);} 191 ~GalleryThemeCacheEntry() { delete mpTheme;DBG_DTOR(GalleryThemeCacheEntry,NULL); } 192 193 const GalleryThemeEntry* GetThemeEntry() const { return mpThemeEntry; } 194 GalleryTheme* GetTheme() const { return mpTheme; } 195 }; 196 197 // ----------- 198 // - Gallery - 199 // ----------- 200 Gallery::Gallery( const String& rMultiPath ) 201 : nReadTextEncoding ( gsl_getSystemTextEncoding() ) 202 , nLastFileNumber ( 0 ) 203 , bMultiPath ( sal_False ) 204 { 205 ImplLoad( rMultiPath ); 206 } 207 208 // ------------------------------------------------------------------------ 209 210 Gallery::~Gallery() 211 { 212 // Themen-Liste loeschen 213 for( GalleryThemeEntry* pThemeEntry = aThemeList.First(); pThemeEntry; pThemeEntry = aThemeList.Next() ) 214 delete pThemeEntry; 215 216 // Import-Liste loeschen 217 for( GalleryImportThemeEntry* pImportEntry = aImportList.First(); pImportEntry; pImportEntry = aImportList.Next() ) 218 delete pImportEntry; 219 } 220 221 // ------------------------------------------------------------------------ 222 223 Gallery* Gallery::GetGalleryInstance() 224 { 225 static Gallery* pGallery = NULL; 226 227 if( !pGallery ) 228 { 229 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 230 if( !pGallery ) 231 { 232 pGallery = new Gallery( SvtPathOptions().GetGalleryPath() ); 233 } 234 } 235 236 return pGallery; 237 } 238 239 // ------------------------------------------------------------------------ 240 241 void Gallery::ImplLoad( const String& rMultiPath ) 242 { 243 const sal_uInt16 nTokenCount = rMultiPath.GetTokenCount( ';' ); 244 sal_Bool bIsReadOnlyDir; 245 246 bMultiPath = ( nTokenCount > 0 ); 247 248 INetURLObject aCurURL(SvtPathOptions().GetConfigPath()); 249 ImplLoadSubDirs( aCurURL, bIsReadOnlyDir ); 250 251 if( !bIsReadOnlyDir ) 252 aUserURL = aCurURL; 253 254 if( bMultiPath ) 255 { 256 aRelURL = INetURLObject( rMultiPath.GetToken( 0, ';' ) ); 257 258 for( sal_uInt16 i = 0UL; i < nTokenCount; i++ ) 259 { 260 aCurURL = INetURLObject(rMultiPath.GetToken( i, ';' )); 261 262 ImplLoadSubDirs( aCurURL, bIsReadOnlyDir ); 263 264 if( !bIsReadOnlyDir ) 265 aUserURL = aCurURL; 266 } 267 } 268 else 269 aRelURL = INetURLObject( rMultiPath ); 270 271 DBG_ASSERT( aUserURL.GetProtocol() != INET_PROT_NOT_VALID, "no writable Gallery user directory available" ); 272 DBG_ASSERT( aRelURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); 273 274 ImplLoadImports(); 275 } 276 277 // ------------------------------------------------------------------------ 278 279 void Gallery::ImplLoadSubDirs( const INetURLObject& rBaseURL, sal_Bool& rbDirIsReadOnly ) 280 { 281 rbDirIsReadOnly = sal_False; 282 283 try 284 { 285 uno::Reference< ucb::XCommandEnvironment > xEnv; 286 ::ucbhelper::Content aCnt( rBaseURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv ); 287 288 uno::Sequence< OUString > aProps( 1 ); 289 aProps.getArray()[ 0 ] = OUString::createFromAscii( "Url" ); 290 291 uno::Reference< sdbc::XResultSet > xResultSet( aCnt.createCursor( aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) ); 292 293 try 294 { 295 // check readonlyness the very hard way 296 INetURLObject aTestURL( rBaseURL ); 297 String aTestFile( RTL_CONSTASCII_USTRINGPARAM( "cdefghij.klm" ) ); 298 299 aTestURL.Append( aTestFile ); 300 SvStream* pTestStm = ::utl::UcbStreamHelper::CreateStream( aTestURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE ); 301 302 if( pTestStm ) 303 { 304 *pTestStm << 1; 305 306 if( pTestStm->GetError() ) 307 rbDirIsReadOnly = sal_True; 308 309 delete pTestStm; 310 KillFile( aTestURL ); 311 } 312 else 313 rbDirIsReadOnly = sal_True; 314 } 315 catch( const ucb::ContentCreationException& ) 316 { 317 } 318 catch( const uno::RuntimeException& ) 319 { 320 } 321 catch( const uno::Exception& ) 322 { 323 } 324 325 if( xResultSet.is() ) 326 { 327 uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY ); 328 329 if( xContentAccess.is() ) 330 { 331 static const ::rtl::OUString s_sTitle(RTL_CONSTASCII_USTRINGPARAM("Title")); 332 static const ::rtl::OUString s_sIsReadOnly(RTL_CONSTASCII_USTRINGPARAM("IsReadOnly")); 333 static const ::rtl::OUString s_sSDG_EXT(RTL_CONSTASCII_USTRINGPARAM("sdg")); 334 static const ::rtl::OUString s_sSDV_EXT(RTL_CONSTASCII_USTRINGPARAM("sdv")); 335 336 while( xResultSet->next() ) 337 { 338 INetURLObject aThmURL( xContentAccess->queryContentIdentifierString() ); 339 340 if(aThmURL.GetExtension().equalsIgnoreAsciiCaseAscii("thm")) 341 { 342 INetURLObject aSdgURL( aThmURL); aSdgURL.SetExtension( s_sSDG_EXT ); 343 INetURLObject aSdvURL( aThmURL ); aSdvURL.SetExtension( s_sSDV_EXT ); 344 345 OUString aTitle; 346 sal_Bool bReadOnly = sal_False; 347 348 try 349 { 350 ::ucbhelper::Content aThmCnt( aThmURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv ); 351 ::ucbhelper::Content aSdgCnt( aSdgURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv ); 352 ::ucbhelper::Content aSdvCnt( aSdvURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv ); 353 354 try 355 { 356 aThmCnt.getPropertyValue( s_sTitle ) >>= aTitle; 357 } 358 catch( const uno::RuntimeException& ) 359 { 360 } 361 catch( const uno::Exception& ) 362 { 363 } 364 365 if( aTitle.getLength() ) 366 { 367 try 368 { 369 aThmCnt.getPropertyValue( s_sIsReadOnly ) >>= bReadOnly; 370 } 371 catch( const uno::RuntimeException& ) 372 { 373 } 374 catch( const uno::Exception& ) 375 { 376 } 377 378 if( !bReadOnly ) 379 { 380 try 381 { 382 aSdgCnt.getPropertyValue( s_sTitle ) >>= aTitle; 383 } 384 catch( const ::com::sun::star::uno::RuntimeException& ) 385 { 386 } 387 catch( const ::com::sun::star::uno::Exception& ) 388 { 389 } 390 391 if( aTitle.getLength() ) 392 { 393 try 394 { 395 aSdgCnt.getPropertyValue( s_sIsReadOnly ) >>= bReadOnly; 396 } 397 catch( const uno::RuntimeException& ) 398 { 399 } 400 catch( const uno::Exception& ) 401 { 402 } 403 } 404 } 405 406 if( !bReadOnly ) 407 { 408 try 409 { 410 aSdvCnt.getPropertyValue( s_sTitle ) >>= aTitle; 411 } 412 catch( const ::com::sun::star::uno::RuntimeException& ) 413 { 414 } 415 catch( const ::com::sun::star::uno::Exception& ) 416 { 417 } 418 419 if( aTitle.getLength() ) 420 { 421 try 422 { 423 aSdvCnt.getPropertyValue( s_sIsReadOnly ) >>= bReadOnly; 424 } 425 catch( const uno::RuntimeException& ) 426 { 427 } 428 catch( const uno::Exception& ) 429 { 430 } 431 } 432 } 433 434 GalleryThemeEntry* pEntry = GalleryTheme::CreateThemeEntry( aThmURL, rbDirIsReadOnly || bReadOnly ); 435 436 if( pEntry ) 437 { 438 const sal_uIntPtr nFileNumber = (sal_uIntPtr) String(aThmURL.GetBase()).Erase( 0, 2 ).Erase( 6 ).ToInt32(); 439 440 aThemeList.Insert( pEntry, LIST_APPEND ); 441 442 if( nFileNumber > nLastFileNumber ) 443 nLastFileNumber = nFileNumber; 444 } 445 } 446 } 447 catch( const ucb::ContentCreationException& ) 448 { 449 } 450 catch( const uno::RuntimeException& ) 451 { 452 } 453 catch( const uno::Exception& ) 454 { 455 } 456 } 457 } 458 } 459 } 460 } 461 catch( const ucb::ContentCreationException& ) 462 { 463 } 464 catch( const uno::RuntimeException& ) 465 { 466 } 467 catch( const uno::Exception& ) 468 { 469 } 470 } 471 472 // ------------------------------------------------------------------------ 473 474 void Gallery::ImplLoadImports() 475 { 476 INetURLObject aURL( GetUserURL() ); 477 478 aURL.Append( String( RTL_CONSTASCII_USTRINGPARAM( "gallery.sdi" ) ) ); 479 480 if( FileExists( aURL ) ) 481 { 482 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ); 483 484 if( pIStm ) 485 { 486 GalleryThemeEntry* pThemeEntry; 487 GalleryImportThemeEntry* pImportEntry; 488 INetURLObject aFile; 489 sal_uInt32 nInventor; 490 sal_uInt32 nCount; 491 sal_uInt16 nId; 492 sal_uInt16 i; 493 sal_uInt16 nTempCharSet; 494 495 for( pImportEntry = aImportList.First(); pImportEntry; pImportEntry = aImportList.Next() ) 496 delete pImportEntry; 497 498 aImportList.Clear(); 499 *pIStm >> nInventor; 500 501 if( nInventor == COMPAT_FORMAT( 'S', 'G', 'A', '3' ) ) 502 { 503 *pIStm >> nId >> nCount >> nTempCharSet; 504 505 for( i = 0; i < nCount; i++ ) 506 { 507 pImportEntry = new GalleryImportThemeEntry; 508 509 *pIStm >> *pImportEntry; 510 aImportList.Insert( pImportEntry, LIST_APPEND ); 511 aFile = INetURLObject( pImportEntry->aURL ); 512 pThemeEntry = new GalleryThemeEntry( aFile, 513 pImportEntry->aUIName, 514 String(aFile.GetBase()).Erase( 0, 2 ).Erase( 6 ).ToInt32(), 515 sal_True, sal_True, sal_False, 0, sal_False ); 516 517 aThemeList.Insert( pThemeEntry, LIST_APPEND ); 518 } 519 } 520 521 delete pIStm; 522 } 523 } 524 } 525 526 // ------------------------------------------------------------------------ 527 528 void Gallery::ImplWriteImportList() 529 { 530 INetURLObject aURL( GetUserURL() ); 531 aURL.Append( ( String( "gallery.sdi", RTL_TEXTENCODING_UTF8 ) ) ); 532 SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE | STREAM_TRUNC ); 533 534 if( pOStm ) 535 { 536 const sal_uInt32 nInventor = (sal_uInt32) COMPAT_FORMAT( 'S', 'G', 'A', '3' ); 537 const sal_uInt16 nId = 0x0004; 538 539 *pOStm << nInventor << nId << (sal_uInt32) aImportList.Count() << (sal_uInt16) gsl_getSystemTextEncoding(); 540 541 for( GalleryImportThemeEntry* pImportEntry = aImportList.First(); pImportEntry; pImportEntry = aImportList.Next() ) 542 *pOStm << *pImportEntry; 543 544 if( pOStm->GetError() ) 545 ErrorHandler::HandleError( ERRCODE_IO_GENERAL ); 546 547 delete pOStm; 548 } 549 } 550 551 // ------------------------------------------------------------------------ 552 553 GalleryThemeEntry* Gallery::ImplGetThemeEntry( const String& rThemeName ) 554 { 555 GalleryThemeEntry* pFound = NULL; 556 557 if( rThemeName.Len() ) 558 for( GalleryThemeEntry* pEntry = aThemeList.First(); pEntry && !pFound; pEntry = aThemeList.Next() ) 559 if( rThemeName == pEntry->GetThemeName() ) 560 pFound = pEntry; 561 562 return pFound; 563 } 564 565 // ------------------------------------------------------------------------ 566 567 GalleryImportThemeEntry* Gallery::ImplGetImportThemeEntry( const String& rImportName ) 568 { 569 GalleryImportThemeEntry* pFound = NULL; 570 571 for( GalleryImportThemeEntry* pImportEntry = aImportList.First(); pImportEntry && !pFound; pImportEntry = aImportList.Next() ) 572 if ( rImportName == pImportEntry->aUIName ) 573 pFound = pImportEntry; 574 575 return pFound; 576 } 577 578 // ------------------------------------------------------------------------ 579 580 String Gallery::GetThemeName( sal_uIntPtr nThemeId ) const 581 { 582 GalleryThemeEntry* pFound = NULL; 583 584 for( sal_uIntPtr n = 0, nCount = aThemeList.Count(); n < nCount; n++ ) 585 { 586 GalleryThemeEntry* pEntry = aThemeList.GetObject( n ); 587 588 if( nThemeId == pEntry->GetId() ) 589 pFound = pEntry; 590 } 591 592 // try fallback, if no entry was found 593 if( !pFound ) 594 { 595 ByteString aFallback; 596 597 switch( nThemeId ) 598 { 599 case( GALLERY_THEME_3D ): aFallback = "3D"; break; 600 case( GALLERY_THEME_BULLETS ): aFallback = "Bullets"; break; 601 case( GALLERY_THEME_HOMEPAGE ): aFallback = "Homepage"; break; 602 case( GALLERY_THEME_POWERPOINT ): aFallback = "private://gallery/hidden/imgppt"; break; 603 case( GALLERY_THEME_FONTWORK ): aFallback = "private://gallery/hidden/fontwork"; break; 604 case( GALLERY_THEME_FONTWORK_VERTICAL ): aFallback = "private://gallery/hidden/fontworkvertical"; break; 605 case( GALLERY_THEME_RULERS ): aFallback = "Rulers"; break; 606 case( GALLERY_THEME_SOUNDS ): aFallback = "Sounds"; break; 607 608 default: 609 break; 610 } 611 612 pFound = ( (Gallery*) this )->ImplGetThemeEntry( String::CreateFromAscii( aFallback.GetBuffer() ) ); 613 } 614 615 return( pFound ? pFound->GetThemeName() : String() ); 616 } 617 618 // ------------------------------------------------------------------------ 619 620 sal_Bool Gallery::HasTheme( const String& rThemeName ) 621 { 622 return( ImplGetThemeEntry( rThemeName ) != NULL ); 623 } 624 625 // ------------------------------------------------------------------------ 626 627 sal_Bool Gallery::CreateTheme( const String& rThemeName, sal_uInt32 nNumFrom ) 628 { 629 sal_Bool bRet = sal_False; 630 631 if( !HasTheme( rThemeName ) && ( GetUserURL().GetProtocol() != INET_PROT_NOT_VALID ) ) 632 { 633 nLastFileNumber = nNumFrom > nLastFileNumber ? nNumFrom : nLastFileNumber + 1; 634 GalleryThemeEntry* pNewEntry = new GalleryThemeEntry( GetUserURL(), rThemeName, 635 nLastFileNumber, 636 sal_False, sal_False, sal_True, 0, sal_False ); 637 638 aThemeList.Insert( pNewEntry, LIST_APPEND ); 639 delete( new GalleryTheme( this, pNewEntry ) ); 640 Broadcast( GalleryHint( GALLERY_HINT_THEME_CREATED, rThemeName ) ); 641 bRet = sal_True; 642 } 643 644 return bRet; 645 } 646 647 // ------------------------------------------------------------------------ 648 649 sal_Bool Gallery::CreateImportTheme( const INetURLObject& rURL, const String& rImportName ) 650 { 651 INetURLObject aURL( rURL ); 652 sal_Bool bRet = sal_False; 653 654 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); 655 656 if( FileExists( aURL ) ) 657 { 658 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ); 659 660 if( pIStm ) 661 { 662 sal_uIntPtr nStmErr; 663 sal_uInt16 nId; 664 665 *pIStm >> nId; 666 667 if( nId > 0x0004 ) 668 ErrorHandler::HandleError( ERRCODE_IO_GENERAL ); 669 else 670 { 671 ByteString aTmpStr; 672 String aThemeName; *pIStm >> aTmpStr; aThemeName = String( aTmpStr, RTL_TEXTENCODING_UTF8 ); 673 GalleryThemeEntry* pThemeEntry = new GalleryThemeEntry( aURL, rImportName, 674 String(aURL.GetBase()).Erase( 0, 2 ).Erase( 6 ).ToInt32(), 675 sal_True, sal_True, sal_True, 0, sal_False ); 676 GalleryTheme* pImportTheme = new GalleryTheme( this, pThemeEntry ); 677 678 pIStm->Seek( STREAM_SEEK_TO_BEGIN ); 679 *pIStm >> *pImportTheme; 680 nStmErr = pIStm->GetError(); 681 682 if( nStmErr ) 683 { 684 delete pThemeEntry; 685 ErrorHandler::HandleError( ERRCODE_IO_GENERAL ); 686 } 687 else 688 { 689 String aName( rImportName ); 690 String aNewName( aName ); 691 sal_uIntPtr nCount = 0; 692 693 aName += ' '; 694 695 while ( HasTheme( aNewName ) && ( nCount++ < 16000 ) ) 696 { 697 aNewName = aName; 698 aNewName += String::CreateFromInt32( nCount ); 699 } 700 701 pImportTheme->SetImportName( aNewName ); 702 aThemeList.Insert( pThemeEntry, LIST_APPEND ); 703 704 // Thema in Import-Liste eintragen und Import-Liste speichern 705 GalleryImportThemeEntry* pImportEntry = new GalleryImportThemeEntry; 706 pImportEntry->aThemeName = pImportEntry->aUIName = aNewName; 707 pImportEntry->aURL = rURL; 708 pImportEntry->aImportName = rImportName; 709 aImportList.Insert( pImportEntry, LIST_APPEND ); 710 ImplWriteImportList(); 711 bRet = sal_True; 712 } 713 714 delete pImportTheme; 715 } 716 717 delete pIStm; 718 } 719 } 720 721 return bRet; 722 } 723 724 // ------------------------------------------------------------------------ 725 726 sal_Bool Gallery::RenameTheme( const String& rOldName, const String& rNewName ) 727 { 728 GalleryThemeEntry* pThemeEntry = ImplGetThemeEntry( rOldName ); 729 sal_Bool bRet = sal_False; 730 731 // Ueberpruefen, ob neuer Themenname schon vorhanden ist 732 if( pThemeEntry && !HasTheme( rNewName ) && ( !pThemeEntry->IsReadOnly() || pThemeEntry->IsImported() ) ) 733 { 734 SfxListener aListener; 735 GalleryTheme* pThm = AcquireTheme( rOldName, aListener ); 736 737 if( pThm ) 738 { 739 const String aOldName( rOldName ); 740 741 pThemeEntry->SetName( rNewName ); 742 pThm->ImplWrite(); 743 744 if( pThemeEntry->IsImported() ) 745 { 746 pThm->SetImportName( rNewName ); 747 748 GalleryImportThemeEntry* pImportEntry = ImplGetImportThemeEntry( rOldName ); 749 750 if( pImportEntry ) 751 { 752 pImportEntry->aUIName = rNewName; 753 ImplWriteImportList(); 754 } 755 } 756 757 Broadcast( GalleryHint( GALLERY_HINT_THEME_RENAMED, aOldName, pThm->GetName() ) ); 758 ReleaseTheme( pThm, aListener ); 759 bRet = sal_True; 760 } 761 } 762 763 return bRet; 764 } 765 766 // ------------------------------------------------------------------------ 767 768 sal_Bool Gallery::RemoveTheme( const String& rThemeName ) 769 { 770 GalleryThemeEntry* pThemeEntry = ImplGetThemeEntry( rThemeName ); 771 sal_Bool bRet = sal_False; 772 773 if( pThemeEntry && ( !pThemeEntry->IsReadOnly() || pThemeEntry->IsImported() ) ) 774 { 775 Broadcast( GalleryHint( GALLERY_HINT_CLOSE_THEME, rThemeName ) ); 776 777 if( pThemeEntry->IsImported() ) 778 { 779 GalleryImportThemeEntry* pImportEntry = ImplGetImportThemeEntry( rThemeName ); 780 781 if( pImportEntry ) 782 { 783 delete aImportList.Remove( pImportEntry ); 784 ImplWriteImportList(); 785 } 786 } 787 else 788 { 789 SfxListener aListener; 790 GalleryTheme* pThm = AcquireTheme( rThemeName, aListener ); 791 792 if( pThm ) 793 { 794 INetURLObject aThmURL( pThm->GetThmURL() ); 795 INetURLObject aSdgURL( pThm->GetSdgURL() ); 796 INetURLObject aSdvURL( pThm->GetSdvURL() ); 797 798 ReleaseTheme( pThm, aListener ); 799 800 KillFile( aThmURL ); 801 KillFile( aSdgURL ); 802 KillFile( aSdvURL ); 803 } 804 } 805 806 delete aThemeList.Remove( pThemeEntry ); 807 Broadcast( GalleryHint( GALLERY_HINT_THEME_REMOVED, rThemeName ) ); 808 809 bRet = sal_True; 810 } 811 812 return bRet; 813 } 814 815 // ------------------------------------------------------------------------ 816 817 INetURLObject Gallery::GetImportURL( const String& rThemeName ) 818 { 819 INetURLObject aURL; 820 GalleryImportThemeEntry* pImportEntry = ImplGetImportThemeEntry( rThemeName ); 821 822 if( pImportEntry ) 823 { 824 aURL = pImportEntry->aURL; 825 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); 826 } 827 828 return aURL; 829 } 830 831 // ------------------------------------------------------------------------ 832 833 GalleryTheme* Gallery::ImplGetCachedTheme( const GalleryThemeEntry* pThemeEntry ) 834 { 835 GalleryTheme* pTheme = NULL; 836 837 if( pThemeEntry ) 838 { 839 GalleryThemeCacheEntry* pEntry; 840 841 for( pEntry = (GalleryThemeCacheEntry*) aThemeCache.First(); pEntry && !pTheme; pEntry = (GalleryThemeCacheEntry*) aThemeCache.Next() ) 842 if( pThemeEntry == pEntry->GetThemeEntry() ) 843 pTheme = pEntry->GetTheme(); 844 845 if( !pTheme ) 846 { 847 INetURLObject aURL; 848 849 if( !pThemeEntry->IsImported() ) 850 aURL = pThemeEntry->GetThmURL(); 851 else 852 aURL = GetImportURL( pThemeEntry->GetThemeName() ); 853 854 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); 855 856 if( FileExists( aURL ) ) 857 { 858 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ); 859 860 if( pIStm ) 861 { 862 pTheme = new GalleryTheme( this, (GalleryThemeEntry*) pThemeEntry ); 863 *pIStm >> *pTheme; 864 865 if( pIStm->GetError() ) 866 delete pTheme, pTheme = NULL; 867 else if( pThemeEntry->IsImported() ) 868 pTheme->SetImportName( pThemeEntry->GetThemeName() ); 869 870 delete pIStm; 871 } 872 } 873 874 if( pTheme ) 875 aThemeCache.Insert( new GalleryThemeCacheEntry( pThemeEntry, pTheme ), LIST_APPEND ); 876 } 877 } 878 879 return pTheme; 880 } 881 882 // ------------------------------------------------------------------------ 883 884 void Gallery::ImplDeleteCachedTheme( GalleryTheme* pTheme ) 885 { 886 GalleryThemeCacheEntry* pEntry; 887 sal_Bool bDone = sal_False; 888 889 for( pEntry = (GalleryThemeCacheEntry*) aThemeCache.First(); pEntry && !bDone; pEntry = (GalleryThemeCacheEntry*) aThemeCache.Next() ) 890 { 891 if( pTheme == pEntry->GetTheme() ) 892 { 893 delete (GalleryThemeCacheEntry*) aThemeCache.Remove( pEntry ); 894 bDone = sal_True; 895 } 896 } 897 } 898 899 // ------------------------------------------------------------------------ 900 901 GalleryTheme* Gallery::AcquireTheme( const String& rThemeName, SfxListener& rListener ) 902 { 903 GalleryTheme* pTheme = NULL; 904 GalleryThemeEntry* pThemeEntry = ImplGetThemeEntry( rThemeName ); 905 906 if( pThemeEntry && ( ( pTheme = ImplGetCachedTheme( pThemeEntry ) ) != NULL ) ) 907 rListener.StartListening( *pTheme ); 908 909 return pTheme; 910 } 911 912 // ------------------------------------------------------------------------ 913 914 void Gallery::ReleaseTheme( GalleryTheme* pTheme, SfxListener& rListener ) 915 { 916 if( pTheme ) 917 { 918 rListener.EndListening( *pTheme ); 919 920 if( !pTheme->HasListeners() ) 921 ImplDeleteCachedTheme( pTheme ); 922 } 923 } 924 925 sal_Bool GalleryThemeEntry::IsDefault() const 926 { return( ( nId > 0 ) && ( nId != ( RID_GALLERYSTR_THEME_MYTHEME - RID_GALLERYSTR_THEME_START ) ) ); } 927 928