Merge Firestorm LGPL tip

master
Ansariel 2015-11-11 19:34:06 +01:00
commit 96c1d7950e
30 changed files with 749 additions and 782 deletions

View File

@ -37,6 +37,7 @@ Any of the configure options can also be used (and do the same thing) with the b
Typical LL autobuild configure options should also work, as long as they don't duplicate configuration we are
already doing.
Logs:
Look for logs in build-linux-i686/logs

View File

@ -1,11 +1,7 @@
# -*- cmake -*-
include(Prebuilt)
if( NOT ND_BUILD64BIT_ARCH OR NOT LINUX )
set(NDOF ON CACHE BOOL "Use NDOF space navigator joystick library.")
else( NOT ND_BUILD64BIT_ARCH OR NOT LINUX )
set(NDOF OFF CACHE BOOL "Use NDOF space navigator joystick library.")
endif( NOT ND_BUILD64BIT_ARCH OR NOT LINUX )
set(NDOF ON CACHE BOOL "Use NDOF space navigator joystick library.")
if (NDOF)
if (USESYSTEMLIBS)

View File

@ -63,7 +63,8 @@ LLConsole::LLConsole(const LLConsole::Params& p)
mFont(p.font),
mConsoleWidth(0),
mConsoleHeight(0),
mParseUrls(p.parse_urls) // <FS:Ansariel> If lines should be parsed for URLs
mParseUrls(p.parse_urls), // <FS:Ansariel> If lines should be parsed for URLs
mSessionSupport(p.session_support) // <FS:Ansariel> Session support
{
if (p.font_size_index.isProvided())
{
@ -174,6 +175,11 @@ void LLConsole::draw()
return;
}
// <FS:Ansariel> Session support
if (!mSessionSupport)
{
// This is done in update() if session support is enabled
// </FS:Ansariel>
U32 num_lines=0;
paragraph_t::reverse_iterator paragraph_it;
@ -196,6 +202,9 @@ void LLConsole::draw()
paragraph_num--;
paragraph_it++;
}
// <FS:Ansariel> Session support
}
// </FS:Ansariel>
if (mParagraphs.empty())
{
@ -267,6 +276,7 @@ void LLConsole::draw()
// y_pos += padding_vertical;
//}
paragraph_t::reverse_iterator paragraph_it;
static LLCachedControl<F32> consoleBackgroundOpacity(*LLUI::sSettingGroups["config"], "ConsoleBackgroundOpacity");
static LLUIColor cbcolor = LLUIColorTable::instance().getColor("ConsoleBackground");
LLColor4 color = cbcolor.get();
@ -280,17 +290,49 @@ void LLConsole::draw()
static const F32 padding_vert = 5;
S32 total_width = 0;
S32 total_height = 0;
S32 lines_drawn = 0;
paragraph_t::reverse_iterator paragraphs_end = mParagraphs.rend();
for (paragraph_it = mParagraphs.rbegin(); paragraph_it != paragraphs_end; ++paragraph_it)
{
if (mSessionSupport)
{
// Skip paragraph if visible in floater and make sure we don't
// exceed the maximum number of lines we want to display
if (mCurrentSessions.find((*paragraph_it).mSessionID) != mCurrentSessions.end())
{
continue;
}
lines_drawn += (*paragraph_it).mLines.size();
if (lines_drawn > mMaxLines)
{
break;
}
}
total_height += llfloor( (*paragraph_it).mLines.size() * line_height + padding_vert);
total_width = llmax(total_width, llfloor( (*paragraph_it).mMaxWidth + padding_horizontal));
}
mBackgroundImage->drawSolid(-14, (S32)(y_pos + line_height / 2), total_width, total_height + (line_height - padding_vert) / 2, color);
lines_drawn = 0;
for (paragraph_it = mParagraphs.rbegin(); paragraph_it != paragraphs_end; ++paragraph_it)
{
if (mSessionSupport)
{
// Skip paragraph if visible in floater and make sure we don't
// exceed the maximum number of lines we want to display
if (mCurrentSessions.find((*paragraph_it).mSessionID) != mCurrentSessions.end())
{
continue;
}
lines_drawn += (*paragraph_it).mLines.size();
if (lines_drawn > mMaxLines)
{
break;
}
}
F32 y_off=0;
F32 alpha;
S32 target_width = llfloor( (*paragraph_it).mMaxWidth + padding_horizontal);
@ -339,9 +381,26 @@ void LLConsole::draw()
}
else
{
S32 lines_drawn = 0;
paragraph_t::reverse_iterator paragraphs_end = mParagraphs.rend();
for(paragraph_it = mParagraphs.rbegin(); paragraph_it != paragraphs_end; paragraph_it++)
{
if (mSessionSupport)
{
// Skip paragraph if visible in floater and make sure we don't
// exceed the maximum number of lines we want to display
if (mCurrentSessions.find((*paragraph_it).mSessionID) != mCurrentSessions.end())
{
continue;
}
lines_drawn += (*paragraph_it).mLines.size();
if (lines_drawn > mMaxLines)
{
break;
}
}
S32 target_height = llfloor( (*paragraph_it).mLines.size() * line_height + padding_vertical);
S32 target_width = llfloor( (*paragraph_it).mMaxWidth + padding_horizontal);
@ -397,20 +456,23 @@ void LLConsole::draw()
}
// <FS:Ansariel> Chat console
void LLConsole::addConsoleLine(const std::string& utf8line, const LLColor4 &color, LLFontGL::StyleFlags styleflags)
void LLConsole::addConsoleLine(const std::string& utf8line, const LLColor4 &color, const LLUUID& session_id, LLFontGL::StyleFlags styleflags)
{
LLWString wline = utf8str_to_wstring(utf8line);
addConsoleLine(wline, color, styleflags);
addConsoleLine(wline, color, session_id, styleflags);
}
void LLConsole::addConsoleLine(const LLWString& wline, const LLColor4 &color, LLFontGL::StyleFlags styleflags)
void LLConsole::addConsoleLine(const LLWString& wline, const LLColor4 &color, const LLUUID& session_id, LLFontGL::StyleFlags styleflags)
{
if (wline.empty())
{
return;
}
removeExtraLines();
if (!mSessionSupport)
{
removeExtraLines();
}
mMutex.lock();
mLines.push_back(wline);
@ -418,6 +480,7 @@ void LLConsole::addConsoleLine(const LLWString& wline, const LLColor4 &color, LL
mAddTimes.push_back(mTimer.getElapsedTimeF32());
mLineColors.push_back(color);
mLineStyle.push_back(styleflags);
mSessionIDs.push_back(session_id);
mMutex.unlock();
}
@ -430,6 +493,7 @@ void LLConsole::clear()
mLineLengths.clear();
mLineColors.clear();
mLineStyle.clear();
mSessionIDs.clear();
mMutex.unlock();
mTimer.reset();
@ -580,11 +644,12 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, const LLFontGL* font, L
}
//Pass in the string and the default color for this block of text.
// <FS:Ansariel> Added styleflags parameter for style customization
// <FS:Ansariel> Added styleflags parameter for style customization and session support
//LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time, const LLFontGL* font, F32 screen_width)
LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time, const LLFontGL* font, F32 screen_width, LLFontGL::StyleFlags styleflags, bool parse_urls, LLConsole* console)
//: mParagraphText(str), mAddTime(add_time), mMaxWidth(-1)
LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time, const LLFontGL* font, F32 screen_width, LLFontGL::StyleFlags styleflags, const LLUUID& session_id, bool parse_urls, LLConsole* console)
: mParagraphText(str), mAddTime(add_time), mMaxWidth(-1), mSessionID(session_id)
// </FS:Ansariel>
: mParagraphText(str), mAddTime(add_time), mMaxWidth(-1)
{
// <FS:Ansariel> Parse SLURLs
mSourceText = str;
@ -664,6 +729,7 @@ void LLConsole::updateClass()
}
}
static LLTrace::BlockTimerStatHandle FTM_CONSOLE_UPDATE_PARAGRAPHS("Update Console Paragraphs");
void LLConsole::update()
{
{
@ -687,6 +753,7 @@ void LLConsole::update()
mFont,
(F32)getRect().getWidth(),
(!mLineStyle.empty() ? mLineStyle.front() : LLFontGL::NORMAL),
(!mSessionIDs.empty() ? mSessionIDs.front(): LLUUID::null),
mParseUrls,
this));
mLines.pop_front();
@ -694,14 +761,55 @@ void LLConsole::update()
mLineColors.pop_front();
if (!mLineStyle.empty())
mLineStyle.pop_front();
if (!mSessionIDs.empty())
mSessionIDs.pop_front();
// </FS:Ansariel>
}
}
// remove old paragraphs which can't possibly be visible any more. ::draw() will do something similar but more conservative - we do this here because ::draw() isn't guaranteed to ever be called! (i.e. the console isn't visible)
// <FS:Ansariel> Session support
if (!mSessionSupport)
{
// </FS:Ansariel>
while ((S32)mParagraphs.size() > llmax((S32)0, (S32)(mMaxLines)))
{
mParagraphs.pop_front();
}
// <FS:Ansariel> Session support
}
else
{
LL_RECORD_BLOCK_TIME(FTM_CONSOLE_UPDATE_PARAGRAPHS);
// skip lines added more than mLinePersistTime ago
F32 skip_time = mTimer.getElapsedTimeF32() - mLinePersistTime;
paragraph_t temp_para;
std::map<LLUUID, S32> session_map;
for (paragraph_t::reverse_iterator it = mParagraphs.rbegin(); it != mParagraphs.rend(); ++it)
{
Paragraph& para = *it;
session_map[para.mSessionID] += (S32)para.mLines.size();
if (session_map[para.mSessionID] <= mMaxLines && // max lines on a per session basis
!((mLinePersistTime > 0.f) && (para.mAddTime - skip_time) / (mLinePersistTime - mFadeTime) <= 0.f)) // not expired yet
{
temp_para.push_front(para);
}
}
mParagraphs.swap(temp_para);
}
// </FS:Ansariel>
}
// <FS:Ansariel> Session support
void LLConsole::addSession(const LLUUID& session_id)
{
mCurrentSessions.insert(session_id);
}
void LLConsole::removeSession(const LLUUID& session_id)
{
mCurrentSessions.erase(session_id);
}
// </FS:Ansariel>

View File

