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