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