LCOV - code coverage report
Current view: top level - framework/source/uiconfiguration - imagemanagerimpl.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 209 722 28.9 %
Date: 2014-04-11 Functions: 28 53 52.8 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <imagemanagerimpl.hxx>
      21             : #include <xml/imagesconfiguration.hxx>
      22             : #include <uiconfiguration/graphicnameaccess.hxx>
      23             : #include <services.h>
      24             : 
      25             : #include "properties.h"
      26             : 
      27             : #include <com/sun/star/frame/theUICommandDescription.hpp>
      28             : #include <com/sun/star/ui/UIElementType.hpp>
      29             : #include <com/sun/star/ui/ConfigurationEvent.hpp>
      30             : #include <com/sun/star/lang/DisposedException.hpp>
      31             : #include <com/sun/star/beans/XPropertySet.hpp>
      32             : #include <com/sun/star/beans/PropertyValue.hpp>
      33             : #include <com/sun/star/embed/ElementModes.hpp>
      34             : #include <com/sun/star/io/XStream.hpp>
      35             : #include <com/sun/star/ui/ImageType.hpp>
      36             : 
      37             : #include <vcl/svapp.hxx>
      38             : #include <rtl/ustrbuf.hxx>
      39             : #include <osl/mutex.hxx>
      40             : #include <comphelper/sequence.hxx>
      41             : #include <tools/urlobj.hxx>
      42             : #include <unotools/ucbstreamhelper.hxx>
      43             : #include <vcl/pngread.hxx>
      44             : #include <vcl/pngwrite.hxx>
      45             : #include <rtl/instance.hxx>
      46             : #include <svtools/miscopt.hxx>
      47             : 
      48             : using ::com::sun::star::uno::Sequence;
      49             : using ::com::sun::star::uno::XInterface;
      50             : using ::com::sun::star::uno::Exception;
      51             : using ::com::sun::star::uno::RuntimeException;
      52             : using ::com::sun::star::uno::UNO_QUERY;
      53             : using ::com::sun::star::uno::Any;
      54             : using ::com::sun::star::uno::makeAny;
      55             : using ::com::sun::star::graphic::XGraphic;
      56             : using namespace ::com::sun::star;
      57             : using namespace ::com::sun::star::io;
      58             : using namespace ::com::sun::star::embed;
      59             : using namespace ::com::sun::star::lang;
      60             : using namespace ::com::sun::star::container;
      61             : using namespace ::com::sun::star::beans;
      62             : using namespace ::com::sun::star::ui;
      63             : using namespace ::cppu;
      64             : 
      65             : // Image sizes for our toolbars/menus
      66             : const sal_Int32 IMAGE_SIZE_NORMAL         = 16;
      67             : const sal_Int32 IMAGE_SIZE_LARGE          = 26;
      68             : const sal_Int16 MAX_IMAGETYPE_VALUE       = ::com::sun::star::ui::ImageType::SIZE_LARGE;
      69             : 
      70             : static const char   IMAGE_FOLDER[]        = "images";
      71             : static const char   BITMAPS_FOLDER[]      = "Bitmaps";
      72             : 
      73             : static const char   ModuleImageList[]     = "private:resource/images/moduleimages";
      74             : 
      75             : static const char*  IMAGELIST_XML_FILE[]  =
      76             : {
      77             :     "sc_imagelist.xml",
      78             :     "lc_imagelist.xml"
      79             : };
      80             : 
      81             : static const char*  BITMAP_FILE_NAMES[]   =
      82             : {
      83             :     "sc_userimages.png",
      84             :     "lc_userimages.png"
      85             : };
      86             : 
      87             : namespace framework
      88             : {
      89             :     static GlobalImageList*     pGlobalImageList = 0;
      90             :     static const char* ImageType_Prefixes[ImageType_COUNT] =
      91             :     {
      92             :         "cmd/sc_",
      93             :         "cmd/lc_"
      94             :     };
      95             : 
      96             : typedef GraphicNameAccess CmdToXGraphicNameAccess;
      97             : 
      98             : namespace
      99             : {
     100             :     class theGlobalImageListMutex
     101             :         : public rtl::Static<osl::Mutex, theGlobalImageListMutex> {};
     102             : }
     103             : 
     104       71616 : static osl::Mutex& getGlobalImageListMutex()
     105             : {
     106       71616 :     return theGlobalImageListMutex::get();
     107             : }
     108             : 
     109          50 : static GlobalImageList* getGlobalImageList( const uno::Reference< uno::XComponentContext >& rxContext )
     110             : {
     111          50 :     osl::MutexGuard guard( getGlobalImageListMutex() );
     112             : 
     113          50 :     if ( pGlobalImageList == 0 )
     114          34 :         pGlobalImageList = new GlobalImageList( rxContext );
     115             : 
     116          50 :     return pGlobalImageList;
     117             : }
     118             : 
     119           0 : static OUString getCanonicalName( const OUString& rFileName )
     120             : {
     121           0 :     bool               bRemoveSlash( true );
     122           0 :     sal_Int32          nLength = rFileName.getLength();
     123           0 :     const sal_Unicode* pString = rFileName.getStr();
     124             : 
     125           0 :     OUStringBuffer aBuf( nLength );
     126           0 :     for ( sal_Int32 i = 0; i < nLength; i++ )
     127             :     {
     128           0 :         const sal_Unicode c = pString[i];
     129           0 :         switch ( c )
     130             :         {
     131             :             // map forbidden characters to escape
     132           0 :             case '/' : if ( !bRemoveSlash )
     133           0 :                          aBuf.appendAscii( "%2f" );
     134           0 :                        break;
     135           0 :             case '\\': aBuf.appendAscii( "%5c" ); bRemoveSlash = false; break;
     136           0 :             case ':' : aBuf.appendAscii( "%3a" ); bRemoveSlash = false; break;
     137           0 :             case '*' : aBuf.appendAscii( "%2a" ); bRemoveSlash = false; break;
     138           0 :             case '?' : aBuf.appendAscii( "%3f" ); bRemoveSlash = false; break;
     139           0 :             case '<' : aBuf.appendAscii( "%3c" ); bRemoveSlash = false; break;
     140           0 :             case '>' : aBuf.appendAscii( "%3e" ); bRemoveSlash = false; break;
     141           0 :             case '|' : aBuf.appendAscii( "%7c" ); bRemoveSlash = false; break;
     142           0 :             default: aBuf.append( c ); bRemoveSlash = false;
     143             :         }
     144             :     }
     145           0 :     return aBuf.makeStringAndClear();
     146             : }
     147             : 
     148          84 : CmdImageList::CmdImageList( const uno::Reference< uno::XComponentContext >& rxContext, const OUString& aModuleIdentifier ) :
     149             :     m_bVectorInit( false ),
     150             :     m_aModuleIdentifier( aModuleIdentifier ),
     151             :     m_xContext( rxContext ),
     152          84 :     m_sIconTheme( SvtMiscOptions().GetIconTheme() )
     153             : {
     154         252 :     for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
     155         168 :         m_pImageList[n] = 0;
     156          84 : }
     157             : 
     158         218 : CmdImageList::~CmdImageList()
     159             : {
     160         252 :     for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
     161         168 :         delete m_pImageList[n];
     162         134 : }
     163             : 
     164      112985 : void CmdImageList::impl_fillCommandToImageNameMap()
     165             : {
     166             :     SAL_INFO( "fwk", "framework: CmdImageList::impl_fillCommandToImageNameMap" );
     167             : 
     168      112985 :     if ( !m_bVectorInit )
     169             :     {
     170          82 :         const OUString aCommandImageList( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDIMAGELIST );
     171         164 :         Sequence< OUString > aCmdImageSeq;
     172         164 :         uno::Reference< XNameAccess > xCmdDesc = frame::theUICommandDescription::get( m_xContext );
     173             : 
     174          82 :         if ( !m_aModuleIdentifier.isEmpty() )
     175             :         {
     176             :             // If we have a module identifier - use to retrieve the command image name list from it.
     177             :             // Otherwise we will use the global command image list
     178             :             try
     179             :             {
     180          50 :                 xCmdDesc->getByName( m_aModuleIdentifier ) >>= xCmdDesc;
     181          50 :                 if ( xCmdDesc.is() )
     182          50 :                     xCmdDesc->getByName( aCommandImageList ) >>= aCmdImageSeq;
     183             :             }
     184           0 :             catch ( const NoSuchElementException& )
     185             :             {
     186             :                 // Module unknown we will work with an empty command image list!
     187      112985 :                 return;
     188             :             }
     189             :         }
     190             : 
     191          82 :         if ( xCmdDesc.is() )
     192             :         {
     193             :             try
     194             :             {
     195          82 :                 xCmdDesc->getByName( aCommandImageList ) >>= aCmdImageSeq;
     196             :             }
     197           0 :             catch ( const NoSuchElementException& )
     198             :             {
     199             :             }
     200           0 :             catch ( const WrappedTargetException& )
     201             :             {
     202             :             }
     203             :         }
     204             : 
     205             :         // We have to map commands which uses special characters like '/',':','?','\','<'.'>','|'
     206         164 :         OUString aExt = ".png";
     207          82 :         m_aImageCommandNameVector.resize(aCmdImageSeq.getLength() );
     208          82 :         m_aImageNameVector.resize( aCmdImageSeq.getLength() );
     209             : 
     210             :         ::std::copy( aCmdImageSeq.getConstArray(),
     211          82 :                      aCmdImageSeq.getConstArray()+aCmdImageSeq.getLength(),
     212         164 :                      m_aImageCommandNameVector.begin() );
     213             : 
     214             :         // Create a image name vector that must be provided to the vcl imagelist. We also need
     215             :         // a command to image name map to speed up access time for image retrieval.
     216         164 :         OUString aUNOString( ".uno:" );
     217         164 :         OUString aEmptyString;
     218          82 :         const sal_uInt32 nCount = m_aImageCommandNameVector.size();
     219       22667 :         for ( sal_uInt32 i = 0; i < nCount; i++ )
     220             :         {
     221       22585 :             OUString aCommandName( m_aImageCommandNameVector[i] );
     222       45170 :             OUString aImageName;
     223             : 
     224       22585 :             if ( aCommandName.indexOf( aUNOString ) != 0 )
     225             :             {
     226           0 :                 INetURLObject aUrlObject( aCommandName, INetURLObject::ENCODE_ALL );
     227           0 :                 aImageName = aUrlObject.GetURLPath();
     228           0 :                 aImageName = getCanonicalName( aImageName ); // convert to valid filename
     229             :             }
     230             :             else
     231             :             {
     232             :                 // just remove the schema
     233       22585 :                 if ( aCommandName.getLength() > 5 )
     234       22585 :                     aImageName = aCommandName.copy( 5 );
     235             :                 else
     236           0 :                     aImageName = aEmptyString;
     237             : 
     238             :                 // Search for query part.
     239       22585 :                 if ( aImageName.indexOf('?') != -1 )
     240           0 :                     aImageName = getCanonicalName( aImageName ); // convert to valid filename
     241             :             }
     242             :             // Image names are not case-dependent. Always use lower case characters to
     243             :             // reflect this.
     244       22585 :             aImageName += aExt;
     245       22585 :             aImageName = aImageName.toAsciiLowerCase();
     246             : 
     247       22585 :             m_aImageNameVector[i] = aImageName;
     248       22585 :             m_aCommandToImageNameMap.insert( CommandToImageNameMap::value_type( aCommandName, aImageName ));
     249       22585 :         }
     250             : 
     251         164 :         m_bVectorInit = true;
     252             :     }
     253             : }
     254             : 
     255       44506 : ImageList* CmdImageList::impl_getImageList( sal_Int16 nImageType )
     256             : {
     257       44506 :     SvtMiscOptions aMiscOptions;
     258             : 
     259       89012 :     const OUString& rIconTheme = aMiscOptions.GetIconTheme();
     260       44506 :     if ( rIconTheme != m_sIconTheme )
     261             :     {
     262           0 :         m_sIconTheme = rIconTheme;
     263           0 :         for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
     264           0 :             delete m_pImageList[n], m_pImageList[n] = NULL;
     265             :     }
     266             : 
     267       44506 :     if ( !m_pImageList[nImageType] )
     268             :     {
     269          81 :         m_pImageList[nImageType] = new ImageList( m_aImageNameVector,
     270         162 :                                                   OUString::createFromAscii( ImageType_Prefixes[nImageType] ) );
     271             :     }
     272             : 
     273       89012 :     return m_pImageList[nImageType];
     274             : }
     275             : 
     276           0 : std::vector< OUString >& CmdImageList::impl_getImageNameVector()
     277             : {
     278           0 :     return m_aImageNameVector;
     279             : }
     280             : 
     281           0 : std::vector< OUString >& CmdImageList::impl_getImageCommandNameVector()
     282             : {
     283           0 :     return m_aImageCommandNameVector;
     284             : }
     285             : 
     286      112985 : Image CmdImageList::getImageFromCommandURL( sal_Int16 nImageType, const OUString& rCommandURL )
     287             : {
     288      112985 :     impl_fillCommandToImageNameMap();
     289      112985 :     CommandToImageNameMap::const_iterator pIter = m_aCommandToImageNameMap.find( rCommandURL );
     290      112985 :     if ( pIter != m_aCommandToImageNameMap.end() )
     291             :     {
     292       44506 :         ImageList* pImageList = impl_getImageList( nImageType );
     293       44506 :         return pImageList->GetImage( pIter->second );
     294             :     }
     295             : 
     296       68479 :     return Image();
     297             : }
     298             : 
     299           0 : bool CmdImageList::hasImage( sal_Int16 /*nImageType*/, const OUString& rCommandURL )
     300             : {
     301           0 :     impl_fillCommandToImageNameMap();
     302           0 :     CommandToImageNameMap::const_iterator pIter = m_aCommandToImageNameMap.find( rCommandURL );
     303           0 :     if ( pIter != m_aCommandToImageNameMap.end() )
     304           0 :         return true;
     305             :     else
     306           0 :         return false;
     307             : }
     308             : 
     309           0 : ::std::vector< OUString >& CmdImageList::getImageNames()
     310             : {
     311           0 :     return impl_getImageNameVector();
     312             : }
     313             : 
     314           0 : ::std::vector< OUString >& CmdImageList::getImageCommandNames()
     315             : {
     316           0 :     return impl_getImageCommandNameVector();
     317             : }
     318             : 
     319          34 : GlobalImageList::GlobalImageList( const uno::Reference< uno::XComponentContext >& rxContext ) :
     320             :     CmdImageList( rxContext, OUString() ),
     321          34 :     m_nRefCount( 0 )
     322             : {
     323          34 : }
     324             : 
     325          68 : GlobalImageList::~GlobalImageList()
     326             : {
     327          68 : }
     328             : 
     329       52131 : Image GlobalImageList::getImageFromCommandURL( sal_Int16 nImageType, const OUString& rCommandURL )
     330             : {
     331       52131 :     osl::MutexGuard guard( getGlobalImageListMutex() );
     332       52131 :     return CmdImageList::getImageFromCommandURL( nImageType, rCommandURL );
     333             : }
     334             : 
     335           0 : bool GlobalImageList::hasImage( sal_Int16 nImageType, const OUString& rCommandURL )
     336             : {
     337           0 :     osl::MutexGuard guard( getGlobalImageListMutex() );
     338           0 :     return CmdImageList::hasImage( nImageType, rCommandURL );
     339             : }
     340             : 
     341           0 : ::std::vector< OUString >& GlobalImageList::getImageNames()
     342             : {
     343           0 :     osl::MutexGuard guard( getGlobalImageListMutex() );
     344           0 :     return impl_getImageNameVector();
     345             : }
     346             : 
     347           0 : ::std::vector< OUString >& GlobalImageList::getImageCommandNames()
     348             : {
     349           0 :     osl::MutexGuard guard( getGlobalImageListMutex() );
     350           0 :     return impl_getImageCommandNameVector();
     351             : }
     352             : 
     353       19435 : oslInterlockedCount GlobalImageList::acquire()
     354             : {
     355       19435 :     osl_atomic_increment( &m_nRefCount );
     356       19435 :     return m_nRefCount;
     357             : }
     358             : 
     359       19435 : oslInterlockedCount GlobalImageList::release()
     360             : {
     361       19435 :     osl::MutexGuard guard( getGlobalImageListMutex() );
     362             : 
     363       19435 :     if ( !osl_atomic_decrement( &m_nRefCount ))
     364             :     {
     365          34 :         oslInterlockedCount nCount( m_nRefCount );
     366             :         // remove global pointer as we destroy the object now
     367          34 :         pGlobalImageList = 0;
     368          34 :         delete this;
     369          34 :         return nCount;
     370             :     }
     371             : 
     372       19401 :     return m_nRefCount;
     373             : }
     374             : 
     375           0 : static bool implts_checkAndScaleGraphic( uno::Reference< XGraphic >& rOutGraphic, const uno::Reference< XGraphic >& rInGraphic, sal_Int16 nImageType )
     376             : {
     377           0 :     static Size   aNormSize( IMAGE_SIZE_NORMAL, IMAGE_SIZE_NORMAL );
     378           0 :     static Size   aLargeSize( IMAGE_SIZE_LARGE, IMAGE_SIZE_LARGE );
     379             : 
     380           0 :     if ( !rInGraphic.is() )
     381             :     {
     382           0 :         rOutGraphic = Image().GetXGraphic();
     383           0 :         return false;
     384             :     }
     385             : 
     386             :     // Check size and scale it
     387           0 :     Image  aImage( rInGraphic );
     388           0 :     Size   aSize = aImage.GetSizePixel();
     389           0 :     bool   bMustScale( false );
     390             : 
     391           0 :     if ( nImageType == ImageType_Color_Large )
     392           0 :         bMustScale = ( aSize != aLargeSize );
     393             :     else
     394           0 :         bMustScale = ( aSize != aNormSize );
     395             : 
     396           0 :     if ( bMustScale )
     397             :     {
     398           0 :         BitmapEx aBitmap = aImage.GetBitmapEx();
     399           0 :         aBitmap.Scale( aNormSize );
     400           0 :         aImage = Image( aBitmap );
     401           0 :         rOutGraphic = aImage.GetXGraphic();
     402             :     }
     403             :     else
     404           0 :         rOutGraphic = rInGraphic;
     405           0 :     return true;
     406             : }
     407             : 
     408       38308 : static sal_Int16 implts_convertImageTypeToIndex( sal_Int16 nImageType )
     409             : {
     410       38308 :     sal_Int16 nIndex( 0 );
     411       38308 :     if ( nImageType & ::com::sun::star::ui::ImageType::SIZE_LARGE )
     412          18 :         nIndex += 1;
     413       38308 :     return nIndex;
     414             : }
     415             : 
     416       38308 : ImageList* ImageManagerImpl::implts_getUserImageList( ImageType nImageType )
     417             : {
     418       38308 :     SolarMutexGuard g;
     419       38308 :     if ( !m_pUserImageList[nImageType] )
     420         704 :         implts_loadUserImages( nImageType, m_xUserImageStorage, m_xUserBitmapsStorage );
     421             : 
     422       38308 :     return m_pUserImageList[nImageType];
     423             : }
     424             : 
     425        2119 : void ImageManagerImpl::implts_initialize()
     426             : {
     427             :     // Initialize the top-level structures with the storage data
     428        2119 :     if ( m_xUserConfigStorage.is() )
     429             :     {
     430        2101 :         long nModes = m_bReadOnly ? ElementModes::READ : ElementModes::READWRITE;
     431             : 
     432             :         try
     433             :         {
     434        6303 :             m_xUserImageStorage = m_xUserConfigStorage->openStorageElement( OUString(IMAGE_FOLDER ),
     435        4202 :                                                                             nModes );
     436        2101 :             if ( m_xUserImageStorage.is() )
     437             :             {
     438        6303 :                 m_xUserBitmapsStorage = m_xUserImageStorage->openStorageElement( OUString(BITMAPS_FOLDER ),
     439        4202 :                                                                                  nModes );
     440             :             }
     441             :         }
     442           0 :         catch ( const ::com::sun::star::container::NoSuchElementException& )
     443             :         {
     444             :         }
     445           0 :         catch ( const ::com::sun::star::embed::InvalidStorageException& )
     446             :         {
     447             :         }
     448           0 :         catch ( const ::com::sun::star::lang::IllegalArgumentException& )
     449             :         {
     450             :         }
     451           0 :         catch ( const ::com::sun::star::io::IOException& )
     452             :         {
     453             :         }
     454           0 :         catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
     455             :         {
     456             :         }
     457             :     }
     458        2119 : }
     459             : 
     460         704 : bool ImageManagerImpl::implts_loadUserImages(
     461             :     ImageType nImageType,
     462             :     const uno::Reference< XStorage >& xUserImageStorage,
     463             :     const uno::Reference< XStorage >& xUserBitmapsStorage )
     464             : {
     465         704 :     SolarMutexGuard g;
     466             : 
     467         704 :     if ( xUserImageStorage.is() && xUserBitmapsStorage.is() )
     468             :     {
     469             :         try
     470             :         {
     471         704 :             uno::Reference< XStream > xStream = xUserImageStorage->openStreamElement( OUString::createFromAscii( IMAGELIST_XML_FILE[nImageType] ),
     472        1408 :                                                                                       ElementModes::READ );
     473           0 :             uno::Reference< XInputStream > xInputStream = xStream->getInputStream();
     474             : 
     475           0 :             ImageListsDescriptor aUserImageListInfo;
     476             :             ImagesConfiguration::LoadImages( m_xContext,
     477             :                                              xInputStream,
     478           0 :                                              aUserImageListInfo );
     479           0 :             if (( aUserImageListInfo.pImageList != 0 ) &&
     480           0 :                 ( !aUserImageListInfo.pImageList->empty() ))
     481             :             {
     482           0 :                 ImageListItemDescriptor* pList = &aUserImageListInfo.pImageList->front();
     483           0 :                 sal_Int32 nCount = pList->pImageItemList->size();
     484           0 :                 std::vector< OUString > aUserImagesVector;
     485           0 :                 aUserImagesVector.reserve(nCount);
     486           0 :                 for ( sal_uInt16 i=0; i < nCount; i++ )
     487             :                 {
     488           0 :                     const ImageItemDescriptor* pItem = &(*pList->pImageItemList)[i];
     489           0 :                     aUserImagesVector.push_back( pItem->aCommandURL );
     490             :                 }
     491             : 
     492           0 :                 uno::Reference< XStream > xBitmapStream = xUserBitmapsStorage->openStreamElement(
     493             :                                                         OUString::createFromAscii( BITMAP_FILE_NAMES[nImageType] ),
     494           0 :                                                         ElementModes::READ );
     495             : 
     496           0 :                 if ( xBitmapStream.is() )
     497             :                 {
     498           0 :                     SvStream* pSvStream( 0 );
     499           0 :                     BitmapEx aUserBitmap;
     500             :                     {
     501           0 :                         pSvStream = utl::UcbStreamHelper::CreateStream( xBitmapStream );
     502           0 :                         vcl::PNGReader aPngReader( *pSvStream );
     503           0 :                         aUserBitmap = aPngReader.Read();
     504             :                     }
     505           0 :                     delete pSvStream;
     506             : 
     507             :                     // Delete old image list and create a new one from the read bitmap
     508           0 :                     delete m_pUserImageList[nImageType];
     509           0 :                     m_pUserImageList[nImageType] = new ImageList();
     510           0 :                     m_pUserImageList[nImageType]->InsertFromHorizontalStrip
     511           0 :                         ( aUserBitmap, aUserImagesVector );
     512           0 :                     return true;
     513           0 :                 }
     514           0 :             }
     515             :         }
     516           0 :         catch ( const ::com::sun::star::container::NoSuchElementException& )
     517             :         {
     518             :         }
     519           0 :         catch ( const ::com::sun::star::embed::InvalidStorageException& )
     520             :         {
     521             :         }
     522           0 :         catch ( const ::com::sun::star::lang::IllegalArgumentException& )
     523             :         {
     524             :         }
     525         704 :         catch ( const ::com::sun::star::io::IOException& )
     526             :         {
     527             :         }
     528           0 :         catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
     529             :         {
     530             :         }
     531             :     }
     532             : 
     533             :     // Destroy old image list - create a new empty one
     534         704 :     delete m_pUserImageList[nImageType];
     535         704 :     m_pUserImageList[nImageType] = new ImageList;
     536             : 
     537         704 :     return true;
     538             : }
     539             : 
     540           0 : bool ImageManagerImpl::implts_storeUserImages(
     541             :     ImageType nImageType,
     542             :     const uno::Reference< XStorage >& xUserImageStorage,
     543             :     const uno::Reference< XStorage >& xUserBitmapsStorage )
     544             : {
     545           0 :     SolarMutexGuard g;
     546             : 
     547           0 :     if ( m_bModified )
     548             :     {
     549           0 :         ImageList* pImageList = implts_getUserImageList( nImageType );
     550           0 :         if ( pImageList->GetImageCount() > 0 )
     551             :         {
     552           0 :             ImageListsDescriptor aUserImageListInfo;
     553           0 :             aUserImageListInfo.pImageList = new ImageListDescriptor;
     554             : 
     555           0 :             ImageListItemDescriptor* pList = new ImageListItemDescriptor;
     556           0 :             aUserImageListInfo.pImageList->push_back( pList );
     557             : 
     558           0 :             pList->pImageItemList = new ImageItemListDescriptor;
     559           0 :             for ( sal_uInt16 i=0; i < pImageList->GetImageCount(); i++ )
     560             :             {
     561           0 :                 ImageItemDescriptor* pItem = new ::framework::ImageItemDescriptor;
     562             : 
     563           0 :                 pItem->nIndex = i;
     564           0 :                 pItem->aCommandURL = pImageList->GetImageName( i );
     565           0 :                 pList->pImageItemList->push_back( pItem );
     566             :             }
     567             : 
     568           0 :             pList->aURL = "Bitmaps/" + OUString::createFromAscii(BITMAP_FILE_NAMES[nImageType]);
     569             : 
     570           0 :             uno::Reference< XTransactedObject > xTransaction;
     571           0 :             uno::Reference< XOutputStream >     xOutputStream;
     572           0 :             uno::Reference< XStream > xStream = xUserImageStorage->openStreamElement( OUString::createFromAscii( IMAGELIST_XML_FILE[nImageType] ),
     573           0 :                                                                                       ElementModes::WRITE|ElementModes::TRUNCATE );
     574           0 :             if ( xStream.is() )
     575             :             {
     576             :                 uno::Reference< XStream > xBitmapStream =
     577           0 :                     xUserBitmapsStorage->openStreamElement( OUString::createFromAscii( BITMAP_FILE_NAMES[nImageType] ),
     578           0 :                                                             ElementModes::WRITE|ElementModes::TRUNCATE );
     579           0 :                 if ( xBitmapStream.is() )
     580             :                 {
     581           0 :                     SvStream* pSvStream = utl::UcbStreamHelper::CreateStream( xBitmapStream );
     582             :                     {
     583           0 :                         vcl::PNGWriter aPngWriter( pImageList->GetAsHorizontalStrip() );
     584           0 :                         aPngWriter.Write( *pSvStream );
     585             :                     }
     586           0 :                     delete pSvStream;
     587             : 
     588             :                     // Commit user bitmaps storage
     589           0 :                     xTransaction = uno::Reference< XTransactedObject >( xUserBitmapsStorage, UNO_QUERY );
     590           0 :                     if ( xTransaction.is() )
     591           0 :                         xTransaction->commit();
     592             :                 }
     593             : 
     594           0 :                 xOutputStream = xStream->getOutputStream();
     595           0 :                 if ( xOutputStream.is() )
     596           0 :                     ImagesConfiguration::StoreImages( m_xContext, xOutputStream, aUserImageListInfo );
     597             : 
     598             :                 // Commit user image storage
     599           0 :                 xTransaction = uno::Reference< XTransactedObject >( xUserImageStorage, UNO_QUERY );
     600           0 :                 if ( xTransaction.is() )
     601           0 :                     xTransaction->commit();
     602             :             }
     603             : 
     604           0 :             return true;
     605             :         }
     606             :         else
     607             :         {
     608             :             // Remove the streams from the storage, if we have no data. We have to catch
     609             :             // the NoSuchElementException as it can be possible that there is no stream at all!
     610             :             try
     611             :             {
     612           0 :                 xUserImageStorage->removeElement( OUString::createFromAscii( IMAGELIST_XML_FILE[nImageType] ));
     613             :             }
     614           0 :             catch ( const ::com::sun::star::container::NoSuchElementException& )
     615             :             {
     616             :             }
     617             : 
     618             :             try
     619             :             {
     620           0 :                 xUserBitmapsStorage->removeElement( OUString::createFromAscii( BITMAP_FILE_NAMES[nImageType] ));
     621             :             }
     622           0 :             catch ( const ::com::sun::star::container::NoSuchElementException& )
     623             :             {
     624             :             }
     625             : 
     626           0 :             uno::Reference< XTransactedObject > xTransaction;
     627             : 
     628             :             // Commit user image storage
     629           0 :             xTransaction = uno::Reference< XTransactedObject >( xUserImageStorage, UNO_QUERY );
     630           0 :             if ( xTransaction.is() )
     631           0 :                 xTransaction->commit();
     632             : 
     633             :             // Commit user bitmaps storage
     634           0 :             xTransaction = uno::Reference< XTransactedObject >( xUserBitmapsStorage, UNO_QUERY );
     635           0 :             if ( xTransaction.is() )
     636           0 :                 xTransaction->commit();
     637             : 
     638           0 :             return true;
     639             :         }
     640             :     }
     641             : 
     642           0 :     return false;
     643             : }
     644             : 
     645       19385 : const rtl::Reference< GlobalImageList >& ImageManagerImpl::implts_getGlobalImageList()
     646             : {
     647       19385 :     SolarMutexGuard g;
     648             : 
     649       19385 :     if ( !m_pGlobalImageList.is() )
     650          50 :         m_pGlobalImageList = getGlobalImageList( m_xContext );
     651       19385 :     return m_pGlobalImageList;
     652             : }
     653             : 
     654       19385 : CmdImageList* ImageManagerImpl::implts_getDefaultImageList()
     655             : {
     656       19385 :     SolarMutexGuard g;
     657             : 
     658       19385 :     if ( !m_pDefaultImageList )
     659          50 :         m_pDefaultImageList = new CmdImageList( m_xContext, m_aModuleIdentifier );
     660             : 
     661       19385 :     return m_pDefaultImageList;
     662             : }
     663             : 
     664        2116 : ImageManagerImpl::ImageManagerImpl( const uno::Reference< uno::XComponentContext >& rxContext,::cppu::OWeakObject* pOwner,bool _bUseGlobal ) :
     665             :     m_xContext( rxContext )
     666             :     , m_pOwner(pOwner)
     667             :     , m_pDefaultImageList( 0 )
     668             :     , m_aXMLPostfix( ".xml" )
     669             :     , m_aResourceString( ModuleImageList )
     670             :     , m_aListenerContainer( m_mutex )
     671             :     , m_bUseGlobal(_bUseGlobal)
     672             :     , m_bReadOnly( true )
     673             :     , m_bInitialized( false )
     674             :     , m_bModified( false )
     675             :     , m_bConfigRead( false )
     676        2116 :     , m_bDisposed( false )
     677             : {
     678        6348 :     for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
     679             :     {
     680        4232 :         m_pUserImageList[n] = 0;
     681        4232 :         m_bUserImageListModified[n] = false;
     682             :     }
     683        2116 : }
     684             : 
     685        4172 : ImageManagerImpl::~ImageManagerImpl()
     686             : {
     687        2086 :     clear();
     688        2086 : }
     689             : 
     690          85 : void ImageManagerImpl::dispose()
     691             : {
     692          85 :     uno::Reference< uno::XInterface > xOwner(static_cast< OWeakObject* >(m_pOwner));
     693         170 :     css::lang::EventObject aEvent( xOwner );
     694          85 :     m_aListenerContainer.disposeAndClear( aEvent );
     695             : 
     696             :     {
     697          85 :         SolarMutexGuard g;
     698          85 :         m_xUserConfigStorage.clear();
     699          85 :         m_xUserImageStorage.clear();
     700          85 :         m_xUserRootCommit.clear();
     701          85 :         m_bConfigRead = false;
     702          85 :         m_bModified = false;
     703          85 :         m_bDisposed = true;
     704             : 
     705             :         // delete user and default image list on dispose
     706         255 :         for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
     707             :         {
     708         170 :             delete m_pUserImageList[n];
     709         170 :             m_pUserImageList[n] = 0;
     710             :         }
     711          85 :         delete m_pDefaultImageList;
     712          85 :         m_pDefaultImageList = 0;
     713          85 :     }
     714             : 
     715          85 : }
     716           0 : void ImageManagerImpl::addEventListener( const uno::Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
     717             : {
     718             :     {
     719           0 :         SolarMutexGuard g;
     720             : 
     721             :         /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     722           0 :         if ( m_bDisposed )
     723           0 :             throw DisposedException();
     724             :     }
     725             : 
     726           0 :     m_aListenerContainer.addInterface( ::getCppuType( ( const uno::Reference< XEventListener >* ) NULL ), xListener );
     727           0 : }
     728             : 
     729           0 : void ImageManagerImpl::removeEventListener( const uno::Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
     730             : {
     731             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     732           0 :     m_aListenerContainer.removeInterface( ::getCppuType( ( const uno::Reference< XEventListener >* ) NULL ), xListener );
     733           0 : }
     734             : 
     735             : // XInitialization
     736        2115 : void ImageManagerImpl::initialize( const Sequence< Any >& aArguments )
     737             : {
     738        2115 :     SolarMutexGuard g;
     739             : 
     740        2115 :     if ( !m_bInitialized )
     741             :     {
     742        6430 :         for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
     743             :         {
     744        4315 :             PropertyValue aPropValue;
     745        4315 :             if ( aArguments[n] >>= aPropValue )
     746             :             {
     747        4315 :                 if ( aPropValue.Name == "UserConfigStorage" )
     748             :                 {
     749        2115 :                     aPropValue.Value >>= m_xUserConfigStorage;
     750             :                 }
     751        2200 :                 else if ( aPropValue.Name == "ModuleIdentifier" )
     752             :                 {
     753        2115 :                     aPropValue.Value >>= m_aModuleIdentifier;
     754             :                 }
     755          85 :                 else if ( aPropValue.Name == "UserRootCommit" )
     756             :                 {
     757          85 :                     aPropValue.Value >>= m_xUserRootCommit;
     758             :                 }
     759             :             }
     760        4315 :         }
     761             : 
     762        2115 :         if ( m_xUserConfigStorage.is() )
     763             :         {
     764        2097 :             uno::Reference< XPropertySet > xPropSet( m_xUserConfigStorage, UNO_QUERY );
     765        2097 :             if ( xPropSet.is() )
     766             :             {
     767        2097 :                 long nOpenMode = 0;
     768        2097 :                 if ( xPropSet->getPropertyValue("OpenMode") >>= nOpenMode )
     769        2097 :                     m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
     770        2097 :             }
     771             :         }
     772             : 
     773        2115 :         implts_initialize();
     774             : 
     775        2115 :         m_bInitialized = true;
     776        2115 :     }
     777        2115 : }
     778             : 
     779             : // XImageManagerImpl
     780           0 : void ImageManagerImpl::reset()
     781             : throw (::com::sun::star::uno::RuntimeException)
     782             : {
     783           0 :     SolarMutexGuard g;
     784             : 
     785             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     786           0 :     if ( m_bDisposed )
     787           0 :         throw DisposedException();
     788             : 
     789           0 :     std::vector< OUString > aUserImageNames;
     790             : 
     791           0 :     for ( sal_Int32 i = 0; i < ImageType_COUNT; i++ )
     792             :     {
     793           0 :         aUserImageNames.clear();
     794           0 :         ImageList* pImageList = implts_getUserImageList( ImageType(i));
     795           0 :         pImageList->GetImageNames( aUserImageNames );
     796             : 
     797           0 :         Sequence< OUString > aRemoveList( aUserImageNames.size() );
     798           0 :         const sal_uInt32 nCount = aUserImageNames.size();
     799           0 :         for ( sal_uInt32 j = 0; j < nCount; j++ )
     800           0 :             aRemoveList[j] = aUserImageNames[j];
     801             : 
     802             :         // Remove images
     803           0 :         removeImages( sal_Int16( i ), aRemoveList );
     804           0 :         m_bUserImageListModified[i] = true;
     805           0 :     }
     806             : 
     807           0 :     m_bModified = true;
     808           0 : }
     809             : 
     810           0 : Sequence< OUString > ImageManagerImpl::getAllImageNames( ::sal_Int16 nImageType )
     811             : throw (::com::sun::star::uno::RuntimeException)
     812             : {
     813           0 :     SolarMutexGuard g;
     814             : 
     815             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     816           0 :     if ( m_bDisposed )
     817           0 :         throw DisposedException();
     818             : 
     819           0 :     ImageNameMap aImageCmdNameMap;
     820             : 
     821           0 :     sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType );
     822             : 
     823           0 :     sal_uInt32 i( 0 );
     824           0 :     if ( m_bUseGlobal )
     825             :     {
     826           0 :         rtl::Reference< GlobalImageList > rGlobalImageList = implts_getGlobalImageList();
     827             : 
     828           0 :         const std::vector< OUString >& rGlobalImageNameVector = rGlobalImageList->getImageCommandNames();
     829           0 :         const sal_uInt32 nGlobalCount = rGlobalImageNameVector.size();
     830           0 :         for ( i = 0; i < nGlobalCount; i++ )
     831           0 :             aImageCmdNameMap.insert( ImageNameMap::value_type( rGlobalImageNameVector[i], sal_True ));
     832             : 
     833           0 :         const std::vector< OUString >& rModuleImageNameVector = implts_getDefaultImageList()->getImageCommandNames();
     834           0 :         const sal_uInt32 nModuleCount = rModuleImageNameVector.size();
     835           0 :         for ( i = 0; i < nModuleCount; i++ )
     836           0 :             aImageCmdNameMap.insert( ImageNameMap::value_type( rModuleImageNameVector[i], sal_True ));
     837             :     }
     838             : 
     839           0 :     ImageList* pImageList = implts_getUserImageList( ImageType( nIndex ));
     840           0 :     std::vector< OUString > rUserImageNames;
     841           0 :     pImageList->GetImageNames( rUserImageNames );
     842           0 :     const sal_uInt32 nUserCount = rUserImageNames.size();
     843           0 :     for ( i = 0; i < nUserCount; i++ )
     844           0 :         aImageCmdNameMap.insert( ImageNameMap::value_type( rUserImageNames[i], sal_True ));
     845             : 
     846           0 :     Sequence< OUString > aImageNameSeq( aImageCmdNameMap.size() );
     847           0 :     ImageNameMap::const_iterator pIter;
     848           0 :     i = 0;
     849           0 :     for ( pIter = aImageCmdNameMap.begin(); pIter != aImageCmdNameMap.end(); ++pIter )
     850           0 :         aImageNameSeq[i++] = pIter->first;
     851             : 
     852           0 :     return aImageNameSeq;
     853             : }
     854             : 
     855           0 : bool ImageManagerImpl::hasImage( ::sal_Int16 nImageType, const OUString& aCommandURL )
     856             : throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
     857             : {
     858           0 :     SolarMutexGuard g;
     859             : 
     860             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     861           0 :     if ( m_bDisposed )
     862           0 :         throw DisposedException();
     863             : 
     864           0 :     if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE ))
     865           0 :         throw IllegalArgumentException();
     866             : 
     867           0 :     sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType );
     868           0 :     if ( m_bUseGlobal && implts_getGlobalImageList()->hasImage( nIndex, aCommandURL ))
     869           0 :         return true;
     870             :     else
     871             :     {
     872           0 :         if ( m_bUseGlobal && implts_getDefaultImageList()->hasImage( nIndex, aCommandURL ))
     873           0 :             return true;
     874             :         else
     875             :         {
     876             :             // User layer
     877           0 :             ImageList* pImageList = implts_getUserImageList( ImageType( nIndex ));
     878           0 :             if ( pImageList )
     879           0 :                 return ( pImageList->GetImagePos( aCommandURL ) != IMAGELIST_IMAGE_NOTFOUND );
     880             :         }
     881             :     }
     882             : 
     883           0 :     return false;
     884             : }
     885             : 
     886       38308 : Sequence< uno::Reference< XGraphic > > ImageManagerImpl::getImages(
     887             :     ::sal_Int16 nImageType,
     888             :     const Sequence< OUString >& aCommandURLSequence )
     889             : throw ( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException )
     890             : {
     891       38308 :     SolarMutexGuard g;
     892             : 
     893             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     894       38308 :     if ( m_bDisposed )
     895           0 :         throw DisposedException();
     896             : 
     897       38308 :     if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE ))
     898           0 :         throw IllegalArgumentException();
     899             : 
     900       38308 :     Sequence< uno::Reference< XGraphic > > aGraphSeq( aCommandURLSequence.getLength() );
     901             : 
     902       38308 :     const OUString* aStrArray = aCommandURLSequence.getConstArray();
     903             : 
     904       38308 :     sal_Int16                         nIndex            = implts_convertImageTypeToIndex( nImageType );
     905       76616 :     rtl::Reference< GlobalImageList > rGlobalImageList;
     906       38308 :     CmdImageList*                     pDefaultImageList = NULL;
     907       38308 :     if ( m_bUseGlobal )
     908             :     {
     909       19385 :         rGlobalImageList  = implts_getGlobalImageList();
     910       19385 :         pDefaultImageList = implts_getDefaultImageList();
     911             :     }
     912       38308 :     ImageList*                        pUserImageList    = implts_getUserImageList( ImageType( nIndex ));
     913             : 
     914             :     // We have to search our image list in the following order:
     915             :     // 1. user image list (read/write)
     916             :     // 2. module image list (read)
     917             :     // 3. global image list (read)
     918      158938 :     for ( sal_Int32 n = 0; n < aCommandURLSequence.getLength(); n++ )
     919             :     {
     920      120632 :         Image aImage = pUserImageList->GetImage( aStrArray[n] );
     921      120632 :         if ( !aImage && m_bUseGlobal )
     922             :         {
     923       60854 :             aImage = pDefaultImageList->getImageFromCommandURL( nIndex, aStrArray[n] );
     924       60854 :             if ( !aImage )
     925       52131 :                 aImage = rGlobalImageList->getImageFromCommandURL( nIndex, aStrArray[n] );
     926             :         }
     927             : 
     928      120632 :         aGraphSeq[n] = aImage.GetXGraphic();
     929      120632 :     }
     930             : 
     931       76614 :     return aGraphSeq;
     932             : }
     933             : 
     934           0 : void ImageManagerImpl::replaceImages(
     935             :     ::sal_Int16 nImageType,
     936             :     const Sequence< OUString >& aCommandURLSequence,
     937             :     const Sequence< uno::Reference< XGraphic > >& aGraphicsSequence )
     938             : throw ( ::com::sun::star::lang::IllegalArgumentException,
     939             :         ::com::sun::star::lang::IllegalAccessException,
     940             :         ::com::sun::star::uno::RuntimeException)
     941             : {
     942           0 :     CmdToXGraphicNameAccess* pInsertedImages( 0 );
     943           0 :     CmdToXGraphicNameAccess* pReplacedImages( 0 );
     944             : 
     945             :     {
     946           0 :         SolarMutexGuard g;
     947             : 
     948             :         /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     949           0 :         if ( m_bDisposed )
     950           0 :             throw DisposedException();
     951             : 
     952           0 :         if (( aCommandURLSequence.getLength() != aGraphicsSequence.getLength() ) ||
     953           0 :             (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE )))
     954           0 :             throw IllegalArgumentException();
     955             : 
     956           0 :         if ( m_bReadOnly )
     957           0 :             throw IllegalAccessException();
     958             : 
     959           0 :         sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType );
     960           0 :         ImageList* pImageList = implts_getUserImageList( ImageType( nIndex ));
     961             : 
     962           0 :         uno::Reference< XGraphic > xGraphic;
     963           0 :         for ( sal_Int32 i = 0; i < aCommandURLSequence.getLength(); i++ )
     964             :         {
     965             :             // Check size and scale. If we don't have any graphics ignore it
     966           0 :             if ( !implts_checkAndScaleGraphic( xGraphic, aGraphicsSequence[i], nIndex ))
     967           0 :                 continue;
     968             : 
     969           0 :             sal_uInt16 nPos = pImageList->GetImagePos( aCommandURLSequence[i] );
     970           0 :             if ( nPos == IMAGELIST_IMAGE_NOTFOUND )
     971             :             {
     972           0 :                 pImageList->AddImage(aCommandURLSequence[i], Image(xGraphic));
     973           0 :                 if ( !pInsertedImages )
     974           0 :                     pInsertedImages = new CmdToXGraphicNameAccess();
     975           0 :                 pInsertedImages->addElement( aCommandURLSequence[i], xGraphic );
     976             :             }
     977             :             else
     978             :             {
     979           0 :                 pImageList->ReplaceImage(aCommandURLSequence[i], Image(xGraphic));
     980           0 :                 if ( !pReplacedImages )
     981           0 :                     pReplacedImages = new CmdToXGraphicNameAccess();
     982           0 :                 pReplacedImages->addElement( aCommandURLSequence[i], xGraphic );
     983             :             }
     984             :         }
     985             : 
     986           0 :         if (( pInsertedImages != 0 ) || (  pReplacedImages != 0 ))
     987             :         {
     988           0 :             m_bModified = true;
     989           0 :             m_bUserImageListModified[nIndex] = true;
     990           0 :         }
     991             :     }
     992             : 
     993           0 :     uno::Reference< uno::XInterface > xOwner(static_cast< OWeakObject* >(m_pOwner));
     994             :     // Notify listeners
     995           0 :     if ( pInsertedImages != 0 )
     996             :     {
     997           0 :         ConfigurationEvent aInsertEvent;
     998           0 :         aInsertEvent.aInfo           <<= nImageType;
     999           0 :         aInsertEvent.Accessor        <<= xOwner;
    1000           0 :         aInsertEvent.Source          = xOwner;
    1001           0 :         aInsertEvent.ResourceURL     = m_aResourceString;
    1002           0 :         aInsertEvent.Element         = uno::makeAny( uno::Reference< XNameAccess >(
    1003           0 :                                         static_cast< OWeakObject *>( pInsertedImages ), UNO_QUERY ));
    1004           0 :         implts_notifyContainerListener( aInsertEvent, NotifyOp_Insert );
    1005             :     }
    1006           0 :     if ( pReplacedImages != 0 )
    1007             :     {
    1008           0 :         ConfigurationEvent aReplaceEvent;
    1009           0 :         aReplaceEvent.aInfo           <<= nImageType;
    1010           0 :         aReplaceEvent.Accessor        <<= xOwner;
    1011           0 :         aReplaceEvent.Source          = xOwner;
    1012           0 :         aReplaceEvent.ResourceURL     = m_aResourceString;
    1013           0 :         aReplaceEvent.ReplacedElement = Any();
    1014           0 :         aReplaceEvent.Element         = uno::makeAny( uno::Reference< XNameAccess >(
    1015           0 :                                             static_cast< OWeakObject *>( pReplacedImages ), UNO_QUERY ));
    1016           0 :         implts_notifyContainerListener( aReplaceEvent, NotifyOp_Replace );
    1017           0 :     }
    1018           0 : }
    1019             : 
    1020           0 : void ImageManagerImpl::removeImages( ::sal_Int16 nImageType, const Sequence< OUString >& aCommandURLSequence )
    1021             : throw ( ::com::sun::star::lang::IllegalArgumentException,
    1022             :         ::com::sun::star::lang::IllegalAccessException,
    1023             :         ::com::sun::star::uno::RuntimeException)
    1024             : {
    1025           0 :     CmdToXGraphicNameAccess* pRemovedImages( 0 );
    1026           0 :     CmdToXGraphicNameAccess* pReplacedImages( 0 );
    1027             : 
    1028             :     {
    1029           0 :         SolarMutexGuard g;
    1030             : 
    1031             :         /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    1032           0 :         if ( m_bDisposed )
    1033           0 :             throw DisposedException();
    1034             : 
    1035           0 :         if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE ))
    1036           0 :             throw IllegalArgumentException();
    1037             : 
    1038           0 :         if ( m_bReadOnly )
    1039           0 :             throw IllegalAccessException();
    1040             : 
    1041           0 :         sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType );
    1042           0 :         rtl::Reference< GlobalImageList > rGlobalImageList;
    1043           0 :         CmdImageList*                     pDefaultImageList = NULL;
    1044           0 :         if ( m_bUseGlobal )
    1045             :         {
    1046           0 :             rGlobalImageList  = implts_getGlobalImageList();
    1047           0 :             pDefaultImageList = implts_getDefaultImageList();
    1048             :         }
    1049           0 :         ImageList*                        pImageList        = implts_getUserImageList( ImageType( nIndex ));
    1050           0 :         uno::Reference< XGraphic >        xEmptyGraphic( Image().GetXGraphic() );
    1051             : 
    1052           0 :         for ( sal_Int32 i = 0; i < aCommandURLSequence.getLength(); i++ )
    1053             :         {
    1054           0 :             sal_uInt16 nPos = pImageList->GetImagePos( aCommandURLSequence[i] );
    1055           0 :             if ( nPos != IMAGELIST_IMAGE_NOTFOUND )
    1056             :             {
    1057           0 :                 Image aImage = pImageList->GetImage( nPos );
    1058           0 :                 sal_uInt16 nId   = pImageList->GetImageId( nPos );
    1059           0 :                 pImageList->RemoveImage( nId );
    1060             : 
    1061           0 :                 if ( m_bUseGlobal )
    1062             :                 {
    1063             :                     // Check, if we have a image in our module/global image list. If we find one =>
    1064             :                     // this is a replace instead of a remove operation!
    1065           0 :                     Image aNewImage = pDefaultImageList->getImageFromCommandURL( nIndex, aCommandURLSequence[i] );
    1066           0 :                     if ( !aNewImage )
    1067           0 :                         aNewImage = rGlobalImageList->getImageFromCommandURL( nIndex, aCommandURLSequence[i] );
    1068           0 :                     if ( !aNewImage )
    1069             :                     {
    1070           0 :                         if ( !pRemovedImages )
    1071           0 :                             pRemovedImages = new CmdToXGraphicNameAccess();
    1072           0 :                         pRemovedImages->addElement( aCommandURLSequence[i], xEmptyGraphic );
    1073             :                     }
    1074             :                     else
    1075             :                     {
    1076           0 :                         if ( !pReplacedImages )
    1077           0 :                             pReplacedImages = new CmdToXGraphicNameAccess();
    1078           0 :                         pReplacedImages->addElement( aCommandURLSequence[i], aNewImage.GetXGraphic() );
    1079           0 :                     }
    1080             :                 } // if ( m_bUseGlobal )
    1081             :                 else
    1082             :                 {
    1083           0 :                     if ( !pRemovedImages )
    1084           0 :                         pRemovedImages = new CmdToXGraphicNameAccess();
    1085           0 :                     pRemovedImages->addElement( aCommandURLSequence[i], xEmptyGraphic );
    1086           0 :                 }
    1087             :             }
    1088             :         }
    1089             : 
    1090           0 :         if (( pReplacedImages != 0 ) || ( pRemovedImages != 0 ))
    1091             :         {
    1092           0 :             m_bModified = true;
    1093           0 :             m_bUserImageListModified[nIndex] = true;
    1094           0 :         }
    1095             :     }
    1096             : 
    1097             :     // Notify listeners
    1098           0 :     uno::Reference< uno::XInterface > xOwner(static_cast< OWeakObject* >(m_pOwner));
    1099           0 :     if ( pRemovedImages != 0 )
    1100             :     {
    1101           0 :         ConfigurationEvent aRemoveEvent;
    1102           0 :         aRemoveEvent.aInfo           = uno::makeAny( nImageType );
    1103           0 :         aRemoveEvent.Accessor        = uno::makeAny( xOwner );
    1104           0 :         aRemoveEvent.Source          = xOwner;
    1105           0 :         aRemoveEvent.ResourceURL     = m_aResourceString;
    1106           0 :         aRemoveEvent.Element         = uno::makeAny( uno::Reference< XNameAccess >(
    1107           0 :                                             static_cast< OWeakObject *>( pRemovedImages ), UNO_QUERY ));
    1108           0 :         implts_notifyContainerListener( aRemoveEvent, NotifyOp_Remove );
    1109             :     }
    1110           0 :     if ( pReplacedImages != 0 )
    1111             :     {
    1112           0 :         ConfigurationEvent aReplaceEvent;
    1113           0 :         aReplaceEvent.aInfo           = uno::makeAny( nImageType );
    1114           0 :         aReplaceEvent.Accessor        = uno::makeAny( xOwner );
    1115           0 :         aReplaceEvent.Source          = xOwner;
    1116           0 :         aReplaceEvent.ResourceURL     = m_aResourceString;
    1117           0 :         aReplaceEvent.ReplacedElement = Any();
    1118           0 :         aReplaceEvent.Element         = uno::makeAny( uno::Reference< XNameAccess >(
    1119           0 :                                             static_cast< OWeakObject *>( pReplacedImages ), UNO_QUERY ));
    1120           0 :         implts_notifyContainerListener( aReplaceEvent, NotifyOp_Replace );
    1121           0 :     }
    1122           0 : }
    1123             : 
    1124           0 : void ImageManagerImpl::insertImages( ::sal_Int16 nImageType, const Sequence< OUString >& aCommandURLSequence, const Sequence< uno::Reference< XGraphic > >& aGraphicSequence )
    1125             : throw ( ::com::sun::star::container::ElementExistException,
    1126             :         ::com::sun::star::lang::IllegalArgumentException,
    1127             :         ::com::sun::star::lang::IllegalAccessException,
    1128             :         ::com::sun::star::uno::RuntimeException)
    1129             : {
    1130           0 :     replaceImages(nImageType,aCommandURLSequence,aGraphicSequence);
    1131           0 : }
    1132             : 
    1133             : // XUIConfigurationPersistence
    1134           0 : void ImageManagerImpl::reload()
    1135             : throw ( ::com::sun::star::uno::Exception,
    1136             :         ::com::sun::star::uno::RuntimeException )
    1137             : {
    1138           0 :     SolarMutexClearableGuard aGuard;
    1139             : 
    1140           0 :     if ( m_bDisposed )
    1141           0 :         throw DisposedException();
    1142             : 
    1143           0 :     CommandMap                   aOldUserCmdImageSet;
    1144           0 :     std::vector< OUString > aNewUserCmdImageSet;
    1145             : 
    1146           0 :     if ( m_bModified )
    1147             :     {
    1148           0 :         for ( sal_Int16 i = 0; i < sal_Int16( ImageType_COUNT ); i++ )
    1149             :         {
    1150           0 :             if ( !m_bDisposed && m_bUserImageListModified[i] )
    1151             :             {
    1152           0 :                 std::vector< OUString > aOldUserCmdImageVector;
    1153           0 :                 ImageList* pImageList = implts_getUserImageList( (ImageType)i );
    1154           0 :                 pImageList->GetImageNames( aOldUserCmdImageVector );
    1155             : 
    1156             :                 // Fill hash map to speed up search afterwards
    1157           0 :                 sal_uInt32 j( 0 );
    1158           0 :                 const sal_uInt32 nOldCount = aOldUserCmdImageVector.size();
    1159           0 :                 for ( j = 0; j < nOldCount; j++ )
    1160           0 :                     aOldUserCmdImageSet.insert( CommandMap::value_type( aOldUserCmdImageVector[j], false ));
    1161             : 
    1162             :                 // Attention: This can make the old image list pointer invalid!
    1163           0 :                 implts_loadUserImages( (ImageType)i, m_xUserImageStorage, m_xUserBitmapsStorage );
    1164           0 :                 pImageList = implts_getUserImageList( (ImageType)i );
    1165           0 :                 pImageList->GetImageNames( aNewUserCmdImageSet );
    1166             : 
    1167           0 :                 CmdToXGraphicNameAccess* pInsertedImages( 0 );
    1168           0 :                 CmdToXGraphicNameAccess* pReplacedImages( 0 );
    1169           0 :                 CmdToXGraphicNameAccess* pRemovedImages( 0 );
    1170             : 
    1171           0 :                 const sal_uInt32 nNewCount = aNewUserCmdImageSet.size();
    1172           0 :                 for ( j = 0; j < nNewCount; j++ )
    1173             :                 {
    1174           0 :                     CommandMap::iterator pIter = aOldUserCmdImageSet.find( aNewUserCmdImageSet[j] );
    1175           0 :                     if ( pIter != aOldUserCmdImageSet.end() )
    1176             :                     {
    1177           0 :                         pIter->second = true; // mark entry as replaced
    1178           0 :                         if ( !pReplacedImages )
    1179           0 :                             pReplacedImages = new CmdToXGraphicNameAccess();
    1180           0 :                         pReplacedImages->addElement( aNewUserCmdImageSet[j],
    1181           0 :                                                      pImageList->GetImage( aNewUserCmdImageSet[j] ).GetXGraphic() );
    1182             :                     }
    1183             :                     else
    1184             :                     {
    1185           0 :                         if ( !pInsertedImages )
    1186           0 :                             pInsertedImages = new CmdToXGraphicNameAccess();
    1187           0 :                         pInsertedImages->addElement( aNewUserCmdImageSet[j],
    1188           0 :                                                      pImageList->GetImage( aNewUserCmdImageSet[j] ).GetXGraphic() );
    1189             :                     }
    1190             :                 }
    1191             : 
    1192             :                 // Search map for unmarked entries => they have been removed from the user list
    1193             :                 // through this reload operation.
    1194             :                 // We have to search the module and global image list!
    1195           0 :                 rtl::Reference< GlobalImageList > rGlobalImageList;
    1196           0 :                 CmdImageList*                     pDefaultImageList = NULL;
    1197           0 :                 if ( m_bUseGlobal )
    1198             :                 {
    1199           0 :                     rGlobalImageList  = implts_getGlobalImageList();
    1200           0 :                     pDefaultImageList = implts_getDefaultImageList();
    1201             :                 }
    1202           0 :                 uno::Reference< XGraphic >        xEmptyGraphic( Image().GetXGraphic() );
    1203           0 :                 CommandMap::const_iterator        pIter = aOldUserCmdImageSet.begin();
    1204           0 :                 while ( pIter != aOldUserCmdImageSet.end() )
    1205             :                 {
    1206           0 :                     if ( !pIter->second )
    1207             :                     {
    1208           0 :                         if ( m_bUseGlobal )
    1209             :                         {
    1210           0 :                             Image aImage = pDefaultImageList->getImageFromCommandURL( i, pIter->first );
    1211           0 :                             if ( !aImage )
    1212           0 :                                 aImage = rGlobalImageList->getImageFromCommandURL( i, pIter->first );
    1213             : 
    1214           0 :                             if ( !aImage )
    1215             :                             {
    1216             :                                 // No image in the module/global image list => remove user image
    1217           0 :                                 if ( !pRemovedImages )
    1218           0 :                                     pRemovedImages = new CmdToXGraphicNameAccess();
    1219           0 :                                 pRemovedImages->addElement( pIter->first, xEmptyGraphic );
    1220             :                             }
    1221             :                             else
    1222             :                             {
    1223             :                                 // Image has been found in the module/global image list => replace user image
    1224           0 :                                 if ( !pReplacedImages )
    1225           0 :                                     pReplacedImages = new CmdToXGraphicNameAccess();
    1226           0 :                                 pReplacedImages->addElement( pIter->first, aImage.GetXGraphic() );
    1227           0 :                             }
    1228             :                         } // if ( m_bUseGlobal )
    1229             :                         else
    1230             :                         {
    1231             :                             // No image in the user image list => remove user image
    1232           0 :                             if ( !pRemovedImages )
    1233           0 :                                 pRemovedImages = new CmdToXGraphicNameAccess();
    1234           0 :                             pRemovedImages->addElement( pIter->first, xEmptyGraphic );
    1235             :                         }
    1236             :                     }
    1237           0 :                     ++pIter;
    1238             :                 }
    1239             : 
    1240           0 :                 aGuard.clear();
    1241             : 
    1242             :                 // Now notify our listeners. Unlock mutex to prevent deadlocks
    1243           0 :                 uno::Reference< uno::XInterface > xOwner(static_cast< OWeakObject* >(m_pOwner));
    1244           0 :                 if ( pInsertedImages != 0 )
    1245             :                 {
    1246           0 :                     ConfigurationEvent aInsertEvent;
    1247           0 :                     aInsertEvent.aInfo           = uno::makeAny( i );
    1248           0 :                     aInsertEvent.Accessor        = uno::makeAny( xOwner );
    1249           0 :                     aInsertEvent.Source          = xOwner;
    1250           0 :                     aInsertEvent.ResourceURL     = m_aResourceString;
    1251           0 :                     aInsertEvent.Element         = uno::makeAny( uno::Reference< XNameAccess >(
    1252           0 :                                                     static_cast< OWeakObject *>( pInsertedImages ), UNO_QUERY ));
    1253           0 :                     implts_notifyContainerListener( aInsertEvent, NotifyOp_Insert );
    1254             :                 }
    1255           0 :                 if ( pReplacedImages != 0 )
    1256             :                 {
    1257           0 :                     ConfigurationEvent aReplaceEvent;
    1258           0 :                     aReplaceEvent.aInfo           = uno::makeAny( i );
    1259           0 :                     aReplaceEvent.Accessor        = uno::makeAny( xOwner );
    1260           0 :                     aReplaceEvent.Source          = xOwner;
    1261           0 :                     aReplaceEvent.ResourceURL     = m_aResourceString;
    1262           0 :                     aReplaceEvent.ReplacedElement = Any();
    1263           0 :                     aReplaceEvent.Element         = uno::makeAny( uno::Reference< XNameAccess >(
    1264           0 :                                                     static_cast< OWeakObject *>( pReplacedImages ), UNO_QUERY ));
    1265           0 :                     implts_notifyContainerListener( aReplaceEvent, NotifyOp_Replace );
    1266             :                 }
    1267           0 :                 if ( pRemovedImages != 0 )
    1268             :                 {
    1269           0 :                     ConfigurationEvent aRemoveEvent;
    1270           0 :                     aRemoveEvent.aInfo           = uno::makeAny( i );
    1271           0 :                     aRemoveEvent.Accessor        = uno::makeAny( xOwner );
    1272           0 :                     aRemoveEvent.Source          = xOwner;
    1273           0 :                     aRemoveEvent.ResourceURL     = m_aResourceString;
    1274           0 :                     aRemoveEvent.Element         = uno::makeAny( uno::Reference< XNameAccess >(
    1275           0 :                                                         static_cast< OWeakObject *>( pRemovedImages ), UNO_QUERY ));
    1276           0 :                     implts_notifyContainerListener( aRemoveEvent, NotifyOp_Remove );
    1277             :                 }
    1278             : 
    1279           0 :                 aGuard.clear();
    1280             :             }
    1281             :         }
    1282           0 :     }
    1283           0 : }
    1284             : 
    1285           0 : void ImageManagerImpl::store()
    1286             :     throw (::com::sun::star::uno::Exception,
    1287             :            ::com::sun::star::uno::RuntimeException,
    1288             :            std::exception)
    1289             : {
    1290           0 :     SolarMutexGuard g;
    1291             : 
    1292           0 :     if ( m_bDisposed )
    1293           0 :         throw DisposedException();
    1294             : 
    1295           0 :     if ( m_bModified )
    1296             :     {
    1297           0 :         bool bWritten( false );
    1298           0 :         for ( sal_Int32 i = 0; i < ImageType_COUNT; i++ )
    1299             :         {
    1300           0 :             bool bSuccess = implts_storeUserImages( ImageType(i), m_xUserImageStorage, m_xUserBitmapsStorage );
    1301           0 :             if ( bSuccess )
    1302           0 :                 bWritten = true;
    1303           0 :             m_bUserImageListModified[i] = false;
    1304             :         }
    1305             : 
    1306           0 :         if ( bWritten &&
    1307           0 :              m_xUserConfigStorage.is() )
    1308             :         {
    1309           0 :             uno::Reference< XTransactedObject > xUserConfigStorageCommit( m_xUserConfigStorage, UNO_QUERY );
    1310           0 :             if ( xUserConfigStorageCommit.is() )
    1311           0 :                 xUserConfigStorageCommit->commit();
    1312           0 :             if ( m_xUserRootCommit.is() )
    1313           0 :                 m_xUserRootCommit->commit();
    1314             :         }
    1315             : 
    1316           0 :         m_bModified = false;
    1317           0 :     }
    1318           0 : }
    1319             : 
    1320           0 : void ImageManagerImpl::storeToStorage( const uno::Reference< XStorage >& Storage )
    1321             :     throw (::com::sun::star::uno::Exception,
    1322             :            ::com::sun::star::uno::RuntimeException,
    1323             :            std::exception)
    1324             : {
    1325           0 :     SolarMutexGuard g;
    1326             : 
    1327           0 :     if ( m_bDisposed )
    1328           0 :         throw DisposedException();
    1329             : 
    1330           0 :     if ( m_bModified && Storage.is() )
    1331             :     {
    1332           0 :         long nModes = ElementModes::READWRITE;
    1333             : 
    1334           0 :         uno::Reference< XStorage > xUserImageStorage = Storage->openStorageElement( OUString(IMAGE_FOLDER ),
    1335           0 :                                                                                     nModes );
    1336           0 :         if ( xUserImageStorage.is() )
    1337             :         {
    1338           0 :             uno::Reference< XStorage > xUserBitmapsStorage = xUserImageStorage->openStorageElement( OUString(BITMAPS_FOLDER ),
    1339           0 :                                                                                                     nModes );
    1340           0 :             for ( sal_Int32 i = 0; i < ImageType_COUNT; i++ )
    1341             :             {
    1342           0 :                 implts_getUserImageList( (ImageType)i );
    1343           0 :                 implts_storeUserImages( (ImageType)i, xUserImageStorage, xUserBitmapsStorage );
    1344             :             }
    1345             : 
    1346           0 :             uno::Reference< XTransactedObject > xTransaction( Storage, UNO_QUERY );
    1347           0 :             if ( xTransaction.is() )
    1348           0 :                 xTransaction->commit();
    1349           0 :         }
    1350           0 :     }
    1351           0 : }
    1352             : 
    1353           0 : bool ImageManagerImpl::isModified()
    1354             : throw (::com::sun::star::uno::RuntimeException)
    1355             : {
    1356           0 :     SolarMutexGuard g;
    1357           0 :     return m_bModified;
    1358             : }
    1359             : 
    1360           0 : bool ImageManagerImpl::isReadOnly() throw (::com::sun::star::uno::RuntimeException)
    1361             : {
    1362           0 :     SolarMutexGuard g;
    1363           0 :     return m_bReadOnly;
    1364             : }
    1365             : // XUIConfiguration
    1366       56569 : void ImageManagerImpl::addConfigurationListener( const uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener )
    1367             : throw (::com::sun::star::uno::RuntimeException)
    1368             : {
    1369             :     {
    1370       56569 :         SolarMutexGuard g;
    1371             : 
    1372             :         /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    1373       56569 :         if ( m_bDisposed )
    1374           0 :             throw DisposedException();
    1375             :     }
    1376             : 
    1377       56569 :     m_aListenerContainer.addInterface( ::getCppuType( ( const uno::Reference< XUIConfigurationListener >* ) NULL ), xListener );
    1378       56569 : }
    1379             : 
    1380       56553 : void ImageManagerImpl::removeConfigurationListener( const uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener )
    1381             : throw (::com::sun::star::uno::RuntimeException)
    1382             : {
    1383             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    1384       56553 :     m_aListenerContainer.removeInterface( ::getCppuType( ( const uno::Reference< XUIConfigurationListener >* ) NULL ), xListener );
    1385       56553 : }
    1386             : 
    1387           0 : void ImageManagerImpl::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp )
    1388             : {
    1389             :     ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer(
    1390           0 :                                         ::getCppuType( ( const css::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >*) NULL ) );
    1391           0 :     if ( pContainer != NULL )
    1392             :     {
    1393           0 :         ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
    1394           0 :         while ( pIterator.hasMoreElements() )
    1395             :         {
    1396             :             try
    1397             :             {
    1398           0 :                 switch ( eOp )
    1399             :                 {
    1400             :                     case NotifyOp_Replace:
    1401           0 :                         ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementReplaced( aEvent );
    1402           0 :                         break;
    1403             :                     case NotifyOp_Insert:
    1404           0 :                         ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementInserted( aEvent );
    1405           0 :                         break;
    1406             :                     case NotifyOp_Remove:
    1407           0 :                         ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementRemoved( aEvent );
    1408           0 :                         break;
    1409             :                 }
    1410             :             }
    1411           0 :             catch( const css::uno::RuntimeException& )
    1412             :             {
    1413           0 :                 pIterator.remove();
    1414             :             }
    1415           0 :         }
    1416             :     }
    1417           0 : }
    1418        4087 : void ImageManagerImpl::clear()
    1419             : {
    1420        4087 :     SolarMutexGuard g;
    1421             : 
    1422       12261 :     for ( sal_Int32 n = 0; n < ImageType_COUNT; n++ )
    1423             :     {
    1424        8174 :         delete m_pUserImageList[n];
    1425        8174 :         m_pUserImageList[n] = 0;
    1426        4087 :     }
    1427        4087 : }
    1428             : } // namespace framework
    1429             : 
    1430             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10