1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sfx2.hxx" 30 31 #include <stdio.h> 32 #include <hash_map> 33 34 #include "sfx2/imgmgr.hxx" 35 #include <sfx2/sfx.hrc> 36 #include <sfx2/app.hxx> 37 #include "sfx2/sfxresid.hxx" 38 #include <sfx2/bindings.hxx> 39 #include "statcach.hxx" 40 #include <sfx2/module.hxx> 41 #include <vcl/bitmap.hxx> 42 #include <vcl/toolbox.hxx> 43 44 #include <tools/rcid.h> 45 #include <tools/link.hxx> 46 #include <svtools/miscopt.hxx> 47 #include <vos/mutex.hxx> 48 49 #ifndef GCC 50 #endif 51 52 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX 53 #include <comphelper/processfactory.hxx> 54 #endif 55 56 const sal_uInt32 IMAGELIST_COUNT = 4; // small, small-hi, large, large-hi 57 58 struct ToolBoxInf_Impl 59 { 60 ToolBox* pToolBox; 61 sal_uInt16 nFlags; 62 }; 63 64 class SfxImageManager_Impl 65 { 66 public: 67 sal_Int16 m_nSymbolsSize; 68 SvtMiscOptions m_aOpt; 69 std::vector< ToolBoxInf_Impl* > m_aToolBoxes; 70 ImageList* m_pImageList[IMAGELIST_COUNT]; 71 SfxModule* m_pModule; 72 73 ImageList* GetImageList( sal_Bool bBig, sal_Bool bHiContrast ); 74 Image GetImage( sal_uInt16 nId, sal_Bool bBig, sal_Bool bHiContrast ); 75 void SetSymbolsSize_Impl( sal_Int16 ); 76 77 DECL_LINK( OptionsChanged_Impl, void* ); 78 DECL_LINK( SettingsChanged_Impl, void* ); 79 80 81 SfxImageManager_Impl( SfxModule* pModule ); 82 ~SfxImageManager_Impl(); 83 }; 84 85 typedef std::hash_map< sal_Int64, sal_Int64 > SfxImageManagerMap; 86 87 // global image lists 88 static SfxImageManager_Impl* pGlobalImageManager = 0; 89 static SfxImageManagerMap m_ImageManager_ImplMap; 90 static SfxImageManagerMap m_ImageManagerMap; 91 static ImageList* pImageListSmall=0; 92 static ImageList* pImageListBig=0; 93 static ImageList* pImageListHiSmall=0; 94 static ImageList* pImageListHiBig=0; 95 96 static SfxImageManager_Impl* GetImageManager( SfxModule* pModule ) 97 { 98 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 99 100 if ( pModule == 0 ) 101 { 102 if ( !pGlobalImageManager ) 103 pGlobalImageManager = new SfxImageManager_Impl( 0 ); 104 return pGlobalImageManager; 105 } 106 else 107 { 108 SfxImageManager_Impl* pImpl( 0 ); 109 SfxImageManagerMap::const_iterator pIter = m_ImageManager_ImplMap.find( sal::static_int_cast< sal_Int64>( reinterpret_cast< sal_IntPtr >( pModule ))); 110 if ( pIter != m_ImageManager_ImplMap.end() ) 111 pImpl = reinterpret_cast< SfxImageManager_Impl* >( sal::static_int_cast< sal_IntPtr >( pIter->second )); 112 else 113 { 114 pImpl = new SfxImageManager_Impl( pModule ); 115 m_ImageManager_ImplMap.insert( 116 SfxImageManagerMap::value_type( 117 sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( pModule )), 118 sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( pImpl )) )); 119 } 120 return pImpl; 121 } 122 } 123 124 // Global image list 125 static ImageList* GetImageList( sal_Bool bBig, sal_Bool bHiContrast ) 126 { 127 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 128 129 // Has to be changed if we know how the IDs are named!!! 130 ImageList*& rpList = bBig ? ( bHiContrast ? pImageListHiBig : pImageListBig ) : 131 ( bHiContrast ? pImageListHiSmall : pImageListSmall ); 132 if ( !rpList ) 133 { 134 ResMgr *pResMgr = SfxApplication::GetOrCreate()->GetOffResManager_Impl(); 135 136 ResId aResId( bBig ? ( bHiContrast ? RID_DEFAULTIMAGELIST_LCH : RID_DEFAULTIMAGELIST_LC ) : 137 ( bHiContrast ? RID_DEFAULTIMAGELIST_SCH : RID_DEFAULTIMAGELIST_SC ), *pResMgr); 138 139 aResId.SetRT( RSC_IMAGELIST ); 140 141 DBG_ASSERT( pResMgr->IsAvailable(aResId), "No default ImageList!" ); 142 143 if ( pResMgr->IsAvailable(aResId) ) 144 rpList = new ImageList( aResId ); 145 else 146 rpList = new ImageList(); 147 } 148 149 return rpList; 150 } 151 152 static sal_Int16 impl_convertBools( sal_Bool bLarge, sal_Bool bHiContrast ) 153 { 154 sal_Int16 nIndex( 0 ); 155 if ( bLarge ) 156 nIndex += 1; 157 if ( bHiContrast ) 158 nIndex += 2; 159 return nIndex; 160 } 161 162 //========================================================================= 163 164 SfxImageManager_Impl::SfxImageManager_Impl( SfxModule* pModule ) : 165 m_nSymbolsSize( SvtMiscOptions().GetCurrentSymbolsSize() ), 166 m_pModule( pModule ) 167 { 168 for ( sal_uInt32 i = 0; i < IMAGELIST_COUNT; i++ ) 169 m_pImageList[i] = 0; 170 171 m_aOpt.AddListenerLink( LINK( this, SfxImageManager_Impl, OptionsChanged_Impl ) ); 172 Application::AddEventListener( LINK( this, SfxImageManager_Impl, SettingsChanged_Impl ) ); 173 } 174 175 //------------------------------------------------------------------------- 176 177 SfxImageManager_Impl::~SfxImageManager_Impl() 178 { 179 m_aOpt.RemoveListenerLink( LINK( this, SfxImageManager_Impl, OptionsChanged_Impl ) ); 180 Application::RemoveEventListener( LINK( this, SfxImageManager_Impl, SettingsChanged_Impl ) ); 181 182 for ( sal_uInt32 i = 0; i < m_aToolBoxes.size(); i++ ) 183 delete m_aToolBoxes[i]; 184 } 185 186 //------------------------------------------------------------------------- 187 188 ImageList* SfxImageManager_Impl::GetImageList( sal_Bool bBig, sal_Bool bHiContrast ) 189 { 190 sal_Int32 nIndex = impl_convertBools( bBig, bHiContrast ); 191 if ( !m_pImageList[nIndex] ) 192 { 193 if ( !m_pModule ) 194 m_pImageList[nIndex] = ::GetImageList( bBig, bHiContrast ); 195 else 196 m_pImageList[nIndex] = m_pModule->GetImageList_Impl( bBig, bHiContrast ); 197 } 198 199 return m_pImageList[nIndex]; 200 } 201 202 //------------------------------------------------------------------------- 203 204 Image SfxImageManager_Impl::GetImage( sal_uInt16 nId, sal_Bool bBig, sal_Bool bHiContrast ) 205 { 206 ImageList* pImageList = GetImageList( bBig, bHiContrast ); 207 if ( pImageList ) 208 return pImageList->GetImage( nId ); 209 return Image(); 210 } 211 212 //------------------------------------------------------------------------- 213 214 void SfxImageManager_Impl::SetSymbolsSize_Impl( sal_Int16 nNewSymbolsSize ) 215 { 216 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 217 218 if ( nNewSymbolsSize != m_nSymbolsSize ) 219 { 220 m_nSymbolsSize = nNewSymbolsSize; 221 sal_Bool bLarge( m_nSymbolsSize == SFX_SYMBOLS_SIZE_LARGE ); 222 223 for ( sal_uInt32 n=0; n < m_aToolBoxes.size(); n++ ) 224 { 225 ToolBoxInf_Impl *pInf = m_aToolBoxes[n]; 226 if ( pInf->nFlags & SFX_TOOLBOX_CHANGESYMBOLSET ) 227 { 228 ToolBox *pBox = pInf->pToolBox; 229 sal_Bool bHiContrast = pBox->GetSettings().GetStyleSettings().GetHighContrastMode(); 230 sal_uInt16 nCount = pBox->GetItemCount(); 231 for ( sal_uInt16 nPos=0; nPos<nCount; nPos++ ) 232 { 233 sal_uInt16 nId = pBox->GetItemId( nPos ); 234 if ( pBox->GetItemType(nPos) == TOOLBOXITEM_BUTTON ) 235 { 236 pBox->SetItemImage( nId, GetImage( nId, bLarge, bHiContrast ) ); 237 SfxStateCache *pCache = SfxViewFrame::Current()->GetBindings().GetStateCache( nId ); 238 if ( pCache ) 239 pCache->SetCachedState(); 240 } 241 } 242 243 if ( !pBox->IsFloatingMode() ) 244 { 245 Size aActSize( pBox->GetSizePixel() ); 246 Size aSize( pBox->CalcWindowSizePixel() ); 247 if ( pBox->IsHorizontal() ) 248 aSize.Width() = aActSize.Width(); 249 else 250 aSize.Height() = aActSize.Height(); 251 252 pBox->SetSizePixel( aSize ); 253 } 254 } 255 } 256 } 257 } 258 259 //------------------------------------------------------------------------- 260 261 IMPL_LINK( SfxImageManager_Impl, OptionsChanged_Impl, void*, EMPTYARG ) 262 { 263 SetSymbolsSize_Impl( SvtMiscOptions().GetCurrentSymbolsSize() ); 264 return 0L; 265 } 266 267 //------------------------------------------------------------------------- 268 269 IMPL_LINK( SfxImageManager_Impl, SettingsChanged_Impl, void*, EMPTYARG ) 270 { 271 // Check if toolbar button size have changed and we have to use system settings 272 sal_Int16 nSymbolsSize = SvtMiscOptions().GetCurrentSymbolsSize(); 273 if ( m_nSymbolsSize != nSymbolsSize ) 274 SetSymbolsSize_Impl( nSymbolsSize ); 275 return 0L; 276 } 277 278 //------------------------------------------------------------------------- 279 280 //========================================================================= 281 282 SfxImageManager::SfxImageManager( SfxModule* pModule ) 283 { 284 pImp = ::GetImageManager( pModule ); 285 } 286 287 //------------------------------------------------------------------------- 288 289 SfxImageManager::~SfxImageManager() 290 { 291 } 292 293 //------------------------------------------------------------------------- 294 295 SfxImageManager* SfxImageManager::GetImageManager( SfxModule* pModule ) 296 { 297 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 298 299 SfxImageManagerMap::const_iterator pIter = 300 m_ImageManagerMap.find( sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( pModule ))); 301 if ( pIter != m_ImageManagerMap.end() ) 302 return reinterpret_cast< SfxImageManager* >( sal::static_int_cast< sal_IntPtr >( pIter->second )); 303 else 304 { 305 SfxImageManager* pSfxImageManager = new SfxImageManager( pModule ); 306 m_ImageManagerMap.insert( SfxImageManagerMap::value_type( 307 sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( pModule )), 308 sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( pSfxImageManager )) )); 309 return pSfxImageManager; 310 } 311 } 312 313 //------------------------------------------------------------------------- 314 315 Image SfxImageManager::GetImage( sal_uInt16 nId, sal_Bool bBig, sal_Bool bHiContrast ) const 316 { 317 ImageList* pImageList = pImp->GetImageList( bBig, bHiContrast ); 318 if ( pImageList && pImageList->HasImageAtPos( nId ) ) 319 return pImageList->GetImage( nId ); 320 return Image(); 321 } 322 323 //------------------------------------------------------------------------- 324 325 Image SfxImageManager::GetImage( sal_uInt16 nId, sal_Bool bHiContrast ) const 326 { 327 sal_Bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge(); 328 return GetImage( nId, bLarge, bHiContrast ); 329 } 330 331 //------------------------------------------------------------------------- 332 333 Image SfxImageManager::SeekImage( sal_uInt16 nId, sal_Bool bBig, sal_Bool bHiContrast ) const 334 { 335 sal_Bool bGlobal = ( pImp->m_pModule == 0 ); 336 ImageList* pImageList = pImp->GetImageList( bBig, bHiContrast ); 337 if ( pImageList && pImageList->HasImageAtPos( nId ) ) 338 return pImageList->GetImage( nId ); 339 else if ( !bGlobal ) 340 { 341 pImageList = ::GetImageManager( 0 )->GetImageList( bBig, bHiContrast ); 342 if ( pImageList ) 343 return pImageList->GetImage( nId ); 344 } 345 return Image(); 346 } 347 348 //------------------------------------------------------------------------- 349 350 Image SfxImageManager::SeekImage( sal_uInt16 nId, sal_Bool bHiContrast ) const 351 { 352 sal_Bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge(); 353 return SeekImage( nId, bLarge, bHiContrast ); 354 } 355 356 //------------------------------------------------------------------------- 357 358 void SfxImageManager::RegisterToolBox( ToolBox *pBox, sal_uInt16 nFlags ) 359 { 360 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 361 362 ToolBoxInf_Impl* pInf = new ToolBoxInf_Impl; 363 pInf->pToolBox = pBox; 364 pInf->nFlags = nFlags; 365 pImp->m_aToolBoxes.push_back( pInf ); 366 } 367 368 //------------------------------------------------------------------------- 369 370 void SfxImageManager::ReleaseToolBox( ToolBox *pBox ) 371 { 372 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 373 374 for ( sal_uInt32 n=0; n < pImp->m_aToolBoxes.size(); n++ ) 375 { 376 if ((pImp->m_aToolBoxes[n])->pToolBox == pBox ) 377 { 378 delete pImp->m_aToolBoxes[n]; 379 pImp->m_aToolBoxes.erase( pImp->m_aToolBoxes.begin() + n ); 380 return; 381 } 382 } 383 } 384 385 //------------------------------------------------------------------------- 386 387 void SfxImageManager::SetImages( ToolBox& rToolBox, sal_Bool bHiContrast, sal_Bool bLarge ) 388 { 389 SetImagesForceSize( rToolBox, bLarge, bHiContrast ); 390 } 391 392 //------------------------------------------------------------------------- 393 394 void SfxImageManager::SetImagesForceSize( ToolBox& rToolBox, sal_Bool bHiContrast, sal_Bool bLarge ) 395 { 396 ImageList* pImageList = pImp->GetImageList( bLarge, bHiContrast ); 397 398 sal_uInt16 nCount = rToolBox.GetItemCount(); 399 for (sal_uInt16 n=0; n<nCount; n++) 400 { 401 sal_uInt16 nId = rToolBox.GetItemId(n); 402 switch ( rToolBox.GetItemType(n) ) 403 { 404 case TOOLBOXITEM_BUTTON: 405 { 406 if ( pImageList && pImageList->HasImageAtPos( nId ) ) 407 rToolBox.SetItemImage( nId, pImageList->GetImage( nId )); 408 else 409 rToolBox.SetItemImage( nId, Image() ); 410 } 411 412 case TOOLBOXITEM_SEPARATOR: 413 case TOOLBOXITEM_SPACE: 414 case TOOLBOXITEM_BREAK: 415 default: 416 break; 417 } 418 } 419 } 420 421 void SfxImageManager::SetImages( ToolBox& rToolBox ) 422 { 423 sal_Bool bLarge = ( pImp->m_nSymbolsSize == SFX_SYMBOLS_SIZE_LARGE ); 424 sal_Bool bHiContrast = rToolBox.GetSettings().GetStyleSettings().GetHighContrastMode(); 425 SetImagesForceSize( rToolBox, bHiContrast, bLarge ); 426 } 427