fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / svx / source / gallery2 / gallery1.cxx
blobb6ec5e99d60466226b971ecd671be5133ba3cd38
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "sal/config.h"
22 #include <comphelper/processfactory.hxx>
23 #include <comphelper/string.hxx>
24 #include <tools/vcompat.hxx>
25 #include <ucbhelper/content.hxx>
26 #include <unotools/ucbstreamhelper.hxx>
27 #include <unotools/pathoptions.hxx>
28 #include <sfx2/docfile.hxx>
29 #include "svx/gallery.hxx"
30 #include "gallery.hrc"
31 #include "svx/galmisc.hxx"
32 #include "svx/galtheme.hxx"
33 #include "svx/gallery1.hxx"
34 #include <com/sun/star/sdbc/XResultSet.hpp>
35 #include <com/sun/star/ucb/XContentAccess.hpp>
37 // --------------
38 // - Namespaces -
39 // --------------
41 using namespace ::rtl;
42 using namespace ::com::sun::star;
44 // ---------------------
45 // - GalleryThemeEntry -
46 // ---------------------
48 static bool FileExists( const INetURLObject &rURL, const rtl::OUString &rExt )
50 INetURLObject aURL( rURL );
51 aURL.setExtension( rExt );
52 return FileExists( aURL );
55 GalleryThemeEntry::GalleryThemeEntry( bool bCreateUniqueURL,
56 const INetURLObject& rBaseURL,
57 const String& rName,
58 sal_Bool _bReadOnly, sal_Bool _bNewFile,
59 sal_uInt32 _nId, sal_Bool _bThemeNameFromResource ) :
60 nId ( _nId ),
61 bReadOnly ( _bReadOnly ),
62 bThemeNameFromResource ( _bThemeNameFromResource )
64 INetURLObject aURL( rBaseURL );
65 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
67 if (bCreateUniqueURL)
69 INetURLObject aBaseNoCase( ImplGetURLIgnoreCase( rBaseURL ) );
70 aURL = aBaseNoCase;
71 static sal_Int32 nIdx = 0;
72 while( FileExists( aURL, "thm" ) )
73 { // create new URLs
74 nIdx++;
75 aURL = aBaseNoCase;
76 aURL.setName( aURL.getName() + OUString::number(nIdx));
80 aURL.setExtension( "thm" );
81 aThmURL = ImplGetURLIgnoreCase( aURL );
83 aURL.setExtension( "sdg" );
84 aSdgURL = ImplGetURLIgnoreCase( aURL );
86 aURL.setExtension( "sdv" );
87 aSdvURL = ImplGetURLIgnoreCase( aURL );
89 aURL.setExtension( "str" );
90 aStrURL = ImplGetURLIgnoreCase( aURL );
92 SetModified( _bNewFile );
94 aName = ReadStrFromIni( "name" );
96 // This is awful - we shouldn't use these resources if we
97 // possibly can avoid them
98 if( aName.isEmpty() && nId && bThemeNameFromResource )
99 aName = GAL_RESSTR( RID_GALLERYSTR_THEME_START + (sal_uInt16) nId );
101 if( aName.isEmpty() )
102 aName = rName;
105 // -----------------------------------------------------------------------------
107 INetURLObject GalleryThemeEntry::ImplGetURLIgnoreCase( const INetURLObject& rURL ) const
109 INetURLObject aURL( rURL );
111 // check original file name
112 if( !FileExists( aURL ) )
114 // check upper case file name
115 aURL.setName( aURL.getName().toAsciiUpperCase() );
117 if(!FileExists( aURL ) )
119 // check lower case file name
120 aURL.setName( aURL.getName().toAsciiLowerCase() );
124 return aURL;
127 // -----------------------------------------------------------------------------
129 void GalleryThemeEntry::SetName( const OUString& rNewName )
131 if( aName != rNewName )
133 aName = rNewName;
134 SetModified( sal_True );
135 bThemeNameFromResource = sal_False;
139 // -----------------------------------------------------------------------------
141 void GalleryThemeEntry::SetId( sal_uInt32 nNewId, sal_Bool bResetThemeName )
143 nId = nNewId;
144 SetModified( sal_True );
145 bThemeNameFromResource = ( nId && bResetThemeName );
148 // --------------------------
149 // - GalleryThemeCacheEntry -
150 // --------------------------
152 class GalleryThemeCacheEntry
154 private:
156 const GalleryThemeEntry* mpThemeEntry;
157 GalleryTheme* mpTheme;
159 public:
161 GalleryThemeCacheEntry( const GalleryThemeEntry* pThemeEntry, GalleryTheme* pTheme ) :
162 mpThemeEntry( pThemeEntry ), mpTheme( pTheme ) {}
163 ~GalleryThemeCacheEntry() { delete mpTheme; }
165 const GalleryThemeEntry* GetThemeEntry() const { return mpThemeEntry; }
166 GalleryTheme* GetTheme() const { return mpTheme; }
169 // -----------
170 // - Gallery -
171 // -----------
173 Gallery::Gallery( const OUString& rMultiPath )
174 : nReadTextEncoding ( osl_getThreadTextEncoding() )
175 , bMultiPath ( sal_False )
177 ImplLoad( rMultiPath );
180 // ------------------------------------------------------------------------
182 Gallery::~Gallery()
184 // Themen-Liste loeschen
185 for ( size_t i = 0, n = aThemeList.size(); i < n; ++i )
186 delete aThemeList[ i ];
187 aThemeList.clear();
190 // ------------------------------------------------------------------------
192 Gallery* Gallery::GetGalleryInstance()
194 static Gallery* pGallery = NULL;
196 if( !pGallery )
198 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
199 if( !pGallery )
201 pGallery = new Gallery( SvtPathOptions().GetGalleryPath() );
205 return pGallery;
208 // ------------------------------------------------------------------------
210 void Gallery::ImplLoad( const OUString& rMultiPath )
212 const sal_Int32 nTokenCount = comphelper::string::getTokenCount(rMultiPath, ';');
213 sal_Bool bIsReadOnlyDir;
215 bMultiPath = ( nTokenCount > 0 );
217 INetURLObject aCurURL(SvtPathOptions().GetConfigPath());
218 ImplLoadSubDirs( aCurURL, bIsReadOnlyDir );
220 if( !bIsReadOnlyDir )
221 aUserURL = aCurURL;
223 if( bMultiPath )
225 aRelURL = INetURLObject( comphelper::string::getToken(rMultiPath, 0, ';') );
227 for( sal_Int32 i = 0; i < nTokenCount; ++i )
229 aCurURL = INetURLObject(comphelper::string::getToken(rMultiPath, i, ';'));
231 ImplLoadSubDirs( aCurURL, bIsReadOnlyDir );
233 if( !bIsReadOnlyDir )
234 aUserURL = aCurURL;
237 else
238 aRelURL = INetURLObject( rMultiPath );
240 DBG_ASSERT( aUserURL.GetProtocol() != INET_PROT_NOT_VALID, "no writable Gallery user directory available" );
241 DBG_ASSERT( aRelURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
244 // ------------------------------------------------------------------------
246 void Gallery::ImplLoadSubDirs( const INetURLObject& rBaseURL, sal_Bool& rbDirIsReadOnly )
248 rbDirIsReadOnly = sal_False;
252 uno::Reference< ucb::XCommandEnvironment > xEnv;
253 ::ucbhelper::Content aCnt( rBaseURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv, comphelper::getProcessComponentContext() );
255 uno::Sequence< OUString > aProps( 1 );
256 aProps.getArray()[ 0 ] = OUString("Url");
258 uno::Reference< sdbc::XResultSet > xResultSet( aCnt.createCursor( aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
262 // check readonlyness the very hard way
263 INetURLObject aTestURL( rBaseURL );
264 String aTestFile( RTL_CONSTASCII_USTRINGPARAM( "cdefghij.klm" ) );
266 aTestURL.Append( aTestFile );
267 SvStream* pTestStm = ::utl::UcbStreamHelper::CreateStream( aTestURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE );
269 if( pTestStm )
271 *pTestStm << sal_Int32(1);
273 if( pTestStm->GetError() )
274 rbDirIsReadOnly = sal_True;
276 delete pTestStm;
277 KillFile( aTestURL );
279 else
280 rbDirIsReadOnly = sal_True;
282 catch( const ucb::ContentCreationException& )
285 catch( const uno::RuntimeException& )
288 catch( const uno::Exception& )
292 if( xResultSet.is() )
294 uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY );
296 if( xContentAccess.is() )
298 static const OUString s_sTitle("Title");
299 static const OUString s_sIsReadOnly("IsReadOnly");
300 static const OUString s_sSDG_EXT("sdg");
301 static const OUString s_sSDV_EXT("sdv");
303 while( xResultSet->next() )
305 INetURLObject aThmURL( xContentAccess->queryContentIdentifierString() );
307 if(aThmURL.GetExtension().equalsIgnoreAsciiCase("thm"))
309 INetURLObject aSdgURL( aThmURL); aSdgURL.SetExtension( s_sSDG_EXT );
310 INetURLObject aSdvURL( aThmURL ); aSdvURL.SetExtension( s_sSDV_EXT );
311 OUString aTitle;
312 sal_Bool bReadOnly = sal_False;
316 ::ucbhelper::Content aThmCnt( aThmURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv, comphelper::getProcessComponentContext() );
317 ::ucbhelper::Content aSdgCnt( aSdgURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv, comphelper::getProcessComponentContext() );
318 ::ucbhelper::Content aSdvCnt( aSdvURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv, comphelper::getProcessComponentContext() );
322 aThmCnt.getPropertyValue( s_sTitle ) >>= aTitle;
324 catch( const uno::RuntimeException& )
327 catch( const uno::Exception& )
331 if( !aTitle.isEmpty() )
335 aThmCnt.getPropertyValue( s_sIsReadOnly ) >>= bReadOnly;
337 catch( const uno::RuntimeException& )
340 catch( const uno::Exception& )
344 if( !bReadOnly )
348 aSdgCnt.getPropertyValue( s_sTitle ) >>= aTitle;
350 catch( const ::com::sun::star::uno::RuntimeException& )
353 catch( const ::com::sun::star::uno::Exception& )
357 if( !aTitle.isEmpty() )
361 aSdgCnt.getPropertyValue( s_sIsReadOnly ) >>= bReadOnly;
363 catch( const uno::RuntimeException& )
366 catch( const uno::Exception& )
372 if( !bReadOnly )
376 aSdvCnt.getPropertyValue( s_sTitle ) >>= aTitle;
378 catch( const ::com::sun::star::uno::RuntimeException& )
381 catch( const ::com::sun::star::uno::Exception& )
385 if( !aTitle.isEmpty() )
389 aSdvCnt.getPropertyValue( s_sIsReadOnly ) >>= bReadOnly;
391 catch( const uno::RuntimeException& )
394 catch( const uno::Exception& )
400 GalleryThemeEntry* pEntry = GalleryTheme::CreateThemeEntry( aThmURL, rbDirIsReadOnly || bReadOnly );
402 if( pEntry )
403 aThemeList.push_back( pEntry );
406 catch( const ucb::ContentCreationException& )
409 catch( const uno::RuntimeException& )
412 catch( const uno::Exception& )
420 catch( const ucb::ContentCreationException& )
423 catch( const uno::RuntimeException& )
426 catch( const uno::Exception& )
431 // ------------------------------------------------------------------------
433 GalleryThemeEntry* Gallery::ImplGetThemeEntry( const OUString& rThemeName )
435 GalleryThemeEntry* pFound = NULL;
437 if( !rThemeName.isEmpty() )
439 for ( size_t i = 0, n = aThemeList.size(); i < n && !pFound; ++i )
440 if( rThemeName == aThemeList[ i ]->GetThemeName() )
441 pFound = aThemeList[ i ];
444 return pFound;
447 // ------------------------------------------------------------------------
449 OUString Gallery::GetThemeName( sal_uIntPtr nThemeId ) const
451 GalleryThemeEntry* pFound = NULL;
453 for ( size_t i = 0, n = aThemeList.size(); i < n && !pFound; ++i )
455 GalleryThemeEntry* pEntry = aThemeList[ i ];
456 if( nThemeId == pEntry->GetId() )
457 pFound = pEntry;
460 // try fallback, if no entry was found
461 if( !pFound )
463 OString aFallback;
465 switch( nThemeId )
467 case( GALLERY_THEME_3D ):
468 aFallback = "3D";
469 break;
470 case( GALLERY_THEME_BULLETS ):
471 aFallback = "Bullets";
472 break;
473 case( GALLERY_THEME_HOMEPAGE ):
474 aFallback = "Homepage";
475 break;
476 case( GALLERY_THEME_POWERPOINT ):
477 aFallback = "private://gallery/hidden/imgppt";
478 break;
479 case( GALLERY_THEME_FONTWORK ):
480 aFallback = "private://gallery/hidden/fontwork";
481 break;
482 case( GALLERY_THEME_FONTWORK_VERTICAL ):
483 aFallback = "private://gallery/hidden/fontworkvertical";
484 break;
485 case( GALLERY_THEME_SOUNDS ):
486 aFallback = "Sounds";
487 break;
488 case( RID_GALLERYSTR_THEME_ARROWS ):
489 aFallback = "Arrows";
490 break;
491 case( RID_GALLERYSTR_THEME_COMPUTERS ):
492 aFallback = "Computers";
493 break;
494 case( RID_GALLERYSTR_THEME_DIAGRAMS ):
495 aFallback = "Diagrams";
496 break;
497 case( RID_GALLERYSTR_THEME_EDUCATION ):
498 aFallback = "Education";
499 break;
500 case( RID_GALLERYSTR_THEME_ENVIRONMENT ):
501 aFallback = "Environment";
502 break;
503 case( RID_GALLERYSTR_THEME_FINANCE ):
504 aFallback = "Finance";
505 break;
506 case( RID_GALLERYSTR_THEME_PEOPLE ):
507 aFallback = "People";
508 break;
509 case( RID_GALLERYSTR_THEME_SYMBOLS ):
510 aFallback = "Symbols";
511 break;
512 case( RID_GALLERYSTR_THEME_TRANSPORT ):
513 aFallback = "Transport";
514 break;
515 case( RID_GALLERYSTR_THEME_TXTSHAPES ):
516 aFallback = "Textshapes";
517 break;
518 default:
519 break;
522 pFound = const_cast<Gallery*>(this)->ImplGetThemeEntry(OStringToOUString(aFallback, RTL_TEXTENCODING_ASCII_US));
525 return( pFound ? pFound->GetThemeName() : OUString() );
528 // ------------------------------------------------------------------------
530 sal_Bool Gallery::HasTheme( const String& rThemeName )
532 return( ImplGetThemeEntry( rThemeName ) != NULL );
535 // ------------------------------------------------------------------------
537 sal_Bool Gallery::CreateTheme( const String& rThemeName )
539 sal_Bool bRet = sal_False;
541 if( !HasTheme( rThemeName ) && ( GetUserURL().GetProtocol() != INET_PROT_NOT_VALID ) )
543 INetURLObject aURL( GetUserURL() );
544 aURL.Append( rThemeName );
545 GalleryThemeEntry* pNewEntry = new GalleryThemeEntry(
546 true, aURL, rThemeName,
547 sal_False, sal_True, 0, sal_False );
549 aThemeList.push_back( pNewEntry );
550 delete( new GalleryTheme( this, pNewEntry ) );
551 Broadcast( GalleryHint( GALLERY_HINT_THEME_CREATED, rThemeName ) );
552 bRet = sal_True;
555 return bRet;
558 // ------------------------------------------------------------------------
560 sal_Bool Gallery::RenameTheme( const String& rOldName, const String& rNewName )
562 GalleryThemeEntry* pThemeEntry = ImplGetThemeEntry( rOldName );
563 sal_Bool bRet = sal_False;
565 // Ueberpruefen, ob neuer Themenname schon vorhanden ist
566 if( pThemeEntry && !HasTheme( rNewName ) && !pThemeEntry->IsReadOnly() )
568 SfxListener aListener;
569 GalleryTheme* pThm = AcquireTheme( rOldName, aListener );
571 if( pThm )
573 const String aOldName( rOldName );
575 pThemeEntry->SetName( rNewName );
576 pThm->ImplWrite();
578 Broadcast( GalleryHint( GALLERY_HINT_THEME_RENAMED, aOldName, pThm->GetName() ) );
579 ReleaseTheme( pThm, aListener );
580 bRet = sal_True;
584 return bRet;
587 // ------------------------------------------------------------------------
589 sal_Bool Gallery::RemoveTheme( const String& rThemeName )
591 GalleryThemeEntry* pThemeEntry = ImplGetThemeEntry( rThemeName );
592 sal_Bool bRet = sal_False;
594 if( pThemeEntry && !pThemeEntry->IsReadOnly() )
596 Broadcast( GalleryHint( GALLERY_HINT_CLOSE_THEME, rThemeName ) );
598 SfxListener aListener;
599 GalleryTheme* pThm = AcquireTheme( rThemeName, aListener );
601 if( pThm )
603 INetURLObject aThmURL( pThm->GetThmURL() );
604 INetURLObject aSdgURL( pThm->GetSdgURL() );
605 INetURLObject aSdvURL( pThm->GetSdvURL() );
606 INetURLObject aStrURL( pThm->GetSdvURL() );
608 ReleaseTheme( pThm, aListener );
610 KillFile( aThmURL );
611 KillFile( aSdgURL );
612 KillFile( aSdvURL );
613 KillFile( aStrURL );
616 for ( GalleryThemeList::iterator it = aThemeList.begin(); it != aThemeList.end(); ++it )
618 if ( pThemeEntry == *it ) {
619 delete pThemeEntry;
620 aThemeList.erase( it );
621 break;
625 Broadcast( GalleryHint( GALLERY_HINT_THEME_REMOVED, rThemeName ) );
627 bRet = sal_True;
630 return bRet;
633 // ------------------------------------------------------------------------
635 GalleryTheme* Gallery::ImplGetCachedTheme( const GalleryThemeEntry* pThemeEntry )
637 GalleryTheme* pTheme = NULL;
639 if( pThemeEntry )
641 for (GalleryCacheThemeList::const_iterator it = aThemeCache.begin(); it != aThemeCache.end(); ++it)
643 if (pThemeEntry == (*it)->GetThemeEntry())
645 pTheme = (*it)->GetTheme();
646 break;
650 if( !pTheme )
652 INetURLObject aURL = pThemeEntry->GetThmURL();
654 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
656 if( FileExists( aURL ) )
658 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );
660 if( pIStm )
662 pTheme = new GalleryTheme( this, (GalleryThemeEntry*) pThemeEntry );
663 *pIStm >> *pTheme;
665 if( pIStm->GetError() )
667 delete pTheme, pTheme = NULL;
670 delete pIStm;
674 if( pTheme )
675 aThemeCache.push_back( new GalleryThemeCacheEntry( pThemeEntry, pTheme ));
679 return pTheme;
682 // ------------------------------------------------------------------------
684 void Gallery::ImplDeleteCachedTheme( GalleryTheme* pTheme )
686 for (GalleryCacheThemeList::iterator it = aThemeCache.begin(); it != aThemeCache.end(); ++it)
688 if (pTheme == (*it)->GetTheme())
690 delete *it;
691 aThemeCache.erase(it);
692 break;
697 // ------------------------------------------------------------------------
699 GalleryTheme* Gallery::AcquireTheme( const String& rThemeName, SfxListener& rListener )
701 GalleryTheme* pTheme = NULL;
702 GalleryThemeEntry* pThemeEntry = ImplGetThemeEntry( rThemeName );
704 if( pThemeEntry && ( ( pTheme = ImplGetCachedTheme( pThemeEntry ) ) != NULL ) )
705 rListener.StartListening( *pTheme );
707 return pTheme;
710 // ------------------------------------------------------------------------
712 void Gallery::ReleaseTheme( GalleryTheme* pTheme, SfxListener& rListener )
714 if( pTheme )
716 rListener.EndListening( *pTheme );
718 if( !pTheme->HasListeners() )
719 ImplDeleteCachedTheme( pTheme );
723 sal_Bool GalleryThemeEntry::IsDefault() const
724 { return( ( nId > 0 ) && ( nId != ( RID_GALLERYSTR_THEME_MYTHEME - RID_GALLERYSTR_THEME_START ) ) ); }
726 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */