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/fontoptions.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_FONT						OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Font"			))
61 
62 #define	PROPERTYNAME_REPLACEMENTTABLE		OUString(RTL_CONSTASCII_USTRINGPARAM("Substitution/Replacement"		))
63 #define	PROPERTYNAME_FONTHISTORY			OUString(RTL_CONSTASCII_USTRINGPARAM("View/History"					))
64 #define	PROPERTYNAME_FONTWYSIWYG			OUString(RTL_CONSTASCII_USTRINGPARAM("View/ShowFontBoxWYSIWYG"		))
65 
66 #define	PROPERTYHANDLE_REPLACEMENTTABLE		0
67 #define	PROPERTYHANDLE_FONTHISTORY			1
68 #define	PROPERTYHANDLE_FONTWYSIWYG			2
69 
70 #define	PROPERTYCOUNT						3
71 
72 //_________________________________________________________________________________________________________________
73 //	private declarations!
74 //_________________________________________________________________________________________________________________
75 
76 class SvtFontOptions_Impl : public ConfigItem
77 {
78 	//-------------------------------------------------------------------------------------------------------------
79 	//	public methods
80 	//-------------------------------------------------------------------------------------------------------------
81 
82 	public:
83 
84 		//---------------------------------------------------------------------------------------------------------
85 		//	constructor / destructor
86 		//---------------------------------------------------------------------------------------------------------
87 
88 		 SvtFontOptions_Impl();
89 		~SvtFontOptions_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	IsReplacementTableEnabled	(					) const	;
144 		void		EnableReplacementTable		( sal_Bool bState	)		;
145 
146 		sal_Bool	IsFontHistoryEnabled		(					) const	;
147 		void		EnableFontHistory			( sal_Bool bState	)		;
148 
149 		sal_Bool	IsFontWYSIWYGEnabled		(					) const	;
150 		void		EnableFontWYSIWYG			( sal_Bool bState	)		;
151 
152 	//-------------------------------------------------------------------------------------------------------------
153 	//	private methods
154 	//-------------------------------------------------------------------------------------------------------------
155 
156 	private:
157 
158 		/*-****************************************************************************************************//**
159 			@short		return list of key names of ouer configuration management which represent oue module tree
160 			@descr		These methods return a static const list of key names. We need it to get needed values from our
161 						configuration management.
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_bReplacementTable		;
180 		sal_Bool		m_bFontHistory			;
181 		sal_Bool		m_bFontWYSIWYG			;
182 };
183 
184 //_________________________________________________________________________________________________________________
185 //	definitions
186 //_________________________________________________________________________________________________________________
187 
188 //*****************************************************************************************************************
189 //	constructor
190 //*****************************************************************************************************************
191 SvtFontOptions_Impl::SvtFontOptions_Impl()
192 	// Init baseclasses first
193     :	ConfigItem			( ROOTNODE_FONT	)
194 	// Init member then.
195 	,	m_bReplacementTable	( sal_False		)
196 	,	m_bFontHistory		( sal_False		)
197 	,	m_bFontWYSIWYG		( sal_False		)
198 {
199 	// Use our static list of configuration keys to get his values.
200 	Sequence< OUString >	seqNames	= impl_GetPropertyNames	(			);
201 	Sequence< Any >			seqValues	= GetProperties			( seqNames	);
202 
203 	// Safe impossible cases.
204 	// We need values from ALL configuration keys.
205 	// Follow assignment use order of values in relation to our list of key names!
206 	DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtFontOptions_Impl::SvtFontOptions_Impl()\nI miss some values of configuration keys!\n" );
207 
208 	// Copy values from list in right order to ouer internal member.
209 	sal_Int32 nPropertyCount = seqValues.getLength();
210 	for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
211 	{
212 		// Safe impossible cases.
213 		// Check any for valid value.
214 		DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtFontOptions_Impl::SvtFontOptions_Impl()\nInvalid property value detected!\n" );
215         switch( nProperty )
216         {
217             case PROPERTYHANDLE_REPLACEMENTTABLE	:	{
218 															DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::SvtFontOptions_Impl()\nWho has changed the value type of \"Office.Common\\Font\\Substitution\\Replacement\"?" );
219 															seqValues[nProperty] >>= m_bReplacementTable;
220 														}
221 														break;
222             case PROPERTYHANDLE_FONTHISTORY			:	{
223 															DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::SvtFontOptions_Impl()\nWho has changed the value type of \"Office.Common\\Font\\View\\History\"?" );
224 															seqValues[nProperty] >>= m_bFontHistory;
225 														}
226 														break;
227             case PROPERTYHANDLE_FONTWYSIWYG			:	{
228 															DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::SvtFontOptions_Impl()\nWho has changed the value type of \"Office.Common\\Font\\View\\ShowFontBoxWYSIWYG\"?" );
229 															seqValues[nProperty] >>= m_bFontWYSIWYG;
230 														}
231 														break;
232         }
233 	}
234 
235 	// Enable notification mechanism of ouer baseclass.
236 	// We need it to get information about changes outside these class on ouer used configuration keys!
237 	EnableNotification( seqNames );
238 }
239 
240 //*****************************************************************************************************************
241 //	destructor
242 //*****************************************************************************************************************
243 SvtFontOptions_Impl::~SvtFontOptions_Impl()
244 {
245 	// We must save our current values .. if user forget it!
246 	if( IsModified() == sal_True )
247 	{
248 		Commit();
249 	}
250 }
251 
252 //*****************************************************************************************************************
253 //	public method
254 //*****************************************************************************************************************
255 void SvtFontOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames )
256 {
257 	// Use given list of updated properties to get his values from configuration directly!
258 	Sequence< Any > seqValues = GetProperties( seqPropertyNames );
259 	// Safe impossible cases.
260 	// We need values from ALL notified configuration keys.
261 	DBG_ASSERT( !(seqPropertyNames.getLength()!=seqValues.getLength()), "SvtFontOptions_Impl::Notify()\nI miss some values of configuration keys!\n" );
262 	// Step over list of property names and get right value from coreesponding value list to set it on internal members!
263 	sal_Int32 nCount = seqPropertyNames.getLength();
264 	for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
265 	{
266 		if( seqPropertyNames[nProperty] == PROPERTYNAME_REPLACEMENTTABLE )
267 		{
268 			DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\Font\\Substitution\\Replacement\"?" );
269 			seqValues[nProperty] >>= m_bReplacementTable;
270 		}
271 		else
272 		if( seqPropertyNames[nProperty] == PROPERTYNAME_FONTHISTORY )
273 		{
274 			DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\Font\\View\\History\"?" );
275 			seqValues[nProperty] >>= m_bFontHistory;
276 		}
277 		else
278 		if( seqPropertyNames[nProperty] == PROPERTYNAME_FONTWYSIWYG )
279 		{
280 			DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtFontOptions_Impl::Notify()\nWho has changed the value type of \"Office.Common\\Font\\View\\ShowFontBoxWYSIWYG\"?" );
281 			seqValues[nProperty] >>= m_bFontWYSIWYG;
282 		}
283         #if OSL_DEBUG_LEVEL > 1
284 		else DBG_ASSERT( sal_False, "SvtFontOptions_Impl::Notify()\nUnkown property detected ... I can't handle these!\n" );
285 		#endif
286 	}
287 }
288 
289 //*****************************************************************************************************************
290 //	public method
291 //*****************************************************************************************************************
292 void SvtFontOptions_Impl::Commit()
293 {
294 	// Get names of supported properties, create a list for values and copy current values to it.
295 	Sequence< OUString >	seqNames	= impl_GetPropertyNames();
296 	sal_Int32				nCount		= seqNames.getLength();
297 	Sequence< Any >			seqValues	( nCount );
298 	for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
299 	{
300         switch( nProperty )
301         {
302             case PROPERTYHANDLE_REPLACEMENTTABLE	:	{
303                 											seqValues[nProperty] <<= m_bReplacementTable;
304 														}
305                 										break;
306             case PROPERTYHANDLE_FONTHISTORY			:	{
307                 											seqValues[nProperty] <<= m_bFontHistory;
308 														}
309                 										break;
310             case PROPERTYHANDLE_FONTWYSIWYG			:	{
311                 											seqValues[nProperty] <<= m_bFontWYSIWYG;
312 														}
313                 										break;
314         }
315 	}
316 	// Set properties in configuration.
317 	PutProperties( seqNames, seqValues );
318 }
319 
320 //*****************************************************************************************************************
321 //	public method
322 //*****************************************************************************************************************
323 sal_Bool SvtFontOptions_Impl::IsReplacementTableEnabled() const
324 {
325 	return m_bReplacementTable;
326 }
327 
328 //*****************************************************************************************************************
329 //	public method
330 //*****************************************************************************************************************
331 void SvtFontOptions_Impl::EnableReplacementTable( sal_Bool bState )
332 {
333 	m_bReplacementTable = bState;
334 	SetModified();
335 }
336 
337 //*****************************************************************************************************************
338 //	public method
339 //*****************************************************************************************************************
340 sal_Bool SvtFontOptions_Impl::IsFontHistoryEnabled() const
341 {
342 	return m_bFontHistory;
343 }
344 
345 //*****************************************************************************************************************
346 //	public method
347 //*****************************************************************************************************************
348 void SvtFontOptions_Impl::EnableFontHistory( sal_Bool bState )
349 {
350 	m_bFontHistory = bState;
351 	SetModified();
352 }
353 
354 //*****************************************************************************************************************
355 //	public method
356 //*****************************************************************************************************************
357 sal_Bool SvtFontOptions_Impl::IsFontWYSIWYGEnabled() const
358 {
359 	return m_bFontWYSIWYG;
360 }
361 
362 //*****************************************************************************************************************
363 //	public method
364 //*****************************************************************************************************************
365 void SvtFontOptions_Impl::EnableFontWYSIWYG( sal_Bool bState )
366 {
367 	m_bFontWYSIWYG = bState;
368 	SetModified();
369 }
370 
371 //*****************************************************************************************************************
372 //	private method
373 //*****************************************************************************************************************
374 Sequence< OUString > SvtFontOptions_Impl::impl_GetPropertyNames()
375 {
376 	// Build static list of configuration key names.
377 	static const OUString pProperties[] =
378 	{
379 		PROPERTYNAME_REPLACEMENTTABLE	,
380 		PROPERTYNAME_FONTHISTORY		,
381 		PROPERTYNAME_FONTWYSIWYG		,
382 	};
383 	// Initialize return sequence with these list ...
384 	static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT );
385 	// ... and return it.
386 	return seqPropertyNames;
387 }
388 
389 //*****************************************************************************************************************
390 //	initialize static member
391 //	DON'T DO IT IN YOUR HEADER!
392 //	see definition for further informations
393 //*****************************************************************************************************************
394 SvtFontOptions_Impl*	SvtFontOptions::m_pDataContainer	= NULL	;
395 sal_Int32				SvtFontOptions::m_nRefCount			= 0		;
396 
397 //*****************************************************************************************************************
398 //	constructor
399 //*****************************************************************************************************************
400 SvtFontOptions::SvtFontOptions()
401 {
402     // Global access, must be guarded (multithreading!).
403     MutexGuard aGuard( impl_GetOwnStaticMutex() );
404 	// Increase ouer refcount ...
405 	++m_nRefCount;
406 	// ... and initialize ouer data container only if it not already exist!
407     if( m_pDataContainer == NULL )
408 	{
409         RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtFontOptions_Impl::ctor()");
410         m_pDataContainer = new SvtFontOptions_Impl;
411 
412         ItemHolder1::holdConfigItem(E_FONTOPTIONS);
413 	}
414 }
415 
416 //*****************************************************************************************************************
417 //	destructor
418 //*****************************************************************************************************************
419 SvtFontOptions::~SvtFontOptions()
420 {
421     // Global access, must be guarded (multithreading!)
422     MutexGuard aGuard( impl_GetOwnStaticMutex() );
423 	// Decrease ouer refcount.
424 	--m_nRefCount;
425 	// If last instance was deleted ...
426 	// we must destroy ouer static data container!
427     if( m_nRefCount <= 0 )
428 	{
429 		delete m_pDataContainer;
430 		m_pDataContainer = NULL;
431 	}
432 }
433 
434 //*****************************************************************************************************************
435 //	public method
436 //*****************************************************************************************************************
437 sal_Bool SvtFontOptions::IsReplacementTableEnabled() const
438 {
439     MutexGuard aGuard( impl_GetOwnStaticMutex() );
440 	return m_pDataContainer->IsReplacementTableEnabled();
441 }
442 
443 //*****************************************************************************************************************
444 //	public method
445 //*****************************************************************************************************************
446 void SvtFontOptions::EnableReplacementTable( sal_Bool bState )
447 {
448     MutexGuard aGuard( impl_GetOwnStaticMutex() );
449 	m_pDataContainer->EnableReplacementTable( bState );
450 }
451 
452 //*****************************************************************************************************************
453 //	public method
454 //*****************************************************************************************************************
455 sal_Bool SvtFontOptions::IsFontHistoryEnabled() const
456 {
457     MutexGuard aGuard( impl_GetOwnStaticMutex() );
458 	return m_pDataContainer->IsFontHistoryEnabled();
459 }
460 
461 //*****************************************************************************************************************
462 //	public method
463 //*****************************************************************************************************************
464 void SvtFontOptions::EnableFontHistory( sal_Bool bState )
465 {
466     MutexGuard aGuard( impl_GetOwnStaticMutex() );
467 	m_pDataContainer->EnableFontHistory( bState );
468 }
469 
470 //*****************************************************************************************************************
471 //	public method
472 //*****************************************************************************************************************
473 sal_Bool SvtFontOptions::IsFontWYSIWYGEnabled() const
474 {
475     MutexGuard aGuard( impl_GetOwnStaticMutex() );
476 	return m_pDataContainer->IsFontWYSIWYGEnabled();
477 }
478 
479 //*****************************************************************************************************************
480 //	public method
481 //*****************************************************************************************************************
482 void SvtFontOptions::EnableFontWYSIWYG( sal_Bool bState )
483 {
484     MutexGuard aGuard( impl_GetOwnStaticMutex() );
485 	m_pDataContainer->EnableFontWYSIWYG( bState );
486 }
487 
488 //*****************************************************************************************************************
489 //	private method
490 //*****************************************************************************************************************
491 Mutex& SvtFontOptions::impl_GetOwnStaticMutex()
492 {
493 	// Initialize static mutex only for one time!
494     static Mutex* pMutex = NULL;
495 	// If these method first called (Mutex not already exist!) ...
496     if( pMutex == NULL )
497     {
498 		// ... we must create a new one. Protect follow code with the global mutex -
499 		// It must be - we create a static variable!
500         MutexGuard aGuard( Mutex::getGlobalMutex() );
501 		// We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
502         if( pMutex == NULL )
503         {
504 			// Create the new mutex and set it for return on static variable.
505             static Mutex aMutex;
506             pMutex = &aMutex;
507         }
508     }
509 	// Return new created or already existing mutex object.
510     return *pMutex;
511 }
512