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_unotools.hxx" 30 #ifndef GCC 31 #endif 32 33 //_________________________________________________________________________________________________________________ 34 // includes 35 //_________________________________________________________________________________________________________________ 36 37 #include <unotools/startoptions.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 44 #include <rtl/logfile.hxx> 45 #include "itemholder1.hxx" 46 //_________________________________________________________________________________________________________________ 47 // namespaces 48 //_________________________________________________________________________________________________________________ 49 50 using namespace ::utl ; 51 using namespace ::rtl ; 52 using namespace ::osl ; 53 using namespace ::com::sun::star::uno ; 54 55 //_________________________________________________________________________________________________________________ 56 // const 57 //_________________________________________________________________________________________________________________ 58 59 #define DEFAULT_SHOWINTRO sal_True 60 #define DEFAULT_CONNECTIONURL OUString() 61 62 #define ROOTNODE_START OUString(RTL_CONSTASCII_USTRINGPARAM("Setup/Office" )) 63 #define PROPERTYNAME_SHOWINTRO OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupShowIntro" )) 64 #define PROPERTYNAME_CONNECTIONURL OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupConnectionURL" )) 65 66 #define PROPERTYHANDLE_SHOWINTRO 0 67 #define PROPERTYHANDLE_CONNECTIONURL 1 68 69 #define PROPERTYCOUNT 2 70 71 //_________________________________________________________________________________________________________________ 72 // private declarations! 73 //_________________________________________________________________________________________________________________ 74 75 class SvtStartOptions_Impl : public ConfigItem 76 { 77 //------------------------------------------------------------------------------------------------------------- 78 // public methods 79 //------------------------------------------------------------------------------------------------------------- 80 81 public: 82 83 //--------------------------------------------------------------------------------------------------------- 84 // constructor / destructor 85 //--------------------------------------------------------------------------------------------------------- 86 87 SvtStartOptions_Impl(); 88 ~SvtStartOptions_Impl(); 89 90 //--------------------------------------------------------------------------------------------------------- 91 // overloaded methods of baseclass 92 //--------------------------------------------------------------------------------------------------------- 93 94 /*-****************************************************************************************************//** 95 @short called for notify of configmanager 96 @descr These method is called from the ConfigManager before application ends or from the 97 PropertyChangeListener if the sub tree broadcasts changes. You must update your 98 internal values. 99 100 @ATTENTION We don't implement these method - because we support readonly values at runtime only! 101 102 @seealso baseclass ConfigItem 103 104 @param "seqPropertyNames" is the list of properties which should be updated. 105 @return - 106 107 @onerror - 108 *//*-*****************************************************************************************************/ 109 110 virtual void Notify( const Sequence< OUString >& seqPropertyNames ); 111 112 /*-****************************************************************************************************//** 113 @short write changes to configuration 114 @descr These method writes the changed values into the sub tree 115 and should always called in our destructor to guarantee consistency of config data. 116 117 @ATTENTION We don't implement these method - because we support readonly values at runtime only! 118 119 @seealso baseclass ConfigItem 120 121 @param - 122 @return - 123 124 @onerror - 125 *//*-*****************************************************************************************************/ 126 127 virtual void Commit(); 128 129 //--------------------------------------------------------------------------------------------------------- 130 // public interface 131 //--------------------------------------------------------------------------------------------------------- 132 133 /*-****************************************************************************************************//** 134 @short access method to get internal values 135 @descr These method give us a chance to regulate acces to ouer internal values. 136 It's not used in the moment - but it's possible for the feature! 137 138 @seealso - 139 140 @param - 141 @return - 142 143 @onerror - 144 *//*-*****************************************************************************************************/ 145 146 sal_Bool IsIntroEnabled ( ) const ; 147 void EnableIntro ( sal_Bool bState ) ; 148 OUString GetConnectionURL( ) const ; 149 void SetConnectionURL( const OUString& sURL ) ; 150 151 //------------------------------------------------------------------------------------------------------------- 152 // private methods 153 //------------------------------------------------------------------------------------------------------------- 154 155 private: 156 157 /*-****************************************************************************************************//** 158 @short return list of fix key names of ouer configuration management which represent oue module tree 159 @descr These methods return a static const list of key names. We need it to get needed values from our 160 configuration management. We return well known key names only - because the "UserData" node 161 is handled in a special way! 162 163 @seealso - 164 165 @param - 166 @return A list of needed configuration keys is returned. 167 168 @onerror - 169 *//*-*****************************************************************************************************/ 170 171 static Sequence< OUString > impl_GetPropertyNames(); 172 173 //------------------------------------------------------------------------------------------------------------- 174 // private member 175 //------------------------------------------------------------------------------------------------------------- 176 177 private: 178 179 sal_Bool m_bShowIntro ; /// cache "ShowIntro" of Start section 180 OUString m_sConnectionURL ; /// cache "Connection" of Start section 181 }; 182 183 //_________________________________________________________________________________________________________________ 184 // definitions 185 //_________________________________________________________________________________________________________________ 186 187 //***************************************************************************************************************** 188 // constructor 189 //***************************************************************************************************************** 190 SvtStartOptions_Impl::SvtStartOptions_Impl() 191 // Init baseclasses first 192 : ConfigItem ( ROOTNODE_START ) 193 // Init member then. 194 , m_bShowIntro ( DEFAULT_SHOWINTRO ) 195 { 196 // Use our static list of configuration keys to get his values. 197 Sequence< OUString > seqNames = impl_GetPropertyNames(); 198 Sequence< Any > seqValues = GetProperties( seqNames ) ; 199 200 // Safe impossible cases. 201 // We need values from ALL configuration keys. 202 // Follow assignment use order of values in relation to our list of key names! 203 DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtStartOptions_Impl::SvtStartOptions_Impl()\nI miss some values of configuration keys!\n" ); 204 205 // Copy values from list in right order to ouer internal member. 206 sal_Int32 nPropertyCount = seqValues.getLength() ; 207 sal_Int32 nProperty = 0 ; 208 for( nProperty=0; nProperty<nPropertyCount; ++nProperty ) 209 { 210 // Safe impossible cases. 211 // Check any for valid value. 212 DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtStartOptions_Impl::SvtStartOptions_Impl()\nInvalid property value for property detected!\n" ); 213 switch( nProperty ) 214 { 215 case PROPERTYHANDLE_SHOWINTRO : { 216 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtStartOptions_Impl::SvtStartOptions_Impl()\nWho has changed the value type of \"Office.Common\\Start\\ShowIntro\"?" ); 217 seqValues[nProperty] >>= m_bShowIntro; 218 } 219 break; 220 221 case PROPERTYHANDLE_CONNECTIONURL : { 222 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_STRING), "SvtStartOptions_Impl::SvtStartOptions_Impl()\nWho has changed the value type of \"Office.Common\\Start\\Connection\"?" ); 223 seqValues[nProperty] >>= m_sConnectionURL; 224 } 225 break; 226 } 227 } 228 229 // Don't enable notification mechanism of ouer baseclass! 230 // We support readonly variables in the moment. 231 } 232 233 //***************************************************************************************************************** 234 // destructor 235 //***************************************************************************************************************** 236 SvtStartOptions_Impl::~SvtStartOptions_Impl() 237 { 238 // We must save our current values .. if user forget it! 239 if( IsModified() == sal_True ) 240 { 241 Commit(); 242 } 243 } 244 245 //***************************************************************************************************************** 246 // public method 247 //***************************************************************************************************************** 248 void SvtStartOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames ) 249 { 250 // Use given list of updated properties to get his values from configuration directly! 251 Sequence< Any > seqValues = GetProperties( seqPropertyNames ); 252 // Safe impossible cases. 253 // We need values from ALL notified configuration keys. 254 DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtStartOptions_Impl::Notify()\nI miss some values of configuration keys!\n" ); 255 // Step over list of property names and get right value from coreesponding value list to set it on internal members! 256 sal_Int32 nCount = seqPropertyNames.getLength(); 257 for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) 258 { 259 if( seqPropertyNames[nProperty] == PROPERTYNAME_SHOWINTRO ) 260 { 261 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtStartOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\Start\\ShowIntro\"?" ); 262 seqValues[nProperty] >>= m_bShowIntro; 263 } 264 else 265 if( seqPropertyNames[nProperty] == PROPERTYNAME_CONNECTIONURL ) 266 { 267 DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_STRING), "SvtStartOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\Start\\Connection\"?" ); 268 seqValues[nProperty] >>= m_sConnectionURL; 269 } 270 #if OSL_DEBUG_LEVEL > 1 271 else DBG_ASSERT( sal_False, "SvtStartOptions_Impl::Notify()\nUnkown property detected ... I can't handle these!\n" ); 272 #endif 273 } 274 } 275 276 //***************************************************************************************************************** 277 // public method 278 //***************************************************************************************************************** 279 void SvtStartOptions_Impl::Commit() 280 { 281 // Get names of supported properties, create a list for values and copy current values to it. 282 Sequence< OUString > seqNames = impl_GetPropertyNames(); 283 sal_Int32 nCount = seqNames.getLength(); 284 Sequence< Any > seqValues ( nCount ); 285 for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) 286 { 287 switch( nProperty ) 288 { 289 case PROPERTYHANDLE_SHOWINTRO : { 290 seqValues[nProperty] <<= m_bShowIntro; 291 } 292 break; 293 case PROPERTYHANDLE_CONNECTIONURL : { 294 seqValues[nProperty] <<= m_sConnectionURL; 295 } 296 break; 297 } 298 } 299 // Set properties in configuration. 300 PutProperties( seqNames, seqValues ); 301 } 302 303 //***************************************************************************************************************** 304 // public method 305 //***************************************************************************************************************** 306 sal_Bool SvtStartOptions_Impl::IsIntroEnabled() const 307 { 308 return m_bShowIntro; 309 } 310 311 //***************************************************************************************************************** 312 // public method 313 //***************************************************************************************************************** 314 void SvtStartOptions_Impl::EnableIntro( sal_Bool bState ) 315 { 316 m_bShowIntro = bState; 317 SetModified(); 318 } 319 320 //***************************************************************************************************************** 321 // public method 322 //***************************************************************************************************************** 323 OUString SvtStartOptions_Impl::GetConnectionURL() const 324 { 325 return m_sConnectionURL; 326 } 327 328 //***************************************************************************************************************** 329 // public method 330 //***************************************************************************************************************** 331 void SvtStartOptions_Impl::SetConnectionURL( const OUString& sURL ) 332 { 333 m_sConnectionURL = sURL; 334 SetModified(); 335 } 336 337 //***************************************************************************************************************** 338 // private method 339 //***************************************************************************************************************** 340 Sequence< OUString > SvtStartOptions_Impl::impl_GetPropertyNames() 341 { 342 // Build static list of configuration key names. 343 static const OUString pProperties[] = 344 { 345 PROPERTYNAME_SHOWINTRO , 346 PROPERTYNAME_CONNECTIONURL , 347 }; 348 // Initialize return sequence with these list ... 349 static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); 350 // ... and return it. 351 return seqPropertyNames; 352 } 353 354 //***************************************************************************************************************** 355 // initialize static member 356 // DON'T DO IT IN YOUR HEADER! 357 // see definition for further informations 358 //***************************************************************************************************************** 359 SvtStartOptions_Impl* SvtStartOptions::m_pDataContainer = NULL ; 360 sal_Int32 SvtStartOptions::m_nRefCount = 0 ; 361 362 //***************************************************************************************************************** 363 // constructor 364 //***************************************************************************************************************** 365 SvtStartOptions::SvtStartOptions() 366 { 367 // Global access, must be guarded (multithreading!). 368 MutexGuard aGuard( GetOwnStaticMutex() ); 369 // Increase ouer refcount ... 370 ++m_nRefCount; 371 // ... and initialize ouer data container only if it not already! 372 if( m_pDataContainer == NULL ) 373 { 374 RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtStartOptions_Impl::ctor()"); 375 m_pDataContainer = new SvtStartOptions_Impl(); 376 377 ItemHolder1::holdConfigItem(E_STARTOPTIONS); 378 } 379 } 380 381 //***************************************************************************************************************** 382 // destructor 383 //***************************************************************************************************************** 384 SvtStartOptions::~SvtStartOptions() 385 { 386 // Global access, must be guarded (multithreading!) 387 MutexGuard aGuard( GetOwnStaticMutex() ); 388 // Decrease ouer refcount. 389 --m_nRefCount; 390 // If last instance was deleted ... 391 // we must destroy ouer static data container! 392 if( m_nRefCount <= 0 ) 393 { 394 delete m_pDataContainer; 395 m_pDataContainer = NULL; 396 } 397 } 398 399 //***************************************************************************************************************** 400 // public method 401 //***************************************************************************************************************** 402 sal_Bool SvtStartOptions::IsIntroEnabled() const 403 { 404 MutexGuard aGuard( GetOwnStaticMutex() ); 405 return m_pDataContainer->IsIntroEnabled(); 406 } 407 408 //***************************************************************************************************************** 409 // public method 410 //***************************************************************************************************************** 411 void SvtStartOptions::EnableIntro( sal_Bool bState ) 412 { 413 MutexGuard aGuard( GetOwnStaticMutex() ); 414 m_pDataContainer->EnableIntro( bState ); 415 } 416 417 //***************************************************************************************************************** 418 // public method 419 //***************************************************************************************************************** 420 OUString SvtStartOptions::GetConnectionURL() const 421 { 422 MutexGuard aGuard( GetOwnStaticMutex() ); 423 return m_pDataContainer->GetConnectionURL(); 424 } 425 426 //***************************************************************************************************************** 427 // public method 428 //***************************************************************************************************************** 429 void SvtStartOptions::SetConnectionURL( const OUString& sURL ) 430 { 431 MutexGuard aGuard( GetOwnStaticMutex() ); 432 m_pDataContainer->SetConnectionURL( sURL ); 433 } 434 435 //***************************************************************************************************************** 436 // private method 437 //***************************************************************************************************************** 438 Mutex& SvtStartOptions::GetOwnStaticMutex() 439 { 440 // Initialize static mutex only for one time! 441 static Mutex* pMutex = NULL; 442 // If these method first called (Mutex not already exist!) ... 443 if( pMutex == NULL ) 444 { 445 // ... we must create a new one. Protect follow code with the global mutex - 446 // It must be - we create a static variable! 447 MutexGuard aGuard( Mutex::getGlobalMutex() ); 448 // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these! 449 if( pMutex == NULL ) 450 { 451 // Create the new mutex and set it for return on static variable. 452 static Mutex aMutex; 453 pMutex = &aMutex; 454 } 455 } 456 // Return new created or already existing mutex object. 457 return *pMutex; 458 } 459