diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llui/llresmgr.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llui/llresmgr.cpp')
-rw-r--r-- | linden/indra/llui/llresmgr.cpp | 466 |
1 files changed, 466 insertions, 0 deletions
diff --git a/linden/indra/llui/llresmgr.cpp b/linden/indra/llui/llresmgr.cpp new file mode 100644 index 0000000..3c54cf6 --- /dev/null +++ b/linden/indra/llui/llresmgr.cpp | |||
@@ -0,0 +1,466 @@ | |||
1 | /** | ||
2 | * @file llresmgr.cpp | ||
3 | * @brief Localized resource manager | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | // NOTE: this is a MINIMAL implementation. The interface will remain, but the implementation will | ||
29 | // (when the time is right) become dynamic and probably use external files. | ||
30 | |||
31 | #include "linden_common.h" | ||
32 | |||
33 | #include "llresmgr.h" | ||
34 | #include "llfontgl.h" | ||
35 | #include "llerror.h" | ||
36 | #include "llstring.h" | ||
37 | |||
38 | // Global singleton | ||
39 | LLResMgr* gResMgr = NULL; | ||
40 | |||
41 | LLResMgr::LLResMgr() | ||
42 | { | ||
43 | U32 i; | ||
44 | |||
45 | // Init values for each locale. | ||
46 | // Note: This is only the most bare-bones version. In the future, load these dynamically, on demand. | ||
47 | |||
48 | ////////////////////////////////////////////////////////////////////////////// | ||
49 | // USA | ||
50 | // USA Fonts | ||
51 | for( i=0; i<LLFONT_COUNT; i++ ) | ||
52 | { | ||
53 | mUSAFonts[i] = NULL; | ||
54 | } | ||
55 | mUSAFonts[ LLFONT_OCRA ] = LLFontGL::sMonospace; | ||
56 | mUSAFonts[ LLFONT_SANSSERIF ] = LLFontGL::sSansSerif; | ||
57 | mUSAFonts[ LLFONT_SANSSERIF_SMALL ] = LLFontGL::sSansSerifSmall; | ||
58 | mUSAFonts[ LLFONT_SANSSERIF_BIG ] = LLFontGL::sSansSerifBig; | ||
59 | mUSAFonts[ LLFONT_SMALL ] = LLFontGL::sMonospace; | ||
60 | /* | ||
61 | // USA Strings | ||
62 | for( i=0; i<LLSTR_COUNT; i++ ) | ||
63 | { | ||
64 | mUSAStrings[i] = ""; | ||
65 | } | ||
66 | mUSAStrings[ LLSTR_HELLO ] = "hello"; | ||
67 | mUSAStrings[ LLSTR_GOODBYE ] = "goodbye"; | ||
68 | mUSAStrings[ LLSTR_CHAT_LABEL ] = "Chat"; | ||
69 | mUSAStrings[ LLSTR_STATUS_LABEL ] = "Properties"; | ||
70 | mUSAStrings[ LLSTR_X ] = "X"; | ||
71 | mUSAStrings[ LLSTR_Y ] = "Y"; | ||
72 | mUSAStrings[ LLSTR_Z ] = "Z"; | ||
73 | mUSAStrings[ LLSTR_POSITION ] = "Position (meters)"; | ||
74 | mUSAStrings[ LLSTR_SCALE ] = "Size (meters)"; | ||
75 | mUSAStrings[ LLSTR_ROTATION ] = "Rotation (degrees)"; | ||
76 | mUSAStrings[ LLSTR_HAS_PHYSICS ] = "Has Physics"; | ||
77 | mUSAStrings[ LLSTR_SCRIPT ] = "Script"; | ||
78 | mUSAStrings[ LLSTR_HELP ] = "Help"; | ||
79 | mUSAStrings[ LLSTR_REMOVE ] = "Remove"; | ||
80 | mUSAStrings[ LLSTR_CLEAR ] = "Clear"; | ||
81 | mUSAStrings[ LLSTR_APPLY ] = "Apply"; | ||
82 | mUSAStrings[ LLSTR_CANCEL ] = "Cancel"; | ||
83 | mUSAStrings[ LLSTR_MATERIAL ] = "Material"; | ||
84 | mUSAStrings[ LLSTR_FACE ] = "Face"; | ||
85 | mUSAStrings[ LLSTR_TEXTURE ] = "Texture"; | ||
86 | mUSAStrings[ LLSTR_TEXTURE_SIZE ] = "Repeats per Face"; | ||
87 | mUSAStrings[ LLSTR_TEXTURE_OFFSET ] = "Offset"; | ||
88 | mUSAStrings[ LLSTR_TEXTURE_ROTATION ] = "Rotation (degrees)"; | ||
89 | mUSAStrings[ LLSTR_U ] = "U"; | ||
90 | mUSAStrings[ LLSTR_V ] = "V"; | ||
91 | mUSAStrings[ LLSTR_OWNERSHIP ] = "Ownership"; | ||
92 | mUSAStrings[ LLSTR_PUBLIC ] = "Public"; | ||
93 | mUSAStrings[ LLSTR_PRIVATE ] = "Private"; | ||
94 | mUSAStrings[ LLSTR_REVERT ] = "Revert"; | ||
95 | mUSAStrings[ LLSTR_INSERT_SAMPLE ] = "Insert Sample"; | ||
96 | mUSAStrings[ LLSTR_SET_TEXTURE ] = "Set Texture"; | ||
97 | mUSAStrings[ LLSTR_EDIT_SCRIPT ] = "Edit Script..."; | ||
98 | mUSAStrings[ LLSTR_MOUSELOOK_INSTRUCTIONS ] = "Press ESC to leave Mouselook."; | ||
99 | mUSAStrings[ LLSTR_EDIT_FACE_INSTRUCTIONS ] = "Click on face to select part. Click and hold on a picture to look more like that. Press ESC to leave Face Edit Mode."; | ||
100 | mUSAStrings[ LLSTR_CLOSE ] = "Close"; | ||
101 | mUSAStrings[ LLSTR_MOVE ] = "Move"; | ||
102 | mUSAStrings[ LLSTR_ROTATE ] = "Rotate"; | ||
103 | mUSAStrings[ LLSTR_RESIZE ] = "Resize"; | ||
104 | mUSAStrings[ LLSTR_PLACE_BOX ] = "Place Box"; | ||
105 | mUSAStrings[ LLSTR_PLACE_PRISM ] = "Place Prism"; | ||
106 | mUSAStrings[ LLSTR_PLACE_PYRAMID ] = "Place Pyramid"; | ||
107 | mUSAStrings[ LLSTR_PLACE_TETRAHEDRON ] = "Place Tetrahedron"; | ||
108 | mUSAStrings[ LLSTR_PLACE_CYLINDER ] = "Place Cylinder"; | ||
109 | mUSAStrings[ LLSTR_PLACE_HALF_CYLINDER ] = "Place Half-Cylinder"; | ||
110 | mUSAStrings[ LLSTR_PLACE_CONE ] = "Place Cone"; | ||
111 | mUSAStrings[ LLSTR_PLACE_HALF_CONE ] = "Place Half-Cone"; | ||
112 | mUSAStrings[ LLSTR_PLACE_SPHERE ] = "Place Sphere"; | ||
113 | mUSAStrings[ LLSTR_PLACE_HALF_SPHERE ] = "Place Half-Sphere"; | ||
114 | mUSAStrings[ LLSTR_PLACE_BIRD ] = "Place Bird"; | ||
115 | mUSAStrings[ LLSTR_PLACE_SNAKE ] = "Place Silly Snake"; | ||
116 | mUSAStrings[ LLSTR_PLACE_ROCK ] = "Place Rock"; | ||
117 | mUSAStrings[ LLSTR_PLACE_TREE ] = "Place Tree"; | ||
118 | mUSAStrings[ LLSTR_PLACE_GRASS ] = "Place Grass"; | ||
119 | mUSAStrings[ LLSTR_MODIFY_LAND ] = "Modify Land"; | ||
120 | */ | ||
121 | ////////////////////////////////////////////////////////////////////////////// | ||
122 | // UK | ||
123 | // The Brits are a lot like us Americans, so initially assume we're the same and only code the exceptions. | ||
124 | |||
125 | // UK Fonts | ||
126 | for( i=0; i<LLFONT_COUNT; i++ ) | ||
127 | { | ||
128 | mUKFonts[i] = mUSAFonts[i]; | ||
129 | } | ||
130 | /* | ||
131 | // UK Strings | ||
132 | for( i=0; i<LLSTR_COUNT; i++ ) | ||
133 | { | ||
134 | mUKStrings[i] = mUSAStrings[i]; | ||
135 | } | ||
136 | mUKStrings[ LLSTR_HELLO ] = "hullo"; | ||
137 | mUKStrings[ LLSTR_GOODBYE ] = "cheerio"; | ||
138 | */ | ||
139 | ////////////////////////////////////////////////////////////////////////////// | ||
140 | // Set default | ||
141 | setLocale( LLLOCALE_USA ); | ||
142 | |||
143 | } | ||
144 | |||
145 | |||
146 | void LLResMgr::setLocale( LLLOCALE_ID locale_id ) | ||
147 | { | ||
148 | mLocale = locale_id; | ||
149 | |||
150 | //RN: for now, use normal 'C' locale for everything but specific UI input/output routines | ||
151 | switch( locale_id ) | ||
152 | { | ||
153 | case LLLOCALE_USA: | ||
154 | //#if LL_WINDOWS | ||
155 | // // Windows doesn't use ISO country codes. | ||
156 | // llinfos << "Setting locale to " << setlocale( LC_ALL, "english-usa" ) << llendl; | ||
157 | //#else | ||
158 | // // posix version should work everywhere else. | ||
159 | // llinfos << "Setting locale to " << setlocale( LC_ALL, "en_US" ) << llendl; | ||
160 | //#endif | ||
161 | |||
162 | // mStrings = mUSAStrings; | ||
163 | mFonts = mUSAFonts; | ||
164 | break; | ||
165 | case LLLOCALE_UK: | ||
166 | //#if LL_WINDOWS | ||
167 | // // Windows doesn't use ISO country codes. | ||
168 | // llinfos << "Setting locale to " << setlocale( LC_ALL, "english-uk" ) << llendl; | ||
169 | //#else | ||
170 | // // posix version should work everywhere else. | ||
171 | // llinfos << "Setting locale to " << setlocale( LC_ALL, "en_GB" ) << llendl; | ||
172 | //#endif | ||
173 | |||
174 | // mStrings = mUKStrings; | ||
175 | mFonts = mUKFonts; | ||
176 | break; | ||
177 | default: | ||
178 | llassert(0); | ||
179 | setLocale(LLLOCALE_USA); | ||
180 | break; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | char LLResMgr::getDecimalPoint() const | ||
185 | { | ||
186 | char decimal = localeconv()->decimal_point[0]; | ||
187 | |||
188 | #if LL_DARWIN | ||
189 | // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped. | ||
190 | if(decimal == 0) | ||
191 | { | ||
192 | decimal = '.'; | ||
193 | } | ||
194 | #endif | ||
195 | |||
196 | return decimal; | ||
197 | } | ||
198 | |||
199 | char LLResMgr::getThousandsSeparator() const | ||
200 | { | ||
201 | char separator = localeconv()->thousands_sep[0]; | ||
202 | |||
203 | #if LL_DARWIN | ||
204 | // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped. | ||
205 | if(separator == 0) | ||
206 | { | ||
207 | separator = ','; | ||
208 | } | ||
209 | #endif | ||
210 | |||
211 | return separator; | ||
212 | } | ||
213 | |||
214 | char LLResMgr::getMonetaryDecimalPoint() const | ||
215 | { | ||
216 | char decimal = localeconv()->mon_decimal_point[0]; | ||
217 | |||
218 | #if LL_DARWIN | ||
219 | // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped. | ||
220 | if(decimal == 0) | ||
221 | { | ||
222 | decimal = '.'; | ||
223 | } | ||
224 | #endif | ||
225 | |||
226 | return decimal; | ||
227 | } | ||
228 | |||
229 | char LLResMgr::getMonetaryThousandsSeparator() const | ||
230 | { | ||
231 | char separator = localeconv()->mon_thousands_sep[0]; | ||
232 | |||
233 | #if LL_DARWIN | ||
234 | // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped. | ||
235 | if(separator == 0) | ||
236 | { | ||
237 | separator = ','; | ||
238 | } | ||
239 | #endif | ||
240 | |||
241 | return separator; | ||
242 | } | ||
243 | |||
244 | |||
245 | // Sets output to a string of integers with monetary separators inserted according to the locale. | ||
246 | void LLResMgr::getMonetaryString( LLString& output, S32 input ) const | ||
247 | { | ||
248 | LLLocale locale(LLLocale::USER_LOCALE); | ||
249 | struct lconv *conv = localeconv(); | ||
250 | |||
251 | #if LL_DARWIN | ||
252 | // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped. | ||
253 | // Fake up a conv structure with some reasonable values for the fields this function uses. | ||
254 | struct lconv fakeconv; | ||
255 | if(conv->negative_sign[0] == 0) // Real locales all seem to have something here... | ||
256 | { | ||
257 | fakeconv = *conv; // start with what's there. | ||
258 | switch(mLocale) | ||
259 | { | ||
260 | default: // Unknown -- use the US defaults. | ||
261 | case LLLOCALE_USA: | ||
262 | case LLLOCALE_UK: // UK ends up being the same as US for the items used here. | ||
263 | fakeconv.negative_sign = "-"; | ||
264 | fakeconv.mon_grouping = "\x03\x03\x00"; // commas every 3 digits | ||
265 | fakeconv.n_sign_posn = 1; // negative sign before the string | ||
266 | break; | ||
267 | } | ||
268 | conv = &fakeconv; | ||
269 | } | ||
270 | #endif | ||
271 | |||
272 | char* negative_sign = conv->negative_sign; | ||
273 | char separator = getMonetaryThousandsSeparator(); | ||
274 | char* grouping = conv->mon_grouping; | ||
275 | |||
276 | // Note on mon_grouping: | ||
277 | // Specifies a string that defines the size of each group of digits in formatted monetary quantities. | ||
278 | // The operand for the mon_grouping keyword consists of a sequence of semicolon-separated integers. | ||
279 | // Each integer specifies the number of digits in a group. The initial integer defines the size of | ||
280 | // the group immediately to the left of the decimal delimiter. The following integers define succeeding | ||
281 | // groups to the left of the previous group. If the last integer is not -1, the size of the previous | ||
282 | // group (if any) is repeatedly used for the remainder of the digits. If the last integer is -1, no | ||
283 | // further grouping is performed. | ||
284 | |||
285 | |||
286 | // Note: we assume here that the currency symbol goes on the left. (Hey, it's Lindens! We can just decide.) | ||
287 | BOOL negative = (input < 0 ); | ||
288 | BOOL negative_before = negative && (conv->n_sign_posn != 2); | ||
289 | BOOL negative_after = negative && (conv->n_sign_posn == 2); | ||
290 | |||
291 | LLString digits = llformat("%u", abs(input)); | ||
292 | if( !grouping || !grouping[0] ) | ||
293 | { | ||
294 | output.assign("L$"); | ||
295 | if( negative_before ) | ||
296 | { | ||
297 | output.append( negative_sign ); | ||
298 | } | ||
299 | output.append( digits ); | ||
300 | if( negative_after ) | ||
301 | { | ||
302 | output.append( negative_sign ); | ||
303 | } | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | S32 groupings[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
308 | S32 cur_group; | ||
309 | for( cur_group = 0; grouping[ cur_group ]; cur_group++ ) | ||
310 | { | ||
311 | if( grouping[ cur_group ] != ';' ) | ||
312 | { | ||
313 | groupings[cur_group] = grouping[ cur_group ]; | ||
314 | } | ||
315 | cur_group++; | ||
316 | |||
317 | if( groupings[cur_group] < 0 ) | ||
318 | { | ||
319 | break; | ||
320 | } | ||
321 | } | ||
322 | S32 group_count = cur_group; | ||
323 | |||
324 | char reversed_output[20] = ""; | ||
325 | char forward_output[20] = ""; | ||
326 | S32 output_pos = 0; | ||
327 | |||
328 | cur_group = 0; | ||
329 | S32 pos = digits.size()-1; | ||
330 | S32 count_within_group = 0; | ||
331 | while( (pos >= 0) && (groupings[cur_group] >= 0) ) | ||
332 | { | ||
333 | count_within_group++; | ||
334 | if( count_within_group > groupings[cur_group] ) | ||
335 | { | ||
336 | count_within_group = 1; | ||
337 | reversed_output[ output_pos++ ] = separator; | ||
338 | |||
339 | if( (cur_group + 1) >= group_count ) | ||
340 | { | ||
341 | break; | ||
342 | } | ||
343 | else | ||
344 | if( groupings[cur_group + 1] > 0 ) | ||
345 | { | ||
346 | cur_group++; | ||
347 | } | ||
348 | } | ||
349 | reversed_output[ output_pos++ ] = digits[pos--]; | ||
350 | } | ||
351 | |||
352 | while( pos >= 0 ) | ||
353 | { | ||
354 | reversed_output[ output_pos++ ] = digits[pos--]; | ||
355 | } | ||
356 | |||
357 | |||
358 | reversed_output[ output_pos ] = '\0'; | ||
359 | forward_output[ output_pos ] = '\0'; | ||
360 | |||
361 | for( S32 i = 0; i < output_pos; i++ ) | ||
362 | { | ||
363 | forward_output[ output_pos - 1 - i ] = reversed_output[ i ]; | ||
364 | } | ||
365 | |||
366 | output.assign("L$"); | ||
367 | if( negative_before ) | ||
368 | { | ||
369 | output.append( negative_sign ); | ||
370 | } | ||
371 | output.append( forward_output ); | ||
372 | if( negative_after ) | ||
373 | { | ||
374 | output.append( negative_sign ); | ||
375 | } | ||
376 | } | ||
377 | |||
378 | void LLResMgr::getIntegerString( LLString& output, S32 input ) const | ||
379 | { | ||
380 | S32 fraction = 0; | ||
381 | LLString fraction_string; | ||
382 | S32 remaining_count = input; | ||
383 | while(remaining_count > 0) | ||
384 | { | ||
385 | fraction = (remaining_count) % 1000; | ||
386 | |||
387 | if (!output.empty()) | ||
388 | { | ||
389 | if (fraction == remaining_count) | ||
390 | { | ||
391 | fraction_string = llformat("%d%c", fraction, getThousandsSeparator()); | ||
392 | } | ||
393 | else | ||
394 | { | ||
395 | fraction_string = llformat("%3.3d%c", fraction, getThousandsSeparator()); | ||
396 | } | ||
397 | output = fraction_string + output; | ||
398 | } | ||
399 | else | ||
400 | { | ||
401 | if (fraction == remaining_count) | ||
402 | { | ||
403 | fraction_string = llformat("%d", fraction); | ||
404 | } | ||
405 | else | ||
406 | { | ||
407 | fraction_string = llformat("%3.3d", fraction); | ||
408 | } | ||
409 | output = fraction_string; | ||
410 | } | ||
411 | remaining_count /= 1000; | ||
412 | } | ||
413 | } | ||
414 | |||
415 | const LLString LLFONT_ID_NAMES[] = | ||
416 | { | ||
417 | LLString("OCRA"), | ||
418 | LLString("SANSSERIF"), | ||
419 | LLString("SANSSERIF_SMALL"), | ||
420 | LLString("SANSSERIF_BIG"), | ||
421 | LLString("SMALL"), | ||
422 | }; | ||
423 | |||
424 | const LLFontGL* LLResMgr::getRes( LLString font_id ) const | ||
425 | { | ||
426 | for (S32 i=0; i<LLFONT_COUNT; ++i) | ||
427 | { | ||
428 | if (LLFONT_ID_NAMES[i] == font_id) | ||
429 | { | ||
430 | return getRes((LLFONT_ID)i); | ||
431 | } | ||
432 | } | ||
433 | return NULL; | ||
434 | } | ||
435 | |||
436 | #if LL_WINDOWS | ||
437 | const LLString LLLocale::USER_LOCALE("English_United States.1252");// = LLString::null; | ||
438 | const LLString LLLocale::SYSTEM_LOCALE("English_United States.1252"); | ||
439 | #elif LL_DARWIN | ||
440 | const LLString LLLocale::USER_LOCALE("en_US.iso8859-1");// = LLString::null; | ||
441 | const LLString LLLocale::SYSTEM_LOCALE("en_US.iso8859-1"); | ||
442 | #else // LL_LINUX likes this | ||
443 | const LLString LLLocale::USER_LOCALE("en_US.utf8");// = LLString::null; | ||
444 | const LLString LLLocale::SYSTEM_LOCALE("en_US.utf8"); | ||
445 | #endif | ||
446 | |||
447 | |||
448 | LLLocale::LLLocale(const LLString& locale_string) | ||
449 | { | ||
450 | mPrevLocaleString = setlocale( LC_ALL, NULL ); | ||
451 | char* new_locale_string = setlocale( LC_ALL, locale_string.c_str()); | ||
452 | if ( new_locale_string == NULL) | ||
453 | { | ||
454 | llwarns << "Failed to set locale " << locale_string << llendl; | ||
455 | setlocale(LC_ALL, SYSTEM_LOCALE.c_str()); | ||
456 | } | ||
457 | //else | ||
458 | //{ | ||
459 | // llinfos << "Set locale to " << new_locale_string << llendl; | ||
460 | //} | ||
461 | } | ||
462 | |||
463 | LLLocale::~LLLocale() | ||
464 | { | ||
465 | setlocale( LC_ALL, mPrevLocaleString.c_str() ); | ||
466 | } | ||