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 //*****************************************************************************************************************
SvtStartOptions_Impl()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 //*****************************************************************************************************************
~SvtStartOptions_Impl()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 //*****************************************************************************************************************
Notify(const Sequence<OUString> & seqPropertyNames)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 //*****************************************************************************************************************
Commit()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 //*****************************************************************************************************************
IsIntroEnabled() const300 sal_Bool SvtStartOptions_Impl::IsIntroEnabled() const
301 {
302 return m_bShowIntro;
303 }
304
305 //*****************************************************************************************************************
306 // public method
307 //*****************************************************************************************************************
EnableIntro(sal_Bool bState)308 void SvtStartOptions_Impl::EnableIntro( sal_Bool bState )
309 {
310 m_bShowIntro = bState;
311 SetModified();
312 }
313
314 //*****************************************************************************************************************
315 // public method
316 //*****************************************************************************************************************
GetConnectionURL() const317 OUString SvtStartOptions_Impl::GetConnectionURL() const
318 {
319 return m_sConnectionURL;
320 }
321
322 //*****************************************************************************************************************
323 // public method
324 //*****************************************************************************************************************
SetConnectionURL(const OUString & sURL)325 void SvtStartOptions_Impl::SetConnectionURL( const OUString& sURL )
326 {
327 m_sConnectionURL = sURL;
328 SetModified();
329 }
330
331 //*****************************************************************************************************************
332 // private method
333 //*****************************************************************************************************************
impl_GetPropertyNames()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 //*****************************************************************************************************************
SvtStartOptions()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 //*****************************************************************************************************************
~SvtStartOptions()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 //*****************************************************************************************************************
IsIntroEnabled() const396 sal_Bool SvtStartOptions::IsIntroEnabled() const
397 {
398 MutexGuard aGuard( GetOwnStaticMutex() );
399 return m_pDataContainer->IsIntroEnabled();
400 }
401
402 //*****************************************************************************************************************
403 // public method
404 //*****************************************************************************************************************
EnableIntro(sal_Bool bState)405 void SvtStartOptions::EnableIntro( sal_Bool bState )
406 {
407 MutexGuard aGuard( GetOwnStaticMutex() );
408 m_pDataContainer->EnableIntro( bState );
409 }
410
411 //*****************************************************************************************************************
412 // public method
413 //*****************************************************************************************************************
GetConnectionURL() const414 OUString SvtStartOptions::GetConnectionURL() const
415 {
416 MutexGuard aGuard( GetOwnStaticMutex() );
417 return m_pDataContainer->GetConnectionURL();
418 }
419
420 //*****************************************************************************************************************
421 // public method
422 //*****************************************************************************************************************
SetConnectionURL(const OUString & sURL)423 void SvtStartOptions::SetConnectionURL( const OUString& sURL )
424 {
425 MutexGuard aGuard( GetOwnStaticMutex() );
426 m_pDataContainer->SetConnectionURL( sURL );
427 }
428
429 //*****************************************************************************************************************
430 // private method
431 //*****************************************************************************************************************
GetOwnStaticMutex()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