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 <boost/shared_ptr.hpp>
22 :
23 : #include <sfx2/imgmgr.hxx>
24 : #include <sfx2/sfx.hrc>
25 : #include <sfx2/app.hxx>
26 : #include <sfx2/sfxresid.hxx>
27 : #include <sfx2/bindings.hxx>
28 : #include "statcach.hxx"
29 : #include <sfx2/module.hxx>
30 : #include <vcl/bitmap.hxx>
31 : #include <vcl/toolbox.hxx>
32 :
33 : #include <tools/rcid.h>
34 : #include <tools/link.hxx>
35 : #include <svtools/miscopt.hxx>
36 : #include <osl/mutex.hxx>
37 : #include <rtl/instance.hxx>
38 :
39 : #include <comphelper/processfactory.hxx>
40 :
41 : #include <unordered_map>
42 :
43 : const sal_uInt32 IMAGELIST_COUNT = 4; // small, small-hi, large, large-hi
44 :
45 708 : struct ToolBoxInf_Impl
46 : {
47 : VclPtr<ToolBox> pToolBox;
48 : SfxToolboxFlags 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_rModule;
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 : SfxImageManager_Impl(SfxModule& rModule);
69 : ~SfxImageManager_Impl();
70 : };
71 :
72 : namespace
73 : {
74 : typedef std::unordered_map< SfxModule*, boost::shared_ptr<SfxImageManager_Impl> > SfxImageManagerImplMap;
75 :
76 : class theImageManagerImplMap :
77 : public rtl::Static<SfxImageManagerImplMap, theImageManagerImplMap> {};
78 : }
79 :
80 43 : static SfxImageManager_Impl* GetImageManager(SfxModule& rModule)
81 : {
82 43 : SolarMutexGuard aGuard;
83 :
84 : SfxImageManagerImplMap &rImageManager_ImplMap =
85 43 : theImageManagerImplMap::get();
86 43 : SfxImageManager_Impl* pImpl( 0 );
87 43 : SfxModule* pModule(&rModule);
88 43 : SfxImageManagerImplMap::const_iterator pIter = rImageManager_ImplMap.find(pModule);
89 43 : if ( pIter != rImageManager_ImplMap.end() )
90 0 : pImpl = pIter->second.get();
91 : else
92 : {
93 43 : rImageManager_ImplMap[pModule].reset(new SfxImageManager_Impl(rModule));
94 43 : pImpl = rImageManager_ImplMap[pModule].get();
95 : }
96 43 : return pImpl;
97 : }
98 :
99 1014 : static sal_Int16 impl_convertBools( bool bLarge )
100 : {
101 1014 : sal_Int16 nIndex( 0 );
102 1014 : if ( bLarge )
103 0 : nIndex += 1;
104 1014 : return nIndex;
105 : }
106 :
107 43 : SfxImageManager_Impl::SfxImageManager_Impl(SfxModule& rModule)
108 : : m_rModule(rModule)
109 43 : , m_bAppEventListener(false)
110 : {
111 43 : m_nSymbolsSize = m_aOpt.GetCurrentSymbolsSize();
112 :
113 215 : for ( sal_uInt32 i = 0; i < IMAGELIST_COUNT; i++ )
114 172 : m_pImageList[i] = 0;
115 :
116 43 : m_aOpt.AddListenerLink( LINK( this, SfxImageManager_Impl, OptionsChanged_Impl ) );
117 43 : Application::AddEventListener( LINK( this, SfxImageManager_Impl, SettingsChanged_Impl ) );
118 43 : m_bAppEventListener = true;
119 43 : }
120 :
121 :
122 :
123 86 : SfxImageManager_Impl::~SfxImageManager_Impl()
124 : {
125 43 : m_aOpt.RemoveListenerLink( LINK( this, SfxImageManager_Impl, OptionsChanged_Impl ) );
126 43 : if (m_bAppEventListener)
127 0 : Application::RemoveEventListener( LINK( this, SfxImageManager_Impl, SettingsChanged_Impl ) );
128 45 : for ( size_t i = 0; i < m_aToolBoxes.size(); i++ )
129 2 : delete m_aToolBoxes[i];
130 43 : }
131 :
132 :
133 :
134 1014 : ImageList* SfxImageManager_Impl::GetImageList( bool bBig )
135 : {
136 1014 : sal_Int32 nIndex = impl_convertBools( bBig );
137 1014 : if ( !m_pImageList[nIndex] )
138 : {
139 41 : m_pImageList[nIndex] = m_rModule.GetImageList_Impl( bBig );
140 : }
141 :
142 1014 : return m_pImageList[nIndex];
143 : }
144 :
145 :
146 :
147 0 : Image SfxImageManager_Impl::GetImage( sal_uInt16 nId, bool bBig )
148 : {
149 0 : ImageList* pImageList = GetImageList( bBig );
150 0 : if ( pImageList )
151 0 : return pImageList->GetImage( nId );
152 0 : return Image();
153 : }
154 :
155 :
156 :
157 0 : void SfxImageManager_Impl::SetSymbolsSize_Impl( sal_Int16 nNewSymbolsSize )
158 : {
159 0 : SolarMutexGuard aGuard;
160 :
161 0 : if ( nNewSymbolsSize != m_nSymbolsSize )
162 : {
163 0 : m_nSymbolsSize = nNewSymbolsSize;
164 0 : bool bLarge( m_nSymbolsSize == SFX_SYMBOLS_SIZE_LARGE );
165 :
166 0 : for ( size_t n=0; n < m_aToolBoxes.size(); n++ )
167 : {
168 0 : ToolBoxInf_Impl *pInf = m_aToolBoxes[n];
169 0 : if ( pInf->nFlags & SfxToolboxFlags::CHANGESYMBOLSET )
170 : {
171 0 : ToolBox *pBox = pInf->pToolBox;
172 0 : sal_uInt16 nCount = pBox->GetItemCount();
173 0 : for ( sal_uInt16 nPos=0; nPos<nCount; nPos++ )
174 : {
175 0 : sal_uInt16 nId = pBox->GetItemId( nPos );
176 0 : if ( pBox->GetItemType(nPos) == ToolBoxItemType::BUTTON )
177 : {
178 0 : pBox->SetItemImage( nId, GetImage( nId, bLarge ) );
179 0 : SfxStateCache *pCache = SfxViewFrame::Current()->GetBindings().GetStateCache( nId );
180 0 : if ( pCache )
181 0 : pCache->SetCachedState();
182 : }
183 : }
184 :
185 0 : if ( !pBox->IsFloatingMode() )
186 : {
187 0 : Size aActSize( pBox->GetSizePixel() );
188 0 : Size aSize( pBox->CalcWindowSizePixel() );
189 0 : if ( pBox->IsHorizontal() )
190 0 : aSize.Width() = aActSize.Width();
191 : else
192 0 : aSize.Height() = aActSize.Height();
193 :
194 0 : pBox->SetSizePixel( aSize );
195 : }
196 : }
197 : }
198 0 : }
199 0 : }
200 :
201 :
202 :
203 0 : IMPL_LINK_NOARG(SfxImageManager_Impl, OptionsChanged_Impl)
204 : {
205 0 : SetSymbolsSize_Impl( m_aOpt.GetCurrentSymbolsSize() );
206 0 : return 0L;
207 : }
208 :
209 :
210 :
211 33250 : IMPL_LINK( SfxImageManager_Impl, SettingsChanged_Impl, VclWindowEvent*, pEvent)
212 : {
213 16625 : if (pEvent)
214 : {
215 16625 : switch (pEvent->GetId())
216 : {
217 : case VCLEVENT_OBJECT_DYING:
218 43 : if (m_bAppEventListener)
219 : {
220 43 : Application::RemoveEventListener( LINK( this, SfxImageManager_Impl, SettingsChanged_Impl ) );
221 43 : m_bAppEventListener = false;
222 : }
223 43 : break;
224 : case VCLEVENT_APPLICATION_DATACHANGED:
225 : // Check if toolbar button size have changed and we have to use system settings
226 : {
227 0 : sal_Int16 nSymbolsSize = m_aOpt.GetCurrentSymbolsSize();
228 0 : if (m_nSymbolsSize != nSymbolsSize)
229 0 : SetSymbolsSize_Impl(nSymbolsSize);
230 : }
231 0 : break;
232 : default:
233 16582 : break;
234 : }
235 : }
236 16625 : return 0L;
237 : }
238 :
239 43 : SfxImageManager::SfxImageManager(SfxModule& rModule)
240 : {
241 43 : pImp = ::GetImageManager(rModule);
242 43 : }
243 :
244 43 : SfxImageManager::~SfxImageManager()
245 : {
246 43 : }
247 :
248 : namespace
249 : {
250 : typedef std::unordered_map< SfxModule*, boost::shared_ptr<SfxImageManager> > SfxImageManagerMap;
251 :
252 : class theImageManagerMap :
253 : public rtl::Static<SfxImageManagerMap, theImageManagerMap> {};
254 : }
255 :
256 2001 : SfxImageManager* SfxImageManager::GetImageManager(SfxModule& rModule)
257 : {
258 2001 : SolarMutexGuard aGuard;
259 2001 : SfxImageManager* pSfxImageManager(0);
260 :
261 2001 : SfxImageManagerMap &rImageManagerMap = theImageManagerMap::get();
262 2001 : SfxModule* pModule = &rModule;
263 2001 : SfxImageManagerMap::const_iterator pIter = rImageManagerMap.find(pModule);
264 2001 : if ( pIter != rImageManagerMap.end() )
265 1958 : pSfxImageManager = pIter->second.get();
266 : else
267 : {
268 43 : rImageManagerMap[pModule].reset(new SfxImageManager(rModule));
269 43 : pSfxImageManager = rImageManagerMap[pModule].get();
270 : }
271 2001 : return pSfxImageManager;
272 : }
273 :
274 0 : Image SfxImageManager::GetImage( sal_uInt16 nId, bool bBig ) const
275 : {
276 0 : ImageList* pImageList = pImp->GetImageList( bBig );
277 0 : if ( pImageList && pImageList->HasImageAtPos( nId ) )
278 0 : return pImageList->GetImage( nId );
279 0 : return Image();
280 : }
281 :
282 0 : Image SfxImageManager::GetImage( sal_uInt16 nId ) const
283 : {
284 0 : bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge();
285 0 : return GetImage( nId, bLarge );
286 : }
287 :
288 1014 : Image SfxImageManager::SeekImage( sal_uInt16 nId, bool bBig ) const
289 : {
290 1014 : ImageList* pImageList = pImp->GetImageList( bBig );
291 1014 : if (pImageList && pImageList->HasImageAtPos(nId))
292 1014 : return pImageList->GetImage( nId );
293 0 : return Image();
294 : }
295 :
296 1014 : Image SfxImageManager::SeekImage( sal_uInt16 nId ) const
297 : {
298 1014 : bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge();
299 1014 : return SeekImage( nId, bLarge );
300 : }
301 :
302 354 : void SfxImageManager::RegisterToolBox( ToolBox *pBox, SfxToolboxFlags nFlags )
303 : {
304 354 : SolarMutexGuard aGuard;
305 :
306 354 : ToolBoxInf_Impl* pInf = new ToolBoxInf_Impl;
307 354 : pInf->pToolBox = pBox;
308 354 : pInf->nFlags = nFlags;
309 354 : pImp->m_aToolBoxes.push_back( pInf );
310 354 : }
311 :
312 :
313 :
314 352 : void SfxImageManager::ReleaseToolBox( ToolBox *pBox )
315 : {
316 352 : SolarMutexGuard aGuard;
317 :
318 353 : for ( size_t n=0; n < pImp->m_aToolBoxes.size(); n++ )
319 : {
320 353 : if ((pImp->m_aToolBoxes[n])->pToolBox == pBox )
321 : {
322 352 : delete pImp->m_aToolBoxes[n];
323 352 : pImp->m_aToolBoxes.erase( pImp->m_aToolBoxes.begin() + n );
324 704 : return;
325 : }
326 0 : }
327 : }
328 :
329 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|