Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <stdio.h>
22 : #include <boost/unordered_map.hpp>
23 : #include <boost/shared_ptr.hpp>
24 :
25 : #include <sfx2/imgmgr.hxx>
26 : #include <sfx2/sfx.hrc>
27 : #include <sfx2/app.hxx>
28 : #include <sfx2/sfxresid.hxx>
29 : #include <sfx2/bindings.hxx>
30 : #include "statcach.hxx"
31 : #include <sfx2/module.hxx>
32 : #include <vcl/bitmap.hxx>
33 : #include <vcl/toolbox.hxx>
34 :
35 : #include <tools/rcid.h>
36 : #include <tools/link.hxx>
37 : #include <svtools/miscopt.hxx>
38 : #include <osl/mutex.hxx>
39 : #include <rtl/instance.hxx>
40 :
41 : #include <comphelper/processfactory.hxx>
42 :
43 : const sal_uInt32 IMAGELIST_COUNT = 4; // small, small-hi, large, large-hi
44 :
45 : struct ToolBoxInf_Impl
46 : {
47 : ToolBox* pToolBox;
48 : sal_uInt16 nFlags;
49 : };
50 :
51 : class SfxImageManager_Impl
52 : {
53 : public:
54 : SvtMiscOptions m_aOpt;
55 : std::vector< ToolBoxInf_Impl* > m_aToolBoxes;
56 : sal_Int16 m_nSymbolsSize;
57 : ImageList* m_pImageList[IMAGELIST_COUNT];
58 : SfxModule* m_pModule;
59 : bool m_bAppEventListener;
60 :
61 : ImageList* GetImageList( bool bBig );
62 : Image GetImage( sal_uInt16 nId, bool bBig );
63 : void SetSymbolsSize_Impl( sal_Int16 );
64 :
65 : DECL_LINK( OptionsChanged_Impl, void* );
66 : DECL_LINK( SettingsChanged_Impl, VclWindowEvent* );
67 :
68 :
69 : SfxImageManager_Impl( SfxModule* pModule );
70 : ~SfxImageManager_Impl();
71 : };
72 :
73 : namespace
74 : {
75 : typedef boost::unordered_map< SfxModule*, boost::shared_ptr<SfxImageManager_Impl> > SfxImageManagerImplMap;
76 :
77 : class theImageManagerImplMap :
78 : public rtl::Static<SfxImageManagerImplMap, theImageManagerImplMap> {};
79 :
80 : class theGlobalImageManager :
81 : public rtl::StaticWithArg<SfxImageManager_Impl, SfxModule*,
82 : theGlobalImageManager> {};
83 : }
84 :
85 0 : static SfxImageManager_Impl* GetImageManager( SfxModule* pModule )
86 : {
87 0 : SolarMutexGuard aGuard;
88 :
89 0 : if ( pModule == 0 )
90 : {
91 0 : return &theGlobalImageManager::get(NULL);
92 : }
93 : else
94 : {
95 : SfxImageManagerImplMap &rImageManager_ImplMap =
96 0 : theImageManagerImplMap::get();
97 0 : SfxImageManager_Impl* pImpl( 0 );
98 0 : SfxImageManagerImplMap::const_iterator pIter = rImageManager_ImplMap.find(pModule);
99 0 : if ( pIter != rImageManager_ImplMap.end() )
100 0 : pImpl = pIter->second.get();
101 : else
102 : {
103 0 : rImageManager_ImplMap[pModule].reset(new SfxImageManager_Impl(pModule));
104 0 : pImpl = rImageManager_ImplMap[pModule].get();
105 : }
106 0 : return pImpl;
107 0 : }
108 : }
109 :
110 : // Global image list
111 0 : static ImageList* GetImageList( bool bBig )
112 : {
113 0 : SolarMutexGuard aGuard;
114 0 : ImageList* rpList = NULL;
115 :
116 0 : ResMgr *pResMgr = SfxApplication::GetOrCreate()->GetOffResManager_Impl();
117 :
118 0 : ResId aResId( bBig ? ( RID_DEFAULTIMAGELIST_LC ) : ( RID_DEFAULTIMAGELIST_SC ), *pResMgr);
119 :
120 0 : aResId.SetRT( RSC_IMAGELIST );
121 :
122 : DBG_ASSERT( pResMgr->IsAvailable(aResId), "No default ImageList!" );
123 :
124 0 : if ( pResMgr->IsAvailable(aResId) )
125 0 : rpList = new ImageList( aResId );
126 : else
127 0 : rpList = new ImageList();
128 :
129 0 : return rpList;
130 : }
131 :
132 0 : static sal_Int16 impl_convertBools( bool bLarge )
133 : {
134 0 : sal_Int16 nIndex( 0 );
135 0 : if ( bLarge )
136 0 : nIndex += 1;
137 0 : return nIndex;
138 : }
139 :
140 :
141 :
142 0 : SfxImageManager_Impl::SfxImageManager_Impl( SfxModule* pModule )
143 : : m_pModule(pModule)
144 0 : , m_bAppEventListener(false)
145 : {
146 0 : m_nSymbolsSize = m_aOpt.GetCurrentSymbolsSize();
147 :
148 0 : for ( sal_uInt32 i = 0; i < IMAGELIST_COUNT; i++ )
149 0 : m_pImageList[i] = 0;
150 :
151 0 : m_aOpt.AddListenerLink( LINK( this, SfxImageManager_Impl, OptionsChanged_Impl ) );
152 0 : Application::AddEventListener( LINK( this, SfxImageManager_Impl, SettingsChanged_Impl ) );
153 0 : m_bAppEventListener = true;
154 0 : }
155 :
156 :
157 :
158 0 : SfxImageManager_Impl::~SfxImageManager_Impl()
159 : {
160 0 : m_aOpt.RemoveListenerLink( LINK( this, SfxImageManager_Impl, OptionsChanged_Impl ) );
161 0 : if (m_bAppEventListener)
162 0 : Application::RemoveEventListener( LINK( this, SfxImageManager_Impl, SettingsChanged_Impl ) );
163 0 : for ( sal_uInt32 i = 0; i < m_aToolBoxes.size(); i++ )
164 0 : delete m_aToolBoxes[i];
165 0 : }
166 :
167 :
168 :
169 0 : ImageList* SfxImageManager_Impl::GetImageList( bool bBig )
170 : {
171 0 : sal_Int32 nIndex = impl_convertBools( bBig );
172 0 : if ( !m_pImageList[nIndex] )
173 : {
174 0 : if ( !m_pModule )
175 0 : m_pImageList[nIndex] = ::GetImageList( bBig );
176 : else
177 0 : m_pImageList[nIndex] = m_pModule->GetImageList_Impl( bBig );
178 : }
179 :
180 0 : return m_pImageList[nIndex];
181 : }
182 :
183 :
184 :
185 0 : Image SfxImageManager_Impl::GetImage( sal_uInt16 nId, bool bBig )
186 : {
187 0 : ImageList* pImageList = GetImageList( bBig );
188 0 : if ( pImageList )
189 0 : return pImageList->GetImage( nId );
190 0 : return Image();
191 : }
192 :
193 :
194 :
195 0 : void SfxImageManager_Impl::SetSymbolsSize_Impl( sal_Int16 nNewSymbolsSize )
196 : {
197 0 : SolarMutexGuard aGuard;
198 :
199 0 : if ( nNewSymbolsSize != m_nSymbolsSize )
200 : {
201 0 : m_nSymbolsSize = nNewSymbolsSize;
202 0 : bool bLarge( m_nSymbolsSize == SFX_SYMBOLS_SIZE_LARGE );
203 :
204 0 : for ( sal_uInt32 n=0; n < m_aToolBoxes.size(); n++ )
205 : {
206 0 : ToolBoxInf_Impl *pInf = m_aToolBoxes[n];
207 0 : if ( pInf->nFlags & SFX_TOOLBOX_CHANGESYMBOLSET )
208 : {
209 0 : ToolBox *pBox = pInf->pToolBox;
210 0 : sal_uInt16 nCount = pBox->GetItemCount();
211 0 : for ( sal_uInt16 nPos=0; nPos<nCount; nPos++ )
212 : {
213 0 : sal_uInt16 nId = pBox->GetItemId( nPos );
214 0 : if ( pBox->GetItemType(nPos) == TOOLBOXITEM_BUTTON )
215 : {
216 0 : pBox->SetItemImage( nId, GetImage( nId, bLarge ) );
217 0 : SfxStateCache *pCache = SfxViewFrame::Current()->GetBindings().GetStateCache( nId );
218 0 : if ( pCache )
219 0 : pCache->SetCachedState();
220 : }
221 : }
222 :
223 0 : if ( !pBox->IsFloatingMode() )
224 : {
225 0 : Size aActSize( pBox->GetSizePixel() );
226 0 : Size aSize( pBox->CalcWindowSizePixel() );
227 0 : if ( pBox->IsHorizontal() )
228 0 : aSize.Width() = aActSize.Width();
229 : else
230 0 : aSize.Height() = aActSize.Height();
231 :
232 0 : pBox->SetSizePixel( aSize );
233 : }
234 : }
235 : }
236 0 : }
237 0 : }
238 :
239 :
240 :
241 0 : IMPL_LINK_NOARG(SfxImageManager_Impl, OptionsChanged_Impl)
242 : {
243 0 : SetSymbolsSize_Impl( m_aOpt.GetCurrentSymbolsSize() );
244 0 : return 0L;
245 : }
246 :
247 :
248 :
249 0 : IMPL_LINK( SfxImageManager_Impl, SettingsChanged_Impl, VclWindowEvent*, pEvent)
250 : {
251 0 : if (pEvent)
252 : {
253 0 : switch (pEvent->GetId())
254 : {
255 : case VCLEVENT_OBJECT_DYING:
256 0 : if (m_bAppEventListener)
257 : {
258 0 : Application::RemoveEventListener( LINK( this, SfxImageManager_Impl, SettingsChanged_Impl ) );
259 0 : m_bAppEventListener = false;
260 : }
261 0 : break;
262 : case VCLEVENT_APPLICATION_DATACHANGED:
263 : // Check if toolbar button size have changed and we have to use system settings
264 : {
265 0 : sal_Int16 nSymbolsSize = m_aOpt.GetCurrentSymbolsSize();
266 0 : if (m_nSymbolsSize != nSymbolsSize)
267 0 : SetSymbolsSize_Impl(nSymbolsSize);
268 : }
269 0 : break;
270 : default:
271 0 : break;
272 : }
273 : }
274 0 : return 0L;
275 : }
276 :
277 :
278 :
279 :
280 :
281 0 : SfxImageManager::SfxImageManager( SfxModule* pModule )
282 : {
283 0 : pImp = ::GetImageManager( pModule );
284 0 : }
285 :
286 :
287 :
288 0 : SfxImageManager::~SfxImageManager()
289 : {
290 0 : }
291 :
292 :
293 :
294 : namespace
295 : {
296 : typedef boost::unordered_map< SfxModule*, boost::shared_ptr<SfxImageManager> > SfxImageManagerMap;
297 :
298 : class theImageManagerMap :
299 : public rtl::Static<SfxImageManagerMap, theImageManagerMap> {};
300 : }
301 :
302 0 : SfxImageManager* SfxImageManager::GetImageManager( SfxModule* pModule )
303 : {
304 0 : SolarMutexGuard aGuard;
305 0 : SfxImageManager* pSfxImageManager(0);
306 :
307 0 : SfxImageManagerMap &rImageManagerMap = theImageManagerMap::get();
308 :
309 0 : SfxImageManagerMap::const_iterator pIter = rImageManagerMap.find(pModule);
310 0 : if ( pIter != rImageManagerMap.end() )
311 0 : pSfxImageManager = pIter->second.get();
312 : else
313 : {
314 0 : rImageManagerMap[pModule].reset(new SfxImageManager(pModule));
315 0 : pSfxImageManager = rImageManagerMap[pModule].get();
316 : }
317 0 : return pSfxImageManager;
318 : }
319 :
320 :
321 :
322 0 : Image SfxImageManager::GetImage( sal_uInt16 nId, bool bBig ) const
323 : {
324 0 : ImageList* pImageList = pImp->GetImageList( bBig );
325 0 : if ( pImageList && pImageList->HasImageAtPos( nId ) )
326 0 : return pImageList->GetImage( nId );
327 0 : return Image();
328 : }
329 :
330 :
331 :
332 0 : Image SfxImageManager::GetImage( sal_uInt16 nId ) const
333 : {
334 0 : bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge();
335 0 : return GetImage( nId, bLarge );
336 : }
337 :
338 :
339 :
340 0 : Image SfxImageManager::SeekImage( sal_uInt16 nId, bool bBig ) const
341 : {
342 0 : bool bGlobal = ( pImp->m_pModule == 0 );
343 0 : ImageList* pImageList = pImp->GetImageList( bBig );
344 0 : if ( pImageList && pImageList->HasImageAtPos( nId ) )
345 0 : return pImageList->GetImage( nId );
346 0 : else if ( !bGlobal )
347 : {
348 0 : pImageList = ::GetImageManager( 0 )->GetImageList( bBig );
349 0 : if ( pImageList )
350 0 : return pImageList->GetImage( nId );
351 : }
352 0 : return Image();
353 : }
354 :
355 :
356 :
357 0 : Image SfxImageManager::SeekImage( sal_uInt16 nId ) const
358 : {
359 0 : bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge();
360 0 : return SeekImage( nId, bLarge );
361 : }
362 :
363 :
364 :
365 0 : void SfxImageManager::RegisterToolBox( ToolBox *pBox, sal_uInt16 nFlags )
366 : {
367 0 : SolarMutexGuard aGuard;
368 :
369 0 : ToolBoxInf_Impl* pInf = new ToolBoxInf_Impl;
370 0 : pInf->pToolBox = pBox;
371 0 : pInf->nFlags = nFlags;
372 0 : pImp->m_aToolBoxes.push_back( pInf );
373 0 : }
374 :
375 :
376 :
377 0 : void SfxImageManager::ReleaseToolBox( ToolBox *pBox )
378 : {
379 0 : SolarMutexGuard aGuard;
380 :
381 0 : for ( sal_uInt32 n=0; n < pImp->m_aToolBoxes.size(); n++ )
382 : {
383 0 : if ((pImp->m_aToolBoxes[n])->pToolBox == pBox )
384 : {
385 0 : delete pImp->m_aToolBoxes[n];
386 0 : pImp->m_aToolBoxes.erase( pImp->m_aToolBoxes.begin() + n );
387 0 : return;
388 : }
389 0 : }
390 : }
391 :
392 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|