27#include <com/sun/star/beans/Optional.hpp>
28#include <com/sun/star/uno/XComponentContext.hpp>
30#include <rtl/character.hxx>
36#if !defined WIN32_LEAN_AND_MEAN
37# define WIN32_LEAN_AND_MEAN
41static css::beans::Optional<css::uno::Any>
ImplGetLocale(LCID lcid)
46 cp += GetLocaleInfoW( lcid, LOCALE_SISO639LANGNAME, buffer, 4 );
49 if( 0 < GetLocaleInfoW( lcid, LOCALE_SISO3166CTRYNAME, cp, buffer + 8 - cp) )
53 return {
true, css::uno::Any(OUString(o3tl::toU(buffer)))};
61#include <rtl/ustrbuf.hxx>
66#include <CoreServices/CoreServices.h>
67#include <CoreFoundation/CoreFoundation.h>
73 void OUStringBufferAppendCFString(OUStringBuffer& buffer,
const CFStringRef s)
75 CFIndex lstr = CFStringGetLength(s);
76 for (CFIndex i = 0;
i < lstr;
i++)
77 buffer.append(
sal_Unicode(CFStringGetCharacterAtIndex(s, i)));
84 explicit CFGuard(T& rT) : rT_(rT) {}
85 ~CFGuard() {
if (rT_) CFRelease(rT_); }
90 typedef CFGuard<CFArrayRef> CFArrayGuard;
91 typedef CFGuard<CFStringRef> CFStringGuard;
92 typedef CFGuard<CFTypeRef> CFTypeRefGuard;
102 CFStringRef ImplGetAppPreference(
const char* pref)
104 CFStringRef csPref = CFStringCreateWithCString(
nullptr, pref, kCFStringEncodingASCII);
105 CFStringGuard csRefGuard(csPref);
107 CFTypeRef ref = CFPreferencesCopyAppValue(csPref, kCFPreferencesCurrentApplication);
108 CFTypeRefGuard refGuard(ref);
113 CFStringRef sref = (CFGetTypeID(ref) == CFArrayGetTypeID()) ?
static_cast<CFStringRef
>(CFArrayGetValueAtIndex(
static_cast<CFArrayRef
>(ref), 0)) :
static_cast<CFStringRef
>(ref);
118 return CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorDefault, sref);
121 css::beans::Optional<css::uno::Any>
ImplGetLocale(
const char* pref)
123 CFStringRef sref = ImplGetAppPreference(pref);
124 CFStringGuard srefGuard(sref);
126 OUStringBuffer aLocaleBuffer(
"en-US");
132 CFArrayRef subs = CFStringCreateArrayBySeparatingStrings(
nullptr, sref, CFSTR(
"_"));
133 CFArrayGuard subsGuard(subs);
137 aLocaleBuffer.setLength(0);
139 CFStringRef lang =
static_cast<CFStringRef
>(CFArrayGetValueAtIndex(subs, 0));
140 OUStringBufferAppendCFString(aLocaleBuffer, lang);
144 if (CFArrayGetCount(subs) > 1)
146 aLocaleBuffer.append(
"-");
147 CFStringRef country =
static_cast<CFStringRef
>(CFArrayGetValueAtIndex(subs, 1));
148 OUStringBufferAppendCFString(aLocaleBuffer, country);
152 return {
true, css::uno::Any(aLocaleBuffer.makeStringAndClear())};
159#include <rtl/ustrbuf.hxx>
163static css::beans::Optional<css::uno::Any>
ImplGetLocale(
char const * category)
165 const char *locale = std::getenv(
"LC_ALL");
166 if (locale ==
nullptr || *locale ==
'\0') {
167 locale = std::getenv(category);
168 if (locale ==
nullptr || *locale ==
'\0') {
169 locale = std::getenv(
"LANG");
174 if( (locale ==
nullptr) || *locale ==
'\0' || std::strcmp(locale,
"C") == 0
175 || std::strcmp(locale,
"POSIX") == 0 )
176 return {
true, css::uno::Any(OUString(
"en-US"))};
180 const char *uscore =
nullptr;
181 const char *
end =
nullptr;
188 for (cp = locale; *cp; cp++)
190 if (*cp ==
'_' && !uscore)
192 if ((*cp ==
'.' || *cp ==
'@') && !
end)
194 if (!rtl::isAscii(
static_cast<unsigned char>(*cp))) {
195 SAL_INFO(
"shell",
"locale env var with non-ASCII content");
199 assert(cp >= locale);
200 if (cp - locale > std::numeric_limits<sal_Int32>::max()) {
201 SAL_INFO(
"shell",
"locale env var content too long");
208 const OString aLocaleStr(locale);
213 return {
true, css::uno::Any(aLangTagStr)};
218 OUStringBuffer aLocaleBuffer;
221 if( uscore !=
nullptr )
223 aLocaleBuffer.appendAscii(locale, uscore++ - locale);
224 aLocaleBuffer.append(
"-");
225 aLocaleBuffer.appendAscii(uscore,
end - uscore);
229 aLocaleBuffer.appendAscii(locale,
end - locale);
232 return {
true, css::uno::Any(aLocaleBuffer.makeStringAndClear())};
253#elif defined (MACOSX)
264 return ImplGetLocale( MAKELCID(GetUserDefaultUILanguage(), SORT_DEFAULT) );
285 OUString
const &, css::uno::Any
const &)
287 throw css::lang::IllegalArgumentException(
288 "setPropertyValue not supported",
293 OUString
const & PropertyName)
295 if ( PropertyName ==
"Locale" ) {
297 }
else if (PropertyName ==
"SystemLocale")
300 }
else if (PropertyName ==
"UILocale")
304 throw css::beans::UnknownPropertyException(
305 PropertyName, getXWeak());
312 return "com.sun.star.comp.configuration.backend.LocaleBackend" ;
322 return {
"com.sun.star.configuration.backend.LocaleBackend" };
325extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
327 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any>
const&)
static OUString convertToBcp47(LanguageType nLangID)
virtual void SAL_CALL setPropertyValue(OUString const &, css::uno::Any const &) override
virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
static css::beans::Optional< css::uno::Any > getLocale()
virtual OUString SAL_CALL getImplementationName() override
virtual sal_Bool SAL_CALL supportsService(const OUString &aServiceName) override
virtual css::uno::Any SAL_CALL getPropertyValue(OUString const &PropertyName) override
static css::beans::Optional< css::uno::Any > getSystemLocale()
static css::beans::Optional< css::uno::Any > getUILocale()
virtual ~LocaleBackend() override
Destructor.
LocaleBackend()
Service constructor from a service factory.
static LanguageType convertUnxByteStringToLanguage(std::string_view rString)
#define LANGUAGE_DONTKNOW
static css::beans::Optional< css::uno::Any > ImplGetLocale(char const *category)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * shell_LocaleBackend_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
#define SAL_INFO(area, stream)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)