diff options
author | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
commit | 420b91db29485df39fd6e724e782c449158811cb (patch) | |
tree | b471a94563af914d3ed3edd3e856d21cb1b69945 /indra/llui/llresmgr.cpp |
Print done when done.
Diffstat (limited to 'indra/llui/llresmgr.cpp')
-rw-r--r-- | indra/llui/llresmgr.cpp | 447 |
1 files changed, 447 insertions, 0 deletions
diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp new file mode 100644 index 0000000000..67137d8bbb --- /dev/null +++ b/indra/llui/llresmgr.cpp @@ -0,0 +1,447 @@ +/** + * @file llresmgr.cpp + * @brief Localized resource manager + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +// NOTE: this is a MINIMAL implementation. The interface will remain, but the implementation will +// (when the time is right) become dynamic and probably use external files. + +#include "linden_common.h" + +#include "llresmgr.h" +#include "llfontgl.h" +#include "llerror.h" +#include "llstring.h" + +// Global singleton +LLResMgr* gResMgr = NULL; + +LLResMgr::LLResMgr() +{ + U32 i; + + // Init values for each locale. + // Note: This is only the most bare-bones version. In the future, load these dynamically, on demand. + + ////////////////////////////////////////////////////////////////////////////// + // USA + // USA Fonts + for( i=0; i<LLFONT_COUNT; i++ ) + { + mUSAFonts[i] = NULL; + } + mUSAFonts[ LLFONT_OCRA ] = LLFontGL::sMonospace; + mUSAFonts[ LLFONT_SANSSERIF ] = LLFontGL::sSansSerif; + mUSAFonts[ LLFONT_SANSSERIF_SMALL ] = LLFontGL::sSansSerifSmall; + mUSAFonts[ LLFONT_SANSSERIF_BIG ] = LLFontGL::sSansSerifBig; + mUSAFonts[ LLFONT_SMALL ] = LLFontGL::sMonospace; +/* + // USA Strings + for( i=0; i<LLSTR_COUNT; i++ ) + { + mUSAStrings[i] = ""; + } + mUSAStrings[ LLSTR_HELLO ] = "hello"; + mUSAStrings[ LLSTR_GOODBYE ] = "goodbye"; + mUSAStrings[ LLSTR_CHAT_LABEL ] = "Chat"; + mUSAStrings[ LLSTR_STATUS_LABEL ] = "Properties"; + mUSAStrings[ LLSTR_X ] = "X"; + mUSAStrings[ LLSTR_Y ] = "Y"; + mUSAStrings[ LLSTR_Z ] = "Z"; + mUSAStrings[ LLSTR_POSITION ] = "Position (meters)"; + mUSAStrings[ LLSTR_SCALE ] = "Size (meters)"; + mUSAStrings[ LLSTR_ROTATION ] = "Rotation (degrees)"; + mUSAStrings[ LLSTR_HAS_PHYSICS ] = "Has Physics"; + mUSAStrings[ LLSTR_SCRIPT ] = "Script"; + mUSAStrings[ LLSTR_HELP ] = "Help"; + mUSAStrings[ LLSTR_REMOVE ] = "Remove"; + mUSAStrings[ LLSTR_CLEAR ] = "Clear"; + mUSAStrings[ LLSTR_APPLY ] = "Apply"; + mUSAStrings[ LLSTR_CANCEL ] = "Cancel"; + mUSAStrings[ LLSTR_MATERIAL ] = "Material"; + mUSAStrings[ LLSTR_FACE ] = "Face"; + mUSAStrings[ LLSTR_TEXTURE ] = "Texture"; + mUSAStrings[ LLSTR_TEXTURE_SIZE ] = "Repeats per Face"; + mUSAStrings[ LLSTR_TEXTURE_OFFSET ] = "Offset"; + mUSAStrings[ LLSTR_TEXTURE_ROTATION ] = "Rotation (degrees)"; + mUSAStrings[ LLSTR_U ] = "U"; + mUSAStrings[ LLSTR_V ] = "V"; + mUSAStrings[ LLSTR_OWNERSHIP ] = "Ownership"; + mUSAStrings[ LLSTR_PUBLIC ] = "Public"; + mUSAStrings[ LLSTR_PRIVATE ] = "Private"; + mUSAStrings[ LLSTR_REVERT ] = "Revert"; + mUSAStrings[ LLSTR_INSERT_SAMPLE ] = "Insert Sample"; + mUSAStrings[ LLSTR_SET_TEXTURE ] = "Set Texture"; + mUSAStrings[ LLSTR_EDIT_SCRIPT ] = "Edit Script..."; + mUSAStrings[ LLSTR_MOUSELOOK_INSTRUCTIONS ] = "Press ESC to leave Mouselook."; + 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."; + mUSAStrings[ LLSTR_CLOSE ] = "Close"; + mUSAStrings[ LLSTR_MOVE ] = "Move"; + mUSAStrings[ LLSTR_ROTATE ] = "Rotate"; + mUSAStrings[ LLSTR_RESIZE ] = "Resize"; + mUSAStrings[ LLSTR_PLACE_BOX ] = "Place Box"; + mUSAStrings[ LLSTR_PLACE_PRISM ] = "Place Prism"; + mUSAStrings[ LLSTR_PLACE_PYRAMID ] = "Place Pyramid"; + mUSAStrings[ LLSTR_PLACE_TETRAHEDRON ] = "Place Tetrahedron"; + mUSAStrings[ LLSTR_PLACE_CYLINDER ] = "Place Cylinder"; + mUSAStrings[ LLSTR_PLACE_HALF_CYLINDER ] = "Place Half-Cylinder"; + mUSAStrings[ LLSTR_PLACE_CONE ] = "Place Cone"; + mUSAStrings[ LLSTR_PLACE_HALF_CONE ] = "Place Half-Cone"; + mUSAStrings[ LLSTR_PLACE_SPHERE ] = "Place Sphere"; + mUSAStrings[ LLSTR_PLACE_HALF_SPHERE ] = "Place Half-Sphere"; + mUSAStrings[ LLSTR_PLACE_BIRD ] = "Place Bird"; + mUSAStrings[ LLSTR_PLACE_SNAKE ] = "Place Silly Snake"; + mUSAStrings[ LLSTR_PLACE_ROCK ] = "Place Rock"; + mUSAStrings[ LLSTR_PLACE_TREE ] = "Place Tree"; + mUSAStrings[ LLSTR_PLACE_GRASS ] = "Place Grass"; + mUSAStrings[ LLSTR_MODIFY_LAND ] = "Modify Land"; +*/ + ////////////////////////////////////////////////////////////////////////////// + // UK + // The Brits are a lot like us Americans, so initially assume we're the same and only code the exceptions. + + // UK Fonts + for( i=0; i<LLFONT_COUNT; i++ ) + { + mUKFonts[i] = mUSAFonts[i]; + } +/* + // UK Strings + for( i=0; i<LLSTR_COUNT; i++ ) + { + mUKStrings[i] = mUSAStrings[i]; + } + mUKStrings[ LLSTR_HELLO ] = "hullo"; + mUKStrings[ LLSTR_GOODBYE ] = "cheerio"; +*/ + ////////////////////////////////////////////////////////////////////////////// + // Set default + setLocale( LLLOCALE_USA ); + +} + + +void LLResMgr::setLocale( LLLOCALE_ID locale_id ) +{ + mLocale = locale_id; + + //RN: for now, use normal 'C' locale for everything but specific UI input/output routines + switch( locale_id ) + { + case LLLOCALE_USA: +//#if LL_WINDOWS +// // Windows doesn't use ISO country codes. +// llinfos << "Setting locale to " << setlocale( LC_ALL, "english-usa" ) << llendl; +//#else +// // posix version should work everywhere else. +// llinfos << "Setting locale to " << setlocale( LC_ALL, "en_US" ) << llendl; +//#endif + +// mStrings = mUSAStrings; + mFonts = mUSAFonts; + break; + case LLLOCALE_UK: +//#if LL_WINDOWS +// // Windows doesn't use ISO country codes. +// llinfos << "Setting locale to " << setlocale( LC_ALL, "english-uk" ) << llendl; +//#else +// // posix version should work everywhere else. +// llinfos << "Setting locale to " << setlocale( LC_ALL, "en_GB" ) << llendl; +//#endif + +// mStrings = mUKStrings; + mFonts = mUKFonts; + break; + default: + llassert(0); + setLocale(LLLOCALE_USA); + break; + } +} + +char LLResMgr::getDecimalPoint() const +{ + char decimal = localeconv()->decimal_point[0]; + +#if LL_DARWIN + // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped. + if(decimal == 0) + { + decimal = '.'; + } +#endif + + return decimal; +} + +char LLResMgr::getThousandsSeparator() const +{ + char separator = localeconv()->thousands_sep[0]; + +#if LL_DARWIN + // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped. + if(separator == 0) + { + separator = ','; + } +#endif + + return separator; +} + +char LLResMgr::getMonetaryDecimalPoint() const +{ + char decimal = localeconv()->mon_decimal_point[0]; + +#if LL_DARWIN + // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped. + if(decimal == 0) + { + decimal = '.'; + } +#endif + + return decimal; +} + +char LLResMgr::getMonetaryThousandsSeparator() const +{ + char separator = localeconv()->mon_thousands_sep[0]; + +#if LL_DARWIN + // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped. + if(separator == 0) + { + separator = ','; + } +#endif + + return separator; +} + + +// Sets output to a string of integers with monetary separators inserted according to the locale. +void LLResMgr::getMonetaryString( LLString& output, S32 input ) const +{ + LLLocale locale(LLLocale::USER_LOCALE); + struct lconv *conv = localeconv(); + +#if LL_DARWIN + // On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped. + // Fake up a conv structure with some reasonable values for the fields this function uses. + struct lconv fakeconv; + if(conv->negative_sign[0] == 0) // Real locales all seem to have something here... + { + fakeconv = *conv; // start with what's there. + switch(mLocale) + { + default: // Unknown -- use the US defaults. + case LLLOCALE_USA: + case LLLOCALE_UK: // UK ends up being the same as US for the items used here. + fakeconv.negative_sign = "-"; + fakeconv.mon_grouping = "\x03\x03\x00"; // commas every 3 digits + fakeconv.n_sign_posn = 1; // negative sign before the string + break; + } + conv = &fakeconv; + } +#endif + + char* negative_sign = conv->negative_sign; + char separator = getMonetaryThousandsSeparator(); + char* grouping = conv->mon_grouping; + + // Note on mon_grouping: + // Specifies a string that defines the size of each group of digits in formatted monetary quantities. + // The operand for the mon_grouping keyword consists of a sequence of semicolon-separated integers. + // Each integer specifies the number of digits in a group. The initial integer defines the size of + // the group immediately to the left of the decimal delimiter. The following integers define succeeding + // groups to the left of the previous group. If the last integer is not -1, the size of the previous + // group (if any) is repeatedly used for the remainder of the digits. If the last integer is -1, no + // further grouping is performed. + + + // Note: we assume here that the currency symbol goes on the left. (Hey, it's Lindens! We can just decide.) + BOOL negative = (input < 0 ); + BOOL negative_before = negative && (conv->n_sign_posn != 2); + BOOL negative_after = negative && (conv->n_sign_posn == 2); + + LLString digits = llformat("%u", abs(input)); + if( !grouping || !grouping[0] ) + { + output.assign("L$"); + if( negative_before ) + { + output.append( negative_sign ); + } + output.append( digits ); + if( negative_after ) + { + output.append( negative_sign ); + } + return; + } + + S32 groupings[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + S32 cur_group; + for( cur_group = 0; grouping[ cur_group ]; cur_group++ ) + { + if( grouping[ cur_group ] != ';' ) + { + groupings[cur_group] = grouping[ cur_group ]; + } + cur_group++; + + if( groupings[cur_group] < 0 ) + { + break; + } + } + S32 group_count = cur_group; + + char reversed_output[20] = ""; + char forward_output[20] = ""; + S32 output_pos = 0; + + cur_group = 0; + S32 pos = digits.size()-1; + S32 count_within_group = 0; + while( (pos >= 0) && (groupings[cur_group] >= 0) ) + { + count_within_group++; + if( count_within_group > groupings[cur_group] ) + { + count_within_group = 1; + reversed_output[ output_pos++ ] = separator; + + if( (cur_group + 1) >= group_count ) + { + break; + } + else + if( groupings[cur_group + 1] > 0 ) + { + cur_group++; + } + } + reversed_output[ output_pos++ ] = digits[pos--]; + } + + while( pos >= 0 ) + { + reversed_output[ output_pos++ ] = digits[pos--]; + } + + + reversed_output[ output_pos ] = '\0'; + forward_output[ output_pos ] = '\0'; + + for( S32 i = 0; i < output_pos; i++ ) + { + forward_output[ output_pos - 1 - i ] = reversed_output[ i ]; + } + + output.assign("L$"); + if( negative_before ) + { + output.append( negative_sign ); + } + output.append( forward_output ); + if( negative_after ) + { + output.append( negative_sign ); + } +} + +void LLResMgr::getIntegerString( LLString& output, S32 input ) const +{ + S32 fraction = 0; + LLString fraction_string; + S32 remaining_count = input; + while(remaining_count > 0) + { + fraction = (remaining_count) % 1000; + + if (!output.empty()) + { + if (fraction == remaining_count) + { + fraction_string = llformat("%d%c", fraction, getThousandsSeparator()); + } + else + { + fraction_string = llformat("%3.3d%c", fraction, getThousandsSeparator()); + } + output = fraction_string + output; + } + else + { + if (fraction == remaining_count) + { + fraction_string = llformat("%d", fraction); + } + else + { + fraction_string = llformat("%3.3d", fraction); + } + output = fraction_string; + } + remaining_count /= 1000; + } +} + +const LLString LLFONT_ID_NAMES[] = +{ + LLString("OCRA"), + LLString("SANSSERIF"), + LLString("SANSSERIF_SMALL"), + LLString("SANSSERIF_BIG"), + LLString("SMALL"), +}; + +const LLFontGL* LLResMgr::getRes( LLString font_id ) const +{ + for (S32 i=0; i<LLFONT_COUNT; ++i) + { + if (LLFONT_ID_NAMES[i] == font_id) + { + return getRes((LLFONT_ID)i); + } + } + return NULL; +} + +#if LL_WINDOWS +const LLString LLLocale::USER_LOCALE("English_United States.1252");// = LLString::null; +const LLString LLLocale::SYSTEM_LOCALE("English_United States.1252"); +#elif LL_DARWIN +const LLString LLLocale::USER_LOCALE("en_US.iso8859-1");// = LLString::null; +const LLString LLLocale::SYSTEM_LOCALE("en_US.iso8859-1"); +#else // LL_LINUX likes this +const LLString LLLocale::USER_LOCALE("en_US.utf8");// = LLString::null; +const LLString LLLocale::SYSTEM_LOCALE("en_US.utf8"); +#endif + + +LLLocale::LLLocale(const LLString& locale_string) +{ + mPrevLocaleString = setlocale( LC_ALL, NULL ); + char* new_locale_string = setlocale( LC_ALL, locale_string.c_str()); + if ( new_locale_string == NULL) + { + llwarns << "Failed to set locale " << locale_string << llendl; + setlocale(LC_ALL, SYSTEM_LOCALE.c_str()); + } + //else + //{ + // llinfos << "Set locale to " << new_locale_string << llendl; + //} +} + +LLLocale::~LLLocale() +{ + setlocale( LC_ALL, mPrevLocaleString.c_str() ); +} |