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