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