@ -52,13 +52,15 @@ public:
Optional<S32> font_size_index;
Optional<bool> parse_urls; // <FS:Ansariel> If lines should be parsed for URLs
Optional<std::string> background_image; // <FS:Ansariel> Configurable background for different console types
Optional<bool> session_support; // <FS:Ansariel> Session support
Params()
: max_lines("max_lines", LLUI::sSettingGroups["config"]->getS32("ConsoleMaxLines")),
persist_time("persist_time", 0.f), // forever
font_size_index("font_size_index"),
parse_urls("parse_urls", false), // <FS:Ansariel> If lines should be parsed for URLs
background_image("background_image", "Console_Background") // <FS:Ansariel> Configurable background for different console types
background_image("background_image", "Console_Background"), // <FS:Ansariel> Configurable background for different console types
session_support("session_support", false) // <FS:Ansariel> Session support
{
changeDefault(mouse_opaque, false);
}
@ -120,7 +122,7 @@ public:
public:
// <FS:Ansariel> Added styleflags parameter for style customization
//Paragraph (LLWString str, const LLColor4 &color, F32 add_time, const LLFontGL* font, F32 screen_width);
Paragraph (LLWString str, const LLColor4 &color, F32 add_time, const LLFontGL* font, F32 screen_width, LLFontGL::StyleFlags styleflags, bool parse_urls, LLConsole* console);
Paragraph (LLWString str, const LLColor4 &color, F32 add_time, const LLFontGL* font, F32 screen_width, LLFontGL::StyleFlags styleflags, const LLUUID& session_id, bool parse_urls, LLConsole* console);
// </FS:Ansariel>
void makeParagraphColorSegments ( const LLColor4 &color);
// <FS:Ansariel> Added styleflags parameter for style customization
@ -133,6 +135,7 @@ public:
F32 mAddTime; //Time this paragraph was added to the display.
F32 mMaxWidth; //Width of the widest line of text in this paragraph.
lines_t mLines;
LLUUID mSessionID; // <FS:Ansariel> Session support
// <FS:Ansariel> Parse SLURLs
LLUUID mID;
@ -160,12 +163,15 @@ public:
/*virtual*/ void draw();
// <FS:Ansariel> Chat console
void addConsoleLine(const std::string& utf8line, const LLColor4 &color, LLFontGL::StyleFlags styleflags = LLFontGL::NORMAL);
void addConsoleLine(const LLWString& wline, const LLColor4 &color, LLFontGL::StyleFlags styleflags = LLFontGL::NORMAL);
void addConsoleLine(const std::string& utf8line, const LLColor4 &color, const LLUUID& session_id = LLUUID::null, LLFontGL::StyleFlags styleflags = LLFontGL::NORMAL);
void addConsoleLine(const LLWString& wline, const LLColor4 &color, const LLUUID& session_id = LLUUID::null, LLFontGL::StyleFlags styleflags = LLFontGL::NORMAL);
void clear();
void addSession(const LLUUID& session_id);
void removeSession(const LLUUID& session_id);
std::deque<LLColor4> mLineColors;
std::deque<LLFontGL::StyleFlags> mLineStyle;
std::deque<LLUUID> mSessionIDs;
protected:
/*virtual*/ void removeExtraLines();
@ -183,6 +189,10 @@ private:
S32 mConsoleHeight;
bool mParseUrls; // <FS:Ansariel> If lines should be parsed for URLs
LLUIImagePtr mBackgroundImage; // <FS:Ansariel> Configurable background for different console types
// <FS:Ansariel> Session support
std::set<LLUUID> mCurrentSessions;
bool mSessionSupport;
// </FS:Ansariel>
};
extern LLConsole* gConsole;

View File

@ -103,7 +103,6 @@ bool FSConsoleUtils::ProcessChatMessage(const LLChat& chat_msg, const LLSD &args
LLColor4 chatcolor;
LLViewerChat::getChatColor(chat_msg, chatcolor);
gConsole->addConsoleLine(consoleChat, chatcolor);
gConsole->setVisible(!isNearbyChatVisible());
}
else
{
@ -126,7 +125,6 @@ bool FSConsoleUtils::ProcessChatMessage(const LLChat& chat_msg, const LLSD &args
LLColor4 chatcolor;
LLViewerChat::getChatColor(chat_msg, chatcolor);
gConsole->addConsoleLine(consoleChat, chatcolor);
gConsole->setVisible(!isNearbyChatVisible());
}
return true;
@ -173,7 +171,6 @@ void FSConsoleUtils::onProcessChatAvatarNameLookup(const LLUUID& agent_id, const
LLColor4 chatcolor;
LLViewerChat::getChatColor(chat_msg, chatcolor);
gConsole->addConsoleLine(consoleChat, chatcolor);
gConsole->setVisible(!isNearbyChatVisible());
}
//static
@ -214,13 +211,13 @@ bool FSConsoleUtils::ProcessInstantMessage(const LLUUID& session_id, const LLUUI
}
}
LLAvatarNameCache::get(from_id, boost::bind(&FSConsoleUtils::onProccessInstantMessageNameLookup, _1, _2, message, group));
LLAvatarNameCache::get(from_id, boost::bind(&FSConsoleUtils::onProccessInstantMessageNameLookup, _1, _2, message, group, session_id));
return true;
}
//static
void FSConsoleUtils::onProccessInstantMessageNameLookup(const LLUUID& agent_id, const LLAvatarName& av_name, const std::string& message_str, const std::string& group)
void FSConsoleUtils::onProccessInstantMessageNameLookup(const LLUUID& agent_id, const LLAvatarName& av_name, const std::string& message_str, const std::string& group, const LLUUID& session_id)
{
const bool is_group = !group.empty();
@ -254,6 +251,5 @@ void FSConsoleUtils::onProccessInstantMessageNameLookup(const LLUUID& agent_id,
LLColor4 textColor;
LLViewerChat::getChatColor(chat, textColor, LLSD().with("is_local", false).with("for_console", true));
gConsole->addConsoleLine("IM: " + senderName + delimiter + message, textColor);
gConsole->setVisible(!isNearbyChatVisible());
gConsole->addConsoleLine("IM: " + senderName + delimiter + message, textColor, session_id);
}

View File

@ -41,7 +41,7 @@ public:
protected:
static BOOL isNearbyChatVisible();
static void onProcessChatAvatarNameLookup(const LLUUID& agent_id, const LLAvatarName& av_name, const LLChat& chat_msg);
static void onProccessInstantMessageNameLookup(const LLUUID& agent_id, const LLAvatarName& av_name, const std::string& message_str, const std::string& group);
static void onProccessInstantMessageNameLookup(const LLUUID& agent_id, const LLAvatarName& av_name, const std::string& message_str, const std::string& group, const LLUUID& session_id);
};

View File

@ -48,6 +48,7 @@
#include "llcheckboxctrl.h"
#include "llchiclet.h"
#include "llchicletbar.h"
#include "llconsole.h"
#include "llfloaterabout.h" // for sysinfo button -Zi
#include "llfloateravatarpicker.h"
#include "llfloaterreg.h"
@ -1202,6 +1203,11 @@ void FSFloaterIM::setVisible(BOOL visible)
if (visible && isInVisibleChain())
{
sIMFloaterShowedSignal(mSessionID);
gConsole->addSession(mSessionID);
}
else
{
gConsole->removeSession(mSessionID);
}
}

View File

@ -74,7 +74,6 @@
#include "llworld.h"
#include "rlvhandler.h"
static const U32 NAME_PREDICTION_MINIMUM_LENGTH = 3;
S32 FSFloaterNearbyChat::sLastSpecialChatChannel = 0;
// [RLVa:KB] - Checked: 2010-02-27 (RLVa-0.2.2)
@ -118,7 +117,7 @@ void FSFloaterNearbyChat::updateFSUseNearbyChatConsole(const LLSD &data)
if (FSUseNearbyChatConsole)
{
removeScreenChat();
gConsole->setVisible(!getVisible());
gConsole->setVisible(TRUE);
}
else
{
@ -386,26 +385,6 @@ void FSFloaterNearbyChat::setVisible(BOOL visible)
}
LLFloater::setVisible(visible);
// <Ansariel> Support for chat console
static LLCachedControl<bool> chatHistoryTornOff(gSavedSettings, "ChatHistoryTornOff");
if (FSUseNearbyChatConsole)
{
FSFloaterIMContainer* floater_container = FSFloaterIMContainer::getInstance();
if (floater_container && !chatHistoryTornOff && !floater_container->getVisible())
{
// In case the nearby chat is docked into the IM floater and the
// IM floater is invisible, always show the console.
gConsole->setVisible(TRUE);
}
else
{
// In case the nearby chat is undocked OR docked and the IM floater
// is visible, show console only if nearby chat is not visible.
gConsole->setVisible(!getVisible());
}
}
// </Ansariel> Support for chat console
BOOL is_minimized = visible && isChatMultiTab()
? FSFloaterIMContainer::getInstance()->isMinimized()
: !visible;
@ -423,6 +402,15 @@ void FSFloaterNearbyChat::setVisible(BOOL visible)
mInputEditor->setFocus(TRUE);
}
}
if (visible && isInVisibleChain())
{
gConsole->addSession(LLUUID::null);
}
else
{
gConsole->removeSession(LLUUID::null);
}
}
void FSFloaterNearbyChat::onOpen(const LLSD& key )
@ -736,221 +724,9 @@ BOOL FSFloaterNearbyChat::handleKeyHere( KEY key, MASK mask )
return handled;
}
BOOL FSFloaterNearbyChat::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
{
U32 in_len = in_str.length();
S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
bool string_was_found = false;
for (S32 n = 0; n < cnt && !string_was_found; n++)
{
if (in_len <= sChatTypeTriggers[n].name.length())
{
std::string trigger_trunc = sChatTypeTriggers[n].name;
LLStringUtil::truncate(trigger_trunc, in_len);
if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
{
*out_str = sChatTypeTriggers[n].name;
string_was_found = true;
}
}
}
return string_was_found;
}
void FSFloaterNearbyChat::onChatBoxKeystroke()
{
LLWString raw_text = mInputEditor->getWText();
// Can't trim the end, because that will cause autocompletion
// to eat trailing spaces that might be part of a gesture.
LLWStringUtil::trimHead(raw_text);
S32 length = raw_text.length();
S32 channel=0;
if (gSavedSettings.getBOOL("FSNearbyChatbar") &&
gSavedSettings.getBOOL("FSShowChatChannel"))
{
// <FS:Ansariel> [FS communication UI]
//channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild<LLSpinCtrl>("ChatChannel")->get());
channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild<LLSpinCtrl>("ChatChannel")->get());
// </FS:Ansariel> [FS communication UI]
}
// -Zi
// if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences
// [RLVa:KB] - Checked: 2010-03-26 (RLVa-1.2.0b) | Modified: RLVa-1.0.0d
if ( (length > 0) && (raw_text[0] != '/') && (!(gSavedSettings.getBOOL("AllowMUpose") && raw_text[0] == ':')) && (!gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT)) )
// [/RLVa:KB]
{
// only start typing animation if we are chatting without / on channel 0 -Zi
if(channel==0)
gAgent.startTyping();
}
else
{
gAgent.stopTyping();
}
KEY key = gKeyboard->currentKey();
MASK mask = gKeyboard->currentMask(FALSE);
// Ignore "special" keys, like backspace, arrows, etc.
if (length > 1
&& raw_text[0] == '/'
&& key < KEY_SPECIAL
&& gSavedSettings.getBOOL("FSChatbarGestureAutoCompleteEnable"))
{
// we're starting a gesture, attempt to autocomplete
std::string utf8_trigger = wstring_to_utf8str(raw_text);
std::string utf8_out_str(utf8_trigger);
if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
{
std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
if (!rest_of_match.empty())
{
mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
// Select to end of line, starting from the character
// after the last one the user typed.
mInputEditor->selectByCursorPosition(utf8_out_str.size()-rest_of_match.size(),utf8_out_str.size());
}
}
else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
{
std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
mInputEditor->endOfDoc();
}
}
// <FS:CR> FIRE-3192 - Predictive name completion, based on code by Satomi Ahn
static LLCachedControl<bool> sNameAutocomplete(gSavedSettings, "FSChatbarNamePrediction");
if (length > NAME_PREDICTION_MINIMUM_LENGTH && sNameAutocomplete && key < KEY_SPECIAL && mask != MASK_CONTROL)
{
S32 cur_pos = mInputEditor->getCursorPos();
if (cur_pos && (raw_text[cur_pos - 1] != ' '))
{
// Get a list of avatars within range
uuid_vec_t avatar_ids;
LLWorld::getInstance()->getAvatars(&avatar_ids, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
if (avatar_ids.empty()) return; // Nobody's in range!
// Parse text for a pattern to search
std::string prefix = wstring_to_utf8str(raw_text.substr(0, cur_pos)); // Text before search string
std::string suffix = "";
if (cur_pos <= raw_text.length()) // Is there anything after the cursor?
{
suffix = wstring_to_utf8str(raw_text.substr(cur_pos)); // Text after search string
}
size_t last_space = prefix.rfind(" ");
std::string pattern = prefix.substr(last_space + 1, prefix.length() - last_space - 1); // Search pattern
prefix = prefix.substr(0, last_space + 1);
std::string match_pattern = "";
if (pattern.size() < NAME_PREDICTION_MINIMUM_LENGTH) return;
match_pattern = prefix.substr(last_space + 1, prefix.length() - last_space - 1);
prefix = prefix.substr(0, last_space + 1);
std::string match = pattern;
LLStringUtil::toLower(pattern);
std::string name;
bool found = false;
bool full_name = false;
uuid_vec_t::iterator iter = avatar_ids.begin();
if (last_space != std::string::npos && !prefix.empty())
{
last_space = prefix.substr(0, prefix.length() - 2).rfind(" ");
match_pattern = prefix.substr(last_space + 1, prefix.length() - last_space - 1);
prefix = prefix.substr(0, last_space + 1);
// prepare search pattern
std::string full_pattern(match_pattern + pattern);
LLStringUtil::toLower(full_pattern);
// Look for a match
while (iter != avatar_ids.end() && !found)
{
if (gCacheName->getFullName(*iter++, name))
{
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
name = RlvStrings::getAnonym(name);
}
LLStringUtil::toLower(name);
found = (name.find(full_pattern) == 0);
}
}
}
if (found)
{
full_name = true; // ignore OnlyFirstName in case we want to disambiguate
prefix += match_pattern;
}
else if (!pattern.empty()) // if first search did not work, try matching with last word before cursor only
{
prefix += match_pattern; // first part of the pattern wasn't a pattern, so keep it in prefix
LLStringUtil::toLower(pattern);
iter = avatar_ids.begin();
// Look for a match
while (iter != avatar_ids.end() && !found)
{
if (gCacheName->getFullName(*iter++, name))
{
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
name = RlvStrings::getAnonym(name);
}
LLStringUtil::toLower(name);
found = (name.find(pattern) == 0);
}
}
}
// if we found something by either method, replace the pattern by the avatar name
if (found)
{
std::string first_name, last_name;
gCacheName->getFirstLastName(*(iter - 1), first_name, last_name);
std::string rest_of_match;
std::string replaced_text;
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
replaced_text += RlvStrings::getAnonym(first_name + " " + last_name) + " ";
}
else
{
if (full_name)
{
rest_of_match = /*first_name + " " +*/ last_name.substr(pattern.size());
}
else
{
rest_of_match = first_name.substr(pattern.size());
}
replaced_text += match + rest_of_match + " ";
}
if (!rest_of_match.empty())
{
mInputEditor->setText(prefix + replaced_text + suffix);
mInputEditor->selectByCursorPosition(utf8string_to_wstring(prefix).size() + utf8string_to_wstring(match).size(), utf8string_to_wstring(prefix).size() + utf8string_to_wstring(replaced_text).size());
}
}
}
}
// </FS:CR>
FSNearbyChat::handleChatBarKeystroke(mInputEditor);
}
// static

