Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <sal/config.h>
21 :
22 : #include <sal/log.hxx>
23 : #include <unotools/syslocale.hxx>
24 : #include <unotools/syslocaleoptions.hxx>
25 : #include <comphelper/processfactory.hxx>
26 : #include <rtl/tencinfo.h>
27 : #include <rtl/locale.h>
28 : #include <osl/thread.h>
29 : #include <osl/nlsupport.h>
30 : #include <vector>
31 :
32 : using namespace osl;
33 : using namespace com::sun::star;
34 :
35 : SvtSysLocale_Impl* SvtSysLocale::pImpl = NULL;
36 : sal_Int32 SvtSysLocale::nRefCount = 0;
37 :
38 : class SvtSysLocale_Impl : public utl::ConfigurationListener
39 : {
40 : public:
41 : SvtSysLocaleOptions aSysLocaleOptions;
42 : LocaleDataWrapper* pLocaleData;
43 : CharClass* pCharClass;
44 :
45 : SvtSysLocale_Impl();
46 : virtual ~SvtSysLocale_Impl();
47 :
48 : CharClass* GetCharClass();
49 : virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 ) SAL_OVERRIDE;
50 :
51 : private:
52 : void setDateAcceptancePatternsConfig();
53 : };
54 :
55 233 : SvtSysLocale_Impl::SvtSysLocale_Impl() : pCharClass(NULL)
56 : {
57 233 : pLocaleData = new LocaleDataWrapper( aSysLocaleOptions.GetRealLanguageTag() );
58 233 : setDateAcceptancePatternsConfig();
59 :
60 : // listen for further changes
61 233 : aSysLocaleOptions.AddListener( this );
62 233 : }
63 :
64 318 : SvtSysLocale_Impl::~SvtSysLocale_Impl()
65 : {
66 106 : aSysLocaleOptions.RemoveListener( this );
67 106 : delete pCharClass;
68 106 : delete pLocaleData;
69 212 : }
70 :
71 129 : CharClass* SvtSysLocale_Impl::GetCharClass()
72 : {
73 129 : if ( !pCharClass )
74 56 : pCharClass = new CharClass( aSysLocaleOptions.GetRealLanguageTag() );
75 129 : return pCharClass;
76 : }
77 :
78 1 : void SvtSysLocale_Impl::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 nHint )
79 : {
80 1 : MutexGuard aGuard( SvtSysLocale::GetMutex() );
81 :
82 1 : if ( nHint & SYSLOCALEOPTIONS_HINT_LOCALE )
83 : {
84 1 : const LanguageTag& rLanguageTag = aSysLocaleOptions.GetRealLanguageTag();
85 1 : pLocaleData->setLanguageTag( rLanguageTag );
86 1 : GetCharClass()->setLanguageTag( rLanguageTag );
87 : }
88 1 : if ( nHint & SYSLOCALEOPTIONS_HINT_DATEPATTERNS )
89 : {
90 0 : setDateAcceptancePatternsConfig();
91 1 : }
92 1 : }
93 :
94 233 : void SvtSysLocale_Impl::setDateAcceptancePatternsConfig()
95 : {
96 233 : OUString aStr( aSysLocaleOptions.GetDatePatternsConfigString());
97 233 : if (aStr.isEmpty())
98 233 : pLocaleData->setDateAcceptancePatterns( uno::Sequence<OUString>()); // reset
99 : else
100 : {
101 0 : ::std::vector< OUString > aVec;
102 0 : for (sal_Int32 nIndex = 0; nIndex >= 0; /*nop*/)
103 : {
104 0 : OUString aTok( aStr.getToken( 0, ';', nIndex));
105 0 : if (!aTok.isEmpty())
106 0 : aVec.push_back( aTok);
107 0 : }
108 0 : uno::Sequence< OUString > aSeq( aVec.size());
109 0 : for (sal_Int32 i=0; i < aSeq.getLength(); ++i)
110 0 : aSeq[i] = aVec[i];
111 0 : pLocaleData->setDateAcceptancePatterns( aSeq);
112 233 : }
113 233 : }
114 :
115 183615 : SvtSysLocale::SvtSysLocale()
116 : {
117 183615 : MutexGuard aGuard( GetMutex() );
118 183615 : if ( !pImpl )
119 233 : pImpl = new SvtSysLocale_Impl;
120 183615 : ++nRefCount;
121 183615 : }
122 :
123 178144 : SvtSysLocale::~SvtSysLocale()
124 : {
125 178144 : MutexGuard aGuard( GetMutex() );
126 178144 : if ( !--nRefCount )
127 : {
128 106 : delete pImpl;
129 106 : pImpl = NULL;
130 178144 : }
131 178144 : }
132 :
133 : // static
134 361760 : Mutex& SvtSysLocale::GetMutex()
135 : {
136 : static Mutex* pMutex = NULL;
137 361760 : if( !pMutex )
138 : {
139 227 : MutexGuard aGuard( Mutex::getGlobalMutex() );
140 227 : if( !pMutex )
141 : {
142 : // #i77768# Due to a static reference in the toolkit lib
143 : // we need a mutex that lives longer than the svl library.
144 : // Otherwise the dtor would use a destructed mutex!!
145 227 : pMutex = new Mutex;
146 227 : }
147 : }
148 361760 : return *pMutex;
149 : }
150 :
151 79159 : const LocaleDataWrapper& SvtSysLocale::GetLocaleData() const
152 : {
153 79159 : return *(pImpl->pLocaleData);
154 : }
155 :
156 46871 : const LocaleDataWrapper* SvtSysLocale::GetLocaleDataPtr() const
157 : {
158 46871 : return pImpl->pLocaleData;
159 : }
160 :
161 24 : const CharClass& SvtSysLocale::GetCharClass() const
162 : {
163 24 : return *(pImpl->GetCharClass());
164 : }
165 :
166 104 : const CharClass* SvtSysLocale::GetCharClassPtr() const
167 : {
168 104 : return pImpl->GetCharClass();
169 : }
170 :
171 872 : SvtSysLocaleOptions& SvtSysLocale::GetOptions() const
172 : {
173 872 : return pImpl->aSysLocaleOptions;
174 : }
175 :
176 22060 : const LanguageTag& SvtSysLocale::GetLanguageTag() const
177 : {
178 22060 : return pImpl->aSysLocaleOptions.GetRealLanguageTag();
179 : }
180 :
181 3619 : const LanguageTag& SvtSysLocale::GetUILanguageTag() const
182 : {
183 3619 : return pImpl->aSysLocaleOptions.GetRealUILanguageTag();
184 : }
185 :
186 : // static
187 18 : rtl_TextEncoding SvtSysLocale::GetBestMimeEncoding()
188 : {
189 : const sal_Char* pCharSet = rtl_getBestMimeCharsetFromTextEncoding(
190 18 : osl_getThreadTextEncoding() );
191 18 : if ( !pCharSet )
192 : {
193 : // If the system locale is unknown to us, e.g. LC_ALL=xx, match the UI
194 : // language if possible.
195 0 : SvtSysLocale aSysLocale;
196 0 : const LanguageTag& rLanguageTag = aSysLocale.GetUILanguageTag();
197 : // Converting blindly to Locale and then to rtl_Locale may feed the
198 : // 'qlt' to rtl_locale_register() and the underlying system locale
199 : // stuff, which doesn't know about it nor about BCP47 in the Variant
200 : // field. So use the real language and for non-pure ISO cases hope for
201 : // the best.. the fallback to UTF-8 should solve these cases nowadays.
202 : /* FIXME-BCP47: the script needs to go in here as well, so actually
203 : * we'd need some variant fiddling or glibc locale string and tweak
204 : * rtl_locale_register() to know about it! But then again the Windows
205 : * implementation still wouldn't know anything about it ... */
206 : SAL_WARN_IF( !rLanguageTag.isIsoLocale(), "unotools.i18n",
207 : "SvtSysLocale::GetBestMimeEncoding - non-ISO UI locale");
208 : rtl_Locale * pLocale = rtl_locale_register( rLanguageTag.getLanguage().getStr(),
209 0 : rLanguageTag.getCountry().getStr(), OUString().getStr() );
210 0 : rtl_TextEncoding nEnc = osl_getTextEncodingFromLocale( pLocale );
211 0 : pCharSet = rtl_getBestMimeCharsetFromTextEncoding( nEnc );
212 : }
213 : rtl_TextEncoding nRet;
214 18 : if ( pCharSet )
215 18 : nRet = rtl_getTextEncodingFromMimeCharset( pCharSet );
216 : else
217 0 : nRet = RTL_TEXTENCODING_UTF8;
218 18 : return nRet;
219 : }
220 :
221 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|