Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "localebackend.hxx"
31 : : #include <com/sun/star/beans/Optional.hpp>
32 : : #include <osl/time.h>
33 : :
34 : : #include <stdio.h>
35 : :
36 : : #ifdef WNT
37 : :
38 : : #ifdef WINVER
39 : : #undef WINVER
40 : : #endif
41 : : #define WINVER 0x0501
42 : :
43 : : #if defined _MSC_VER
44 : : #pragma warning(push, 1)
45 : : #endif
46 : : #include <windows.h>
47 : : #if defined _MSC_VER
48 : : #pragma warning(pop)
49 : : #endif
50 : :
51 : : rtl::OUString ImplGetLocale(LCID lcid)
52 : : {
53 : : TCHAR buffer[8];
54 : : LPTSTR cp = buffer;
55 : :
56 : : cp += GetLocaleInfo( lcid, LOCALE_SISO639LANGNAME , buffer, 4 );
57 : : if( cp > buffer )
58 : : {
59 : : if( 0 < GetLocaleInfo( lcid, LOCALE_SISO3166CTRYNAME, cp, buffer + 8 - cp) )
60 : : // #i50822# minus character must be written before cp
61 : : *(cp - 1) = '-';
62 : :
63 : : return rtl::OUString::createFromAscii(buffer);
64 : : }
65 : :
66 : : return rtl::OUString();
67 : : }
68 : :
69 : : #elif defined(MACOSX)
70 : :
71 : : #include <rtl/ustrbuf.hxx>
72 : : #include <locale.h>
73 : : #include <string.h>
74 : :
75 : : #include <premac.h>
76 : : #include <CoreServices/CoreServices.h>
77 : : #include <CoreFoundation/CoreFoundation.h>
78 : : #include <postmac.h>
79 : :
80 : : namespace /* private */
81 : : {
82 : :
83 : : void OUStringBufferAppendCFString(rtl::OUStringBuffer& buffer, const CFStringRef s)
84 : : {
85 : : CFIndex lstr = CFStringGetLength(s);
86 : : for (CFIndex i = 0; i < lstr; i++)
87 : : buffer.append(CFStringGetCharacterAtIndex(s, i));
88 : : }
89 : :
90 : : template <typename T>
91 : : class CFGuard
92 : : {
93 : : public:
94 : : explicit CFGuard(T& rT) : rT_(rT) {}
95 : : ~CFGuard() { if (rT_) CFRelease(rT_); }
96 : : private:
97 : : T& rT_;
98 : : };
99 : :
100 : : typedef CFGuard<CFArrayRef> CFArrayGuard;
101 : : typedef CFGuard<CFStringRef> CFStringGuard;
102 : : typedef CFGuard<CFTypeRef> CFTypeRefGuard;
103 : :
104 : : /* For more information on the Apple locale concept please refer to
105 : : http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFLocales/Articles/CFLocaleConcepts.html
106 : : According to this documentation a locale identifier has the format: language[_country][_variant]*
107 : : e.g. es_ES_PREEURO -> spain prior Euro support
108 : : Note: The calling code should be able to handle locales with only language information e.g. 'en' for certain
109 : : UI languages just the language code will be returned.
110 : : */
111 : :
112 : : CFStringRef ImplGetAppPreference(const char* pref)
113 : : {
114 : : CFStringRef csPref = CFStringCreateWithCString(NULL, pref, kCFStringEncodingASCII);
115 : : CFStringGuard csRefGuard(csPref);
116 : :
117 : : CFTypeRef ref = CFPreferencesCopyAppValue(csPref, kCFPreferencesCurrentApplication);
118 : : CFTypeRefGuard refGuard(ref);
119 : :
120 : : if (ref == NULL)
121 : : return NULL;
122 : :
123 : : CFStringRef sref = (CFGetTypeID(ref) == CFArrayGetTypeID()) ? (CFStringRef)CFArrayGetValueAtIndex((CFArrayRef)ref, 0) : (CFStringRef)ref;
124 : :
125 : : // NOTE: this API is only available with Mac OS X >=10.3. We need to use it because
126 : : // Apple used non-ISO values on systems <10.2 like "German" for instance but didn't
127 : : // upgrade those values during upgrade to newer Mac OS X versions. See also #i54337#
128 : : return CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorDefault, sref);
129 : : }
130 : :
131 : : rtl::OUString ImplGetLocale(const char* pref)
132 : : {
133 : : CFStringRef sref = ImplGetAppPreference(pref);
134 : : CFStringGuard srefGuard(sref);
135 : :
136 : : rtl::OUStringBuffer aLocaleBuffer;
137 : : aLocaleBuffer.appendAscii("en-US"); // initialize with fallback value
138 : :
139 : : if (sref != NULL)
140 : : {
141 : : // split the string into substrings; the first two (if there are two) substrings
142 : : // are language and country
143 : : CFArrayRef subs = CFStringCreateArrayBySeparatingStrings(NULL, sref, CFSTR("_"));
144 : : CFArrayGuard subsGuard(subs);
145 : :
146 : : if (subs != NULL)
147 : : {
148 : : aLocaleBuffer.setLength(0); // clear buffer which still contains fallback value
149 : :
150 : : CFStringRef lang = (CFStringRef)CFArrayGetValueAtIndex(subs, 0);
151 : : OUStringBufferAppendCFString(aLocaleBuffer, lang);
152 : :
153 : : // country also available? Assumption: if the array contains more than one
154 : : // value the second value is always the country!
155 : : if (CFArrayGetCount(subs) > 1)
156 : : {
157 : : aLocaleBuffer.appendAscii("-");
158 : : CFStringRef country = (CFStringRef)CFArrayGetValueAtIndex(subs, 1);
159 : : OUStringBufferAppendCFString(aLocaleBuffer, country);
160 : : }
161 : : }
162 : : }
163 : : return aLocaleBuffer.makeStringAndClear();
164 : : }
165 : :
166 : : } // namespace /* private */
167 : :
168 : : #else
169 : :
170 : : #include <rtl/ustrbuf.hxx>
171 : : #include <locale.h>
172 : : #include <string.h>
173 : :
174 : : /*
175 : : * Note: setlocale is not at all thread safe, so is this code. It could
176 : : * especially interfere with the stuff VCL is doing, so make sure this
177 : : * is called from the main thread only.
178 : : */
179 : :
180 : 474 : static rtl::OUString ImplGetLocale(int category)
181 : : {
182 : 474 : const char *locale = setlocale(category, "");
183 : :
184 : : // Return "en-US" for C locales
185 [ - + ][ # # ]: 474 : if( (locale == NULL) || ( locale[0] == 'C' && locale[1] == '\0' ) )
[ + - ]
186 : 0 : return rtl::OUString( "en-US" );
187 : :
188 : :
189 : : const char *cp;
190 : 474 : const char *uscore = NULL;
191 : :
192 : : // locale string have the format lang[_ctry][.encoding][@modifier]
193 : : // we are only interested in the first two items, so we handle
194 : : // '.' and '@' as string end.
195 [ + - ]: 2844 : for (cp = locale; *cp; cp++)
196 : : {
197 [ + + ]: 2844 : if (*cp == '_')
198 : 474 : uscore = cp;
199 [ + + ][ - + ]: 2844 : if (*cp == '.' || *cp == '@')
200 : 474 : break;
201 : : }
202 : :
203 : 474 : rtl::OUStringBuffer aLocaleBuffer;
204 [ + - ]: 474 : if( uscore != NULL )
205 : : {
206 [ + - ]: 474 : aLocaleBuffer.appendAscii(locale, uscore++ - locale);
207 [ + - ]: 474 : aLocaleBuffer.appendAscii("-");
208 [ + - ]: 474 : aLocaleBuffer.appendAscii(uscore, cp - uscore);
209 : : }
210 : : else
211 : : {
212 [ # # ]: 0 : aLocaleBuffer.appendAscii(locale, cp - locale);
213 : : }
214 : :
215 [ + - ]: 474 : return aLocaleBuffer.makeStringAndClear();
216 : : }
217 : :
218 : : #endif
219 : :
220 : : // -------------------------------------------------------------------------------
221 : :
222 : 158 : LocaleBackend::LocaleBackend()
223 : : {
224 : 158 : }
225 : :
226 : : //------------------------------------------------------------------------------
227 : :
228 : 0 : LocaleBackend::~LocaleBackend(void)
229 : : {
230 [ # # ]: 0 : }
231 : :
232 : : //------------------------------------------------------------------------------
233 : :
234 : 158 : LocaleBackend* LocaleBackend::createInstance()
235 : : {
236 [ + - ]: 158 : return new LocaleBackend;
237 : : }
238 : :
239 : : // ---------------------------------------------------------------------------------------
240 : :
241 : 316 : rtl::OUString LocaleBackend::getLocale(void)
242 : : {
243 : : #if defined WNT
244 : : return ImplGetLocale( GetUserDefaultLCID() );
245 : : #elif defined (MACOSX)
246 : : return ImplGetLocale("AppleLocale");
247 : : #else
248 : 316 : return ImplGetLocale(LC_CTYPE);
249 : : #endif
250 : : }
251 : :
252 : : //------------------------------------------------------------------------------
253 : :
254 : 158 : rtl::OUString LocaleBackend::getUILocale(void)
255 : : {
256 : : #if defined WNT
257 : : return ImplGetLocale( MAKELCID(GetUserDefaultUILanguage(), SORT_DEFAULT) );
258 : : #elif defined(MACOSX)
259 : : return ImplGetLocale("AppleLanguages");
260 : : #else
261 : 158 : return ImplGetLocale(LC_MESSAGES);
262 : : #endif
263 : : }
264 : :
265 : : // ---------------------------------------------------------------------------------------
266 : :
267 : 158 : rtl::OUString LocaleBackend::getSystemLocale(void)
268 : : {
269 : : // note: the implementation differs from getLocale() only on Windows
270 : : #if defined WNT
271 : : return ImplGetLocale( GetSystemDefaultLCID() );
272 : : #else
273 : 158 : return getLocale();
274 : : #endif
275 : : }
276 : : //------------------------------------------------------------------------------
277 : :
278 : 0 : void LocaleBackend::setPropertyValue(
279 : : rtl::OUString const &, css::uno::Any const &)
280 : : throw (
281 : : css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
282 : : css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
283 : : css::uno::RuntimeException)
284 : : {
285 : : throw css::lang::IllegalArgumentException(
286 : : rtl::OUString(
287 : : "setPropertyValue not supported"),
288 [ # # ][ # # ]: 0 : static_cast< cppu::OWeakObject * >(this), -1);
289 : : }
290 : :
291 : 474 : css::uno::Any LocaleBackend::getPropertyValue(
292 : : rtl::OUString const & PropertyName)
293 : : throw (
294 : : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
295 : : css::uno::RuntimeException)
296 : : {
297 [ + + ]: 474 : if ( PropertyName == "Locale" ) {
298 : : return css::uno::makeAny(
299 : : css::beans::Optional< css::uno::Any >(
300 [ + - ][ + - ]: 158 : true, css::uno::makeAny(getLocale())));
301 [ + + ]: 316 : } else if (PropertyName.equalsAsciiL(
302 : 316 : RTL_CONSTASCII_STRINGPARAM("SystemLocale")))
303 : : {
304 : : return css::uno::makeAny(
305 : : css::beans::Optional< css::uno::Any >(
306 [ + - ][ + - ]: 158 : true, css::uno::makeAny(getSystemLocale())));
307 [ + - ]: 158 : } else if (PropertyName.equalsAsciiL(
308 : 158 : RTL_CONSTASCII_STRINGPARAM("UILocale")))
309 : : {
310 : : return css::uno::makeAny(
311 : : css::beans::Optional< css::uno::Any >(
312 [ + - ][ + - ]: 158 : true, css::uno::makeAny(getUILocale())));
313 : : } else {
314 : : throw css::beans::UnknownPropertyException(
315 [ # # ][ # # ]: 474 : PropertyName, static_cast< cppu::OWeakObject * >(this));
316 : : }
317 : : }
318 : :
319 : : //------------------------------------------------------------------------------
320 : :
321 : 158 : rtl::OUString SAL_CALL LocaleBackend::getBackendName(void) {
322 : 158 : return rtl::OUString("com.sun.star.comp.configuration.backend.LocaleBackend") ;
323 : : }
324 : :
325 : : //------------------------------------------------------------------------------
326 : :
327 : 0 : rtl::OUString SAL_CALL LocaleBackend::getImplementationName(void)
328 : : throw (uno::RuntimeException)
329 : : {
330 : 0 : return getBackendName() ;
331 : : }
332 : :
333 : : //------------------------------------------------------------------------------
334 : :
335 : 158 : uno::Sequence<rtl::OUString> SAL_CALL LocaleBackend::getBackendServiceNames(void)
336 : : {
337 : 158 : uno::Sequence<rtl::OUString> aServiceNameList(1);
338 [ + - ]: 158 : aServiceNameList[0] = rtl::OUString( "com.sun.star.configuration.backend.LocaleBackend") ;
339 : 158 : return aServiceNameList ;
340 : : }
341 : :
342 : : //------------------------------------------------------------------------------
343 : :
344 : 0 : sal_Bool SAL_CALL LocaleBackend::supportsService(const rtl::OUString& aServiceName)
345 : : throw (uno::RuntimeException)
346 : : {
347 [ # # ]: 0 : uno::Sequence< rtl::OUString > const svc = getBackendServiceNames();
348 : :
349 [ # # ]: 0 : for(sal_Int32 i = 0; i < svc.getLength(); ++i )
350 [ # # ]: 0 : if(svc[i] == aServiceName)
351 : 0 : return true;
352 : :
353 [ # # ]: 0 : return false;
354 : : }
355 : :
356 : : //------------------------------------------------------------------------------
357 : :
358 : 0 : uno::Sequence<rtl::OUString> SAL_CALL LocaleBackend::getSupportedServiceNames(void)
359 : : throw (uno::RuntimeException)
360 : : {
361 : 0 : return getBackendServiceNames() ;
362 : : }
363 : :
364 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|