diff options
57 files changed, 1786 insertions, 431 deletions
| @@ -66,3 +66,4 @@ glob:indra/newview/search_history.txt  glob:indra/newview/filters.xml  glob:indra/newview/avatar_icons_cache.txt  glob:indra/newview/avatar_lad.log +glob:*.diff @@ -207,3 +207,7 @@ bc01ee26fd0f1866e266429e85f76340523e91f1 3.1.0-beta2  ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 DRTVWR-92_3.1.0-release  ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 3.1.0-release  a8230590e28e4f30f5105549e0e43211d9d55711 3.2.0-start +e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1 +e440cd1dfbd128d7d5467019e497f7f803640ad6 3.2.0-beta1 +9bcc2b7176634254e501e3fb4c5b56c1f637852e DRTVWR-97_3.2.0-beta2 +9bcc2b7176634254e501e3fb4c5b56c1f637852e 3.2.0-beta2 diff --git a/doc/contributions.txt b/doc/contributions.txt index 988410701b..d719f64baf 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -480,6 +480,7 @@ Ima Mechanique  	OPEN-50  	OPEN-61  	OPEN-76 +	STORM-959  	STORM-1175  Imnotgoing Sideways  Inma Rau @@ -654,6 +655,8 @@ Lilly Zenovka  Lizzy Macarthur  Luban Yiyuan  Luc Starsider +Luminous Luminos +	STORM-959  Lunita Savira  Maccus McCullough  maciek marksman diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp index 7316717193..62465f9937 100644..100755 --- a/indra/linux_crash_logger/llcrashloggerlinux.cpp +++ b/indra/linux_crash_logger/llcrashloggerlinux.cpp @@ -133,6 +133,12 @@ bool LLCrashLoggerLinux::mainLoop()  	return true;  } +bool LLCrashLoggerLinux::cleanup() +{ +	commonCleanup(); +	return true; +} +  void LLCrashLoggerLinux::updateApplication(const std::string& message)  {  	LLCrashLogger::updateApplication(message); diff --git a/indra/linux_crash_logger/llcrashloggerlinux.h b/indra/linux_crash_logger/llcrashloggerlinux.h index 65d5e4e653..dae6c46651 100644..100755 --- a/indra/linux_crash_logger/llcrashloggerlinux.h +++ b/indra/linux_crash_logger/llcrashloggerlinux.h @@ -39,6 +39,7 @@ public:  	virtual bool mainLoop();  	virtual void updateApplication(const std::string& = LLStringUtil::null);  	virtual void gatherPlatformSpecificFiles(); +	virtual bool cleanup();  };  #endif diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 331a1692ee..3461aa3e6c 100644..100755 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -42,6 +42,7 @@  #include "llpumpio.h"  #include "llhttpclient.h"  #include "llsdserialize.h" +#include "llproxy.h"  LLPumpIO* gServicePump;  BOOL gBreak = false; @@ -428,3 +429,9 @@ bool LLCrashLogger::init()  	return true;  } + +// For cleanup code common to all platforms. +void LLCrashLogger::commonCleanup() +{ +	LLProxy::cleanupClass(); +} diff --git a/indra/llcrashlogger/llcrashlogger.h b/indra/llcrashlogger/llcrashlogger.h index 5d0cb5931c..1510d7e0b3 100644..100755 --- a/indra/llcrashlogger/llcrashlogger.h +++ b/indra/llcrashlogger/llcrashlogger.h @@ -48,7 +48,8 @@ public:  	virtual void updateApplication(const std::string& message = LLStringUtil::null);  	virtual bool init();  	virtual bool mainLoop() = 0; -	virtual bool cleanup() { return true; } +	virtual bool cleanup() = 0; +	void commonCleanup();  	void setUserText(const std::string& text) { mCrashInfo["UserNotes"] = text; }  	S32 getCrashBehavior() { return mCrashBehavior; }  	bool runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout); diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 87de202717..87de202717 100644..100755 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index ceec9c7eb1..c1cd04186b 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -57,6 +57,22 @@ LLKeywords::LLKeywords() : mLoaded(FALSE)  {  } +inline BOOL LLKeywordToken::isTail(const llwchar* s) const +{ +	BOOL res = TRUE; +	const llwchar* t = mDelimiter.c_str(); +	S32 len = mDelimiter.size(); +	for (S32 i=0; i<len; i++) +	{ +		if (s[i] != t[i]) +		{ +			res = FALSE; +			break; +		} +	} +	return res; +} +  LLKeywords::~LLKeywords()  {  	std::for_each(mWordTokenMap.begin(), mWordTokenMap.end(), DeletePairedPointer()); @@ -106,6 +122,7 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )  	std::string SOL_LINE("[line ");  	std::string SOL_ONE_SIDED_DELIMITER("[one_sided_delimiter ");  	std::string SOL_TWO_SIDED_DELIMITER("[two_sided_delimiter "); +	std::string SOL_DOUBLE_QUOTATION_MARKS("[double_quotation_marks ");  	LLColor3 cur_color( 1, 0, 0 );  	LLKeywordToken::TOKEN_TYPE cur_type = LLKeywordToken::WORD; @@ -137,6 +154,12 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )  			cur_type = LLKeywordToken::TWO_SIDED_DELIMITER;  			continue;  		} +		else if( line.find(SOL_DOUBLE_QUOTATION_MARKS) == 0 ) +		{ +			cur_color = readColor( line.substr(SOL_DOUBLE_QUOTATION_MARKS.size()) ); +			cur_type = LLKeywordToken::DOUBLE_QUOTATION_MARKS; +			continue; +		}  		else if( line.find(SOL_ONE_SIDED_DELIMITER) == 0 )	  		{  			cur_color = readColor( line.substr(SOL_ONE_SIDED_DELIMITER.size()) ); @@ -154,10 +177,26 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )  		if( !token_buffer.empty() && token_word_iter != word_tokens.end() )  		{ -			// first word is keyword +			// first word is the keyword or a left delimiter  			std::string keyword = (*token_word_iter);  			LLStringUtil::trim(keyword); +			// second word may be a right delimiter +			std::string delimiter; +			if (cur_type == LLKeywordToken::TWO_SIDED_DELIMITER) +			{ +				while (delimiter.length() == 0 && ++token_word_iter != word_tokens.end()) +				{ +					delimiter = *token_word_iter; +					LLStringUtil::trim(delimiter); +				} +			} +			else if (cur_type == LLKeywordToken::DOUBLE_QUOTATION_MARKS) +			{ +				// Closing delimiter is identical to the opening one. +				delimiter = keyword; +			} +  			// following words are tooltip  			std::string tool_tip;  			while (++token_word_iter != word_tokens.end()) @@ -170,11 +209,11 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )  			{  				// Replace : with \n for multi-line tool tips.  				LLStringUtil::replaceChar( tool_tip, ':', '\n' ); -				addToken(cur_type, keyword, cur_color, tool_tip ); +				addToken(cur_type, keyword, cur_color, tool_tip, delimiter );  			}  			else  			{ -				addToken(cur_type, keyword, cur_color, LLStringUtil::null ); +				addToken(cur_type, keyword, cur_color, LLStringUtil::null, delimiter );  			}  		}  	} @@ -189,23 +228,26 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )  void LLKeywords::addToken(LLKeywordToken::TOKEN_TYPE type,  						  const std::string& key_in,  						  const LLColor3& color, -						  const std::string& tool_tip_in ) +						  const std::string& tool_tip_in, +						  const std::string& delimiter_in)  {  	LLWString key = utf8str_to_wstring(key_in);  	LLWString tool_tip = utf8str_to_wstring(tool_tip_in); +	LLWString delimiter = utf8str_to_wstring(delimiter_in);  	switch(type)  	{  	case LLKeywordToken::WORD: -		mWordTokenMap[key] = new LLKeywordToken(type, color, key, tool_tip); +		mWordTokenMap[key] = new LLKeywordToken(type, color, key, tool_tip, LLWStringUtil::null);  		break;  	case LLKeywordToken::LINE: -		mLineTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip)); +		mLineTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip, LLWStringUtil::null));  		break;  	case LLKeywordToken::TWO_SIDED_DELIMITER: +	case LLKeywordToken::DOUBLE_QUOTATION_MARKS:  	case LLKeywordToken::ONE_SIDED_DELIMITER: -		mDelimiterTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip)); +		mDelimiterTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip, delimiter));  		break;  	default: @@ -357,7 +399,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  			}  			// cur is now at the first non-whitespace character of a new line	 -		 +  			// Line start tokens  			{  				BOOL line_done = FALSE; @@ -418,14 +460,15 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  					S32 seg_end = 0;  					seg_start = cur - base; -					cur += cur_delimiter->getLength(); +					cur += cur_delimiter->getLengthHead(); -					if( cur_delimiter->getType() == LLKeywordToken::TWO_SIDED_DELIMITER ) +					LLKeywordToken::TOKEN_TYPE type = cur_delimiter->getType(); +					if( type == LLKeywordToken::TWO_SIDED_DELIMITER || type == LLKeywordToken::DOUBLE_QUOTATION_MARKS )  					{ -						while( *cur && !cur_delimiter->isHead(cur)) +						while( *cur && !cur_delimiter->isTail(cur))  						{  							// Check for an escape sequence. -							if (*cur == '\\') +							if (type == LLKeywordToken::DOUBLE_QUOTATION_MARKS && *cur == '\\')  							{  								// Count the number of backslashes.  								S32 num_backslashes = 0; @@ -435,10 +478,10 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  									between_delimiters++;  									cur++;  								} -								// Is the next character the end delimiter? -								if (cur_delimiter->isHead(cur)) +								// If the next character is the end delimiter? +								if (cur_delimiter->isTail(cur))  								{ -									// Is there was an odd number of backslashes, then this delimiter +									// If there was an odd number of backslashes, then this delimiter  									// does not end the sequence.  									if (num_backslashes % 2 == 1)  									{ @@ -461,13 +504,13 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  						if( *cur )  						{ -							cur += cur_delimiter->getLength(); -							seg_end = seg_start + between_delimiters + 2 * cur_delimiter->getLength(); +							cur += cur_delimiter->getLengthHead(); +							seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead() + cur_delimiter->getLengthTail();  						}  						else  						{  							// eof -							seg_end = seg_start + between_delimiters + cur_delimiter->getLength(); +							seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();  						}  					}  					else @@ -479,7 +522,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  							between_delimiters++;  							cur++;  						} -						seg_end = seg_start + between_delimiters + cur_delimiter->getLength(); +						seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();  					}  					insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, defaultColor, editor); diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h index f6d75b7e75..d050cd7d7c 100644 --- a/indra/llui/llkeywords.h +++ b/indra/llui/llkeywords.h @@ -41,23 +41,44 @@ typedef LLPointer<LLTextSegment> LLTextSegmentPtr;  class LLKeywordToken  {  public: -	enum TOKEN_TYPE { WORD, LINE, TWO_SIDED_DELIMITER, ONE_SIDED_DELIMITER }; +	/**  +	 * @brief Types of tokens/delimters being parsed. +	 * +	 * @desc Tokens/delimiters that need to be identified/highlighted. All are terminated if an EOF is encountered. +	 * - WORD are keywords in the normal sense, i.e. constants, events, etc. +	 * - LINE are for entire lines (currently only flow control labels use this). +	 * - ONE_SIDED_DELIMITER are for open-ended delimiters which are terminated by EOL. +	 * - TWO_SIDED_DELIMITER are for delimiters that end with a different delimiter than they open with. +	 * - DOUBLE_QUOTATION_MARKS are for delimiting areas using the same delimiter to open and close. +	 */ +	typedef enum TOKEN_TYPE +	{ +		WORD, +		LINE, +		TWO_SIDED_DELIMITER, +		ONE_SIDED_DELIMITER, +		DOUBLE_QUOTATION_MARKS +	}; -	LLKeywordToken( TOKEN_TYPE type, const LLColor3& color, const LLWString& token, const LLWString& tool_tip )  +	LLKeywordToken( TOKEN_TYPE type, const LLColor3& color, const LLWString& token, const LLWString& tool_tip, const LLWString& delimiter  )   		:  		mType( type ),  		mToken( token ),  		mColor( color ), -		mToolTip( tool_tip ) +		mToolTip( tool_tip ), +		mDelimiter( delimiter )		// right delimiter  	{  	} -	S32					getLength() const		{ return mToken.size(); } +	S32					getLengthHead() const	{ return mToken.size(); } +	S32					getLengthTail() const	{ return mDelimiter.size(); }  	BOOL				isHead(const llwchar* s) const; +	BOOL				isTail(const llwchar* s) const;  	const LLWString&	getToken() const		{ return mToken; }  	const LLColor3&		getColor() const		{ return mColor; }  	TOKEN_TYPE			getType()  const		{ return mType; }  	const LLWString&	getToolTip() const		{ return mToolTip; } +	const LLWString&	getDelimiter() const	{ return mDelimiter; }  #ifdef _DEBUG  	void		dump(); @@ -68,6 +89,7 @@ private:  	LLWString	mToken;  	LLColor3	mColor;  	LLWString	mToolTip; +	LLWString	mDelimiter;  };  class LLKeywords @@ -85,7 +107,8 @@ public:  	void addToken(LLKeywordToken::TOKEN_TYPE type,  					const std::string& key,  					const LLColor3& color, -					const std::string& tool_tip = LLStringUtil::null); +					const std::string& tool_tip = LLStringUtil::null, +					const std::string& delimiter = LLStringUtil::null);  	// This class is here as a performance optimization.  	// The word token map used to be defined as std::map<LLWString, LLKeywordToken*>. diff --git a/indra/mac_crash_logger/llcrashloggermac.cpp b/indra/mac_crash_logger/llcrashloggermac.cpp index b555e92b96..8f1c1a2dd0 100644..100755 --- a/indra/mac_crash_logger/llcrashloggermac.cpp +++ b/indra/mac_crash_logger/llcrashloggermac.cpp @@ -249,5 +249,6 @@ void LLCrashLoggerMac::updateApplication(const std::string& message)  bool LLCrashLoggerMac::cleanup()  { +	commonCleanup();  	return true;  } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7288bf6933..bef775cdb8 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -241,6 +241,7 @@ set(viewer_SOURCE_FILES      llfloatertopobjects.cpp      llfloatertos.cpp      llfloatertoybox.cpp +    llfloatertranslationsettings.cpp      llfloateruipreview.cpp      llfloaterurlentry.cpp      llfloatervoiceeffect.cpp @@ -807,6 +808,7 @@ set(viewer_HEADER_FILES      llfloatertopobjects.h      llfloatertos.h      llfloatertoybox.h +    llfloatertranslationsettings.h      llfloateruipreview.h      llfloaterurlentry.h      llfloatervoiceeffect.h @@ -1987,12 +1989,19 @@ if (LL_TESTS)      llmediadataclient.cpp      lllogininstance.cpp      llremoteparcelrequest.cpp +    lltranslate.cpp      llviewerhelputil.cpp      llversioninfo.cpp      llworldmap.cpp      llworldmipmap.cpp    ) +  set_source_files_properties( +    lltranslate.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_LIBRARIES "${JSONCPP_LIBRARIES}" +  ) +    ##################################################    # DISABLING PRECOMPILED HEADERS USAGE FOR TESTS    ################################################## diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index b5f105439c..82b43432eb 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -603,9 +603,11 @@ return				Leave current function or event handler  # Comment  [one_sided_delimiter .8, .3, .15]  //					Comment:Non-functional commentary or disabled code +[two_sided_delimiter .8, .3, .15] +/* */				Comment:Non-functional commentary or disabled code  # String literals -[two_sided_delimiter 0, .2, 0] +[double_quotation_marks 0, .2, 0]  "					String literal  #functions are supplied by the program now diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 3771222455..5c0ea2f774 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11014,6 +11014,39 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>TranslationService</key> +    <map> +      <key>Comment</key> +      <string>Translation API to use. (google|bing)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string>bing</string> +    </map> +    <key>GoogleTranslateAPIKey</key> +    <map> +      <key>Comment</key> +      <string>Google Translate API key</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string></string> +    </map> +    <key>BingTranslateAPIKey</key> +    <map> +      <key>Comment</key> +      <string>Bing AppID to use with the Microsoft Translator API</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string></string> +    </map>      <key>TutorialURL</key>      <map>        <key>Comment</key> diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 5d6b10c047..6641c80b94 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -393,7 +393,26 @@         max_attachment_offset="2.0"         visible_in_first_person="true" /> - +    <attachment_point +       id="39" +       group="9" +       pie_slice="1" +       name="Neck" +       joint="mNeck" +       position="0 0 0" +       rotation="0 0 0" +       visible_in_first_person="true" /> +  	 +  	<attachment_point +       id="40" +       group="9" +       pie_slice="2" +       name="Avatar Center" +       joint="mRoot" +       position="0 0 0" +       rotation="0 0 0" +       visible_in_first_person="true" /> +  	      <param         id="32"         group="1" diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 9ad313a9a7..9ad313a9a7 100644..100755 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ecfd101eeb..dc88c81d6a 100644..100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2825,48 +2825,15 @@ void LLAppViewer::initUpdater()  void LLAppViewer::checkForCrash(void)  { -      #if LL_SEND_CRASH_REPORTS  	if (gLastExecEvent == LAST_EXEC_FROZE)      { -        llinfos << "Last execution froze, requesting to send crash report." << llendl; -        // -        // Pop up a freeze or crash warning dialog -        // -        S32 choice; -	const S32 cb = gCrashSettings.getS32("CrashSubmitBehavior"); -        if(cb == CRASH_BEHAVIOR_ASK) -        { -            std::ostringstream msg; -			msg << LLTrans::getString("MBFrozenCrashed"); -			std::string alert = LLTrans::getString("APP_NAME") + " " + LLTrans::getString("MBAlert"); -            choice = OSMessageBox(msg.str(), -                                  alert, -                                  OSMB_YESNO); -        }  -        else if(cb == CRASH_BEHAVIOR_NEVER_SEND) -        { -            choice = OSBTN_NO; -        } -        else -        { -            choice = OSBTN_YES; -        } - -        if (OSBTN_YES == choice) -        { -            llinfos << "Sending crash report." << llendl; +        llinfos << "Last execution froze, sending a crash report." << llendl; -            bool report_freeze = true; -            handleCrashReporting(report_freeze); -        } -        else -        { -            llinfos << "Not sending crash report." << llendl; -        } +		bool report_freeze = true; +		handleCrashReporting(report_freeze);      }  #endif // LL_SEND_CRASH_REPORTS     -      }  // diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 22f500ba15..83fb887d81 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -384,6 +384,9 @@ void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url)  	// Render the LLSD from getInfo() as a format_map_t  	LLStringUtil::format_map_t args; +	// allow the "Release Notes" URL label to be localized +	args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes"); +  	for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap());  		 ii != iend; ++ii)  	{ diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 5fdeb46daa..a333989e7e 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -345,6 +345,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)  	mCommitCallbackRegistrar.add("Pref.MaturitySettings",		boost::bind(&LLFloaterPreference::onChangeMaturity, this));  	mCommitCallbackRegistrar.add("Pref.BlockList",				boost::bind(&LLFloaterPreference::onClickBlockList, this));  	mCommitCallbackRegistrar.add("Pref.Proxy",					boost::bind(&LLFloaterPreference::onClickProxySettings, this)); +	mCommitCallbackRegistrar.add("Pref.TranslationSettings",	boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));  	sSkin = gSavedSettings.getString("SkinCurrent"); @@ -599,6 +600,9 @@ void LLFloaterPreference::cancel()  	}  	// hide joystick pref floater  	LLFloaterReg::hideInstance("pref_joystick"); + +	// hide translation settings floater +	LLFloaterReg::hideInstance("prefs_translation");  	// cancel hardware menu  	LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings"); @@ -1505,6 +1509,11 @@ void LLFloaterPreference::onClickProxySettings()  	LLFloaterReg::showInstance("prefs_proxy");  } +void LLFloaterPreference::onClickTranslationSettings() +{ +	LLFloaterReg::showInstance("prefs_translation"); +} +  void LLFloaterPreference::onClickActionChange()  {  	mClickActionDirty = true; diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 5c74e9f60c..7ee3294478 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -156,6 +156,7 @@ public:  	void onChangeMaturity();  	void onClickBlockList();  	void onClickProxySettings(); +	void onClickTranslationSettings();  	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);  	void getUIColor(LLUICtrl* ctrl, const LLSD& param); diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp new file mode 100644 index 0000000000..959edff713 --- /dev/null +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -0,0 +1,296 @@ +/**  + * @file llfloatertranslationsettings.cpp + * @brief Machine translation settings for chat + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatertranslationsettings.h" + +// Viewer includes +#include "lltranslate.h" +#include "llviewercontrol.h" // for gSavedSettings + +// Linden library includes +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfloaterreg.h" +#include "lllineeditor.h" +#include "llnotificationsutil.h" +#include "llradiogroup.h" + +class EnteredKeyVerifier : public LLTranslate::KeyVerificationReceiver +{ +public: +	EnteredKeyVerifier(LLTranslate::EService service, bool alert) +	:	LLTranslate::KeyVerificationReceiver(service) +	,	mAlert(alert) +	{ +	} + +private: +	/*virtual*/ void setVerificationStatus(bool ok) +	{ +		LLFloaterTranslationSettings* floater = +			LLFloaterReg::getTypedInstance<LLFloaterTranslationSettings>("prefs_translation"); + +		if (!floater) +		{ +			llwarns << "Cannot find translation settings floater" << llendl; +			return; +		} + +		switch (getService()) +		{ +		case LLTranslate::SERVICE_BING: +			floater->setBingVerified(ok, mAlert); +			break; +		case LLTranslate::SERVICE_GOOGLE: +			floater->setGoogleVerified(ok, mAlert); +			break; +		} +	} + +	bool mAlert; +}; + +LLFloaterTranslationSettings::LLFloaterTranslationSettings(const LLSD& key) +:	LLFloater(key) +,	mMachineTranslationCB(NULL) +,	mLanguageCombo(NULL) +,	mTranslationServiceRadioGroup(NULL) +,	mBingAPIKeyEditor(NULL) +,	mGoogleAPIKeyEditor(NULL) +,	mBingVerifyBtn(NULL) +,	mGoogleVerifyBtn(NULL) +,	mOKBtn(NULL) +,	mBingKeyVerified(false) +,	mGoogleKeyVerified(false) +{ +} + +// virtual +BOOL LLFloaterTranslationSettings::postBuild() +{ +	mMachineTranslationCB = getChild<LLCheckBoxCtrl>("translate_chat_checkbox"); +	mLanguageCombo = getChild<LLComboBox>("translate_language_combo"); +	mTranslationServiceRadioGroup = getChild<LLRadioGroup>("translation_service_rg"); +	mBingAPIKeyEditor = getChild<LLLineEditor>("bing_api_key"); +	mGoogleAPIKeyEditor = getChild<LLLineEditor>("google_api_key"); +	mBingVerifyBtn = getChild<LLButton>("verify_bing_api_key_btn"); +	mGoogleVerifyBtn = getChild<LLButton>("verify_google_api_key_btn"); +	mOKBtn = getChild<LLButton>("ok_btn"); + +	mMachineTranslationCB->setCommitCallback(boost::bind(&LLFloaterTranslationSettings::updateControlsEnabledState, this)); +	mTranslationServiceRadioGroup->setCommitCallback(boost::bind(&LLFloaterTranslationSettings::updateControlsEnabledState, this)); +	mOKBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnOK, this)); +	getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloater::closeFloater, this, false)); +	mBingVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnBingVerify, this)); +	mGoogleVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnGoogleVerify, this)); + +	mBingAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1)); +	mBingAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onBingKeyEdited, this), NULL); +	mGoogleAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1)); +	mGoogleAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onGoogleKeyEdited, this), NULL); + +	center(); +	return TRUE; +} + +// virtual +void LLFloaterTranslationSettings::onOpen(const LLSD& key) +{ +	mMachineTranslationCB->setValue(gSavedSettings.getBOOL("TranslateChat")); +	mLanguageCombo->setSelectedByValue(gSavedSettings.getString("TranslateLanguage"), TRUE); +	mTranslationServiceRadioGroup->setSelectedByValue(gSavedSettings.getString("TranslationService"), TRUE); + +	std::string bing_key = gSavedSettings.getString("BingTranslateAPIKey"); +	if (!bing_key.empty()) +	{ +		mBingAPIKeyEditor->setText(bing_key); +		mBingAPIKeyEditor->setTentative(FALSE); +		verifyKey(LLTranslate::SERVICE_BING, bing_key, false); +	} +	else +	{ +		mBingAPIKeyEditor->setTentative(TRUE); +		mBingKeyVerified = FALSE; +	} + +	std::string google_key = gSavedSettings.getString("GoogleTranslateAPIKey"); +	if (!google_key.empty()) +	{ +		mGoogleAPIKeyEditor->setText(google_key); +		mGoogleAPIKeyEditor->setTentative(FALSE); +		verifyKey(LLTranslate::SERVICE_GOOGLE, google_key, false); +	} +	else +	{ +		mGoogleAPIKeyEditor->setTentative(TRUE); +		mGoogleKeyVerified = FALSE; +	} + +	updateControlsEnabledState(); +} + +void LLFloaterTranslationSettings::setBingVerified(bool ok, bool alert) +{ +	if (alert) +	{ +		showAlert(ok ? "bing_api_key_verified" : "bing_api_key_not_verified"); +	} + +	mBingKeyVerified = ok; +	updateControlsEnabledState(); +} + +void LLFloaterTranslationSettings::setGoogleVerified(bool ok, bool alert) +{ +	if (alert) +	{ +		showAlert(ok ? "google_api_key_verified" : "google_api_key_not_verified"); +	} + +	mGoogleKeyVerified = ok; +	updateControlsEnabledState(); +} + +std::string LLFloaterTranslationSettings::getSelectedService() const +{ +	return mTranslationServiceRadioGroup->getSelectedValue().asString(); +} + +std::string LLFloaterTranslationSettings::getEnteredBingKey() const +{ +	return mBingAPIKeyEditor->getTentative() ? LLStringUtil::null : mBingAPIKeyEditor->getText(); +} + +std::string LLFloaterTranslationSettings::getEnteredGoogleKey() const +{ +	return mGoogleAPIKeyEditor->getTentative() ? LLStringUtil::null : mGoogleAPIKeyEditor->getText(); +} + +void LLFloaterTranslationSettings::showAlert(const std::string& msg_name) const +{ +	LLSD args; +	args["MESSAGE"] = getString(msg_name); +	LLNotificationsUtil::add("GenericAlert", args); +} + +void LLFloaterTranslationSettings::updateControlsEnabledState() +{ +	// Enable/disable controls based on the checkbox value. +	bool on = mMachineTranslationCB->getValue().asBoolean(); +	std::string service = getSelectedService(); +	bool bing_selected = service == "bing"; +	bool google_selected = service == "google"; + +	mTranslationServiceRadioGroup->setEnabled(on); +	mLanguageCombo->setEnabled(on); + +	getChild<LLTextBox>("bing_api_key_label")->setEnabled(on); +	mBingAPIKeyEditor->setEnabled(on); + +	getChild<LLTextBox>("google_api_key_label")->setEnabled(on); +	mGoogleAPIKeyEditor->setEnabled(on); + +	mBingAPIKeyEditor->setEnabled(on && bing_selected); +	mGoogleAPIKeyEditor->setEnabled(on && google_selected); + +	mBingVerifyBtn->setEnabled(on && bing_selected && +		!mBingKeyVerified && !getEnteredBingKey().empty()); +	mGoogleVerifyBtn->setEnabled(on && google_selected && +		!mGoogleKeyVerified && !getEnteredGoogleKey().empty()); + +	mOKBtn->setEnabled( +		!on || ( +		(bing_selected && mBingKeyVerified) || +		(google_selected && mGoogleKeyVerified) +	)); +} + +void LLFloaterTranslationSettings::verifyKey(int service, const std::string& key, bool alert) +{ +	LLTranslate::KeyVerificationReceiverPtr receiver = +		new EnteredKeyVerifier((LLTranslate::EService) service, alert); +	LLTranslate::verifyKey(receiver, key); +} + +void LLFloaterTranslationSettings::onEditorFocused(LLFocusableElement* control) +{ +	LLLineEditor* editor = dynamic_cast<LLLineEditor*>(control); +	if (editor && editor->hasTabStop()) // if enabled. getEnabled() doesn't work +	{ +		if (editor->getTentative()) +		{ +			editor->setText(LLStringUtil::null); +			editor->setTentative(FALSE); +		} +	} +} + +void LLFloaterTranslationSettings::onBingKeyEdited() +{ +	if (mBingAPIKeyEditor->isDirty()) +	{ +		setBingVerified(false, false); +	} +} + +void LLFloaterTranslationSettings::onGoogleKeyEdited() +{ +	if (mGoogleAPIKeyEditor->isDirty()) +	{ +		setGoogleVerified(false, false); +	} +} + +void LLFloaterTranslationSettings::onBtnBingVerify() +{ +	std::string key = getEnteredBingKey(); +	if (!key.empty()) +	{ +		verifyKey(LLTranslate::SERVICE_BING, key); +	} +} + +void LLFloaterTranslationSettings::onBtnGoogleVerify() +{ +	std::string key = getEnteredGoogleKey(); +	if (!key.empty()) +	{ +		verifyKey(LLTranslate::SERVICE_GOOGLE, key); +	} +} + +void LLFloaterTranslationSettings::onBtnOK() +{ +	gSavedSettings.setBOOL("TranslateChat", mMachineTranslationCB->getValue().asBoolean()); +	gSavedSettings.setString("TranslateLanguage", mLanguageCombo->getSelectedValue().asString()); +	gSavedSettings.setString("TranslationService", getSelectedService()); +	gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey()); +	gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey()); +	closeFloater(false); +} diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h new file mode 100644 index 0000000000..9b47ad72ed --- /dev/null +++ b/indra/newview/llfloatertranslationsettings.h @@ -0,0 +1,76 @@ +/**  + * @file llfloatertranslationsettings.h + * @brief Machine translation settings for chat + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERTRANSLATIONSETTINGS_H +#define LL_LLFLOATERTRANSLATIONSETTINGS_H + +#include "llfloater.h" + +class LLButton; +class LLCheckBoxCtrl; +class LLComboBox; +class LLLineEditor; +class LLRadioGroup; + +class LLFloaterTranslationSettings : public LLFloater +{ +public: +	LLFloaterTranslationSettings(const LLSD& key); +	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void onOpen(const LLSD& key); + +	void setBingVerified(bool ok, bool alert); +	void setGoogleVerified(bool ok, bool alert); + +private: +	std::string getSelectedService() const; +	std::string getEnteredBingKey() const; +	std::string getEnteredGoogleKey() const; +	void showAlert(const std::string& msg_name) const; +	void updateControlsEnabledState(); +	void verifyKey(int service, const std::string& key, bool alert = true); + +	void onEditorFocused(LLFocusableElement* control); +	void onBingKeyEdited(); +	void onGoogleKeyEdited(); +	void onBtnBingVerify(); +	void onBtnGoogleVerify(); +	void onBtnOK(); + +	LLCheckBoxCtrl* mMachineTranslationCB; +	LLComboBox* mLanguageCombo; +	LLLineEditor* mBingAPIKeyEditor; +	LLLineEditor* mGoogleAPIKeyEditor; +	LLRadioGroup* mTranslationServiceRadioGroup; +	LLButton* mBingVerifyBtn; +	LLButton* mGoogleVerifyBtn; +	LLButton* mOKBtn; + +	bool mBingKeyVerified; +	bool mGoogleKeyVerified; +}; + +#endif // LL_LLFLOATERTRANSLATIONSETTINGS_H diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index fa3f546157..2b9c113a72 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -240,7 +240,7 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)  	gViewerWindow->setup3DRender();  } -const F32 WIND_ALTITUDE			= 180.f; +const F32 WIND_RELATIVE_ALTITUDE			= 25.f;  void LLWind::renderVectors()  { @@ -254,13 +254,13 @@ void LLWind::renderVectors()  	gGL.pushMatrix();  	LLVector3 origin_agent;  	origin_agent = gAgent.getPosAgentFromGlobal(mOriginGlobal); -	gGL.translatef(origin_agent.mV[VX], origin_agent.mV[VY], WIND_ALTITUDE); +	gGL.translatef(origin_agent.mV[VX], origin_agent.mV[VY], gAgent.getPositionAgent().mV[VZ] + WIND_RELATIVE_ALTITUDE);  	for (j = 0; j < mSize; j++)  	{  		for (i = 0; i < mSize; i++)  		{ -			x = mCloudVelX[i + j*mSize] * WIND_SCALE_HACK; -			y = mCloudVelY[i + j*mSize] * WIND_SCALE_HACK; +			x = mVelX[i + j*mSize] * WIND_SCALE_HACK; +			y = mVelY[i + j*mSize] * WIND_SCALE_HACK;  			gGL.pushMatrix();  			gGL.translatef((F32)i * region_width_meters/mSize, (F32)j * region_width_meters/mSize, 0.0);  			gGL.color3f(0,1,0); diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 3692f67a8d..7eb54271f4 100755..100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -31,50 +31,224 @@  #include <curl/curl.h>  #include "llbufferstream.h" +#include "lltrans.h"  #include "llui.h"  #include "llversioninfo.h"  #include "llviewercontrol.h"  #include "reader.h" -// These two are concatenated with the language specifiers to form a complete Google Translate URL -const char* LLTranslate::m_GoogleURL = "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q="; -const char* LLTranslate::m_GoogleLangSpec = "&langpair="; -float LLTranslate::m_GoogleTimeout = 5; +// virtual +void LLGoogleTranslationHandler::getTranslateURL( +	std::string &url, +	const std::string &from_lang, +	const std::string &to_lang, +	const std::string &text) const +{ +	url = std::string("https://www.googleapis.com/language/translate/v2?key=") +		+ getAPIKey() + "&q=" + LLURI::escape(text) + "&target=" + to_lang; +	if (!from_lang.empty()) +	{ +		url += "&source=" + from_lang; +	} +} + +// virtual +void LLGoogleTranslationHandler::getKeyVerificationURL( +	std::string& url, +	const std::string& key) const +{ +	url = std::string("https://www.googleapis.com/language/translate/v2/languages?key=") +		+ key + "&target=en"; +} + +// virtual +bool LLGoogleTranslationHandler::parseResponse( +	int& status, +	const std::string& body, +	std::string& translation, +	std::string& detected_lang, +	std::string& err_msg) const +{ +	Json::Value root; +	Json::Reader reader; + +	if (!reader.parse(body, root)) +	{ +		err_msg = reader.getFormatedErrorMessages(); +		return false; +	} + +	if (!root.isObject()) // empty response? should not happen +	{ +		return false; +	} + +	if (status != STATUS_OK) +	{ +		// Request failed. Extract error message from the response. +		parseErrorResponse(root, status, err_msg); +		return false; +	} + +	// Request succeeded, extract translation from the response. +	return parseTranslation(root, translation, detected_lang); +} + +// static +void LLGoogleTranslationHandler::parseErrorResponse( +	const Json::Value& root, +	int& status, +	std::string& err_msg) +{ +	const Json::Value& error = root.get("error", 0); +	if (!error.isObject() || !error.isMember("message") || !error.isMember("code")) +	{ +		return; +	} -LLSD LLTranslate::m_Header; -// These constants are for the GET header. -const char* LLTranslate::m_AcceptHeader = "Accept"; -const char* LLTranslate::m_AcceptType = "text/plain"; -const char* LLTranslate::m_AgentHeader = "User-Agent"; +	err_msg = error["message"].asString(); +	status = error["code"].asInt(); +} + +// static +bool LLGoogleTranslationHandler::parseTranslation( +	const Json::Value& root, +	std::string& translation, +	std::string& detected_lang) +{ +	// JsonCpp is prone to aborting the program on failed assertions, +	// so be super-careful and verify the response format. +	const Json::Value& data = root.get("data", 0); +	if (!data.isObject() || !data.isMember("translations")) +	{ +		return false; +	} + +	const Json::Value& translations = data["translations"]; +	if (!translations.isArray() || translations.size() == 0) +	{ +		return false; +	} + +	const Json::Value& first = translations[0U]; +	if (!first.isObject() || !first.isMember("translatedText")) +	{ +		return false; +	} + +	translation = first["translatedText"].asString(); +	detected_lang = first.get("detectedSourceLanguage", "").asString(); +	return true; +} -// These constants are in the JSON returned from Google -const char* LLTranslate::m_GoogleData = "responseData"; -const char* LLTranslate::m_GoogleTranslation = "translatedText"; -const char* LLTranslate::m_GoogleLanguage = "detectedSourceLanguage"; +// static +std::string LLGoogleTranslationHandler::getAPIKey() +{ +	return gSavedSettings.getString("GoogleTranslateAPIKey"); +}  // virtual -void LLTranslate::TranslationReceiver::completedRaw( U32 status, -													 const std::string& reason, -													 const LLChannelDescriptors& channels, -													 const LLIOPipe::buffer_ptr_t& buffer) +void LLBingTranslationHandler::getTranslateURL( +	std::string &url, +	const std::string &from_lang, +	const std::string &to_lang, +	const std::string &text) const  { -	if (200 <= status && status < 300) +	url = std::string("http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=") +		+ getAPIKey() + "&text=" + LLURI::escape(text) + "&to=" + to_lang; +	if (!from_lang.empty())  	{ -		LLBufferStream istr(channels, buffer.get()); -		std::stringstream strstrm; -		strstrm << istr.rdbuf(); +		url += "&from=" + from_lang; +	} +} -		const std::string result = strstrm.str(); -		std::string translation; -		std::string detected_language; +// virtual +void LLBingTranslationHandler::getKeyVerificationURL( +	std::string& url, +	const std::string& key) const +{ +	url = std::string("http://api.microsofttranslator.com/v2/Http.svc/GetLanguagesForTranslate?appId=") +		+ key; +} -		if (!parseGoogleTranslate(result, translation, detected_language)) +// virtual +bool LLBingTranslationHandler::parseResponse( +	int& status, +	const std::string& body, +	std::string& translation, +	std::string& detected_lang, +	std::string& err_msg) const +{ +	if (status != STATUS_OK) +	{ +		static const std::string MSG_BEGIN_MARKER = "Message: "; +		size_t begin = body.find(MSG_BEGIN_MARKER); +		if (begin != std::string::npos) +		{ +			begin += MSG_BEGIN_MARKER.size(); +		} +		else  		{ -			handleFailure(); -			return; +			begin = 0; +			err_msg.clear();  		} -				 +		size_t end = body.find("</p>", begin); +		err_msg = body.substr(begin, end-begin); +		LLStringUtil::replaceString(err_msg, "
", ""); // strip CR +		return false; +	} + +	// Sample response: <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Hola</string> +	size_t begin = body.find(">"); +	if (begin == std::string::npos || begin >= (body.size() - 1)) +	{ +		begin = 0; +	} +	else +	{ +		++begin; +	} + +	size_t end = body.find("</string>", begin); + +	detected_lang = ""; // unsupported by this API +	translation = body.substr(begin, end-begin); +	LLStringUtil::replaceString(translation, "
", ""); // strip CR +	return true; +} + +// static +std::string LLBingTranslationHandler::getAPIKey() +{ +	return gSavedSettings.getString("BingTranslateAPIKey"); +} + +LLTranslate::TranslationReceiver::TranslationReceiver(const std::string& from_lang, const std::string& to_lang) +:	mFromLang(from_lang) +,	mToLang(to_lang) +,	mHandler(LLTranslate::getPreferredHandler()) +{ +} + +// virtual +void LLTranslate::TranslationReceiver::completedRaw( +	U32 http_status, +	const std::string& reason, +	const LLChannelDescriptors& channels, +	const LLIOPipe::buffer_ptr_t& buffer) +{ +	LLBufferStream istr(channels, buffer.get()); +	std::stringstream strstrm; +	strstrm << istr.rdbuf(); + +	const std::string body = strstrm.str(); +	std::string translation, detected_lang, err_msg; +	int status = http_status; +	LL_DEBUGS("Translate") << "HTTP status: " << status << " " << reason << LL_ENDL; +	LL_DEBUGS("Translate") << "Response body: " << body << LL_ENDL; +	if (mHandler.parseResponse(status, body, translation, detected_lang, err_msg)) +	{  		// Fix up the response  		LLStringUtil::replaceString(translation, "<", "<");  		LLStringUtil::replaceString(translation, ">",">"); @@ -83,67 +257,66 @@ void LLTranslate::TranslationReceiver::completedRaw( U32 status,  		LLStringUtil::replaceString(translation, "&","&");  		LLStringUtil::replaceString(translation, "'","'"); -		handleResponse(translation, detected_language); +		handleResponse(translation, detected_lang);  	}  	else  	{ -		LL_WARNS("Translate") << "HTTP request for Google Translate failed with status " << status << ", reason: " << reason << LL_ENDL; -		handleFailure(); +		if (err_msg.empty()) +		{ +			err_msg = LLTrans::getString("TranslationResponseParseError"); +		} + +		llwarns << "Translation request failed: " << err_msg << llendl; +		handleFailure(status, err_msg);  	}  } -//static -void LLTranslate::translateMessage(LLHTTPClient::ResponderPtr &result, const std::string &from_lang, const std::string &to_lang, const std::string &mesg) +LLTranslate::KeyVerificationReceiver::KeyVerificationReceiver(EService service) +:	mService(service)  { -	std::string url; -	getTranslateUrl(url, from_lang, to_lang, mesg); - -    std::string user_agent = llformat("%s %d.%d.%d (%d)", -		LLVersionInfo::getChannel().c_str(), -		LLVersionInfo::getMajor(), -		LLVersionInfo::getMinor(), -		LLVersionInfo::getPatch(), -		LLVersionInfo::getBuild()); +} -	if (!m_Header.size()) -	{ -		m_Header.insert(m_AcceptHeader, LLSD(m_AcceptType)); -		m_Header.insert(m_AgentHeader, LLSD(user_agent)); -	} +LLTranslate::EService LLTranslate::KeyVerificationReceiver::getService() const +{ +	return mService; +} -	LLHTTPClient::get(url, result, m_Header, m_GoogleTimeout); +// virtual +void LLTranslate::KeyVerificationReceiver::completedRaw( +	U32 http_status, +	const std::string& reason, +	const LLChannelDescriptors& channels, +	const LLIOPipe::buffer_ptr_t& buffer) +{ +	bool ok = (http_status == 200); +	setVerificationStatus(ok);  }  //static -void LLTranslate::getTranslateUrl(std::string &translate_url, const std::string &from_lang, const std::string &to_lang, const std::string &mesg) +void LLTranslate::translateMessage( +	TranslationReceiverPtr &receiver, +	const std::string &from_lang, +	const std::string &to_lang, +	const std::string &mesg)  { -	char * curl_str = curl_escape(mesg.c_str(), mesg.size()); -	std::string const escaped_mesg(curl_str); -	curl_free(curl_str); +	std::string url; +	receiver->mHandler.getTranslateURL(url, from_lang, to_lang, mesg); -	translate_url = m_GoogleURL -		+ escaped_mesg + m_GoogleLangSpec -		+ from_lang // 'from' language; empty string for auto -		+ "%7C" // | -		+ to_lang; // 'to' language +	LL_DEBUGS("Translate") << "Sending translation request: " << url << LL_ENDL; +	sendRequest(url, receiver);  } -//static -bool LLTranslate::parseGoogleTranslate(const std::string& body, std::string &translation, std::string &detected_language) +// static +void LLTranslate::verifyKey( +	KeyVerificationReceiverPtr& receiver, +	const std::string& key)  { -	Json::Value root; -	Json::Reader reader; -	 -	bool success = reader.parse(body, root); -	if (!success) -	{ -		LL_WARNS("Translate") << "Non valid response from Google Translate API: '" << reader.getFormatedErrorMessages() << "'" << LL_ENDL; -		return false; -	} -	 -	translation = 			root[m_GoogleData].get(m_GoogleTranslation, "").asString(); -	detected_language = 	root[m_GoogleData].get(m_GoogleLanguage, "").asString(); -	return true; +	std::string url; +	const LLTranslationAPIHandler& handler = getHandler(receiver->getService()); +	handler.getKeyVerificationURL(url, key); + +	LL_DEBUGS("Translate") << "Sending key verification request: " << url << LL_ENDL; +	sendRequest(url, receiver);  }  //static @@ -158,3 +331,52 @@ std::string LLTranslate::getTranslateLanguage()  	return language;  } +// static +const LLTranslationAPIHandler& LLTranslate::getPreferredHandler() +{ +	EService service = SERVICE_BING; + +	std::string service_str = gSavedSettings.getString("TranslationService"); +	if (service_str == "google") +	{ +		service = SERVICE_GOOGLE; +	} + +	return getHandler(service); +} + +// static +const LLTranslationAPIHandler& LLTranslate::getHandler(EService service) +{ +	static LLGoogleTranslationHandler google; +	static LLBingTranslationHandler bing; + +	if (service == SERVICE_GOOGLE) +	{ +		return google; +	} + +	return bing; +} + +// static +void LLTranslate::sendRequest(const std::string& url, LLHTTPClient::ResponderPtr responder) +{ +	static const float REQUEST_TIMEOUT = 5; +	static LLSD sHeader; + +	if (!sHeader.size()) +	{ +	    std::string user_agent = llformat("%s %d.%d.%d (%d)", +			LLVersionInfo::getChannel().c_str(), +			LLVersionInfo::getMajor(), +			LLVersionInfo::getMinor(), +			LLVersionInfo::getPatch(), +			LLVersionInfo::getBuild()); + +		sHeader.insert("Accept", "text/plain"); +		sHeader.insert("User-Agent", user_agent); +	} + +	LLHTTPClient::get(url, responder, sHeader, REQUEST_TIMEOUT); +} diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index c7d6eac33f..c2330daa81 100755..100644 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -30,56 +30,257 @@  #include "llhttpclient.h"  #include "llbufferstream.h" +namespace Json +{ +    class Value; +} + +/** + * Handler of an HTTP machine translation service. + * + * Derived classes know the service URL + * and how to parse the translation result. + */ +class LLTranslationAPIHandler +{ +public: +	/** +	 * Get URL for translation of the given string. +	 * +	 * Sending HTTP GET request to the URL will initiate translation. +	 * +	 * @param[out] url        Place holder for the result. +	 * @param      from_lang  Source language. Leave empty for auto-detection. +	 * @param      to_lang    Target language. +	 * @param      text       Text to translate. +	 */ +	virtual void getTranslateURL( +		std::string &url, +		const std::string &from_lang, +		const std::string &to_lang, +		const std::string &text) const = 0; + +	/** +	 * Get URL to verify the given API key. +	 * +	 * Sending request to the URL verifies the key. +	 * Positive HTTP response (code 200) means that the key is valid. +	 * +	 * @param[out] url  Place holder for the URL. +	 * @param[in]  key  Key to verify. +	 */ +	virtual void getKeyVerificationURL( +		std::string &url, +		const std::string &key) const = 0; + +	/** +	 * Parse translation response. +	 * +	 * @param[in,out] status        HTTP status. May be modified while parsing. +	 * @param         body          Response text. +	 * @param[out]    translation   Translated text. +	 * @param[out]    detected_lang Detected source language. May be empty. +	 * @param[out]    err_msg       Error message (in case of error). +	 */ +	virtual bool parseResponse( +		int& status, +		const std::string& body, +		std::string& translation, +		std::string& detected_lang, +		std::string& err_msg) const = 0; + +	virtual ~LLTranslationAPIHandler() {} + +protected: +	static const int STATUS_OK = 200; +}; + +/// Google Translate v2 API handler. +class LLGoogleTranslationHandler : public LLTranslationAPIHandler +{ +	LOG_CLASS(LLGoogleTranslationHandler); + +public: +	/*virtual*/ void getTranslateURL( +		std::string &url, +		const std::string &from_lang, +		const std::string &to_lang, +		const std::string &text) const; +	/*virtual*/ void getKeyVerificationURL( +		std::string &url, +		const std::string &key) const; +	/*virtual*/ bool parseResponse( +		int& status, +		const std::string& body, +		std::string& translation, +		std::string& detected_lang, +		std::string& err_msg) const; + +private: +	static void parseErrorResponse( +		const Json::Value& root, +		int& status, +		std::string& err_msg); +	static bool parseTranslation( +		const Json::Value& root, +		std::string& translation, +		std::string& detected_lang); +	static std::string getAPIKey(); +}; + +/// Microsoft Translator v2 API handler. +class LLBingTranslationHandler : public LLTranslationAPIHandler +{ +	LOG_CLASS(LLBingTranslationHandler); + +public: +	/*virtual*/ void getTranslateURL( +		std::string &url, +		const std::string &from_lang, +		const std::string &to_lang, +		const std::string &text) const; +	/*virtual*/ void getKeyVerificationURL( +		std::string &url, +		const std::string &key) const; +	/*virtual*/ bool parseResponse( +		int& status, +		const std::string& body, +		std::string& translation, +		std::string& detected_lang, +		std::string& err_msg) const; +private: +	static std::string getAPIKey(); +}; + +/** + * Entry point for machine translation services. + * + * Basically, to translate a string, we need to know the URL + * of a translation service, have a valid API for the service + * and be given the target language. + * + * Callers specify the string to translate and the target language, + * LLTranslate takes care of the rest. + * + * API keys for translation are taken from saved settings. + */  class LLTranslate  {  	LOG_CLASS(LLTranslate); +  public : + +	typedef enum e_service { +		SERVICE_BING, +		SERVICE_GOOGLE, +	} EService; + +	/** +	 * Subclasses are supposed to handle translation results (e.g. show them in chat) +	 */  	class TranslationReceiver: public LLHTTPClient::Responder  	{ +	public: + +		/** +		 * Using mHandler, parse incoming response. +		 * +		 * Calls either handleResponse() or handleFailure() +		 * depending on the HTTP status code and parsing success. +		 * +		 * @see handleResponse() +		 * @see handleFailure() +		 * @see mHandler +		 */ +		/*virtual*/ void completedRaw( +			U32 http_status, +			const std::string& reason, +			const LLChannelDescriptors& channels, +			const LLIOPipe::buffer_ptr_t& buffer); +  	protected: -		TranslationReceiver(const std::string &from_lang, const std::string &to_lang) -			: m_fromLang(from_lang), -			m_toLang(to_lang) -		{ -		} +		friend class LLTranslate; + +		/// Remember source and target languages for subclasses to be able to filter inappropriate results. +		TranslationReceiver(const std::string& from_lang, const std::string& to_lang); +		/// Override point to handle successful translation.  		virtual void handleResponse(const std::string &translation, const std::string &recognized_lang) = 0; -		virtual void handleFailure() = 0; -	public: -		~TranslationReceiver() -		{ -		} +		/// Override point to handle unsuccessful translation. +		virtual void handleFailure(int status, const std::string& err_msg) = 0; + +		std::string mFromLang; +		std::string mToLang; +		const LLTranslationAPIHandler& mHandler; +	}; -		virtual void completedRaw(	U32 status, -									const std::string& reason, -									const LLChannelDescriptors& channels, -									const LLIOPipe::buffer_ptr_t& buffer); +	/** +	 * Subclasses are supposed to handle API key verification result. +	 */ +	class KeyVerificationReceiver: public LLHTTPClient::Responder +	{ +	public: +		EService getService() const;  	protected: -		const std::string m_toLang; -		const std::string m_fromLang; +		/** +		 * Save the translation service the key belongs to. +		 * +		 * Subclasses need to know it. +		 * +		 * @see getService() +		 */ +		KeyVerificationReceiver(EService service); + +		/** +		 * Parse verification response. +		 * +		 * Calls setVerificationStatus() with the verification status, +		 * which is true if HTTP status code is 200. +		 * +		 * @see setVerificationStatus() +		 */ +		/*virtual*/ void completedRaw( +			U32 http_status, +			const std::string& reason, +			const LLChannelDescriptors& channels, +			const LLIOPipe::buffer_ptr_t& buffer); + +		/** +		 * Override point for subclasses to handle key verification status. +		 */ +		virtual void setVerificationStatus(bool ok) = 0; + +		EService mService;  	}; -	static void translateMessage(LLHTTPClient::ResponderPtr &result, const std::string &from_lang, const std::string &to_lang, const std::string &mesg); -	static float m_GoogleTimeout; +	typedef boost::intrusive_ptr<TranslationReceiver> TranslationReceiverPtr; +	typedef boost::intrusive_ptr<KeyVerificationReceiver> KeyVerificationReceiverPtr; + +	/** +	 * Translate given text. +	 * +	 * @param receiver   Object to pass translation result to. +	 * @param from_lang  Source language. Leave empty for auto-detection. +	 * @param to_lang    Target language. +	 * @param mesg       Text to translate. +	 */ +	static void translateMessage(TranslationReceiverPtr &receiver, const std::string &from_lang, const std::string &to_lang, const std::string &mesg); + +	/** +	 * Verify given API key of a translation service. +	 * +	 * @param receiver  Object to pass verification result to. +	 * @param key       Key to verify. +	 */ +	static void verifyKey(KeyVerificationReceiverPtr& receiver, const std::string& key);  	static std::string getTranslateLanguage();  private: -	static void getTranslateUrl(std::string &translate_url, const std::string &from_lang, const std::string &to_lang, const std::string &text); -	static bool parseGoogleTranslate(const std::string& body, std::string &translation, std::string &detected_language); - -	static LLSD m_Header; -	static const char* m_GoogleURL; -	static const char* m_GoogleLangSpec; -	static const char* m_AcceptHeader; -	static const char* m_AcceptType; -	static const char* m_AgentHeader; -	static const char* m_UserAgent; - -	static const char* m_GoogleData; -	static const char* m_GoogleTranslation; -	static const char* m_GoogleLanguage; +	static const LLTranslationAPIHandler& getPreferredHandler(); +	static const LLTranslationAPIHandler& getHandler(EService service); +	static void sendRequest(const std::string& url, LLHTTPClient::ResponderPtr responder);  };  #endif diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index ba53540374..c761969fcf 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -107,6 +107,7 @@  #include "llfloatertos.h"  #include "llfloatertopobjects.h"  #include "llfloatertoybox.h" +#include "llfloatertranslationsettings.h"  #include "llfloateruipreview.h"  #include "llfloatervoiceeffect.h"  #include "llfloaterwhitelistentry.h" @@ -248,6 +249,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);  	LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);  	LLFloaterReg::add("prefs_hardware_settings", "floater_hardware_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHardwareSettings>); +	LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);  	LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>);  	LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);  	LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index e32716eca4..22d95563d8 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -968,6 +968,10 @@ U32 info_display_from_string(std::string info_display)  	{  		return LLPipeline::RENDER_DEBUG_SCULPTED;  	} +	else if ("wind vectors" == info_display) +	{ +		return LLPipeline::RENDER_DEBUG_WIND_VECTORS; +	}  	else  	{  		return 0; @@ -980,6 +984,8 @@ class LLAdvancedToggleInfoDisplay : public view_listener_t  	{  		U32 info_display = info_display_from_string( userdata.asString() ); +		LL_INFOS("ViewerMenu") << "toggle " << userdata.asString() << LL_ENDL; +		  		if ( info_display != 0 )  		{  			LLPipeline::toggleRenderDebug( (void*)info_display ); @@ -997,6 +1003,8 @@ class LLAdvancedCheckInfoDisplay : public view_listener_t  		U32 info_display = info_display_from_string( userdata.asString() );  		bool new_value = false; +		LL_INFOS("ViewerMenu") << "check " << userdata.asString() << LL_ENDL; +  		if ( info_display != 0 )  		{  			new_value = LLPipeline::toggleRenderDebugControl( (void*)info_display ); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 65b569a190..a9ca70fd26 100755..100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3121,7 +3121,7 @@ protected:  	{  		// filter out non-interesting responeses  		if ( !translation.empty() -			&& (m_toLang != detected_language) +			&& (mToLang != detected_language)  			&& (LLStringUtil::compareInsensitive(translation, m_origMesg) != 0) )  		{  			m_chat.mText += " (" + translation + ")"; @@ -3130,10 +3130,13 @@ protected:  		LLNotificationsUI::LLNotificationManager::instance().onChat(m_chat, m_toastArgs);  	} -	void handleFailure() +	void handleFailure(int status, const std::string& err_msg)  	{ -		llwarns << "translation failed for mesg " << m_origMesg << " toLang " << m_toLang << " fromLang " << m_fromLang << llendl; -		m_chat.mText += " (?)"; +		llwarns << "Translation failed for mesg " << m_origMesg << " toLang " << mToLang << " fromLang " << mFromLang << llendl; + +		std::string msg = LLTrans::getString("TranslationFailed", LLSD().with("[REASON]", err_msg)); +		LLStringUtil::replaceString(msg, "\n", " "); // we want one-line error messages +		m_chat.mText += " (" + msg + ")";  		LLNotificationsUI::LLNotificationManager::instance().onChat(m_chat, m_toastArgs);  	} @@ -3371,7 +3374,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  			const std::string from_lang = ""; // leave empty to trigger autodetect  			const std::string to_lang = LLTranslate::getTranslateLanguage(); -			LLHTTPClient::ResponderPtr result = ChatTranslationReceiver::build(from_lang, to_lang, mesg, chat, args); +			LLTranslate::TranslationReceiverPtr result = ChatTranslationReceiver::build(from_lang, to_lang, mesg, chat, args);  			LLTranslate::translateMessage(result, from_lang, to_lang, mesg);  		}  		else diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index d81e67bfe2..d81e67bfe2 100644..100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 380d63c77b..380d63c77b 100644..100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp diff --git a/indra/newview/llwind.cpp b/indra/newview/llwind.cpp index 69d3090442..4c39fb5b74 100644 --- a/indra/newview/llwind.cpp +++ b/indra/newview/llwind.cpp @@ -46,16 +46,12 @@  #include "llworld.h" -const F32 CLOUD_DIVERGENCE_COEF = 0.5f;  - -  //////////////////////////////////////////////////////////////////////  // Construction/Destruction  //////////////////////////////////////////////////////////////////////  LLWind::LLWind() -:	mSize(16), -	mCloudDensityp(NULL) +:	mSize(16)  {  	init();  } @@ -65,8 +61,6 @@ LLWind::~LLWind()  {  	delete [] mVelX;  	delete [] mVelY; -	delete [] mCloudVelX; -	delete [] mCloudVelY;  } @@ -77,31 +71,23 @@ LLWind::~LLWind()  void LLWind::init()  { +	LL_DEBUGS("Wind") << "initializing wind size: "<< mSize << LL_ENDL; +	  	// Initialize vector data  	mVelX = new F32[mSize*mSize];  	mVelY = new F32[mSize*mSize]; -	mCloudVelX = new F32[mSize*mSize]; -	mCloudVelY = new F32[mSize*mSize]; -  	S32 i;  	for (i = 0; i < mSize*mSize; i++)  	{  		mVelX[i] = 0.5f;  		mVelY[i] = 0.5f; -		mCloudVelX[i] = 0.0f; -		mCloudVelY[i] = 0.0f;  	}  }  void LLWind::decompress(LLBitPack &bitpack, LLGroupHeader *group_headerp)  { -	if (!mCloudDensityp) -	{ -		return; -	} -  	LLPatchHeader  patch_header;  	S32 buffer[16*16]; @@ -122,22 +108,15 @@ void LLWind::decompress(LLBitPack &bitpack, LLGroupHeader *group_headerp)  	decode_patch(bitpack, buffer);  	decompress_patch(mVelY, buffer, &patch_header); - -  	S32 i, j, k; -	// HACK -- mCloudVelXY is the same as mVelXY, except we add a divergence -	// that is proportional to the gradient of the cloud density  -	// ==> this helps to clump clouds together -	// NOTE ASSUMPTION: cloud density has the same dimensions as the wind field -	// This needs to be fixed... causes discrepency at region boundaries  	for (j=1; j<mSize-1; j++)  	{  		for (i=1; i<mSize-1; i++)  		{  			k = i + j * mSize; -			*(mCloudVelX + k) = *(mVelX + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + 1) - *(mCloudDensityp + k - 1)); -			*(mCloudVelY + k) = *(mVelY + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + mSize) - *(mCloudDensityp + k - mSize)); +			*(mVelX + k) = *(mVelX + k); +			*(mVelY + k) = *(mVelY + k);  		}  	} @@ -145,29 +124,29 @@ void LLWind::decompress(LLBitPack &bitpack, LLGroupHeader *group_headerp)  	for (j=1; j<mSize-1; j++)  	{  		k = i + j * mSize; -		*(mCloudVelX + k) = *(mVelX + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k) - *(mCloudDensityp + k - 2)); -		*(mCloudVelY + k) = *(mVelY + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + mSize) - *(mCloudDensityp + k - mSize)); +		*(mVelX + k) = *(mVelX + k); +		*(mVelY + k) = *(mVelY + k);  	}  	i = 0;  	for (j=1; j<mSize-1; j++)  	{  		k = i + j * mSize; -		*(mCloudVelX + k) = *(mVelX + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + 2) - *(mCloudDensityp + k)); -		*(mCloudVelY + k) = *(mVelY + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + mSize) - *(mCloudDensityp + k + mSize)); +		*(mVelX + k) = *(mVelX + k); +		*(mVelY + k) = *(mVelY + k);  	}  	j = mSize - 1;  	for (i=1; i<mSize-1; i++)  	{  		k = i + j * mSize; -		*(mCloudVelX + k) = *(mVelX + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + 1) - *(mCloudDensityp + k - 1)); -		*(mCloudVelY + k) = *(mVelY + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k) - *(mCloudDensityp + k - 2*mSize)); +		*(mVelX + k) = *(mVelX + k); +		*(mVelY + k) = *(mVelY + k);  	}  	j = 0;  	for (i=1; i<mSize-1; i++)  	{  		k = i + j * mSize; -		*(mCloudVelX + k) = *(mVelX + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + 1) - *(mCloudDensityp + k -1)); -		*(mCloudVelY + k) = *(mVelY + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + 2*mSize) - *(mCloudDensityp + k)); +		*(mVelX + k) = *(mVelX + k); +		*(mVelY + k) = *(mVelY + k);  	}  } @@ -280,74 +259,6 @@ LLVector3 LLWind::getVelocity(const LLVector3 &pos_region)  	return r_val * WIND_SCALE_HACK;  } - -LLVector3 LLWind::getCloudVelocity(const LLVector3 &pos_region) -{ -	llassert(mSize == 16); -	// Resolves value of wind at a location relative to SW corner of region -	//   -	// Returns wind magnitude in X,Y components of vector3 -	LLVector3 r_val; -	F32 dx,dy; -	S32 k; - -	LLVector3 pos_clamped_region(pos_region); -	 -	F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters(); - -	if (pos_clamped_region.mV[VX] < 0.f) -	{ -		pos_clamped_region.mV[VX] = 0.f; -	} -	else if (pos_clamped_region.mV[VX] >= region_width_meters) -	{ -		pos_clamped_region.mV[VX] = (F32) fmod(pos_clamped_region.mV[VX], region_width_meters); -	} - -	if (pos_clamped_region.mV[VY] < 0.f) -	{ -		pos_clamped_region.mV[VY] = 0.f; -	} -	else if (pos_clamped_region.mV[VY] >= region_width_meters) -	{ -		pos_clamped_region.mV[VY] = (F32) fmod(pos_clamped_region.mV[VY], region_width_meters); -	} -	 -	 -	S32 i = llfloor(pos_clamped_region.mV[VX] * mSize / region_width_meters); -	S32 j = llfloor(pos_clamped_region.mV[VY] * mSize / region_width_meters); -	k = i + j*mSize; -	dx = ((pos_clamped_region.mV[VX] * mSize / region_width_meters) - (F32) i); -	dy = ((pos_clamped_region.mV[VY] * mSize / region_width_meters) - (F32) j); - -	if ((i < mSize-1) && (j < mSize-1)) -	{ -		//  Interior points, no edges -		r_val.mV[VX] =  mCloudVelX[k]*(1.0f - dx)*(1.0f - dy) +  -						mCloudVelX[k + 1]*dx*(1.0f - dy) +  -						mCloudVelX[k + mSize]*dy*(1.0f - dx) +  -						mCloudVelX[k + mSize + 1]*dx*dy; -		r_val.mV[VY] =  mCloudVelY[k]*(1.0f - dx)*(1.0f - dy) +  -						mCloudVelY[k + 1]*dx*(1.0f - dy) +  -						mCloudVelY[k + mSize]*dy*(1.0f - dx) +  -						mCloudVelY[k + mSize + 1]*dx*dy; -	} -	else  -	{ -		r_val.mV[VX] = mCloudVelX[k]; -		r_val.mV[VY] = mCloudVelY[k]; -	} - -	r_val.mV[VZ] = 0.f; -	return r_val * WIND_SCALE_HACK; -} - - -void LLWind::setCloudDensityPointer(F32 *densityp) -{ -	mCloudDensityp = densityp; -} -  void LLWind::setOriginGlobal(const LLVector3d &origin_global)  {  	mOriginGlobal = origin_global; diff --git a/indra/newview/llwind.h b/indra/newview/llwind.h index 925cb6d642..3b57f07124 100644 --- a/indra/newview/llwind.h +++ b/indra/newview/llwind.h @@ -27,7 +27,6 @@  #ifndef LL_LLWIND_H  #define LL_LLWIND_H -//#include "vmath.h"  #include "llmath.h"  #include "v3math.h"  #include "v3dmath.h" @@ -44,25 +43,21 @@ public:  	~LLWind();  	void renderVectors();  	LLVector3 getVelocity(const LLVector3 &location); // "location" is region-local -	LLVector3 getCloudVelocity(const LLVector3 &location); // "location" is region-local  	LLVector3 getVelocityNoisy(const LLVector3 &location, const F32 dim);	// "location" is region-local  	void decompress(LLBitPack &bitpack, LLGroupHeader *group_headerp);  	LLVector3 getAverage(); -	void setCloudDensityPointer(F32 *densityp);  	void setOriginGlobal(const LLVector3d &origin_global);  private:  	S32 mSize;  	F32 * mVelX;  	F32 * mVelY; -	F32 * mCloudVelX; -	F32 * mCloudVelY; -	F32 * mCloudDensityp;  	LLVector3d mOriginGlobal;  	void init(); +	LOG_CLASS(LLWind);  };  #endif diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index a50f66f282..93354e6579 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4383,6 +4383,11 @@ void LLPipeline::renderDebug()  		}  	} +	if (mRenderDebugMask & RENDER_DEBUG_WIND_VECTORS) +	{ +		gAgent.getRegion()->mWind.renderVectors(); +	} +	  	if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION)  	{  		// Debug composition layers diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 27ee2745b5..0661de8cec 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -438,7 +438,7 @@ public:  		RENDER_DEBUG_VERIFY				= 0x0000002,  		RENDER_DEBUG_BBOXES				= 0x0000004,  		RENDER_DEBUG_OCTREE				= 0x0000008, -		RENDER_DEBUG_PICKING			= 0x0000010, +		RENDER_DEBUG_WIND_VECTORS		= 0x0000010,  		RENDER_DEBUG_OCCLUSION			= 0x0000020,  		RENDER_DEBUG_POINTS				= 0x0000040,  		RENDER_DEBUG_TEXTURE_PRIORITY	= 0x0000080, diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml index 0ccaab73ba..fc8bc33096 100644 --- a/indra/newview/skins/default/xui/da/floater_about.xml +++ b/indra/newview/skins/default/xui/da/floater_about.xml @@ -10,7 +10,7 @@  	<floater.string name="AboutPosition">  		Du er ved [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] i regionen [REGION] lokaliseret ved <nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION] -[[SERVER_RELEASE_NOTES_URL] [ReleaseNotes]] +[SERVER_RELEASE_NOTES_URL]  	</floater.string>  	<floater.string name="AboutSystem">  		CPU: [CPU] diff --git a/indra/newview/skins/default/xui/de/inspect_group.xml b/indra/newview/skins/default/xui/de/inspect_group.xml index d85ca7ce4d..60fa8ff0d8 100644 --- a/indra/newview/skins/default/xui/de/inspect_group.xml +++ b/indra/newview/skins/default/xui/de/inspect_group.xml @@ -26,7 +26,7 @@ Hoch solln sie leben!  Elche forever! Und auch Mungos!  	<text name="group_cost">  		Mitgliedschaft: 123 L$  	</text> -	<button label="Zusammen" name="join_btn"/> +	<button label="Beitreten" name="join_btn"/>  	<button label="Verlassen" name="leave_btn"/>  	<button label="Profil anzeigen" name="view_profile_btn"/>  </floater> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_general.xml b/indra/newview/skins/default/xui/de/panel_preferences_general.xml index 5c8b8302c8..979ccba48d 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_general.xml @@ -16,7 +16,7 @@  		<combo_box.item label="Русский (Russisch) – Beta" name="Russian"/>  		<combo_box.item label="Türkçe (Türkisch) – Beta" name="Turkish"/>  		<combo_box.item label="日本語 (Japanisch) - Beta" name="(Japanese)"/> -		<combo_box.item label="正體 (Traditionelles Chinesisch) – Beta" name="Traditional Chinese"/> +		<combo_box.item label="正體中文 (Traditionelles Chinesisch) – Beta" name="Traditional Chinese"/>  	</combo_box>  	<text name="language_textbox2">  		(Erfordert Neustart) diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index fbaf4f0a8a..fbaf4f0a8a 100644..100755 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml new file mode 100644 index 0000000000..c03f751265 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml @@ -0,0 +1,244 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + height="310" + layout="topleft" + name="floater_translation_settings" + help_topic="environment_editor_floater" + save_rect="true" + title="CHAT TRANSLATION SETTINGS" + width="485"> + + <string name="bing_api_key_not_verified">Bing appID not verified. Please try again.</string> + <string name="google_api_key_not_verified">Google API key not verified. Please try again.</string> + + <string name="bing_api_key_verified">Bing appID verified.</string> + <string name="google_api_key_verified">Google API key verified.</string> + + <check_box +  height="16"      +  label="Enable machine translation while chatting" +  layout="topleft" +  left="10" +  name="translate_chat_checkbox" +  top="30" +  width="20" /> + <text +  height="20" +  follows="left|top" +  layout="topleft" +  left="40" +  name="translate_language_label" +  top_pad="20" +  width="130"> +  Translate chat into:  + </text> + <combo_box +  allow_text_entry="true" +  follows="left|top" +  height="23" +  left_pad="10" +  max_chars="135" +  mouse_opaque="true" +  name="translate_language_combo" +  top_delta="-5" +  width="190"> +  <combo_box.item +   label="System Default" +   name="System Default Language" +   value="default" /> +  <combo_box.item +   label="English" +   name="English" +   value="en" /> +  <!-- After "System Default" and "English", please keep the rest of these combo_box.items in alphabetical order by the first character in the string. --> +  <combo_box.item +   label="Dansk (Danish)" +   name="Danish" +   value="da" /> +  <combo_box.item +   label="Deutsch (German)" +   name="German" +   value="de" /> +  <combo_box.item +   label="Español (Spanish)" +   name="Spanish" +   value="es" /> +  <combo_box.item +   label="Français (French)" +   name="French" +   value="fr" /> +  <combo_box.item +   label="Italiano (Italian)" +   name="Italian" +   value="it" /> +  <combo_box.item +   label="Magyar (Hungarian)" +   name="Hungarian" +   value="hu" /> +  <combo_box.item +   label="Nederlands (Dutch)" +   name="Dutch" +   value="nl" /> +  <combo_box.item +   label="Polski (Polish)" +   name="Polish" +   value="pl" /> +  <combo_box.item +   label="Português (Portuguese)" +   name="Portugese" +   value="pt" /> +  <combo_box.item +   label="Русский (Russian)" +   name="Russian" +   value="ru" /> +  <combo_box.item +   label="Türkçe (Turkish)" +   name="Turkish" +   value="tr" /> +  <combo_box.item +   label="Українська (Ukrainian)" +   name="Ukrainian" +   value="uk" /> +  <combo_box.item +   label="中文 (正體) (Chinese)" +   name="Chinese" +   value="zh" /> +  <combo_box.item +   label="日本語 (Japanese)" +   name="Japanese" +   value="ja" /> +  <combo_box.item +   label="한국어 (Korean)" +   name="Korean" +   value="ko" /> + </combo_box> + + <text +  follows="top|left|right" +  height="15" +  layout="topleft" +  left="40" +  name="tip" +  top_pad="20" +  width="330" +  wrap="true"> +  Choose translation service: + </text> + + <radio_group +  follows="top|left" +  height="80" +  layout="topleft" +  left_delta="10" +  name="translation_service_rg" +  top_pad="20" +  width="320"> +  <radio_item +   initial_value="bing" +   label="Bing Translator" +   layout="topleft" +   name="bing" /> +  <radio_item +   initial_value="google" +   label="Google Translate" +   layout="topleft" +   name="google" +   top_pad="55" /> + </radio_group> + + <text +  type="string" +  length="1" +  follows="top|right" +  height="20" +  layout="topleft" +  left="70" +  name="bing_api_key_label" +  top_pad="-55" +  width="85"> +  Bing [http://www.bing.com/developers/createapp.aspx AppID]: +  </text> + <line_editor +  default_text="Enter Bing AppID and click "Verify"" +  follows="top|left" +  height="20" +  layout="topleft" +  left_pad="10" +  max_length_chars="50" +  top_delta="-4" +  name="bing_api_key" +  width="210" /> + <button +  follows="left|top" +  height="23" +  label="Verify" +  layout="topleft" +  left_pad="10" +  name="verify_bing_api_key_btn" +  top_delta="-2" +  width="90" />	 + + <text +  follows="top|right" +  height="20" +  layout="topleft" +  left="70" +  length="1" +  name="google_api_key_label" +  top_pad="50" +  type="string" +  width="85"> +  Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API key]: + </text> + <line_editor +  default_text="Enter Google API key and click "Verify"" +  follows="top|left" +  height="20" +  layout="topleft" +  left_pad="10" +  max_length_chars="50" +  top_delta="-4" +  name="google_api_key" +  width="210" /> + <button +  follows="left|top" +  height="23" +  label="Verify" +  layout="topleft" +  left_pad="10" +  name="verify_google_api_key_btn" +  top_delta="-2" +  width="90" />	 + + <text +  follows="top|right" +  height="20" +  layout="topleft" +  left="185" +  length="1" +  name="google_links_text" +  top_delta="-23" +  type="string" +  width="100"> +  [http://code.google.com/apis/language/translate/v2/pricing.html Pricing] | [https://code.google.com/apis/console Stats]  + </text> + + <button +  follows="left|top" +  height="23" +  label="OK" +  layout="topleft" +  right="-120" +  name="ok_btn" +  top="-30" +  width="100" /> + <button +  follows="left|top" +  height="23" +  label="Cancel" +  layout="topleft" +  left_pad="10" +  name="cancel_btn" +  width="100" />	 +</floater> diff --git a/indra/newview/skins/default/xui/en/inspect_remote_object.xml b/indra/newview/skins/default/xui/en/inspect_remote_object.xml index ef3dd844cd..e83257d2a0 100644 --- a/indra/newview/skins/default/xui/en/inspect_remote_object.xml +++ b/indra/newview/skins/default/xui/en/inspect_remote_object.xml @@ -36,7 +36,7 @@     height="16"     left="8"     name="object_owner_label" -   width="55" +   width="65"     top_pad="12">       Owner:    </text> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 33e705cfd2..9c44d90a6e 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2446,6 +2446,16 @@             parameter="raycast" />          </menu_item_check>  		<menu_item_check +         label="Wind Vectors" +         name="Wind Vectors"> +          <menu_item_check.on_check +           function="Advanced.CheckInfoDisplay" +           parameter="wind vectors" /> +          <menu_item_check.on_click +           function="Advanced.ToggleInfoDisplay" +           parameter="wind vectors" /> +        </menu_item_check> +        <menu_item_check           label="Render Complexity"           name="rendercomplexity">            <menu_item_check.on_check diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml index 52be805260..caf7fc85f5 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml @@ -204,119 +204,16 @@       name="nearby_toasts_fadingtime"       top_pad="3"       width="325" /> -     -    <check_box -     control_name="TranslateChat" -     enabled="true" -     height="16"      -     layout="topleft" -     left="30" -     name="translate_chat_checkbox" -     top_pad="5" -     width="400" /> -     <!-- *HACK  -     	After storm-1109 will be fixed: instead of using this text_box, word_wrap should be applied for "translate_chat_checkbox" check_box's label.--> -     <text -      follows="top|left" -      height="15" -      layout="topleft" -      left="50" -      name="translate_chb_label" -      top_delta="1" -      width="450" -      wrap="true"> -      Use machine translation while chatting (powered by Google) -     </text> -    <text -     top_pad="20" -     name="translate_language_text" -     follows="left|top" -     layout="topleft" -     left_delta="20" -     height="20" -     width="110"> -     Translate chat into:  -    </text> -    <combo_box -     allow_text_entry="true" -     bottom_delta="3" -     control_name="TranslateLanguage" -     enabled="true" -     follows="left|top" -     height="23" -     left_delta="110" -     max_chars="135" -     mouse_opaque="true" -     name="translate_language_combobox" -     width="146"> -        <combo_box.item -         label="System Default" -         name="System Default Language" -         value="default" /> -        <combo_box.item -         label="English" -         name="English" -         value="en" /> -        <!-- After "System Default" and "English", please keep the rest of these combo_box.items in alphabetical order by the first character in the string. --> -        <combo_box.item -         label="Dansk (Danish)" -         name="Danish" -         value="da" /> -        <combo_box.item -         label="Deutsch (German)" -         name="German" -         value="de" /> -        <combo_box.item -         label="Español (Spanish)" -         name="Spanish" -         value="es" /> -        <combo_box.item -         label="Français (French)" -         name="French" -         value="fr" /> -        <combo_box.item -         label="Italiano (Italian)" -         name="Italian" -         value="it" /> -        <combo_box.item -         label="Magyar (Hungarian)" -         name="Hungarian" -         value="hu" /> -        <combo_box.item -         label="Nederlands (Dutch)" -         name="Dutch" -         value="nl" /> -        <combo_box.item -         label="Polski (Polish)" -         name="Polish" -         value="pl" /> -        <combo_box.item -         label="Português (Portuguese)" -         name="Portugese" -         value="pt" /> -        <combo_box.item -         label="Русский (Russian)" -         name="Russian" -         value="ru" /> -        <combo_box.item -         label="Türkçe (Turkish)" -         name="Turkish" -         value="tr" /> -        <combo_box.item -         label="Українська (Ukrainian)" -         name="Ukrainian" -         value="uk" /> -        <combo_box.item -         label="中文 (正體) (Chinese)" -         name="Chinese" -         value="zh" /> -        <combo_box.item -         label="日本語 (Japanese)" -         name="Japanese" -         value="ja" /> -        <combo_box.item -         label="한국어 (Korean)" -         name="Korean" -         value="ko" /> -    </combo_box> +  <button +   follows="left|top" +   height="23" +   label="Chat Translation Settings" +   layout="topleft" +   left="30" +   name="ok_btn" +   top="-40" +   width="170"> +   <button.commit_callback +    function="Pref.TranslationSettings" /> +  </button>  </panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml index 0a1c0872e9..4079a80924 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml @@ -92,7 +92,7 @@           value="ja" />          <combo_box.item           enabled="true" -         label="正體 (Traditional Chinese) - Beta" +         label="正體中文 (Traditional Chinese) - Beta"           name="Traditional Chinese"           value="zh" />      </combo_box> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 084b8f3074..ec230773cc 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2183,6 +2183,8 @@ Returns a string with the requested data about the region  	<string name="Stomach">Stomach</string>  	<string name="Left Pec">Left Pec</string>  	<string name="Right Pec">Right Pec</string> +    <string name="Neck">Neck</string> +    <string name="Avatar Center">Avatar Center</string>  	<string name="Invalid Attachment">Invalid Attachment Point</string>    <!-- Avatar age computation, see LLDateUtil::ageFromDate --> @@ -3529,6 +3531,10 @@ Try enclosing path to the editor with double quotes.   <string name="ExternalEditorCommandParseError">Error parsing the external editor command.</string>   <string name="ExternalEditorFailedToRun">External editor failed to run.</string> + <!--  Machine translation of chat messahes --> + <string name="TranslationFailed">Translation failed: [REASON]</string> + <string name="TranslationResponseParseError">Error parsing translation response.</string> +    <!-- Key names begin -->    <string name="Esc">Esc</string>    <string name="Space">Space</string> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_general.xml b/indra/newview/skins/default/xui/es/panel_preferences_general.xml index 920729bb07..4fc163f5b6 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_general.xml @@ -16,7 +16,7 @@  		<combo_box.item label="Русский (Ruso) - Beta" name="Russian"/>  		<combo_box.item label="Türkçe (Turco) - Beta" name="Turkish"/>  		<combo_box.item label="日本語 (Japonés) - Beta" name="(Japanese)"/> -		<combo_box.item label="正體 (Chino tradicional) - Beta" name="Traditional Chinese"/> +		<combo_box.item label="正體中文 (Chino tradicional) - Beta" name="Traditional Chinese"/>  	</combo_box>  	<text name="language_textbox2">  		(requiere reiniciar) diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml index dd4c1c9f63..66b84af3aa 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml @@ -16,7 +16,7 @@  		<combo_box.item label="Русский (Russe) - Bêta" name="Russian"/>  		<combo_box.item label="Türkçe (Turc) - Bêta" name="Turkish"/>  		<combo_box.item label="日本語 (Japonais) - Bêta" name="(Japanese)"/> -		<combo_box.item label="正體 (Chinois traditionnel) - Bêta" name="Traditional Chinese"/> +		<combo_box.item label="正體中文 (Chinois traditionnel) - Bêta" name="Traditional Chinese"/>  	</combo_box>  	<text name="language_textbox2">  		(redémarrage requis) diff --git a/indra/newview/skins/default/xui/it/panel_preferences_general.xml b/indra/newview/skins/default/xui/it/panel_preferences_general.xml index 4f52105404..90a833471c 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_general.xml @@ -16,7 +16,7 @@  		<combo_box.item label="Русский (Russo) - Beta" name="Russian"/>  		<combo_box.item label="Türkçe (Turco) - Beta" name="Turkish"/>  		<combo_box.item label="日本語 (Giapponese) - Beta" name="(Japanese)"/> -		<combo_box.item label="正體 (Cinese tradizionale) - Beta" name="Traditional Chinese"/> +		<combo_box.item label="正體中文 (Cinese tradizionale) - Beta" name="Traditional Chinese"/>  	</combo_box>  	<text name="language_textbox2">  		(Richiede il riavvio) diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml index 51db95735b..1bafa52fbe 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml @@ -13,10 +13,10 @@  		<combo_box.item label="Italiano (イタリア語) - ベータ" name="Italian"/>  		<combo_box.item label="Polski (ポーランド語) - ベータ" name="Polish"/>  		<combo_box.item label="Português(ポルトガル語) - ベータ" name="Portugese"/> -		<combo_box.item label="Русский (Russian) - Beta" name="Russian"/> -		<combo_box.item label="Türkçe (Turkish) - Beta" name="Turkish"/> +		<combo_box.item label="Русский (ロシア語) - ベータ" name="Russian"/> +		<combo_box.item label="Türkçe (トルコ語) - ベータ" name="Turkish"/>  		<combo_box.item label="日本語 – ベータ" name="(Japanese)"/> -		<combo_box.item label="正體 (Traditional Chinese) - Beta" name="Traditional Chinese"/> +		<combo_box.item label="正體中文 (中国語 - 繁体字) - ベータ" name="Traditional Chinese"/>  	</combo_box>  	<text name="language_textbox2">  		(再起動後に反映) diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml index 637325ddd0..409429ffaa 100644 --- a/indra/newview/skins/default/xui/pl/floater_about.xml +++ b/indra/newview/skins/default/xui/pl/floater_about.xml @@ -10,7 +10,7 @@  	<floater.string name="AboutPosition">  		Położenie [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] w [REGION] zlokalizowanym w <nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION] -[[SERVER_RELEASE_NOTES_URL] [ReleaseNotes]] +[SERVER_RELEASE_NOTES_URL]  	</floater.string>  	<floater.string name="AboutSystem">  		Procesor: [CPU] diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml index 1c19a55de6..c53aa7d5f7 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml @@ -16,7 +16,7 @@  		<combo_box.item label="Русский (Russo) - Beta" name="Russian"/>  		<combo_box.item label="Türkçe (Turco) - Beta" name="Turkish"/>  		<combo_box.item label="日本語 (Japonês) - Beta" name="(Japanese)"/> -		<combo_box.item label="正體 (Chinês tradicional) - Beta" name="Traditional Chinese"/> +		<combo_box.item label="正體中文 (Chinês tradicional) - Beta" name="Traditional Chinese"/>  	</combo_box>  	<text name="language_textbox2">  		(Reinicie para trocar de idioma) diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_general.xml b/indra/newview/skins/default/xui/ru/panel_preferences_general.xml index 3e21697616..770c47b3d4 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_general.xml @@ -5,7 +5,7 @@  	</text>  	<combo_box name="language_combobox">  		<combo_box.item label="Стандартная настройка системы" name="System Default Language"/> -		<combo_box.item label="Английский" name="English"/> +		<combo_box.item label="English - Английский" name="English"/>  		<combo_box.item label="Dansk – датский (бета-версия)" name="Danish"/>  		<combo_box.item label="Deutsch – немецкий (бета-версия)" name="Deutsch(German)"/>  		<combo_box.item label="Español – испанский (бета-версия)" name="Spanish"/> @@ -13,10 +13,10 @@  		<combo_box.item label="Italiano – итальянский (бета-версия)" name="Italian"/>  		<combo_box.item label="Polski – польский (бета-версия)" name="Polish"/>  		<combo_box.item label="Português – португальский (бета-версия)" name="Portugese"/> -		<combo_box.item label="Русский - бета-версия" name="Russian"/> -		<combo_box.item label="Türkçe (турецкий) - бета-версия" name="Turkish"/> +		<combo_box.item label="Русский (бета-версия)" name="Russian"/> +		<combo_box.item label="Türkçe - турецкий (бета-версия)" name="Turkish"/>  		<combo_box.item label="日本語 – японский (бета-версия)" name="(Japanese)"/> -		<combo_box.item label="正體 (китайский, традиционное письмо) - бета-версия" name="Traditional Chinese"/> +		<combo_box.item label="正體中文 - китайский, традиционное письмо (бета-версия)" name="Traditional Chinese"/>  	</combo_box>  	<text name="language_textbox2">  		(Требуется перезапуск) diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index d52cee6b0d..0134298166 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -4252,7 +4252,7 @@ support@secondlife.com.  		Женщина – ух ты!  	</string>  	<string name="/bow"> -		/поклониться +		/поклон  	</string>  	<string name="/clap">  		/хлопнуть diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_general.xml b/indra/newview/skins/default/xui/tr/panel_preferences_general.xml index da01bd98a0..fbfc07c4b8 100644 --- a/indra/newview/skins/default/xui/tr/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/tr/panel_preferences_general.xml @@ -5,7 +5,7 @@  	</text>  	<combo_box name="language_combobox">  		<combo_box.item label="Sistem varsayılanı" name="System Default Language"/> -		<combo_box.item label="İngilizce" name="English"/> +		<combo_box.item label="English (İngilizce)" name="English"/>  		<combo_box.item label="Dansk (Danca) - Beta" name="Danish"/>  		<combo_box.item label="Deutsch (Almanca) - Beta" name="Deutsch(German)"/>  		<combo_box.item label="Español (İspanyolca) - Beta" name="Spanish"/> @@ -14,9 +14,9 @@  		<combo_box.item label="Polski (Lehçe) - Beta" name="Polish"/>  		<combo_box.item label="Português (Portekizce) - Beta" name="Portugese"/>  		<combo_box.item label="Русский (Rusça) - Beta" name="Russian"/> -		<combo_box.item label="Türkçe (Türkçe) - Beta" name="Turkish"/> +		<combo_box.item label="Türkçe - Beta" name="Turkish"/>  		<combo_box.item label="日本語 (Japonca) - Beta" name="(Japanese)"/> -		<combo_box.item label="正體 (Geleneksel Çince) - Beta" name="Traditional Chinese"/> +		<combo_box.item label="正體中文 (Geleneksel Çince) - Beta" name="Traditional Chinese"/>  	</combo_box>  	<text name="language_textbox2">  		(Yeniden başlatma gerekir) diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml index 0ac85d399e..7e19c124a1 100644 --- a/indra/newview/skins/default/xui/zh/floater_about.xml +++ b/indra/newview/skins/default/xui/zh/floater_about.xml @@ -10,7 +10,7 @@  	<floater.string name="AboutPosition">  		You are at [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] located at <nolink>[HOSTNAME]</nolink> ([HOSTIP])  [SERVER_VERSION] -[[SERVER_RELEASE_NOTES_URL] [ReleaseNotes]] +[SERVER_RELEASE_NOTES_URL]  	</floater.string>  	<floater.string name="AboutSystem">  		CPU:[CPU] diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml index 29f9599c97..6827fab6e6 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml @@ -5,15 +5,15 @@  	</text>  	<combo_box name="language_combobox">  		<combo_box.item label="系統預設" name="System Default Language"/> -		<combo_box.item label="英語" name="English"/> -		<combo_box.item label="Dansk (Danish) - Beta" name="Danish"/> -		<combo_box.item label="Deutsch (German) - Beta" name="Deutsch(German)"/> -		<combo_box.item label="Español (Spanish) - Beta" name="Spanish"/> -		<combo_box.item label="Français (French) - Beta" name="French"/> -		<combo_box.item label="Italiano (Italian) - Beta" name="Italian"/> -		<combo_box.item label="Polski (Polish) - Beta" name="Polish"/> -		<combo_box.item label="Português (Portuguese) - Beta" name="Portugese"/> -		<combo_box.item label="日本語 (Japanese) - Beta" name="(Japanese)"/> +		<combo_box.item label="English (英語)" name="English"/> +		<combo_box.item label="Dansk (丹麥語) - Beta" name="Danish"/> +		<combo_box.item label="Deutsch (德語) - Beta" name="Deutsch(German)"/> +		<combo_box.item label="Español (西班牙語) - Beta" name="Spanish"/> +		<combo_box.item label="Français (法語) - Beta" name="French"/> +		<combo_box.item label="Italiano (義大利語) - Beta" name="Italian"/> +		<combo_box.item label="Polski (波蘭語) - Beta" name="Polish"/> +		<combo_box.item label="Português (葡萄牙語) - Beta" name="Portugese"/> +		<combo_box.item label="日本語 (日語) - Beta" name="(Japanese)"/>  	</combo_box>  	<text name="language_textbox2">  		(須重新啟動) diff --git a/indra/newview/tests/lltranslate_test.cpp b/indra/newview/tests/lltranslate_test.cpp new file mode 100644 index 0000000000..10e37fae97 --- /dev/null +++ b/indra/newview/tests/lltranslate_test.cpp @@ -0,0 +1,345 @@ +/**  + * @file lltranslate_test.cpp + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../test/lltut.h" +#include "../lltranslate.h" +#include "../llversioninfo.h" +#include "../llviewercontrol.h" + +#include "llbufferstream.h" +#include "lltrans.h" +#include "llui.h" + +static const std::string GOOGLE_VALID_RESPONSE1 = +"{\ + \"data\": {\ +  \"translations\": [\ +   {\ +    \"translatedText\": \"привет\",\ +    \"detectedSourceLanguage\": \"es\"\ +   }\ +  ]\ + }\ +}"; + +static const std::string GOOGLE_VALID_RESPONSE2 = +"{\ + \"data\": {\ +  \"translations\": [\ +   {\ +    \"translatedText\": \"привет\"\ +   }\ +  ]\ + }\ +}\ +"; + +static const std::string GOOGLE_VALID_RESPONSE3 = +"{\ + \"error\": {\ +  \"errors\": [\ +   {\ +    \"domain\": \"global\",\ +    \"reason\": \"invalid\",\ +    \"message\": \"Invalid Value\"\ +   }\ +  ],\ +  \"code\": 400,\ +  \"message\": \"Invalid Value\"\ + }\ +}"; + +static const std::string BING_VALID_RESPONSE1 = +"<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">Привет</string>"; + +static const std::string BING_VALID_RESPONSE2 = +"<html><body><h1>Argument Exception</h1><p>Method: Translate()</p><p>Parameter: </p>\ +<p>Message: 'from' must be a valid language</p><code></code>\ +<p>message id=3743.V2_Rest.Translate.58E8454F</p></body></html>"; + +static const std::string BING_VALID_RESPONSE3 = +"<html><body><h1>Argument Exception</h1><p>Method: Translate()</p>\ +<p>Parameter: appId</p><p>Message: Invalid appId
\nParameter name: appId</p>\ +<code></code><p>message id=3737.V2_Rest.Translate.56016759</p></body></html>"; + +namespace tut +{ +	class translate_test +	{ +	protected: +		void test_translation( +			LLTranslationAPIHandler& handler, +			int status, const std::string& resp, +			const std::string& exp_trans, const std::string& exp_lang, const std::string& exp_err) +		{ +			std::string translation, detected_lang, err_msg; +			bool rc = handler.parseResponse(status, resp, translation, detected_lang, err_msg); +			ensure_equals("rc", rc, (status == 200)); +			ensure_equals("err_msg", err_msg, exp_err); +			ensure_equals("translation", translation, exp_trans); +			ensure_equals("detected_lang", detected_lang,  exp_lang); +		} + +		LLGoogleTranslationHandler mGoogle; +		LLBingTranslationHandler mBing; +	}; + +	typedef test_group<translate_test> translate_test_group_t; +	typedef translate_test_group_t::object translate_test_object_t; +	tut::translate_test_group_t tut_translate("LLTranslate"); + +	template<> template<> +	void translate_test_object_t::test<1>() +	{ +		test_translation(mGoogle, 200, GOOGLE_VALID_RESPONSE1, "привет", "es", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<2>() +	{ +		test_translation(mGoogle, 200, GOOGLE_VALID_RESPONSE2, "привет", "", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<3>() +	{ +		test_translation(mGoogle, 400, GOOGLE_VALID_RESPONSE3, "", "", "Invalid Value"); +	} + +	template<> template<> +	void translate_test_object_t::test<4>() +	{ +		test_translation(mGoogle, 400, +			"", +			"", "", "* Line 1, Column 1\n  Syntax error: value, object or array expected.\n"); +	} + +	template<> template<> +	void translate_test_object_t::test<5>() +	{ +		test_translation(mGoogle, 400, +			"[]", +			"", "", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<6>() +	{ +		test_translation(mGoogle, 400, +			"{\"oops\": \"invalid\"}", +			"", "", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<7>() +	{ +		test_translation(mGoogle, 400, +			"{\"data\": {}}", +			"", "", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<8>() +	{ +		test_translation(mGoogle, 400, +				"{\"data\": { \"translations\": [ {} ] }}", +			"", "", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<9>() +	{ +		test_translation(mGoogle, 400, +				"{\"data\": { \"translations\": [ { \"translatedTextZZZ\": \"привет\", \"detectedSourceLanguageZZZ\": \"es\" } ] }}", +			"", "", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<10>() +	{ +		test_translation(mBing, 200, BING_VALID_RESPONSE1, "Привет", "", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<11>() +	{ +		test_translation(mBing, 400, BING_VALID_RESPONSE2, "", "", "'from' must be a valid language"); +	} + +	template<> template<> +	void translate_test_object_t::test<12>() +	{ +		test_translation(mBing, 400, BING_VALID_RESPONSE3, "", "", "Invalid appId\nParameter name: appId"); +	} + +	template<> template<> +	void translate_test_object_t::test<13>() +	{ +		test_translation(mBing, 200, +			"Привет</string>", +			"Привет", "", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<14>() +	{ +		test_translation(mBing, 200, +			"<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">Привет", +			"Привет", "", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<15>() +	{ +		test_translation(mBing, 200, +			"Привет", +			"Привет", "", ""); +	} + +	template<> template<> +	void translate_test_object_t::test<16>() +	{ +		test_translation(mBing, 400, +			"Message: some error</p>", +			"", "", "some error"); +	} + +	template<> template<> +	void translate_test_object_t::test<17>() +	{ +		test_translation(mBing, 400, +			"Message: some error", +			"", "", "some error"); +	} + +	template<> template<> +	void translate_test_object_t::test<18>() +	{ +		test_translation(mBing, 400, +			"some error</p>", +			"", "", "some error"); +	} + +	template<> template<> +	void translate_test_object_t::test<19>() +	{ +		test_translation(mBing, 400, +			"some error", +			"", "", "some error"); +	} + +	template<> template<> +	void translate_test_object_t::test<20>() +	{ +		std::string url; +		mBing.getTranslateURL(url, "en", "es", "hi"); +		ensure_equals("bing URL", url, +			"http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=dummy&text=hi&to=es&from=en"); +	} + +	template<> template<> +	void translate_test_object_t::test<21>() +	{ +		std::string url; +		mBing.getTranslateURL(url, "", "es", "hi"); +		ensure_equals("bing URL", url, +			"http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=dummy&text=hi&to=es"); +	} + +	template<> template<> +	void translate_test_object_t::test<22>() +	{ +		std::string url; +		mGoogle.getTranslateURL(url, "en", "es", "hi"); +		ensure_equals("google URL", url, +			"https://www.googleapis.com/language/translate/v2?key=dummy&q=hi&target=es&source=en"); +	} + +	template<> template<> +	void translate_test_object_t::test<23>() +	{ +		std::string url; +		mGoogle.getTranslateURL(url, "", "es", "hi"); +		ensure_equals("google URL", url, +			"https://www.googleapis.com/language/translate/v2?key=dummy&q=hi&target=es"); +	} +} + +//== Misc stubs =============================================================== +LLControlGroup gSavedSettings("test"); + +std::string LLUI::getLanguage() { return "en"; } +std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) { return "dummy"; } + +LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) {} +std::string LLControlGroup::getString(const std::string& name) { return "dummy"; } +LLControlGroup::~LLControlGroup() {} + +namespace boost { +	void intrusive_ptr_add_ref(LLCurl::Responder*) {} +	void intrusive_ptr_release(LLCurl::Responder*) {} +} + +LLCurl::Responder::Responder() {} +void LLCurl::Responder::completedHeader(U32, std::string const&, LLSD const&) {} +void LLCurl::Responder::completedRaw(U32, const std::string&, const LLChannelDescriptors&, const LLIOPipe::buffer_ptr_t& buffer) {} +void LLCurl::Responder::completed(U32, std::string const&, LLSD const&) {} +void LLCurl::Responder::error(U32, std::string const&) {} +void LLCurl::Responder::errorWithContent(U32, std::string const&, LLSD const&) {} +void LLCurl::Responder::result(LLSD const&) {} +LLCurl::Responder::~Responder() {} + +void LLHTTPClient::get(const std::string&, const LLSD&, ResponderPtr, const LLSD&, const F32) {} +void LLHTTPClient::get(const std::string&, boost::intrusive_ptr<LLCurl::Responder>, const LLSD&, const F32) {} + +LLBufferStream::LLBufferStream(const LLChannelDescriptors& channels, LLBufferArray* buffer) +:	std::iostream(&mStreamBuf), mStreamBuf(channels, buffer) {} +LLBufferStream::~LLBufferStream() {} + +LLBufferStreamBuf::LLBufferStreamBuf(const LLChannelDescriptors&, LLBufferArray*) {} +#if( LL_WINDOWS || __GNUC__ > 2) +LLBufferStreamBuf::pos_type LLBufferStreamBuf::seekoff( +	off_type off, +	std::ios::seekdir way, +	std::ios::openmode which) +#else +streampos LLBufferStreamBuf::seekoff( +	streamoff off, +	std::ios::seekdir way, +	std::ios::openmode which) +#endif +{ return 0; } +int LLBufferStreamBuf::sync() {return 0;} +int LLBufferStreamBuf::underflow() {return 0;} +int LLBufferStreamBuf::overflow(int) {return 0;} +LLBufferStreamBuf::~LLBufferStreamBuf() {} + +S32 LLVersionInfo::getBuild() { return 0; } +const std::string& LLVersionInfo::getChannel() {static std::string dummy; return dummy;} +S32 LLVersionInfo::getMajor() { return 0; } +S32 LLVersionInfo::getMinor() { return 0; } +S32 LLVersionInfo::getPatch() { return 0; } diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp index 170babbb98..36d988ead7 100644..100755 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ b/indra/win_crash_logger/llcrashloggerwindows.cpp @@ -370,5 +370,6 @@ bool LLCrashLoggerWindows::cleanup()  		sleep_and_pump_messages(3);  	}  	PostQuitMessage(0); +	commonCleanup();  	return true;  } | 
