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