View File

@ -103,7 +103,6 @@ public:
void updateShowMutedChatHistory(const LLSD &data);
protected:
static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
void onChatBoxKeystroke();
void onChatBoxFocusLost();
void onChatBoxFocusReceived();

View File

@ -37,44 +37,26 @@
#include "fsfloaternearbychat.h"
#include "llagent.h" // gAgent
#include "llagentcamera.h" // gAgentCamera
#include "llautoreplace.h"
#include "llfloaterimnearbychathandler.h"
//AO - includes for textentry
#include "llautoreplace.h"
#include "llgesturemgr.h"
#include "llkeyboard.h"
#include "llworld.h" // <FS:CR> FIRE-3192 - Name Prediction
#include "rlvhandler.h"
static const U32 NAME_PREDICTION_MINIMUM_LENGTH = 3;
static LLDefaultChildRegistry::Register<FSNearbyChatControl> r("fs_nearby_chat_control");
struct LLChatTypeTrigger {
std::string name;
EChatType type;
};
static LLChatTypeTrigger sChatTypeTriggers[] = {
{ "/whisper" , CHAT_TYPE_WHISPER},
{ "/shout" , CHAT_TYPE_SHOUT}
};
FSNearbyChatControl::FSNearbyChatControl(const FSNearbyChatControl::Params& p) :
LLLineEditor(p)
{
//<FS:TS> FIRE-11373: Autoreplace doesn't work in nearby chat bar
setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
setKeystrokeCallback(onKeystroke,this);
setKeystrokeCallback(onKeystroke, this);
FSNearbyChat::instance().registerChatBar(this);
setEnableLineHistory(TRUE);
setIgnoreArrowKeys( FALSE );
setCommitOnFocusLost( FALSE );
setRevertOnEsc( FALSE );
setIgnoreTab( TRUE );
setReplaceNewlinesWithSpaces( FALSE );
setPassDelete( TRUE );
setIgnoreArrowKeys(FALSE);
setCommitOnFocusLost(FALSE);
setRevertOnEsc(FALSE);
setIgnoreTab(TRUE);
setReplaceNewlinesWithSpaces(FALSE);
setPassDelete(TRUE);
setFont(LLViewerChat::getChatFont());
// Register for font change notifications
@ -85,252 +67,40 @@ FSNearbyChatControl::~FSNearbyChatControl()
{
}
void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata)
void FSNearbyChatControl::onKeystroke(LLLineEditor* caller, void* userdata)
{
LLWString raw_text = caller->getWText();
// Can't trim the end, because that will cause autocompletion
// to eat trailing spaces that might be part of a gesture.
LLWStringUtil::trimHead(raw_text);
S32 length = raw_text.length();
// Get the currently selected channel from the channel spinner in the nearby chat bar, if present and used.
// NOTE: Parts of the gAgent.startTyping() code are duplicated in 3 places:
// - llnearbychatbar.cpp
// - llchatbar.cpp
// - llnearbychat.cpp
// So be sure to look in all three places if changes are needed. This needs to be addressed at some point.
// -Zi
S32 channel=0;
if (gSavedSettings.getBOOL("FSNearbyChatbar") &&
gSavedSettings.getBOOL("FSShowChatChannel"))
{
// <FS:Ansariel> [FS communication UI]
//channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild<LLSpinCtrl>("ChatChannel")->get());
channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild<LLSpinCtrl>("ChatChannel")->get());
// </FS:Ansariel> [FS communication UI]
}
// -Zi
// if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences
// [RLVa:KB] - Checked: 2010-03-26 (RLVa-1.2.0b) | Modified: RLVa-1.0.0d
if ( (length > 0) && (raw_text[0] != '/') && (!(gSavedSettings.getBOOL("AllowMUpose") && raw_text[0] == ':')) && (!gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT)) )
// [/RLVa:KB]
{
// only start typing animation if we are chatting without / on channel 0 -Zi
if(channel==0)
gAgent.startTyping();
}
else
{
gAgent.stopTyping();
}
KEY key = gKeyboard->currentKey();
MASK mask = gKeyboard->currentMask(FALSE); // <FS:CR> FIRE-3192 - Predictive name completion
// Ignore "special" keys, like backspace, arrows, etc.
if (length > 1
&& raw_text[0] == '/'
// <FS:Ansariel / Holy Gavenkrantz> Optional gesture autocomplete
//&& key < KEY_SPECIAL)
&& key < KEY_SPECIAL
&& gSavedSettings.getBOOL("FSChatbarGestureAutoCompleteEnable"))
// </FS:Ansariel / Holy Gavenkrantz> Optional gesture autocomplete
{
// we're starting a gesture, attempt to autocomplete
std::string utf8_trigger = wstring_to_utf8str(raw_text);
std::string utf8_out_str(utf8_trigger);
if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
{
std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
caller->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
S32 outlength = caller->getLength(); // in characters
// Select to end of line, starting from the character
// after the last one the user typed.
caller->setSelection(length, outlength);
}
else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
{
std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
caller->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
caller->setCursorToEnd();
}
}
// <FS:CR> FIRE-3192 - Predictive name completion, based on code by Satomi Ahn
static LLCachedControl<bool> sNameAutocomplete(gSavedSettings, "FSChatbarNamePrediction");
if (length > NAME_PREDICTION_MINIMUM_LENGTH && sNameAutocomplete && key < KEY_SPECIAL && mask != MASK_CONTROL)
{
S32 cur_pos = caller->getCursor();
if (cur_pos && (raw_text[cur_pos - 1] != ' '))
{
// Get a list of avatars within range
uuid_vec_t avatar_ids;
LLWorld::getInstance()->getAvatars(&avatar_ids, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
if (avatar_ids.empty()) return; // Nobody's in range!
// Parse text for a pattern to search
std::string prefix = wstring_to_utf8str(raw_text.substr(0, cur_pos)); // Text before search string
std::string suffix = "";
if (cur_pos <= raw_text.length()) // Is there anything after the cursor?
{
suffix = wstring_to_utf8str(raw_text.substr(cur_pos)); // Text after search string
}
size_t last_space = prefix.rfind(" ");
std::string pattern = prefix.substr(last_space + 1, prefix.length() - last_space - 1); // Search pattern
prefix = prefix.substr(0, last_space + 1);
std::string match_pattern = "";
if (pattern.size() < NAME_PREDICTION_MINIMUM_LENGTH) return;
match_pattern = prefix.substr(last_space + 1, prefix.length() - last_space - 1);
prefix = prefix.substr(0, last_space + 1);
std::string match = pattern;
LLStringUtil::toLower(pattern);
std::string name;
bool found = false;
bool full_name = false;
uuid_vec_t::iterator iter = avatar_ids.begin();
if (last_space != std::string::npos && !prefix.empty())
{
last_space = prefix.substr(0, prefix.length() - 2).rfind(" ");
match_pattern = prefix.substr(last_space + 1, prefix.length() - last_space - 1);
prefix = prefix.substr(0, last_space + 1);
// prepare search pattern
std::string full_pattern(match_pattern + pattern);
LLStringUtil::toLower(full_pattern);
// Look for a match
while (iter != avatar_ids.end() && !found)
{
if (gCacheName->getFullName(*iter++, name))
{
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
name = RlvStrings::getAnonym(name);
}
LLStringUtil::toLower(name);
found = (name.find(full_pattern) == 0);
}
}
}
if (found)
{
full_name = true; // ignore OnlyFirstName in case we want to disambiguate
prefix += match_pattern;
}
else if (!pattern.empty()) // if first search did not work, try matching with last word before cursor only
{
prefix += match_pattern; // first part of the pattern wasn't a pattern, so keep it in prefix
LLStringUtil::toLower(pattern);
iter = avatar_ids.begin();
// Look for a match
while (iter != avatar_ids.end() && !found)
{
if (gCacheName->getFullName(*iter++, name))
{
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
name = RlvStrings::getAnonym(name);
}
LLStringUtil::toLower(name);
found = (name.find(pattern) == 0);
}
}
}
// if we found something by either method, replace the pattern by the avatar name
if (found)
{
std::string first_name, last_name;
gCacheName->getFirstLastName(*(iter - 1), first_name, last_name);
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
prefix += RlvStrings::getAnonym(first_name + " " + last_name) + " ";
}
else
{
std::string rest_of_match;
if (full_name)
{
rest_of_match = /*first_name + " " +*/ last_name.substr(pattern.size());
}
else
{
rest_of_match = first_name.substr(pattern.size());
}
prefix += match + rest_of_match + " ";
}
caller->setText(prefix + suffix);
caller->setSelection(utf8str_to_wstring(prefix).length(), cur_pos);
}
}
}
// </FS:CR>
}
BOOL FSNearbyChatControl::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
{
U32 in_len = in_str.length();
S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
for (S32 n = 0; n < cnt; n++)
{
if (in_len > sChatTypeTriggers[n].name.length())
continue;
std::string trigger_trunc = sChatTypeTriggers[n].name;
LLStringUtil::truncate(trigger_trunc, in_len);
if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
{
*out_str = sChatTypeTriggers[n].name;
return TRUE;
}
}
return FALSE;
FSNearbyChat::handleChatBarKeystroke(caller);
}
// send our focus status to the LLNearbyChat hub
void FSNearbyChatControl::onFocusReceived()
{
FSNearbyChat::instance().setFocusedInputEditor(this,TRUE);
FSNearbyChat::instance().setFocusedInputEditor(this, TRUE);
LLLineEditor::onFocusReceived();
}
void FSNearbyChatControl::onFocusLost()
{
FSNearbyChat::instance().setFocusedInputEditor(this,FALSE);
FSNearbyChat::instance().setFocusedInputEditor(this, FALSE);
LLLineEditor::onFocusLost();
}
void FSNearbyChatControl::setFocus(BOOL focus)
{
FSNearbyChat::instance().setFocusedInputEditor(this,focus);
FSNearbyChat::instance().setFocusedInputEditor(this, focus);
LLLineEditor::setFocus(focus);
}
void FSNearbyChatControl::autohide()
{
if(getName()=="default_chat_bar")
if (getName() == "default_chat_bar")
{
if(gSavedSettings.getBOOL("CloseChatOnReturn"))
if (gSavedSettings.getBOOL("CloseChatOnReturn"))
{
setFocus(FALSE);
}
if(gAgentCamera.cameraMouselook() || gSavedSettings.getBOOL("AutohideChatBar"))
if (gAgentCamera.cameraMouselook() || gSavedSettings.getBOOL("AutohideChatBar"))
{
FSNearbyChat::instance().showDefaultChatBar(FALSE);
}
@ -338,59 +108,58 @@ void FSNearbyChatControl::autohide()
}
// handle ESC key here
BOOL FSNearbyChatControl::handleKeyHere(KEY key, MASK mask )
BOOL FSNearbyChatControl::handleKeyHere(KEY key, MASK mask)
{
BOOL handled = FALSE;
bool handled = false;
EChatType type = CHAT_TYPE_NORMAL;
// autohide the chat bar if escape key was pressed and we're the default chat bar
if(key==KEY_ESCAPE && mask==MASK_NONE)
if (key == KEY_ESCAPE && mask == MASK_NONE)
{
// we let ESC key go through to the rest of the UI code, so don't set handled=TRUE
// we let ESC key go through to the rest of the UI code, so don't set handled = true
autohide();
gAgent.stopTyping();
}
else if( KEY_RETURN == key )
else if (KEY_RETURN == key)
{
if (mask == MASK_CONTROL && gSavedSettings.getBOOL("FSUseCtrlShout"))
{
// shout
type = CHAT_TYPE_SHOUT;
handled = TRUE;
handled = true;
}
else if (mask == MASK_SHIFT && gSavedSettings.getBOOL("FSUseShiftWhisper"))
{
// whisper
type = CHAT_TYPE_WHISPER;
handled = TRUE;
handled = true;
}
else if (mask == MASK_ALT && gSavedSettings.getBOOL("FSUseAltOOC"))
{
// OOC
type = CHAT_TYPE_OOC;
handled = TRUE;
handled = true;
}
else if (mask == (MASK_SHIFT | MASK_CONTROL))
{
addChar(llwchar(182));
return TRUE;
}
else
{
// say
type = CHAT_TYPE_NORMAL;
handled = TRUE;
handled = true;
}
}
if (handled == TRUE)
if (handled)
{
// save current line in the history buffer
LLLineEditor::onCommit();
// send chat to nearby chat hub
FSNearbyChat::instance().sendChat(getConvertedText(),type);
FSNearbyChat::instance().sendChat(getConvertedText(), type);
setText(LLStringExplicit(""));
autohide();
@ -398,5 +167,5 @@ BOOL FSNearbyChatControl::handleKeyHere(KEY key, MASK mask )
}
// let the line editor handle everything we don't handle
return LLLineEditor::handleKeyHere(key,mask);
return LLLineEditor::handleKeyHere(key, mask);
}

View File

@ -43,13 +43,11 @@ public:
virtual void onFocusLost();
virtual void setFocus(BOOL focus);
virtual BOOL handleKeyHere(KEY key,MASK mask);
static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
virtual BOOL handleKeyHere(KEY key, MASK mask);
private:
// Typing in progress, expand gestures etc.
static void onKeystroke(LLLineEditor* caller,void* userdata);
static void onKeystroke(LLLineEditor* caller, void* userdata);
// Unfocus and autohide chat bar accordingly if we are the default chat bar
void autohide();

View File

@ -35,13 +35,19 @@
#include "fsnearbychatcontrol.h"
#include "llagent.h" // gAgent
#include "llanimationstates.h" // ANIM_AGENT_WHISPER, ANIM_AGENT_TALK, ANIM_AGENT_SHOUT
#include "llchatentry.h"
#include "llcommandhandler.h"
#include "llgesturemgr.h"
#include "lllineeditor.h"
#include "llspinctrl.h"
#include "llviewercontrol.h"
#include "llviewerkeyboard.h"
#include "llviewerstats.h"
#include "llworld.h"
#include "rlvhandler.h"
static const U32 NAME_PREDICTION_MINIMUM_LENGTH = 3;
// <FS:KC> Fix for bad edge snapping
// *HACK* chat bar cannot return its correct height for some reason
static const S32 MAGIC_CHAT_BAR_PAD = 5;
@ -583,6 +589,275 @@ BOOL FSNearbyChat::defaultChatBarHasFocus() const
return FALSE;
}
bool matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
{
U32 in_len = in_str.length();
S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
for (S32 n = 0; n < cnt; n++)
{
if (in_len > sChatTypeTriggers[n].name.length())
continue;
std::string trigger_trunc = sChatTypeTriggers[n].name;
LLStringUtil::truncate(trigger_trunc, in_len);
if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
{
*out_str = sChatTypeTriggers[n].name;
return true;
}
}
return false;
}
//static
void FSNearbyChat::handleChatBarKeystroke(LLUICtrl* source)
{
LLChatEntry* chat_entry = dynamic_cast<LLChatEntry*>(source);
LLLineEditor* line_editor = dynamic_cast<LLLineEditor*>(source);
if (!chat_entry && !line_editor)
{
return;
}
LLWString raw_text;
if (chat_entry)
{
raw_text = chat_entry->getWText();
}
else
{
raw_text = line_editor->getWText();
}
// Can't trim the end, because that will cause autocompletion
// to eat trailing spaces that might be part of a gesture.
LLWStringUtil::trimHead(raw_text);
S32 length = raw_text.length();
S32 channel=0;
if (gSavedSettings.getBOOL("FSNearbyChatbar") &&
gSavedSettings.getBOOL("FSShowChatChannel"))
{
// <FS:Ansariel> [FS communication UI]
//channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild<LLSpinCtrl>("ChatChannel")->get());
channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild<LLSpinCtrl>("ChatChannel")->get());
// </FS:Ansariel> [FS communication UI]
}
// if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences
// [RLVa:KB] - Checked: 2010-03-26 (RLVa-1.2.0b) | Modified: RLVa-1.0.0d
if (length > 0 &&
raw_text[0] != '/' && (raw_text[0] != ':' || !gSavedSettings.getBOOL("AllowMUpose")) &&
!gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT))
// [/RLVa:KB]
{
// only start typing animation if we are chatting without / on channel 0 -Zi
if(channel==0)
gAgent.startTyping();
}
else
{
gAgent.stopTyping();
}
KEY key = gKeyboard->currentKey();
MASK mask = gKeyboard->currentMask(FALSE);
// Ignore "special" keys, like backspace, arrows, etc.
if (length > 1
&& raw_text[0] == '/'
&& key < KEY_SPECIAL
&& gSavedSettings.getBOOL("FSChatbarGestureAutoCompleteEnable"))
{
// we're starting a gesture, attempt to autocomplete
std::string utf8_trigger = wstring_to_utf8str(raw_text);
std::string utf8_out_str(utf8_trigger);
if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
{
std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
if (!rest_of_match.empty())
{
if (chat_entry)
{
chat_entry->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
// Select to end of line, starting from the character
// after the last one the user typed.
chat_entry->selectByCursorPosition(utf8_out_str.size()-rest_of_match.size(),utf8_out_str.size());
}
else
{
line_editor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
// Select to end of line, starting from the character
// after the last one the user typed.
S32 outlength = line_editor->getLength(); // in characters
line_editor->setSelection(length, outlength);
line_editor->setCursor(outlength);
}
}
}
else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
{
std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
if (chat_entry)
{
chat_entry->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
chat_entry->endOfDoc();
}
else
{
line_editor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
line_editor->setCursorToEnd();
}
}
}
// <FS:CR> FIRE-3192 - Predictive name completion, based on code by Satomi Ahn
static LLCachedControl<bool> sNameAutocomplete(gSavedSettings, "FSChatbarNamePrediction");
if (length > NAME_PREDICTION_MINIMUM_LENGTH && sNameAutocomplete && key < KEY_SPECIAL && mask != MASK_CONTROL)
{
S32 cur_pos;
if (chat_entry)
{
cur_pos = chat_entry->getCursorPos();
}
else
{
cur_pos = line_editor->getCursor();
}
if (cur_pos && (raw_text[cur_pos - 1] != ' '))
{
// Get a list of avatars within range
uuid_vec_t avatar_ids;
LLWorld::getInstance()->getAvatars(&avatar_ids, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
if (avatar_ids.empty()) return; // Nobody's in range!
// Parse text for a pattern to search
std::string prefix = wstring_to_utf8str(raw_text.substr(0, cur_pos)); // Text before search string
std::string suffix = "";
if (cur_pos <= raw_text.length()) // Is there anything after the cursor?
{
suffix = wstring_to_utf8str(raw_text.substr(cur_pos)); // Text after search string
}
size_t last_space = prefix.rfind(" ");
std::string pattern = prefix.substr(last_space + 1, prefix.length() - last_space - 1); // Search pattern
prefix = prefix.substr(0, last_space + 1);
std::string match_pattern = "";
if (pattern.size() < NAME_PREDICTION_MINIMUM_LENGTH) return;
match_pattern = prefix.substr(last_space + 1, prefix.length() - last_space - 1);
prefix = prefix.substr(0, last_space + 1);
std::string match = pattern;
LLStringUtil::toLower(pattern);
std::string name;
bool found = false;
bool full_name = false;
uuid_vec_t::iterator iter = avatar_ids.begin();
if (last_space != std::string::npos && !prefix.empty())
{
last_space = prefix.substr(0, prefix.length() - 2).rfind(" ");
match_pattern = prefix.substr(last_space + 1, prefix.length() - last_space - 1);
prefix = prefix.substr(0, last_space + 1);
// prepare search pattern
std::string full_pattern(match_pattern + pattern);
LLStringUtil::toLower(full_pattern);
// Look for a match
while (iter != avatar_ids.end() && !found)
{
if (gCacheName->getFullName(*iter++, name))
{
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
name = RlvStrings::getAnonym(name);
}
LLStringUtil::toLower(name);
found = (name.find(full_pattern) == 0);
}
}
}
if (found)
{
full_name = true; // ignore OnlyFirstName in case we want to disambiguate
prefix += match_pattern;
}
else if (!pattern.empty()) // if first search did not work, try matching with last word before cursor only
{
prefix += match_pattern; // first part of the pattern wasn't a pattern, so keep it in prefix
LLStringUtil::toLower(pattern);
iter = avatar_ids.begin();
// Look for a match
while (iter != avatar_ids.end() && !found)
{
if (gCacheName->getFullName(*iter++, name))
{
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
name = RlvStrings::getAnonym(name);
}
LLStringUtil::toLower(name);
found = (name.find(pattern) == 0);
}
}
}
// if we found something by either method, replace the pattern by the avatar name
if (found)
{
std::string first_name, last_name;
gCacheName->getFirstLastName(*(iter - 1), first_name, last_name);
std::string rest_of_match;
std::string replaced_text;
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
replaced_text += RlvStrings::getAnonym(first_name + " " + last_name) + " ";
}
else
{
if (full_name)
{
rest_of_match = /*first_name + " " +*/ last_name.substr(pattern.size());
}
else
{
rest_of_match = first_name.substr(pattern.size());
}
replaced_text += match + rest_of_match + " ";
}
if (!rest_of_match.empty())
{
if (chat_entry)
{
chat_entry->setText(prefix + replaced_text + suffix);
chat_entry->selectByCursorPosition(utf8string_to_wstring(prefix).size() + utf8string_to_wstring(match).size(), utf8string_to_wstring(prefix).size() + utf8string_to_wstring(replaced_text).size());
}
else
{
line_editor->setText(prefix + replaced_text + suffix);
line_editor->setSelection(utf8str_to_wstring(prefix + replaced_text).length(), cur_pos);
}
}
}
}
}
// </FS:CR>
}
class LLChatCommandHandler : public LLCommandHandler
{

View File

@ -32,6 +32,7 @@
#include "llviewerchat.h"
class FSNearbyChatControl;
class LLUICtrl;
class FSNearbyChat : public LLSingleton<FSNearbyChat>
{
@ -52,19 +53,21 @@ public:
void registerChatBar(FSNearbyChatControl* chatBar);
// set the contents of the chat bar to "text" if it was empty, otherwise just show it
void showDefaultChatBar(BOOL visible,const char* text=0) const;
void showDefaultChatBar(BOOL visible, const char* text = NULL) const;
void sendChat(LLWString text,EChatType type);
void sendChat(LLWString text, EChatType type);
static LLWString stripChannelNumber(const LLWString &mesg, S32* channel, S32* last_channel, bool* is_set);
EChatType processChatTypeTriggers(EChatType type, std::string &str);
void sendChatFromViewer(const std::string& utf8text, EChatType type, BOOL animate);
void sendChatFromViewer(const LLWString& wtext, EChatType type, BOOL animate);
void setFocusedInputEditor(FSNearbyChatControl* inputEditor,BOOL focus);
void setFocusedInputEditor(FSNearbyChatControl* inputEditor, BOOL focus);
BOOL defaultChatBarIsIdle() const;
BOOL defaultChatBarHasFocus() const;
static void handleChatBarKeystroke(LLUICtrl* source);
FSNearbyChatControl* mFocusedInputEditor;
};

View File

@ -47,8 +47,6 @@
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
#endif
static const LLAvatarItemAgentOnTopComparator AGENT_ON_TOP_NAME_COMPARATOR;
// helper function to update AvatarList Item's indicator in the voice participant list
static void update_speaker_indicator(const LLAvatarList* const avatar_list, const LLUUID& avatar_uuid, bool is_muted)
{
@ -613,8 +611,7 @@ void FSParticipantList::sort()
}
else
{
mAvatarList->setComparator(&AGENT_ON_TOP_NAME_COMPARATOR);
mAvatarList->sort();
mAvatarList->sortByName(true);
}
break;
case E_SORT_BY_RECENT_SPEAKERS:

View File

@ -159,6 +159,8 @@ static const LLAvatarItemNameComparator NAME_COMPARATOR;
static const LLFlatListView::ItemReverseComparator REVERSE_NAME_COMPARATOR(NAME_COMPARATOR);
// <FS:Ansariel> FIRE-5283: Sort by username
static const LLAvatarItemUserNameComparator USERNAME_COMPARATOR;
// <FS:Ansariel> [FS Communication UI]
static const LLAvatarItemAgentOnTopComparator AGENT_ON_TOP_NAME_COMPARATOR;
LLAvatarList::Params::Params()
: ignore_online_status("ignore_online_status", false)
@ -315,9 +317,21 @@ void LLAvatarList::setNameFilter(const std::string& filter)
}
}
void LLAvatarList::sortByName()
// <FS:Ansariel> [FS Communication UI]
//void LLAvatarList::sortByName()
//{
// setComparator(&NAME_COMPARATOR);
void LLAvatarList::sortByName(bool agent_on_top /* = false*/)
{
setComparator(&NAME_COMPARATOR);
if (agent_on_top)
{
setComparator(&AGENT_ON_TOP_NAME_COMPARATOR);
}
else
{
setComparator(&NAME_COMPARATOR);
}
// </FS:Ansariel>
sort();
}
@ -540,7 +554,15 @@ boost::signals2::connection LLAvatarList::setItemDoubleClickCallback(const mouse
//virtual
S32 LLAvatarList::notifyParent(const LLSD& info)
{
if (info.has("sort") && &NAME_COMPARATOR == mItemComparator)
// <FS:Ansariel> FIRE-11344: Group IM chatter list (and probably other) not sorting properly
//if (info.has("sort") && &NAME_COMPARATOR == mItemComparator)
if (info.has("sort") &&
(
&NAME_COMPARATOR == mItemComparator ||
&USERNAME_COMPARATOR == mItemComparator ||
&AGENT_ON_TOP_NAME_COMPARATOR == mItemComparator
))
// </FS:Ansariel>
{
sort();
return 1;

View File

@ -85,7 +85,10 @@ public:
void showDisplayName(bool visible);
void showUsername(bool visible);
void showVoiceVolume(bool visible);
void sortByName();
// <FS:Ansariel> [FS Communication UI]
//void sortByName();
void sortByName(bool agent_on_top = false);
// </FS:Ansariel>
// <FS:Ansariel> FIRE-5283: Sort by username
void sortByUserName();
void setShowIcons(std::string param_name);

View File

@ -166,7 +166,9 @@ void LLFloaterBvhPreview::setAnimCallbacks()
getChild<LLUICtrl>("playback_slider")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onSliderMove, this));
getChild<LLUICtrl>("preview_base_anim")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitBaseAnim, this));
getChild<LLUICtrl>("preview_base_anim")->setValue("Standing");
// <FS:Sei> FIRE-17251: Use the XUI values for defaults
//getChild<LLUICtrl>("preview_base_anim")->setValue("Standing");
// </FS:Sei>
getChild<LLUICtrl>("priority")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitPriority, this));
getChild<LLUICtrl>("loop_check")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoop, this));
@ -178,7 +180,9 @@ void LLFloaterBvhPreview::setAnimCallbacks()
getChild<LLUICtrl>("hand_pose_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitHandPose, this));
getChild<LLUICtrl>("emote_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEmote, this));
getChild<LLUICtrl>("emote_combo")->setValue("[None]");
// <FS:Sei> FIRE-17251: Use the XUI values for defaults
//getChild<LLUICtrl>("emote_combo")->setValue("[None]");
// </FS:Sei>
getChild<LLUICtrl>("ease_in_time")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEaseIn, this));
getChild<LLUICtrl>("ease_in_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseIn, this, _1));
@ -371,13 +375,22 @@ BOOL LLFloaterBvhPreview::loadBVH()
getChild<LLSlider>("playback_slider")->setMinValue(0.0);
getChild<LLSlider>("playback_slider")->setMaxValue(1.0);
getChild<LLUICtrl>("loop_check")->setValue(LLSD(motionp->getLoop()));
getChild<LLUICtrl>("loop_in_point")->setValue(LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f));
getChild<LLUICtrl>("loop_out_point")->setValue(LLSD(motionp->getLoopOut() / motionp->getDuration() * 100.f));
getChild<LLUICtrl>("priority")->setValue(LLSD((F32)motionp->getPriority()));
getChild<LLUICtrl>("hand_pose_combo")->setValue(LLHandMotion::getHandPoseName(motionp->getHandPose()));
getChild<LLUICtrl>("ease_in_time")->setValue(LLSD(motionp->getEaseInDuration()));
getChild<LLUICtrl>("ease_out_time")->setValue(LLSD(motionp->getEaseOutDuration()));
//<FS:Sei> FIRE-17251: Use defaults from XUI, not from the JointMotionList constructor
//getChild<LLUICtrl>("loop_check")->setValue(LLSD(motionp->getLoop()));
//getChild<LLUICtrl>("loop_in_point")->setValue(LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f));
//getChild<LLUICtrl>("loop_out_point")->setValue(LLSD(motionp->getLoopOut() / motionp->getDuration() * 100.f));
//getChild<LLUICtrl>("priority")->setValue(LLSD((F32)motionp->getPriority()));
//getChild<LLUICtrl>("hand_pose_combo")->setValue(LLHandMotion::getHandPoseName(motionp->getHandPose()));
//getChild<LLUICtrl>("ease_in_time")->setValue(LLSD(motionp->getEaseInDuration()));
//getChild<LLUICtrl>("ease_out_time")->setValue(LLSD(motionp->getEaseOutDuration()));
motionp->setLoop(getChild<LLUICtrl>("loop_check")->getValue().asBoolean());
motionp->setLoopIn((F32)getChild<LLUICtrl>("loop_in_point")->getValue().asReal() / 100.f * motionp->getDuration());
motionp->setLoopOut((F32)getChild<LLUICtrl>("loop_out_point")->getValue().asReal() / 100.f * motionp->getDuration());
motionp->setPriority(getChild<LLUICtrl>("priority")->getValue().asInteger());
motionp->setHandPose(LLHandMotion::getHandPose(getChild<LLUICtrl>("hand_pose_combo")->getValue().asString()));
motionp->setEaseIn((F32)getChild<LLUICtrl>("ease_in_time")->getValue().asReal());
motionp->setEaseOut((F32)getChild<LLUICtrl>("ease_out_time")->getValue().asReal());
//</FS>
setEnabled(TRUE);
std::string seconds_string;
seconds_string = llformat(" - %.2f seconds", motionp->getDuration());

