[Translate] Introduce an option to translate IMs
If Local chat is being translated, IM translation is on by default. IM translation can be toggled from the drop down(flyout) menu of IMs. Option is not shown if translation is not configured. Translators: floater_instant_message.xml and floater_instant_message_concisebuttons.xml have two new strings for you to translate.
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
#include "llspeakers.h"
|
||||
#include "llstylemap.h"
|
||||
#include "lltrans.h"
|
||||
#include "lltranslate.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewertexteditor.h"
|
||||
#include "llviewerstats.h"
|
||||
@@ -296,6 +297,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(
|
||||
mShowSpeakersOnConnect(true),
|
||||
mDing(false),
|
||||
mRPMode(false),
|
||||
mTranslate(false),
|
||||
mTextIMPossible(true),
|
||||
mCallBackEnabled(true),
|
||||
mSpeakers(NULL),
|
||||
@@ -349,6 +351,8 @@ LLFloaterIMPanel::LLFloaterIMPanel(
|
||||
LLAvatarTracker::instance().addParticularFriendObserver(mOtherParticipantUUID, this);
|
||||
LLMuteList::instance().addObserver(this);
|
||||
mDing = gSavedSettings.getBOOL("LiruNewMessageSoundIMsOn");
|
||||
if (LLTranslate::isTranslationConfigured())
|
||||
mTranslate = gSavedSettings.getBOOL("TranslateChat");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -696,9 +700,79 @@ bool LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
class IMTranslationReceiver : public LLTranslate::TranslationReceiver
|
||||
{
|
||||
public :
|
||||
IMTranslationReceiver(const std::string& from_lang, const std::string& to_lang, LLFloaterIMPanel* panel, const std::string& msg, LLColor4 color, bool log, const LLUUID& source, const std::string& name, bool irc) : LLTranslate::TranslationReceiver(from_lang, to_lang),
|
||||
mPanel(panel), mMsg(msg), mColor(color), mLog(log), mSource(source), mName(name), mIRC(irc)
|
||||
{
|
||||
}
|
||||
|
||||
static boost::intrusive_ptr<IMTranslationReceiver> build(const std::string& from_lang, const std::string& to_lang, LLFloaterIMPanel* panel, const std::string& msg, LLColor4 color, bool log, const LLUUID& source, const std::string& name, bool irc)
|
||||
{
|
||||
return boost::intrusive_ptr<IMTranslationReceiver>(new IMTranslationReceiver(from_lang, to_lang, panel, msg, color, log, source, name, irc));
|
||||
}
|
||||
|
||||
protected:
|
||||
void handleResponse(const std::string& translation, const std::string& detected_language)
|
||||
{
|
||||
// filter out non-interesting responses
|
||||
if (!translation.empty() && mToLang != detected_language && LLStringUtil::compareInsensitive(translation, mMsg))
|
||||
mMsg += " (" + translation + ')';
|
||||
mPanel->addHistoryLine(mMsg, mColor, mLog, mSource, mName, false, true, mIRC);
|
||||
}
|
||||
|
||||
void handleFailure(int status, const std::string& err_msg)
|
||||
{
|
||||
llwarns << "Translation failed for mesg " << mMsg << " 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
|
||||
mPanel->addHistoryLine(mMsg + " (" + msg + ')', mColor, mLog, mSource, mName, false, true, mIRC);
|
||||
}
|
||||
|
||||
/*virtual*/ char const* getName() const { return "IMTranslationReceiver"; }
|
||||
|
||||
private:
|
||||
LLFloaterIMPanel* mPanel;
|
||||
std::string mMsg;
|
||||
const LLColor4 mColor;
|
||||
const bool mLog;
|
||||
const LLUUID mSource;
|
||||
const std::string mName;
|
||||
const bool mIRC;
|
||||
};
|
||||
|
||||
void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incolor, bool log_to_file, const LLUUID& source, const std::string& name)
|
||||
{
|
||||
bool is_agent(gAgentID == source), from_user(source.notNull());
|
||||
bool is_agent(gAgentID == source), from_user(name != SYSTEM_FROM && source.notNull());
|
||||
// IRC style text starts with a colon here; empty names and system messages aren't irc style.
|
||||
bool is_irc = from_user && utf8msg[0] != ':';
|
||||
|
||||
// Now we're adding the actual line of text, so erase the
|
||||
// "Foo is typing..." text segment, and the optional timestamp
|
||||
// if it was present. JC
|
||||
removeTypingIndicator(NULL);
|
||||
|
||||
std::string show_name = name;
|
||||
if (from_user)
|
||||
{
|
||||
LLAvatarNameCache::getNSName(source, show_name);
|
||||
if (mTranslate && !is_agent)
|
||||
{
|
||||
const std::string from_lang = ""; // leave empty to trigger autodetect
|
||||
const std::string to_lang = LLTranslate::getTranslateLanguage();
|
||||
|
||||
LLTranslate::TranslationReceiverPtr result = IMTranslationReceiver::build(from_lang, to_lang, this, utf8msg, incolor, log_to_file, source, show_name, is_irc);
|
||||
LLTranslate::translateMessage(result, from_lang, to_lang, utf8msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
addHistoryLine(utf8msg, incolor, log_to_file, source, show_name, is_agent, from_user, is_irc);
|
||||
}
|
||||
|
||||
void LLFloaterIMPanel::addHistoryLine(const std::string& utf8msg, LLColor4 incolor, bool log_to_file, const LLUUID& source, const std::string& name, bool is_agent, bool from_user, bool is_irc)
|
||||
{
|
||||
if (!is_agent)
|
||||
{
|
||||
static const LLCachedControl<bool> mKeywordsChangeColor(gSavedPerAccountSettings, "KeywordsChangeColor", false);
|
||||
@@ -729,14 +803,8 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol
|
||||
if (invisible || (!host && focused))
|
||||
++mNumUnreadMessages;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Now we're adding the actual line of text, so erase the
|
||||
// "Foo is typing..." text segment, and the optional timestamp
|
||||
// if it was present. JC
|
||||
removeTypingIndicator(NULL);
|
||||
|
||||
// Actually add the line
|
||||
bool prepend_newline = true;
|
||||
if (gSavedSettings.getBOOL("IMShowTimestamps"))
|
||||
@@ -745,27 +813,21 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol
|
||||
prepend_newline = false;
|
||||
}
|
||||
|
||||
std::string show_name = name;
|
||||
bool is_irc = false;
|
||||
if (is_irc) is_irc = gSavedSettings.getBOOL("LiruItalicizeActions");
|
||||
// 'name' is a sender name that we want to hotlink so that clicking on it opens a profile.
|
||||
if (!name.empty()) // If name exists, then add it to the front of the message.
|
||||
{
|
||||
// Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text.
|
||||
if (name == SYSTEM_FROM)
|
||||
if (!from_user)
|
||||
{
|
||||
mHistoryEditor->appendColoredText(name,false,prepend_newline,incolor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// IRC style text starts with a colon here; empty names and system messages aren't irc style.
|
||||
static const LLCachedControl<bool> italicize("LiruItalicizeActions");
|
||||
is_irc = italicize && utf8msg[0] != ':';
|
||||
if (from_user)
|
||||
LLAvatarNameCache::getNSName(source, show_name);
|
||||
// Convert the name to a hotlink and add to message.
|
||||
LLStyleSP source_style = LLStyleMap::instance().lookupAgent(source);
|
||||
source_style->mItalic = is_irc;
|
||||
mHistoryEditor->appendStyledText(show_name,false,prepend_newline,source_style);
|
||||
mHistoryEditor->appendStyledText(name,false,prepend_newline,source_style);
|
||||
}
|
||||
prepend_newline = false;
|
||||
}
|
||||
@@ -779,21 +841,10 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol
|
||||
mHistoryEditor->appendStyledText(utf8msg, false, prepend_newline, style);
|
||||
}
|
||||
|
||||
if (log_to_file
|
||||
&& gSavedPerAccountSettings.getBOOL("LogInstantMessages") )
|
||||
if (log_to_file && gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
|
||||
{
|
||||
std::string histstr;
|
||||
if (gSavedPerAccountSettings.getBOOL("IMLogTimestamp"))
|
||||
histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + show_name + utf8msg;
|
||||
else
|
||||
histstr = show_name + utf8msg;
|
||||
|
||||
// [Ansariel: Display name support]
|
||||
// Floater title contains display name -> bad idea to use that as filename
|
||||
// mLogLabel, however, is the old legacy name
|
||||
//LLLogChat::saveHistory(getTitle(),histstr);
|
||||
LLLogChat::saveHistory(mLogLabel, histstr);
|
||||
// [/Ansariel: Display name support]
|
||||
const std::string histstr(name + utf8msg);
|
||||
LLLogChat::saveHistory(mLogLabel, gSavedPerAccountSettings.getBOOL("IMLogTimestamp") ? LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + histstr : histstr);
|
||||
}
|
||||
|
||||
if (from_user)
|
||||
@@ -951,6 +1002,8 @@ void LLFloaterIMPanel::removeDynamics(LLComboBox* flyout)
|
||||
flyout->remove(mRPMode ? getString("rp mode on") : getString("rp mode off"));
|
||||
flyout->remove(LLAvatarActions::isFriend(mOtherParticipantUUID) ? getString("remove friend") : getString("add friend"));
|
||||
flyout->remove(LLAvatarActions::isBlocked(mOtherParticipantUUID) ? getString("unmute") : getString("mute"));
|
||||
if (mSessionType == P2P_SESSION)
|
||||
flyout->remove(mTranslate ? getString("translate on") : getString("translate off"));
|
||||
}
|
||||
|
||||
void LLFloaterIMPanel::addDynamics(LLComboBox* flyout)
|
||||
@@ -959,6 +1012,14 @@ void LLFloaterIMPanel::addDynamics(LLComboBox* flyout)
|
||||
flyout->add(mRPMode ? getString("rp mode on") : getString("rp mode off"), 7);
|
||||
flyout->add(LLAvatarActions::isFriend(mOtherParticipantUUID) ? getString("remove friend") : getString("add friend"), 8);
|
||||
flyout->add(LLAvatarActions::isBlocked(mOtherParticipantUUID) ? getString("unmute") : getString("mute"), 9);
|
||||
if (mSessionType == P2P_SESSION && LLTranslate::isTranslationConfigured())
|
||||
flyout->add(mTranslate ? getString("translate on") : getString("translate off"), 10);
|
||||
}
|
||||
|
||||
void LLFloaterIMPanel::rebuildDynamics()
|
||||
{
|
||||
if (LLComboBox* flyout = findChild<LLComboBox>("instant_message_flyout"))
|
||||
rebuildDynamics(flyout);
|
||||
}
|
||||
|
||||
void copy_profile_uri(const LLUUID& id, bool group = false);
|
||||
@@ -988,6 +1049,7 @@ void LLFloaterIMPanel::onFlyoutCommit(LLComboBox* flyout, const LLSD& value)
|
||||
else if (option == 7) mRPMode = !mRPMode;
|
||||
else if (option == 8) LLAvatarActions::isFriend(mOtherParticipantUUID) ? LLAvatarActions::removeFriendDialog(mOtherParticipantUUID) : LLAvatarActions::requestFriendshipDialog(mOtherParticipantUUID);
|
||||
else if (option == 9) LLAvatarActions::toggleBlock(mOtherParticipantUUID);
|
||||
else if (option == 10) mTranslate = !mTranslate;
|
||||
|
||||
// Last add them back
|
||||
addDynamics(flyout);
|
||||
|
||||
Reference in New Issue
Block a user