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