View File

@ -269,7 +269,6 @@ void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChat
LLColor4 chatcolor;
LLViewerChat::getChatColor(chat_msg, chatcolor);
gConsole->addConsoleLine(chat_msg.mText, chatcolor);
gConsole->setVisible(!nearby_chat->getVisible());
}
}
}

View File

@ -58,10 +58,10 @@ static const std::string COLLAPSED_BY_USER = "collapsed_by_user";
class LLTeleportHistoryFlatItem : public LLPanel
{
public:
LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name,
// <FS:Ansariel> Extended TP history
//LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name,
// LLDate date, const std::string &hl);
LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name, const LLDate& date, const LLVector3& local_pos, const std::string &hl);
LLDate date, const LLVector3& local_pos, const std::string &hl);
// </FS:Ansariel>
virtual ~LLTeleportHistoryFlatItem();
@ -73,17 +73,14 @@ public:
void setIndex(S32 index) { mIndex = index; }
const std::string& getRegionName() { return mRegionName;}
void setRegionName(const std::string& name);
// <FS:Ansariel> Extended TP history
//void setDate(LLDate date);
void setDate(LLDate date);
void setHighlightedText(const std::string& text);
void updateTitle();
void updateTimestamp();
std::string getTimestamp();
// <FS:Ansariel> Extended TP history
void setDate(const LLDate& date);
void setLocalPos(const LLVector3& local_pos);
// </FS:Ansariel>
/*virtual*/ void setValue(const LLSD& value);
@ -145,10 +142,10 @@ private:
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name,
// <FS:Ansariel> Extended TP history
//LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name,
// LLDate date, const std::string &hl)
LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name, const LLDate& date, const LLVector3& local_pos, const std::string &hl)
LLDate date, const LLVector3& local_pos, const std::string &hl)
// </FS:Ansariel>
: LLPanel(),
mIndex(index),
@ -182,8 +179,7 @@ BOOL LLTeleportHistoryFlatItem::postBuild()
mProfileBtn->setClickedCallback(boost::bind(&LLTeleportHistoryFlatItem::onProfileBtnClick, this));
updateTitle();
// <FS:Ansariel> Extended TP history
//updateTimestamp();
updateTimestamp();
return true;
}
@ -218,10 +214,7 @@ void LLTeleportHistoryFlatItem::setRegionName(const std::string& name)
mRegionName = name;
}
// <FS:Ansariel> Extended TP history
//void LLTeleportHistoryFlatItem::setDate(LLDate date)
void LLTeleportHistoryFlatItem::setDate(const LLDate& date)
// </FS:Ansariel>
void LLTeleportHistoryFlatItem::setDate(LLDate date)
{
mDate = date;
}
@ -238,23 +231,29 @@ std::string LLTeleportHistoryFlatItem::getTimestamp()
const LLDate &date = mDate;
std::string timestamp = "";
LLDate now = LLDate::now();
S32 now_year, now_month, now_day, now_hour, now_min, now_sec;
now.split(&now_year, &now_month, &now_day, &now_hour, &now_min, &now_sec);
// <FS:Ansariel> Extended TP history
//LLDate now = LLDate::now();
//S32 now_year, now_month, now_day, now_hour, now_min, now_sec;
//now.split(&now_year, &now_month, &now_day, &now_hour, &now_min, &now_sec);
const S32 seconds_in_day = 24 * 60 * 60;
S32 seconds_today = now_hour * 60 * 60 + now_min * 60 + now_sec;
S32 time_diff = (S32) now.secondsSinceEpoch() - (S32) date.secondsSinceEpoch();
//const S32 seconds_in_day = 24 * 60 * 60;
//S32 seconds_today = now_hour * 60 * 60 + now_min * 60 + now_sec;
//S32 time_diff = (S32) now.secondsSinceEpoch() - (S32) date.secondsSinceEpoch();
// Only show timestamp for today and yesterday
if(time_diff < seconds_today + seconds_in_day)
{
timestamp = "[" + LLTrans::getString("TimeHour12")+"]:["
+ LLTrans::getString("TimeMin")+"] ["+ LLTrans::getString("TimeAMPM")+"]";
LLSD substitution;
substitution["datetime"] = (S32) date.secondsSinceEpoch();
LLStringUtil::format(timestamp, substitution);
}
//// Only show timestamp for today and yesterday
//if(time_diff < seconds_today + seconds_in_day)
//{
// timestamp = "[" + LLTrans::getString("TimeHour12")+"]:["
// + LLTrans::getString("TimeMin")+"] ["+ LLTrans::getString("TimeAMPM")+"]";
// LLSD substitution;
// substitution["datetime"] = (S32) date.secondsSinceEpoch();
// LLStringUtil::format(timestamp, substitution);
//}
LLSD args;
args["datetime"] = date.secondsSinceEpoch();
timestamp = getString("DateFmt");
LLStringUtil::format(timestamp, args);
// </FS:Ansariel>
return timestamp;
@ -276,17 +275,6 @@ void LLTeleportHistoryFlatItem::updateTitle()
LLStyle::Params().color(sFgColor),
llformat("%.0f, %.0f, %.0f", mLocalPos.mV[VX], mLocalPos.mV[VY], mLocalPos.mV[VZ]),
mHighlight);
LLSD args;
args["datetime"] = mDate.secondsSinceEpoch();
std::string date = getString("DateFmt");
LLStringUtil::format(date, args);
LLTextUtil::textboxSetHighlightedVal(
mTimeTextBox,
LLStyle::Params().color(sFgColor),
date,
mHighlight);
// </FS:Ansariel>
}

