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 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 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 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 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 188 CmdImageList::~CmdImageList() 189 { 190 for ( sal_Int32 n=0; n < ImageType_COUNT; n++ ) 191 delete m_pImageList[n]; 192 } 193 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 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 309 std::vector< ::rtl::OUString >& CmdImageList::impl_getImageNameVector() 310 { 311 return m_aImageNameVector; 312 } 313 314 std::vector< rtl::OUString >& CmdImageList::impl_getImageCommandNameVector() 315 { 316 return m_aImageCommandNameVector; 317 } 318 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 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 342 ::std::vector< rtl::OUString >& CmdImageList::getImageNames() 343 { 344 return impl_getImageNameVector(); 345 } 346 347 ::std::vector< rtl::OUString >& CmdImageList::getImageCommandNames() 348 { 349 return impl_getImageCommandNameVector(); 350 } 351 352 //_________________________________________________________________________________________________________________ 353 354 GlobalImageList::GlobalImageList( const uno::Reference< XMultiServiceFactory >& rServiceManager ) : 355 CmdImageList( rServiceManager, rtl::OUString() ), 356 m_nRefCount( 0 ) 357 { 358 } 359 360 GlobalImageList::~GlobalImageList() 361 { 362 } 363 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 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 376 ::std::vector< rtl::OUString >& GlobalImageList::getImageNames() 377 { 378 osl::MutexGuard guard( getGlobalImageListMutex() ); 379 return impl_getImageNameVector(); 380 } 381 382 ::std::vector< rtl::OUString >& GlobalImageList::getImageCommandNames() 383 { 384 osl::MutexGuard guard( getGlobalImageListMutex() ); 385 return impl_getImageCommandNameVector(); 386 } 387 388 oslInterlockedCount GlobalImageList::acquire() 389 { 390 osl_incrementInterlockedCount( &m_nRefCount ); 391 return m_nRefCount; 392 } 393 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 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 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 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 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 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 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 } 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 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 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 724 ImageManagerImpl::~ImageManagerImpl() 725 { 726 clear(); 727 } 728 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 } 754 void ImageManagerImpl::addEventListener( const uno::Reference< XEventListener >& xListener ) 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 767 void ImageManagerImpl::removeEventListener( const uno::Reference< XEventListener >& xListener ) 768 { 769 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 770 m_aListenerContainer.removeInterface( ::getCppuType( ( const uno::Reference< XEventListener >* ) NULL ), xListener ); 771 } 772 773 // XInitialization 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 818 void ImageManagerImpl::reset() 819 { 820 ResetableGuard aLock( m_aLock ); 821 822 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 823 if ( m_bDisposed ) 824 throw DisposedException(); 825 826 std::vector< OUString > aUserImageNames; 827 828 for ( sal_Int32 i = 0; i < ImageType_COUNT; i++ ) 829 { 830 aUserImageNames.clear(); 831 ImageList* pImageList = implts_getUserImageList( ImageType(i)); 832 pImageList->GetImageNames( aUserImageNames ); 833 834 Sequence< rtl::OUString > aRemoveList( aUserImageNames.size() ); 835 const sal_uInt32 nCount = aUserImageNames.size(); 836 for ( sal_uInt32 j = 0; j < nCount; j++ ) 837 aRemoveList[j] = aUserImageNames[j]; 838 839 // Remove images 840 removeImages( sal_Int16( i ), aRemoveList ); 841 m_bUserImageListModified[i] = true; 842 } 843 844 m_bModified = sal_True; 845 } 846 847 Sequence< ::rtl::OUString > ImageManagerImpl::getAllImageNames( ::sal_Int16 nImageType ) 848 { 849 ResetableGuard aLock( m_aLock ); 850 851 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 852 if ( m_bDisposed ) 853 throw DisposedException(); 854 855 ImageNameMap aImageCmdNameMap; 856 857 sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType ); 858 859 sal_uInt32 i( 0 ); 860 if ( m_bUseGlobal ) 861 { 862 rtl::Reference< GlobalImageList > rGlobalImageList = implts_getGlobalImageList(); 863 864 const std::vector< OUString >& rGlobalImageNameVector = rGlobalImageList->getImageCommandNames(); 865 const sal_uInt32 nGlobalCount = rGlobalImageNameVector.size(); 866 for ( i = 0; i < nGlobalCount; i++ ) 867 aImageCmdNameMap.insert( ImageNameMap::value_type( rGlobalImageNameVector[i], sal_True )); 868 869 const std::vector< OUString >& rModuleImageNameVector = implts_getDefaultImageList()->getImageCommandNames(); 870 const sal_uInt32 nModuleCount = rModuleImageNameVector.size(); 871 for ( i = 0; i < nModuleCount; i++ ) 872 aImageCmdNameMap.insert( ImageNameMap::value_type( rModuleImageNameVector[i], sal_True )); 873 } 874 875 ImageList* pImageList = implts_getUserImageList( ImageType( nIndex )); 876 std::vector< OUString > rUserImageNames; 877 pImageList->GetImageNames( rUserImageNames ); 878 const sal_uInt32 nUserCount = rUserImageNames.size(); 879 for ( i = 0; i < nUserCount; i++ ) 880 aImageCmdNameMap.insert( ImageNameMap::value_type( rUserImageNames[i], sal_True )); 881 882 Sequence< OUString > aImageNameSeq( aImageCmdNameMap.size() ); 883 ImageNameMap::const_iterator pIter; 884 i = 0; 885 for ( pIter = aImageCmdNameMap.begin(); pIter != aImageCmdNameMap.end(); pIter++ ) 886 aImageNameSeq[i++] = pIter->first; 887 888 return aImageNameSeq; 889 } 890 891 ::sal_Bool ImageManagerImpl::hasImage( ::sal_Int16 nImageType, const ::rtl::OUString& aCommandURL ) 892 { 893 ResetableGuard aLock( m_aLock ); 894 895 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 896 if ( m_bDisposed ) 897 throw DisposedException(); 898 899 if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE )) 900 throw IllegalArgumentException(); 901 902 sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType ); 903 if ( m_bUseGlobal && implts_getGlobalImageList()->hasImage( nIndex, aCommandURL )) 904 return sal_True; 905 else 906 { 907 if ( m_bUseGlobal && implts_getDefaultImageList()->hasImage( nIndex, aCommandURL )) 908 return sal_True; 909 else 910 { 911 // User layer 912 ImageList* pImageList = implts_getUserImageList( ImageType( nIndex )); 913 if ( pImageList ) 914 return ( pImageList->GetImagePos( aCommandURL ) != IMAGELIST_IMAGE_NOTFOUND ); 915 } 916 } 917 918 return sal_False; 919 } 920 921 Sequence< uno::Reference< XGraphic > > ImageManagerImpl::getImages( 922 ::sal_Int16 nImageType, 923 const Sequence< ::rtl::OUString >& aCommandURLSequence ) 924 { 925 ResetableGuard aLock( m_aLock ); 926 927 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 928 if ( m_bDisposed ) 929 throw DisposedException(); 930 931 if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE )) 932 throw IllegalArgumentException(); 933 934 Sequence< uno::Reference< XGraphic > > aGraphSeq( aCommandURLSequence.getLength() ); 935 936 const rtl::OUString* aStrArray = aCommandURLSequence.getConstArray(); 937 938 sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType ); 939 rtl::Reference< GlobalImageList > rGlobalImageList; 940 CmdImageList* pDefaultImageList = NULL; 941 if ( m_bUseGlobal ) 942 { 943 rGlobalImageList = implts_getGlobalImageList(); 944 pDefaultImageList = implts_getDefaultImageList(); 945 } 946 ImageList* pUserImageList = implts_getUserImageList( ImageType( nIndex )); 947 948 // We have to search our image list in the following order: 949 // 1. user image list (read/write) 950 // 2. module image list (read) 951 // 3. global image list (read) 952 for ( sal_Int32 n = 0; n < aCommandURLSequence.getLength(); n++ ) 953 { 954 Image aImage = pUserImageList->GetImage( aStrArray[n] ); 955 if ( !aImage && m_bUseGlobal ) 956 { 957 aImage = pDefaultImageList->getImageFromCommandURL( nIndex, aStrArray[n] ); 958 if ( !aImage ) 959 aImage = rGlobalImageList->getImageFromCommandURL( nIndex, aStrArray[n] ); 960 } 961 962 aGraphSeq[n] = aImage.GetXGraphic(); 963 } 964 965 return aGraphSeq; 966 } 967 968 void ImageManagerImpl::replaceImages( 969 ::sal_Int16 nImageType, 970 const Sequence< ::rtl::OUString >& aCommandURLSequence, 971 const Sequence< uno::Reference< XGraphic > >& aGraphicsSequence ) 972 { 973 CmdToXGraphicNameAccess* pInsertedImages( 0 ); 974 CmdToXGraphicNameAccess* pReplacedImages( 0 ); 975 976 { 977 ResetableGuard aLock( m_aLock ); 978 979 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 980 if ( m_bDisposed ) 981 throw DisposedException(); 982 983 if (( aCommandURLSequence.getLength() != aGraphicsSequence.getLength() ) || 984 (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE ))) 985 throw IllegalArgumentException(); 986 987 if ( m_bReadOnly ) 988 throw IllegalAccessException(); 989 990 sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType ); 991 ImageList* pImageList = implts_getUserImageList( ImageType( nIndex )); 992 993 uno::Reference< XGraphic > xGraphic; 994 for ( sal_Int32 i = 0; i < aCommandURLSequence.getLength(); i++ ) 995 { 996 // Check size and scale. If we don't have any graphics ignore it 997 if ( !implts_checkAndScaleGraphic( xGraphic, aGraphicsSequence[i], nIndex )) 998 continue; 999 1000 sal_uInt16 nPos = pImageList->GetImagePos( aCommandURLSequence[i] ); 1001 if ( nPos == IMAGELIST_IMAGE_NOTFOUND ) 1002 { 1003 pImageList->AddImage( aCommandURLSequence[i], xGraphic ); 1004 if ( !pInsertedImages ) 1005 pInsertedImages = new CmdToXGraphicNameAccess(); 1006 pInsertedImages->addElement( aCommandURLSequence[i], xGraphic ); 1007 } 1008 else 1009 { 1010 pImageList->ReplaceImage( aCommandURLSequence[i], xGraphic ); 1011 if ( !pReplacedImages ) 1012 pReplacedImages = new CmdToXGraphicNameAccess(); 1013 pReplacedImages->addElement( aCommandURLSequence[i], xGraphic ); 1014 } 1015 } 1016 1017 if (( pInsertedImages != 0 ) || ( pReplacedImages != 0 )) 1018 { 1019 m_bModified = sal_True; 1020 m_bUserImageListModified[nIndex] = true; 1021 } 1022 } 1023 1024 // Notify listeners 1025 if ( pInsertedImages != 0 ) 1026 { 1027 ConfigurationEvent aInsertEvent; 1028 aInsertEvent.aInfo <<= nImageType; 1029 aInsertEvent.Accessor <<= m_xOwner; 1030 aInsertEvent.Source = m_xOwner; 1031 aInsertEvent.ResourceURL = m_aResourceString; 1032 aInsertEvent.Element = uno::makeAny( uno::Reference< XNameAccess >( 1033 static_cast< OWeakObject *>( pInsertedImages ), UNO_QUERY )); 1034 implts_notifyContainerListener( aInsertEvent, NotifyOp_Insert ); 1035 } 1036 if ( pReplacedImages != 0 ) 1037 { 1038 ConfigurationEvent aReplaceEvent; 1039 aReplaceEvent.aInfo <<= nImageType; 1040 aReplaceEvent.Accessor <<= m_xOwner; 1041 aReplaceEvent.Source = m_xOwner; 1042 aReplaceEvent.ResourceURL = m_aResourceString; 1043 aReplaceEvent.ReplacedElement = Any(); 1044 aReplaceEvent.Element = uno::makeAny( uno::Reference< XNameAccess >( 1045 static_cast< OWeakObject *>( pReplacedImages ), UNO_QUERY )); 1046 implts_notifyContainerListener( aReplaceEvent, NotifyOp_Replace ); 1047 } 1048 } 1049 1050 void ImageManagerImpl::removeImages( ::sal_Int16 nImageType, const Sequence< ::rtl::OUString >& aCommandURLSequence ) 1051 { 1052 CmdToXGraphicNameAccess* pRemovedImages( 0 ); 1053 CmdToXGraphicNameAccess* pReplacedImages( 0 ); 1054 1055 { 1056 ResetableGuard aLock( m_aLock ); 1057 1058 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 1059 if ( m_bDisposed ) 1060 throw DisposedException(); 1061 1062 if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE )) 1063 throw IllegalArgumentException(); 1064 1065 if ( m_bReadOnly ) 1066 throw IllegalAccessException(); 1067 1068 sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType ); 1069 rtl::Reference< GlobalImageList > rGlobalImageList; 1070 CmdImageList* pDefaultImageList = NULL; 1071 if ( m_bUseGlobal ) 1072 { 1073 rGlobalImageList = implts_getGlobalImageList(); 1074 pDefaultImageList = implts_getDefaultImageList(); 1075 } 1076 ImageList* pImageList = implts_getUserImageList( ImageType( nIndex )); 1077 uno::Reference< XGraphic > xEmptyGraphic( Image().GetXGraphic() ); 1078 1079 for ( sal_Int32 i = 0; i < aCommandURLSequence.getLength(); i++ ) 1080 { 1081 sal_uInt16 nPos = pImageList->GetImagePos( aCommandURLSequence[i] ); 1082 if ( nPos != IMAGELIST_IMAGE_NOTFOUND ) 1083 { 1084 Image aImage = pImageList->GetImage( nPos ); 1085 sal_uInt16 nId = pImageList->GetImageId( nPos ); 1086 pImageList->RemoveImage( nId ); 1087 1088 if ( m_bUseGlobal ) 1089 { 1090 // Check, if we have a image in our module/global image list. If we find one => 1091 // this is a replace instead of a remove operation! 1092 Image aNewImage = pDefaultImageList->getImageFromCommandURL( nIndex, aCommandURLSequence[i] ); 1093 if ( !aNewImage ) 1094 aNewImage = rGlobalImageList->getImageFromCommandURL( nIndex, aCommandURLSequence[i] ); 1095 if ( !aNewImage ) 1096 { 1097 if ( !pRemovedImages ) 1098 pRemovedImages = new CmdToXGraphicNameAccess(); 1099 pRemovedImages->addElement( aCommandURLSequence[i], xEmptyGraphic ); 1100 } 1101 else 1102 { 1103 if ( !pReplacedImages ) 1104 pReplacedImages = new CmdToXGraphicNameAccess(); 1105 pReplacedImages->addElement( aCommandURLSequence[i], aNewImage.GetXGraphic() ); 1106 } 1107 } // if ( m_bUseGlobal ) 1108 else 1109 { 1110 if ( !pRemovedImages ) 1111 pRemovedImages = new CmdToXGraphicNameAccess(); 1112 pRemovedImages->addElement( aCommandURLSequence[i], xEmptyGraphic ); 1113 } 1114 } 1115 } 1116 1117 if (( pReplacedImages != 0 ) || ( pRemovedImages != 0 )) 1118 { 1119 m_bModified = sal_True; 1120 m_bUserImageListModified[nIndex] = true; 1121 } 1122 } 1123 1124 // Notify listeners 1125 if ( pRemovedImages != 0 ) 1126 { 1127 ConfigurationEvent aRemoveEvent; 1128 aRemoveEvent.aInfo = uno::makeAny( nImageType ); 1129 aRemoveEvent.Accessor = uno::makeAny( m_xOwner ); 1130 aRemoveEvent.Source = m_xOwner; 1131 aRemoveEvent.ResourceURL = m_aResourceString; 1132 aRemoveEvent.Element = uno::makeAny( uno::Reference< XNameAccess >( 1133 static_cast< OWeakObject *>( pRemovedImages ), UNO_QUERY )); 1134 implts_notifyContainerListener( aRemoveEvent, NotifyOp_Remove ); 1135 } 1136 if ( pReplacedImages != 0 ) 1137 { 1138 ConfigurationEvent aReplaceEvent; 1139 aReplaceEvent.aInfo = uno::makeAny( nImageType ); 1140 aReplaceEvent.Accessor = uno::makeAny( m_xOwner ); 1141 aReplaceEvent.Source = m_xOwner; 1142 aReplaceEvent.ResourceURL = m_aResourceString; 1143 aReplaceEvent.ReplacedElement = Any(); 1144 aReplaceEvent.Element = uno::makeAny( uno::Reference< XNameAccess >( 1145 static_cast< OWeakObject *>( pReplacedImages ), UNO_QUERY )); 1146 implts_notifyContainerListener( aReplaceEvent, NotifyOp_Replace ); 1147 } 1148 } 1149 1150 void ImageManagerImpl::insertImages( ::sal_Int16 nImageType, const Sequence< ::rtl::OUString >& aCommandURLSequence, const Sequence< uno::Reference< XGraphic > >& aGraphicSequence ) 1151 { 1152 replaceImages(nImageType,aCommandURLSequence,aGraphicSequence); 1153 } 1154 1155 1156 // XUIConfigurationPersistence 1157 void ImageManagerImpl::reload() 1158 { 1159 ResetableGuard aGuard( m_aLock ); 1160 1161 if ( m_bDisposed ) 1162 throw DisposedException(); 1163 1164 CommandMap aOldUserCmdImageSet; 1165 std::vector< rtl::OUString > aNewUserCmdImageSet; 1166 1167 if ( m_bModified ) 1168 { 1169 for ( sal_Int16 i = 0; i < sal_Int16( ImageType_COUNT ); i++ ) 1170 { 1171 if ( !m_bDisposed && m_bUserImageListModified[i] ) 1172 { 1173 std::vector< rtl::OUString > aOldUserCmdImageVector; 1174 ImageList* pImageList = implts_getUserImageList( (ImageType)i ); 1175 pImageList->GetImageNames( aOldUserCmdImageVector ); 1176 1177 // Fill hash map to speed up search afterwards 1178 sal_uInt32 j( 0 ); 1179 const sal_uInt32 nOldCount = aOldUserCmdImageVector.size(); 1180 for ( j = 0; j < nOldCount; j++ ) 1181 aOldUserCmdImageSet.insert( CommandMap::value_type( aOldUserCmdImageVector[j], false )); 1182 1183 // Attention: This can make the old image list pointer invalid! 1184 implts_loadUserImages( (ImageType)i, m_xUserImageStorage, m_xUserBitmapsStorage ); 1185 pImageList = implts_getUserImageList( (ImageType)i ); 1186 pImageList->GetImageNames( aNewUserCmdImageSet ); 1187 1188 CmdToXGraphicNameAccess* pInsertedImages( 0 ); 1189 CmdToXGraphicNameAccess* pReplacedImages( 0 ); 1190 CmdToXGraphicNameAccess* pRemovedImages( 0 ); 1191 1192 const sal_uInt32 nNewCount = aNewUserCmdImageSet.size(); 1193 for ( j = 0; j < nNewCount; j++ ) 1194 { 1195 CommandMap::iterator pIter = aOldUserCmdImageSet.find( aNewUserCmdImageSet[j] ); 1196 if ( pIter != aOldUserCmdImageSet.end() ) 1197 { 1198 pIter->second = true; // mark entry as replaced 1199 if ( !pReplacedImages ) 1200 pReplacedImages = new CmdToXGraphicNameAccess(); 1201 pReplacedImages->addElement( aNewUserCmdImageSet[j], 1202 pImageList->GetImage( aNewUserCmdImageSet[j] ).GetXGraphic() ); 1203 } 1204 else 1205 { 1206 if ( !pInsertedImages ) 1207 pInsertedImages = new CmdToXGraphicNameAccess(); 1208 pInsertedImages->addElement( aNewUserCmdImageSet[j], 1209 pImageList->GetImage( aNewUserCmdImageSet[j] ).GetXGraphic() ); 1210 } 1211 } 1212 1213 // Search map for unmarked entries => they have been removed from the user list 1214 // through this reload operation. 1215 // We have to search the module and global image list! 1216 rtl::Reference< GlobalImageList > rGlobalImageList; 1217 CmdImageList* pDefaultImageList = NULL; 1218 if ( m_bUseGlobal ) 1219 { 1220 rGlobalImageList = implts_getGlobalImageList(); 1221 pDefaultImageList = implts_getDefaultImageList(); 1222 } 1223 uno::Reference< XGraphic > xEmptyGraphic( Image().GetXGraphic() ); 1224 CommandMap::const_iterator pIter = aOldUserCmdImageSet.begin(); 1225 while ( pIter != aOldUserCmdImageSet.end() ) 1226 { 1227 if ( !pIter->second ) 1228 { 1229 if ( m_bUseGlobal ) 1230 { 1231 Image aImage = pDefaultImageList->getImageFromCommandURL( i, pIter->first ); 1232 if ( !aImage ) 1233 aImage = rGlobalImageList->getImageFromCommandURL( i, pIter->first ); 1234 1235 if ( !aImage ) 1236 { 1237 // No image in the module/global image list => remove user image 1238 if ( !pRemovedImages ) 1239 pRemovedImages = new CmdToXGraphicNameAccess(); 1240 pRemovedImages->addElement( pIter->first, xEmptyGraphic ); 1241 } 1242 else 1243 { 1244 // Image has been found in the module/global image list => replace user image 1245 if ( !pReplacedImages ) 1246 pReplacedImages = new CmdToXGraphicNameAccess(); 1247 pReplacedImages->addElement( pIter->first, aImage.GetXGraphic() ); 1248 } 1249 } // if ( m_bUseGlobal ) 1250 else 1251 { 1252 // No image in the user image list => remove user image 1253 if ( !pRemovedImages ) 1254 pRemovedImages = new CmdToXGraphicNameAccess(); 1255 pRemovedImages->addElement( pIter->first, xEmptyGraphic ); 1256 } 1257 } 1258 ++pIter; 1259 } 1260 1261 aGuard.unlock(); 1262 1263 // Now notify our listeners. Unlock mutex to prevent deadlocks 1264 if ( pInsertedImages != 0 ) 1265 { 1266 ConfigurationEvent aInsertEvent; 1267 aInsertEvent.aInfo = uno::makeAny( i ); 1268 aInsertEvent.Accessor = uno::makeAny( m_xOwner ); 1269 aInsertEvent.Source = m_xOwner; 1270 aInsertEvent.ResourceURL = m_aResourceString; 1271 aInsertEvent.Element = uno::makeAny( uno::Reference< XNameAccess >( 1272 static_cast< OWeakObject *>( pInsertedImages ), UNO_QUERY )); 1273 implts_notifyContainerListener( aInsertEvent, NotifyOp_Insert ); 1274 } 1275 if ( pReplacedImages != 0 ) 1276 { 1277 ConfigurationEvent aReplaceEvent; 1278 aReplaceEvent.aInfo = uno::makeAny( i ); 1279 aReplaceEvent.Accessor = uno::makeAny( m_xOwner ); 1280 aReplaceEvent.Source = m_xOwner; 1281 aReplaceEvent.ResourceURL = m_aResourceString; 1282 aReplaceEvent.ReplacedElement = Any(); 1283 aReplaceEvent.Element = uno::makeAny( uno::Reference< XNameAccess >( 1284 static_cast< OWeakObject *>( pReplacedImages ), UNO_QUERY )); 1285 implts_notifyContainerListener( aReplaceEvent, NotifyOp_Replace ); 1286 } 1287 if ( pRemovedImages != 0 ) 1288 { 1289 ConfigurationEvent aRemoveEvent; 1290 aRemoveEvent.aInfo = uno::makeAny( i ); 1291 aRemoveEvent.Accessor = uno::makeAny( m_xOwner ); 1292 aRemoveEvent.Source = m_xOwner; 1293 aRemoveEvent.ResourceURL = m_aResourceString; 1294 aRemoveEvent.Element = uno::makeAny( uno::Reference< XNameAccess >( 1295 static_cast< OWeakObject *>( pRemovedImages ), UNO_QUERY )); 1296 implts_notifyContainerListener( aRemoveEvent, NotifyOp_Remove ); 1297 } 1298 1299 aGuard.lock(); 1300 } 1301 } 1302 } 1303 } 1304 1305 void ImageManagerImpl::store() 1306 { 1307 ResetableGuard aGuard( m_aLock ); 1308 1309 if ( m_bDisposed ) 1310 throw DisposedException(); 1311 1312 if ( m_bModified ) 1313 { 1314 sal_Bool bWritten( sal_False ); 1315 for ( sal_Int32 i = 0; i < ImageType_COUNT; i++ ) 1316 { 1317 sal_Bool bSuccess = implts_storeUserImages( ImageType(i), m_xUserImageStorage, m_xUserBitmapsStorage ); 1318 if ( bSuccess ) 1319 bWritten = sal_True; 1320 m_bUserImageListModified[i] = false; 1321 } 1322 1323 if ( bWritten && 1324 m_xUserConfigStorage.is() ) 1325 { 1326 uno::Reference< XTransactedObject > xUserConfigStorageCommit( m_xUserConfigStorage, UNO_QUERY ); 1327 if ( xUserConfigStorageCommit.is() ) 1328 xUserConfigStorageCommit->commit(); 1329 if ( m_xUserRootCommit.is() ) 1330 m_xUserRootCommit->commit(); 1331 } 1332 1333 m_bModified = sal_False; 1334 } 1335 } 1336 1337 void ImageManagerImpl::storeToStorage( const uno::Reference< XStorage >& Storage ) 1338 { 1339 ResetableGuard aGuard( m_aLock ); 1340 1341 if ( m_bDisposed ) 1342 throw DisposedException(); 1343 1344 if ( m_bModified && Storage.is() ) 1345 { 1346 long nModes = ElementModes::READWRITE; 1347 1348 uno::Reference< XStorage > xUserImageStorage = Storage->openStorageElement( OUString::createFromAscii( IMAGE_FOLDER ), 1349 nModes ); 1350 if ( xUserImageStorage.is() ) 1351 { 1352 uno::Reference< XStorage > xUserBitmapsStorage = xUserImageStorage->openStorageElement( OUString::createFromAscii( BITMAPS_FOLDER ), 1353 nModes ); 1354 for ( sal_Int32 i = 0; i < ImageType_COUNT; i++ ) 1355 { 1356 implts_getUserImageList( (ImageType)i ); 1357 implts_storeUserImages( (ImageType)i, xUserImageStorage, xUserBitmapsStorage ); 1358 } 1359 1360 uno::Reference< XTransactedObject > xTransaction( Storage, UNO_QUERY ); 1361 if ( xTransaction.is() ) 1362 xTransaction->commit(); 1363 } 1364 } 1365 } 1366 1367 sal_Bool ImageManagerImpl::isModified() 1368 { 1369 ResetableGuard aGuard( m_aLock ); 1370 return m_bModified; 1371 } 1372 1373 sal_Bool ImageManagerImpl::isReadOnly() 1374 { 1375 ResetableGuard aGuard( m_aLock ); 1376 return m_bReadOnly; 1377 } 1378 // XUIConfiguration 1379 void ImageManagerImpl::addConfigurationListener( const uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) 1380 { 1381 { 1382 ResetableGuard aGuard( m_aLock ); 1383 1384 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 1385 if ( m_bDisposed ) 1386 throw DisposedException(); 1387 } 1388 1389 m_aListenerContainer.addInterface( ::getCppuType( ( const uno::Reference< XUIConfigurationListener >* ) NULL ), xListener ); 1390 } 1391 1392 void ImageManagerImpl::removeConfigurationListener( const uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) 1393 { 1394 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 1395 m_aListenerContainer.removeInterface( ::getCppuType( ( const uno::Reference< XUIConfigurationListener >* ) NULL ), xListener ); 1396 } 1397 1398 1399 void ImageManagerImpl::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp ) 1400 { 1401 ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( 1402 ::getCppuType( ( const css::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >*) NULL ) ); 1403 if ( pContainer != NULL ) 1404 { 1405 ::cppu::OInterfaceIteratorHelper pIterator( *pContainer ); 1406 while ( pIterator.hasMoreElements() ) 1407 { 1408 try 1409 { 1410 switch ( eOp ) 1411 { 1412 case NotifyOp_Replace: 1413 ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementReplaced( aEvent ); 1414 break; 1415 case NotifyOp_Insert: 1416 ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementInserted( aEvent ); 1417 break; 1418 case NotifyOp_Remove: 1419 ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementRemoved( aEvent ); 1420 break; 1421 } 1422 } 1423 catch( css::uno::RuntimeException& ) 1424 { 1425 pIterator.remove(); 1426 } 1427 } 1428 } 1429 } 1430 void ImageManagerImpl::clear() 1431 { 1432 ResetableGuard aGuard( m_aLock ); 1433 for ( sal_Int32 n = 0; n < ImageType_COUNT; n++ ) 1434 { 1435 delete m_pUserImageList[n]; 1436 m_pUserImageList[n] = 0; 1437 } 1438 } 1439 } // namespace framework 1440