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/localisationoptions.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 //_________________________________________________________________________________________________________________
48 //	namespaces
49 //_________________________________________________________________________________________________________________
50 
51 using namespace ::utl					;
52 using namespace ::rtl					;
53 using namespace ::osl					;
54 using namespace ::com::sun::star::uno	;
55 
56 //_________________________________________________________________________________________________________________
57 //	const
58 //_________________________________________________________________________________________________________________
59 
60 #define	ROOTNODE_LOCALISATION			OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/View/Localisation"))
61 #define	DEFAULT_AUTOMNEMONIC			sal_False
62 #define	DEFAULT_DIALOGSCALE				0
63 
64 #define	PROPERTYNAME_AUTOMNEMONIC		OUString(RTL_CONSTASCII_USTRINGPARAM("AutoMnemonic"	))
65 #define	PROPERTYNAME_DIALOGSCALE		OUString(RTL_CONSTASCII_USTRINGPARAM("DialogScale"	))
66 
67 #define	PROPERTYHANDLE_AUTOMNEMONIC		0
68 #define	PROPERTYHANDLE_DIALOGSCALE		1
69 
70 #define	PROPERTYCOUNT					2
71 
72 //_________________________________________________________________________________________________________________
73 //	private declarations!
74 //_________________________________________________________________________________________________________________
75 
76 class SvtLocalisationOptions_Impl : public ConfigItem
77 {
78 	//-------------------------------------------------------------------------------------------------------------
79 	//	public methods
80 	//-------------------------------------------------------------------------------------------------------------
81 
82 	public:
83 
84 		//---------------------------------------------------------------------------------------------------------
85 		//	constructor / destructor
86 		//---------------------------------------------------------------------------------------------------------
87 
88 		 SvtLocalisationOptions_Impl();
89 		~SvtLocalisationOptions_Impl();
90 
91 		//---------------------------------------------------------------------------------------------------------
92 		//	overloaded methods of baseclass
93 		//---------------------------------------------------------------------------------------------------------
94 
95 		/*-****************************************************************************************************//**
96 			@short		called for notify of configmanager
97 			@descr		These method is called from the ConfigManager before application ends or from the
98 			 			PropertyChangeListener if the sub tree broadcasts changes. You must update your
99 						internal values.
100 
101 			@seealso	baseclass ConfigItem
102 
103 			@param		"seqPropertyNames" is the list of properties which should be updated.
104 			@return		-
105 
106 			@onerror	-
107 		*//*-*****************************************************************************************************/
108 
109     	virtual void Notify( const Sequence< OUString >& seqPropertyNames );
110 
111 		/*-****************************************************************************************************//**
112 			@short		write changes to configuration
113 			@descr		These method writes the changed values into the sub tree
114 						and should always called in our destructor to guarantee consistency of config data.
115 
116 			@seealso	baseclass ConfigItem
117 
118 			@param		-
119 			@return		-
120 
121 			@onerror	-
122 		*//*-*****************************************************************************************************/
123 
124     	virtual void Commit();
125 
126 		//---------------------------------------------------------------------------------------------------------
127 		//	public interface
128 		//---------------------------------------------------------------------------------------------------------
129 
130 		/*-****************************************************************************************************//**
131 			@short		access method to get internal values
132 			@descr		These method give us a chance to regulate acces to ouer internal values.
133 						It's not used in the moment - but it's possible for the feature!
134 
135 			@seealso	-
136 
137 			@param		-
138 			@return		-
139 
140 			@onerror	-
141 		*//*-*****************************************************************************************************/
142 
143 		sal_Bool	IsAutoMnemonic	(					) const	;
144 		void		SetAutoMnemonic	( sal_Bool	bState	)		;
145 		sal_Int32	GetDialogScale	(					) const	;
146 		void		SetDialogScale	( sal_Int32	nScale	)		;
147 
148 	//-------------------------------------------------------------------------------------------------------------
149 	//	private methods
150 	//-------------------------------------------------------------------------------------------------------------
151 
152 	private:
153 
154 		/*-****************************************************************************************************//**
155 			@short		return list of key names of ouer configuration management which represent oue module tree
156 			@descr		These methods return a static const list of key names. We need it to get needed values from our
157 						configuration management.
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 > GetPropertyNames();
168 
169 	//-------------------------------------------------------------------------------------------------------------
170 	//	private member
171 	//-------------------------------------------------------------------------------------------------------------
172 
173 	private:
174 
175 		sal_Bool	m_bAutoMnemonic		;
176 		sal_Int32	m_nDialogScale		;
177 };
178 
179 //_________________________________________________________________________________________________________________
180 //	definitions
181 //_________________________________________________________________________________________________________________
182 
183 //*****************************************************************************************************************
184 //	constructor
185 //*****************************************************************************************************************
186 SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()
187 	// Init baseclasses first
188     :	ConfigItem			( ROOTNODE_LOCALISATION	)
189 	// Init member then.
190 	,	m_bAutoMnemonic		( DEFAULT_AUTOMNEMONIC	)
191 	,	m_nDialogScale		( DEFAULT_DIALOGSCALE	)
192 {
193 	// Use our static list of configuration keys to get his values.
194 	Sequence< OUString >	seqNames	= GetPropertyNames	(			);
195 	Sequence< Any >			seqValues	= GetProperties		( seqNames	);
196 
197 	// Safe impossible cases.
198 	// We need values from ALL configuration keys.
199 	// Follow assignment use order of values in relation to our list of key names!
200 	DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nI miss some values of configuration keys!\n" );
201 
202 	// Copy values from list in right order to ouer internal member.
203 	sal_Int32 nPropertyCount = seqValues.getLength();
204 	for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
205 	{
206 		// Safe impossible cases.
207 		// Check any for valid value.
208 		DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nInvalid property value detected!\n" );
209         switch( nProperty )
210         {
211             case PROPERTYHANDLE_AUTOMNEMONIC	:	{
212 														DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Localisation\\AutoMnemonic\"?" );
213 														seqValues[nProperty] >>= m_bAutoMnemonic;
214 													}
215 													break;
216 
217 			case PROPERTYHANDLE_DIALOGSCALE		:	{
218 														DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Localisation\\DialogScale\"?" );
219 														seqValues[nProperty] >>= m_nDialogScale;
220 													}
221 													break;
222         }
223 	}
224 
225 	// Enable notification mechanism of ouer baseclass.
226 	// We need it to get information about changes outside these class on ouer used configuration keys!
227 	EnableNotification( seqNames );
228 }
229 
230 //*****************************************************************************************************************
231 //	destructor
232 //*****************************************************************************************************************
233 SvtLocalisationOptions_Impl::~SvtLocalisationOptions_Impl()
234 {
235 	// We must save our current values .. if user forget it!
236 	if( IsModified() == sal_True )
237 	{
238 		Commit();
239 	}
240 }
241 
242 //*****************************************************************************************************************
243 //	public method
244 //*****************************************************************************************************************
245 void SvtLocalisationOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames )
246 {
247 	// Use given list of updated properties to get his values from configuration directly!
248 	Sequence< Any > seqValues = GetProperties( seqPropertyNames );
249 	// Safe impossible cases.
250 	// We need values from ALL notified configuration keys.
251 	DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtLocalisationOptions_Impl::Notify()\nI miss some values of configuration keys!\n" );
252 	// Step over list of property names and get right value from coreesponding value list to set it on internal members!
253 	sal_Int32 nCount = seqPropertyNames.getLength();
254 	for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
255 	{
256 		if( seqPropertyNames[nProperty] == PROPERTYNAME_AUTOMNEMONIC )
257 		{
258 			DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Localisation\\AutoMnemonic\"?" );
259 			seqValues[nProperty] >>= m_bAutoMnemonic;
260 		}
261 		else
262 		if( seqPropertyNames[nProperty] == PROPERTYNAME_DIALOGSCALE )
263 		{
264 			DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_LONG), "SvtLocalisationOptions_Impl::SvtLocalisationOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Localisation\\DialogScale\"?" );
265 			seqValues[nProperty] >>= m_nDialogScale;
266 		}
267         #if OSL_DEBUG_LEVEL > 1
268 		else DBG_ASSERT( sal_False, "SvtLocalisationOptions_Impl::Notify()\nUnkown property detected ... I can't handle these!\n" );
269 		#endif
270 	}
271 
272 	NotifyListeners(0);
273 }
274 
275 //*****************************************************************************************************************
276 //	public method
277 //*****************************************************************************************************************
278 void SvtLocalisationOptions_Impl::Commit()
279 {
280 	// Get names of supported properties, create a list for values and copy current values to it.
281 	Sequence< OUString >	seqNames	= GetPropertyNames	();
282 	sal_Int32				nCount		= seqNames.getLength();
283 	Sequence< Any >			seqValues	( nCount );
284 	for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
285 	{
286         switch( nProperty )
287         {
288             case PROPERTYHANDLE_AUTOMNEMONIC	:	{
289                 										seqValues[nProperty] <<= m_bAutoMnemonic;
290 													}
291                 									break;
292 
293             case PROPERTYHANDLE_DIALOGSCALE		:	{
294                 										seqValues[nProperty] <<= m_nDialogScale;
295 													}
296                 									break;
297         }
298 	}
299 	// Set properties in configuration.
300 	PutProperties( seqNames, seqValues );
301 }
302 
303 //*****************************************************************************************************************
304 //	public method
305 //*****************************************************************************************************************
306 sal_Bool SvtLocalisationOptions_Impl::IsAutoMnemonic() const
307 {
308 	return m_bAutoMnemonic;
309 }
310 
311 //*****************************************************************************************************************
312 //	public method
313 //*****************************************************************************************************************
314 void SvtLocalisationOptions_Impl::SetAutoMnemonic( sal_Bool bState )
315 {
316 	m_bAutoMnemonic = bState;
317 	SetModified();
318 }
319 
320 //*****************************************************************************************************************
321 //	public method
322 //*****************************************************************************************************************
323 sal_Int32 SvtLocalisationOptions_Impl::GetDialogScale() const
324 {
325 	return m_nDialogScale;
326 }
327 
328 //*****************************************************************************************************************
329 //	public method
330 //*****************************************************************************************************************
331 void SvtLocalisationOptions_Impl::SetDialogScale( sal_Int32 nScale )
332 {
333 	m_nDialogScale = nScale;
334 	SetModified();
335 }
336 
337 //*****************************************************************************************************************
338 //	private method
339 //*****************************************************************************************************************
340 Sequence< OUString > SvtLocalisationOptions_Impl::GetPropertyNames()
341 {
342 	// Build static list of configuration key names.
343 	static const OUString pProperties[] =
344 	{
345 		PROPERTYNAME_AUTOMNEMONIC	,
346 		PROPERTYNAME_DIALOGSCALE	,
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 SvtLocalisationOptions_Impl*	SvtLocalisationOptions::m_pDataContainer	= NULL	;
360 sal_Int32						SvtLocalisationOptions::m_nRefCount			= 0		;
361 
362 //*****************************************************************************************************************
363 //	constructor
364 //*****************************************************************************************************************
365 SvtLocalisationOptions::SvtLocalisationOptions()
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 exist!
372     if( m_pDataContainer == NULL )
373 	{
374         RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtLocalisationOptions_Impl::ctor()");
375         m_pDataContainer = new SvtLocalisationOptions_Impl;
376 
377         ItemHolder1::holdConfigItem(E_LOCALISATIONOPTIONS);
378 	}
379 }
380 
381 //*****************************************************************************************************************
382 //	destructor
383 //*****************************************************************************************************************
384 SvtLocalisationOptions::~SvtLocalisationOptions()
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 SvtLocalisationOptions::IsAutoMnemonic() const
403 {
404     MutexGuard aGuard( GetOwnStaticMutex() );
405 	return m_pDataContainer->IsAutoMnemonic();
406 }
407 
408 //*****************************************************************************************************************
409 //	public method
410 //*****************************************************************************************************************
411 void SvtLocalisationOptions::SetAutoMnemonic( sal_Bool bState )
412 {
413     MutexGuard aGuard( GetOwnStaticMutex() );
414 	m_pDataContainer->SetAutoMnemonic( bState );
415 }
416 
417 //*****************************************************************************************************************
418 //	public method
419 //*****************************************************************************************************************
420 sal_Int32 SvtLocalisationOptions::GetDialogScale() const
421 {
422     MutexGuard aGuard( GetOwnStaticMutex() );
423 	return m_pDataContainer->GetDialogScale();
424 }
425 
426 //*****************************************************************************************************************
427 //	public method
428 //*****************************************************************************************************************
429 void SvtLocalisationOptions::SetDialogScale( sal_Int32 nScale )
430 {
431     MutexGuard aGuard( GetOwnStaticMutex() );
432 	m_pDataContainer->SetDialogScale( nScale );
433 }
434 
435 //*****************************************************************************************************************
436 //	private method
437 //*****************************************************************************************************************
438 Mutex& SvtLocalisationOptions::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