1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <unotools/syslocale.hxx>
21 #include <unotools/syslocaleoptions.hxx>
22 #include <comphelper/processfactory.hxx>
23 #include <rtl/tencinfo.h>
24 #include <rtl/locale.h>
25 #include <osl/thread.h>
26 #include <osl/nlsupport.h>
30 using namespace com::sun::star
;
32 SvtSysLocale_Impl
* SvtSysLocale::pImpl
= NULL
;
33 sal_Int32
SvtSysLocale::nRefCount
= 0;
35 class SvtSysLocale_Impl
: public utl::ConfigurationListener
38 SvtSysLocaleOptions aSysLocaleOptions
;
39 LocaleDataWrapper
* pLocaleData
;
40 CharClass
* pCharClass
;
43 virtual ~SvtSysLocale_Impl();
45 CharClass
* GetCharClass();
46 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster
*, sal_uInt32
) SAL_OVERRIDE
;
49 void setDateAcceptancePatternsConfig();
52 SvtSysLocale_Impl::SvtSysLocale_Impl() : pCharClass(NULL
)
54 pLocaleData
= new LocaleDataWrapper( aSysLocaleOptions
.GetRealLanguageTag() );
55 setDateAcceptancePatternsConfig();
57 // listen for further changes
58 aSysLocaleOptions
.AddListener( this );
61 SvtSysLocale_Impl::~SvtSysLocale_Impl()
63 aSysLocaleOptions
.RemoveListener( this );
68 CharClass
* SvtSysLocale_Impl::GetCharClass()
71 pCharClass
= new CharClass( aSysLocaleOptions
.GetRealLanguageTag() );
75 void SvtSysLocale_Impl::ConfigurationChanged( utl::ConfigurationBroadcaster
*, sal_uInt32 nHint
)
77 MutexGuard
aGuard( SvtSysLocale::GetMutex() );
79 if ( nHint
& SYSLOCALEOPTIONS_HINT_LOCALE
)
81 const LanguageTag
& rLanguageTag
= aSysLocaleOptions
.GetRealLanguageTag();
82 pLocaleData
->setLanguageTag( rLanguageTag
);
83 GetCharClass()->setLanguageTag( rLanguageTag
);
85 if ( nHint
& SYSLOCALEOPTIONS_HINT_DATEPATTERNS
)
87 setDateAcceptancePatternsConfig();
91 void SvtSysLocale_Impl::setDateAcceptancePatternsConfig()
93 OUString
aStr( aSysLocaleOptions
.GetDatePatternsConfigString());
95 pLocaleData
->setDateAcceptancePatterns( uno::Sequence
<OUString
>()); // reset
98 ::std::vector
< OUString
> aVec
;
99 for (sal_Int32 nIndex
= 0; nIndex
>= 0; /*nop*/)
101 OUString
aTok( aStr
.getToken( 0, ';', nIndex
));
103 aVec
.push_back( aTok
);
105 uno::Sequence
< OUString
> aSeq( aVec
.size());
106 for (sal_Int32 i
=0; i
< aSeq
.getLength(); ++i
)
108 pLocaleData
->setDateAcceptancePatterns( aSeq
);
112 SvtSysLocale::SvtSysLocale()
114 MutexGuard
aGuard( GetMutex() );
116 pImpl
= new SvtSysLocale_Impl
;
120 SvtSysLocale::~SvtSysLocale()
122 MutexGuard
aGuard( GetMutex() );
131 Mutex
& SvtSysLocale::GetMutex()
133 static Mutex
* pMutex
= NULL
;
136 MutexGuard
aGuard( Mutex::getGlobalMutex() );
139 // #i77768# Due to a static reference in the toolkit lib
140 // we need a mutex that lives longer than the svl library.
141 // Otherwise the dtor would use a destructed mutex!!
148 const LocaleDataWrapper
& SvtSysLocale::GetLocaleData() const
150 return *(pImpl
->pLocaleData
);
153 const LocaleDataWrapper
* SvtSysLocale::GetLocaleDataPtr() const
155 return pImpl
->pLocaleData
;
158 const CharClass
& SvtSysLocale::GetCharClass() const
160 return *(pImpl
->GetCharClass());
163 const CharClass
* SvtSysLocale::GetCharClassPtr() const
165 return pImpl
->GetCharClass();
168 SvtSysLocaleOptions
& SvtSysLocale::GetOptions() const
170 return pImpl
->aSysLocaleOptions
;
173 const LanguageTag
& SvtSysLocale::GetLanguageTag() const
175 return pImpl
->aSysLocaleOptions
.GetRealLanguageTag();
178 const LanguageTag
& SvtSysLocale::GetUILanguageTag() const
180 return pImpl
->aSysLocaleOptions
.GetRealUILanguageTag();
184 rtl_TextEncoding
SvtSysLocale::GetBestMimeEncoding()
186 const sal_Char
* pCharSet
= rtl_getBestMimeCharsetFromTextEncoding(
187 osl_getThreadTextEncoding() );
190 // If the system locale is unknown to us, e.g. LC_ALL=xx, match the UI
191 // language if possible.
192 SvtSysLocale aSysLocale
;
193 const LanguageTag
& rLanguageTag
= aSysLocale
.GetUILanguageTag();
194 // Converting blindly to Locale and then to rtl_Locale may feed the
195 // 'qlt' to rtl_locale_register() and the underlying system locale
196 // stuff, which doesn't know about it nor about BCP47 in the Variant
197 // field. So use the real language and for non-pure ISO cases hope for
198 // the best.. the fallback to UTF-8 should solve these cases nowadays.
199 /* FIXME-BCP47: the script needs to go in here as well, so actually
200 * we'd need some variant fiddling or glibc locale string and tweak
201 * rtl_locale_register() to know about it! But then again the Windows
202 * implementation still wouldn't know anything about it ... */
203 SAL_WARN_IF( !rLanguageTag
.isIsoLocale(), "unotools.i18n",
204 "SvtSysLocale::GetBestMimeEncoding - non-ISO UI locale");
205 rtl_Locale
* pLocale
= rtl_locale_register( rLanguageTag
.getLanguage().getStr(),
206 rLanguageTag
.getCountry().getStr(), OUString().getStr() );
207 rtl_TextEncoding nEnc
= osl_getTextEncodingFromLocale( pLocale
);
208 pCharSet
= rtl_getBestMimeCharsetFromTextEncoding( nEnc
);
210 rtl_TextEncoding nRet
;
212 nRet
= rtl_getTextEncodingFromMimeCharset( pCharSet
);
214 nRet
= RTL_TEXTENCODING_UTF8
;
218 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */