bump product version to 5.0.4.1
[LibreOffice.git] / svl / source / config / ctloptions.cxx
blob170052c1b8673fa138da4438d150d58ff35afa97
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <com/sun/star/uno/Any.h>
27 #include <com/sun/star/uno/Sequence.hxx>
28 #include <osl/mutex.hxx>
29 #include <svl/smplhint.hxx>
30 #include <rtl/instance.hxx>
31 #include <unotools/syslocale.hxx>
32 #include "itemholder2.hxx"
34 using namespace ::com::sun::star;
35 using namespace ::com::sun::star::uno;
37 #define CFG_READONLY_DEFAULT false
39 class SvtCTLOptions_Impl : public utl::ConfigItem
41 private:
42 bool m_bIsLoaded;
43 bool m_bCTLFontEnabled;
44 bool m_bCTLSequenceChecking;
45 bool m_bCTLRestricted;
46 bool m_bCTLTypeAndReplace;
47 SvtCTLOptions::CursorMovement m_eCTLCursorMovement;
48 SvtCTLOptions::TextNumerals m_eCTLTextNumerals;
50 bool m_bROCTLFontEnabled;
51 bool m_bROCTLSequenceChecking;
52 bool m_bROCTLRestricted;
53 bool m_bROCTLTypeAndReplace;
54 bool m_bROCTLCursorMovement;
55 bool m_bROCTLTextNumerals;
57 virtual void ImplCommit() SAL_OVERRIDE;
59 public:
60 SvtCTLOptions_Impl();
61 virtual ~SvtCTLOptions_Impl();
63 virtual void Notify( const Sequence< OUString >& _aPropertyNames ) SAL_OVERRIDE;
64 void Load();
66 bool IsLoaded() { return m_bIsLoaded; }
67 void SetCTLFontEnabled( bool _bEnabled );
68 bool IsCTLFontEnabled() const { return m_bCTLFontEnabled; }
70 void SetCTLSequenceChecking( bool _bEnabled );
71 bool IsCTLSequenceChecking() const { return m_bCTLSequenceChecking;}
73 void SetCTLSequenceCheckingRestricted( bool _bEnable );
74 bool IsCTLSequenceCheckingRestricted() const { return m_bCTLRestricted; }
76 void SetCTLSequenceCheckingTypeAndReplace( bool _bEnable );
77 bool IsCTLSequenceCheckingTypeAndReplace() const { return m_bCTLTypeAndReplace; }
79 void SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement );
80 SvtCTLOptions::CursorMovement
81 GetCTLCursorMovement() const { return m_eCTLCursorMovement; }
83 void SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals );
84 SvtCTLOptions::TextNumerals
85 GetCTLTextNumerals() const { return m_eCTLTextNumerals; }
87 bool IsReadOnly(SvtCTLOptions::EOption eOption) const;
89 namespace
91 struct PropertyNames
92 : public rtl::Static< Sequence< OUString >, PropertyNames > {};
94 bool SvtCTLOptions_Impl::IsReadOnly(SvtCTLOptions::EOption eOption) const
96 bool bReadOnly = CFG_READONLY_DEFAULT;
97 switch(eOption)
99 case SvtCTLOptions::E_CTLFONT : bReadOnly = m_bROCTLFontEnabled ; break;
100 case SvtCTLOptions::E_CTLSEQUENCECHECKING : bReadOnly = m_bROCTLSequenceChecking ; break;
101 case SvtCTLOptions::E_CTLCURSORMOVEMENT : bReadOnly = m_bROCTLCursorMovement ; break;
102 case SvtCTLOptions::E_CTLTEXTNUMERALS : bReadOnly = m_bROCTLTextNumerals ; break;
103 case SvtCTLOptions::E_CTLSEQUENCECHECKINGRESTRICTED: bReadOnly = m_bROCTLRestricted ; break;
104 case SvtCTLOptions::E_CTLSEQUENCECHECKINGTYPEANDREPLACE: bReadOnly = m_bROCTLTypeAndReplace; break;
105 default: assert(false);
107 return bReadOnly;
109 SvtCTLOptions_Impl::SvtCTLOptions_Impl() :
111 utl::ConfigItem("Office.Common/I18N/CTL"),
113 m_bIsLoaded ( false ),
114 m_bCTLFontEnabled ( false ),
115 m_bCTLSequenceChecking ( false ),
116 m_bCTLRestricted ( false ),
117 m_bCTLTypeAndReplace ( false ),
118 m_eCTLCursorMovement ( SvtCTLOptions::MOVEMENT_LOGICAL ),
119 m_eCTLTextNumerals ( SvtCTLOptions::NUMERALS_ARABIC ),
121 m_bROCTLFontEnabled ( CFG_READONLY_DEFAULT ),
122 m_bROCTLSequenceChecking( CFG_READONLY_DEFAULT ),
123 m_bROCTLRestricted ( CFG_READONLY_DEFAULT ),
124 m_bROCTLTypeAndReplace ( CFG_READONLY_DEFAULT ),
125 m_bROCTLCursorMovement ( CFG_READONLY_DEFAULT ),
126 m_bROCTLTextNumerals ( CFG_READONLY_DEFAULT )
129 SvtCTLOptions_Impl::~SvtCTLOptions_Impl()
131 assert(!IsModified()); // should have been committed
134 void SvtCTLOptions_Impl::Notify( const Sequence< OUString >& )
136 Load();
137 NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED);
140 void SvtCTLOptions_Impl::ImplCommit()
142 Sequence< OUString > &rPropertyNames = PropertyNames::get();
143 OUString* pOrgNames = rPropertyNames.getArray();
144 sal_Int32 nOrgCount = rPropertyNames.getLength();
146 Sequence< OUString > aNames( nOrgCount );
147 Sequence< Any > aValues( nOrgCount );
149 OUString* pNames = aNames.getArray();
150 Any* pValues = aValues.getArray();
151 sal_Int32 nRealCount = 0;
153 const uno::Type& rType = cppu::UnoType<bool>::get();
155 for ( int nProp = 0; nProp < nOrgCount; nProp++ )
157 switch ( nProp )
159 case 0:
161 if (!m_bROCTLFontEnabled)
163 pNames[nRealCount] = pOrgNames[nProp];
164 pValues[nRealCount].setValue( &m_bCTLFontEnabled, rType );
165 ++nRealCount;
168 break;
170 case 1:
172 if (!m_bROCTLSequenceChecking)
174 pNames[nRealCount] = pOrgNames[nProp];
175 pValues[nRealCount].setValue( &m_bCTLSequenceChecking, rType );
176 ++nRealCount;
179 break;
181 case 2:
183 if (!m_bROCTLCursorMovement)
185 pNames[nRealCount] = pOrgNames[nProp];
186 pValues[nRealCount] <<= (sal_Int32)m_eCTLCursorMovement;
187 ++nRealCount;
190 break;
192 case 3:
194 if (!m_bROCTLTextNumerals)
196 pNames[nRealCount] = pOrgNames[nProp];
197 pValues[nRealCount] <<= (sal_Int32)m_eCTLTextNumerals;
198 ++nRealCount;
201 break;
203 case 4:
205 if (!m_bROCTLRestricted)
207 pNames[nRealCount] = pOrgNames[nProp];
208 pValues[nRealCount].setValue( &m_bCTLRestricted, rType );
209 ++nRealCount;
212 break;
213 case 5:
215 if(!m_bROCTLTypeAndReplace)
217 pNames[nRealCount] = pOrgNames[nProp];
218 pValues[nRealCount].setValue( &m_bCTLTypeAndReplace, rType );
219 ++nRealCount;
222 break;
225 aNames.realloc(nRealCount);
226 aValues.realloc(nRealCount);
227 PutProperties( aNames, aValues );
228 //broadcast changes
229 NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED);
232 void SvtCTLOptions_Impl::Load()
234 Sequence< OUString >& rPropertyNames = PropertyNames::get();
235 if ( !rPropertyNames.getLength() )
237 rPropertyNames.realloc(6);
238 OUString* pNames = rPropertyNames.getArray();
239 pNames[0] = "CTLFont";
240 pNames[1] = "CTLSequenceChecking";
241 pNames[2] = "CTLCursorMovement";
242 pNames[3] = "CTLTextNumerals";
243 pNames[4] = "CTLSequenceCheckingRestricted";
244 pNames[5] = "CTLSequenceCheckingTypeAndReplace";
245 EnableNotification( rPropertyNames );
247 Sequence< Any > aValues = GetProperties( rPropertyNames );
248 Sequence< sal_Bool > aROStates = GetReadOnlyStates( rPropertyNames );
249 const Any* pValues = aValues.getConstArray();
250 const sal_Bool* pROStates = aROStates.getConstArray();
251 assert(aValues.getLength() == rPropertyNames.getLength() && "GetProperties failed");
252 assert(aROStates.getLength() == rPropertyNames.getLength() && "GetReadOnlyStates failed");
253 if ( aValues.getLength() == rPropertyNames.getLength() && aROStates.getLength() == rPropertyNames.getLength() )
255 bool bValue = false;
256 sal_Int32 nValue = 0;
258 for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ )
260 if ( pValues[nProp].hasValue() )
262 if ( pValues[nProp] >>= bValue )
264 switch ( nProp )
266 case 0: { m_bCTLFontEnabled = bValue; m_bROCTLFontEnabled = pROStates[nProp]; } break;
267 case 1: { m_bCTLSequenceChecking = bValue; m_bROCTLSequenceChecking = pROStates[nProp]; } break;
268 case 4: { m_bCTLRestricted = bValue; m_bROCTLRestricted = pROStates[nProp]; } break;
269 case 5: { m_bCTLTypeAndReplace = bValue; m_bROCTLTypeAndReplace = pROStates[nProp]; } break;
272 else if ( pValues[nProp] >>= nValue )
274 switch ( nProp )
276 case 2: { m_eCTLCursorMovement = (SvtCTLOptions::CursorMovement)nValue; m_bROCTLCursorMovement = pROStates[nProp]; } break;
277 case 3: { m_eCTLTextNumerals = (SvtCTLOptions::TextNumerals)nValue; m_bROCTLTextNumerals = pROStates[nProp]; } break;
284 if (!m_bCTLFontEnabled)
286 SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(LANGUAGE_SYSTEM);
287 //system locale is CTL
288 bool bAutoEnableCTL = bool(nScriptType & SvtScriptType::COMPLEX);
290 LanguageType eSystemLanguage = LANGUAGE_SYSTEM;
292 if (!bAutoEnableCTL)
294 SvtSystemLanguageOptions aSystemLocaleSettings;
296 //windows secondary system locale is CTL
297 eSystemLanguage = aSystemLocaleSettings.GetWin16SystemLanguage();
298 if (eSystemLanguage != LANGUAGE_SYSTEM)
300 SvtScriptType nWinScript = SvtLanguageOptions::GetScriptTypeOfLanguage( eSystemLanguage );
301 bAutoEnableCTL = bool(nWinScript & SvtScriptType::COMPLEX);
304 //CTL keyboard is installed
305 if (!bAutoEnableCTL)
306 bAutoEnableCTL = aSystemLocaleSettings.isCTLKeyboardLayoutInstalled();
309 if (bAutoEnableCTL)
311 m_bCTLFontEnabled = true;
312 sal_uInt16 nLanguage = SvtSysLocale().GetLanguageTag().getLanguageType();
313 //enable sequence checking for the appropriate languages
314 m_bCTLSequenceChecking = m_bCTLRestricted = m_bCTLTypeAndReplace =
315 (MsLangId::needsSequenceChecking( nLanguage) ||
316 MsLangId::needsSequenceChecking( eSystemLanguage));
317 Commit();
321 m_bIsLoaded = true;
323 void SvtCTLOptions_Impl::SetCTLFontEnabled( bool _bEnabled )
325 if(!m_bROCTLFontEnabled && m_bCTLFontEnabled != _bEnabled)
327 m_bCTLFontEnabled = _bEnabled;
328 SetModified();
329 NotifyListeners(0);
332 void SvtCTLOptions_Impl::SetCTLSequenceChecking( bool _bEnabled )
334 if(!m_bROCTLSequenceChecking && m_bCTLSequenceChecking != _bEnabled)
336 SetModified();
337 m_bCTLSequenceChecking = _bEnabled;
338 NotifyListeners(0);
341 void SvtCTLOptions_Impl::SetCTLSequenceCheckingRestricted( bool _bEnabled )
343 if(!m_bROCTLRestricted && m_bCTLRestricted != _bEnabled)
345 SetModified();
346 m_bCTLRestricted = _bEnabled;
347 NotifyListeners(0);
350 void SvtCTLOptions_Impl::SetCTLSequenceCheckingTypeAndReplace( bool _bEnabled )
352 if(!m_bROCTLTypeAndReplace && m_bCTLTypeAndReplace != _bEnabled)
354 SetModified();
355 m_bCTLTypeAndReplace = _bEnabled;
356 NotifyListeners(0);
359 void SvtCTLOptions_Impl::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement )
361 if (!m_bROCTLCursorMovement && m_eCTLCursorMovement != _eMovement )
363 SetModified();
364 m_eCTLCursorMovement = _eMovement;
365 NotifyListeners(0);
368 void SvtCTLOptions_Impl::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals )
370 if (!m_bROCTLTextNumerals && m_eCTLTextNumerals != _eNumerals )
372 SetModified();
373 m_eCTLTextNumerals = _eNumerals;
374 NotifyListeners(0);
377 // global
379 static SvtCTLOptions_Impl* pCTLOptions = NULL;
380 static sal_Int32 nCTLRefCount = 0;
381 namespace { struct CTLMutex : public rtl::Static< osl::Mutex, CTLMutex > {}; }
383 SvtCTLOptions::SvtCTLOptions( bool bDontLoad )
385 // Global access, must be guarded (multithreading)
386 ::osl::MutexGuard aGuard( CTLMutex::get() );
387 if ( !pCTLOptions )
389 pCTLOptions = new SvtCTLOptions_Impl;
390 ItemHolder2::holdConfigItem(E_CTLOPTIONS);
392 if( !bDontLoad && !pCTLOptions->IsLoaded() )
393 pCTLOptions->Load();
395 ++nCTLRefCount;
396 m_pImp = pCTLOptions;
397 m_pImp->AddListener(this);
402 SvtCTLOptions::~SvtCTLOptions()
404 // Global access, must be guarded (multithreading)
405 ::osl::MutexGuard aGuard( CTLMutex::get() );
407 m_pImp->RemoveListener(this);
408 if ( !--nCTLRefCount )
409 DELETEZ( pCTLOptions );
412 void SvtCTLOptions::SetCTLFontEnabled( bool _bEnabled )
414 assert(pCTLOptions->IsLoaded());
415 pCTLOptions->SetCTLFontEnabled( _bEnabled );
418 bool SvtCTLOptions::IsCTLFontEnabled() const
420 assert(pCTLOptions->IsLoaded());
421 return pCTLOptions->IsCTLFontEnabled();
424 void SvtCTLOptions::SetCTLSequenceChecking( bool _bEnabled )
426 assert(pCTLOptions->IsLoaded());
427 pCTLOptions->SetCTLSequenceChecking(_bEnabled);
430 bool SvtCTLOptions::IsCTLSequenceChecking() const
432 assert(pCTLOptions->IsLoaded());
433 return pCTLOptions->IsCTLSequenceChecking();
436 void SvtCTLOptions::SetCTLSequenceCheckingRestricted( bool _bEnable )
438 assert(pCTLOptions->IsLoaded());
439 pCTLOptions->SetCTLSequenceCheckingRestricted(_bEnable);
442 bool SvtCTLOptions::IsCTLSequenceCheckingRestricted() const
444 assert(pCTLOptions->IsLoaded());
445 return pCTLOptions->IsCTLSequenceCheckingRestricted();
448 void SvtCTLOptions::SetCTLSequenceCheckingTypeAndReplace( bool _bEnable )
450 assert(pCTLOptions->IsLoaded());
451 pCTLOptions->SetCTLSequenceCheckingTypeAndReplace(_bEnable);
454 bool SvtCTLOptions::IsCTLSequenceCheckingTypeAndReplace() const
456 assert(pCTLOptions->IsLoaded());
457 return pCTLOptions->IsCTLSequenceCheckingTypeAndReplace();
460 void SvtCTLOptions::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement )
462 assert(pCTLOptions->IsLoaded());
463 pCTLOptions->SetCTLCursorMovement( _eMovement );
466 SvtCTLOptions::CursorMovement SvtCTLOptions::GetCTLCursorMovement() const
468 assert(pCTLOptions->IsLoaded());
469 return pCTLOptions->GetCTLCursorMovement();
472 void SvtCTLOptions::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals )
474 assert(pCTLOptions->IsLoaded());
475 pCTLOptions->SetCTLTextNumerals( _eNumerals );
478 SvtCTLOptions::TextNumerals SvtCTLOptions::GetCTLTextNumerals() const
480 assert(pCTLOptions->IsLoaded());
481 return pCTLOptions->GetCTLTextNumerals();
484 bool SvtCTLOptions::IsReadOnly(EOption eOption) const
486 assert(pCTLOptions->IsLoaded());
487 return pCTLOptions->IsReadOnly(eOption);
491 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */