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_svtools.hxx"
26 #ifndef GCC
27 #endif
28
29 //_________________________________________________________________________________________________________________
30 // includes
31 //_________________________________________________________________________________________________________________
32
33 #include <svtools/menuoptions.hxx>
34 #include <unotools/configmgr.hxx>
35 #include <unotools/configitem.hxx>
36 #include <tools/debug.hxx>
37 #include <com/sun/star/uno/Any.hxx>
38 #include <com/sun/star/uno/Sequence.hxx>
39 #include <vcl/svapp.hxx>
40
41 #include <rtl/logfile.hxx>
42 #include "itemholder2.hxx"
43
44 //_________________________________________________________________________________________________________________
45 // namespaces
46 //_________________________________________________________________________________________________________________
47
48 using namespace ::utl ;
49 using namespace ::rtl ;
50 using namespace ::osl ;
51 using namespace ::com::sun::star::uno ;
52
53 //_________________________________________________________________________________________________________________
54 // const
55 //_________________________________________________________________________________________________________________
56
57 #define ROOTNODE_MENU OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/View/Menu" ))
58 #define DEFAULT_DONTHIDEDISABLEDENTRIES sal_False
59 #define DEFAULT_FOLLOWMOUSE sal_True
60 #define DEFAULT_MENUICONS 2
61
62 #define PROPERTYNAME_DONTHIDEDISABLEDENTRIES OUString(RTL_CONSTASCII_USTRINGPARAM("DontHideDisabledEntry" ))
63 #define PROPERTYNAME_FOLLOWMOUSE OUString(RTL_CONSTASCII_USTRINGPARAM("FollowMouse" ))
64 #define PROPERTYNAME_SHOWICONSINMENUES OUString(RTL_CONSTASCII_USTRINGPARAM("ShowIconsInMenues" ))
65 #define PROPERTYNAME_SYSTEMICONSINMENUES OUString(RTL_CONSTASCII_USTRINGPARAM("IsSystemIconsInMenus" ))
66
67 #define PROPERTYHANDLE_DONTHIDEDISABLEDENTRIES 0
68 #define PROPERTYHANDLE_FOLLOWMOUSE 1
69 #define PROPERTYHANDLE_SHOWICONSINMENUES 2
70 #define PROPERTYHANDLE_SYSTEMICONSINMENUES 3
71
72 #define PROPERTYCOUNT 4
73
74 #include <tools/link.hxx>
75 #include <tools/list.hxx>
76 DECLARE_LIST( LinkList, Link * )
77
78 //_________________________________________________________________________________________________________________
79 // private declarations!
80 //_________________________________________________________________________________________________________________
81
82 class SvtMenuOptions_Impl : public ConfigItem
83 {
84 //-------------------------------------------------------------------------------------------------------------
85 // private member
86 //-------------------------------------------------------------------------------------------------------------
87
88 private:
89 LinkList aList;
90 sal_Bool m_bDontHideDisabledEntries ; /// cache "DontHideDisabledEntries" of Menu section
91 sal_Bool m_bFollowMouse ; /// cache "FollowMouse" of Menu section
92 sal_Int16 m_nMenuIcons ; /// cache "MenuIcons" of Menu section
93
94 //-------------------------------------------------------------------------------------------------------------
95 // public methods
96 //-------------------------------------------------------------------------------------------------------------
97
98 public:
99
100 //---------------------------------------------------------------------------------------------------------
101 // constructor / destructor
102 //---------------------------------------------------------------------------------------------------------
103
104 SvtMenuOptions_Impl();
105 ~SvtMenuOptions_Impl();
106
107 void AddListenerLink( const Link& rLink );
108 void RemoveListenerLink( const Link& rLink );
109
110 //---------------------------------------------------------------------------------------------------------
111 // overloaded methods of baseclass
112 //---------------------------------------------------------------------------------------------------------
113
114 /*-****************************************************************************************************//**
115 @short called for notify of configmanager
116 @descr These method is called from the ConfigManager before application ends or from the
117 PropertyChangeListener if the sub tree broadcasts changes. You must update your
118 internal values.
119
120 @seealso baseclass ConfigItem
121
122 @param "seqPropertyNames" is the list of properties which should be updated.
123 @return -
124
125 @onerror -
126 *//*-*****************************************************************************************************/
127
128 virtual void Notify( const Sequence< OUString >& seqPropertyNames );
129
130 /*-****************************************************************************************************//**
131 @short write changes to configuration
132 @descr These method writes the changed values into the sub tree
133 and should always called in our destructor to guarantee consistency of config data.
134
135 @seealso baseclass ConfigItem
136
137 @param -
138 @return -
139
140 @onerror -
141 *//*-*****************************************************************************************************/
142
143 virtual void Commit();
144
145 //---------------------------------------------------------------------------------------------------------
146 // public interface
147 //---------------------------------------------------------------------------------------------------------
148
149 /*-****************************************************************************************************//**
150 @short access method to get internal values
151 @descr These method give us a chance to regulate acces to ouer internal values.
152 It's not used in the moment - but it's possible for the feature!
153
154 @seealso -
155
156 @param -
157 @return -
158
159 @onerror -
160 *//*-*****************************************************************************************************/
161
IsEntryHidingEnabled() const162 sal_Bool IsEntryHidingEnabled() const
163 { return m_bDontHideDisabledEntries; }
164
IsFollowMouseEnabled() const165 sal_Bool IsFollowMouseEnabled() const
166 { return m_bFollowMouse; }
167
GetMenuIconsState() const168 sal_Int16 GetMenuIconsState() const
169 { return m_nMenuIcons; }
170
SetEntryHidingState(sal_Bool bState)171 void SetEntryHidingState ( sal_Bool bState )
172 {
173 m_bDontHideDisabledEntries = bState;
174 SetModified();
175 for ( sal_uInt16 n=0; n<aList.Count(); n++ )
176 aList.GetObject(n)->Call( this );
177 Commit();
178 }
179
SetFollowMouseState(sal_Bool bState)180 void SetFollowMouseState ( sal_Bool bState )
181 {
182 m_bFollowMouse = bState;
183 SetModified();
184 for ( sal_uInt16 n=0; n<aList.Count(); n++ )
185 aList.GetObject(n)->Call( this );
186 Commit();
187 }
188
SetMenuIconsState(sal_Int16 bState)189 void SetMenuIconsState ( sal_Int16 bState )
190 {
191 m_nMenuIcons = bState;
192 SetModified();
193 for ( sal_uInt16 n=0; n<aList.Count(); n++ )
194 aList.GetObject(n)->Call( this );
195 Commit();
196 }
197
198 //-------------------------------------------------------------------------------------------------------------
199 // private methods
200 //-------------------------------------------------------------------------------------------------------------
201
202 private:
203
204 /*-****************************************************************************************************//**
205 @short return list of fix key names of ouer configuration management which represent oue module tree
206 @descr These methods return a static const list of key names. We need it to get needed values from our
207 configuration management.
208
209 @seealso -
210
211 @param -
212 @return A list of needed configuration keys is returned.
213
214 @onerror -
215 *//*-*****************************************************************************************************/
216
217 static Sequence< OUString > impl_GetPropertyNames();
218 };
219
220 //_________________________________________________________________________________________________________________
221 // definitions
222 //_________________________________________________________________________________________________________________
223
224 //*****************************************************************************************************************
225 // constructor
226 //*****************************************************************************************************************
SvtMenuOptions_Impl()227 SvtMenuOptions_Impl::SvtMenuOptions_Impl()
228 // Init baseclasses first
229 : ConfigItem ( ROOTNODE_MENU )
230 // Init member then.
231 , m_bDontHideDisabledEntries ( DEFAULT_DONTHIDEDISABLEDENTRIES )
232 , m_bFollowMouse ( DEFAULT_FOLLOWMOUSE )
233 , m_nMenuIcons ( DEFAULT_MENUICONS )
234 {
235 // Use our static list of configuration keys to get his values.
236 Sequence< OUString > seqNames = impl_GetPropertyNames();
237 Sequence< Any > seqValues = GetProperties( seqNames ) ;
238
239 // Safe impossible cases.
240 // We need values from ALL configuration keys.
241 // Follow assignment use order of values in relation to our list of key names!
242 DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nI miss some values of configuration keys!\n" );
243
244 sal_Bool bMenuIcons = true;
245 sal_Bool bSystemMenuIcons = true;
246
247 // Copy values from list in right order to ouer internal member.
248 sal_Int32 nPropertyCount = seqValues.getLength() ;
249 sal_Int32 nProperty = 0 ;
250 for( nProperty=0; nProperty<nPropertyCount; ++nProperty )
251 {
252 // Safe impossible cases.
253 // Check any for valid value.
254 DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nInvalid property value for property detected!\n" );
255 switch( nProperty )
256 {
257 case PROPERTYHANDLE_DONTHIDEDISABLEDENTRIES : {
258 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\DontHideDisabledEntry\"?" );
259 seqValues[nProperty] >>= m_bDontHideDisabledEntries;
260 }
261 break;
262
263 case PROPERTYHANDLE_FOLLOWMOUSE : {
264 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\FollowMouse\"?" );
265 seqValues[nProperty] >>= m_bFollowMouse;
266 }
267 break;
268 case PROPERTYHANDLE_SHOWICONSINMENUES : {
269 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\ShowIconsInMenues\"?" );
270 seqValues[nProperty] >>= bMenuIcons;
271 }
272 break;
273 case PROPERTYHANDLE_SYSTEMICONSINMENUES : {
274 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\IsSystemIconsInMenus\"?" );
275 seqValues[nProperty] >>= bSystemMenuIcons;
276 }
277 break;
278 }
279 }
280
281 m_nMenuIcons = bSystemMenuIcons ? 2 : bMenuIcons;
282
283 EnableNotification( seqNames );
284 }
285
286 //*****************************************************************************************************************
287 // destructor
288 //*****************************************************************************************************************
~SvtMenuOptions_Impl()289 SvtMenuOptions_Impl::~SvtMenuOptions_Impl()
290 {
291 // Flush data to configuration!
292 // User has no chance to do that.
293 if( IsModified() == sal_True )
294 {
295 Commit();
296 }
297
298 for ( sal_uInt16 n=0; n<aList.Count(); )
299 delete aList.Remove(n);
300 }
301
302 //*****************************************************************************************************************
303 // public method
304 //*****************************************************************************************************************
Notify(const Sequence<OUString> & seqPropertyNames)305 void SvtMenuOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames )
306 {
307 // Use given list of updated properties to get his values from configuration directly!
308 Sequence< Any > seqValues = GetProperties( seqPropertyNames );
309 // Safe impossible cases.
310 // We need values from ALL notified configuration keys.
311 DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtMenuOptions_Impl::Notify()\nI miss some values of configuration keys!\n" );
312
313 sal_Bool bMenuSettingsChanged = sal_False;
314 sal_Bool bMenuIcons = sal_True;
315 sal_Bool bSystemMenuIcons = sal_True;
316 if (m_nMenuIcons == 2)
317 bMenuIcons = (sal_Bool)(Application::GetSettings().GetStyleSettings().GetUseImagesInMenus());
318 else
319 {
320 bSystemMenuIcons = sal_False;
321 bMenuIcons = m_nMenuIcons ? sal_True : sal_False;
322 }
323
324 // Step over list of property names and get right value from coreesponding value list to set it on internal members!
325 sal_Int32 nCount = seqPropertyNames.getLength();
326 for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
327 {
328 if( seqPropertyNames[nProperty] == PROPERTYNAME_DONTHIDEDISABLEDENTRIES )
329 {
330 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\View\\Menu\\DontHideDisabledEntry\"?" );
331 seqValues[nProperty] >>= m_bDontHideDisabledEntries;
332 }
333 else if( seqPropertyNames[nProperty] == PROPERTYNAME_FOLLOWMOUSE )
334 {
335 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\View\\Menu\\FollowMouse\"?" );
336 seqValues[nProperty] >>= m_bFollowMouse;
337 }
338 else if( seqPropertyNames[nProperty] == PROPERTYNAME_SHOWICONSINMENUES )
339 {
340 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\ShowIconsInMenues\"?" );
341 bMenuSettingsChanged = seqValues[nProperty] >>= bMenuIcons;
342 }
343 else if( seqPropertyNames[nProperty] == PROPERTYNAME_SYSTEMICONSINMENUES )
344 {
345 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\IsSystemIconsInMenus\"?" );
346 bMenuSettingsChanged = seqValues[nProperty] >>= bSystemMenuIcons;
347 }
348
349 #if OSL_DEBUG_LEVEL > 1
350 else DBG_ASSERT( sal_False, "SvtMenuOptions_Impl::Notify()\nUnkown property detected ... I can't handle these!\n" );
351 #endif
352 }
353
354 if ( bMenuSettingsChanged )
355 m_nMenuIcons = bSystemMenuIcons ? 2 : bMenuIcons;
356
357 for ( sal_uInt16 n=0; n<aList.Count(); n++ )
358 aList.GetObject(n)->Call( this );
359 }
360
361 //*****************************************************************************************************************
362 // public method
363 //*****************************************************************************************************************
Commit()364 void SvtMenuOptions_Impl::Commit()
365 {
366 // Get names of supported properties, create a list for values and copy current values to it.
367 Sequence< OUString > seqNames = impl_GetPropertyNames();
368 sal_Int32 nCount = seqNames.getLength();
369 Sequence< Any > seqValues ( nCount );
370 for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
371 {
372 switch( nProperty )
373 {
374 case PROPERTYHANDLE_DONTHIDEDISABLEDENTRIES : {
375 seqValues[nProperty] <<= m_bDontHideDisabledEntries;
376 }
377 break;
378
379 case PROPERTYHANDLE_FOLLOWMOUSE : {
380 seqValues[nProperty] <<= m_bFollowMouse;
381 }
382 break;
383 //Output cache of current setting as possibly modified by System Theme for older version
384 case PROPERTYHANDLE_SHOWICONSINMENUES : {
385 sal_Bool bValue = (sal_Bool)(Application::GetSettings().GetStyleSettings().GetUseImagesInMenus());
386 seqValues[nProperty] <<= bValue;
387 }
388 break;
389 case PROPERTYHANDLE_SYSTEMICONSINMENUES : {
390 sal_Bool bValue = (m_nMenuIcons == 2 ? sal_True : sal_False) ;
391 seqValues[nProperty] <<= bValue;
392 }
393 break;
394 }
395 }
396 // Set properties in configuration.
397 PutProperties( seqNames, seqValues );
398 }
399
400 //*****************************************************************************************************************
401 // private method
402 //*****************************************************************************************************************
impl_GetPropertyNames()403 Sequence< OUString > SvtMenuOptions_Impl::impl_GetPropertyNames()
404 {
405 // Build static list of configuration key names.
406 static const OUString pProperties[] =
407 {
408 PROPERTYNAME_DONTHIDEDISABLEDENTRIES ,
409 PROPERTYNAME_FOLLOWMOUSE ,
410 PROPERTYNAME_SHOWICONSINMENUES ,
411 PROPERTYNAME_SYSTEMICONSINMENUES
412 };
413 // Initialize return sequence with these list ...
414 static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT );
415 // ... and return it.
416 return seqPropertyNames;
417 }
418
AddListenerLink(const Link & rLink)419 void SvtMenuOptions_Impl::AddListenerLink( const Link& rLink )
420 {
421 aList.Insert( new Link( rLink ) );
422 }
423
RemoveListenerLink(const Link & rLink)424 void SvtMenuOptions_Impl::RemoveListenerLink( const Link& rLink )
425 {
426 for ( sal_uInt16 n=0; n<aList.Count(); n++ )
427 {
428 if ( (*aList.GetObject(n) ) == rLink )
429 {
430 delete aList.Remove(n);
431 break;
432 }
433 }
434 }
435
436 //*****************************************************************************************************************
437 // initialize static member
438 // DON'T DO IT IN YOUR HEADER!
439 // see definition for further informations
440 //*****************************************************************************************************************
441 SvtMenuOptions_Impl* SvtMenuOptions::m_pDataContainer = NULL ;
442 sal_Int32 SvtMenuOptions::m_nRefCount = 0 ;
443
444 //*****************************************************************************************************************
445 // constructor
446 //*****************************************************************************************************************
SvtMenuOptions()447 SvtMenuOptions::SvtMenuOptions()
448 {
449 // Global access, must be guarded (multithreading!).
450 MutexGuard aGuard( GetOwnStaticMutex() );
451 // Increase ouer refcount ...
452 ++m_nRefCount;
453 // ... and initialize ouer data container only if it not already!
454 if( m_pDataContainer == NULL )
455 {
456 RTL_LOGFILE_CONTEXT(aLog, "svtools ( ??? ) ::SvtMenuOptions_Impl::ctor()");
457 m_pDataContainer = new SvtMenuOptions_Impl();
458
459 ItemHolder2::holdConfigItem(E_MENUOPTIONS);
460 }
461 }
462
463 //*****************************************************************************************************************
464 // destructor
465 //*****************************************************************************************************************
~SvtMenuOptions()466 SvtMenuOptions::~SvtMenuOptions()
467 {
468 // Global access, must be guarded (multithreading!)
469 MutexGuard aGuard( GetOwnStaticMutex() );
470 // Decrease ouer refcount.
471 --m_nRefCount;
472 // If last instance was deleted ...
473 // we must destroy ouer static data container!
474 if( m_nRefCount <= 0 )
475 {
476 delete m_pDataContainer;
477 m_pDataContainer = NULL;
478 }
479 }
480
481 //*****************************************************************************************************************
482 // public method
483 //*****************************************************************************************************************
IsEntryHidingEnabled() const484 sal_Bool SvtMenuOptions::IsEntryHidingEnabled() const
485 {
486 MutexGuard aGuard( GetOwnStaticMutex() );
487 return m_pDataContainer->IsEntryHidingEnabled();
488 }
489
490 //*****************************************************************************************************************
491 // public method
492 //*****************************************************************************************************************
IsFollowMouseEnabled() const493 sal_Bool SvtMenuOptions::IsFollowMouseEnabled() const
494 {
495 MutexGuard aGuard( GetOwnStaticMutex() );
496 return m_pDataContainer->IsFollowMouseEnabled();
497 }
498
499 //*****************************************************************************************************************
500 // public method
501 //*****************************************************************************************************************
SetEntryHidingState(sal_Bool bState)502 void SvtMenuOptions::SetEntryHidingState( sal_Bool bState )
503 {
504 MutexGuard aGuard( GetOwnStaticMutex() );
505 m_pDataContainer->SetEntryHidingState( bState );
506 }
507
508 //*****************************************************************************************************************
509 // public method
510 //*****************************************************************************************************************
SetFollowMouseState(sal_Bool bState)511 void SvtMenuOptions::SetFollowMouseState( sal_Bool bState )
512 {
513 MutexGuard aGuard( GetOwnStaticMutex() );
514 m_pDataContainer->SetFollowMouseState( bState );
515 }
516
517 //*****************************************************************************************************************
518 // public method
519 //*****************************************************************************************************************
GetMenuIconsState() const520 sal_Int16 SvtMenuOptions::GetMenuIconsState() const
521 {
522 MutexGuard aGuard( GetOwnStaticMutex() );
523 return m_pDataContainer->GetMenuIconsState();
524 }
525
526 //*****************************************************************************************************************
527 // public method
528 //*****************************************************************************************************************
SetMenuIconsState(sal_Int16 bState)529 void SvtMenuOptions::SetMenuIconsState( sal_Int16 bState )
530 {
531 MutexGuard aGuard( GetOwnStaticMutex() );
532 m_pDataContainer->SetMenuIconsState( bState );
533 }
534
535 //*****************************************************************************************************************
536 // private method
537 //*****************************************************************************************************************
GetOwnStaticMutex()538 Mutex& SvtMenuOptions::GetOwnStaticMutex()
539 {
540 // Initialize static mutex only for one time!
541 static Mutex* pMutex = NULL;
542 // If these method first called (Mutex not already exist!) ...
543 if( pMutex == NULL )
544 {
545 // ... we must create a new one. Protect follow code with the global mutex -
546 // It must be - we create a static variable!
547 MutexGuard aGuard( Mutex::getGlobalMutex() );
548 // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
549 if( pMutex == NULL )
550 {
551 // Create the new mutex and set it for return on static variable.
552 static Mutex aMutex;
553 pMutex = &aMutex;
554 }
555 }
556 // Return new created or already existing mutex object.
557 return *pMutex;
558 }
559
AddListenerLink(const Link & rLink)560 void SvtMenuOptions::AddListenerLink( const Link& rLink )
561 {
562 m_pDataContainer->AddListenerLink( rLink );
563 }
564
RemoveListenerLink(const Link & rLink)565 void SvtMenuOptions::RemoveListenerLink( const Link& rLink )
566 {
567 m_pDataContainer->RemoveListenerLink( rLink );
568 }
569