bump product version to 5.0.4.1
[LibreOffice.git] / shell / source / backends / localebe / localebackend.cxx
blob4b5c34a50be14cf4584276749b58a034b34aeca2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 #include "localebackend.hxx"
22 #include <com/sun/star/beans/Optional.hpp>
23 #include <cppuhelper/supportsservice.hxx>
24 #include <osl/time.h>
26 #include <stdio.h>
28 #ifdef WNT
29 #if defined _MSC_VER
30 #pragma warning(push, 1)
31 #endif
32 #include <windows.h>
33 #if defined _MSC_VER
34 #pragma warning(pop)
35 #endif
37 OUString ImplGetLocale(LCID lcid)
39 TCHAR buffer[8];
40 LPTSTR cp = buffer;
42 cp += GetLocaleInfo( lcid, LOCALE_SISO639LANGNAME , buffer, 4 );
43 if( cp > buffer )
45 if( 0 < GetLocaleInfo( lcid, LOCALE_SISO3166CTRYNAME, cp, buffer + 8 - cp) )
46 // #i50822# minus character must be written before cp
47 *(cp - 1) = '-';
49 return OUString::createFromAscii(buffer);
52 return OUString();
55 #elif defined(MACOSX)
57 #include <rtl/ustrbuf.hxx>
58 #include <locale.h>
59 #include <string.h>
61 #include <premac.h>
62 #include <CoreServices/CoreServices.h>
63 #include <CoreFoundation/CoreFoundation.h>
64 #include <postmac.h>
66 namespace /* private */
69 void OUStringBufferAppendCFString(OUStringBuffer& buffer, const CFStringRef s)
71 CFIndex lstr = CFStringGetLength(s);
72 for (CFIndex i = 0; i < lstr; i++)
73 buffer.append(CFStringGetCharacterAtIndex(s, i));
76 template <typename T>
77 class CFGuard
79 public:
80 explicit CFGuard(T& rT) : rT_(rT) {}
81 ~CFGuard() { if (rT_) CFRelease(rT_); }
82 private:
83 T& rT_;
86 typedef CFGuard<CFArrayRef> CFArrayGuard;
87 typedef CFGuard<CFStringRef> CFStringGuard;
88 typedef CFGuard<CFTypeRef> CFTypeRefGuard;
90 /* For more information on the Apple locale concept please refer to
91 http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFLocales/Articles/CFLocaleConcepts.html
92 According to this documentation a locale identifier has the format: language[_country][_variant]*
93 e.g. es_ES_PREEURO -> spain prior Euro support
94 Note: The calling code should be able to handle locales with only language information e.g. 'en' for certain
95 UI languages just the language code will be returned.
98 CFStringRef ImplGetAppPreference(const char* pref)
100 CFStringRef csPref = CFStringCreateWithCString(NULL, pref, kCFStringEncodingASCII);
101 CFStringGuard csRefGuard(csPref);
103 CFTypeRef ref = CFPreferencesCopyAppValue(csPref, kCFPreferencesCurrentApplication);
104 CFTypeRefGuard refGuard(ref);
106 if (ref == NULL)
107 return NULL;
109 CFStringRef sref = (CFGetTypeID(ref) == CFArrayGetTypeID()) ? static_cast<CFStringRef>(CFArrayGetValueAtIndex(static_cast<CFArrayRef>(ref), 0)) : static_cast<CFStringRef>(ref);
111 // NOTE: this API is only available with Mac OS X >=10.3. We need to use it because
112 // Apple used non-ISO values on systems <10.2 like "German" for instance but didn't
113 // upgrade those values during upgrade to newer Mac OS X versions. See also #i54337#
114 return CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorDefault, sref);
117 OUString ImplGetLocale(const char* pref)
119 CFStringRef sref = ImplGetAppPreference(pref);
120 CFStringGuard srefGuard(sref);
122 OUStringBuffer aLocaleBuffer;
123 aLocaleBuffer.appendAscii("en-US"); // initialize with fallback value
125 if (sref != NULL)
127 // split the string into substrings; the first two (if there are two) substrings
128 // are language and country
129 CFArrayRef subs = CFStringCreateArrayBySeparatingStrings(NULL, sref, CFSTR("_"));
130 CFArrayGuard subsGuard(subs);
132 if (subs != NULL)
134 aLocaleBuffer.setLength(0); // clear buffer which still contains fallback value
136 CFStringRef lang = static_cast<CFStringRef>(CFArrayGetValueAtIndex(subs, 0));
137 OUStringBufferAppendCFString(aLocaleBuffer, lang);
139 // country also available? Assumption: if the array contains more than one
140 // value the second value is always the country!
141 if (CFArrayGetCount(subs) > 1)
143 aLocaleBuffer.appendAscii("-");
144 CFStringRef country = static_cast<CFStringRef>(CFArrayGetValueAtIndex(subs, 1));
145 OUStringBufferAppendCFString(aLocaleBuffer, country);
149 return aLocaleBuffer.makeStringAndClear();
152 } // namespace /* private */
154 #else
156 #include <rtl/ustrbuf.hxx>
157 #include <locale.h>
158 #include <string.h>
161 * Note: setlocale is not at all thread safe, so is this code. It could
162 * especially interfere with the stuff VCL is doing, so make sure this
163 * is called from the main thread only.
166 static OUString ImplGetLocale(int category)
168 const char *locale = setlocale(category, "");
170 // Return "en-US" for C locales
171 if( (locale == NULL) || ( locale[0] == 'C' && locale[1] == '\0' ) )
172 return OUString( "en-US" );
175 const char *cp;
176 const char *uscore = NULL;
178 // locale string have the format lang[_ctry][.encoding][@modifier]
179 // we are only interested in the first two items, so we handle
180 // '.' and '@' as string end.
181 for (cp = locale; *cp; cp++)
183 if (*cp == '_')
184 uscore = cp;
185 if (*cp == '.' || *cp == '@')
186 break;
189 OUStringBuffer aLocaleBuffer;
190 if( uscore != NULL )
192 aLocaleBuffer.appendAscii(locale, uscore++ - locale);
193 aLocaleBuffer.appendAscii("-");
194 aLocaleBuffer.appendAscii(uscore, cp - uscore);
196 else
198 aLocaleBuffer.appendAscii(locale, cp - locale);
201 return aLocaleBuffer.makeStringAndClear();
204 #endif
208 LocaleBackend::LocaleBackend()
214 LocaleBackend::~LocaleBackend()
220 LocaleBackend* LocaleBackend::createInstance()
222 return new LocaleBackend;
227 OUString LocaleBackend::getLocale()
229 #if defined WNT
230 return ImplGetLocale( GetUserDefaultLCID() );
231 #elif defined (MACOSX)
232 return ImplGetLocale("AppleLocale");
233 #else
234 return ImplGetLocale(LC_CTYPE);
235 #endif
240 OUString LocaleBackend::getUILocale()
242 #if defined WNT
243 return ImplGetLocale( MAKELCID(GetUserDefaultUILanguage(), SORT_DEFAULT) );
244 #elif defined(MACOSX)
245 return ImplGetLocale("AppleLanguages");
246 #else
247 return ImplGetLocale(LC_MESSAGES);
248 #endif
253 OUString LocaleBackend::getSystemLocale()
255 // note: the implementation differs from getLocale() only on Windows
256 #if defined WNT
257 return ImplGetLocale( GetSystemDefaultLCID() );
258 #else
259 return getLocale();
260 #endif
264 void LocaleBackend::setPropertyValue(
265 OUString const &, css::uno::Any const &)
266 throw (
267 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
268 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
269 css::uno::RuntimeException, std::exception)
271 throw css::lang::IllegalArgumentException(
272 OUString(
273 "setPropertyValue not supported"),
274 static_cast< cppu::OWeakObject * >(this), -1);
277 css::uno::Any LocaleBackend::getPropertyValue(
278 OUString const & PropertyName)
279 throw (
280 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
281 css::uno::RuntimeException, std::exception)
283 if ( PropertyName == "Locale" ) {
284 return css::uno::makeAny(
285 css::beans::Optional< css::uno::Any >(
286 true, css::uno::makeAny(getLocale())));
287 } else if (PropertyName == "SystemLocale")
289 return css::uno::makeAny(
290 css::beans::Optional< css::uno::Any >(
291 true, css::uno::makeAny(getSystemLocale())));
292 } else if (PropertyName == "UILocale")
294 return css::uno::makeAny(
295 css::beans::Optional< css::uno::Any >(
296 true, css::uno::makeAny(getUILocale())));
297 } else {
298 throw css::beans::UnknownPropertyException(
299 PropertyName, static_cast< cppu::OWeakObject * >(this));
305 OUString SAL_CALL LocaleBackend::getBackendName() {
306 return OUString("com.sun.star.comp.configuration.backend.LocaleBackend") ;
309 OUString SAL_CALL LocaleBackend::getImplementationName()
310 throw (uno::RuntimeException, std::exception)
312 return getBackendName() ;
315 uno::Sequence<OUString> SAL_CALL LocaleBackend::getBackendServiceNames()
317 uno::Sequence<OUString> aServiceNameList(1);
318 aServiceNameList[0] = "com.sun.star.configuration.backend.LocaleBackend";
319 return aServiceNameList ;
322 sal_Bool SAL_CALL LocaleBackend::supportsService(const OUString& aServiceName)
323 throw (uno::RuntimeException, std::exception)
325 return cppu::supportsService(this, aServiceName);
328 uno::Sequence<OUString> SAL_CALL LocaleBackend::getSupportedServiceNames()
329 throw (uno::RuntimeException, std::exception)
331 return getBackendServiceNames() ;
334 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */