From b2770f2f55ea20066cd2f3fc202c73198263e8a4 Mon Sep 17 00:00:00 2001 From: Nicky Date: Mon, 9 Nov 2015 10:04:45 +0100 Subject: [PATCH 1/9] Tip to default. --- README_BUILD_FIRESTORM_LINUX.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/README_BUILD_FIRESTORM_LINUX.txt b/README_BUILD_FIRESTORM_LINUX.txt index 2beec5e46f..7a54f90c03 100755 --- a/README_BUILD_FIRESTORM_LINUX.txt +++ b/README_BUILD_FIRESTORM_LINUX.txt @@ -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 From 73e4267504c5d20727773b39afe75a4747ac5dbb Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 10 Nov 2015 09:06:16 +0100 Subject: [PATCH 2/9] FIRE-11344: Group IM chatter list (and probably other) not sorting properly --- indra/newview/fsparticipantlist.cpp | 5 +---- indra/newview/llavatarlist.cpp | 28 +++++++++++++++++++++++++--- indra/newview/llavatarlist.h | 5 ++++- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/indra/newview/fsparticipantlist.cpp b/indra/newview/fsparticipantlist.cpp index d21355aeb3..a136c558d2 100644 --- a/indra/newview/fsparticipantlist.cpp +++ b/indra/newview/fsparticipantlist.cpp @@ -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) { @@ -605,8 +603,7 @@ void FSParticipantList::sort() } else { - mAvatarList->setComparator(&AGENT_ON_TOP_NAME_COMPARATOR); - mAvatarList->sort(); + mAvatarList->sortByName(true); } break; case E_SORT_BY_RECENT_SPEAKERS: diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 15d760ba44..e0f4c98ea2 100755 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -226,6 +226,8 @@ static const LLAvatarItemNameComparator NAME_COMPARATOR; static const LLFlatListView::ItemReverseComparator REVERSE_NAME_COMPARATOR(NAME_COMPARATOR); // FIRE-5283: Sort by username static const LLAvatarItemUserNameComparator USERNAME_COMPARATOR; +// [FS Communication UI] +static const LLAvatarItemAgentOnTopComparator AGENT_ON_TOP_NAME_COMPARATOR; LLAvatarList::Params::Params() : ignore_online_status("ignore_online_status", false) @@ -453,9 +455,21 @@ void LLAvatarList::onFocusReceived() gEditMenuHandler = this; } -void LLAvatarList::sortByName() +// [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); + } +// sort(); } @@ -678,7 +692,15 @@ boost::signals2::connection LLAvatarList::setItemDoubleClickCallback(const mouse //virtual S32 LLAvatarList::notifyParent(const LLSD& info) { - if (info.has("sort") && &NAME_COMPARATOR == mItemComparator) + // 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 + )) + // { sort(); return 1; diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index f99ed63cd0..728d399fd2 100755 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -93,7 +93,10 @@ public: void showAvatarAge(bool visible); void showUsername(bool visible); void showVoiceVolume(bool visible); - void sortByName(); + // [FS Communication UI] + //void sortByName(); + void sortByName(bool agent_on_top = false); + // // FIRE-5283: Sort by username void sortByUserName(); void setShowIcons(std::string param_name); From 722adec6a9f813d9ef1ced4ab01592e9f68d7ffc Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 10 Nov 2015 17:09:07 +0100 Subject: [PATCH 3/9] FIRE-17258: Fix dates disappearing when entering a search term in teleport history; also made extended TP history less intrusive --- indra/newview/llpanelteleporthistory.cpp | 68 ++++++++++-------------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 86fe7ddd84..dc0d396479 100755 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -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 ®ion_name, // Extended TP history - //LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, // LLDate date, const std::string &hl); - LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, const LLDate& date, const LLVector3& local_pos, const std::string &hl); + LLDate date, const LLVector3& local_pos, const std::string &hl); // 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); - // Extended TP history - //void setDate(LLDate date); + void setDate(LLDate date); void setHighlightedText(const std::string& text); void updateTitle(); void updateTimestamp(); std::string getTimestamp(); // Extended TP history - void setDate(const LLDate& date); void setLocalPos(const LLVector3& local_pos); - // /*virtual*/ void setValue(const LLSD& value); @@ -145,10 +142,10 @@ private: //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// +LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, // Extended TP history -//LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, // LLDate date, const std::string &hl) -LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, const LLDate& date, const LLVector3& local_pos, const std::string &hl) + LLDate date, const LLVector3& local_pos, const std::string &hl) // : LLPanel(), mIndex(index), @@ -182,8 +179,7 @@ BOOL LLTeleportHistoryFlatItem::postBuild() mProfileBtn->setClickedCallback(boost::bind(&LLTeleportHistoryFlatItem::onProfileBtnClick, this)); updateTitle(); - // Extended TP history - //updateTimestamp(); + updateTimestamp(); return true; } @@ -218,10 +214,7 @@ void LLTeleportHistoryFlatItem::setRegionName(const std::string& name) mRegionName = name; } -// Extended TP history -//void LLTeleportHistoryFlatItem::setDate(LLDate date) -void LLTeleportHistoryFlatItem::setDate(const LLDate& date) -// +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); + // 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); + // 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); // } From 4a77254d67a903bcd7c9dd4fa41055c24f6517e1 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 11 Nov 2015 08:58:43 +0100 Subject: [PATCH 4/9] FIRE-17261: Facial expressions in animation uploader do not work for most languages; fix by Sei Lisa --- .../xui/de/floater_animation_bvh_preview.xml | 48 +++++++++---------- .../xui/fr/floater_animation_bvh_preview.xml | 48 +++++++++---------- .../xui/it/floater_animation_bvh_preview.xml | 48 +++++++++---------- .../xui/ja/floater_animation_bvh_preview.xml | 48 +++++++++---------- .../xui/pt/floater_animation_bvh_preview.xml | 48 +++++++++---------- .../xui/ru/floater_animation_bvh_preview.xml | 48 +++++++++---------- .../xui/tr/floater_animation_bvh_preview.xml | 48 +++++++++---------- .../xui/zh/floater_animation_bvh_preview.xml | 48 +++++++++---------- 8 files changed, 192 insertions(+), 192 deletions(-) diff --git a/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml index 3c865efb0b..42a8edd94b 100755 --- a/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml @@ -141,35 +141,35 @@ Maximal erlaubt sind [MAX_LENGTH] Sekunden. Ausdruck - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + Vorschau während: - - - - + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml index 84c40b5987..a20b8cdf72 100755 --- a/indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml @@ -141,35 +141,35 @@ La limite maximale est de [MAX_LENGTH] secondes. Expression - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + Aperçu - - - - + + + + diff --git a/indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml index a4319f2e77..292fac5b7d 100755 --- a/indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml @@ -141,35 +141,35 @@ La lunghezza massima dell'animazione è [MAX_LENGTH] secondi. Espressione - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + Anteprima mentre - - - - + + + + diff --git a/indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml index f74bab3598..20c7298462 100755 --- a/indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml @@ -141,35 +141,35 @@ 表情 - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + プレビュー中の動作 - - - - + + + + diff --git a/indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml index 5cae581045..64515dfa61 100755 --- a/indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml @@ -141,35 +141,35 @@ A duração máxima da animação é de [MAX_LENGTH] segundos. Expressão - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + Visualizar enquanto - - - - + + + + diff --git a/indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml index 8ad9d8657a..d709987147 100755 --- a/indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml @@ -141,35 +141,35 @@ Выражение лица - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + Просмотр во время - - - - + + + + diff --git a/indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml index f8800c674d..c4e2fd2a93 100755 --- a/indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml @@ -141,35 +141,35 @@ Maksimum animasyon uzunluğu [LENGTH] saniye. İfade - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + Şu sırada önizle - - - - + + + + diff --git a/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml index ffb0de8a68..756cca825d 100755 --- a/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml @@ -141,35 +141,35 @@ 表情 - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + 預覽… - - - - + + + + From c546da140084cc90ab9e68168b33e615cb8c88b0 Mon Sep 17 00:00:00 2001 From: Nicky Date: Wed, 11 Nov 2015 13:13:27 +0100 Subject: [PATCH 5/9] Updated ndof-dev for Linux x64. --- indra/cmake/NDOF.cmake | 6 +----- package_override_gcc.ini | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/indra/cmake/NDOF.cmake b/indra/cmake/NDOF.cmake index 4a598c773d..388df16a52 100755 --- a/indra/cmake/NDOF.cmake +++ b/indra/cmake/NDOF.cmake @@ -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) diff --git a/package_override_gcc.ini b/package_override_gcc.ini index 5a9d492533..98790e02a8 100644 --- a/package_override_gcc.ini +++ b/package_override_gcc.ini @@ -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 From 9036ed275af9434e9db1b4f60f0ae4e5704b13a4 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 11 Nov 2015 13:55:23 +0100 Subject: [PATCH 6/9] FIRE-2436: Change behavior of chat console: Chat console will now always show the chat for sessions that are currently not shown by a visible floater --- indra/llui/llconsole.cpp | 124 ++++++++++++++++++-- indra/llui/llconsole.h | 20 +++- indra/newview/fsconsoleutils.cpp | 10 +- indra/newview/fsconsoleutils.h | 2 +- indra/newview/fsfloaterim.cpp | 6 + indra/newview/fsfloaternearbychat.cpp | 31 ++--- indra/newview/llnotificationhandlerutil.cpp | 1 - indra/newview/llviewerwindow.cpp | 5 +- 8 files changed, 154 insertions(+), 45 deletions(-) diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index e2e0efee10..a5fb5387a1 100755 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -63,7 +63,8 @@ LLConsole::LLConsole(const LLConsole::Params& p) mFont(p.font), mConsoleWidth(0), mConsoleHeight(0), - mParseUrls(p.parse_urls) // If lines should be parsed for URLs + mParseUrls(p.parse_urls), // If lines should be parsed for URLs + mSessionSupport(p.session_support) // Session support { if (p.font_size_index.isProvided()) { @@ -174,6 +175,11 @@ void LLConsole::draw() return; } + // Session support + if (!mSessionSupport) + { + // This is done in update() if session support is enabled + // U32 num_lines=0; paragraph_t::reverse_iterator paragraph_it; @@ -196,6 +202,9 @@ void LLConsole::draw() paragraph_num--; paragraph_it++; } + // Session support + } + // if (mParagraphs.empty()) { @@ -267,6 +276,7 @@ void LLConsole::draw() // y_pos += padding_vertical; //} + paragraph_t::reverse_iterator paragraph_it; static LLCachedControl 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() } // 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. -// Added styleflags parameter for style customization +// 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) // -: mParagraphText(str), mAddTime(add_time), mMaxWidth(-1) { // 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(); // } } // 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) + // Session support + if (!mSessionSupport) + { + // while ((S32)mParagraphs.size() > llmax((S32)0, (S32)(mMaxLines))) { mParagraphs.pop_front(); } + // 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 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); + } + // } +// Session support +void LLConsole::addSession(const LLUUID& session_id) +{ + mCurrentSessions.insert(session_id); +} + +void LLConsole::removeSession(const LLUUID& session_id) +{ + mCurrentSessions.erase(session_id); +} +// diff --git a/indra/llui/llconsole.h b/indra/llui/llconsole.h index a16f849186..86f1ac87c3 100755 --- a/indra/llui/llconsole.h +++ b/indra/llui/llconsole.h @@ -52,13 +52,15 @@ public: Optional font_size_index; Optional parse_urls; // If lines should be parsed for URLs Optional background_image; // Configurable background for different console types + Optional session_support; // 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), // If lines should be parsed for URLs - background_image("background_image", "Console_Background") // Configurable background for different console types + background_image("background_image", "Console_Background"), // Configurable background for different console types + session_support("session_support", false) // Session support { changeDefault(mouse_opaque, false); } @@ -120,7 +122,7 @@ public: public: // 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); // void makeParagraphColorSegments ( const LLColor4 &color); // 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; // Session support // Parse SLURLs LLUUID mID; @@ -160,12 +163,15 @@ public: /*virtual*/ void draw(); // 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 mLineColors; std::deque mLineStyle; + std::deque mSessionIDs; protected: /*virtual*/ void removeExtraLines(); @@ -183,6 +189,10 @@ private: S32 mConsoleHeight; bool mParseUrls; // If lines should be parsed for URLs LLUIImagePtr mBackgroundImage; // Configurable background for different console types + // Session support + std::set mCurrentSessions; + bool mSessionSupport; + // }; extern LLConsole* gConsole; diff --git a/indra/newview/fsconsoleutils.cpp b/indra/newview/fsconsoleutils.cpp index a5a7a131bc..dbda6fbfe9 100644 --- a/indra/newview/fsconsoleutils.cpp +++ b/indra/newview/fsconsoleutils.cpp @@ -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); } diff --git a/indra/newview/fsconsoleutils.h b/indra/newview/fsconsoleutils.h index 03e74a34b2..80e1fd0a61 100644 --- a/indra/newview/fsconsoleutils.h +++ b/indra/newview/fsconsoleutils.h @@ -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); }; diff --git a/indra/newview/fsfloaterim.cpp b/indra/newview/fsfloaterim.cpp index 6c12cd4304..f737ca9a30 100644 --- a/indra/newview/fsfloaterim.cpp +++ b/indra/newview/fsfloaterim.cpp @@ -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); } } diff --git a/indra/newview/fsfloaternearbychat.cpp b/indra/newview/fsfloaternearbychat.cpp index 93b7fb1a13..2329e9c5bf 100644 --- a/indra/newview/fsfloaternearbychat.cpp +++ b/indra/newview/fsfloaternearbychat.cpp @@ -118,7 +118,7 @@ void FSFloaterNearbyChat::updateFSUseNearbyChatConsole(const LLSD &data) if (FSUseNearbyChatConsole) { removeScreenChat(); - gConsole->setVisible(!getVisible()); + gConsole->setVisible(TRUE); } else { @@ -386,26 +386,6 @@ void FSFloaterNearbyChat::setVisible(BOOL visible) } LLFloater::setVisible(visible); - // Support for chat console - static LLCachedControl 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()); - } - } - // Support for chat console - BOOL is_minimized = visible && isChatMultiTab() ? FSFloaterIMContainer::getInstance()->isMinimized() : !visible; @@ -423,6 +403,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 ) diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 45301c4dd0..2c976a57f1 100755 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -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()); } } } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 80ea22b93d..4c57592bf5 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -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); // Enable URL parsing for the chat console + cp.background_image("Rounded_Square"); // Configurable background for different console types + cp.session_support(true); // Session support // , 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")); From b97ceaa77bc925c8bf43d4aded27efdbf1d6e7f6 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 11 Nov 2015 14:17:47 +0100 Subject: [PATCH 7/9] FIRE-17251: Allow users to set default values for animation uploads - patch by Sei Lisa; this also fixes FIRE-13738 (Default hand position is spread instead of relaxed) --- indra/newview/llfloaterbvhpreview.cpp | 31 +++++++++++++------ .../xui/en/floater_animation_bvh_preview.xml | 9 +++++- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 947a985681..3b1aee77d1 100755 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -166,7 +166,9 @@ void LLFloaterBvhPreview::setAnimCallbacks() getChild("playback_slider")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onSliderMove, this)); getChild("preview_base_anim")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitBaseAnim, this)); - getChild("preview_base_anim")->setValue("Standing"); + // FIRE-17251: Use the XUI values for defaults + //getChild("preview_base_anim")->setValue("Standing"); + // getChild("priority")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitPriority, this)); getChild("loop_check")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoop, this)); @@ -178,7 +180,9 @@ void LLFloaterBvhPreview::setAnimCallbacks() getChild("hand_pose_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitHandPose, this)); getChild("emote_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEmote, this)); - getChild("emote_combo")->setValue("[None]"); + // FIRE-17251: Use the XUI values for defaults + //getChild("emote_combo")->setValue("[None]"); + // getChild("ease_in_time")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEaseIn, this)); getChild("ease_in_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseIn, this, _1)); @@ -371,13 +375,22 @@ BOOL LLFloaterBvhPreview::loadBVH() getChild("playback_slider")->setMinValue(0.0); getChild("playback_slider")->setMaxValue(1.0); - getChild("loop_check")->setValue(LLSD(motionp->getLoop())); - getChild("loop_in_point")->setValue(LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f)); - getChild("loop_out_point")->setValue(LLSD(motionp->getLoopOut() / motionp->getDuration() * 100.f)); - getChild("priority")->setValue(LLSD((F32)motionp->getPriority())); - getChild("hand_pose_combo")->setValue(LLHandMotion::getHandPoseName(motionp->getHandPose())); - getChild("ease_in_time")->setValue(LLSD(motionp->getEaseInDuration())); - getChild("ease_out_time")->setValue(LLSD(motionp->getEaseOutDuration())); + // FIRE-17251: Use defaults from XUI, not from the JointMotionList constructor + //getChild("loop_check")->setValue(LLSD(motionp->getLoop())); + //getChild("loop_in_point")->setValue(LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f)); + //getChild("loop_out_point")->setValue(LLSD(motionp->getLoopOut() / motionp->getDuration() * 100.f)); + //getChild("priority")->setValue(LLSD((F32)motionp->getPriority())); + //getChild("hand_pose_combo")->setValue(LLHandMotion::getHandPoseName(motionp->getHandPose())); + //getChild("ease_in_time")->setValue(LLSD(motionp->getEaseInDuration())); + //getChild("ease_out_time")->setValue(LLSD(motionp->getEaseOutDuration())); + motionp->setLoop(getChild("loop_check")->getValue().asBoolean()); + motionp->setLoopIn((F32)getChild("loop_in_point")->getValue().asReal() / 100.f * motionp->getDuration()); + motionp->setLoopOut((F32)getChild("loop_out_point")->getValue().asReal() / 100.f * motionp->getDuration()); + motionp->setPriority(getChild("priority")->getValue().asInteger()); + motionp->setHandPose(LLHandMotion::getHandPose(getChild("hand_pose_combo")->getValue().asString())); + motionp->setEaseIn((F32)getChild("ease_in_time")->getValue().asReal()); + motionp->setEaseOut((F32)getChild("ease_out_time")->getValue().asReal()); + // setEnabled(TRUE); std::string seconds_string; seconds_string = llformat(" - %.2f seconds", motionp->getDuration()); diff --git a/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml index 9cb3ab83bf..453a92c5e5 100755 --- a/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml @@ -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" /> @@ -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"> Date: Wed, 11 Nov 2015 16:41:44 +0100 Subject: [PATCH 8/9] Maintenance: Synchronize FSFloaterNearbyChat::onChatBoxKeystroke() and FSNearbyChatControl::onKeystroke() for further refactoring; this also synchronizes previously different behavior with gesture completion --- indra/newview/fsfloaternearbychat.cpp | 50 +++++++-------- indra/newview/fsnearbychatcontrol.cpp | 88 +++++++++++++-------------- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/indra/newview/fsfloaternearbychat.cpp b/indra/newview/fsfloaternearbychat.cpp index 2329e9c5bf..841f5bd30b 100644 --- a/indra/newview/fsfloaternearbychat.cpp +++ b/indra/newview/fsfloaternearbychat.cpp @@ -753,13 +753,12 @@ BOOL FSFloaterNearbyChat::matchChatTypeTrigger(const std::string& in_str, std::s 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")) @@ -769,12 +768,13 @@ void FSFloaterNearbyChat::onChatBoxKeystroke() channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); // [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] + 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) @@ -784,10 +784,10 @@ void FSFloaterNearbyChat::onChatBoxKeystroke() { gAgent.stopTyping(); } - + KEY key = gKeyboard->currentKey(); MASK mask = gKeyboard->currentMask(FALSE); - + // Ignore "special" keys, like backspace, arrows, etc. if (length > 1 && raw_text[0] == '/' @@ -795,17 +795,17 @@ void FSFloaterNearbyChat::onChatBoxKeystroke() && 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()); @@ -818,7 +818,7 @@ void FSFloaterNearbyChat::onChatBoxKeystroke() mInputEditor->endOfDoc(); } } - + // FIRE-3192 - Predictive name completion, based on code by Satomi Ahn static LLCachedControl sNameAutocomplete(gSavedSettings, "FSChatbarNamePrediction"); if (length > NAME_PREDICTION_MINIMUM_LENGTH && sNameAutocomplete && key < KEY_SPECIAL && mask != MASK_CONTROL) @@ -829,9 +829,9 @@ void FSFloaterNearbyChat::onChatBoxKeystroke() // 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 = ""; @@ -841,32 +841,32 @@ void FSFloaterNearbyChat::onChatBoxKeystroke() } 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) { @@ -881,7 +881,7 @@ void FSFloaterNearbyChat::onChatBoxKeystroke() } } } - + if (found) { full_name = true; // ignore OnlyFirstName in case we want to disambiguate @@ -892,7 +892,7 @@ void FSFloaterNearbyChat::onChatBoxKeystroke() 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) { @@ -907,7 +907,7 @@ void FSFloaterNearbyChat::onChatBoxKeystroke() } } } - + // if we found something by either method, replace the pattern by the avatar name if (found) { diff --git a/indra/newview/fsnearbychatcontrol.cpp b/indra/newview/fsnearbychatcontrol.cpp index f22e8d7d2a..48a279b497 100644 --- a/indra/newview/fsnearbychatcontrol.cpp +++ b/indra/newview/fsnearbychatcontrol.cpp @@ -88,19 +88,12 @@ FSNearbyChatControl::~FSNearbyChatControl() 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")) @@ -110,12 +103,13 @@ void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); // [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] + 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) @@ -125,33 +119,34 @@ void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) { gAgent.stopTyping(); } - + KEY key = gKeyboard->currentKey(); - MASK mask = gKeyboard->currentMask(FALSE); // FIRE-3192 - Predictive name completion - + MASK mask = gKeyboard->currentMask(FALSE); + // Ignore "special" keys, like backspace, arrows, etc. - if (length > 1 + if (length > 1 && raw_text[0] == '/' - // Optional gesture autocomplete - //&& key < KEY_SPECIAL) && key < KEY_SPECIAL && gSavedSettings.getBOOL("FSChatbarGestureAutoCompleteEnable")) - // 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); + if (!rest_of_match.empty()) + { + caller->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 = caller->getLength(); // in characters + caller->setSelection(length, outlength); + caller->setCursor(outlength); + } } else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str)) { @@ -160,7 +155,8 @@ void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) caller->setCursorToEnd(); } } -// FIRE-3192 - Predictive name completion, based on code by Satomi Ahn + + // FIRE-3192 - Predictive name completion, based on code by Satomi Ahn static LLCachedControl sNameAutocomplete(gSavedSettings, "FSChatbarNamePrediction"); if (length > NAME_PREDICTION_MINIMUM_LENGTH && sNameAutocomplete && key < KEY_SPECIAL && mask != MASK_CONTROL) { @@ -170,9 +166,9 @@ void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) // 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 = ""; @@ -182,32 +178,32 @@ void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) } 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) { @@ -222,7 +218,7 @@ void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) } } } - + if (found) { full_name = true; // ignore OnlyFirstName in case we want to disambiguate @@ -233,7 +229,7 @@ void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) 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) { @@ -248,19 +244,20 @@ void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) } } } - + // 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)) { - prefix += RlvStrings::getAnonym(first_name + " " + last_name) + " "; + replaced_text += 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()); @@ -269,14 +266,17 @@ void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) { rest_of_match = first_name.substr(pattern.size()); } - prefix += match + rest_of_match + " "; + replaced_text += match + rest_of_match + " "; + } + if (!rest_of_match.empty()) + { + caller->setText(prefix + replaced_text + suffix); + caller->setSelection(utf8str_to_wstring(prefix + replaced_text).length(), cur_pos); } - caller->setText(prefix + suffix); - caller->setSelection(utf8str_to_wstring(prefix).length(), cur_pos); } } } -// + // } BOOL FSNearbyChatControl::matchChatTypeTrigger(const std::string& in_str, std::string* out_str) From 4b02740f094d1f03a6276eee497a69da5d3cd9dd Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 11 Nov 2015 17:37:33 +0100 Subject: [PATCH 9/9] Maintenance: Get rid of code duplication in FSFloaterNearbyChat::onChatBoxKeystroke() and FSNearbyChatControl::onKeystroke() --- indra/newview/fsfloaternearbychat.cpp | 215 +------------------ indra/newview/fsfloaternearbychat.h | 1 - indra/newview/fsnearbychatcontrol.cpp | 287 +++----------------------- indra/newview/fsnearbychatcontrol.h | 6 +- indra/newview/fsnearbychathub.cpp | 275 ++++++++++++++++++++++++ indra/newview/fsnearbychathub.h | 9 +- 6 files changed, 312 insertions(+), 481 deletions(-) diff --git a/indra/newview/fsfloaternearbychat.cpp b/indra/newview/fsfloaternearbychat.cpp index 841f5bd30b..f729ab46e9 100644 --- a/indra/newview/fsfloaternearbychat.cpp +++ b/indra/newview/fsfloaternearbychat.cpp @@ -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) @@ -725,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 communication UI] - //channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); - channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); - // [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()) - { - 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(); - } - } - - // FIRE-3192 - Predictive name completion, based on code by Satomi Ahn - static LLCachedControl 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()); - } - } - } - } - // + FSNearbyChat::handleChatBarKeystroke(mInputEditor); } // static diff --git a/indra/newview/fsfloaternearbychat.h b/indra/newview/fsfloaternearbychat.h index 2f4c51eb30..0b66c0b29d 100644 --- a/indra/newview/fsfloaternearbychat.h +++ b/indra/newview/fsfloaternearbychat.h @@ -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(); diff --git a/indra/newview/fsnearbychatcontrol.cpp b/indra/newview/fsnearbychatcontrol.cpp index 48a279b497..26ba7f6038 100644 --- a/indra/newview/fsnearbychatcontrol.cpp +++ b/indra/newview/fsnearbychatcontrol.cpp @@ -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" // FIRE-3192 - Name Prediction -#include "rlvhandler.h" - -static const U32 NAME_PREDICTION_MINIMUM_LENGTH = 3; - static LLDefaultChildRegistry::Register 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) { // 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(); - - S32 channel=0; - if (gSavedSettings.getBOOL("FSNearbyChatbar") && - gSavedSettings.getBOOL("FSShowChatChannel")) - { - // [FS communication UI] - //channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); - channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); - // [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()) - { - caller->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 = caller->getLength(); // in characters - caller->setSelection(length, outlength); - caller->setCursor(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(); - } - } - - // FIRE-3192 - Predictive name completion, based on code by Satomi Ahn - static LLCachedControl 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); - 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()) - { - caller->setText(prefix + replaced_text + suffix); - caller->setSelection(utf8str_to_wstring(prefix + replaced_text).length(), cur_pos); - } - } - } - } - // -} - -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); } diff --git a/indra/newview/fsnearbychatcontrol.h b/indra/newview/fsnearbychatcontrol.h index f8af8bc156..43a0b22eba 100644 --- a/indra/newview/fsnearbychatcontrol.h +++ b/indra/newview/fsnearbychatcontrol.h @@ -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(); diff --git a/indra/newview/fsnearbychathub.cpp b/indra/newview/fsnearbychathub.cpp index 11e2b13cbb..890b464f7f 100644 --- a/indra/newview/fsnearbychathub.cpp +++ b/indra/newview/fsnearbychathub.cpp @@ -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; + // 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(source); + LLLineEditor* line_editor = dynamic_cast(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 communication UI] + //channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + // [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(); + } + } + } + + // FIRE-3192 - Predictive name completion, based on code by Satomi Ahn + static LLCachedControl 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); + } + } + } + } + } + // +} + class LLChatCommandHandler : public LLCommandHandler { diff --git a/indra/newview/fsnearbychathub.h b/indra/newview/fsnearbychathub.h index b205183f2e..9d89cbc9dd 100644 --- a/indra/newview/fsnearbychathub.h +++ b/indra/newview/fsnearbychathub.h @@ -32,6 +32,7 @@ #include "llviewerchat.h" class FSNearbyChatControl; +class LLUICtrl; class FSNearbyChat : public LLSingleton { @@ -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; };