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