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