summaryrefslogtreecommitdiff
path: root/binfilter/bf_svtools/source/config/svt_syslocaleoptions.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_svtools/source/config/svt_syslocaleoptions.cxx')
-rw-r--r--binfilter/bf_svtools/source/config/svt_syslocaleoptions.cxx476
1 files changed, 476 insertions, 0 deletions
diff --git a/binfilter/bf_svtools/source/config/svt_syslocaleoptions.cxx b/binfilter/bf_svtools/source/config/svt_syslocaleoptions.cxx
new file mode 100644
index 000000000000..72b07b7ba6e9
--- /dev/null
+++ b/binfilter/bf_svtools/source/config/svt_syslocaleoptions.cxx
@@ -0,0 +1,476 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <bf_svtools/syslocaleoptions.hxx>
+
+#include <broadcast.hxx>
+#include <listener.hxx>
+#include <bf_svtools/smplhint.hxx>
+#include <i18npool/mslangid.hxx>
+#include <tools/string.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/instance.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/configitem.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+#include <rtl/logfile.hxx>
+
+#include "itemholder2.hxx"
+
+namespace binfilter
+{
+
+#define CFG_READONLY_DEFAULT sal_False
+
+using namespace osl;
+using namespace utl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+
+
+SvtSysLocaleOptions_Impl* SvtSysLocaleOptions::pOptions = NULL;
+sal_Int32 SvtSysLocaleOptions::nRefCount = 0;
+namespace
+{
+ struct CurrencyChangeLink
+ : public rtl::Static<Link, CurrencyChangeLink> {};
+}
+
+class SvtSysLocaleOptions_Impl : public utl::ConfigItem
+{
+ OUString m_aLocaleString; // en-US or de-DE or empty for SYSTEM
+ LanguageType m_eLocaleLanguageType; // same for convenience access
+ OUString m_aCurrencyString; // USD-en-US or EUR-de-DE
+ SvtBroadcaster m_aBroadcaster;
+ ULONG m_nBlockedHint; // pending hints
+ sal_Int32 m_nBroadcastBlocked; // broadcast only if this is 0
+ sal_Bool m_bDecimalSeparator; //use decimal separator same as locale
+
+
+ sal_Bool m_bROLocale;
+ sal_Bool m_bROCurrency;
+ sal_Bool m_bRODecimalSeparator;
+
+ static const Sequence< /* const */ OUString > GetPropertyNames();
+
+ void UpdateMiscSettings_Impl();
+ ULONG ChangeLocaleSettings();
+ void ChangeDefaultCurrency() const;
+ void Broadcast( ULONG nHint );
+
+public:
+ SvtSysLocaleOptions_Impl();
+ virtual ~SvtSysLocaleOptions_Impl();
+
+ virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
+ virtual void Commit();
+
+ const OUString& GetLocaleString() const
+ { return m_aLocaleString; }
+ LanguageType GetLocaleLanguageType() const
+ { return m_eLocaleLanguageType; }
+
+ const OUString& GetCurrencyString() const
+ { return m_aCurrencyString; }
+
+ sal_Bool IsDecimalSeparatorAsLocale() const { return m_bDecimalSeparator;}
+
+ SvtBroadcaster& GetBroadcaster()
+ { return m_aBroadcaster; }
+};
+
+
+#define ROOTNODE_SYSLOCALE OUString(RTL_CONSTASCII_USTRINGPARAM("Setup/L10N"))
+
+#define PROPERTYNAME_LOCALE OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupSystemLocale"))
+#define PROPERTYNAME_CURRENCY OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupCurrency"))
+#define PROPERTYNAME_DECIMALSEPARATOR OUString(RTL_CONSTASCII_USTRINGPARAM("DecimalSeparatorAsLocale"))
+
+#define PROPERTYHANDLE_LOCALE 0
+#define PROPERTYHANDLE_CURRENCY 1
+#define PROPERTYHANDLE_DECIMALSEPARATOR 2
+
+#define PROPERTYCOUNT 3
+
+const Sequence< OUString > SvtSysLocaleOptions_Impl::GetPropertyNames()
+{
+ static const OUString pProperties[] =
+ {
+ PROPERTYNAME_LOCALE,
+ PROPERTYNAME_CURRENCY,
+ PROPERTYNAME_DECIMALSEPARATOR
+ };
+ static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT );
+ return seqPropertyNames;
+}
+
+
+// -----------------------------------------------------------------------
+
+SvtSysLocaleOptions_Impl::SvtSysLocaleOptions_Impl()
+ : ConfigItem( ROOTNODE_SYSLOCALE )
+ , m_nBlockedHint( 0 )
+ , m_nBroadcastBlocked( 0 )
+ , m_bDecimalSeparator( sal_True )
+ , m_bROLocale(CFG_READONLY_DEFAULT)
+ , m_bROCurrency(CFG_READONLY_DEFAULT)
+ , m_bRODecimalSeparator(sal_False)
+
+{
+ if ( !IsValidConfigMgr() )
+ ChangeLocaleSettings(); // assume SYSTEM defaults during Setup
+ else
+ {
+ const Sequence< OUString > aNames = GetPropertyNames();
+ Sequence< Any > aValues = GetProperties( aNames );
+ Sequence< sal_Bool > aROStates = GetReadOnlyStates( aNames );
+ const Any* pValues = aValues.getConstArray();
+ const sal_Bool* pROStates = aROStates.getConstArray();
+ DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" );
+ DBG_ASSERT( aROStates.getLength() == aNames.getLength(), "GetReadOnlyStates failed" );
+ if ( aValues.getLength() == aNames.getLength() && aROStates.getLength() == aNames.getLength() )
+ {
+ for ( sal_Int32 nProp = 0; nProp < aNames.getLength(); nProp++ )
+ {
+ DBG_ASSERT( pValues[nProp].hasValue(), "property value missing" );
+ if ( pValues[nProp].hasValue() )
+ {
+ switch ( nProp )
+ {
+ case PROPERTYHANDLE_LOCALE :
+ {
+ OUString aStr;
+ if ( pValues[nProp] >>= aStr )
+ m_aLocaleString = aStr;
+ else
+ {
+ DBG_ERRORFILE( "Wrong property type!" );
+ }
+ m_bROLocale = pROStates[nProp];
+ }
+ break;
+ case PROPERTYHANDLE_CURRENCY :
+ {
+ OUString aStr;
+ if ( pValues[nProp] >>= aStr )
+ m_aCurrencyString = aStr;
+ else
+ {
+ DBG_ERRORFILE( "Wrong property type!" );
+ }
+ m_bROCurrency = pROStates[nProp];
+ }
+ break;
+ case PROPERTYHANDLE_DECIMALSEPARATOR:
+ {
+ sal_Bool bValue = sal_Bool();
+ if ( pValues[nProp] >>= bValue )
+ m_bDecimalSeparator = bValue;
+ else
+ {
+ DBG_ERRORFILE( "Wrong property type!" );
+ }
+ m_bRODecimalSeparator = pROStates[nProp];
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "Wrong property type!" );
+ }
+ }
+ }
+ }
+ UpdateMiscSettings_Impl();
+ ChangeLocaleSettings();
+ EnableNotification( aNames );
+ }
+}
+
+
+SvtSysLocaleOptions_Impl::~SvtSysLocaleOptions_Impl()
+{
+ if ( IsModified() )
+ Commit();
+}
+
+
+void SvtSysLocaleOptions_Impl::Broadcast( ULONG nHint )
+{
+ if ( m_nBroadcastBlocked )
+ m_nBlockedHint |= nHint;
+ else
+ {
+ nHint |= m_nBlockedHint;
+ m_nBlockedHint = 0;
+ if ( nHint )
+ {
+ if ( nHint & SYSLOCALEOPTIONS_HINT_CURRENCY )
+ ChangeDefaultCurrency();
+ SfxSimpleHint aHint( nHint );
+ GetBroadcaster().Broadcast( aHint );
+ }
+ }
+}
+
+
+void SvtSysLocaleOptions_Impl::Commit()
+{
+ const Sequence< OUString > aOrgNames = GetPropertyNames();
+ sal_Int32 nOrgCount = aOrgNames.getLength();
+
+ Sequence< OUString > aNames( nOrgCount );
+ Sequence< Any > aValues( nOrgCount );
+
+ OUString* pNames = aNames.getArray();
+ Any* pValues = aValues.getArray();
+ sal_Int32 nRealCount = 0;
+
+ for ( sal_Int32 nProp = 0; nProp < nOrgCount; nProp++ )
+ {
+ switch ( nProp )
+ {
+ case PROPERTYHANDLE_LOCALE :
+ {
+ if (!m_bROLocale)
+ {
+ pNames[nRealCount] = aOrgNames[nProp];
+ pValues[nRealCount] <<= m_aLocaleString;
+ ++nRealCount;
+ }
+ }
+ break;
+ case PROPERTYHANDLE_CURRENCY :
+ {
+ if (!m_bROLocale)
+ {
+ pNames[nRealCount] = aOrgNames[nProp];
+ pValues[nRealCount] <<= m_aCurrencyString;
+ ++nRealCount;
+ }
+ }
+ break;
+ case PROPERTYHANDLE_DECIMALSEPARATOR:
+ if( !m_bRODecimalSeparator )
+ {
+ pNames[nRealCount] = aOrgNames[nProp];
+ pValues[nRealCount] <<= m_bDecimalSeparator;
+ ++nRealCount;
+ }
+ break;
+ default:
+ DBG_ERRORFILE( "invalid index to save a path" );
+ }
+ }
+ aNames.realloc(nRealCount);
+ aValues.realloc(nRealCount);
+ PutProperties( aNames, aValues );
+ ClearModified();
+}
+
+
+ULONG SvtSysLocaleOptions_Impl::ChangeLocaleSettings()
+{
+ // An empty config value denotes SYSTEM locale
+ if ( m_aLocaleString.getLength() )
+ m_eLocaleLanguageType = MsLangId::convertIsoStringToLanguage( m_aLocaleString );
+ else
+ m_eLocaleLanguageType = LANGUAGE_SYSTEM;
+ ULONG nHint = 0;
+ // new locale and no fixed currency => locale default currency might change
+ if ( !m_aCurrencyString.getLength() )
+ nHint |= SYSLOCALEOPTIONS_HINT_CURRENCY;
+ return nHint;
+}
+
+
+void SvtSysLocaleOptions_Impl::ChangeDefaultCurrency() const
+{
+ const Link& rLink = SvtSysLocaleOptions::GetCurrencyChangeLink();
+ if ( rLink.IsSet() )
+ rLink.Call( NULL );
+}
+
+
+void SvtSysLocaleOptions_Impl::Notify( const Sequence< rtl::OUString >& seqPropertyNames )
+{
+ ULONG nHint = 0;
+ Sequence< Any > seqValues = GetProperties( seqPropertyNames );
+ Sequence< sal_Bool > seqROStates = GetReadOnlyStates( seqPropertyNames );
+ sal_Int32 nCount = seqPropertyNames.getLength();
+ for( sal_Int32 nProp = 0; nProp < nCount; ++nProp )
+ {
+ if( seqPropertyNames[nProp] == PROPERTYNAME_LOCALE )
+ {
+ DBG_ASSERT( seqValues[nProp].getValueTypeClass() == TypeClass_STRING, "Locale property type" );
+ seqValues[nProp] >>= m_aLocaleString;
+ m_bROLocale = seqROStates[nProp];
+ nHint |= SYSLOCALEOPTIONS_HINT_LOCALE;
+ nHint |= ChangeLocaleSettings();
+ }
+ else if( seqPropertyNames[nProp] == PROPERTYNAME_CURRENCY )
+ {
+ DBG_ASSERT( seqValues[nProp].getValueTypeClass() == TypeClass_STRING, "Currency property type" );
+ seqValues[nProp] >>= m_aCurrencyString;
+ m_bROCurrency = seqROStates[nProp];
+ nHint |= SYSLOCALEOPTIONS_HINT_CURRENCY;
+ }
+ else if( seqPropertyNames[nProp] == PROPERTYNAME_DECIMALSEPARATOR )
+ {
+ seqValues[nProp] >>= m_bDecimalSeparator;
+ m_bRODecimalSeparator = seqROStates[nProp];
+ UpdateMiscSettings_Impl();
+ }
+ }
+ if ( nHint )
+ Broadcast( nHint );
+}
+/* -----------------10.02.2004 15:25-----------------
+
+ --------------------------------------------------*/
+void SvtSysLocaleOptions_Impl::UpdateMiscSettings_Impl()
+{
+ AllSettings aAllSettings( Application::GetSettings() );
+ MiscSettings aMiscSettings = aAllSettings.GetMiscSettings();
+ aMiscSettings.SetEnableLocalizedDecimalSep(m_bDecimalSeparator);
+ aAllSettings.SetMiscSettings( aMiscSettings );
+ Application::SetSettings( aAllSettings );
+}
+
+// ====================================================================
+
+SvtSysLocaleOptions::SvtSysLocaleOptions()
+{
+ MutexGuard aGuard( GetMutex() );
+ if ( !pOptions )
+ {
+ RTL_LOGFILE_CONTEXT(aLog, "svtools ( ??? ) ::SvtSysLocaleOptions_Impl::ctor()");
+ pOptions = new SvtSysLocaleOptions_Impl;
+
+ ItemHolder2::holdConfigItem(E_SYSLOCALEOPTIONS);
+ }
+ ++nRefCount;
+}
+
+
+SvtSysLocaleOptions::~SvtSysLocaleOptions()
+{
+ MutexGuard aGuard( GetMutex() );
+ if ( !--nRefCount )
+ {
+ delete pOptions;
+ pOptions = NULL;
+ }
+}
+
+
+// static
+Mutex& SvtSysLocaleOptions::GetMutex()
+{
+ static Mutex* pMutex = NULL;
+ if( !pMutex )
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if( !pMutex )
+ {
+ // #i77768# Due to a static reference in the toolkit lib
+ // we need a mutex that lives longer than the svtools library.
+ // Otherwise the dtor would use a destructed mutex!!
+ pMutex = new Mutex;
+ }
+ }
+ return *pMutex;
+}
+
+BOOL SvtSysLocaleOptions::AddListener( SvtListener& rLst )
+{
+ MutexGuard aGuard( GetMutex() );
+ return rLst.StartListening( pOptions->GetBroadcaster() );
+}
+
+
+BOOL SvtSysLocaleOptions::RemoveListener( SvtListener& rLst )
+{
+ MutexGuard aGuard( GetMutex() );
+ return rLst.EndListening( pOptions->GetBroadcaster() );
+}
+
+
+const OUString& SvtSysLocaleOptions::GetCurrencyConfigString() const
+{
+ MutexGuard aGuard( GetMutex() );
+ return pOptions->GetCurrencyString();
+}
+
+/*-- 11.02.2004 13:31:41---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+
+// static
+void SvtSysLocaleOptions::GetCurrencyAbbrevAndLanguage( String& rAbbrev,
+ LanguageType& eLang, const ::rtl::OUString& rConfigString )
+{
+ sal_Int32 nDelim = rConfigString.indexOf( '-' );
+ if ( nDelim >= 0 )
+ {
+ rAbbrev = rConfigString.copy( 0, nDelim );
+ String aIsoStr( rConfigString.copy( nDelim+1 ) );
+ eLang = MsLangId::convertIsoStringToLanguage( aIsoStr );
+ }
+ else
+ {
+ rAbbrev = rConfigString;
+ eLang = (rAbbrev.Len() ? LANGUAGE_NONE : LANGUAGE_SYSTEM);
+ }
+}
+
+
+// static
+void SvtSysLocaleOptions::SetCurrencyChangeLink( const Link& rLink )
+{
+ MutexGuard aGuard( GetMutex() );
+ DBG_ASSERT( !CurrencyChangeLink::get().IsSet(), "SvtSysLocaleOptions::SetCurrencyChangeLink: already set" );
+ CurrencyChangeLink::get() = rLink;
+}
+
+
+// static
+const Link& SvtSysLocaleOptions::GetCurrencyChangeLink()
+{
+ MutexGuard aGuard( GetMutex() );
+ return CurrencyChangeLink::get();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */