00001
00032
00033
00034
00035 #include "linden_common.h"
00036
00037 #include "llresmgr.h"
00038 #include "llfontgl.h"
00039 #include "llerror.h"
00040 #include "llstring.h"
00041
00042
00043 LLResMgr::LLResMgr()
00044 {
00045 U32 i;
00046
00047
00048
00049
00051
00052
00053 for( i=0; i<LLFONT_COUNT; i++ )
00054 {
00055 mUSAFonts[i] = NULL;
00056 }
00057 mUSAFonts[ LLFONT_OCRA ] = LLFontGL::sMonospace;
00058 mUSAFonts[ LLFONT_SANSSERIF ] = LLFontGL::sSansSerif;
00059 mUSAFonts[ LLFONT_SANSSERIF_SMALL ] = LLFontGL::sSansSerifSmall;
00060 mUSAFonts[ LLFONT_SANSSERIF_BIG ] = LLFontGL::sSansSerifBig;
00061 mUSAFonts[ LLFONT_SMALL ] = LLFontGL::sMonospace;
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00124
00125
00126
00127
00128 for( i=0; i<LLFONT_COUNT; i++ )
00129 {
00130 mUKFonts[i] = mUSAFonts[i];
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00142
00143 setLocale( LLLOCALE_USA );
00144
00145 }
00146
00147
00148 void LLResMgr::setLocale( LLLOCALE_ID locale_id )
00149 {
00150 mLocale = locale_id;
00151
00152
00153 switch( locale_id )
00154 {
00155 case LLLOCALE_USA:
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 mFonts = mUSAFonts;
00166 break;
00167 case LLLOCALE_UK:
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 mFonts = mUKFonts;
00178 break;
00179 default:
00180 llassert(0);
00181 setLocale(LLLOCALE_USA);
00182 break;
00183 }
00184 }
00185
00186 char LLResMgr::getDecimalPoint() const
00187 {
00188 char decimal = localeconv()->decimal_point[0];
00189
00190 #if LL_DARWIN
00191
00192 if(decimal == 0)
00193 {
00194 decimal = '.';
00195 }
00196 #endif
00197
00198 return decimal;
00199 }
00200
00201 char LLResMgr::getThousandsSeparator() const
00202 {
00203 char separator = localeconv()->thousands_sep[0];
00204
00205 #if LL_DARWIN
00206
00207 if(separator == 0)
00208 {
00209 separator = ',';
00210 }
00211 #endif
00212
00213 return separator;
00214 }
00215
00216 char LLResMgr::getMonetaryDecimalPoint() const
00217 {
00218 char decimal = localeconv()->mon_decimal_point[0];
00219
00220 #if LL_DARWIN
00221
00222 if(decimal == 0)
00223 {
00224 decimal = '.';
00225 }
00226 #endif
00227
00228 return decimal;
00229 }
00230
00231 char LLResMgr::getMonetaryThousandsSeparator() const
00232 {
00233 char separator = localeconv()->mon_thousands_sep[0];
00234
00235 #if LL_DARWIN
00236
00237 if(separator == 0)
00238 {
00239 separator = ',';
00240 }
00241 #endif
00242
00243 return separator;
00244 }
00245
00246
00247
00248 std::string LLResMgr::getMonetaryString( S32 input ) const
00249 {
00250 std::string output;
00251
00252 LLLocale locale(LLLocale::USER_LOCALE);
00253 struct lconv *conv = localeconv();
00254
00255 #if LL_DARWIN
00256
00257
00258 struct lconv fakeconv;
00259 if(conv->negative_sign[0] == 0)
00260 {
00261 fakeconv = *conv;
00262 switch(mLocale)
00263 {
00264 default:
00265 case LLLOCALE_USA:
00266 case LLLOCALE_UK:
00267 fakeconv.negative_sign = "-";
00268 fakeconv.mon_grouping = "\x03\x03\x00";
00269 fakeconv.n_sign_posn = 1;
00270 break;
00271 }
00272 conv = &fakeconv;
00273 }
00274 #endif
00275
00276 char* negative_sign = conv->negative_sign;
00277 char separator = getMonetaryThousandsSeparator();
00278 char* grouping = conv->mon_grouping;
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 BOOL negative = (input < 0 );
00292 BOOL negative_before = negative && (conv->n_sign_posn != 2);
00293 BOOL negative_after = negative && (conv->n_sign_posn == 2);
00294
00295 LLString digits = llformat("%u", abs(input));
00296 if( !grouping || !grouping[0] )
00297 {
00298 if( negative_before )
00299 {
00300 output.append( negative_sign );
00301 }
00302 output.append( digits );
00303 if( negative_after )
00304 {
00305 output.append( negative_sign );
00306 }
00307 return output;
00308 }
00309
00310 S32 groupings[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
00311 S32 cur_group;
00312 for( cur_group = 0; grouping[ cur_group ]; cur_group++ )
00313 {
00314 if( grouping[ cur_group ] != ';' )
00315 {
00316 groupings[cur_group] = grouping[ cur_group ];
00317 }
00318 cur_group++;
00319
00320 if( groupings[cur_group] < 0 )
00321 {
00322 break;
00323 }
00324 }
00325 S32 group_count = cur_group;
00326
00327 char reversed_output[20] = "";
00328 char forward_output[20] = "";
00329 S32 output_pos = 0;
00330
00331 cur_group = 0;
00332 S32 pos = digits.size()-1;
00333 S32 count_within_group = 0;
00334 while( (pos >= 0) && (groupings[cur_group] >= 0) )
00335 {
00336 count_within_group++;
00337 if( count_within_group > groupings[cur_group] )
00338 {
00339 count_within_group = 1;
00340 reversed_output[ output_pos++ ] = separator;
00341
00342 if( (cur_group + 1) >= group_count )
00343 {
00344 break;
00345 }
00346 else
00347 if( groupings[cur_group + 1] > 0 )
00348 {
00349 cur_group++;
00350 }
00351 }
00352 reversed_output[ output_pos++ ] = digits[pos--];
00353 }
00354
00355 while( pos >= 0 )
00356 {
00357 reversed_output[ output_pos++ ] = digits[pos--];
00358 }
00359
00360
00361 reversed_output[ output_pos ] = '\0';
00362 forward_output[ output_pos ] = '\0';
00363
00364 for( S32 i = 0; i < output_pos; i++ )
00365 {
00366 forward_output[ output_pos - 1 - i ] = reversed_output[ i ];
00367 }
00368
00369 if( negative_before )
00370 {
00371 output.append( negative_sign );
00372 }
00373 output.append( forward_output );
00374 if( negative_after )
00375 {
00376 output.append( negative_sign );
00377 }
00378 return output;
00379 }
00380
00381 void LLResMgr::getIntegerString( LLString& output, S32 input ) const
00382 {
00383 S32 fraction = 0;
00384 LLString fraction_string;
00385 S32 remaining_count = input;
00386 while(remaining_count > 0)
00387 {
00388 fraction = (remaining_count) % 1000;
00389
00390 if (!output.empty())
00391 {
00392 if (fraction == remaining_count)
00393 {
00394 fraction_string = llformat("%d%c", fraction, getThousandsSeparator());
00395 }
00396 else
00397 {
00398 fraction_string = llformat("%3.3d%c", fraction, getThousandsSeparator());
00399 }
00400 output = fraction_string + output;
00401 }
00402 else
00403 {
00404 if (fraction == remaining_count)
00405 {
00406 fraction_string = llformat("%d", fraction);
00407 }
00408 else
00409 {
00410 fraction_string = llformat("%3.3d", fraction);
00411 }
00412 output = fraction_string;
00413 }
00414 remaining_count /= 1000;
00415 }
00416 }
00417
00418 const LLString LLFONT_ID_NAMES[] =
00419 {
00420 LLString("OCRA"),
00421 LLString("SANSSERIF"),
00422 LLString("SANSSERIF_SMALL"),
00423 LLString("SANSSERIF_BIG"),
00424 LLString("SMALL"),
00425 };
00426
00427 const LLFontGL* LLResMgr::getRes( LLString font_id ) const
00428 {
00429 for (S32 i=0; i<LLFONT_COUNT; ++i)
00430 {
00431 if (LLFONT_ID_NAMES[i] == font_id)
00432 {
00433 return getRes((LLFONT_ID)i);
00434 }
00435 }
00436 return NULL;
00437 }
00438
00439 #if LL_WINDOWS
00440 const LLString LLLocale::USER_LOCALE("English_United States.1252");
00441 const LLString LLLocale::SYSTEM_LOCALE("English_United States.1252");
00442 #elif LL_DARWIN
00443 const LLString LLLocale::USER_LOCALE("en_US.iso8859-1");
00444 const LLString LLLocale::SYSTEM_LOCALE("en_US.iso8859-1");
00445 #elif LL_SOLARIS
00446 const LLString LLLocale::USER_LOCALE("en_US.ISO8859-1");
00447 const LLString LLLocale::SYSTEM_LOCALE("C");
00448 #else // LL_LINUX likes this
00449 const LLString LLLocale::USER_LOCALE("en_US.utf8");
00450 const LLString LLLocale::SYSTEM_LOCALE("C");
00451 #endif
00452
00453
00454 LLLocale::LLLocale(const LLString& locale_string)
00455 {
00456 mPrevLocaleString = setlocale( LC_ALL, NULL );
00457 char* new_locale_string = setlocale( LC_ALL, locale_string.c_str());
00458 if ( new_locale_string == NULL)
00459 {
00460 llwarns << "Failed to set locale " << locale_string << llendl;
00461 setlocale(LC_ALL, SYSTEM_LOCALE.c_str());
00462 }
00463
00464
00465
00466
00467 }
00468
00469 LLLocale::~LLLocale()
00470 {
00471 setlocale( LC_ALL, mPrevLocaleString.c_str() );
00472 }