LibreOffice Module svx (master)  1
gallery1.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <config_features.h>
21 
22 #if defined(MACOSX) && HAVE_FEATURE_READONLY_INSTALLSET
23 #define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
24 #include <premac.h>
25 #include <Foundation/Foundation.h>
26 #include <postmac.h>
27 #endif
28 
29 #include <sal/config.h>
30 
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>
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>
50 #include <memory>
51 
52 
53 using namespace ::com::sun::star;
54 
55 
56 static bool FileExists( const INetURLObject &rURL, const OUString &rExt )
57 {
58  INetURLObject aURL( rURL );
59  aURL.setExtension( rExt );
60  return FileExists( aURL );
61 }
62 
63 const std::pair<sal_uInt16, const char*> aUnlocalized[] =
64 {
72 };
73 
74 const std::pair<sal_uInt16, const char*> aLocalized[] =
75 {
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 },
93 
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 },
104 
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 },
109 
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 }
116 };
117 
119  const INetURLObject& rBaseURL, const OUString& rName,
120  bool _bReadOnly, bool _bNewFile,
121  sal_uInt32 _nId, bool _bThemeNameFromResource ) :
122  nId ( _nId ),
123  bReadOnly ( _bReadOnly ),
124  bThemeNameFromResource ( _bThemeNameFromResource )
125 {
126  INetURLObject aURL( rBaseURL );
127  DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
128 
129  if (bCreateUniqueURL)
130  {
131  INetURLObject aBaseNoCase( ImplGetURLIgnoreCase( rBaseURL ) );
132  aURL = aBaseNoCase;
133  static sal_Int32 nIdx = 0;
134  while( FileExists( aURL, "thm" ) )
135  { // create new URLs
136  nIdx++;
137  aURL = aBaseNoCase;
138  aURL.setName( aURL.getName() + OUString::number(nIdx));
139  }
140  }
141 
142  aURL.setExtension( "thm" );
143  aThmURL = ImplGetURLIgnoreCase( aURL );
144 
145  aURL.setExtension( "sdg" );
146  aSdgURL = ImplGetURLIgnoreCase( aURL );
147 
148  aURL.setExtension( "sdv" );
149  aSdvURL = ImplGetURLIgnoreCase( aURL );
150 
151  aURL.setExtension( "str" );
152  aStrURL = ImplGetURLIgnoreCase( aURL );
153 
154  SetModified( _bNewFile );
155 
156  aName = ReadStrFromIni( "name" );
157 
158  // This is awful - we shouldn't use these resources if we
159  // possibly can avoid them
160  if( aName.isEmpty() && nId && bThemeNameFromResource )
161  {
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)
165  {
166  if (aUnlocalized[i].first == nId)
167  {
168  aName = OUString::createFromAscii(aUnlocalized[i].second);
169  break;
170  }
171  }
172  //look up the rest of the ids in string resources
173  if (aName.isEmpty())
174  {
175  for (size_t i = 0; i < SAL_N_ELEMENTS(aLocalized); ++i)
176  {
177  if (aLocalized[i].first == nId)
178  {
179  aName = SvxResId(aLocalized[i].second);
180  break;
181  }
182  }
183  }
184  }
185 
186  if( aName.isEmpty() )
187  aName = rName;
188 }
189 
191 {
192  for (size_t i = 0; i < SAL_N_ELEMENTS(aUnlocalized); ++i)
193  rListBox.append_text(OUString::createFromAscii(aUnlocalized[i].second));
194 
195  for (size_t i = 0; i < SAL_N_ELEMENTS(aLocalized); ++i)
196  rListBox.append_text(SvxResId(aLocalized[i].second));
197 }
198 
200 {
201  INetURLObject aURL( rURL );
202 
203  // check original file name
204  if( !FileExists( aURL ) )
205  {
206  // check upper case file name
207  aURL.setName( aURL.getName().toAsciiUpperCase() );
208 
209  if(!FileExists( aURL ) )
210  {
211  // check lower case file name
212  aURL.setName( aURL.getName().toAsciiLowerCase() );
213  }
214  }
215 
216  return aURL;
217 }
218 
219 void GalleryThemeEntry::SetName( const OUString& rNewName )
220 {
221  if( aName != rNewName )
222  {
223  aName = rNewName;
224  SetModified( true );
225  bThemeNameFromResource = false;
226  }
227 }
228 
229 void GalleryThemeEntry::SetId( sal_uInt32 nNewId, bool bResetThemeName )
230 {
231  nId = nNewId;
232  SetModified( true );
233  bThemeNameFromResource = ( nId && bResetThemeName );
234 }
235 
236 
238 {
239 private:
240 
242  std::unique_ptr<GalleryTheme> mpTheme;
243 
244 public:
245 
246  GalleryThemeCacheEntry( const GalleryThemeEntry* pThemeEntry, std::unique_ptr<GalleryTheme> pTheme ) :
247  mpThemeEntry( pThemeEntry ), mpTheme( std::move(pTheme) ) {}
248 
249  const GalleryThemeEntry* GetThemeEntry() const { return mpThemeEntry; }
250  GalleryTheme* GetTheme() const { return mpTheme.get(); }
251 };
252 
253 
254 Gallery::Gallery( const OUString& rMultiPath )
255 : bMultiPath ( false )
256 {
257  ImplLoad( rMultiPath );
258 }
259 
261 {
262 }
263 
265 {
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()));
270 
271  return s_pGallery;
272 }
273 
274 void Gallery::ImplLoad( const OUString& rMultiPath )
275 {
276  bool bIsReadOnlyDir {false};
277 
278  bMultiPath = !rMultiPath.isEmpty();
279 
280  INetURLObject aCurURL(SvtPathOptions().GetConfigPath());
281  ImplLoadSubDirs( aCurURL, bIsReadOnlyDir );
282 
283  if( !bIsReadOnlyDir )
284  aUserURL = aCurURL;
285 
286  if( bMultiPath )
287  {
288  bool bIsRelURL {true};
289  sal_Int32 nIdx {0};
290  do
291  {
292  aCurURL = INetURLObject(rMultiPath.getToken(0, ';', nIdx));
293  if (bIsRelURL)
294  {
295  aRelURL = aCurURL;
296  bIsRelURL = false;
297  }
298 
299  ImplLoadSubDirs( aCurURL, bIsReadOnlyDir );
300 
301  if( !bIsReadOnlyDir )
302  aUserURL = aCurURL;
303  }
304  while (nIdx>0);
305  }
306  else
307  aRelURL = INetURLObject( rMultiPath );
308 
309  DBG_ASSERT( aUserURL.GetProtocol() != INetProtocol::NotValid, "no writable Gallery user directory available" );
310  DBG_ASSERT( aRelURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
311 }
312 
313 void Gallery::ImplLoadSubDirs( const INetURLObject& rBaseURL, bool& rbDirIsReadOnly )
314 {
315  rbDirIsReadOnly = false;
316 
317  try
318  {
319  uno::Reference< ucb::XCommandEnvironment > xEnv;
321 
322  uno::Sequence<OUString> aProps { "Url" };
323 
324  uno::Reference< sdbc::XResultSet > xResultSet( aCnt.createCursor( aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
325 
326 #if defined(MACOSX) && HAVE_FEATURE_READONLY_INSTALLSET
327  if( rBaseURL.GetProtocol() == INetProtocol::File )
328  {
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;
333  }
334 #else
335  try
336  {
337  // check readonlyness the very hard way
338  INetURLObject aTestURL( rBaseURL );
339 
340  aTestURL.Append( "cdefghij.klm" );
341  std::unique_ptr<SvStream> pTestStm(::utl::UcbStreamHelper::CreateStream( aTestURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE ));
342 
343  if( pTestStm )
344  {
345  pTestStm->WriteInt32( sal_Int32(1) );
346 
347  if( pTestStm->GetError() )
348  rbDirIsReadOnly = true;
349 
350  pTestStm.reset();
351  KillFile( aTestURL );
352  }
353  else
354  rbDirIsReadOnly = true;
355  }
356  catch( const ucb::ContentCreationException& )
357  {
358  }
359  catch( const uno::RuntimeException& )
360  {
361  }
362  catch( const uno::Exception& )
363  {
364  }
365 #endif
366  if( xResultSet.is() )
367  {
368  uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY );
369 
370  if( xContentAccess.is() )
371  {
372  static const char s_sTitle[] = "Title";
373  static const char s_sIsReadOnly[] = "IsReadOnly";
374 
375  while( xResultSet->next() )
376  {
377  INetURLObject aThmURL( xContentAccess->queryContentIdentifierString() );
378 
379  if (aThmURL.GetFileExtension().equalsIgnoreAsciiCase("thm"))
380  {
381  INetURLObject aSdgURL( aThmURL); aSdgURL.SetExtension( "sdg" );
382  INetURLObject aSdvURL( aThmURL ); aSdvURL.SetExtension( "sdv" );
383  OUString aTitle;
384 
385  try
386  {
390 
391  try
392  {
393  aThmCnt.getPropertyValue( s_sTitle ) >>= aTitle;
394  }
395  catch( const uno::RuntimeException& )
396  {
397  }
398  catch( const uno::Exception& )
399  {
400  }
401 
402  if( !aTitle.isEmpty() )
403  {
404  bool bReadOnly = false;
405 
406  try
407  {
408  aThmCnt.getPropertyValue( s_sIsReadOnly ) >>= bReadOnly;
409  }
410  catch( const uno::RuntimeException& )
411  {
412  }
413  catch( const uno::Exception& )
414  {
415  }
416 
417  if( !bReadOnly )
418  {
419  try
420  {
421  aSdgCnt.getPropertyValue( s_sTitle ) >>= aTitle;
422  }
423  catch( const css::uno::RuntimeException& )
424  {
425  }
426  catch( const css::uno::Exception& )
427  {
428  }
429 
430  if( !aTitle.isEmpty() )
431  {
432  try
433  {
434  aSdgCnt.getPropertyValue( s_sIsReadOnly ) >>= bReadOnly;
435  }
436  catch( const uno::RuntimeException& )
437  {
438  }
439  catch( const uno::Exception& )
440  {
441  }
442  }
443  }
444 
445  if( !bReadOnly )
446  {
447  try
448  {
449  aSdvCnt.getPropertyValue( s_sTitle ) >>= aTitle;
450  }
451  catch( const css::uno::RuntimeException& )
452  {
453  }
454  catch( const css::uno::Exception& )
455  {
456  }
457 
458  if( !aTitle.isEmpty() )
459  {
460  try
461  {
462  aSdvCnt.getPropertyValue( s_sIsReadOnly ) >>= bReadOnly;
463  }
464  catch( const uno::RuntimeException& )
465  {
466  }
467  catch( const uno::Exception& )
468  {
469  }
470  }
471  }
472 
473  GalleryThemeEntry* pEntry = GalleryTheme::CreateThemeEntry( aThmURL, rbDirIsReadOnly || bReadOnly );
474 
475  if( pEntry )
476  aThemeList.emplace_back( pEntry );
477  }
478  }
479  catch( const ucb::ContentCreationException& )
480  {
481  }
482  catch( const uno::RuntimeException& )
483  {
484  }
485  catch( const uno::Exception& )
486  {
487  }
488  }
489  }
490  }
491  }
492  }
493  catch( const ucb::ContentCreationException& )
494  {
495  }
496  catch( const uno::RuntimeException& )
497  {
498  }
499  catch( const uno::Exception& )
500  {
501  }
502 }
503 
504 GalleryThemeEntry* Gallery::ImplGetThemeEntry( const OUString& rThemeName )
505 {
506  if( !rThemeName.isEmpty() )
507  {
508  for ( size_t i = 0, n = aThemeList.size(); i < n; ++i )
509  if( rThemeName == aThemeList[ i ]->GetThemeName() )
510  return aThemeList[ i ].get();
511  }
512 
513  return nullptr;
514 }
515 
516 OUString Gallery::GetThemeName( sal_uInt32 nThemeId ) const
517 {
518  GalleryThemeEntry* pFound = nullptr;
519 
520  for ( size_t i = 0, n = aThemeList.size(); i < n && !pFound; ++i )
521  {
522  GalleryThemeEntry* pEntry = aThemeList[ i ].get();
523  if( nThemeId == pEntry->GetId() )
524  pFound = pEntry;
525  }
526 
527  // try fallback, if no entry was found
528  if( !pFound )
529  {
530  OUString aFallback;
531 
532  switch( nThemeId )
533  {
534  case GALLERY_THEME_3D:
535  aFallback = SvxResId(RID_GALLERYSTR_THEME_3D);
536  break;
538  aFallback = SvxResId(RID_GALLERYSTR_THEME_BULLETS);
539  break;
541  aFallback = SvxResId(RID_GALLERYSTR_THEME_HOMEPAGE);
542  break;
545  break;
547  aFallback = RID_GALLERYSTR_THEME_FONTWORK;
548  break;
551  break;
553  aFallback = SvxResId(RID_GALLERYSTR_THEME_SOUNDS);
554  break;
556  aFallback = SvxResId(RID_GALLERYSTR_THEME_ARROWS);
557  break;
559  aFallback = SvxResId(RID_GALLERYSTR_THEME_COMPUTERS);
560  break;
562  aFallback = SvxResId(RID_GALLERYSTR_THEME_DIAGRAMS);
563  break;
565  aFallback = SvxResId(RID_GALLERYSTR_THEME_EDUCATION);
566  break;
568  aFallback = SvxResId(RID_GALLERYSTR_THEME_ENVIRONMENT);
569  break;
571  aFallback = SvxResId(RID_GALLERYSTR_THEME_FINANCE);
572  break;
574  aFallback = SvxResId(RID_GALLERYSTR_THEME_PEOPLE);
575  break;
577  aFallback = SvxResId(RID_GALLERYSTR_THEME_SYMBOLS);
578  break;
580  aFallback = SvxResId(RID_GALLERYSTR_THEME_TRANSPORT);
581  break;
583  aFallback = SvxResId(RID_GALLERYSTR_THEME_TXTSHAPES);
584  break;
585  default:
586  break;
587  }
588 
589  pFound = const_cast<Gallery*>(this)->ImplGetThemeEntry(aFallback);
590  }
591 
592  return( pFound ? pFound->GetThemeName() : OUString() );
593 }
594 
595 bool Gallery::HasTheme( const OUString& rThemeName )
596 {
597  return( ImplGetThemeEntry( rThemeName ) != nullptr );
598 }
599 
600 bool Gallery::CreateTheme( const OUString& rThemeName )
601 {
602  bool bRet = false;
603 
604  if( !HasTheme( rThemeName ) && ( GetUserURL().GetProtocol() != INetProtocol::NotValid ) )
605  {
607  aURL.Append( rThemeName );
608  GalleryThemeEntry* pNewEntry = new GalleryThemeEntry(
609  true, aURL, rThemeName,
610  false, true, 0, false );
611 
612  aThemeList.emplace_back( pNewEntry );
613  delete new GalleryTheme( this, pNewEntry );
615  bRet = true;
616  }
617 
618  return bRet;
619 }
620 
621 void Gallery::RenameTheme( const OUString& rOldName, const OUString& rNewName )
622 {
623  GalleryThemeEntry* pThemeEntry = ImplGetThemeEntry( rOldName );
624 
625  // check if the new theme name is already present
626  if( pThemeEntry && !HasTheme( rNewName ) && !pThemeEntry->IsReadOnly() )
627  {
628  SfxListener aListener;
629  GalleryTheme* pThm = AcquireTheme( rOldName, aListener );
630 
631  if( pThm )
632  {
633  pThemeEntry->SetName( rNewName );
634  pThm->ImplWrite();
635 
637  ReleaseTheme( pThm, aListener );
638  }
639  }
640 }
641 
642 bool Gallery::RemoveTheme( const OUString& rThemeName )
643 {
644  GalleryThemeEntry* pThemeEntry = ImplGetThemeEntry( rThemeName );
645  bool bRet = false;
646 
647  if( pThemeEntry && !pThemeEntry->IsReadOnly() )
648  {
650 
651  SfxListener aListener;
652  GalleryTheme* pThm = AcquireTheme( rThemeName, aListener );
653 
654  if( pThm )
655  {
656  INetURLObject aThmURL( pThm->GetThmURL() );
657  INetURLObject aSdgURL( pThm->GetSdgURL() );
658  INetURLObject aSdvURL( pThm->GetSdvURL() );
659  INetURLObject aStrURL( pThm->GetStrURL() );
660 
661  ReleaseTheme( pThm, aListener );
662 
663  KillFile( aThmURL );
664  KillFile( aSdgURL );
665  KillFile( aSdvURL );
666  KillFile( aStrURL );
667  }
668 
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 );
673 
675 
676  bRet = true;
677  }
678 
679  return bRet;
680 }
681 
683 {
684  GalleryTheme* pTheme = nullptr;
685 
686  if( pThemeEntry )
687  {
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();
692 
693  if( !pTheme )
694  {
695  INetURLObject aURL = pThemeEntry->GetThmURL();
696 
697  DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
698 
699  std::unique_ptr<GalleryTheme> pNewTheme;
700  if( FileExists( aURL ) )
701  {
702  std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
703 
704  if( pIStm )
705  {
706  try
707  {
708  pNewTheme.reset( new GalleryTheme( this, const_cast<GalleryThemeEntry*>(pThemeEntry) ) );
709  ReadGalleryTheme( *pIStm, *pNewTheme );
710 
711  if( pIStm->GetError() )
712  pNewTheme.reset();
713  }
714  catch (const css::ucb::ContentCreationException&)
715  {
716  }
717  }
718  }
719 
720  if (pNewTheme)
721  {
722  aThemeCache.push_back( new GalleryThemeCacheEntry( pThemeEntry, std::move(pNewTheme) ));
723  pTheme = aThemeCache.back()->GetTheme();
724  }
725  }
726  }
727 
728  return pTheme;
729 }
730 
732 {
733  auto it = std::find_if(aThemeCache.begin(), aThemeCache.end(),
734  [&pTheme](const GalleryThemeCacheEntry* pEntry) { return pTheme == pEntry->GetTheme(); });
735  if (it != aThemeCache.end())
736  {
737  delete *it;
738  aThemeCache.erase(it);
739  }
740 }
741 
742 GalleryTheme* Gallery::AcquireTheme( const OUString& rThemeName, SfxListener& rListener )
743 {
744  GalleryTheme* pTheme = nullptr;
745  GalleryThemeEntry* pThemeEntry = ImplGetThemeEntry( rThemeName );
746 
747  if( pThemeEntry && ( ( pTheme = ImplGetCachedTheme( pThemeEntry ) ) != nullptr ) )
748  rListener.StartListening(*pTheme, DuplicateHandling::Prevent);
749 
750  return pTheme;
751 }
752 
753 void Gallery::ReleaseTheme( GalleryTheme* pTheme, SfxListener& rListener )
754 {
755  if( pTheme )
756  {
757  rListener.EndListening( *pTheme );
758 
759  if( !pTheme->HasListeners() )
760  ImplDeleteCachedTheme( pTheme );
761  }
762 }
763 
765 {
766  return nId > 0 && nId != GALLERY_THEME_MYTHEME;
767 }
768 
769 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const GalleryThemeEntry * GetThemeEntry() const
Definition: gallery1.cxx:249
URL aURL
bool HasListeners() const
INetURLObject aStrURL
Definition: gallery1.hxx:41
GalleryTheme * AcquireTheme(const OUString &rThemeName, SfxListener &rListener)
Definition: gallery1.cxx:742
INetURLObject aSdgURL
Definition: gallery1.hxx:39
#define RID_GALLERYSTR_THEME_FONTWORK
Definition: strings.hxx:18
static SAL_DLLPRIVATE GalleryThemeEntry * CreateThemeEntry(const INetURLObject &rURL, bool bReadOnly)
Definition: galtheme.cxx:648
OUString GetURLPath(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
const INetURLObject & GetSdgURL() const
Definition: galtheme.cxx:1464
INetURLObject aSdvURL
Definition: gallery1.hxx:40
css::uno::Any getPropertyValue(const OUString &rPropertyName)
SAL_DLLPRIVATE void ImplLoad(const OUString &rMultiPath)
Definition: gallery1.cxx:274
sal_Int64 n
std::unique_ptr< GalleryTheme > mpTheme
Definition: gallery1.cxx:242
sal_Int16 nId
static void InsertAllThemes(weld::ComboBox &rListBox)
Definition: gallery1.cxx:190
bool IsReadOnly() const
Definition: gallery1.hxx:65
bool bReadOnly
INetURLObject aUserURL
Definition: gallery1.hxx:94
SAL_DLLPRIVATE OUString GetThemeName(sal_uInt32 nThemeId) const
Definition: gallery1.cxx:516
bool setName(OUString const &rTheName, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
GalleryThemeEntry * ImplGetThemeEntry(const OUString &rThemeName)
Definition: gallery1.cxx:504
SvStream & ReadGalleryTheme(SvStream &rIn, GalleryTheme &rTheme)
Definition: galtheme.cxx:1453
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
bool setExtension(OUString const &rTheExtension, sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
SAL_DLLPRIVATE void RenameTheme(const OUString &rOldName, const OUString &rNewName)
Definition: gallery1.cxx:621
static bool IsFuzzing()
static Gallery * GetGalleryInstance()
Definition: gallery1.cxx:264
#define RID_GALLERYSTR_THEME_DUMMY5
Definition: strings.hxx:17
SAL_DLLPRIVATE void ImplLoadSubDirs(const INetURLObject &rBaseURL, bool &rbIsReadOnly)
Definition: gallery1.cxx:313
sal_uInt32 nId
Definition: gallery1.hxx:42
const GalleryThemeEntry * mpThemeEntry
Definition: gallery1.cxx:241
void SetExtension(OUString const &rTheExtension)
bool bThemeNameFromResource
Definition: gallery1.hxx:45
#define RID_GALLERYSTR_THEME_HTMLBUTTONS
Definition: strings.hxx:13
bool RemoveTheme(const OUString &rThemeName)
Definition: gallery1.cxx:642
SAL_DLLPRIVATE const INetURLObject & GetStrURL() const
Definition: galtheme.cxx:1466
SAL_DLLPRIVATE void ImplDeleteCachedTheme(GalleryTheme const *pTheme)
Definition: gallery1.cxx:731
#define RID_GALLERYSTR_THEME_FONTWORK_VERTICAL
Definition: strings.hxx:19
#define SAL_N_ELEMENTS(arr)
GalleryTheme * GetTheme() const
Definition: gallery1.cxx:250
sal_uInt32 GetId() const
Definition: gallery1.hxx:76
SAL_DLLPRIVATE const INetURLObject & GetUserURL() const
Definition: gallery1.hxx:132
#define DBG_ASSERT(sCon, aError)
bool Append(OUString const &rTheSegment, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
void SetModified(bool bSet)
Definition: gallery1.hxx:71
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
INetURLObject aThmURL
Definition: gallery1.hxx:38
const std::pair< sal_uInt16, const char * > aLocalized[]
Definition: gallery1.cxx:74
SAL_DLLPRIVATE void ImplWrite()
Definition: galtheme.cxx:192
int i
#define RID_GALLERYSTR_THEME_POWERPOINT
Definition: strings.hxx:14
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
#define RID_GALLERYSTR_THEME_RULERS
Definition: strings.hxx:15
bool KillFile(const INetURLObject &rURL)
Definition: galmisc.cxx:306
Gallery(Gallery const &)=delete
bool IsDefault() const
Definition: gallery1.cxx:764
bool HasTheme(const OUString &rThemeName)
Definition: gallery1.cxx:595
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void Broadcast(const SfxHint &rHint)
void ReleaseTheme(GalleryTheme *pTheme, SfxListener &rListener)
Definition: gallery1.cxx:753
void SetName(const OUString &rNewName)
Definition: gallery1.cxx:219
const std::pair< sal_uInt16, const char * > aUnlocalized[]
Definition: gallery1.cxx:63
INetURLObject aRelURL
Definition: gallery1.hxx:93
GalleryThemeCacheEntry(const GalleryThemeEntry *pThemeEntry, std::unique_ptr< GalleryTheme > pTheme)
Definition: gallery1.cxx:246
bool bMultiPath
Definition: gallery1.hxx:95
INetProtocol GetProtocol() const
void SetId(sal_uInt32 nNewId, bool bResetThemeName)
Definition: gallery1.cxx:229
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
#define RID_GALLERYSTR_THEME_USERSOUNDS
Definition: strings.hxx:16
Reference< XComponentContext > getProcessComponentContext()
GalleryCacheThemeList aThemeCache
Definition: gallery1.hxx:92
static INetURLObject ImplGetURLIgnoreCase(const INetURLObject &rURL)
Definition: gallery1.cxx:199
SAL_DLLPRIVATE const INetURLObject & GetThmURL() const
Definition: galtheme.cxx:1463
GalleryThemeEntry(bool bCreateUniqueURL, const INetURLObject &rBaseURL, const OUString &rName, bool bReadOnly, bool bNewFile, sal_uInt32 nId, bool bThemeNameFromResource)
Definition: gallery1.cxx:118
OUString aName
Definition: gallery1.hxx:37
void SAL_CALL first(const css::awt::SpinEvent &rEvent) override
OUString ReadStrFromIni(const OUString &aKeyName)
Definition: galini.cxx:29
void append_text(const OUString &rStr)
const OUString & GetName() const
Definition: galtheme.cxx:1478
virtual ~Gallery() override
Definition: gallery1.cxx:260
bool CreateTheme(const OUString &rThemeName)
Definition: gallery1.cxx:600
static bool FileExists(const INetURLObject &rURL, const OUString &rExt)
Definition: gallery1.cxx:56
INCLUDE_DOCUMENTS_ONLY
SAL_DLLPRIVATE GalleryTheme * ImplGetCachedTheme(const GalleryThemeEntry *pThemeEntry)
Definition: gallery1.cxx:682
const OUString & GetThemeName() const
Definition: gallery1.hxx:56
SAL_DLLPRIVATE const INetURLObject & GetSdvURL() const
Definition: galtheme.cxx:1465
std::vector< std::unique_ptr< GalleryThemeEntry > > aThemeList
Definition: gallery1.hxx:91
const INetURLObject & GetThmURL() const
Definition: gallery1.hxx:58