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

Generated on Thu Jul 1 06:09:05 2010 for Second Life Viewer by  doxygen 1.4.7