View File

@ -1957,8 +1957,9 @@ void LLViewerWindow::initBase()
cp.name("console");
cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize"));
cp.rect(getChatConsoleRect());
cp.parse_urls(true); // Ansariel: Enable URL parsing for the chat console
cp.background_image("Rounded_Square"); // Ansariel: Configurable background for different console types
cp.parse_urls(true); // <FS:Ansariel> Enable URL parsing for the chat console
cp.background_image("Rounded_Square"); // <FS:Ansariel> Configurable background for different console types
cp.session_support(true); // <FS:Ansariel> Session support
// <FS:AO>, have console respect/reuse NearbyToastLifeTime for the length popup chat messages are displayed.
//cp.persist_time(gSavedSettings.getF32("ChatPersistTime"));
cp.persist_time((F32)gSavedSettings.getS32("NearbyToastLifeTime"));

View File

@ -141,35 +141,35 @@ Maximal erlaubt sind [MAX_LENGTH] Sekunden.
Ausdruck
</text>
<combo_box name="emote_combo" tool_tip="Steuert Gesichtsregungen während der Animation">
<item label="(Keine)" name="[None]" value=""/>
<item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
<item label="Ängstlich" name="Afraid" value="Ängstlich"/>
<item label="Verärgert" name="Angry" value="Verärgert"/>
<item label="Grinst" name="BigSmile" value="Grinst"/>
<item label="Gelangweilt" name="Bored" value="Gelangweilt"/>
<item label="Weinen" name="Cry" value="Weinen"/>
<item label="Verachtung" name="Disdain" value="Verachtung"/>
<item label="Verlegen" name="Embarrassed" value="Verlegen"/>
<item label="Stirnrunzeln" name="Frown" value="Stirnrunzeln"/>
<item label="Küssen" name="Kiss" value="Küssen"/>
<item label="Lachen" name="Laugh" value="Lachen"/>
<item label="Bäääh" name="Plllppt" value="Bäääh"/>
<item label="Angewidert" name="Repulsed" value="Angewidert"/>
<item label="Traurig" name="Sad" value="Traurig"/>
<item label="Achselzucken" name="Shrug" value="Achselzucken"/>
<item label="Lächeln" name="Smile" value="Lächeln"/>
<item label="Überraschung" name="Surprise" value="Überraschung"/>
<item label="Zwinkern" name="Wink" value="Zwinkern"/>
<item label="Sorgenvoll" name="Worry" value="Sorgenvoll"/>
<item label="(Keine)" name="[None]"/>
<item label="Aaaaah" name="Aaaaah"/>
<item label="Ängstlich" name="Afraid"/>
<item label="Verärgert" name="Angry"/>
<item label="Grinst" name="BigSmile"/>
<item label="Gelangweilt" name="Bored"/>
<item label="Weinen" name="Cry"/>
<item label="Verachtung" name="Disdain"/>
<item label="Verlegen" name="Embarrassed"/>
<item label="Stirnrunzeln" name="Frown"/>
<item label="Küssen" name="Kiss"/>
<item label="Lachen" name="Laugh"/>
<item label="Bäääh" name="Plllppt"/>
<item label="Angewidert" name="Repulsed"/>
<item label="Traurig" name="Sad"/>
<item label="Achselzucken" name="Shrug"/>
<item label="Lächeln" name="Smile"/>
<item label="Überraschung" name="Surprise"/>
<item label="Zwinkern" name="Wink"/>
<item label="Sorgenvoll" name="Worry"/>
</combo_box>
<text name="preview_label">
Vorschau während:
</text>
<combo_box name="preview_base_anim" tool_tip="Hiermit können Sie das Verhalten Ihres Avatars testen, während Ihr Avatar normale Bewegungen ausführt.">
<item label="Stehen" name="Standing" value="Stehen"/>
<item label="Gehen" name="Walking" value="Gehen"/>
<item label="Sitzen" name="Sitting" value="Sitzen"/>
<item label="Fliegen" name="Flying" value="Fliegen"/>
<item label="Stehen" name="Standing"/>
<item label="Gehen" name="Walking"/>
<item label="Sitzen" name="Sitting"/>
<item label="Fliegen" name="Flying"/>
</combo_box>
<spinner label="Einblenden (s)" name="ease_in_time" tool_tip="Einblendungszeit für Animationen (in Sekunden)"/>
<spinner label="Ausblenden (s)" name="ease_out_time" tool_tip="Ausblendungszeit für Animationen (in Sekunden)"/>

