xref: /trunk/main/svx/source/gallery2/gallery1.cxx (revision 02c50d82)
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