llresmgr.cpp

Go to the documentation of this file.
00001 
00032 // NOTE: this is a MINIMAL implementation.  The interface will remain, but the implementation will
00033 // (when the time is right) become dynamic and probably use external files.
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         // Init values for each locale.
00048         // Note: This is only the most bare-bones version.  In the future, load these dynamically, on demand.
00049 
00051         // USA
00052         // USA Fonts
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         // USA Strings
00064         for( i=0; i<LLSTR_COUNT; i++ )
00065         {
00066                 mUSAStrings[i] = "";
00067         }
00068         mUSAStrings[ LLSTR_HELLO ]                      = "hello";
00069         mUSAStrings[ LLSTR_GOODBYE ]            = "goodbye";
00070         mUSAStrings[ LLSTR_CHAT_LABEL ]         = "Chat";
00071         mUSAStrings[ LLSTR_STATUS_LABEL ]       = "Properties";
00072         mUSAStrings[ LLSTR_X ]                          = "X";
00073         mUSAStrings[ LLSTR_Y ]                          = "Y";
00074         mUSAStrings[ LLSTR_Z ]                          = "Z";
00075         mUSAStrings[ LLSTR_POSITION ]           = "Position (meters)";
00076         mUSAStrings[ LLSTR_SCALE ]                      = "Size (meters)";
00077         mUSAStrings[ LLSTR_ROTATION ]           = "Rotation (degrees)";
00078         mUSAStrings[ LLSTR_HAS_PHYSICS ]        = "Has Physics";
00079         mUSAStrings[ LLSTR_SCRIPT ]                     = "Script";
00080         mUSAStrings[ LLSTR_HELP ]                       = "Help";
00081         mUSAStrings[ LLSTR_REMOVE ]                     = "Remove";
00082         mUSAStrings[ LLSTR_CLEAR ]                      = "Clear";
00083         mUSAStrings[ LLSTR_APPLY ]                      = "Apply";
00084         mUSAStrings[ LLSTR_CANCEL ]                     = "Cancel";
00085         mUSAStrings[ LLSTR_MATERIAL ]           = "Material";
00086         mUSAStrings[ LLSTR_FACE ]                       = "Face";
00087         mUSAStrings[ LLSTR_TEXTURE ]            = "Texture";
00088         mUSAStrings[ LLSTR_TEXTURE_SIZE ]       = "Repeats per Face";
00089         mUSAStrings[ LLSTR_TEXTURE_OFFSET ]     = "Offset";
00090         mUSAStrings[ LLSTR_TEXTURE_ROTATION ]   = "Rotation (degrees)";
00091         mUSAStrings[ LLSTR_U ]                          = "U";
00092         mUSAStrings[ LLSTR_V ]                          = "V";
00093         mUSAStrings[ LLSTR_OWNERSHIP ]          = "Ownership";
00094         mUSAStrings[ LLSTR_PUBLIC ]                     = "Public";
00095         mUSAStrings[ LLSTR_PRIVATE ]            = "Private";
00096         mUSAStrings[ LLSTR_REVERT ]                     = "Revert";
00097         mUSAStrings[ LLSTR_INSERT_SAMPLE ]      = "Insert Sample";
00098         mUSAStrings[ LLSTR_SET_TEXTURE ]        = "Set Texture";
00099         mUSAStrings[ LLSTR_EDIT_SCRIPT ]        = "Edit Script...";
00100         mUSAStrings[ LLSTR_MOUSELOOK_INSTRUCTIONS ] = "Press ESC to leave Mouselook.";
00101         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.";
00102         mUSAStrings[ LLSTR_CLOSE ]                      = "Close";
00103         mUSAStrings[ LLSTR_MOVE ]                       = "Move";
00104         mUSAStrings[ LLSTR_ROTATE ]                     = "Rotate";
00105         mUSAStrings[ LLSTR_RESIZE ]                     = "Resize";
00106         mUSAStrings[ LLSTR_PLACE_BOX ]          = "Place Box";
00107         mUSAStrings[ LLSTR_PLACE_PRISM ]        = "Place Prism";
00108         mUSAStrings[ LLSTR_PLACE_PYRAMID ]      = "Place Pyramid";
00109         mUSAStrings[ LLSTR_PLACE_TETRAHEDRON ]  = "Place Tetrahedron";
00110         mUSAStrings[ LLSTR_PLACE_CYLINDER ]     = "Place Cylinder";
00111         mUSAStrings[ LLSTR_PLACE_HALF_CYLINDER ] = "Place Half-Cylinder";
00112         mUSAStrings[ LLSTR_PLACE_CONE ]         = "Place Cone";
00113         mUSAStrings[ LLSTR_PLACE_HALF_CONE ] = "Place Half-Cone";
00114         mUSAStrings[ LLSTR_PLACE_SPHERE ]       = "Place Sphere";
00115         mUSAStrings[ LLSTR_PLACE_HALF_SPHERE ] = "Place Half-Sphere";
00116         mUSAStrings[ LLSTR_PLACE_BIRD ]         = "Place Bird";
00117         mUSAStrings[ LLSTR_PLACE_SNAKE ]        = "Place Silly Snake";
00118         mUSAStrings[ LLSTR_PLACE_ROCK ]         = "Place Rock";
00119         mUSAStrings[ LLSTR_PLACE_TREE ]         = "Place Tree";
00120         mUSAStrings[ LLSTR_PLACE_GRASS ]        = "Place Grass";
00121         mUSAStrings[ LLSTR_MODIFY_LAND ]        = "Modify Land";
00122 */
00124         // UK
00125         // The Brits are a lot like us Americans, so initially assume we're the same and only code the exceptions.
00126 
00127         // UK Fonts
00128         for( i=0; i<LLFONT_COUNT; i++ )
00129         {
00130                 mUKFonts[i] = mUSAFonts[i];
00131         }
00132 /*
00133         // UK Strings
00134         for( i=0; i<LLSTR_COUNT; i++ )
00135         {
00136                 mUKStrings[i] = mUSAStrings[i];
00137         }
00138         mUKStrings[ LLSTR_HELLO ]                       = "hullo";
00139         mUKStrings[ LLSTR_GOODBYE ]                     = "cheerio";
00140 */
00142         // Set default
00143         setLocale( LLLOCALE_USA );
00144 
00145 }
00146 
00147 
00148 void LLResMgr::setLocale( LLLOCALE_ID locale_id )
00149 {
00150         mLocale = locale_id;
00151 
00152         //RN: for now, use normal 'C' locale for everything but specific UI input/output routines
00153         switch( locale_id )
00154         {
00155         case LLLOCALE_USA: 
00156 //#if LL_WINDOWS
00157 //              // Windows doesn't use ISO country codes.
00158 //              llinfos << "Setting locale to " << setlocale( LC_ALL, "english-usa" ) << llendl;
00159 //#else 
00160 //              // posix version should work everywhere else.
00161 //              llinfos << "Setting locale to " << setlocale( LC_ALL, "en_US" ) << llendl;
00162 //#endif
00163 
00164 //              mStrings        = mUSAStrings;
00165                 mFonts          = mUSAFonts;
00166                 break;
00167         case LLLOCALE_UK:
00168 //#if LL_WINDOWS
00169 //              // Windows doesn't use ISO country codes.
00170 //              llinfos << "Setting locale to " << setlocale( LC_ALL, "english-uk" ) << llendl;
00171 //#else
00172 //              // posix version should work everywhere else.
00173 //              llinfos << "Setting locale to " << setlocale( LC_ALL, "en_GB" ) << llendl;
00174 //#endif
00175 
00176 //              mStrings        = mUKStrings;
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         // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped.
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         // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped.
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         // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped.
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         // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped.
00237         if(separator == 0)
00238         {
00239                 separator = ',';
00240         }
00241 #endif
00242 
00243         return separator;
00244 }
00245 
00246 
00247 // Sets output to a string of integers with monetary separators inserted according to the locale.
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         // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped.
00257         // Fake up a conv structure with some reasonable values for the fields this function uses.
00258         struct lconv fakeconv;
00259         if(conv->negative_sign[0] == 0) // Real locales all seem to have something here...
00260         {
00261                 fakeconv = *conv;       // start with what's there.
00262                 switch(mLocale)
00263                 {
00264                         default:                        // Unknown -- use the US defaults.
00265                         case LLLOCALE_USA: 
00266                         case LLLOCALE_UK:       // UK ends up being the same as US for the items used here.
00267                                 fakeconv.negative_sign = "-";
00268                                 fakeconv.mon_grouping = "\x03\x03\x00"; // commas every 3 digits
00269                                 fakeconv.n_sign_posn = 1; // negative sign before the string
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         // Note on mon_grouping:
00281         // Specifies a string that defines the size of each group of digits in formatted monetary quantities.
00282         // The operand for the mon_grouping keyword consists of a sequence of semicolon-separated integers. 
00283         // Each integer specifies the number of digits in a group. The initial integer defines the size of
00284         // the group immediately to the left of the decimal delimiter. The following integers define succeeding
00285         // groups to the left of the previous group. If the last integer is not -1, the size of the previous
00286         // group (if any) is repeatedly used for the remainder of the digits. If the last integer is -1, no
00287         // further grouping is performed. 
00288 
00289 
00290         // Note: we assume here that the currency symbol goes on the left. (Hey, it's Lindens! We can just decide.)
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] = "";  /* Flawfinder: ignore */
00328         char forward_output[20] = "";   /* Flawfinder: ignore */
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");// = LLString::null;
00441 const LLString LLLocale::SYSTEM_LOCALE("English_United States.1252");
00442 #elif LL_DARWIN
00443 const LLString LLLocale::USER_LOCALE("en_US.iso8859-1");// = LLString::null;
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         //else
00464         //{
00465         //      llinfos << "Set locale to " << new_locale_string << llendl;
00466         //}
00467 }
00468 
00469 LLLocale::~LLLocale() 
00470 {
00471         setlocale( LC_ALL, mPrevLocaleString.c_str() );
00472 }

Generated on Fri May 16 08:32:56 2008 for SecondLife by  doxygen 1.5.5