merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / config / syslocaleoptions.cxx
blob94b96bd91bd1f87574f2accced93341cb693595c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: syslocaleoptions.cxx,v $
10 * $Revision: 1.23 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #ifdef SVL_DLLIMPLEMENTATION
35 #undef SVL_DLLIMPLEMENTATION
36 #endif
37 #define SVT_DLLIMPLEMENTATION
39 #include <svtools/syslocaleoptions.hxx>
40 #include <broadcast.hxx>
41 #include <listener.hxx>
42 #include <svtools/smplhint.hxx>
43 #include <i18npool/mslangid.hxx>
44 #include <tools/string.hxx>
45 #include <rtl/ustrbuf.hxx>
46 #include <rtl/instance.hxx>
47 #include <unotools/configmgr.hxx>
48 #include <unotools/configitem.hxx>
49 #include <tools/debug.hxx>
50 #include <com/sun/star/uno/Any.hxx>
51 #include <com/sun/star/uno/Sequence.hxx>
52 #include <vcl/settings.hxx>
53 #include <vcl/svapp.hxx>
55 #include <rtl/logfile.hxx>
57 #include "itemholder2.hxx"
60 #define CFG_READONLY_DEFAULT sal_False
62 using namespace osl;
63 using namespace utl;
64 using namespace rtl;
65 using namespace com::sun::star::uno;
66 using namespace com::sun::star::lang;
69 SvtSysLocaleOptions_Impl* SvtSysLocaleOptions::pOptions = NULL;
70 sal_Int32 SvtSysLocaleOptions::nRefCount = 0;
71 namespace
73 struct CurrencyChangeLink
74 : public rtl::Static<Link, CurrencyChangeLink> {};
77 class SvtSysLocaleOptions_Impl : public utl::ConfigItem
79 OUString m_aLocaleString; // en-US or de-DE or empty for SYSTEM
80 LanguageType m_eLocaleLanguageType; // same for convenience access
81 OUString m_aCurrencyString; // USD-en-US or EUR-de-DE
82 SvtBroadcaster m_aBroadcaster;
83 ULONG m_nBlockedHint; // pending hints
84 sal_Int32 m_nBroadcastBlocked; // broadcast only if this is 0
85 sal_Bool m_bDecimalSeparator; //use decimal separator same as locale
88 sal_Bool m_bROLocale;
89 sal_Bool m_bROCurrency;
90 sal_Bool m_bRODecimalSeparator;
92 static const Sequence< /* const */ OUString > GetPropertyNames();
94 void UpdateMiscSettings_Impl();
95 ULONG ChangeLocaleSettings();
96 void ChangeDefaultCurrency() const;
97 void Broadcast( ULONG nHint );
99 public:
100 SvtSysLocaleOptions_Impl();
101 virtual ~SvtSysLocaleOptions_Impl();
103 virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
104 virtual void Commit();
106 const OUString& GetLocaleString() const
107 { return m_aLocaleString; }
108 void SetLocaleString( const OUString& rStr );
109 LanguageType GetLocaleLanguageType() const
110 { return m_eLocaleLanguageType; }
112 const OUString& GetCurrencyString() const
113 { return m_aCurrencyString; }
114 void SetCurrencyString( const OUString& rStr );
116 sal_Bool IsDecimalSeparatorAsLocale() const { return m_bDecimalSeparator;}
117 void SetDecimalSeparatorAsLocale( sal_Bool bSet);
119 SvtBroadcaster& GetBroadcaster()
120 { return m_aBroadcaster; }
121 void BlockBroadcasts( BOOL bBlock );
122 sal_Bool IsReadOnly( SvtSysLocaleOptions::EOption eOption ) const;
126 #define ROOTNODE_SYSLOCALE OUString(RTL_CONSTASCII_USTRINGPARAM("Setup/L10N"))
128 #define PROPERTYNAME_LOCALE OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupSystemLocale"))
129 #define PROPERTYNAME_CURRENCY OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupCurrency"))
130 #define PROPERTYNAME_DECIMALSEPARATOR OUString(RTL_CONSTASCII_USTRINGPARAM("DecimalSeparatorAsLocale"))
132 #define PROPERTYHANDLE_LOCALE 0
133 #define PROPERTYHANDLE_CURRENCY 1
134 #define PROPERTYHANDLE_DECIMALSEPARATOR 2
136 #define PROPERTYCOUNT 3
138 const Sequence< OUString > SvtSysLocaleOptions_Impl::GetPropertyNames()
140 static const OUString pProperties[] =
142 PROPERTYNAME_LOCALE,
143 PROPERTYNAME_CURRENCY,
144 PROPERTYNAME_DECIMALSEPARATOR
146 static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT );
147 return seqPropertyNames;
151 // -----------------------------------------------------------------------
153 SvtSysLocaleOptions_Impl::SvtSysLocaleOptions_Impl()
154 : ConfigItem( ROOTNODE_SYSLOCALE )
155 , m_nBlockedHint( 0 )
156 , m_nBroadcastBlocked( 0 )
157 , m_bDecimalSeparator( sal_True )
158 , m_bROLocale(CFG_READONLY_DEFAULT)
159 , m_bROCurrency(CFG_READONLY_DEFAULT)
160 , m_bRODecimalSeparator(sal_False)
163 if ( !IsValidConfigMgr() )
164 ChangeLocaleSettings(); // assume SYSTEM defaults during Setup
165 else
167 const Sequence< OUString > aNames = GetPropertyNames();
168 Sequence< Any > aValues = GetProperties( aNames );
169 Sequence< sal_Bool > aROStates = GetReadOnlyStates( aNames );
170 const Any* pValues = aValues.getConstArray();
171 const sal_Bool* pROStates = aROStates.getConstArray();
172 DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" );
173 DBG_ASSERT( aROStates.getLength() == aNames.getLength(), "GetReadOnlyStates failed" );
174 if ( aValues.getLength() == aNames.getLength() && aROStates.getLength() == aNames.getLength() )
176 for ( sal_Int32 nProp = 0; nProp < aNames.getLength(); nProp++ )
178 DBG_ASSERT( pValues[nProp].hasValue(), "property value missing" );
179 if ( pValues[nProp].hasValue() )
181 switch ( nProp )
183 case PROPERTYHANDLE_LOCALE :
185 OUString aStr;
186 if ( pValues[nProp] >>= aStr )
187 m_aLocaleString = aStr;
188 else
190 DBG_ERRORFILE( "Wrong property type!" );
192 m_bROLocale = pROStates[nProp];
194 break;
195 case PROPERTYHANDLE_CURRENCY :
197 OUString aStr;
198 if ( pValues[nProp] >>= aStr )
199 m_aCurrencyString = aStr;
200 else
202 DBG_ERRORFILE( "Wrong property type!" );
204 m_bROCurrency = pROStates[nProp];
206 break;
207 case PROPERTYHANDLE_DECIMALSEPARATOR:
209 sal_Bool bValue = sal_Bool();
210 if ( pValues[nProp] >>= bValue )
211 m_bDecimalSeparator = bValue;
212 else
214 DBG_ERRORFILE( "Wrong property type!" );
216 m_bRODecimalSeparator = pROStates[nProp];
218 break;
219 default:
220 DBG_ERRORFILE( "Wrong property type!" );
225 UpdateMiscSettings_Impl();
226 ChangeLocaleSettings();
227 EnableNotification( aNames );
232 SvtSysLocaleOptions_Impl::~SvtSysLocaleOptions_Impl()
234 if ( IsModified() )
235 Commit();
239 void SvtSysLocaleOptions_Impl::BlockBroadcasts( BOOL bBlock )
241 if ( bBlock )
242 ++m_nBroadcastBlocked;
243 else if ( m_nBroadcastBlocked )
245 if ( --m_nBroadcastBlocked == 0 )
246 Broadcast( 0 );
250 sal_Bool SvtSysLocaleOptions_Impl::IsReadOnly( SvtSysLocaleOptions::EOption eOption ) const
252 sal_Bool bReadOnly = CFG_READONLY_DEFAULT;
253 switch(eOption)
255 case SvtSysLocaleOptions::E_LOCALE :
257 bReadOnly = m_bROLocale;
258 break;
260 case SvtSysLocaleOptions::E_CURRENCY :
262 bReadOnly = m_bROCurrency;
263 break;
266 return bReadOnly;
270 void SvtSysLocaleOptions_Impl::Broadcast( ULONG nHint )
272 if ( m_nBroadcastBlocked )
273 m_nBlockedHint |= nHint;
274 else
276 nHint |= m_nBlockedHint;
277 m_nBlockedHint = 0;
278 if ( nHint )
280 if ( nHint & SYSLOCALEOPTIONS_HINT_CURRENCY )
281 ChangeDefaultCurrency();
282 SfxSimpleHint aHint( nHint );
283 GetBroadcaster().Broadcast( aHint );
289 void SvtSysLocaleOptions_Impl::Commit()
291 const Sequence< OUString > aOrgNames = GetPropertyNames();
292 sal_Int32 nOrgCount = aOrgNames.getLength();
294 Sequence< OUString > aNames( nOrgCount );
295 Sequence< Any > aValues( nOrgCount );
297 OUString* pNames = aNames.getArray();
298 Any* pValues = aValues.getArray();
299 sal_Int32 nRealCount = 0;
301 for ( sal_Int32 nProp = 0; nProp < nOrgCount; nProp++ )
303 switch ( nProp )
305 case PROPERTYHANDLE_LOCALE :
307 if (!m_bROLocale)
309 pNames[nRealCount] = aOrgNames[nProp];
310 pValues[nRealCount] <<= m_aLocaleString;
311 ++nRealCount;
314 break;
315 case PROPERTYHANDLE_CURRENCY :
317 if (!m_bROLocale)
319 pNames[nRealCount] = aOrgNames[nProp];
320 pValues[nRealCount] <<= m_aCurrencyString;
321 ++nRealCount;
324 break;
325 case PROPERTYHANDLE_DECIMALSEPARATOR:
326 if( !m_bRODecimalSeparator )
328 pNames[nRealCount] = aOrgNames[nProp];
329 pValues[nRealCount] <<= m_bDecimalSeparator;
330 ++nRealCount;
332 break;
333 default:
334 DBG_ERRORFILE( "invalid index to save a path" );
337 aNames.realloc(nRealCount);
338 aValues.realloc(nRealCount);
339 PutProperties( aNames, aValues );
340 ClearModified();
344 void SvtSysLocaleOptions_Impl::SetLocaleString( const OUString& rStr )
346 if (!m_bROLocale && rStr != m_aLocaleString )
348 m_aLocaleString = rStr;
349 SetModified();
350 ULONG nHint = SYSLOCALEOPTIONS_HINT_LOCALE;
351 nHint |= ChangeLocaleSettings();
352 Broadcast( nHint );
357 ULONG SvtSysLocaleOptions_Impl::ChangeLocaleSettings()
359 // An empty config value denotes SYSTEM locale
360 if ( m_aLocaleString.getLength() )
361 m_eLocaleLanguageType = MsLangId::convertIsoStringToLanguage( m_aLocaleString );
362 else
363 m_eLocaleLanguageType = LANGUAGE_SYSTEM;
364 ULONG nHint = 0;
365 // new locale and no fixed currency => locale default currency might change
366 if ( !m_aCurrencyString.getLength() )
367 nHint |= SYSLOCALEOPTIONS_HINT_CURRENCY;
368 return nHint;
372 void SvtSysLocaleOptions_Impl::SetCurrencyString( const OUString& rStr )
374 if (!m_bROCurrency && rStr != m_aCurrencyString )
376 m_aCurrencyString = rStr;
377 SetModified();
378 Broadcast( SYSLOCALEOPTIONS_HINT_CURRENCY );
382 void SvtSysLocaleOptions_Impl::SetDecimalSeparatorAsLocale( sal_Bool bSet)
384 if(bSet != m_bDecimalSeparator)
386 m_bDecimalSeparator = bSet;
387 SetModified();
388 UpdateMiscSettings_Impl();
393 void SvtSysLocaleOptions_Impl::ChangeDefaultCurrency() const
395 const Link& rLink = SvtSysLocaleOptions::GetCurrencyChangeLink();
396 if ( rLink.IsSet() )
397 rLink.Call( NULL );
401 void SvtSysLocaleOptions_Impl::Notify( const Sequence< rtl::OUString >& seqPropertyNames )
403 ULONG nHint = 0;
404 Sequence< Any > seqValues = GetProperties( seqPropertyNames );
405 Sequence< sal_Bool > seqROStates = GetReadOnlyStates( seqPropertyNames );
406 sal_Int32 nCount = seqPropertyNames.getLength();
407 for( sal_Int32 nProp = 0; nProp < nCount; ++nProp )
409 if( seqPropertyNames[nProp] == PROPERTYNAME_LOCALE )
411 DBG_ASSERT( seqValues[nProp].getValueTypeClass() == TypeClass_STRING, "Locale property type" );
412 seqValues[nProp] >>= m_aLocaleString;
413 m_bROLocale = seqROStates[nProp];
414 nHint |= SYSLOCALEOPTIONS_HINT_LOCALE;
415 nHint |= ChangeLocaleSettings();
417 else if( seqPropertyNames[nProp] == PROPERTYNAME_CURRENCY )
419 DBG_ASSERT( seqValues[nProp].getValueTypeClass() == TypeClass_STRING, "Currency property type" );
420 seqValues[nProp] >>= m_aCurrencyString;
421 m_bROCurrency = seqROStates[nProp];
422 nHint |= SYSLOCALEOPTIONS_HINT_CURRENCY;
424 else if( seqPropertyNames[nProp] == PROPERTYNAME_DECIMALSEPARATOR )
426 seqValues[nProp] >>= m_bDecimalSeparator;
427 m_bRODecimalSeparator = seqROStates[nProp];
428 UpdateMiscSettings_Impl();
431 if ( nHint )
432 Broadcast( nHint );
434 /* -----------------10.02.2004 15:25-----------------
436 --------------------------------------------------*/
437 void SvtSysLocaleOptions_Impl::UpdateMiscSettings_Impl()
439 AllSettings aAllSettings( Application::GetSettings() );
440 MiscSettings aMiscSettings = aAllSettings.GetMiscSettings();
441 aMiscSettings.SetEnableLocalizedDecimalSep(m_bDecimalSeparator);
442 aAllSettings.SetMiscSettings( aMiscSettings );
443 Application::SetSettings( aAllSettings );
446 // ====================================================================
448 SvtSysLocaleOptions::SvtSysLocaleOptions()
450 MutexGuard aGuard( GetMutex() );
451 if ( !pOptions )
453 RTL_LOGFILE_CONTEXT(aLog, "svtools ( ??? ) ::SvtSysLocaleOptions_Impl::ctor()");
454 pOptions = new SvtSysLocaleOptions_Impl;
456 ItemHolder2::holdConfigItem(E_SYSLOCALEOPTIONS);
458 ++nRefCount;
462 SvtSysLocaleOptions::~SvtSysLocaleOptions()
464 MutexGuard aGuard( GetMutex() );
465 if ( !--nRefCount )
467 delete pOptions;
468 pOptions = NULL;
473 // static
474 Mutex& SvtSysLocaleOptions::GetMutex()
476 static Mutex* pMutex = NULL;
477 if( !pMutex )
479 MutexGuard aGuard( Mutex::getGlobalMutex() );
480 if( !pMutex )
482 // #i77768# Due to a static reference in the toolkit lib
483 // we need a mutex that lives longer than the svtools library.
484 // Otherwise the dtor would use a destructed mutex!!
485 pMutex = new Mutex;
488 return *pMutex;
492 sal_Bool SvtSysLocaleOptions::IsModified()
494 MutexGuard aGuard( GetMutex() );
495 return pOptions->IsModified();
499 void SvtSysLocaleOptions::Commit()
501 MutexGuard aGuard( GetMutex() );
502 pOptions->Commit();
506 BOOL SvtSysLocaleOptions::AddListener( SvtListener& rLst )
508 MutexGuard aGuard( GetMutex() );
509 return rLst.StartListening( pOptions->GetBroadcaster() );
513 BOOL SvtSysLocaleOptions::RemoveListener( SvtListener& rLst )
515 MutexGuard aGuard( GetMutex() );
516 return rLst.EndListening( pOptions->GetBroadcaster() );
520 void SvtSysLocaleOptions::BlockBroadcasts( BOOL bBlock )
522 MutexGuard aGuard( GetMutex() );
523 pOptions->BlockBroadcasts( bBlock );
527 const OUString& SvtSysLocaleOptions::GetLocaleConfigString() const
529 MutexGuard aGuard( GetMutex() );
530 return pOptions->GetLocaleString();
534 void SvtSysLocaleOptions::SetLocaleConfigString( const OUString& rStr )
536 MutexGuard aGuard( GetMutex() );
537 pOptions->SetLocaleString( rStr );
541 const OUString& SvtSysLocaleOptions::GetCurrencyConfigString() const
543 MutexGuard aGuard( GetMutex() );
544 return pOptions->GetCurrencyString();
548 void SvtSysLocaleOptions::SetCurrencyConfigString( const OUString& rStr )
550 MutexGuard aGuard( GetMutex() );
551 pOptions->SetCurrencyString( rStr );
555 LanguageType SvtSysLocaleOptions::GetLocaleLanguageType() const
557 MutexGuard aGuard( GetMutex() );
558 return pOptions->GetLocaleLanguageType();
561 /*-- 11.02.2004 13:31:41---------------------------------------------------
563 -----------------------------------------------------------------------*/
564 sal_Bool SvtSysLocaleOptions::IsDecimalSeparatorAsLocale() const
566 MutexGuard aGuard( GetMutex() );
567 return pOptions->IsDecimalSeparatorAsLocale();
569 /*-- 11.02.2004 13:31:41---------------------------------------------------
571 -----------------------------------------------------------------------*/
572 void SvtSysLocaleOptions::SetDecimalSeparatorAsLocale( sal_Bool bSet)
574 MutexGuard aGuard( GetMutex() );
575 pOptions->SetDecimalSeparatorAsLocale(bSet);
579 sal_Bool SvtSysLocaleOptions::IsReadOnly( EOption eOption ) const
581 MutexGuard aGuard( GetMutex() );
582 return pOptions->IsReadOnly( eOption );
585 // static
586 void SvtSysLocaleOptions::GetCurrencyAbbrevAndLanguage( String& rAbbrev,
587 LanguageType& eLang, const ::rtl::OUString& rConfigString )
589 sal_Int32 nDelim = rConfigString.indexOf( '-' );
590 if ( nDelim >= 0 )
592 rAbbrev = rConfigString.copy( 0, nDelim );
593 String aIsoStr( rConfigString.copy( nDelim+1 ) );
594 eLang = MsLangId::convertIsoStringToLanguage( aIsoStr );
596 else
598 rAbbrev = rConfigString;
599 eLang = (rAbbrev.Len() ? LANGUAGE_NONE : LANGUAGE_SYSTEM);
604 // static
605 ::rtl::OUString SvtSysLocaleOptions::CreateCurrencyConfigString(
606 const String& rAbbrev, LanguageType eLang )
608 String aIsoStr( MsLangId::convertLanguageToIsoString( eLang ) );
609 if ( aIsoStr.Len() )
611 ::rtl::OUStringBuffer aStr( rAbbrev.Len() + 1 + aIsoStr.Len() );
612 aStr.append( rAbbrev.GetBuffer(), rAbbrev.Len() );
613 aStr.append( sal_Unicode('-') );
614 aStr.append( aIsoStr.GetBuffer(), aIsoStr.Len() );
615 return aStr.makeStringAndClear();
617 else
618 return rAbbrev;
622 // static
623 void SvtSysLocaleOptions::SetCurrencyChangeLink( const Link& rLink )
625 MutexGuard aGuard( GetMutex() );
626 DBG_ASSERT( !CurrencyChangeLink::get().IsSet(), "SvtSysLocaleOptions::SetCurrencyChangeLink: already set" );
627 CurrencyChangeLink::get() = rLink;
631 // static
632 const Link& SvtSysLocaleOptions::GetCurrencyChangeLink()
634 MutexGuard aGuard( GetMutex() );
635 return CurrencyChangeLink::get();