Branch data 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 <comphelper/locale.hxx>
21 : :
22 : : #include <rtl/ustrbuf.hxx>
23 : :
24 : :
25 : : namespace comphelper{
26 : :
27 : : //-----------------------------------------------
28 : : const sal_Unicode Locale::SEPERATOR_LC = (sal_Unicode)'-';
29 : : const sal_Unicode Locale::SEPERATOR_CV = (sal_Unicode)'_';
30 : : const sal_Unicode Locale::SEPERATOR_CV_LINUX = (sal_Unicode)'.';
31 : :
32 : : //-----------------------------------------------
33 : 35015 : const Locale Locale::X_DEFAULT()
34 : : {
35 [ + - ]: 35015 : return Locale(::rtl::OUString("x"), ::rtl::OUString("default"));
36 : : }
37 : :
38 : : //-----------------------------------------------
39 : 70030 : const Locale Locale::EN_US()
40 : : {
41 [ + - ]: 70030 : return Locale(::rtl::OUString("en"), ::rtl::OUString("US"));
42 : : }
43 : :
44 : : //-----------------------------------------------
45 : 21587 : const Locale Locale::X_NOTRANSLATE()
46 : : {
47 [ + - ]: 21587 : return Locale(::rtl::OUString("x"), ::rtl::OUString("notranslate"));
48 : : }
49 : :
50 : : //-----------------------------------------------
51 : 103333 : Locale::Locale(const ::rtl::OUString& sISO)
52 : 103333 : throw(Locale::MalFormedLocaleException)
53 : : {
54 [ + - ]: 103333 : fromISO(sISO);
55 : 103333 : }
56 : :
57 : : //-----------------------------------------------
58 : 126952 : Locale::Locale(const ::rtl::OUString& sLanguage,
59 : : const ::rtl::OUString& sCountry ,
60 : 126952 : const ::rtl::OUString& sVariant )
61 : : {
62 : : // Use set methods to check values too!
63 [ + - ]: 126952 : setLanguage(sLanguage);
64 [ + - ]: 126952 : setCountry (sCountry );
65 [ + - ]: 126952 : setVariant (sVariant );
66 : 126952 : }
67 : :
68 : : //-----------------------------------------------
69 : 0 : Locale::Locale()
70 : : {
71 : : // Initialize instance ... otherwhise user will
72 : : // may be get exceptions if he e.g. copy this instance ...
73 [ # # ][ # # ]: 0 : (*this) = X_NOTRANSLATE();
[ # # ]
74 : 0 : }
75 : :
76 : : //-----------------------------------------------
77 : 0 : Locale::Locale(const Locale& aCopy)
78 : : {
79 [ # # ]: 0 : (*this) = aCopy; // recycle assign operator
80 : 0 : }
81 : :
82 : : //-----------------------------------------------
83 : 2776 : ::rtl::OUString Locale::getLanguage() const
84 : : {
85 : 2776 : return m_sLanguage;
86 : : }
87 : :
88 : : //-----------------------------------------------
89 : 2776 : ::rtl::OUString Locale::getCountry() const
90 : : {
91 : 2776 : return m_sCountry;
92 : : }
93 : :
94 : : //-----------------------------------------------
95 : 2776 : ::rtl::OUString Locale::getVariant() const
96 : : {
97 : 2776 : return m_sVariant;
98 : : }
99 : :
100 : : //-----------------------------------------------
101 : 230285 : void Locale::setLanguage(const ::rtl::OUString& sLanguage)
102 : : {
103 : 230285 : m_sLanguage = sLanguage;
104 : 230285 : }
105 : :
106 : : //-----------------------------------------------
107 : 209907 : void Locale::setCountry(const ::rtl::OUString& sCountry)
108 : : {
109 : 209907 : m_sCountry = sCountry;
110 : 209907 : }
111 : :
112 : : //-----------------------------------------------
113 : 126952 : void Locale::setVariant(const ::rtl::OUString& sVariant)
114 : : {
115 : 126952 : m_sVariant = sVariant;
116 : 126952 : }
117 : :
118 : : //-----------------------------------------------
119 : : /* Attention: Use own interface methods to set the
120 : : different parts of this locale. Because the
121 : : check the incoming value and throw an exception
122 : : automaticly ...
123 : : */
124 : 103333 : void Locale::fromISO(const ::rtl::OUString& sISO)
125 : : throw(Locale::MalFormedLocaleException)
126 : : {
127 : 103333 : m_sLanguage = ::rtl::OUString();
128 : 103333 : m_sCountry = ::rtl::OUString();
129 : 103333 : m_sVariant = ::rtl::OUString();
130 : :
131 : 103333 : ::rtl::OUString sParser(sISO);
132 : 103333 : sParser.trim();
133 : :
134 : 103333 : sal_Int32 nStart = 0;
135 : 103333 : sal_Int32 nEnd = 0;
136 : :
137 : : // extract language part
138 : 103333 : nEnd = sParser.indexOf(SEPERATOR_LC, nStart);
139 [ + + ]: 103333 : if (nEnd<0)
140 : : {
141 [ + - ]: 20378 : setLanguage(sParser);
142 : : return;
143 : : }
144 [ + - ]: 82955 : setLanguage(sParser.copy(nStart, nEnd-nStart));
145 : 82955 : nStart = nEnd+1;
146 : :
147 : : // extract country
148 : 82955 : nEnd = sParser.indexOf(SEPERATOR_CV, nStart);
149 [ + - ]: 82955 : if (nEnd<0)
150 : 82955 : nEnd = sParser.indexOf(SEPERATOR_CV_LINUX, nStart);
151 [ + - ]: 82955 : if (nEnd<0)
152 : : {
153 [ + - ]: 82955 : setCountry(sParser.copy(nStart, sParser.getLength()-nStart));
154 : : return;
155 : : }
156 : 0 : nStart = nEnd+1;
157 : :
158 : : // extract variant
159 [ # # ][ - + ]: 103333 : setVariant(sParser.copy(nStart, sParser.getLength()-nStart));
160 : : }
161 : :
162 : : //-----------------------------------------------
163 : 5622 : ::rtl::OUString Locale::toISO() const
164 : : {
165 : 5622 : ::rtl::OUStringBuffer sISO(64);
166 : :
167 [ + - ]: 5622 : sISO.append(m_sLanguage);
168 [ + + ]: 5622 : if (!m_sCountry.isEmpty())
169 : : {
170 [ + - ]: 5620 : sISO.append(SEPERATOR_LC);
171 [ + - ]: 5620 : sISO.append(m_sCountry);
172 : :
173 [ - + ]: 5620 : if (!m_sVariant.isEmpty())
174 : : {
175 [ # # ]: 0 : sISO.append(SEPERATOR_CV);
176 [ # # ]: 0 : sISO.append(m_sVariant);
177 : : }
178 : : }
179 : :
180 [ + - ]: 5622 : return sISO.makeStringAndClear();
181 : : }
182 : :
183 : : //-----------------------------------------------
184 : 132637 : sal_Bool Locale::equals(const Locale& aComparable) const
185 : : {
186 : : return (
187 : 132637 : m_sLanguage.equals(aComparable.m_sLanguage) &&
188 : 25830 : m_sCountry.equals (aComparable.m_sCountry ) &&
189 : 25830 : m_sVariant.equals (aComparable.m_sVariant )
190 [ + + + - : 184297 : );
+ - ]
191 : : }
192 : :
193 : : //-----------------------------------------------
194 : 70030 : sal_Bool Locale::similar(const Locale& aComparable) const
195 : : {
196 : 70030 : return (m_sLanguage.equals(aComparable.m_sLanguage));
197 : : }
198 : :
199 : : //-----------------------------------------------
200 : 48315 : ::std::vector< ::rtl::OUString >::const_iterator Locale::getFallback(const ::std::vector< ::rtl::OUString >& lISOList ,
201 : : const ::rtl::OUString& sReferenceISO)
202 : : throw(Locale::MalFormedLocaleException)
203 : : {
204 [ + - ]: 48315 : Locale aReference(sReferenceISO);
205 : :
206 : : // Note: The same language or "en"/"en-US" should be preferred as fallback.
207 : : // On the other side some localized variables doesnt use localzation in real.
208 : : // May be the use a "fix" value only ... marked as X-DEFAULT or X-NOTRANSLATE.
209 : : // At least it can be discussed, if any language is a valid fallback ...
210 : : // But in case some office functionality depends on that (that means real functionality instead
211 : : // of pure UI descriptions) we should do anything, so it can work.
212 : :
213 : 48315 : ::std::vector< ::rtl::OUString >::const_iterator pSimilar = lISOList.end();
214 : 48315 : ::std::vector< ::rtl::OUString >::const_iterator pEN_US = lISOList.end();
215 : 48315 : ::std::vector< ::rtl::OUString >::const_iterator pEN = lISOList.end();
216 : 48315 : ::std::vector< ::rtl::OUString >::const_iterator pXDefault = lISOList.end();
217 : 48315 : ::std::vector< ::rtl::OUString >::const_iterator pXNoTranslate = lISOList.end();
218 : 48315 : ::std::vector< ::rtl::OUString >::const_iterator pAny = lISOList.end();
219 : :
220 : 48315 : ::std::vector< ::rtl::OUString >::const_iterator pIt;
221 [ + - ][ + + ]: 174792 : for ( pIt = lISOList.begin();
222 : 83330 : pIt != lISOList.end() ;
223 : : ++pIt )
224 : : {
225 [ + - ]: 43147 : Locale aCheck(*pIt);
226 : : // found Locale, which match with 100% => return it
227 [ + - ][ + + ]: 43147 : if (aCheck.equals(aReference))
228 : 8132 : return pIt;
229 : :
230 : : // found similar Locale => safe it as possible fallback
231 [ + - ][ - + ]: 105045 : if (
[ - + ]
232 [ + - ][ + - ]: 70030 : (pSimilar == lISOList.end()) &&
[ # # ]
233 [ + - ]: 35015 : (aCheck.similar(aReference))
234 : : )
235 : : {
236 : 0 : pSimilar = pIt;
237 : : }
238 : : else
239 : : // found en-US => safe it as fallback
240 [ + - ][ - + ]: 105045 : if (
[ - + ]
241 [ + - ][ + - ]: 70030 : (pEN_US == lISOList.end()) &&
[ # # ]
242 [ + - ][ + - ]: 70030 : (aCheck.equals(EN_US()) )
[ + - ][ + - ]
[ # # ]
243 : : )
244 : : {
245 : 0 : pEN_US = pIt;
246 : : }
247 : : else
248 : : // found en[-XX] => safe it as fallback
249 [ + - ][ - + ]: 105045 : if (
[ - + ]
250 [ + - ][ + - ]: 70030 : (pEN == lISOList.end() ) &&
[ # # ]
251 [ + - ][ + - ]: 70030 : (aCheck.similar(EN_US()))
[ + - ][ + - ]
[ # # ]
252 : : )
253 : : {
254 : 0 : pEN = pIt;
255 : : }
256 : : else
257 : : // found an explicit default value(!) => safe it as fallback
258 [ + - ][ + + ]: 105045 : if (
[ + + ]
259 [ + - ][ + - ]: 70030 : (pXDefault == lISOList.end()) &&
[ # # ]
260 [ + - ][ + - ]: 70030 : (aCheck.equals(X_DEFAULT()) )
[ + - ][ + - ]
[ # # ]
261 : : )
262 : : {
263 : 17197 : pXDefault = pIt;
264 : : }
265 : : else
266 : : // found an implicit default value(!) => safe it as fallback
267 [ + - ][ - + ]: 53454 : if (
[ - + ]
268 [ + - ][ + - ]: 35636 : (pXNoTranslate == lISOList.end()) &&
[ # # ]
269 [ + - ][ + - ]: 35636 : (aCheck.equals(X_NOTRANSLATE()) )
[ + - ][ + - ]
[ # # ]
270 : : )
271 : : {
272 : 0 : pXNoTranslate = pIt;
273 : : }
274 : : else
275 : : // safe the first locale, which isn't an explicit fallback
276 : : // as "last possible fallback"
277 [ + - ][ + - ]: 17818 : if (pAny == lISOList.end())
278 : 35015 : pAny = pIt;
279 [ + - ][ + + ]: 43147 : }
280 : :
281 [ + - ][ - + ]: 40183 : if (pSimilar != lISOList.end())
282 : 0 : return pSimilar;
283 : :
284 [ + - ][ - + ]: 40183 : if (pEN_US != lISOList.end())
285 : 0 : return pEN_US;
286 : :
287 [ + - ][ - + ]: 40183 : if (pEN != lISOList.end())
288 : 0 : return pEN;
289 : :
290 [ + - ][ + + ]: 40183 : if (pXDefault != lISOList.end())
291 : 17197 : return pXDefault;
292 : :
293 [ + - ][ - + ]: 22986 : if (pXNoTranslate != lISOList.end())
294 : 0 : return pXNoTranslate;
295 : :
296 [ + - ][ + + ]: 22986 : if (pAny != lISOList.end())
297 : 17818 : return pAny;
298 : :
299 [ + - ]: 48315 : return lISOList.end();
300 : : }
301 : :
302 : : //-----------------------------------------------
303 : 1642 : void Locale::operator=(const Locale& rCopy)
304 : : {
305 : : // Take over these values without checking ...
306 : : // They was already checked if the copy was constructed
307 : : // and must be valid now!
308 : 1642 : m_sLanguage = rCopy.m_sLanguage;
309 : 1642 : m_sCountry = rCopy.m_sCountry;
310 : 1642 : m_sVariant = rCopy.m_sVariant;
311 : 1642 : }
312 : :
313 : : //-----------------------------------------------
314 : 0 : sal_Bool Locale::operator==(const Locale& aComparable) const
315 : : {
316 : 0 : return equals(aComparable);
317 : : }
318 : :
319 : : //-----------------------------------------------
320 : 1642 : sal_Bool Locale::operator!=(const Locale& aComparable) const
321 : : {
322 : 1642 : return !equals(aComparable);
323 : : }
324 : :
325 : : } // namespace comphelper
326 : :
327 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|