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