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