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