1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_desktop.hxx"
26
27 #include "dp_misc.h"
28 #include "dp_resource.h"
29 #include "osl/module.hxx"
30 #include "osl/mutex.hxx"
31 #include "rtl/ustring.h"
32 #include "cppuhelper/implbase1.hxx"
33 #include "unotools/configmgr.hxx"
34
35
36 using namespace ::com::sun::star;
37 using namespace ::com::sun::star::uno;
38 using ::rtl::OUString;
39
40 namespace dp_misc {
41 namespace {
42
43 struct OfficeLocale :
44 public rtl::StaticWithInit<const OUString, OfficeLocale> {
operator ()dp_misc::__anonb5738ea70111::OfficeLocale45 const OUString operator () () {
46 OUString slang;
47 if (! (::utl::ConfigManager::GetDirectConfigProperty(
48 ::utl::ConfigManager::LOCALE ) >>= slang))
49 throw RuntimeException( OUSTR("Cannot determine language!"), 0 );
50 //fallback, the locale is currently only set when the user starts the
51 //office for the first time.
52 if (slang.getLength() == 0)
53 slang = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US"));
54 return slang;
55 }
56 };
57
58 struct DeploymentResMgr : public rtl::StaticWithInit<
59 ResMgr *, DeploymentResMgr> {
operator ()dp_misc::__anonb5738ea70111::DeploymentResMgr60 ResMgr * operator () () {
61 return ResMgr::CreateResMgr( "deployment", getOfficeLocale() );
62 }
63 };
64
65 osl::Mutex s_mutex;
66
67 } // anon namespace
68
69 //==============================================================================
getResId(sal_uInt16 id)70 ResId getResId( sal_uInt16 id )
71 {
72 const osl::MutexGuard guard( s_mutex );
73 return ResId( id, *DeploymentResMgr::get() );
74 }
75
76 //==============================================================================
getResourceString(sal_uInt16 id)77 String getResourceString( sal_uInt16 id )
78 {
79 const osl::MutexGuard guard( s_mutex );
80 String ret( ResId( id, *DeploymentResMgr::get() ) );
81 if (ret.SearchAscii( "%PRODUCTNAME" ) != STRING_NOTFOUND) {
82 static String s_brandName;
83 if (s_brandName.Len() == 0) {
84 OUString brandName(
85 ::utl::ConfigManager::GetDirectConfigProperty(
86 ::utl::ConfigManager::PRODUCTNAME ).get<OUString>() );
87 s_brandName = brandName;
88 }
89 ret.SearchAndReplaceAllAscii( "%PRODUCTNAME", s_brandName );
90 }
91 return ret;
92 }
93
94 //throws an Exception on failure
95 //primary subtag 2 or three letters(A-Z, a-z), i or x
checkPrimarySubtag(::rtl::OUString const & tag)96 void checkPrimarySubtag(::rtl::OUString const & tag)
97 {
98 sal_Int32 len = tag.getLength();
99 sal_Unicode const * arLang = tag.getStr();
100 if (len < 1 || len > 3)
101 throw Exception(OUSTR("Invalid language string."), 0);
102
103 if (len == 1
104 && (arLang[0] != 'i' && arLang[0] != 'x'))
105 throw Exception(OUSTR("Invalid language string."), 0);
106
107 if (len == 2 || len == 3)
108 {
109 for (sal_Int32 i = 0; i < len; i++)
110 {
111 if ( !((arLang[i] >= 'A' && arLang[i] <= 'Z')
112 || (arLang[i] >= 'a' && arLang[i] <= 'z')))
113 {
114 throw Exception(OUSTR("Invalid language string."), 0);
115 }
116 }
117 }
118 }
119
120 //throws an Exception on failure
121 //second subtag 2 letter country code or 3-8 letter other code(A-Z, a-z, 0-9)
checkSecondSubtag(::rtl::OUString const & tag,bool & bIsCountry)122 void checkSecondSubtag(::rtl::OUString const & tag, bool & bIsCountry)
123 {
124 sal_Int32 len = tag.getLength();
125 sal_Unicode const * arLang = tag.getStr();
126 if (len < 2 || len > 8)
127 throw Exception(OUSTR("Invalid language string."), 0);
128 //country code
129 bIsCountry = false;
130 if (len == 2)
131 {
132 for (sal_Int32 i = 0; i < 2; i++)
133 {
134 if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
135 || (arLang[i] >= 'a' && arLang[i] <= 'z')))
136 {
137 throw Exception(OUSTR("Invalid language string."), 0);
138 }
139 }
140 bIsCountry = true;
141 }
142
143 if (len > 2)
144 {
145 for (sal_Int32 i = 0; i < len; i++)
146 {
147 if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
148 || (arLang[i] >= 'a' && arLang[i] <= 'z')
149 || (arLang[i] >= '0' && arLang[i] <= '9') ))
150 {
151 throw Exception(OUSTR("Invalid language string."), 0);
152 }
153 }
154 }
155 }
156
checkThirdSubtag(::rtl::OUString const & tag)157 void checkThirdSubtag(::rtl::OUString const & tag)
158 {
159 sal_Int32 len = tag.getLength();
160 sal_Unicode const * arLang = tag.getStr();
161 if (len < 1 || len > 8)
162 throw Exception(OUSTR("Invalid language string."), 0);
163
164 for (sal_Int32 i = 0; i < len; i++)
165 {
166 if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
167 || (arLang[i] >= 'a' && arLang[i] <= 'z')
168 || (arLang[i] >= '0' && arLang[i] <= '9') ))
169 {
170 throw Exception(OUSTR("Invalid language string."), 0);
171 }
172 }
173 }
174
175 //=============================================================================
176
177 //We parse the string according to RFC 3066
178 //We only use the primary sub-tag and two subtags. That is lang-country-variant
179 //We do some simple tests if the string is correct. Actually this should do a
180 //validating parser
181 //We may have the case that there is no country tag, for example en-welsh
toLocale(::rtl::OUString const & slang)182 ::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang )
183 {
184 OUString _sLang = slang.trim();
185 ::com::sun::star::lang::Locale locale;
186 sal_Int32 nIndex = 0;
187 OUString lang = _sLang.getToken( 0, '-', nIndex );
188 checkPrimarySubtag(lang);
189 locale.Language = lang;
190 OUString country = _sLang.getToken( 0, '-', nIndex );
191 if (country.getLength() > 0)
192 {
193 bool bIsCountry = false;
194 checkSecondSubtag(country, bIsCountry);
195 if (bIsCountry)
196 {
197 locale.Country = country;
198 }
199 else
200 {
201 locale.Variant = country;
202 }
203 }
204 if (locale.Variant.getLength() == 0)
205 {
206 OUString variant = _sLang.getToken( 0, '-', nIndex );
207 if (variant.getLength() > 0)
208 {
209 checkThirdSubtag(variant);
210 locale.Variant = variant;
211 }
212 }
213
214 return locale;
215 }
216
217 //==============================================================================
getOfficeLocale()218 lang::Locale getOfficeLocale()
219 {
220 return toLocale(OfficeLocale::get());
221 }
222
getOfficeLocaleString()223 ::rtl::OUString getOfficeLocaleString()
224 {
225 return OfficeLocale::get();
226 }
227
228 }
229
230