xref: /aoo41x/main/svl/source/config/ctloptions.cxx (revision cdf0e10c)
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_svl.hxx"
30 
31 #include <svl/ctloptions.hxx>
32 
33 #include <svl/languageoptions.hxx>
34 #include <i18npool/mslangid.hxx>
35 #include <unotools/configitem.hxx>
36 #include <tools/debug.hxx>
37 #include <com/sun/star/uno/Any.h>
38 #include <com/sun/star/uno/Sequence.hxx>
39 #include <osl/mutex.hxx>
40 #include <vos/mutex.hxx>
41 #include <svl/smplhint.hxx>
42 #include <rtl/instance.hxx>
43 #include <unotools/syslocale.hxx>
44 #include <itemholder2.hxx>
45 
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::uno;
48 
49 #define ASCII_STR(s)	rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(s) )
50 #define CFG_READONLY_DEFAULT    sal_False
51 
52 // SvtCJKOptions_Impl ----------------------------------------------------------
53 
54 class SvtCTLOptions_Impl : public utl::ConfigItem
55 {
56 private:
57     sal_Bool						m_bIsLoaded;
58     sal_Bool						m_bCTLFontEnabled;
59     sal_Bool						m_bCTLSequenceChecking;
60 	sal_Bool						m_bCTLRestricted;
61     sal_Bool                        m_bCTLTypeAndReplace;
62     SvtCTLOptions::CursorMovement   m_eCTLCursorMovement;
63 	SvtCTLOptions::TextNumerals		m_eCTLTextNumerals;
64 
65     sal_Bool                        m_bROCTLFontEnabled;
66     sal_Bool                        m_bROCTLSequenceChecking;
67 	sal_Bool						m_bROCTLRestricted;
68     sal_Bool                        m_bROCTLTypeAndReplace;
69     sal_Bool                        m_bROCTLCursorMovement;
70     sal_Bool                        m_bROCTLTextNumerals;
71 
72 public:
73     SvtCTLOptions_Impl();
74     ~SvtCTLOptions_Impl();
75 
76 	virtual void 	Notify( const Sequence< rtl::OUString >& _aPropertyNames );
77 	virtual void	Commit();
78     void            Load();
79 
80     sal_Bool 		IsLoaded() { return m_bIsLoaded; }
81     void			SetCTLFontEnabled( sal_Bool _bEnabled );
82     sal_Bool		IsCTLFontEnabled() const { return m_bCTLFontEnabled; }
83 
84     void            SetCTLSequenceChecking( sal_Bool _bEnabled );
85     sal_Bool        IsCTLSequenceChecking() const { return m_bCTLSequenceChecking;}
86 
87 	void			SetCTLSequenceCheckingRestricted( sal_Bool _bEnable );
88 	sal_Bool		IsCTLSequenceCheckingRestricted( void ) const	{ return m_bCTLRestricted; }
89 
90     void            SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable );
91     sal_Bool        IsCTLSequenceCheckingTypeAndReplace() const { return m_bCTLTypeAndReplace; }
92 
93     void            SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement );
94     SvtCTLOptions::CursorMovement
95 					GetCTLCursorMovement() const { return m_eCTLCursorMovement; }
96 
97 	void        	SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals );
98     SvtCTLOptions::TextNumerals
99 					GetCTLTextNumerals() const { return m_eCTLTextNumerals; }
100 
101     sal_Bool        IsReadOnly(SvtCTLOptions::EOption eOption) const;
102 };
103 //------------------------------------------------------------------------------
104 namespace
105 {
106     struct PropertyNames
107         : public rtl::Static< Sequence< rtl::OUString >, PropertyNames > {};
108 }
109 //------------------------------------------------------------------------------
110 sal_Bool SvtCTLOptions_Impl::IsReadOnly(SvtCTLOptions::EOption eOption) const
111 {
112     sal_Bool bReadOnly = CFG_READONLY_DEFAULT;
113     switch(eOption)
114     {
115         case SvtCTLOptions::E_CTLFONT             : bReadOnly = m_bROCTLFontEnabled       ; break;
116         case SvtCTLOptions::E_CTLSEQUENCECHECKING : bReadOnly = m_bROCTLSequenceChecking  ; break;
117         case SvtCTLOptions::E_CTLCURSORMOVEMENT   : bReadOnly = m_bROCTLCursorMovement    ; break;
118         case SvtCTLOptions::E_CTLTEXTNUMERALS     : bReadOnly = m_bROCTLTextNumerals      ; break;
119 		case SvtCTLOptions::E_CTLSEQUENCECHECKINGRESTRICTED: bReadOnly = m_bROCTLRestricted  ; break;
120         case SvtCTLOptions::E_CTLSEQUENCECHECKINGTYPEANDREPLACE: bReadOnly = m_bROCTLTypeAndReplace; break;
121         default: DBG_ERROR(  "SvtCTLOptions_Impl::IsReadOnly() - invalid option" );
122     }
123     return bReadOnly;
124 }
125 //------------------------------------------------------------------------------
126 SvtCTLOptions_Impl::SvtCTLOptions_Impl() :
127 
128     utl::ConfigItem( ASCII_STR("Office.Common/I18N/CTL") ),
129 
130 	m_bIsLoaded				( sal_False ),
131     m_bCTLFontEnabled		( sal_False ),
132     m_bCTLSequenceChecking	( sal_False ),
133 	m_bCTLRestricted		( sal_False ),
134 	m_eCTLCursorMovement	( SvtCTLOptions::MOVEMENT_LOGICAL ),
135     m_eCTLTextNumerals      ( SvtCTLOptions::NUMERALS_ARABIC ),
136 
137     m_bROCTLFontEnabled     ( CFG_READONLY_DEFAULT ),
138     m_bROCTLSequenceChecking( CFG_READONLY_DEFAULT ),
139 	m_bROCTLRestricted		( CFG_READONLY_DEFAULT ),
140     m_bROCTLCursorMovement  ( CFG_READONLY_DEFAULT ),
141     m_bROCTLTextNumerals    ( CFG_READONLY_DEFAULT )
142 {
143 }
144 //------------------------------------------------------------------------------
145 SvtCTLOptions_Impl::~SvtCTLOptions_Impl()
146 {
147     if ( IsModified() == sal_True )
148 		Commit();
149 }
150 // -----------------------------------------------------------------------------
151 void SvtCTLOptions_Impl::Notify( const Sequence< rtl::OUString >& )
152 {
153     Load();
154     NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED);
155 }
156 // -----------------------------------------------------------------------------
157 void SvtCTLOptions_Impl::Commit()
158 {
159     Sequence< rtl::OUString > &rPropertyNames = PropertyNames::get();
160     rtl::OUString* pOrgNames = rPropertyNames.getArray();
161     sal_Int32 nOrgCount = rPropertyNames.getLength();
162 
163     Sequence< rtl::OUString > aNames( nOrgCount );
164     Sequence< Any > aValues( nOrgCount );
165 
166     rtl::OUString* pNames = aNames.getArray();
167     Any* pValues = aValues.getArray();
168     sal_Int32 nRealCount = 0;
169 
170     const uno::Type& rType = ::getBooleanCppuType();
171 
172     for ( int nProp = 0; nProp < nOrgCount; nProp++ )
173 	{
174 		switch ( nProp )
175 		{
176             case  0:
177             {
178                 if (!m_bROCTLFontEnabled)
179                 {
180                     pNames[nRealCount] = pOrgNames[nProp];
181                     pValues[nRealCount].setValue( &m_bCTLFontEnabled, rType );
182                     ++nRealCount;
183                 }
184             }
185             break;
186 
187             case  1:
188             {
189                 if (!m_bROCTLSequenceChecking)
190                 {
191                     pNames[nRealCount] = pOrgNames[nProp];
192                     pValues[nRealCount].setValue( &m_bCTLSequenceChecking, rType );
193                     ++nRealCount;
194                 }
195             }
196             break;
197 
198             case  2:
199             {
200                 if (!m_bROCTLCursorMovement)
201                 {
202                     pNames[nRealCount] = pOrgNames[nProp];
203                     pValues[nRealCount] <<= (sal_Int32)m_eCTLCursorMovement;
204                     ++nRealCount;
205                 }
206             }
207             break;
208 
209             case  3:
210             {
211                 if (!m_bROCTLTextNumerals)
212                 {
213                     pNames[nRealCount] = pOrgNames[nProp];
214                     pValues[nRealCount] <<= (sal_Int32)m_eCTLTextNumerals;
215                     ++nRealCount;
216                 }
217             }
218 			break;
219 
220 			case  4:
221 			{
222 				if (!m_bROCTLRestricted)
223 				{
224 					pNames[nRealCount] = pOrgNames[nProp];
225 					pValues[nRealCount].setValue( &m_bCTLRestricted, rType );
226 					++nRealCount;
227 				}
228 			}
229             break;
230             case 5:
231             {
232                 if(!m_bROCTLTypeAndReplace)
233                 {
234                     pNames[nRealCount] = pOrgNames[nProp];
235                     pValues[nRealCount].setValue( &m_bCTLTypeAndReplace, rType );
236 					++nRealCount;
237                 }
238             }
239             break;
240         }
241 	}
242     aNames.realloc(nRealCount);
243     aValues.realloc(nRealCount);
244     PutProperties( aNames, aValues );
245     //broadcast changes
246     NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED);
247 }
248 // -----------------------------------------------------------------------------
249 void SvtCTLOptions_Impl::Load()
250 {
251     Sequence< rtl::OUString >& rPropertyNames = PropertyNames::get();
252     if ( !rPropertyNames.getLength() )
253     {
254         rPropertyNames.realloc(6);
255         rtl::OUString* pNames = rPropertyNames.getArray();
256 		pNames[0] = ASCII_STR("CTLFont");
257         pNames[1] = ASCII_STR("CTLSequenceChecking");
258         pNames[2] = ASCII_STR("CTLCursorMovement");
259         pNames[3] = ASCII_STR("CTLTextNumerals");
260         pNames[4] = ASCII_STR("CTLSequenceCheckingRestricted");
261         pNames[5] = ASCII_STR("CTLSequenceCheckingTypeAndReplace");
262         EnableNotification( rPropertyNames );
263     }
264     Sequence< Any > aValues = GetProperties( rPropertyNames );
265     Sequence< sal_Bool > aROStates = GetReadOnlyStates( rPropertyNames );
266     const Any* pValues = aValues.getConstArray();
267     const sal_Bool* pROStates = aROStates.getConstArray();
268     DBG_ASSERT( aValues.getLength() == rPropertyNames.getLength(), "GetProperties failed" );
269     DBG_ASSERT( aROStates.getLength() == rPropertyNames.getLength(), "GetReadOnlyStates failed" );
270     if ( aValues.getLength() == rPropertyNames.getLength() && aROStates.getLength() == rPropertyNames.getLength() )
271 	{
272 		sal_Bool bValue = sal_False;
273 		sal_Int32 nValue = 0;
274 
275         for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ )
276 		{
277             if ( pValues[nProp].hasValue() )
278 			{
279                 if ( pValues[nProp] >>= bValue )
280 				{
281                 	switch ( nProp )
282                 	{
283                         case 0: { m_bCTLFontEnabled = bValue; m_bROCTLFontEnabled = pROStates[nProp]; } break;
284                         case 1: { m_bCTLSequenceChecking = bValue; m_bROCTLSequenceChecking = pROStates[nProp]; } break;
285                         case 4: { m_bCTLRestricted = bValue; m_bROCTLRestricted = pROStates[nProp]; } break;
286                         case 5: { m_bCTLTypeAndReplace = bValue; m_bROCTLTypeAndReplace = pROStates[nProp]; } break;
287                     }
288 				}
289                 else if ( pValues[nProp] >>= nValue )
290 				{
291                 	switch ( nProp )
292                 	{
293                         case 2: { m_eCTLCursorMovement = (SvtCTLOptions::CursorMovement)nValue; m_bROCTLCursorMovement = pROStates[nProp]; } break;
294                         case 3: { m_eCTLTextNumerals = (SvtCTLOptions::TextNumerals)nValue; m_bROCTLTextNumerals = pROStates[nProp]; } break;
295                 	}
296 				}
297             }
298         }
299     }
300 	sal_uInt16 nType = SvtLanguageOptions::GetScriptTypeOfLanguage(LANGUAGE_SYSTEM);
301     SvtSystemLanguageOptions aSystemLocaleSettings;
302     LanguageType eSystemLanguage = aSystemLocaleSettings.GetWin16SystemLanguage();
303     sal_uInt16 nWinScript = SvtLanguageOptions::GetScriptTypeOfLanguage( eSystemLanguage );
304     if( !m_bCTLFontEnabled && (( nType & SCRIPTTYPE_COMPLEX ) ||
305             ((eSystemLanguage != LANGUAGE_SYSTEM)  && ( nWinScript & SCRIPTTYPE_COMPLEX )))  )
306 	{
307 		m_bCTLFontEnabled = sal_True;
308         sal_uInt16 nLanguage = SvtSysLocale().GetLanguage();
309         //enable sequence checking for the appropriate languages
310         m_bCTLSequenceChecking = m_bCTLRestricted = m_bCTLTypeAndReplace =
311             (MsLangId::needsSequenceChecking( nLanguage) ||
312              MsLangId::needsSequenceChecking( eSystemLanguage));
313         Commit();
314 	}
315     m_bIsLoaded = sal_True;
316 }
317 //------------------------------------------------------------------------------
318 void SvtCTLOptions_Impl::SetCTLFontEnabled( sal_Bool _bEnabled )
319 {
320     if(!m_bROCTLFontEnabled && m_bCTLFontEnabled != _bEnabled)
321     {
322         m_bCTLFontEnabled = _bEnabled;
323         SetModified();
324 		NotifyListeners(0);
325     }
326 }
327 //------------------------------------------------------------------------------
328 void SvtCTLOptions_Impl::SetCTLSequenceChecking( sal_Bool _bEnabled )
329 {
330     if(!m_bROCTLSequenceChecking && m_bCTLSequenceChecking != _bEnabled)
331     {
332         SetModified();
333         m_bCTLSequenceChecking = _bEnabled;
334 		NotifyListeners(0);
335     }
336 }
337 //------------------------------------------------------------------------------
338 void SvtCTLOptions_Impl::SetCTLSequenceCheckingRestricted( sal_Bool _bEnabled )
339 {
340     if(!m_bROCTLRestricted && m_bCTLRestricted != _bEnabled)
341     {
342         SetModified();
343         m_bCTLRestricted = _bEnabled;
344 		NotifyListeners(0);
345     }
346 }
347 //------------------------------------------------------------------------------
348 void  SvtCTLOptions_Impl::SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnabled )
349 {
350     if(!m_bROCTLTypeAndReplace && m_bCTLTypeAndReplace != _bEnabled)
351     {
352         SetModified();
353         m_bCTLTypeAndReplace = _bEnabled;
354 		NotifyListeners(0);
355     }
356 }
357 //------------------------------------------------------------------------------
358 void SvtCTLOptions_Impl::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement )
359 {
360     if (!m_bROCTLCursorMovement && m_eCTLCursorMovement != _eMovement )
361     {
362         SetModified();
363         m_eCTLCursorMovement = _eMovement;
364 		NotifyListeners(0);
365     }
366 }
367 //------------------------------------------------------------------------------
368 void SvtCTLOptions_Impl::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals )
369 {
370     if (!m_bROCTLTextNumerals && m_eCTLTextNumerals != _eNumerals )
371     {
372         SetModified();
373         m_eCTLTextNumerals = _eNumerals;
374 		NotifyListeners(0);
375     }
376 }
377 // global ----------------------------------------------------------------
378 
379 static SvtCTLOptions_Impl*	pCTLOptions = NULL;
380 static sal_Int32			nCTLRefCount = 0;
381 namespace { struct CTLMutex : public rtl::Static< osl::Mutex, CTLMutex > {}; }
382 
383 // class SvtCTLOptions --------------------------------------------------
384 
385 SvtCTLOptions::SvtCTLOptions( sal_Bool bDontLoad )
386 {
387     // Global access, must be guarded (multithreading)
388     ::osl::MutexGuard aGuard( CTLMutex::get() );
389     if ( !pCTLOptions )
390     {
391         pCTLOptions = new SvtCTLOptions_Impl;
392         ItemHolder2::holdConfigItem(E_CTLOPTIONS);
393     }
394     if( !bDontLoad && !pCTLOptions->IsLoaded() )
395         pCTLOptions->Load();
396 
397     ++nCTLRefCount;
398     m_pImp = pCTLOptions;
399     m_pImp->AddListener(this);
400 }
401 
402 // -----------------------------------------------------------------------
403 
404 SvtCTLOptions::~SvtCTLOptions()
405 {
406     // Global access, must be guarded (multithreading)
407     ::osl::MutexGuard aGuard( CTLMutex::get() );
408 
409     m_pImp->RemoveListener(this);
410 	if ( !--nCTLRefCount )
411         DELETEZ( pCTLOptions );
412 }
413 // -----------------------------------------------------------------------------
414 void SvtCTLOptions::SetCTLFontEnabled( sal_Bool _bEnabled )
415 {
416     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
417     pCTLOptions->SetCTLFontEnabled( _bEnabled );
418 }
419 // -----------------------------------------------------------------------------
420 sal_Bool SvtCTLOptions::IsCTLFontEnabled() const
421 {
422     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
423     return pCTLOptions->IsCTLFontEnabled();
424 }
425 // -----------------------------------------------------------------------------
426 void SvtCTLOptions::SetCTLSequenceChecking( sal_Bool _bEnabled )
427 {
428     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
429     pCTLOptions->SetCTLSequenceChecking(_bEnabled);
430 }
431 // -----------------------------------------------------------------------------
432 sal_Bool SvtCTLOptions::IsCTLSequenceChecking() const
433 {
434     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
435     return pCTLOptions->IsCTLSequenceChecking();
436 }
437 // -----------------------------------------------------------------------------
438 void SvtCTLOptions::SetCTLSequenceCheckingRestricted( sal_Bool _bEnable )
439 {
440     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
441 	pCTLOptions->SetCTLSequenceCheckingRestricted(_bEnable);
442 }
443 // -----------------------------------------------------------------------------
444 sal_Bool SvtCTLOptions::IsCTLSequenceCheckingRestricted( void ) const
445 {
446     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
447     return pCTLOptions->IsCTLSequenceCheckingRestricted();
448 }
449 // -----------------------------------------------------------------------------
450 void SvtCTLOptions::SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable )
451 {
452     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
453     pCTLOptions->SetCTLSequenceCheckingTypeAndReplace(_bEnable);
454 }
455 // -----------------------------------------------------------------------------
456 sal_Bool SvtCTLOptions::IsCTLSequenceCheckingTypeAndReplace() const
457 {
458     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
459     return pCTLOptions->IsCTLSequenceCheckingTypeAndReplace();
460 }
461 // -----------------------------------------------------------------------------
462 void SvtCTLOptions::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement )
463 {
464     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
465     pCTLOptions->SetCTLCursorMovement( _eMovement );
466 }
467 // -----------------------------------------------------------------------------
468 SvtCTLOptions::CursorMovement SvtCTLOptions::GetCTLCursorMovement() const
469 {
470     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
471     return pCTLOptions->GetCTLCursorMovement();
472 }
473 // -----------------------------------------------------------------------------
474 void SvtCTLOptions::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals )
475 {
476     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
477     pCTLOptions->SetCTLTextNumerals( _eNumerals );
478 }
479 // -----------------------------------------------------------------------------
480 SvtCTLOptions::TextNumerals SvtCTLOptions::GetCTLTextNumerals() const
481 {
482     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
483     return pCTLOptions->GetCTLTextNumerals();
484 }
485 // -----------------------------------------------------------------------------
486 sal_Bool SvtCTLOptions::IsReadOnly(EOption eOption) const
487 {
488     DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" );
489     return pCTLOptions->IsReadOnly(eOption);
490 }
491 // -----------------------------------------------------------------------------
492 
493