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 }