View File

@ -193,7 +193,7 @@ Maximum animation length is [MAX_LENGTH] seconds.
follows="left|top"
height="23"
increment="1"
initial_value="0"
initial_value="2"
label="Priority"
label_width="88"
layout="topleft"
@ -209,6 +209,7 @@ Maximum animation length is [MAX_LENGTH] seconds.
layout="topleft"
left="10"
width="100"
initial_value="false"
name="loop_check"
tool_tip="Makes this animation loop" />
<spinner
@ -256,6 +257,8 @@ Maximum animation length is [MAX_LENGTH] seconds.
height="23"
layout="topleft"
left_pad="20"
initial_value="Hands_Relaxed"
label=" "
name="hand_pose_combo"
tool_tip="Controls what hands do during animation"
width="130">
@ -330,6 +333,8 @@ Maximum animation length is [MAX_LENGTH] seconds.
width="130"
layout="topleft"
left_pad="20"
initial_value=""
label=" "
name="emote_combo"
tool_tip="Controls what face does during animation">
<item
@ -431,6 +436,8 @@ Maximum animation length is [MAX_LENGTH] seconds.
width="130"
layout="topleft"
left_pad="20"
initial_value="Standing"
label=" "
name="preview_base_anim"
tool_tip="Use this to test your animation behavior while your avatar performs common actions.">
<item

View File

@ -141,35 +141,35 @@ La limite maximale est de [MAX_LENGTH] secondes.
Expression
</text>
<combo_box name="emote_combo" tool_tip="Contrôle ce que fait le visage pendant l&apos;animation.">
<item label="(Aucune)" name="[None]" value=""/>
<item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
<item label="Effrayé" name="Afraid" value="Effrayé"/>
<item label="En colère" name="Angry" value="En colère"/>
<item label="Grand sourire" name="BigSmile" value="Grand sourire"/>
<item label="Ennui" name="Bored" value="Ennui"/>
<item label="Pleurer" name="Cry" value="Pleurer"/>
<item label="Mépris" name="Disdain" value="Mépris"/>
<item label="Gêne" name="Embarrassed" value="Gêne"/>
<item label="Froncer les sourcils" name="Frown" value="Froncer les sourcils"/>
<item label="Embrasser" name="Kiss" value="Embrasser"/>
<item label="Rire" name="Laugh" value="Rire"/>
<item label="Tirer la langue" name="Plllppt" value="Tirer la langue"/>
<item label="Dégoût" name="Repulsed" value="Dégoût"/>
<item label="Triste" name="Sad" value="Triste"/>
<item label="Hausser les épaules" name="Shrug" value="Hausser les épaules"/>
<item label="Sourire" name="Smile" value="Sourire"/>
<item label="Surprise" name="Surprise" value="Surprise"/>
<item label="Clin d&apos;œil" name="Wink" value="Clin d&apos;œil"/>
<item label="Inquiétude" name="Worry" value="Inquiétude"/>
<item label="(Aucune)" name="[None]"/>
<item label="Aaaaah" name="Aaaaah"/>
<item label="Effrayé" name="Afraid"/>
<item label="En colère" name="Angry"/>
<item label="Grand sourire" name="BigSmile"/>
<item label="Ennui" name="Bored"/>
<item label="Pleurer" name="Cry"/>
<item label="Mépris" name="Disdain"/>
<item label="Gêne" name="Embarrassed"/>
<item label="Froncer les sourcils" name="Frown"/>
<item label="Embrasser" name="Kiss"/>
<item label="Rire" name="Laugh"/>
<item label="Tirer la langue" name="Plllppt"/>
<item label="Dégoût" name="Repulsed"/>
<item label="Triste" name="Sad"/>
<item label="Hausser les épaules" name="Shrug"/>
<item label="Sourire" name="Smile"/>
<item label="Surprise" name="Surprise"/>
<item label="Clin d&apos;œil" name="Wink"/>
<item label="Inquiétude" name="Worry"/>
</combo_box>
<text name="preview_label">
Aperçu
</text>
<combo_box name="preview_base_anim" tool_tip="Permet de tester le comportement de l&apos;animation lorsque votre avatar effectue certaines actions courantes.">
<item label="Debout" name="Standing" value="Debout"/>
<item label="En marche" name="Walking" value="En marche"/>
<item label="Assis" name="Sitting" value="Assis"/>
<item label="En vol" name="Flying" value="En vol"/>
<item label="Debout" name="Standing"/>
<item label="En marche" name="Walking"/>
<item label="Assis" name="Sitting"/>
<item label="En vol" name="Flying"/>
</combo_box>
<spinner label="Transition début (s)" name="ease_in_time" tool_tip="Durée (en secondes) de l&apos;entrée en fondu de l&apos;animation."/>
<spinner label="Transition fin (s)" name="ease_out_time" tool_tip="Durée (en secondes) de la sortie en fondu de l&apos;animation."/>

