xref: /trunk/main/sfx2/source/toolbox/imgmgr.cxx (revision d119d52d)
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 
GetImageManager(SfxModule * pModule)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
GetImageList(sal_Bool bBig,sal_Bool bHiContrast)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 
impl_convertBools(sal_Bool bLarge,sal_Bool bHiContrast)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 
SfxImageManager_Impl(SfxModule * pModule)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 
~SfxImageManager_Impl()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 
GetImageList(sal_Bool bBig,sal_Bool bHiContrast)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 
GetImage(sal_uInt16 nId,sal_Bool bBig,sal_Bool bHiContrast)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 
SetSymbolsSize_Impl(sal_Int16 nNewSymbolsSize)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 
IMPL_LINK(SfxImageManager_Impl,OptionsChanged_Impl,void *,EMPTYARG)257 IMPL_LINK( SfxImageManager_Impl, OptionsChanged_Impl, void*, EMPTYARG )
258 {
259     SetSymbolsSize_Impl( SvtMiscOptions().GetCurrentSymbolsSize() );
260     return 0L;
261 }
262 
263 //-------------------------------------------------------------------------
264 
IMPL_LINK(SfxImageManager_Impl,SettingsChanged_Impl,void *,EMPTYARG)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 
SfxImageManager(SfxModule * pModule)278 SfxImageManager::SfxImageManager( SfxModule* pModule )
279 {
280     pImp = ::GetImageManager( pModule );
281 }
282 
283 //-------------------------------------------------------------------------
284 
~SfxImageManager()285 SfxImageManager::~SfxImageManager()
286 {
287 }
288 
289 //-------------------------------------------------------------------------
290 
GetImageManager(SfxModule * pModule)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 
GetImage(sal_uInt16 nId,sal_Bool bBig,sal_Bool bHiContrast) const311 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 
GetImage(sal_uInt16 nId,sal_Bool bHiContrast) const321 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 
SeekImage(sal_uInt16 nId,sal_Bool bBig,sal_Bool bHiContrast) const329 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 
SeekImage(sal_uInt16 nId,sal_Bool bHiContrast) const346 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 
RegisterToolBox(ToolBox * pBox,sal_uInt16 nFlags)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 
ReleaseToolBox(ToolBox * pBox)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 
SetImages(ToolBox & rToolBox,sal_Bool bHiContrast,sal_Bool bLarge)383 void SfxImageManager::SetImages( ToolBox& rToolBox, sal_Bool bHiContrast, sal_Bool bLarge )
384 {
385     SetImagesForceSize( rToolBox, bLarge, bHiContrast );
386 }
387 
388 //-------------------------------------------------------------------------
389 
SetImagesForceSize(ToolBox & rToolBox,sal_Bool bHiContrast,sal_Bool bLarge)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 
SetImages(ToolBox & rToolBox)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