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