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