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 162 sal_Bool IsEntryHidingEnabled() const 163 { return m_bDontHideDisabledEntries; } 164 165 sal_Bool IsFollowMouseEnabled() const 166 { return m_bFollowMouse; } 167 168 sal_Int16 GetMenuIconsState() const 169 { return m_nMenuIcons; } 170 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 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 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 419 void SvtMenuOptions_Impl::AddListenerLink( const Link& rLink ) 420 { 421 aList.Insert( new Link( rLink ) ); 422 } 423 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 484 sal_Bool SvtMenuOptions::IsEntryHidingEnabled() const 485 { 486 MutexGuard aGuard( GetOwnStaticMutex() ); 487 return m_pDataContainer->IsEntryHidingEnabled(); 488 } 489 490 //***************************************************************************************************************** 491 // public method 492 //***************************************************************************************************************** 493 sal_Bool SvtMenuOptions::IsFollowMouseEnabled() const 494 { 495 MutexGuard aGuard( GetOwnStaticMutex() ); 496 return m_pDataContainer->IsFollowMouseEnabled(); 497 } 498 499 //***************************************************************************************************************** 500 // public method 501 //***************************************************************************************************************** 502 void SvtMenuOptions::SetEntryHidingState( sal_Bool bState ) 503 { 504 MutexGuard aGuard( GetOwnStaticMutex() ); 505 m_pDataContainer->SetEntryHidingState( bState ); 506 } 507 508 //***************************************************************************************************************** 509 // public method 510 //***************************************************************************************************************** 511 void SvtMenuOptions::SetFollowMouseState( sal_Bool bState ) 512 { 513 MutexGuard aGuard( GetOwnStaticMutex() ); 514 m_pDataContainer->SetFollowMouseState( bState ); 515 } 516 517 //***************************************************************************************************************** 518 // public method 519 //***************************************************************************************************************** 520 sal_Int16 SvtMenuOptions::GetMenuIconsState() const 521 { 522 MutexGuard aGuard( GetOwnStaticMutex() ); 523 return m_pDataContainer->GetMenuIconsState(); 524 } 525 526 //***************************************************************************************************************** 527 // public method 528 //***************************************************************************************************************** 529 void SvtMenuOptions::SetMenuIconsState( sal_Int16 bState ) 530 { 531 MutexGuard aGuard( GetOwnStaticMutex() ); 532 m_pDataContainer->SetMenuIconsState( bState ); 533 } 534 535 //***************************************************************************************************************** 536 // private method 537 //***************************************************************************************************************** 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 560 void SvtMenuOptions::AddListenerLink( const Link& rLink ) 561 { 562 m_pDataContainer->AddListenerLink( rLink ); 563 } 564 565 void SvtMenuOptions::RemoveListenerLink( const Link& rLink ) 566 { 567 m_pDataContainer->RemoveListenerLink( rLink ); 568 } 569