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