View File

@ -141,35 +141,35 @@ La lunghezza massima dell&apos;animazione è [MAX_LENGTH] secondi.
Espressione
</text>
<combo_box name="emote_combo" tool_tip="Definisce ciò che fa il viso durante l&apos;animazione">
<item label="(Nulla)" name="[None]" value=""/>
<item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
<item label="Spavento" name="Afraid" value="Spavento"/>
<item label="Arrabbiato" name="Angry" value="Arrabbiato"/>
<item label="Grande sorriso" name="BigSmile" value="Grande sorriso"/>
<item label="Annoiato" name="Bored" value="Annoiato"/>
<item label="Pianto" name="Cry" value="Pianto"/>
<item label="Disdegno" name="Disdain" value="Disdegno"/>
<item label="Imbarazzato" name="Embarrassed" value="Imbarazzato"/>
<item label="Accigliato" name="Frown" value="Accigliato"/>
<item label="Bacio" name="Kiss" value="Bacio"/>
<item label="Risata" name="Laugh" value="Risata"/>
<item label="Linguaccia" name="Plllppt" value="Linguaccia"/>
<item label="Repulsione" name="Repulsed" value="Repulsione"/>
<item label="Triste" name="Sad" value="Triste"/>
<item label="Scrollata di spalle" name="Shrug" value="Scrollata di spalle"/>
<item label="Sorriso" name="Smile" value="Sorriso"/>
<item label="Stupore" name="Surprise" value="Stupore"/>
<item label="Occhiolino" name="Wink" value="Occhiolino"/>
<item label="Preoccupato" name="Worry" value="Preoccupato"/>
<item label="(Nulla)" name="[None]"/>
<item label="Aaaaah" name="Aaaaah"/>
<item label="Spavento" name="Afraid"/>
<item label="Arrabbiato" name="Angry"/>
<item label="Grande sorriso" name="BigSmile"/>
<item label="Annoiato" name="Bored"/>
<item label="Pianto" name="Cry"/>
<item label="Disdegno" name="Disdain"/>
<item label="Imbarazzato" name="Embarrassed"/>
<item label="Accigliato" name="Frown"/>
<item label="Bacio" name="Kiss"/>
<item label="Risata" name="Laugh"/>
<item label="Linguaccia" name="Plllppt"/>
<item label="Repulsione" name="Repulsed"/>
<item label="Triste" name="Sad"/>
<item label="Scrollata di spalle" name="Shrug"/>
<item label="Sorriso" name="Smile"/>
<item label="Stupore" name="Surprise"/>
<item label="Occhiolino" name="Wink"/>
<item label="Preoccupato" name="Worry"/>
</combo_box>
<text name="preview_label">
Anteprima mentre
</text>
<combo_box name="preview_base_anim" tool_tip="Prova il comportamento dell&apos;animazione mentre l&apos;avatar esegue attività comuni.">
<item label="In piedi" name="Standing" value="In piedi"/>
<item label="Camminare" name="Walking" value="Camminare"/>
<item label="Seduto" name="Sitting" value="Seduto"/>
<item label="Volare" name="Flying" value="Volare"/>
<item label="In piedi" name="Standing"/>
<item label="Camminare" name="Walking"/>
<item label="Seduto" name="Sitting"/>
<item label="Volare" name="Flying"/>
</combo_box>
<spinner label="Transizione in ingresso (sec)" name="ease_in_time" tool_tip="Durata (in secondi) della fusione in entrata delle animazioni"/>
<spinner label="Transizione in uscita (sec)" name="ease_out_time" tool_tip="Durata (in secondi) della fusione in uscita delle animazioni"/>

View File

@ -141,35 +141,35 @@
表情
</text>
<combo_box name="emote_combo" tool_tip="アニメーション再生中の顔の表情を決めます">
<item label="(なし)" name="[None]" value=""/>
<item label="アーーーーー" name="Aaaaah" value="アーーーーー"/>
<item label="恐れる" name="Afraid" value="恐れる"/>
<item label="怒る" name="Angry" value="怒る"/>
<item label="満面の笑み" name="BigSmile" value="満面の笑み"/>
<item label="退屈" name="Bored" value="退屈"/>
<item label="泣く" name="Cry" value="泣く"/>
<item label="軽蔑" name="Disdain" value="軽蔑"/>
<item label="恥ずかしがる" name="Embarrassed" value="恥ずかしがる"/>
<item label="しかめっ面" name="Frown" value="しかめっ面"/>
<item label="キス" name="Kiss" value="キス"/>
<item label="笑う" name="Laugh" value="笑う"/>
<item label="むかつく" name="Plllppt" value="むかつく"/>
<item label="嫌悪感" name="Repulsed" value="嫌悪感"/>
<item label="悲しい" name="Sad" value="悲しい"/>
<item label="肩をすくめる" name="Shrug" value="肩をすくめる"/>
<item label="微笑む" name="Smile" value="微笑む"/>
<item label="驚く" name="Surprise" value="驚く"/>
<item label="ウィンク" name="Wink" value="ウィンク"/>
<item label="心配する" name="Worry" value="心配する"/>
<item label="(なし)" name="[None]"/>
<item label="アーーーーー" name="Aaaaah"/>
<item label="恐れる" name="Afraid"/>
<item label="怒る" name="Angry"/>
<item label="満面の笑み" name="BigSmile"/>
<item label="退屈" name="Bored"/>
<item label="泣く" name="Cry"/>
<item label="軽蔑" name="Disdain"/>
<item label="恥ずかしがる" name="Embarrassed"/>
<item label="しかめっ面" name="Frown"/>
<item label="キス" name="Kiss"/>
<item label="笑う" name="Laugh"/>
<item label="むかつく" name="Plllppt"/>
<item label="嫌悪感" name="Repulsed"/>
<item label="悲しい" name="Sad"/>
<item label="肩をすくめる" name="Shrug"/>
<item label="微笑む" name="Smile"/>
<item label="驚く" name="Surprise"/>
<item label="ウィンク" name="Wink"/>
<item label="心配する" name="Worry"/>
</combo_box>
<text name="preview_label">
プレビュー中の動作
</text>
<combo_box name="preview_base_anim" tool_tip="これを使用して、アバターが一般的なアクションを実行している間にアニメーションの動作をテストします。">
<item label="立つ" name="Standing" value="立つ"/>
<item label="歩く" name="Walking" value="歩く"/>
<item label="座る" name="Sitting" value="座る"/>
<item label="飛ぶ" name="Flying" value="飛ぶ"/>
<item label="立つ" name="Standing"/>
<item label="歩く" name="Walking"/>
<item label="座る" name="Sitting"/>
<item label="飛ぶ" name="Flying"/>
</combo_box>
<spinner label="イーズイン(秒)" name="ease_in_time" tool_tip="アニメーションのブレンドイン時間(秒)"/>
<spinner label="イーズアウト(秒)" name="ease_out_time" tool_tip="アニメーションのブレンドアウト時間(秒)"/>

View File

@ -141,35 +141,35 @@ A duração máxima da animação é de [MAX_LENGTH] segundos.
Expressão
</text>
<combo_box name="emote_combo" tool_tip="Controla as expressões faciais durante a animação">
<item label="(nenhum)" name="[None]" value=""/>
<item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
<item label="Com medo" name="Afraid" value="Com medo"/>
<item label="Bravo" name="Angry" value="Bravo"/>
<item label="Sorriso contagiante" name="BigSmile" value="Sorriso contagiante"/>
<item label="À toa" name="Bored" value="À toa"/>
<item label="Chorar" name="Cry" value="Chorar"/>
<item label="Desdenho" name="Disdain" value="Desdenho"/>
<item label="Com vergonha" name="Embarrassed" value="Com vergonha"/>
<item label="Franzir testa" name="Frown" value="Franzir testa"/>
<item label="Beijo" name="Kiss" value="Beijo"/>
<item label="Rir" name="Laugh" value="Rir"/>
<item label="Mostrar a língua" name="Plllppt" value="Mostrar a língua"/>
<item label="Asco" name="Repulsed" value="Asco"/>
<item label="Triste" name="Sad" value="Triste"/>
<item label="Encolher os ombros" name="Shrug" value="Encolher os ombros"/>
<item label="Sorriso" name="Smile" value="Sorriso"/>
<item label="Surpresa" name="Surprise" value="Surpresa"/>
<item label="Piscar" name="Wink" value="Piscar"/>
<item label="Preocupado" name="Worry" value="Preocupado"/>
<item label="(nenhum)" name="[None]"/>
<item label="Aaaaah" name="Aaaaah"/>
<item label="Com medo" name="Afraid"/>
<item label="Bravo" name="Angry"/>
<item label="Sorriso contagiante" name="BigSmile"/>
<item label="À toa" name="Bored"/>
<item label="Chorar" name="Cry"/>
<item label="Desdenho" name="Disdain"/>
<item label="Com vergonha" name="Embarrassed"/>
<item label="Franzir testa" name="Frown"/>
<item label="Beijo" name="Kiss"/>
<item label="Rir" name="Laugh"/>
<item label="Mostrar a língua" name="Plllppt"/>
<item label="Asco" name="Repulsed"/>
<item label="Triste" name="Sad"/>
<item label="Encolher os ombros" name="Shrug"/>
<item label="Sorriso" name="Smile"/>
<item label="Surpresa" name="Surprise"/>
<item label="Piscar" name="Wink"/>
<item label="Preocupado" name="Worry"/>
</combo_box>
<text name="preview_label">
Visualizar enquanto
</text>
<combo_box name="preview_base_anim" tool_tip="Use para testar o comportamento de sua animação enquanto seu avatar executa ações comuns.">
<item label="Em pé" name="Standing" value="Em pé"/>
<item label="Andar" name="Walking" value="Andar"/>
<item label="Sentado" name="Sitting" value="Sentado"/>
<item label="Voar" name="Flying" value="Voar"/>
<item label="Em pé" name="Standing"/>
<item label="Andar" name="Walking"/>
<item label="Sentado" name="Sitting"/>
<item label="Voar" name="Flying"/>
</combo_box>
<spinner label="Aproximação (seg)" name="ease_in_time" tool_tip="Tempo (em segundos) da transição inicial da animação"/>
<spinner label="Afastamento (seg)" name="ease_out_time" tool_tip="Tempo (em segundos) da transição de saída da animação"/>

