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