xref: /aoo41x/main/sfx2/source/toolbox/imgmgr.cxx (revision cdf0e10c)
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