1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #if defined(MACOSX) && HAVE_FEATURE_READONLY_INSTALLSET
23 #define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
25 #include <Foundation/Foundation.h>
29 #include <sal/config.h>
31 #include <comphelper/processfactory.hxx>
32 #include <osl/thread.h>
33 #include <tools/vcompat.hxx>
34 #include <ucbhelper/content.hxx>
35 #include <com/sun/star/ucb/ContentCreationException.hpp>
36 #include <unotools/configmgr.hxx>
37 #include <unotools/ucbstreamhelper.hxx>
38 #include <unotools/pathoptions.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <svx/dialmgr.hxx>
41 #include <svx/gallery.hxx>
42 #include <svx/strings.hrc>
43 #include <strings.hxx>
44 #include <svx/galmisc.hxx>
45 #include <svx/galtheme.hxx>
46 #include <svx/gallery1.hxx>
47 #include <vcl/weld.hxx>
48 #include <com/sun/star/sdbc/XResultSet.hpp>
49 #include <com/sun/star/ucb/XContentAccess.hpp>
53 using namespace ::com::sun::star
;
56 static bool FileExists( const INetURLObject
&rURL
, const OUString
&rExt
)
58 INetURLObject
aURL( rURL
);
59 aURL
.setExtension( rExt
);
60 return FileExists( aURL
);
63 const std::pair
<sal_uInt16
, const char*> aUnlocalized
[] =
65 { GALLERY_THEME_HOMEPAGE
, RID_GALLERYSTR_THEME_HTMLBUTTONS
},
66 { GALLERY_THEME_POWERPOINT
, RID_GALLERYSTR_THEME_POWERPOINT
},
67 { GALLERY_THEME_USERSOUNDS
, RID_GALLERYSTR_THEME_USERSOUNDS
},
68 { GALLERY_THEME_DUMMY5
, RID_GALLERYSTR_THEME_DUMMY5
},
69 { GALLERY_THEME_RULERS
, RID_GALLERYSTR_THEME_RULERS
},
70 { GALLERY_THEME_FONTWORK
, RID_GALLERYSTR_THEME_FONTWORK
},
71 { GALLERY_THEME_FONTWORK_VERTICAL
, RID_GALLERYSTR_THEME_FONTWORK_VERTICAL
}
74 const std::pair
<sal_uInt16
, const char*> aLocalized
[] =
76 { RID_GALLERY_THEME_3D
, RID_GALLERYSTR_THEME_3D
},
77 { RID_GALLERY_THEME_ANIMATIONS
, RID_GALLERYSTR_THEME_ANIMATIONS
},
78 { RID_GALLERY_THEME_BULLETS
, RID_GALLERYSTR_THEME_BULLETS
},
79 { RID_GALLERY_THEME_OFFICE
, RID_GALLERYSTR_THEME_OFFICE
},
80 { RID_GALLERY_THEME_FLAGS
, RID_GALLERYSTR_THEME_FLAGS
},
81 { RID_GALLERY_THEME_FLOWCHARTS
, RID_GALLERYSTR_THEME_FLOWCHARTS
},
82 { RID_GALLERY_THEME_EMOTICONS
, RID_GALLERYSTR_THEME_EMOTICONS
},
83 { RID_GALLERY_THEME_PHOTOS
, RID_GALLERYSTR_THEME_PHOTOS
},
84 { RID_GALLERY_THEME_BACKGROUNDS
, RID_GALLERYSTR_THEME_BACKGROUNDS
},
85 { RID_GALLERY_THEME_HOMEPAGE
, RID_GALLERYSTR_THEME_HOMEPAGE
},
86 { RID_GALLERY_THEME_INTERACTION
, RID_GALLERYSTR_THEME_INTERACTION
},
87 { RID_GALLERY_THEME_MAPS
, RID_GALLERYSTR_THEME_MAPS
},
88 { RID_GALLERY_THEME_PEOPLE
, RID_GALLERYSTR_THEME_PEOPLE
},
89 { RID_GALLERY_THEME_SURFACES
, RID_GALLERYSTR_THEME_SURFACES
},
90 { RID_GALLERY_THEME_SOUNDS
, RID_GALLERYSTR_THEME_SOUNDS
},
91 { RID_GALLERY_THEME_SYMBOLS
, RID_GALLERYSTR_THEME_SYMBOLS
},
92 { RID_GALLERY_THEME_MYTHEME
, RID_GALLERYSTR_THEME_MYTHEME
},
94 { RID_GALLERY_THEME_ARROWS
, RID_GALLERYSTR_THEME_ARROWS
},
95 { RID_GALLERY_THEME_BALLOONS
, RID_GALLERYSTR_THEME_BALLOONS
},
96 { RID_GALLERY_THEME_KEYBOARD
, RID_GALLERYSTR_THEME_KEYBOARD
},
97 { RID_GALLERY_THEME_TIME
, RID_GALLERYSTR_THEME_TIME
},
98 { RID_GALLERY_THEME_PRESENTATION
, RID_GALLERYSTR_THEME_PRESENTATION
},
99 { RID_GALLERY_THEME_CALENDAR
, RID_GALLERYSTR_THEME_CALENDAR
},
100 { RID_GALLERY_THEME_NAVIGATION
, RID_GALLERYSTR_THEME_NAVIGATION
},
101 { RID_GALLERY_THEME_COMMUNICATION
, RID_GALLERYSTR_THEME_COMMUNICATION
},
102 { RID_GALLERY_THEME_FINANCES
, RID_GALLERYSTR_THEME_FINANCES
},
103 { RID_GALLERY_THEME_COMPUTER
, RID_GALLERYSTR_THEME_COMPUTER
},
105 { RID_GALLERY_THEME_CLIMA
, RID_GALLERYSTR_THEME_CLIMA
},
106 { RID_GALLERY_THEME_EDUCATION
, RID_GALLERYSTR_THEME_EDUCATION
},
107 { RID_GALLERY_THEME_TROUBLE
, RID_GALLERYSTR_THEME_TROUBLE
},
108 { RID_GALLERY_THEME_SCREENBEANS
, RID_GALLERYSTR_THEME_SCREENBEANS
},
110 { RID_GALLERY_THEME_COMPUTERS
, RID_GALLERYSTR_THEME_COMPUTERS
},
111 { RID_GALLERY_THEME_DIAGRAMS
, RID_GALLERYSTR_THEME_DIAGRAMS
},
112 { RID_GALLERY_THEME_ENVIRONMENT
, RID_GALLERYSTR_THEME_ENVIRONMENT
},
113 { RID_GALLERY_THEME_FINANCE
, RID_GALLERYSTR_THEME_FINANCE
},
114 { RID_GALLERY_THEME_TRANSPORT
, RID_GALLERYSTR_THEME_TRANSPORT
},
115 { RID_GALLERY_THEME_TXTSHAPES
, RID_GALLERYSTR_THEME_TXTSHAPES
}
118 GalleryThemeEntry::GalleryThemeEntry( bool bCreateUniqueURL
,
119 const INetURLObject
& rBaseURL
, const OUString
& rName
,
120 bool _bReadOnly
, bool _bNewFile
,
121 sal_uInt32 _nId
, bool _bThemeNameFromResource
) :
123 bReadOnly ( _bReadOnly
),
124 bThemeNameFromResource ( _bThemeNameFromResource
)
126 INetURLObject
aURL( rBaseURL
);
127 DBG_ASSERT( aURL
.GetProtocol() != INetProtocol::NotValid
, "invalid URL" );
129 if (bCreateUniqueURL
)
131 INetURLObject
aBaseNoCase( ImplGetURLIgnoreCase( rBaseURL
) );
133 static sal_Int32 nIdx
= 0;
134 while( FileExists( aURL
, "thm" ) )
138 aURL
.setName( aURL
.getName() + OUString::number(nIdx
));
142 aURL
.setExtension( "thm" );
143 aThmURL
= ImplGetURLIgnoreCase( aURL
);
145 aURL
.setExtension( "sdg" );
146 aSdgURL
= ImplGetURLIgnoreCase( aURL
);
148 aURL
.setExtension( "sdv" );
149 aSdvURL
= ImplGetURLIgnoreCase( aURL
);
151 aURL
.setExtension( "str" );
152 aStrURL
= ImplGetURLIgnoreCase( aURL
);
154 SetModified( _bNewFile
);
156 aName
= ReadStrFromIni( "name" );
158 // This is awful - we shouldn't use these resources if we
159 // possibly can avoid them
160 if( aName
.isEmpty() && nId
&& bThemeNameFromResource
)
162 //some of these are supposed to *not* be localized
163 //so catch them before looking up the resource
164 for (size_t i
= 0; i
< SAL_N_ELEMENTS(aUnlocalized
); ++i
)
166 if (aUnlocalized
[i
].first
== nId
)
168 aName
= OUString::createFromAscii(aUnlocalized
[i
].second
);
172 //look up the rest of the ids in string resources
175 for (size_t i
= 0; i
< SAL_N_ELEMENTS(aLocalized
); ++i
)
177 if (aLocalized
[i
].first
== nId
)
179 aName
= SvxResId(aLocalized
[i
].second
);
186 if( aName
.isEmpty() )
190 void GalleryTheme::InsertAllThemes(weld::ComboBox
& rListBox
)
192 for (size_t i
= 0; i
< SAL_N_ELEMENTS(aUnlocalized
); ++i
)
193 rListBox
.append_text(OUString::createFromAscii(aUnlocalized
[i
].second
));
195 for (size_t i
= 0; i
< SAL_N_ELEMENTS(aLocalized
); ++i
)
196 rListBox
.append_text(SvxResId(aLocalized
[i
].second
));
199 INetURLObject
GalleryThemeEntry::ImplGetURLIgnoreCase( const INetURLObject
& rURL
)
201 INetURLObject
aURL( rURL
);
203 // check original file name
204 if( !FileExists( aURL
) )
206 // check upper case file name
207 aURL
.setName( aURL
.getName().toAsciiUpperCase() );
209 if(!FileExists( aURL
) )
211 // check lower case file name
212 aURL
.setName( aURL
.getName().toAsciiLowerCase() );
219 void GalleryThemeEntry::SetName( const OUString
& rNewName
)
221 if( aName
!= rNewName
)
225 bThemeNameFromResource
= false;
229 void GalleryThemeEntry::SetId( sal_uInt32 nNewId
, bool bResetThemeName
)
233 bThemeNameFromResource
= ( nId
&& bResetThemeName
);
237 class GalleryThemeCacheEntry
241 const GalleryThemeEntry
* mpThemeEntry
;
242 std::unique_ptr
<GalleryTheme
> mpTheme
;
246 GalleryThemeCacheEntry( const GalleryThemeEntry
* pThemeEntry
, std::unique_ptr
<GalleryTheme
> pTheme
) :
247 mpThemeEntry( pThemeEntry
), mpTheme( std::move(pTheme
) ) {}
249 const GalleryThemeEntry
* GetThemeEntry() const { return mpThemeEntry
; }
250 GalleryTheme
* GetTheme() const { return mpTheme
.get(); }
254 Gallery::Gallery( const OUString
& rMultiPath
)
255 : bMultiPath ( false )
257 ImplLoad( rMultiPath
);
264 Gallery
* Gallery::GetGalleryInstance()
266 // note: this would deadlock if it used osl::Mutex::getGlobalMutex()
267 static Gallery
*const s_pGallery(
268 utl::ConfigManager::IsFuzzing() ? nullptr :
269 new Gallery(SvtPathOptions().GetGalleryPath()));
274 void Gallery::ImplLoad( const OUString
& rMultiPath
)
276 bool bIsReadOnlyDir
{false};
278 bMultiPath
= !rMultiPath
.isEmpty();
280 INetURLObject
aCurURL(SvtPathOptions().GetConfigPath());
281 ImplLoadSubDirs( aCurURL
, bIsReadOnlyDir
);
283 if( !bIsReadOnlyDir
)
288 bool bIsRelURL
{true};
292 aCurURL
= INetURLObject(rMultiPath
.getToken(0, ';', nIdx
));
299 ImplLoadSubDirs( aCurURL
, bIsReadOnlyDir
);
301 if( !bIsReadOnlyDir
)
307 aRelURL
= INetURLObject( rMultiPath
);
309 DBG_ASSERT( aUserURL
.GetProtocol() != INetProtocol::NotValid
, "no writable Gallery user directory available" );
310 DBG_ASSERT( aRelURL
.GetProtocol() != INetProtocol::NotValid
, "invalid URL" );
313 void Gallery::ImplLoadSubDirs( const INetURLObject
& rBaseURL
, bool& rbDirIsReadOnly
)
315 rbDirIsReadOnly
= false;
319 uno::Reference
< ucb::XCommandEnvironment
> xEnv
;
320 ::ucbhelper::Content
aCnt( rBaseURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xEnv
, comphelper::getProcessComponentContext() );
322 uno::Sequence
<OUString
> aProps
{ "Url" };
324 uno::Reference
< sdbc::XResultSet
> xResultSet( aCnt
.createCursor( aProps
, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY
) );
326 #if defined(MACOSX) && HAVE_FEATURE_READONLY_INSTALLSET
327 if( rBaseURL
.GetProtocol() == INetProtocol::File
)
329 const char *appBundle
= [[[NSBundle mainBundle
] bundlePath
] UTF8String
];
330 OUString path
= rBaseURL
.GetURLPath();
331 if( path
.startsWith( OUString( appBundle
, strlen( appBundle
), RTL_TEXTENCODING_UTF8
) + "/" ) )
332 rbDirIsReadOnly
= true;
337 // check readonlyness the very hard way
338 INetURLObject
aTestURL( rBaseURL
);
340 aTestURL
.Append( "cdefghij.klm" );
341 std::unique_ptr
<SvStream
> pTestStm(::utl::UcbStreamHelper::CreateStream( aTestURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), StreamMode::WRITE
));
345 pTestStm
->WriteInt32( sal_Int32(1) );
347 if( pTestStm
->GetError() )
348 rbDirIsReadOnly
= true;
351 KillFile( aTestURL
);
354 rbDirIsReadOnly
= true;
356 catch( const ucb::ContentCreationException
& )
359 catch( const uno::RuntimeException
& )
362 catch( const uno::Exception
& )
366 if( xResultSet
.is() )
368 uno::Reference
< ucb::XContentAccess
> xContentAccess( xResultSet
, uno::UNO_QUERY
);
370 if( xContentAccess
.is() )
372 static const char s_sTitle
[] = "Title";
373 static const char s_sIsReadOnly
[] = "IsReadOnly";
375 while( xResultSet
->next() )
377 INetURLObject
aThmURL( xContentAccess
->queryContentIdentifierString() );
379 if (aThmURL
.GetFileExtension().equalsIgnoreAsciiCase("thm"))
381 INetURLObject
aSdgURL( aThmURL
); aSdgURL
.SetExtension( "sdg" );
382 INetURLObject
aSdvURL( aThmURL
); aSdvURL
.SetExtension( "sdv" );
387 ::ucbhelper::Content
aThmCnt( aThmURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xEnv
, comphelper::getProcessComponentContext() );
388 ::ucbhelper::Content
aSdgCnt( aSdgURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xEnv
, comphelper::getProcessComponentContext() );
389 ::ucbhelper::Content
aSdvCnt( aSdvURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xEnv
, comphelper::getProcessComponentContext() );
393 aThmCnt
.getPropertyValue( s_sTitle
) >>= aTitle
;
395 catch( const uno::RuntimeException
& )
398 catch( const uno::Exception
& )
402 if( !aTitle
.isEmpty() )
404 bool bReadOnly
= false;
408 aThmCnt
.getPropertyValue( s_sIsReadOnly
) >>= bReadOnly
;
410 catch( const uno::RuntimeException
& )
413 catch( const uno::Exception
& )
421 aSdgCnt
.getPropertyValue( s_sTitle
) >>= aTitle
;
423 catch( const css::uno::RuntimeException
& )
426 catch( const css::uno::Exception
& )
430 if( !aTitle
.isEmpty() )
434 aSdgCnt
.getPropertyValue( s_sIsReadOnly
) >>= bReadOnly
;
436 catch( const uno::RuntimeException
& )
439 catch( const uno::Exception
& )
449 aSdvCnt
.getPropertyValue( s_sTitle
) >>= aTitle
;
451 catch( const css::uno::RuntimeException
& )
454 catch( const css::uno::Exception
& )
458 if( !aTitle
.isEmpty() )
462 aSdvCnt
.getPropertyValue( s_sIsReadOnly
) >>= bReadOnly
;
464 catch( const uno::RuntimeException
& )
467 catch( const uno::Exception
& )
473 GalleryThemeEntry
* pEntry
= GalleryTheme::CreateThemeEntry( aThmURL
, rbDirIsReadOnly
|| bReadOnly
);
476 aThemeList
.emplace_back( pEntry
);
479 catch( const ucb::ContentCreationException
& )
482 catch( const uno::RuntimeException
& )
485 catch( const uno::Exception
& )
493 catch( const ucb::ContentCreationException
& )
496 catch( const uno::RuntimeException
& )
499 catch( const uno::Exception
& )
504 GalleryThemeEntry
* Gallery::ImplGetThemeEntry( const OUString
& rThemeName
)
506 if( !rThemeName
.isEmpty() )
508 for ( size_t i
= 0, n
= aThemeList
.size(); i
< n
; ++i
)
509 if( rThemeName
== aThemeList
[ i
]->GetThemeName() )
510 return aThemeList
[ i
].get();
516 OUString
Gallery::GetThemeName( sal_uInt32 nThemeId
) const
518 GalleryThemeEntry
* pFound
= nullptr;
520 for ( size_t i
= 0, n
= aThemeList
.size(); i
< n
&& !pFound
; ++i
)
522 GalleryThemeEntry
* pEntry
= aThemeList
[ i
].get();
523 if( nThemeId
== pEntry
->GetId() )
527 // try fallback, if no entry was found
534 case GALLERY_THEME_3D
:
535 aFallback
= SvxResId(RID_GALLERYSTR_THEME_3D
);
537 case GALLERY_THEME_BULLETS
:
538 aFallback
= SvxResId(RID_GALLERYSTR_THEME_BULLETS
);
540 case GALLERY_THEME_HOMEPAGE
:
541 aFallback
= SvxResId(RID_GALLERYSTR_THEME_HOMEPAGE
);
543 case GALLERY_THEME_POWERPOINT
:
544 aFallback
= RID_GALLERYSTR_THEME_POWERPOINT
;
546 case GALLERY_THEME_FONTWORK
:
547 aFallback
= RID_GALLERYSTR_THEME_FONTWORK
;
549 case GALLERY_THEME_FONTWORK_VERTICAL
:
550 aFallback
= RID_GALLERYSTR_THEME_FONTWORK_VERTICAL
;
552 case GALLERY_THEME_SOUNDS
:
553 aFallback
= SvxResId(RID_GALLERYSTR_THEME_SOUNDS
);
555 case RID_GALLERY_THEME_ARROWS
:
556 aFallback
= SvxResId(RID_GALLERYSTR_THEME_ARROWS
);
558 case RID_GALLERY_THEME_COMPUTERS
:
559 aFallback
= SvxResId(RID_GALLERYSTR_THEME_COMPUTERS
);
561 case RID_GALLERY_THEME_DIAGRAMS
:
562 aFallback
= SvxResId(RID_GALLERYSTR_THEME_DIAGRAMS
);
564 case RID_GALLERY_THEME_EDUCATION
:
565 aFallback
= SvxResId(RID_GALLERYSTR_THEME_EDUCATION
);
567 case RID_GALLERY_THEME_ENVIRONMENT
:
568 aFallback
= SvxResId(RID_GALLERYSTR_THEME_ENVIRONMENT
);
570 case RID_GALLERY_THEME_FINANCE
:
571 aFallback
= SvxResId(RID_GALLERYSTR_THEME_FINANCE
);
573 case RID_GALLERY_THEME_PEOPLE
:
574 aFallback
= SvxResId(RID_GALLERYSTR_THEME_PEOPLE
);
576 case RID_GALLERY_THEME_SYMBOLS
:
577 aFallback
= SvxResId(RID_GALLERYSTR_THEME_SYMBOLS
);
579 case RID_GALLERY_THEME_TRANSPORT
:
580 aFallback
= SvxResId(RID_GALLERYSTR_THEME_TRANSPORT
);
582 case RID_GALLERY_THEME_TXTSHAPES
:
583 aFallback
= SvxResId(RID_GALLERYSTR_THEME_TXTSHAPES
);
589 pFound
= const_cast<Gallery
*>(this)->ImplGetThemeEntry(aFallback
);
592 return( pFound
? pFound
->GetThemeName() : OUString() );
595 bool Gallery::HasTheme( const OUString
& rThemeName
)
597 return( ImplGetThemeEntry( rThemeName
) != nullptr );
600 bool Gallery::CreateTheme( const OUString
& rThemeName
)
604 if( !HasTheme( rThemeName
) && ( GetUserURL().GetProtocol() != INetProtocol::NotValid
) )
606 INetURLObject
aURL( GetUserURL() );
607 aURL
.Append( rThemeName
);
608 GalleryThemeEntry
* pNewEntry
= new GalleryThemeEntry(
609 true, aURL
, rThemeName
,
610 false, true, 0, false );
612 aThemeList
.emplace_back( pNewEntry
);
613 delete new GalleryTheme( this, pNewEntry
);
614 Broadcast( GalleryHint( GalleryHintType::THEME_CREATED
, rThemeName
) );
621 void Gallery::RenameTheme( const OUString
& rOldName
, const OUString
& rNewName
)
623 GalleryThemeEntry
* pThemeEntry
= ImplGetThemeEntry( rOldName
);
625 // check if the new theme name is already present
626 if( pThemeEntry
&& !HasTheme( rNewName
) && !pThemeEntry
->IsReadOnly() )
628 SfxListener aListener
;
629 GalleryTheme
* pThm
= AcquireTheme( rOldName
, aListener
);
633 pThemeEntry
->SetName( rNewName
);
636 Broadcast( GalleryHint( GalleryHintType::THEME_RENAMED
, rOldName
, pThm
->GetName() ) );
637 ReleaseTheme( pThm
, aListener
);
642 bool Gallery::RemoveTheme( const OUString
& rThemeName
)
644 GalleryThemeEntry
* pThemeEntry
= ImplGetThemeEntry( rThemeName
);
647 if( pThemeEntry
&& !pThemeEntry
->IsReadOnly() )
649 Broadcast( GalleryHint( GalleryHintType::CLOSE_THEME
, rThemeName
) );
651 SfxListener aListener
;
652 GalleryTheme
* pThm
= AcquireTheme( rThemeName
, aListener
);
656 INetURLObject
aThmURL( pThm
->GetThmURL() );
657 INetURLObject
aSdgURL( pThm
->GetSdgURL() );
658 INetURLObject
aSdvURL( pThm
->GetSdvURL() );
659 INetURLObject
aStrURL( pThm
->GetStrURL() );
661 ReleaseTheme( pThm
, aListener
);
669 auto it
= std::find_if(aThemeList
.begin(), aThemeList
.end(),
670 [&pThemeEntry
](const std::unique_ptr
<GalleryThemeEntry
>& rpEntry
) { return pThemeEntry
== rpEntry
.get(); });
671 if (it
!= aThemeList
.end())
672 aThemeList
.erase( it
);
674 Broadcast( GalleryHint( GalleryHintType::THEME_REMOVED
, rThemeName
) );
682 GalleryTheme
* Gallery::ImplGetCachedTheme(const GalleryThemeEntry
* pThemeEntry
)
684 GalleryTheme
* pTheme
= nullptr;
688 auto it
= std::find_if(aThemeCache
.begin(), aThemeCache
.end(),
689 [&pThemeEntry
](const GalleryThemeCacheEntry
* pEntry
) { return pThemeEntry
== pEntry
->GetThemeEntry(); });
690 if (it
!= aThemeCache
.end())
691 pTheme
= (*it
)->GetTheme();
695 INetURLObject aURL
= pThemeEntry
->GetThmURL();
697 DBG_ASSERT( aURL
.GetProtocol() != INetProtocol::NotValid
, "invalid URL" );
699 std::unique_ptr
<GalleryTheme
> pNewTheme
;
700 if( FileExists( aURL
) )
702 std::unique_ptr
<SvStream
> pIStm(::utl::UcbStreamHelper::CreateStream( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), StreamMode::READ
));
708 pNewTheme
.reset( new GalleryTheme( this, const_cast<GalleryThemeEntry
*>(pThemeEntry
) ) );
709 ReadGalleryTheme( *pIStm
, *pNewTheme
);
711 if( pIStm
->GetError() )
714 catch (const css::ucb::ContentCreationException
&)
722 aThemeCache
.push_back( new GalleryThemeCacheEntry( pThemeEntry
, std::move(pNewTheme
) ));
723 pTheme
= aThemeCache
.back()->GetTheme();
731 void Gallery::ImplDeleteCachedTheme( GalleryTheme
const * pTheme
)
733 auto it
= std::find_if(aThemeCache
.begin(), aThemeCache
.end(),
734 [&pTheme
](const GalleryThemeCacheEntry
* pEntry
) { return pTheme
== pEntry
->GetTheme(); });
735 if (it
!= aThemeCache
.end())
738 aThemeCache
.erase(it
);
742 GalleryTheme
* Gallery::AcquireTheme( const OUString
& rThemeName
, SfxListener
& rListener
)
744 GalleryTheme
* pTheme
= nullptr;
745 GalleryThemeEntry
* pThemeEntry
= ImplGetThemeEntry( rThemeName
);
747 if( pThemeEntry
&& ( ( pTheme
= ImplGetCachedTheme( pThemeEntry
) ) != nullptr ) )
748 rListener
.StartListening(*pTheme
, DuplicateHandling::Prevent
);
753 void Gallery::ReleaseTheme( GalleryTheme
* pTheme
, SfxListener
& rListener
)
757 rListener
.EndListening( *pTheme
);
759 if( !pTheme
->HasListeners() )
760 ImplDeleteCachedTheme( pTheme
);
764 bool GalleryThemeEntry::IsDefault() const
766 return nId
> 0 && nId
!= GALLERY_THEME_MYTHEME
;
769 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */