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 "dp_misc.h"
31 : : #include "dp_resource.h"
32 : : #include "osl/module.hxx"
33 : : #include "osl/mutex.hxx"
34 : : #include <tools/resmgr.hxx>
35 : : #include "rtl/ustring.h"
36 : : #include "cppuhelper/implbase1.hxx"
37 : : #include "unotools/configmgr.hxx"
38 : :
39 : :
40 : : using namespace ::com::sun::star;
41 : : using namespace ::com::sun::star::uno;
42 : : using ::rtl::OUString;
43 : :
44 : : namespace dp_misc {
45 : : namespace {
46 : :
47 : : struct OfficeLocale :
48 : : public rtl::StaticWithInit<OUString, OfficeLocale> {
49 : 124 : const OUString operator () () {
50 : 124 : OUString slang(utl::ConfigManager::getLocale());
51 : : //fallback, the locale is currently only set when the user starts the
52 : : //office for the first time.
53 [ - + ]: 124 : if (slang.isEmpty())
54 [ # # ]: 0 : slang = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US"));
55 : 124 : return slang;
56 : : }
57 : : };
58 : :
59 : : struct DeploymentResMgr : public rtl::StaticWithInit<
60 : : ResMgr *, DeploymentResMgr> {
61 : 124 : ResMgr * operator () () {
62 [ + - ]: 124 : return ResMgr::CreateResMgr( "deployment", getOfficeLocale() );
63 : : }
64 : : };
65 : :
66 : : class theResourceMutex : public rtl::Static<osl::Mutex, theResourceMutex> {};
67 : :
68 : : } // anon namespace
69 : :
70 : : //==============================================================================
71 : 0 : ResId getResId( sal_uInt16 id )
72 : : {
73 [ # # ][ # # ]: 0 : const osl::MutexGuard guard( theResourceMutex::get() );
74 [ # # ][ # # ]: 0 : return ResId( id, *DeploymentResMgr::get() );
75 : : }
76 : :
77 : : //==============================================================================
78 : 4780 : String getResourceString( sal_uInt16 id )
79 : : {
80 [ + - ][ + - ]: 4780 : const osl::MutexGuard guard( theResourceMutex::get() );
81 [ + - ][ + - ]: 4780 : String ret( ResId( id, *DeploymentResMgr::get() ) );
82 : : ret.SearchAndReplaceAllAscii(
83 [ + - ][ + - ]: 4780 : "%PRODUCTNAME", utl::ConfigManager::getProductName() );
[ + - ][ + - ]
84 [ + - ]: 4780 : return ret;
85 : : }
86 : :
87 : : //throws an Exception on failure
88 : : //primary subtag 2 or three letters(A-Z, a-z), i or x
89 : 1118 : void checkPrimarySubtag(::rtl::OUString const & tag)
90 : : {
91 : 1118 : sal_Int32 len = tag.getLength();
92 : 1118 : sal_Unicode const * arLang = tag.getStr();
93 [ - + ][ + - ]: 1118 : if (len < 1 || len > 3)
94 [ # # ][ # # ]: 0 : throw Exception(OUSTR("Invalid language string."), 0);
[ # # ]
95 : :
96 [ - + ][ # # ]: 1118 : if (len == 1
[ # # ]
97 : : && (arLang[0] != 'i' && arLang[0] != 'x'))
98 [ # # ][ # # ]: 0 : throw Exception(OUSTR("Invalid language string."), 0);
[ # # ]
99 : :
100 [ - + ][ # # ]: 1118 : if (len == 2 || len == 3)
101 : : {
102 [ + + ]: 3354 : for (sal_Int32 i = 0; i < len; i++)
103 : : {
104 [ + - ]: 2236 : if ( !((arLang[i] >= 'A' && arLang[i] <= 'Z')
105 [ + - ][ + - ]: 2236 : || (arLang[i] >= 'a' && arLang[i] <= 'z')))
[ - + ]
106 : : {
107 [ # # ][ # # ]: 0 : throw Exception(OUSTR("Invalid language string."), 0);
[ # # ]
108 : : }
109 : : }
110 : : }
111 : 1118 : }
112 : :
113 : : //throws an Exception on failure
114 : : //second subtag 2 letter country code or 3-8 letter other code(A-Z, a-z, 0-9)
115 : 1118 : void checkSecondSubtag(::rtl::OUString const & tag, bool & bIsCountry)
116 : : {
117 : 1118 : sal_Int32 len = tag.getLength();
118 : 1118 : sal_Unicode const * arLang = tag.getStr();
119 [ - + ][ + - ]: 1118 : if (len < 2 || len > 8)
120 [ # # ][ # # ]: 0 : throw Exception(OUSTR("Invalid language string."), 0);
[ # # ]
121 : : //country code
122 : 1118 : bIsCountry = false;
123 [ + - ]: 1118 : if (len == 2)
124 : : {
125 [ + + ]: 3354 : for (sal_Int32 i = 0; i < 2; i++)
126 : : {
127 [ + - ]: 2236 : if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
128 [ - + ][ # # ]: 2236 : || (arLang[i] >= 'a' && arLang[i] <= 'z')))
[ # # ]
129 : : {
130 [ # # ][ # # ]: 0 : throw Exception(OUSTR("Invalid language string."), 0);
[ # # ]
131 : : }
132 : : }
133 : 1118 : bIsCountry = true;
134 : : }
135 : :
136 [ - + ]: 1118 : if (len > 2)
137 : : {
138 [ # # ]: 0 : for (sal_Int32 i = 0; i < len; i++)
139 : : {
140 [ # # ]: 0 : if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
141 : 0 : || (arLang[i] >= 'a' && arLang[i] <= 'z')
142 [ # # ][ # # ]: 0 : || (arLang[i] >= '0' && arLang[i] <= '9') ))
[ # # ][ # # ]
[ # # ]
143 : : {
144 [ # # ][ # # ]: 0 : throw Exception(OUSTR("Invalid language string."), 0);
[ # # ]
145 : : }
146 : : }
147 : : }
148 : 1118 : }
149 : :
150 : 0 : void checkThirdSubtag(::rtl::OUString const & tag)
151 : : {
152 : 0 : sal_Int32 len = tag.getLength();
153 : 0 : sal_Unicode const * arLang = tag.getStr();
154 [ # # ][ # # ]: 0 : if (len < 1 || len > 8)
155 [ # # ][ # # ]: 0 : throw Exception(OUSTR("Invalid language string."), 0);
[ # # ]
156 : :
157 [ # # ]: 0 : for (sal_Int32 i = 0; i < len; i++)
158 : : {
159 [ # # ]: 0 : if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
160 : 0 : || (arLang[i] >= 'a' && arLang[i] <= 'z')
161 [ # # ][ # # ]: 0 : || (arLang[i] >= '0' && arLang[i] <= '9') ))
[ # # ][ # # ]
[ # # ]
162 : : {
163 [ # # ][ # # ]: 0 : throw Exception(OUSTR("Invalid language string."), 0);
[ # # ]
164 : : }
165 : : }
166 : 0 : }
167 : :
168 : : //=============================================================================
169 : :
170 : : //We parse the string acording to RFC 3066
171 : : //We only use the primary sub-tag and two subtags. That is lang-country-variant
172 : : //We do some simple tests if the string is correct. Actually this should do a
173 : : //validating parser
174 : : //We may have the case that there is no country tag, for example en-welsh
175 : 1118 : ::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang )
176 : : {
177 : 1118 : OUString _sLang = slang.trim();
178 : 1118 : ::com::sun::star::lang::Locale locale;
179 : 1118 : sal_Int32 nIndex = 0;
180 : 1118 : OUString lang = _sLang.getToken( 0, '-', nIndex );
181 [ + - ]: 1118 : checkPrimarySubtag(lang);
182 : 1118 : locale.Language = lang;
183 : 1118 : OUString country = _sLang.getToken( 0, '-', nIndex );
184 [ + - ]: 1118 : if (!country.isEmpty())
185 : : {
186 : 1118 : bool bIsCountry = false;
187 [ + - ]: 1118 : checkSecondSubtag(country, bIsCountry);
188 [ + - ]: 1118 : if (bIsCountry)
189 : : {
190 : 1118 : locale.Country = country;
191 : : }
192 : : else
193 : : {
194 : 1118 : locale.Variant = country;
195 : : }
196 : : }
197 [ + - ]: 1118 : if (locale.Variant.isEmpty())
198 : : {
199 : 1118 : OUString variant = _sLang.getToken( 0, '-', nIndex );
200 [ - + ]: 1118 : if (!variant.isEmpty())
201 : : {
202 [ # # ]: 0 : checkThirdSubtag(variant);
203 : 0 : locale.Variant = variant;
204 : 1118 : }
205 : : }
206 : :
207 : 1118 : return locale;
208 : : }
209 : :
210 : : //==============================================================================
211 : 1118 : lang::Locale getOfficeLocale()
212 : : {
213 : 1118 : return toLocale(OfficeLocale::get());
214 : : }
215 : :
216 : 4712 : ::rtl::OUString getOfficeLocaleString()
217 : : {
218 : 4712 : return OfficeLocale::get();
219 : : }
220 : :
221 : : }
222 : :
223 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|