1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svl/ctloptions.hxx>
23 #include <svl/languageoptions.hxx>
24 #include <i18nlangtag/mslangid.hxx>
25 #include <unotools/configitem.hxx>
26 #include <tools/debug.hxx>
27 #include <com/sun/star/uno/Any.h>
28 #include <com/sun/star/uno/Sequence.hxx>
29 #include <osl/mutex.hxx>
30 #include <svl/smplhint.hxx>
31 #include <rtl/instance.hxx>
32 #include <unotools/syslocale.hxx>
33 #include <itemholder2.hxx>
35 using namespace ::com::sun::star
;
36 using namespace ::com::sun::star::uno
;
38 #define CFG_READONLY_DEFAULT sal_False
40 // SvtCJKOptions_Impl ----------------------------------------------------------
42 class SvtCTLOptions_Impl
: public utl::ConfigItem
46 bool m_bCTLFontEnabled
;
47 bool m_bCTLSequenceChecking
;
48 bool m_bCTLRestricted
;
49 bool m_bCTLTypeAndReplace
;
50 SvtCTLOptions::CursorMovement m_eCTLCursorMovement
;
51 SvtCTLOptions::TextNumerals m_eCTLTextNumerals
;
53 bool m_bROCTLFontEnabled
;
54 bool m_bROCTLSequenceChecking
;
55 bool m_bROCTLRestricted
;
56 bool m_bROCTLTypeAndReplace
;
57 bool m_bROCTLCursorMovement
;
58 bool m_bROCTLTextNumerals
;
62 ~SvtCTLOptions_Impl();
64 virtual void Notify( const Sequence
< OUString
>& _aPropertyNames
);
65 virtual void Commit();
68 bool IsLoaded() { return m_bIsLoaded
; }
69 void SetCTLFontEnabled( bool _bEnabled
);
70 bool IsCTLFontEnabled() const { return m_bCTLFontEnabled
; }
72 void SetCTLSequenceChecking( bool _bEnabled
);
73 bool IsCTLSequenceChecking() const { return m_bCTLSequenceChecking
;}
75 void SetCTLSequenceCheckingRestricted( bool _bEnable
);
76 bool IsCTLSequenceCheckingRestricted( void ) const { return m_bCTLRestricted
; }
78 void SetCTLSequenceCheckingTypeAndReplace( bool _bEnable
);
79 bool IsCTLSequenceCheckingTypeAndReplace() const { return m_bCTLTypeAndReplace
; }
81 void SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement
);
82 SvtCTLOptions::CursorMovement
83 GetCTLCursorMovement() const { return m_eCTLCursorMovement
; }
85 void SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals
);
86 SvtCTLOptions::TextNumerals
87 GetCTLTextNumerals() const { return m_eCTLTextNumerals
; }
89 bool IsReadOnly(SvtCTLOptions::EOption eOption
) const;
94 : public rtl::Static
< Sequence
< OUString
>, PropertyNames
> {};
96 bool SvtCTLOptions_Impl::IsReadOnly(SvtCTLOptions::EOption eOption
) const
98 bool bReadOnly
= CFG_READONLY_DEFAULT
;
101 case SvtCTLOptions::E_CTLFONT
: bReadOnly
= m_bROCTLFontEnabled
; break;
102 case SvtCTLOptions::E_CTLSEQUENCECHECKING
: bReadOnly
= m_bROCTLSequenceChecking
; break;
103 case SvtCTLOptions::E_CTLCURSORMOVEMENT
: bReadOnly
= m_bROCTLCursorMovement
; break;
104 case SvtCTLOptions::E_CTLTEXTNUMERALS
: bReadOnly
= m_bROCTLTextNumerals
; break;
105 case SvtCTLOptions::E_CTLSEQUENCECHECKINGRESTRICTED
: bReadOnly
= m_bROCTLRestricted
; break;
106 case SvtCTLOptions::E_CTLSEQUENCECHECKINGTYPEANDREPLACE
: bReadOnly
= m_bROCTLTypeAndReplace
; break;
107 default: OSL_FAIL( "SvtCTLOptions_Impl::IsReadOnly() - invalid option" );
111 SvtCTLOptions_Impl::SvtCTLOptions_Impl() :
113 utl::ConfigItem("Office.Common/I18N/CTL"),
115 m_bIsLoaded ( sal_False
),
116 m_bCTLFontEnabled ( sal_False
),
117 m_bCTLSequenceChecking ( sal_False
),
118 m_bCTLRestricted ( sal_False
),
119 m_bCTLTypeAndReplace ( sal_False
),
120 m_eCTLCursorMovement ( SvtCTLOptions::MOVEMENT_LOGICAL
),
121 m_eCTLTextNumerals ( SvtCTLOptions::NUMERALS_ARABIC
),
123 m_bROCTLFontEnabled ( CFG_READONLY_DEFAULT
),
124 m_bROCTLSequenceChecking( CFG_READONLY_DEFAULT
),
125 m_bROCTLRestricted ( CFG_READONLY_DEFAULT
),
126 m_bROCTLTypeAndReplace ( CFG_READONLY_DEFAULT
),
127 m_bROCTLCursorMovement ( CFG_READONLY_DEFAULT
),
128 m_bROCTLTextNumerals ( CFG_READONLY_DEFAULT
)
131 SvtCTLOptions_Impl::~SvtCTLOptions_Impl()
133 if ( IsModified() == sal_True
)
136 // -----------------------------------------------------------------------------
137 void SvtCTLOptions_Impl::Notify( const Sequence
< OUString
>& )
140 NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED
);
142 // -----------------------------------------------------------------------------
143 void SvtCTLOptions_Impl::Commit()
145 Sequence
< OUString
> &rPropertyNames
= PropertyNames::get();
146 OUString
* pOrgNames
= rPropertyNames
.getArray();
147 sal_Int32 nOrgCount
= rPropertyNames
.getLength();
149 Sequence
< OUString
> aNames( nOrgCount
);
150 Sequence
< Any
> aValues( nOrgCount
);
152 OUString
* pNames
= aNames
.getArray();
153 Any
* pValues
= aValues
.getArray();
154 sal_Int32 nRealCount
= 0;
156 const uno::Type
& rType
= ::getBooleanCppuType();
158 for ( int nProp
= 0; nProp
< nOrgCount
; nProp
++ )
164 if (!m_bROCTLFontEnabled
)
166 pNames
[nRealCount
] = pOrgNames
[nProp
];
167 pValues
[nRealCount
].setValue( &m_bCTLFontEnabled
, rType
);
175 if (!m_bROCTLSequenceChecking
)
177 pNames
[nRealCount
] = pOrgNames
[nProp
];
178 pValues
[nRealCount
].setValue( &m_bCTLSequenceChecking
, rType
);
186 if (!m_bROCTLCursorMovement
)
188 pNames
[nRealCount
] = pOrgNames
[nProp
];
189 pValues
[nRealCount
] <<= (sal_Int32
)m_eCTLCursorMovement
;
197 if (!m_bROCTLTextNumerals
)
199 pNames
[nRealCount
] = pOrgNames
[nProp
];
200 pValues
[nRealCount
] <<= (sal_Int32
)m_eCTLTextNumerals
;
208 if (!m_bROCTLRestricted
)
210 pNames
[nRealCount
] = pOrgNames
[nProp
];
211 pValues
[nRealCount
].setValue( &m_bCTLRestricted
, rType
);
218 if(!m_bROCTLTypeAndReplace
)
220 pNames
[nRealCount
] = pOrgNames
[nProp
];
221 pValues
[nRealCount
].setValue( &m_bCTLTypeAndReplace
, rType
);
228 aNames
.realloc(nRealCount
);
229 aValues
.realloc(nRealCount
);
230 PutProperties( aNames
, aValues
);
232 NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED
);
234 // -----------------------------------------------------------------------------
235 void SvtCTLOptions_Impl::Load()
237 Sequence
< OUString
>& rPropertyNames
= PropertyNames::get();
238 if ( !rPropertyNames
.getLength() )
240 rPropertyNames
.realloc(6);
241 OUString
* pNames
= rPropertyNames
.getArray();
242 pNames
[0] = "CTLFont";
243 pNames
[1] = "CTLSequenceChecking";
244 pNames
[2] = "CTLCursorMovement";
245 pNames
[3] = "CTLTextNumerals";
246 pNames
[4] = "CTLSequenceCheckingRestricted";
247 pNames
[5] = "CTLSequenceCheckingTypeAndReplace";
248 EnableNotification( rPropertyNames
);
250 Sequence
< Any
> aValues
= GetProperties( rPropertyNames
);
251 Sequence
< sal_Bool
> aROStates
= GetReadOnlyStates( rPropertyNames
);
252 const Any
* pValues
= aValues
.getConstArray();
253 const sal_Bool
* pROStates
= aROStates
.getConstArray();
254 DBG_ASSERT( aValues
.getLength() == rPropertyNames
.getLength(), "GetProperties failed" );
255 DBG_ASSERT( aROStates
.getLength() == rPropertyNames
.getLength(), "GetReadOnlyStates failed" );
256 if ( aValues
.getLength() == rPropertyNames
.getLength() && aROStates
.getLength() == rPropertyNames
.getLength() )
258 sal_Bool bValue
= sal_False
;
259 sal_Int32 nValue
= 0;
261 for ( int nProp
= 0; nProp
< rPropertyNames
.getLength(); nProp
++ )
263 if ( pValues
[nProp
].hasValue() )
265 if ( pValues
[nProp
] >>= bValue
)
269 case 0: { m_bCTLFontEnabled
= bValue
; m_bROCTLFontEnabled
= pROStates
[nProp
]; } break;
270 case 1: { m_bCTLSequenceChecking
= bValue
; m_bROCTLSequenceChecking
= pROStates
[nProp
]; } break;
271 case 4: { m_bCTLRestricted
= bValue
; m_bROCTLRestricted
= pROStates
[nProp
]; } break;
272 case 5: { m_bCTLTypeAndReplace
= bValue
; m_bROCTLTypeAndReplace
= pROStates
[nProp
]; } break;
275 else if ( pValues
[nProp
] >>= nValue
)
279 case 2: { m_eCTLCursorMovement
= (SvtCTLOptions::CursorMovement
)nValue
; m_bROCTLCursorMovement
= pROStates
[nProp
]; } break;
280 case 3: { m_eCTLTextNumerals
= (SvtCTLOptions::TextNumerals
)nValue
; m_bROCTLTextNumerals
= pROStates
[nProp
]; } break;
287 if (!m_bCTLFontEnabled
)
289 bool bAutoEnableCTL
= false;
291 sal_uInt16 nScriptType
= SvtLanguageOptions::GetScriptTypeOfLanguage(LANGUAGE_SYSTEM
);
292 //system locale is CTL
293 bAutoEnableCTL
= (nScriptType
& SCRIPTTYPE_COMPLEX
);
295 LanguageType eSystemLanguage
= LANGUAGE_SYSTEM
;
299 SvtSystemLanguageOptions aSystemLocaleSettings
;
301 //windows secondary system locale is CTL
302 eSystemLanguage
= aSystemLocaleSettings
.GetWin16SystemLanguage();
303 if (eSystemLanguage
!= LANGUAGE_SYSTEM
)
305 sal_uInt16 nWinScript
= SvtLanguageOptions::GetScriptTypeOfLanguage( eSystemLanguage
);
306 bAutoEnableCTL
= (nWinScript
& SCRIPTTYPE_COMPLEX
);
309 //CTL keyboard is installed
311 bAutoEnableCTL
= aSystemLocaleSettings
.isCTLKeyboardLayoutInstalled();
316 m_bCTLFontEnabled
= sal_True
;
317 sal_uInt16 nLanguage
= SvtSysLocale().GetLanguageTag().getLanguageType();
318 //enable sequence checking for the appropriate languages
319 m_bCTLSequenceChecking
= m_bCTLRestricted
= m_bCTLTypeAndReplace
=
320 (MsLangId::needsSequenceChecking( nLanguage
) ||
321 MsLangId::needsSequenceChecking( eSystemLanguage
));
326 m_bIsLoaded
= sal_True
;
328 void SvtCTLOptions_Impl::SetCTLFontEnabled( bool _bEnabled
)
330 if(!m_bROCTLFontEnabled
&& m_bCTLFontEnabled
!= _bEnabled
)
332 m_bCTLFontEnabled
= _bEnabled
;
337 void SvtCTLOptions_Impl::SetCTLSequenceChecking( bool _bEnabled
)
339 if(!m_bROCTLSequenceChecking
&& m_bCTLSequenceChecking
!= _bEnabled
)
342 m_bCTLSequenceChecking
= _bEnabled
;
346 void SvtCTLOptions_Impl::SetCTLSequenceCheckingRestricted( bool _bEnabled
)
348 if(!m_bROCTLRestricted
&& m_bCTLRestricted
!= _bEnabled
)
351 m_bCTLRestricted
= _bEnabled
;
355 void SvtCTLOptions_Impl::SetCTLSequenceCheckingTypeAndReplace( bool _bEnabled
)
357 if(!m_bROCTLTypeAndReplace
&& m_bCTLTypeAndReplace
!= _bEnabled
)
360 m_bCTLTypeAndReplace
= _bEnabled
;
364 void SvtCTLOptions_Impl::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement
)
366 if (!m_bROCTLCursorMovement
&& m_eCTLCursorMovement
!= _eMovement
)
369 m_eCTLCursorMovement
= _eMovement
;
373 void SvtCTLOptions_Impl::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals
)
375 if (!m_bROCTLTextNumerals
&& m_eCTLTextNumerals
!= _eNumerals
)
378 m_eCTLTextNumerals
= _eNumerals
;
382 // global ----------------------------------------------------------------
384 static SvtCTLOptions_Impl
* pCTLOptions
= NULL
;
385 static sal_Int32 nCTLRefCount
= 0;
386 namespace { struct CTLMutex
: public rtl::Static
< osl::Mutex
, CTLMutex
> {}; }
388 // class SvtCTLOptions --------------------------------------------------
390 SvtCTLOptions::SvtCTLOptions( bool bDontLoad
)
392 // Global access, must be guarded (multithreading)
393 ::osl::MutexGuard
aGuard( CTLMutex::get() );
396 pCTLOptions
= new SvtCTLOptions_Impl
;
397 ItemHolder2::holdConfigItem(E_CTLOPTIONS
);
399 if( !bDontLoad
&& !pCTLOptions
->IsLoaded() )
403 m_pImp
= pCTLOptions
;
404 m_pImp
->AddListener(this);
407 // -----------------------------------------------------------------------
409 SvtCTLOptions::~SvtCTLOptions()
411 // Global access, must be guarded (multithreading)
412 ::osl::MutexGuard
aGuard( CTLMutex::get() );
414 m_pImp
->RemoveListener(this);
415 if ( !--nCTLRefCount
)
416 DELETEZ( pCTLOptions
);
418 // -----------------------------------------------------------------------------
419 void SvtCTLOptions::SetCTLFontEnabled( bool _bEnabled
)
421 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
422 pCTLOptions
->SetCTLFontEnabled( _bEnabled
);
424 // -----------------------------------------------------------------------------
425 bool SvtCTLOptions::IsCTLFontEnabled() const
427 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
428 return pCTLOptions
->IsCTLFontEnabled();
430 // -----------------------------------------------------------------------------
431 void SvtCTLOptions::SetCTLSequenceChecking( bool _bEnabled
)
433 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
434 pCTLOptions
->SetCTLSequenceChecking(_bEnabled
);
436 // -----------------------------------------------------------------------------
437 bool SvtCTLOptions::IsCTLSequenceChecking() const
439 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
440 return pCTLOptions
->IsCTLSequenceChecking();
442 // -----------------------------------------------------------------------------
443 void SvtCTLOptions::SetCTLSequenceCheckingRestricted( bool _bEnable
)
445 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
446 pCTLOptions
->SetCTLSequenceCheckingRestricted(_bEnable
);
448 // -----------------------------------------------------------------------------
449 bool SvtCTLOptions::IsCTLSequenceCheckingRestricted( void ) const
451 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
452 return pCTLOptions
->IsCTLSequenceCheckingRestricted();
454 // -----------------------------------------------------------------------------
455 void SvtCTLOptions::SetCTLSequenceCheckingTypeAndReplace( bool _bEnable
)
457 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
458 pCTLOptions
->SetCTLSequenceCheckingTypeAndReplace(_bEnable
);
460 // -----------------------------------------------------------------------------
461 bool SvtCTLOptions::IsCTLSequenceCheckingTypeAndReplace() const
463 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
464 return pCTLOptions
->IsCTLSequenceCheckingTypeAndReplace();
466 // -----------------------------------------------------------------------------
467 void SvtCTLOptions::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement
)
469 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
470 pCTLOptions
->SetCTLCursorMovement( _eMovement
);
472 // -----------------------------------------------------------------------------
473 SvtCTLOptions::CursorMovement
SvtCTLOptions::GetCTLCursorMovement() const
475 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
476 return pCTLOptions
->GetCTLCursorMovement();
478 // -----------------------------------------------------------------------------
479 void SvtCTLOptions::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals
)
481 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
482 pCTLOptions
->SetCTLTextNumerals( _eNumerals
);
484 // -----------------------------------------------------------------------------
485 SvtCTLOptions::TextNumerals
SvtCTLOptions::GetCTLTextNumerals() const
487 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
488 return pCTLOptions
->GetCTLTextNumerals();
490 // -----------------------------------------------------------------------------
491 bool SvtCTLOptions::IsReadOnly(EOption eOption
) const
493 DBG_ASSERT( pCTLOptions
->IsLoaded(), "CTL options not loaded" );
494 return pCTLOptions
->IsReadOnly(eOption
);
496 // -----------------------------------------------------------------------------
498 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */