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