1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svl.hxx" 30 31 #include <svl/ctloptions.hxx> 32 33 #include <svl/languageoptions.hxx> 34 #include <i18npool/mslangid.hxx> 35 #include <unotools/configitem.hxx> 36 #include <tools/debug.hxx> 37 #include <com/sun/star/uno/Any.h> 38 #include <com/sun/star/uno/Sequence.hxx> 39 #include <osl/mutex.hxx> 40 #include <vos/mutex.hxx> 41 #include <svl/smplhint.hxx> 42 #include <rtl/instance.hxx> 43 #include <unotools/syslocale.hxx> 44 #include <itemholder2.hxx> 45 46 using namespace ::com::sun::star; 47 using namespace ::com::sun::star::uno; 48 49 #define ASCII_STR(s) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(s) ) 50 #define CFG_READONLY_DEFAULT sal_False 51 52 // SvtCJKOptions_Impl ---------------------------------------------------------- 53 54 class SvtCTLOptions_Impl : public utl::ConfigItem 55 { 56 private: 57 sal_Bool m_bIsLoaded; 58 sal_Bool m_bCTLFontEnabled; 59 sal_Bool m_bCTLSequenceChecking; 60 sal_Bool m_bCTLRestricted; 61 sal_Bool m_bCTLTypeAndReplace; 62 SvtCTLOptions::CursorMovement m_eCTLCursorMovement; 63 SvtCTLOptions::TextNumerals m_eCTLTextNumerals; 64 65 sal_Bool m_bROCTLFontEnabled; 66 sal_Bool m_bROCTLSequenceChecking; 67 sal_Bool m_bROCTLRestricted; 68 sal_Bool m_bROCTLTypeAndReplace; 69 sal_Bool m_bROCTLCursorMovement; 70 sal_Bool m_bROCTLTextNumerals; 71 72 public: 73 SvtCTLOptions_Impl(); 74 ~SvtCTLOptions_Impl(); 75 76 virtual void Notify( const Sequence< rtl::OUString >& _aPropertyNames ); 77 virtual void Commit(); 78 void Load(); 79 80 sal_Bool IsLoaded() { return m_bIsLoaded; } 81 void SetCTLFontEnabled( sal_Bool _bEnabled ); 82 sal_Bool IsCTLFontEnabled() const { return m_bCTLFontEnabled; } 83 84 void SetCTLSequenceChecking( sal_Bool _bEnabled ); 85 sal_Bool IsCTLSequenceChecking() const { return m_bCTLSequenceChecking;} 86 87 void SetCTLSequenceCheckingRestricted( sal_Bool _bEnable ); 88 sal_Bool IsCTLSequenceCheckingRestricted( void ) const { return m_bCTLRestricted; } 89 90 void SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable ); 91 sal_Bool IsCTLSequenceCheckingTypeAndReplace() const { return m_bCTLTypeAndReplace; } 92 93 void SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement ); 94 SvtCTLOptions::CursorMovement 95 GetCTLCursorMovement() const { return m_eCTLCursorMovement; } 96 97 void SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals ); 98 SvtCTLOptions::TextNumerals 99 GetCTLTextNumerals() const { return m_eCTLTextNumerals; } 100 101 sal_Bool IsReadOnly(SvtCTLOptions::EOption eOption) const; 102 }; 103 //------------------------------------------------------------------------------ 104 namespace 105 { 106 struct PropertyNames 107 : public rtl::Static< Sequence< rtl::OUString >, PropertyNames > {}; 108 } 109 //------------------------------------------------------------------------------ 110 sal_Bool SvtCTLOptions_Impl::IsReadOnly(SvtCTLOptions::EOption eOption) const 111 { 112 sal_Bool bReadOnly = CFG_READONLY_DEFAULT; 113 switch(eOption) 114 { 115 case SvtCTLOptions::E_CTLFONT : bReadOnly = m_bROCTLFontEnabled ; break; 116 case SvtCTLOptions::E_CTLSEQUENCECHECKING : bReadOnly = m_bROCTLSequenceChecking ; break; 117 case SvtCTLOptions::E_CTLCURSORMOVEMENT : bReadOnly = m_bROCTLCursorMovement ; break; 118 case SvtCTLOptions::E_CTLTEXTNUMERALS : bReadOnly = m_bROCTLTextNumerals ; break; 119 case SvtCTLOptions::E_CTLSEQUENCECHECKINGRESTRICTED: bReadOnly = m_bROCTLRestricted ; break; 120 case SvtCTLOptions::E_CTLSEQUENCECHECKINGTYPEANDREPLACE: bReadOnly = m_bROCTLTypeAndReplace; break; 121 default: DBG_ERROR( "SvtCTLOptions_Impl::IsReadOnly() - invalid option" ); 122 } 123 return bReadOnly; 124 } 125 //------------------------------------------------------------------------------ 126 SvtCTLOptions_Impl::SvtCTLOptions_Impl() : 127 128 utl::ConfigItem( ASCII_STR("Office.Common/I18N/CTL") ), 129 130 m_bIsLoaded ( sal_False ), 131 m_bCTLFontEnabled ( sal_False ), 132 m_bCTLSequenceChecking ( sal_False ), 133 m_bCTLRestricted ( sal_False ), 134 m_eCTLCursorMovement ( SvtCTLOptions::MOVEMENT_LOGICAL ), 135 m_eCTLTextNumerals ( SvtCTLOptions::NUMERALS_ARABIC ), 136 137 m_bROCTLFontEnabled ( CFG_READONLY_DEFAULT ), 138 m_bROCTLSequenceChecking( CFG_READONLY_DEFAULT ), 139 m_bROCTLRestricted ( CFG_READONLY_DEFAULT ), 140 m_bROCTLCursorMovement ( CFG_READONLY_DEFAULT ), 141 m_bROCTLTextNumerals ( CFG_READONLY_DEFAULT ) 142 { 143 } 144 //------------------------------------------------------------------------------ 145 SvtCTLOptions_Impl::~SvtCTLOptions_Impl() 146 { 147 if ( IsModified() == sal_True ) 148 Commit(); 149 } 150 // ----------------------------------------------------------------------------- 151 void SvtCTLOptions_Impl::Notify( const Sequence< rtl::OUString >& ) 152 { 153 Load(); 154 NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED); 155 } 156 // ----------------------------------------------------------------------------- 157 void SvtCTLOptions_Impl::Commit() 158 { 159 Sequence< rtl::OUString > &rPropertyNames = PropertyNames::get(); 160 rtl::OUString* pOrgNames = rPropertyNames.getArray(); 161 sal_Int32 nOrgCount = rPropertyNames.getLength(); 162 163 Sequence< rtl::OUString > aNames( nOrgCount ); 164 Sequence< Any > aValues( nOrgCount ); 165 166 rtl::OUString* pNames = aNames.getArray(); 167 Any* pValues = aValues.getArray(); 168 sal_Int32 nRealCount = 0; 169 170 const uno::Type& rType = ::getBooleanCppuType(); 171 172 for ( int nProp = 0; nProp < nOrgCount; nProp++ ) 173 { 174 switch ( nProp ) 175 { 176 case 0: 177 { 178 if (!m_bROCTLFontEnabled) 179 { 180 pNames[nRealCount] = pOrgNames[nProp]; 181 pValues[nRealCount].setValue( &m_bCTLFontEnabled, rType ); 182 ++nRealCount; 183 } 184 } 185 break; 186 187 case 1: 188 { 189 if (!m_bROCTLSequenceChecking) 190 { 191 pNames[nRealCount] = pOrgNames[nProp]; 192 pValues[nRealCount].setValue( &m_bCTLSequenceChecking, rType ); 193 ++nRealCount; 194 } 195 } 196 break; 197 198 case 2: 199 { 200 if (!m_bROCTLCursorMovement) 201 { 202 pNames[nRealCount] = pOrgNames[nProp]; 203 pValues[nRealCount] <<= (sal_Int32)m_eCTLCursorMovement; 204 ++nRealCount; 205 } 206 } 207 break; 208 209 case 3: 210 { 211 if (!m_bROCTLTextNumerals) 212 { 213 pNames[nRealCount] = pOrgNames[nProp]; 214 pValues[nRealCount] <<= (sal_Int32)m_eCTLTextNumerals; 215 ++nRealCount; 216 } 217 } 218 break; 219 220 case 4: 221 { 222 if (!m_bROCTLRestricted) 223 { 224 pNames[nRealCount] = pOrgNames[nProp]; 225 pValues[nRealCount].setValue( &m_bCTLRestricted, rType ); 226 ++nRealCount; 227 } 228 } 229 break; 230 case 5: 231 { 232 if(!m_bROCTLTypeAndReplace) 233 { 234 pNames[nRealCount] = pOrgNames[nProp]; 235 pValues[nRealCount].setValue( &m_bCTLTypeAndReplace, rType ); 236 ++nRealCount; 237 } 238 } 239 break; 240 } 241 } 242 aNames.realloc(nRealCount); 243 aValues.realloc(nRealCount); 244 PutProperties( aNames, aValues ); 245 //broadcast changes 246 NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED); 247 } 248 // ----------------------------------------------------------------------------- 249 void SvtCTLOptions_Impl::Load() 250 { 251 Sequence< rtl::OUString >& rPropertyNames = PropertyNames::get(); 252 if ( !rPropertyNames.getLength() ) 253 { 254 rPropertyNames.realloc(6); 255 rtl::OUString* pNames = rPropertyNames.getArray(); 256 pNames[0] = ASCII_STR("CTLFont"); 257 pNames[1] = ASCII_STR("CTLSequenceChecking"); 258 pNames[2] = ASCII_STR("CTLCursorMovement"); 259 pNames[3] = ASCII_STR("CTLTextNumerals"); 260 pNames[4] = ASCII_STR("CTLSequenceCheckingRestricted"); 261 pNames[5] = ASCII_STR("CTLSequenceCheckingTypeAndReplace"); 262 EnableNotification( rPropertyNames ); 263 } 264 Sequence< Any > aValues = GetProperties( rPropertyNames ); 265 Sequence< sal_Bool > aROStates = GetReadOnlyStates( rPropertyNames ); 266 const Any* pValues = aValues.getConstArray(); 267 const sal_Bool* pROStates = aROStates.getConstArray(); 268 DBG_ASSERT( aValues.getLength() == rPropertyNames.getLength(), "GetProperties failed" ); 269 DBG_ASSERT( aROStates.getLength() == rPropertyNames.getLength(), "GetReadOnlyStates failed" ); 270 if ( aValues.getLength() == rPropertyNames.getLength() && aROStates.getLength() == rPropertyNames.getLength() ) 271 { 272 sal_Bool bValue = sal_False; 273 sal_Int32 nValue = 0; 274 275 for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ ) 276 { 277 if ( pValues[nProp].hasValue() ) 278 { 279 if ( pValues[nProp] >>= bValue ) 280 { 281 switch ( nProp ) 282 { 283 case 0: { m_bCTLFontEnabled = bValue; m_bROCTLFontEnabled = pROStates[nProp]; } break; 284 case 1: { m_bCTLSequenceChecking = bValue; m_bROCTLSequenceChecking = pROStates[nProp]; } break; 285 case 4: { m_bCTLRestricted = bValue; m_bROCTLRestricted = pROStates[nProp]; } break; 286 case 5: { m_bCTLTypeAndReplace = bValue; m_bROCTLTypeAndReplace = pROStates[nProp]; } break; 287 } 288 } 289 else if ( pValues[nProp] >>= nValue ) 290 { 291 switch ( nProp ) 292 { 293 case 2: { m_eCTLCursorMovement = (SvtCTLOptions::CursorMovement)nValue; m_bROCTLCursorMovement = pROStates[nProp]; } break; 294 case 3: { m_eCTLTextNumerals = (SvtCTLOptions::TextNumerals)nValue; m_bROCTLTextNumerals = pROStates[nProp]; } break; 295 } 296 } 297 } 298 } 299 } 300 sal_uInt16 nType = SvtLanguageOptions::GetScriptTypeOfLanguage(LANGUAGE_SYSTEM); 301 SvtSystemLanguageOptions aSystemLocaleSettings; 302 LanguageType eSystemLanguage = aSystemLocaleSettings.GetWin16SystemLanguage(); 303 sal_uInt16 nWinScript = SvtLanguageOptions::GetScriptTypeOfLanguage( eSystemLanguage ); 304 if( !m_bCTLFontEnabled && (( nType & SCRIPTTYPE_COMPLEX ) || 305 ((eSystemLanguage != LANGUAGE_SYSTEM) && ( nWinScript & SCRIPTTYPE_COMPLEX ))) ) 306 { 307 m_bCTLFontEnabled = sal_True; 308 sal_uInt16 nLanguage = SvtSysLocale().GetLanguage(); 309 //enable sequence checking for the appropriate languages 310 m_bCTLSequenceChecking = m_bCTLRestricted = m_bCTLTypeAndReplace = 311 (MsLangId::needsSequenceChecking( nLanguage) || 312 MsLangId::needsSequenceChecking( eSystemLanguage)); 313 Commit(); 314 } 315 m_bIsLoaded = sal_True; 316 } 317 //------------------------------------------------------------------------------ 318 void SvtCTLOptions_Impl::SetCTLFontEnabled( sal_Bool _bEnabled ) 319 { 320 if(!m_bROCTLFontEnabled && m_bCTLFontEnabled != _bEnabled) 321 { 322 m_bCTLFontEnabled = _bEnabled; 323 SetModified(); 324 NotifyListeners(0); 325 } 326 } 327 //------------------------------------------------------------------------------ 328 void SvtCTLOptions_Impl::SetCTLSequenceChecking( sal_Bool _bEnabled ) 329 { 330 if(!m_bROCTLSequenceChecking && m_bCTLSequenceChecking != _bEnabled) 331 { 332 SetModified(); 333 m_bCTLSequenceChecking = _bEnabled; 334 NotifyListeners(0); 335 } 336 } 337 //------------------------------------------------------------------------------ 338 void SvtCTLOptions_Impl::SetCTLSequenceCheckingRestricted( sal_Bool _bEnabled ) 339 { 340 if(!m_bROCTLRestricted && m_bCTLRestricted != _bEnabled) 341 { 342 SetModified(); 343 m_bCTLRestricted = _bEnabled; 344 NotifyListeners(0); 345 } 346 } 347 //------------------------------------------------------------------------------ 348 void SvtCTLOptions_Impl::SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnabled ) 349 { 350 if(!m_bROCTLTypeAndReplace && m_bCTLTypeAndReplace != _bEnabled) 351 { 352 SetModified(); 353 m_bCTLTypeAndReplace = _bEnabled; 354 NotifyListeners(0); 355 } 356 } 357 //------------------------------------------------------------------------------ 358 void SvtCTLOptions_Impl::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement ) 359 { 360 if (!m_bROCTLCursorMovement && m_eCTLCursorMovement != _eMovement ) 361 { 362 SetModified(); 363 m_eCTLCursorMovement = _eMovement; 364 NotifyListeners(0); 365 } 366 } 367 //------------------------------------------------------------------------------ 368 void SvtCTLOptions_Impl::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals ) 369 { 370 if (!m_bROCTLTextNumerals && m_eCTLTextNumerals != _eNumerals ) 371 { 372 SetModified(); 373 m_eCTLTextNumerals = _eNumerals; 374 NotifyListeners(0); 375 } 376 } 377 // global ---------------------------------------------------------------- 378 379 static SvtCTLOptions_Impl* pCTLOptions = NULL; 380 static sal_Int32 nCTLRefCount = 0; 381 namespace { struct CTLMutex : public rtl::Static< osl::Mutex, CTLMutex > {}; } 382 383 // class SvtCTLOptions -------------------------------------------------- 384 385 SvtCTLOptions::SvtCTLOptions( sal_Bool bDontLoad ) 386 { 387 // Global access, must be guarded (multithreading) 388 ::osl::MutexGuard aGuard( CTLMutex::get() ); 389 if ( !pCTLOptions ) 390 { 391 pCTLOptions = new SvtCTLOptions_Impl; 392 ItemHolder2::holdConfigItem(E_CTLOPTIONS); 393 } 394 if( !bDontLoad && !pCTLOptions->IsLoaded() ) 395 pCTLOptions->Load(); 396 397 ++nCTLRefCount; 398 m_pImp = pCTLOptions; 399 m_pImp->AddListener(this); 400 } 401 402 // ----------------------------------------------------------------------- 403 404 SvtCTLOptions::~SvtCTLOptions() 405 { 406 // Global access, must be guarded (multithreading) 407 ::osl::MutexGuard aGuard( CTLMutex::get() ); 408 409 m_pImp->RemoveListener(this); 410 if ( !--nCTLRefCount ) 411 DELETEZ( pCTLOptions ); 412 } 413 // ----------------------------------------------------------------------------- 414 void SvtCTLOptions::SetCTLFontEnabled( sal_Bool _bEnabled ) 415 { 416 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 417 pCTLOptions->SetCTLFontEnabled( _bEnabled ); 418 } 419 // ----------------------------------------------------------------------------- 420 sal_Bool SvtCTLOptions::IsCTLFontEnabled() const 421 { 422 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 423 return pCTLOptions->IsCTLFontEnabled(); 424 } 425 // ----------------------------------------------------------------------------- 426 void SvtCTLOptions::SetCTLSequenceChecking( sal_Bool _bEnabled ) 427 { 428 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 429 pCTLOptions->SetCTLSequenceChecking(_bEnabled); 430 } 431 // ----------------------------------------------------------------------------- 432 sal_Bool SvtCTLOptions::IsCTLSequenceChecking() const 433 { 434 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 435 return pCTLOptions->IsCTLSequenceChecking(); 436 } 437 // ----------------------------------------------------------------------------- 438 void SvtCTLOptions::SetCTLSequenceCheckingRestricted( sal_Bool _bEnable ) 439 { 440 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 441 pCTLOptions->SetCTLSequenceCheckingRestricted(_bEnable); 442 } 443 // ----------------------------------------------------------------------------- 444 sal_Bool SvtCTLOptions::IsCTLSequenceCheckingRestricted( void ) const 445 { 446 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 447 return pCTLOptions->IsCTLSequenceCheckingRestricted(); 448 } 449 // ----------------------------------------------------------------------------- 450 void SvtCTLOptions::SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable ) 451 { 452 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 453 pCTLOptions->SetCTLSequenceCheckingTypeAndReplace(_bEnable); 454 } 455 // ----------------------------------------------------------------------------- 456 sal_Bool SvtCTLOptions::IsCTLSequenceCheckingTypeAndReplace() const 457 { 458 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 459 return pCTLOptions->IsCTLSequenceCheckingTypeAndReplace(); 460 } 461 // ----------------------------------------------------------------------------- 462 void SvtCTLOptions::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement ) 463 { 464 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 465 pCTLOptions->SetCTLCursorMovement( _eMovement ); 466 } 467 // ----------------------------------------------------------------------------- 468 SvtCTLOptions::CursorMovement SvtCTLOptions::GetCTLCursorMovement() const 469 { 470 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 471 return pCTLOptions->GetCTLCursorMovement(); 472 } 473 // ----------------------------------------------------------------------------- 474 void SvtCTLOptions::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals ) 475 { 476 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 477 pCTLOptions->SetCTLTextNumerals( _eNumerals ); 478 } 479 // ----------------------------------------------------------------------------- 480 SvtCTLOptions::TextNumerals SvtCTLOptions::GetCTLTextNumerals() const 481 { 482 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 483 return pCTLOptions->GetCTLTextNumerals(); 484 } 485 // ----------------------------------------------------------------------------- 486 sal_Bool SvtCTLOptions::IsReadOnly(EOption eOption) const 487 { 488 DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); 489 return pCTLOptions->IsReadOnly(eOption); 490 } 491 // ----------------------------------------------------------------------------- 492 493