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