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 76 sal_Bool IsLoaded() { return m_bIsLoaded; } 77 void SetCTLFontEnabled( sal_Bool _bEnabled ); 78 sal_Bool IsCTLFontEnabled() const { return m_bCTLFontEnabled; } 79 80 void SetCTLSequenceChecking( sal_Bool _bEnabled ); 81 sal_Bool IsCTLSequenceChecking() const { return m_bCTLSequenceChecking;} 82 83 void SetCTLSequenceCheckingRestricted( sal_Bool _bEnable ); 84 sal_Bool IsCTLSequenceCheckingRestricted( void ) const { return m_bCTLRestricted; } 85 86 void SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable ); 87 sal_Bool IsCTLSequenceCheckingTypeAndReplace() const { return m_bCTLTypeAndReplace; } 88 89 void SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement ); 90 SvtCTLOptions::CursorMovement 91 GetCTLCursorMovement() const { return m_eCTLCursorMovement; } 92 93 void SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals ); 94 SvtCTLOptions::TextNumerals 95 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 //------------------------------------------------------------------------------ 106 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 141 SvtCTLOptions_Impl::~SvtCTLOptions_Impl() 142 { 143 if ( IsModified() == sal_True ) 144 Commit(); 145 } 146 // ----------------------------------------------------------------------------- 147 void SvtCTLOptions_Impl::Notify( const Sequence< rtl::OUString >& ) 148 { 149 Load(); 150 NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED); 151 } 152 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 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 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 // ----------------------------------------------------------------------------- 410 void SvtCTLOptions::SetCTLFontEnabled( sal_Bool _bEnabled ) 411 { 412 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 413 pCTLOptions->SetCTLFontEnabled( _bEnabled ); 414 } 415 // ----------------------------------------------------------------------------- 416 sal_Bool SvtCTLOptions::IsCTLFontEnabled() const 417 { 418 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 419 return pCTLOptions->IsCTLFontEnabled(); 420 } 421 // ----------------------------------------------------------------------------- 422 void SvtCTLOptions::SetCTLSequenceChecking( sal_Bool _bEnabled ) 423 { 424 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 425 pCTLOptions->SetCTLSequenceChecking(_bEnabled); 426 } 427 // ----------------------------------------------------------------------------- 428 sal_Bool SvtCTLOptions::IsCTLSequenceChecking() const 429 { 430 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 431 return pCTLOptions->IsCTLSequenceChecking(); 432 } 433 // ----------------------------------------------------------------------------- 434 void SvtCTLOptions::SetCTLSequenceCheckingRestricted( sal_Bool _bEnable ) 435 { 436 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 437 pCTLOptions->SetCTLSequenceCheckingRestricted(_bEnable); 438 } 439 // ----------------------------------------------------------------------------- 440 sal_Bool SvtCTLOptions::IsCTLSequenceCheckingRestricted( void ) const 441 { 442 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 443 return pCTLOptions->IsCTLSequenceCheckingRestricted(); 444 } 445 // ----------------------------------------------------------------------------- 446 void SvtCTLOptions::SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable ) 447 { 448 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 449 pCTLOptions->SetCTLSequenceCheckingTypeAndReplace(_bEnable); 450 } 451 // ----------------------------------------------------------------------------- 452 sal_Bool SvtCTLOptions::IsCTLSequenceCheckingTypeAndReplace() const 453 { 454 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 455 return pCTLOptions->IsCTLSequenceCheckingTypeAndReplace(); 456 } 457 // ----------------------------------------------------------------------------- 458 void SvtCTLOptions::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement ) 459 { 460 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 461 pCTLOptions->SetCTLCursorMovement( _eMovement ); 462 } 463 // ----------------------------------------------------------------------------- 464 SvtCTLOptions::CursorMovement SvtCTLOptions::GetCTLCursorMovement() const 465 { 466 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 467 return pCTLOptions->GetCTLCursorMovement(); 468 } 469 // ----------------------------------------------------------------------------- 470 void SvtCTLOptions::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals ) 471 { 472 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 473 pCTLOptions->SetCTLTextNumerals( _eNumerals ); 474 } 475 // ----------------------------------------------------------------------------- 476 SvtCTLOptions::TextNumerals SvtCTLOptions::GetCTLTextNumerals() const 477 { 478 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 479 return pCTLOptions->GetCTLTextNumerals(); 480 } 481 // ----------------------------------------------------------------------------- 482 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