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