View File

@ -141,35 +141,35 @@
Выражение лица
</text>
<combo_box name="emote_combo" tool_tip="Контролирует выражение лица во время анимации">
<item label="(нет)" name="[None]" value=""/>
<item label="Ааааах" name="Aaaaah" value="Ааааах"/>
<item label="Боится" name="Afraid" value="Боится"/>
<item label="Злится" name="Angry" value="Злится"/>
<item label="Широко улыбается" name="BigSmile" value="Широко улыбается"/>
<item label="Скучает" name="Bored" value="Скучает"/>
<item label="Плачет" name="Cry" value="Плачет"/>
<item label="Презирает" name="Disdain" value="Презирает"/>
<item label="Смущается" name="Embarrassed" value="Смущается"/>
<item label="Хмурится" name="Frown" value="Хмурится"/>
<item label="Целует" name="Kiss" value="Целует"/>
<item label="Смеется" name="Laugh" value="Смеется"/>
<item label="Дразнится" name="Plllppt" value="Дразнится"/>
<item label="Не соглашается" name="Repulsed" value="Не соглашается"/>
<item label="Грустит" name="Sad" value="Грустит"/>
<item label="Не понимает" name="Shrug" value="Не понимает"/>
<item label="Улыбается" name="Smile" value="Улыбается"/>
<item label="Удивляется" name="Surprise" value="Удивляется"/>
<item label="Подмигивает" name="Wink" value="Подмигивает"/>
<item label="Беспокоится" name="Worry" value="Беспокоится"/>
<item label="(нет)" name="[None]"/>
<item label="Ааааах" name="Aaaaah"/>
<item label="Боится" name="Afraid"/>
<item label="Злится" name="Angry"/>
<item label="Широко улыбается" name="BigSmile"/>
<item label="Скучает" name="Bored"/>
<item label="Плачет" name="Cry"/>
<item label="Презирает" name="Disdain"/>
<item label="Смущается" name="Embarrassed"/>
<item label="Хмурится" name="Frown"/>
<item label="Целует" name="Kiss"/>
<item label="Смеется" name="Laugh"/>
<item label="Дразнится" name="Plllppt"/>
<item label="Не соглашается" name="Repulsed"/>
<item label="Грустит" name="Sad"/>
<item label="Не понимает" name="Shrug"/>
<item label="Улыбается" name="Smile"/>
<item label="Удивляется" name="Surprise"/>
<item label="Подмигивает" name="Wink"/>
<item label="Беспокоится" name="Worry"/>
</combo_box>
<text name="preview_label">
Просмотр во время
</text>
<combo_box name="preview_base_anim" tool_tip="Просмотр вашей анимации во время выполнения аватаром действий.">
<item label="Стояние" name="Standing" value="Стояние"/>
<item label="Ходьба" name="Walking" value="Ходьба"/>
<item label="Сидение" name="Sitting" value="Сидение"/>
<item label="Полет" name="Flying" value="Полет"/>
<item label="Стояние" name="Standing"/>
<item label="Ходьба" name="Walking"/>
<item label="Сидение" name="Sitting"/>
<item label="Полет" name="Flying"/>
</combo_box>
<spinner label="Вход (сек.)" name="ease_in_time" tool_tip="Количество времени (в секундах) для входа в стартовое положение"/>
<spinner label="Выход (сек.)" name="ease_out_time" tool_tip="Количество времени (в секундах) для выхода из анимации"/>

View File

@ -141,35 +141,35 @@ Maksimum animasyon uzunluğu [LENGTH] saniye.
İfade
</text>
<combo_box name="emote_combo" tool_tip="Yüzün animasyon sırasındaki ifadesini kontrol eder">
<item label="(Hiçbiri)" name="[None]" value=""/>
<item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
<item label="Korkmuş" name="Afraid" value="Korkmuş"/>
<item label="Kızgın" name="Angry" value="Kızgın"/>
<item label="Yaygın Gülümseyiş" name="BigSmile" value="Yaygın Gülümseyiş"/>
<item label="Canı Sıkılmış" name="Bored" value="Canı Sıkılmış"/>
<item label="Ağlama" name="Cry" value="Ağlama"/>
<item label="Dudak Bükme" name="Disdain" value="Dudak Bükme"/>
<item label="Utanmış" name="Embarrassed" value="Utanmış"/>
<item label="Kaş Çatma" name="Frown" value="Kaş Çatma"/>
<item label="Öpücük" name="Kiss" value="Öpücük"/>
<item label="Gülme" name="Laugh" value="Gülme"/>
<item label="Kahkaha" name="Plllppt" value="Kahkaha"/>
<item label="Tiksinmiş" name="Repulsed" value="Tiksinmiş"/>
<item label="Üzgün" name="Sad" value="Üzgün"/>
<item label="Omuz Silkme" name="Shrug" value="Omuz Silkme"/>
<item label="Gülümseme" name="Smile" value="Gülümseme"/>
<item label="Sürpriz" name="Surprise" value="Sürpriz"/>
<item label="Göz Kırpma" name="Wink" value="Göz Kırpma"/>
<item label="Endişelenme" name="Worry" value="Endişelenme"/>
<item label="(Hiçbiri)" name="[None]"/>
<item label="Aaaaah" name="Aaaaah"/>
<item label="Korkmuş" name="Afraid"/>
<item label="Kızgın" name="Angry"/>
<item label="Yaygın Gülümseyiş" name="BigSmile"/>
<item label="Canı Sıkılmış" name="Bored"/>
<item label="Ağlama" name="Cry"/>
<item label="Dudak Bükme" name="Disdain"/>
<item label="Utanmış" name="Embarrassed"/>
<item label="Kaş Çatma" name="Frown"/>
<item label="Öpücük" name="Kiss"/>
<item label="Gülme" name="Laugh"/>
<item label="Kahkaha" name="Plllppt"/>
<item label="Tiksinmiş" name="Repulsed"/>
<item label="Üzgün" name="Sad"/>
<item label="Omuz Silkme" name="Shrug"/>
<item label="Gülümseme" name="Smile"/>
<item label="Sürpriz" name="Surprise"/>
<item label="Göz Kırpma" name="Wink"/>
<item label="Endişelenme" name="Worry"/>
</combo_box>
<text name="preview_label">
Şu sırada önizle
</text>
<combo_box name="preview_base_anim" tool_tip="Animasyon davranışınızı avatarınız genel hareketleri yaparken test etmek için bunu kullanın.">
<item label="Ayakta Duruyor" name="Standing" value="Ayakta Duruyor"/>
<item label="Yürüyor" name="Walking" value="Yürüyor"/>
<item label="Oturuyor" name="Sitting" value="Oturuyor"/>
<item label="Uçuyor" name="Flying" value="Uçuyor"/>
<item label="Ayakta Duruyor" name="Standing"/>
<item label="Yürüyor" name="Walking"/>
<item label="Oturuyor" name="Sitting"/>
<item label="Uçuyor" name="Flying"/>
</combo_box>
<spinner label="Yavaş Başlangıç (saniye)" name="ease_in_time" tool_tip="Animasyonun kaynaştığı süre (saniye olarak)"/>
<spinner label="Yavaş Bitiş (saniye)" name="ease_out_time" tool_tip="Animasyonun ayrıştığı süre (saniye olarak)"/>

View File

@ -141,35 +141,35 @@
表情
</text>
<combo_box name="emote_combo" tool_tip="控制動作演繹時臉部的姿態">
<item label="(無)" name="[None]" value=""/>
<item label="張口吶喊貌" name="Aaaaah" value="張口吶喊貌"/>
<item label="害怕" name="Afraid" value="害怕"/>
<item label="生氣" name="Angry" value="生氣"/>
<item label="燦爛笑容" name="BigSmile" value="燦爛笑容"/>
<item label="無聊" name="Bored" value="無聊"/>
<item label="哭泣" name="Cry" value="哭泣"/>
<item label="鄙視" name="Disdain" value="鄙視"/>
<item label="尷尬" name="Embarrassed" value="尷尬"/>
<item label="皺眉" name="Frown" value="皺眉"/>
<item label="親吻" name="Kiss" value="親吻"/>
<item label="笑" name="Laugh" value="笑"/>
<item label="嫌惡貌" name="Plllppt" value="嫌惡貌"/>
<item label="作噁" name="Repulsed" value="作噁"/>
<item label="傷心" name="Sad" value="傷心"/>
<item label="聳聳肩" name="Shrug" value="聳聳肩"/>
<item label="微笑" name="Smile" value="微笑"/>
<item label="驚喜" name="Surprise" value="驚喜"/>
<item label="眨眼" name="Wink" value="眨眼"/>
<item label="擔心" name="Worry" value="擔心"/>
<item label="(無)" name="[None]"/>
<item label="張口吶喊貌" name="Aaaaah"/>
<item label="害怕" name="Afraid"/>
<item label="生氣" name="Angry"/>
<item label="燦爛笑容" name="BigSmile"/>
<item label="無聊" name="Bored"/>
<item label="哭泣" name="Cry"/>
<item label="鄙視" name="Disdain"/>
<item label="尷尬" name="Embarrassed"/>
<item label="皺眉" name="Frown"/>
<item label="親吻" name="Kiss"/>
<item label="笑" name="Laugh"/>
<item label="嫌惡貌" name="Plllppt"/>
<item label="作噁" name="Repulsed"/>
<item label="傷心" name="Sad"/>
<item label="聳聳肩" name="Shrug"/>
<item label="微笑" name="Smile"/>
<item label="驚喜" name="Surprise"/>
<item label="眨眼" name="Wink"/>
<item label="擔心" name="Worry"/>
</combo_box>
<text name="preview_label">
預覽…
</text>
<combo_box name="preview_base_anim" tool_tip="用這個來測試你的化身從一般動作轉入動作演繹時的情況。">
<item label="站立" name="Standing" value="站立"/>
<item label="步行中" name="Walking" value="步行中"/>
<item label="坐著" name="Sitting" value="坐著"/>
<item label="飛行" name="Flying" value="飛行"/>
<item label="站立" name="Standing"/>
<item label="步行中" name="Walking"/>
<item label="坐著" name="Sitting"/>
<item label="飛行" name="Flying"/>
</combo_box>
<spinner label="淡入(秒)" name="ease_in_time" tool_tip="動作攙混植入的時間長度(秒)"/>
<spinner label="淡出(秒)" name="ease_out_time" tool_tip="動作攙混淡出的時間長度(秒)"/>

View File

@ -92,7 +92,7 @@ linux = http://downloads.phoenixviewer.com/llqtwebkit-4.7.1-linux-x64-201505150
linux = http://downloads.phoenixviewer.com/SDL-1.2.15-linux-x64-201509062227-r43.tar.bz2|2566e373b89a2e4f8e93a78948deda10
[open-libndofdev]
linux = http://downloads.phoenixviewer.com/open_libndofdev-0.6-linux-x64-201509062233-r14.tar.bz2|240c5937f467c61e3d5ca6647c24295f
linux = http://downloads.phoenixviewer.com/open_libndofdev-0.6-linux-x64-201511091824-r14.tar.bz2|58ba081f6f10b8a29604451ab1076370
[uriparser]
linux = http://downloads.phoenixviewer.com/uriparser-0.8.0.1-linux-x64-201502251606-r15.tar.bz2|e67a27e13e546cbb13fad2665a1896b7