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