From 63ef2950e94522cf3b2eaa13da93068ecb77d933 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Thu, 28 Feb 2013 18:57:38 +0100 Subject: [PATCH] CHUI preparation phase 1: Move FS-specific communication parts into a separate domain and out of the way for CHUI merge to reduce conflicts * LLChatHistory moved to FSChatHistory * LLFloaterNearbyChat moved to FSFloaterNearbyChat * LLIMFloater moved to FSFloaterIM * LLIMFloaterContainer moved to FSFloaterIMContainer * LLNearbyChatbarListener moved to FSNearbyChatbarListener * LLNearbyChatControl moved to FSNearbyChatControl * LLNearbyChatHub moved to FSNearbyChatHub * floater_im_container.xml moved to floater_fs_im_container.xml * floater_im_session.xml moved to floater_fs_im_session.xml * floater_nearby_chat.xml moved to floater_fs_nearby_chat.xml * widget chat_history.xml moved to fs_chat_history * widget nearby_chat_control.xml moved to fs_nearby_chat_control.xml --- indra/newview/CMakeLists.txt | 18 +- indra/newview/app_settings/commands.xml | 4 +- indra/newview/chatbar_as_cmdline.cpp | 10 +- indra/newview/fschathistory.cpp | 1557 ++++++++++++++ indra/newview/fschathistory.h | 167 ++ indra/newview/fsconsoleutils.cpp | 8 +- indra/newview/fscontactsfloater.cpp | 15 +- indra/newview/fsfloaterim.cpp | 1876 +++++++++++++++++ indra/newview/fsfloaterim.h | 225 ++ indra/newview/fsfloaterimcontainer.cpp | 290 +++ indra/newview/fsfloaterimcontainer.h | 76 + indra/newview/fsfloaternearbychat.cpp | 651 ++++++ indra/newview/fsfloaternearbychat.h | 117 + indra/newview/fsmoneytracker.cpp | 6 +- indra/newview/fsmoneytracker.h | 10 +- indra/newview/fsnearbychatbarlistener.cpp | 116 + indra/newview/fsnearbychatbarlistener.h | 55 + ...hatcontrol.cpp => fsnearbychatcontrol.cpp} | 50 +- ...rbychatcontrol.h => fsnearbychatcontrol.h} | 14 +- ...lnearbychathub.cpp => fsnearbychathub.cpp} | 51 +- .../{llnearbychathub.h => fsnearbychathub.h} | 24 +- indra/newview/fsnearbychatvoicemonitor.cpp | 4 +- indra/newview/fsnearbychatvoicemonitor.h | 6 +- indra/newview/llagent.cpp | 12 +- indra/newview/llavataractions.cpp | 15 +- indra/newview/llcallfloater.cpp | 10 +- indra/newview/llcallingcard.cpp | 25 +- indra/newview/llchathistory.cpp | 4 + indra/newview/llchathistory.h | 4 + indra/newview/llchatitemscontainerctrl.cpp | 25 +- indra/newview/llchiclet.cpp | 46 +- indra/newview/llchicletbar.cpp | 15 +- indra/newview/llfirstuse.cpp | 5 +- indra/newview/llfloaternearbychat.cpp | 32 +- indra/newview/llfloaternearbychat.h | 4 + indra/newview/llfloaterpreference.cpp | 27 +- indra/newview/llgesturemgr.cpp | 4 +- indra/newview/llgroupactions.cpp | 10 +- indra/newview/llimfloater.cpp | 4 + indra/newview/llimfloater.h | 4 + indra/newview/llimfloatercontainer.cpp | 4 + indra/newview/llimfloatercontainer.h | 4 + indra/newview/llimview.cpp | 80 +- indra/newview/llnearbychatbarlistener.cpp | 12 +- indra/newview/llnearbychatbarlistener.h | 2 + indra/newview/llnearbychathandler.cpp | 14 +- indra/newview/llnotificationhandler.h | 10 +- indra/newview/llnotificationhandlerutil.cpp | 40 +- indra/newview/llnotificationtiphandler.cpp | 10 +- indra/newview/llstartup.cpp | 20 +- indra/newview/lltoastnotifypanel.cpp | 10 +- indra/newview/llviewerfloaterreg.cpp | 20 +- indra/newview/llviewergesture.cpp | 4 +- indra/newview/llviewerkeyboard.cpp | 6 +- indra/newview/llviewermenufile.cpp | 10 +- indra/newview/llviewermessage.cpp | 20 +- indra/newview/llviewerwindow.cpp | 10 +- indra/newview/rlvui.cpp | 5 +- .../ansastorm/xui/en/panel_toolbar_view.xml | 2 +- .../xui/da/floater_fs_im_container.xml | 2 + .../default/xui/da/floater_fs_im_session.xml | 8 + .../xui/de/floater_fs_im_container.xml | 2 + .../default/xui/de/floater_fs_im_session.xml | 47 + .../xui/de/floater_fs_money_tracker.xml | 2 +- .../default/xui/de/floater_fs_nearby_chat.xml | 20 + .../xui/en/floater_fs_im_container.xml | 50 + .../default/xui/en/floater_fs_im_session.xml | 408 ++++ .../xui/en/floater_fs_money_tracker.xml | 4 +- .../default/xui/en/floater_fs_nearby_chat.xml | 213 ++ .../default/xui/en/floater_im_session.xml | 4 +- .../default/xui/en/floater_nearby_chat-cb.xml | 4 +- .../default/xui/en/floater_nearby_chat.xml | 6 +- .../skins/default/xui/en/menu_viewer.xml | 8 +- .../default/xui/en/panel_nearby_chat.xml | 2 +- .../default/xui/en/panel_toolbar_view.xml | 2 +- .../xui/en/widgets/fs_chat_history.xml | 25 + .../xui/en/widgets/fs_nearby_chat_control.xml | 3 + .../xui/es/floater_fs_im_container.xml | 2 + .../default/xui/es/floater_fs_im_session.xml | 45 + .../default/xui/es/floater_fs_nearby_chat.xml | 20 + .../default/xui/es/floater_nearby_chat.xml | 2 +- .../xui/fr/floater_fs_im_container.xml | 2 + .../default/xui/fr/floater_fs_im_session.xml | 8 + .../xui/it/floater_fs_im_container.xml | 2 + .../default/xui/it/floater_fs_im_session.xml | 42 + .../xui/ja/floater_fs_im_container.xml | 2 + .../default/xui/ja/floater_fs_im_session.xml | 8 + .../xui/pl/floater_fs_im_container.xml | 2 + .../default/xui/pl/floater_fs_im_session.xml | 42 + .../default/xui/pl/floater_fs_nearby_chat.xml | 20 + .../default/xui/pl/floater_nearby_chat.xml | 2 +- .../xui/pt/floater_fs_im_container.xml | 2 + .../default/xui/pt/floater_fs_im_session.xml | 8 + .../xui/ru/floater_fs_im_container.xml | 2 + .../default/xui/ru/floater_fs_im_session.xml | 8 + .../default/xui/ru/floater_nearby_chat-cb.xml | 4 +- .../xui/ru/widgets/fs_chat_history.xml | 25 + .../xui/tr/floater_fs_im_container.xml | 2 + .../default/xui/tr/floater_fs_im_session.xml | 8 + .../xui/zh/floater_fs_im_container.xml | 2 + .../default/xui/zh/floater_fs_im_session.xml | 8 + .../xui/en/floater_fs_nearby_chat.xml | 216 ++ .../metaharper/xui/en/floater_nearby_chat.xml | 6 +- .../metaharper/xui/en/panel_toolbar_view.xml | 2 +- .../xui/en/floater_fs_im_container.xml | 50 + .../starlight/xui/en/panel_toolbar_view.xml | 2 +- .../xui/en/floater_fs_im_container.xml | 50 + .../starlightcui/xui/en/panel_nearby_chat.xml | 2 +- .../xui/en/panel_toolbar_view.xml | 2 +- .../xui/en/floater_fs_im_container.xml | 51 + .../vintage/xui/en/panel_toolbar_view.xml | 4 +- .../vintage/xui/pl/panel_toolbar_view.xml | 2 +- 112 files changed, 7112 insertions(+), 232 deletions(-) create mode 100644 indra/newview/fschathistory.cpp create mode 100644 indra/newview/fschathistory.h create mode 100644 indra/newview/fsfloaterim.cpp create mode 100644 indra/newview/fsfloaterim.h create mode 100644 indra/newview/fsfloaterimcontainer.cpp create mode 100644 indra/newview/fsfloaterimcontainer.h create mode 100644 indra/newview/fsfloaternearbychat.cpp create mode 100644 indra/newview/fsfloaternearbychat.h create mode 100644 indra/newview/fsnearbychatbarlistener.cpp create mode 100644 indra/newview/fsnearbychatbarlistener.h rename indra/newview/{llnearbychatcontrol.cpp => fsnearbychatcontrol.cpp} (84%) rename indra/newview/{llnearbychatcontrol.h => fsnearbychatcontrol.h} (87%) rename indra/newview/{llnearbychathub.cpp => fsnearbychathub.cpp} (91%) rename indra/newview/{llnearbychathub.h => fsnearbychathub.h} (81%) create mode 100644 indra/newview/skins/default/xui/da/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/da/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/de/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/de/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/de/floater_fs_nearby_chat.xml create mode 100644 indra/newview/skins/default/xui/en/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/en/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/en/floater_fs_nearby_chat.xml create mode 100644 indra/newview/skins/default/xui/en/widgets/fs_chat_history.xml create mode 100644 indra/newview/skins/default/xui/en/widgets/fs_nearby_chat_control.xml create mode 100644 indra/newview/skins/default/xui/es/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/es/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/es/floater_fs_nearby_chat.xml create mode 100644 indra/newview/skins/default/xui/fr/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/fr/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/it/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/it/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/ja/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/ja/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/pl/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/pl/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/pl/floater_fs_nearby_chat.xml create mode 100644 indra/newview/skins/default/xui/pt/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/pt/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/ru/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/ru/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/ru/widgets/fs_chat_history.xml create mode 100644 indra/newview/skins/default/xui/tr/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/tr/floater_fs_im_session.xml create mode 100644 indra/newview/skins/default/xui/zh/floater_fs_im_container.xml create mode 100644 indra/newview/skins/default/xui/zh/floater_fs_im_session.xml create mode 100644 indra/newview/skins/metaharper/xui/en/floater_fs_nearby_chat.xml create mode 100644 indra/newview/skins/starlight/xui/en/floater_fs_im_container.xml create mode 100644 indra/newview/skins/starlightcui/xui/en/floater_fs_im_container.xml create mode 100644 indra/newview/skins/vintage/xui/en/floater_fs_im_container.xml diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b8562f0652..3f8dc87a02 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -120,12 +120,16 @@ set(viewer_SOURCE_FILES exopostprocess.cpp floatermedialists.cpp fsareasearch.cpp + fschathistory.cpp fscommon.cpp fsconsoleutils.cpp fscontactsfloater.cpp fsdata.cpp fsfloaterblocklist.cpp fsfloatergroup.cpp + fsfloaterim.cpp + fsfloaterimcontainer.cpp + fsfloaternearbychat.cpp fsfloaterplacedetails.cpp fsfloaterprofile.cpp fsfloatersearch.cpp @@ -138,6 +142,9 @@ set(viewer_SOURCE_FILES fslslbridgerequest.cpp fslslpreproc.cpp fsmoneytracker.cpp + fsnearbychatbarlistener.cpp + fsnearbychatcontrol.cpp + fsnearbychathub.cpp fsnearbychatvoicemonitor.cpp fspanelclassified.cpp fspanelprefs.cpp @@ -417,9 +424,7 @@ set(viewer_SOURCE_FILES llnameeditor.cpp llnamelistctrl.cpp llnavigationbar.cpp - llnearbychatcontrol.cpp llnearbychathandler.cpp - llnearbychathub.cpp llnearbychatbarlistener.cpp llnetmap.cpp llnotificationalerthandler.cpp @@ -768,12 +773,16 @@ set(viewer_HEADER_FILES exopostprocess.h floatermedialists.h fsareasearch.h + fschathistory.h fscommon.h fsconsoleutils.h fscontactsfloater.h fsdata.h fsfloaterblocklist.h fsfloatergroup.h + fsfloaterim.h + fsfloaterimcontainer.h + fsfloaternearbychat.h fsfloaterplacedetails.h fsfloaterprofile.h fsfloatersearch.h @@ -787,6 +796,9 @@ set(viewer_HEADER_FILES fslslbridgerequest.h fslslpreproc.h fsmoneytracker.h + fsnearbychatbarlistener.h + fsnearbychatcontrol.h + fsnearbychathub.h fsnearbychatvoicemonitor.h fspanelclassified.h fspanelprefs.h @@ -1068,9 +1080,7 @@ set(viewer_HEADER_FILES llnameeditor.h llnamelistctrl.h llnavigationbar.h - llnearbychatcontrol.h llnearbychathandler.h - llnearbychathub.h llnearbychatbarlistener.h llnetmap.h llnotificationhandler.h diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 29b38f7537..0675f0fd91 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -50,9 +50,9 @@ label_ref="Command_Chat_Label" tooltip_ref="Command_Chat_Tooltip" execute_function="Floater.Toggle" - execute_parameters="im_container" + execute_parameters="fs_im_container" is_running_function="Floater.IsOpen" - is_running_parameters="im_container" + is_running_parameters="fs_im_container" /> [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llinventorymodel.h" @@ -851,7 +854,10 @@ bool cmd_line_chat(std::string revised_text, EChatType type, bool from_gesture) else if (command == std::string(sFSCmdLineClearChat)) { - LLFloaterNearbyChat* chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); + // [FS communication UI] + //LLFloaterNearbyChat* chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); + FSFloaterNearbyChat* chat = LLFloaterReg::getTypedInstance("fs_nearby_chat", LLSD()); + // [FS communication UI] if (chat) { chat->clearChatHistory(); diff --git a/indra/newview/fschathistory.cpp b/indra/newview/fschathistory.cpp new file mode 100644 index 0000000000..1ce46aa0ac --- /dev/null +++ b/indra/newview/fschathistory.cpp @@ -0,0 +1,1557 @@ +/** + * @file fschathistory.cpp + * @brief LLTextEditor base class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Original file: FSChatHistory.cpp + +#include "llviewerprecompiledheaders.h" + +#include "fschathistory.h" + +#include "llavatarnamecache.h" +#include "llinstantmessage.h" + +#include "llimview.h" +#include "llcommandhandler.h" +#include "llpanel.h" +#include "lluictrlfactory.h" +#include "llscrollcontainer.h" +#include "llavatariconctrl.h" +#include "llcallingcard.h" //for LLAvatarTracker +#include "llagentdata.h" +#include "llavataractions.h" +#include "lltrans.h" +#include "llfloaterreg.h" +#include "llfloatersidepanelcontainer.h" +#include "llmutelist.h" +#include "llstylemap.h" +#include "llslurl.h" +#include "lllayoutstack.h" +#include "llagent.h" +#include "llnotificationsutil.h" +#include "lltoastnotifypanel.h" +#include "lltooltip.h" +#include "llviewerregion.h" +#include "llviewertexteditor.h" +#include "llworld.h" +#include "lluiconstants.h" +#include "llstring.h" +#include "llviewercontrol.h" +// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) +#include "rlvcommon.h" +// [/RLVa:KB] + +// llviewernetwork.h : SJ: Needed to find the grid we are running on +#include "llviewernetwork.h" + +// FIRE-8602: Typing in chat history focuses chat input line +#include "llfocusmgr.h" +#include "llkeyboard.h" +#include "lllineeditor.h" +// + +static LLDefaultChildRegistry::Register r("fs_chat_history"); + +const static std::string NEW_LINE(rawstr_to_utf8("\n")); + +const static std::string SLURL_APP_AGENT = "secondlife:///app/agent/"; +const static std::string SLURL_ABOUT = "/about"; + +// support for secondlife:///app/objectim/{UUID}/ SLapps +class LLObjectIMHandler : public LLCommandHandler +{ +public: + // requests will be throttled from a non-trusted browser + LLObjectIMHandler() : LLCommandHandler("objectim", UNTRUSTED_THROTTLE) {} + + bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) + { + if (params.size() < 1) + { + return false; + } + + LLUUID object_id; + if (!object_id.set(params[0], FALSE)) + { + return false; + } + + LLSD payload; + payload["object_id"] = object_id; + payload["owner_id"] = query_map["owner"]; +// [RLVa:KB] - Checked: 2010-11-02 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + if (query_map.has("rlv_shownames")) + payload["rlv_shownames"] = query_map["rlv_shownames"]; +// [/RLVa:KB] + payload["name"] = query_map["name"]; + payload["slurl"] = LLWeb::escapeURL(query_map["slurl"]); + payload["group_owned"] = query_map["groupowned"]; + LLFloaterReg::showInstance("inspect_remote_object", payload); + return true; + } +}; +LLObjectIMHandler gObjectIMHandler; + +class FSChatHistoryHeader: public LLPanel +{ +public: + FSChatHistoryHeader() + : LLPanel(), +// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f + mShowContextMenu(true), + mShowInfoCtrl(true), +// [/RLVa:KB] + mPopupMenuHandleAvatar(), + mPopupMenuHandleObject(), + mAvatarID(), + mSourceType(CHAT_SOURCE_UNKNOWN), + mType(CHAT_TYPE_NORMAL), // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports + mFrom(), + mSessionID(), + mMinUserNameWidth(0), + mUserNameFont(NULL), + mUserNameTextBox(NULL), + mTimeBoxTextBox(NULL) + {} + + static FSChatHistoryHeader* createInstance(const std::string& file_name) + { + FSChatHistoryHeader* pInstance = new FSChatHistoryHeader; + pInstance->buildFromFile(file_name); + return pInstance; + } + + ~FSChatHistoryHeader() + { + // Detach the info button so that it doesn't get destroyed (EXT-8463). + hideInfoCtrl(); + } + + BOOL handleMouseUp(S32 x, S32 y, MASK mask) + { + return LLPanel::handleMouseUp(x,y,mask); + } + + void onObjectIconContextMenuItemClicked(const LLSD& userdata) + { + std::string level = userdata.asString(); + + if (level == "profile") + { + LLFloaterReg::showInstance("inspect_remote_object", mObjectData); + } + else if (level == "block") + { + LLMuteList::getInstance()->add(LLMute(getAvatarId(), mFrom, LLMute::OBJECT)); + + // Optional standalone blocklist floater + //LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with("blocked_to_select", getAvatarId())); + if (gSavedSettings.getBOOL("FSUseStandaloneBlocklistFloater")) + { + LLFloaterReg::showInstance("fs_blocklist", LLSD().with("blocked_to_select", getAvatarId())); + } + else + { + LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with("blocked_to_select", getAvatarId())); + } + // + } + } + + void onAvatarIconContextMenuItemClicked(const LLSD& userdata) + { + std::string level = userdata.asString(); + + if (level == "profile") + { + LLAvatarActions::showProfile(getAvatarId()); + } + else if (level == "im") + { + LLAvatarActions::startIM(getAvatarId()); + } + else if (level == "add") + { + LLAvatarActions::requestFriendshipDialog(getAvatarId(), mFrom); + } + else if (level == "remove") + { + LLAvatarActions::removeFriendDialog(getAvatarId()); + } + } + + BOOL postBuild() + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + + registrar.add("AvatarIcon.Action", boost::bind(&FSChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2)); + registrar.add("ObjectIcon.Action", boost::bind(&FSChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2)); + + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mPopupMenuHandleAvatar = menu->getHandle(); + + menu = LLUICtrlFactory::getInstance()->createFromFile("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mPopupMenuHandleObject = menu->getHandle(); + + setDoubleClickCallback(boost::bind(&FSChatHistoryHeader::showInspector, this)); + + setMouseEnterCallback(boost::bind(&FSChatHistoryHeader::showInfoCtrl, this)); + setMouseLeaveCallback(boost::bind(&FSChatHistoryHeader::hideInfoCtrl, this)); + + mUserNameTextBox = getChild("user_name"); + mTimeBoxTextBox = getChild("time_box"); + + return LLPanel::postBuild(); + } + + bool pointInChild(const std::string& name,S32 x,S32 y) + { + LLUICtrl* child = findChild(name); + if(!child) + return false; + + LLView* parent = child->getParent(); + if(parent!=this) + { + x-=parent->getRect().mLeft; + y-=parent->getRect().mBottom; + } + + S32 local_x = x - child->getRect().mLeft ; + S32 local_y = y - child->getRect().mBottom ; + return child->pointInView(local_x, local_y); + } + + BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) + { + if(pointInChild("avatar_icon",x,y) || pointInChild("user_name",x,y)) + { + showContextMenu(x,y); + return TRUE; + } + + return LLPanel::handleRightMouseDown(x,y,mask); + } + + void showInspector() + { +// if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) return; +// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f + // Don't double-click show the inspector if we're not showing the info control + if ( (!mShowInfoCtrl) || (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) ) return; +// [/RLVa:KB] + + if (mSourceType == CHAT_SOURCE_OBJECT) + { + LLFloaterReg::showInstance("inspect_remote_object", mObjectData); + } + //else if (mSourceType == CHAT_SOURCE_AGENT) + else if (mSourceType == CHAT_SOURCE_AGENT || (mSourceType == CHAT_SOURCE_SYSTEM && mType == CHAT_TYPE_RADAR)) // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports + { + LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mAvatarID)); + } + //if chat source is system, you may add "else" here to define behaviour. + } + + static void onClickInfoCtrl(LLUICtrl* info_ctrl) + { + if (!info_ctrl) return; + + FSChatHistoryHeader* header = dynamic_cast(info_ctrl->getParent()); + if (!header) return; + + header->showInspector(); + } + + + const LLUUID& getAvatarId () const { return mAvatarID;} + + void setup(const LLChat& chat, const LLStyle::Params& style_params, const LLSD& args) + { + mAvatarID = chat.mFromID; + mSessionID = chat.mSessionID; + mSourceType = chat.mSourceType; + mType = chat.mChatType; // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports + + //*TODO overly defensive thing, source type should be maintained out there + if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull())) + { + mSourceType = CHAT_SOURCE_SYSTEM; + } + + mUserNameFont = style_params.font(); + LLTextBox* user_name = getChild("user_name"); + user_name->setReadOnlyColor(style_params.readonly_color()); + user_name->setColor(style_params.color()); + + if (chat.mFromName.empty() + //|| mSourceType == CHAT_SOURCE_SYSTEM + // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports + || (mSourceType == CHAT_SOURCE_SYSTEM && mType != CHAT_TYPE_RADAR) + || mAvatarID.isNull()) + { + //mFrom = LLTrans::getString("SECOND_LIFE"); + //[FIX FIRE-2852] Changed function to find the right Gridname + mFrom = LLGridManager::getInstance()->getGridLabel(); + user_name->setValue(mFrom); + updateMinUserNameWidth(); + } + else if (mSourceType == CHAT_SOURCE_AGENT +// && !mAvatarID.isNull() + && chat.mChatStyle != CHAT_STYLE_HISTORY) + { + // ...from a normal user, lookup the name and fill in later. + // *NOTE: Do not do this for chat history logs, otherwise the viewer + // will flood the People API with lookup requests on startup + + // Start with blank so sample data from XUI XML doesn't + // flash on the screen +// user_name->setValue( LLSD() ); +// LLAvatarNameCache::get(mAvatarID, +// boost::bind(&FSChatHistoryHeader::onAvatarNameCache, this, _1, _2)); +// [RLVa:KB] - Checked: 2010-11-01 (RLVa-1.2.2a) | Added: RLVa-1.2.2a + if (!chat.mRlvNamesFiltered) + { + user_name->setValue( LLSD() ); + LLAvatarNameCache::get(mAvatarID, + boost::bind(&FSChatHistoryHeader::onAvatarNameCache, this, _1, _2, chat.mChatType, chat.mFromNameGroup)); // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //boost::bind(&FSChatHistoryHeader::onAvatarNameCache, this, _1, _2, chat.mChatType)); + } + else + { + // If the agent's chat was subject to @shownames=n we should display their anonimized name + mFrom = chat.mFromName; + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //if (chat.mChatType == CHAT_TYPE_IM) mFrom = LLTrans::getString("IMPrefix") + " " + mFrom; + if (chat.mChatType == CHAT_TYPE_IM) + { + mFrom = LLTrans::getString("IMPrefix") + " " + mFrom; + } + else if (chat.mChatType == CHAT_TYPE_IM_GROUP) + { + mFrom = LLTrans::getString("IMPrefix") + " " + chat.mFromNameGroup + mFrom; + } + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + user_name->setValue(mFrom); + user_name->setToolTip(mFrom); + setToolTip(mFrom); + updateMinUserNameWidth(); + } +// [/RLVa:KB] + } + else if (chat.mChatStyle == CHAT_STYLE_HISTORY || + mSourceType == CHAT_SOURCE_AGENT) + { + //if it's an avatar name with a username add formatting + S32 username_start = chat.mFromName.rfind(" ("); + S32 username_end = chat.mFromName.rfind(')'); + + if (username_start != std::string::npos && + username_end == (chat.mFromName.length() - 1)) + { + mFrom = chat.mFromName.substr(0, username_start); + user_name->setValue(mFrom); + + //-TT 2.6.9 - old style headers removed in FS? + /* + if (gSavedSettings.getBOOL("NameTagShowUsernames")) + { + std::string username = chat.mFromName.substr(username_start + 2); + username = username.substr(0, username.length() - 1); + LLStyle::Params style_params_name; + LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor"); + style_params_name.color(userNameColor); + style_params_name.font.name("SansSerifSmall"); + style_params_name.font.style("NORMAL"); + style_params_name.readonly_color(userNameColor); + user_name->appendText(" - " + username, FALSE, style_params_name); + } + */ + //LLAvatarNameCache::get(mAvatarID, boost::bind(&FSChatHistoryHeader::onAvatarNameCache, this, _1, _2, chat.mChatType)); + LLAvatarNameCache::get(mAvatarID, boost::bind(&FSChatHistoryHeader::onAvatarNameCache, this, _1, _2, chat.mChatType, chat.mFromNameGroup)); // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + } + else + { + // If the agent's chat was subject to @shownames=n we should display their anonimized name + mFrom = chat.mFromName; + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //if (chat.mChatType == CHAT_TYPE_IM) mFrom = LLTrans::getString("IMPrefix") + " " + mFrom; + if (chat.mChatType == CHAT_TYPE_IM) + { + mFrom = LLTrans::getString("IMPrefix") + " " + mFrom; + } + else if (chat.mChatType == CHAT_TYPE_IM_GROUP) + { + mFrom = LLTrans::getString("IMPrefix") + " " + chat.mFromNameGroup + mFrom; + } + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + user_name->setValue(mFrom); + user_name->setToolTip(mFrom); + setToolTip(mFrom); + updateMinUserNameWidth(); + } +// [/RLVa:KB] + } + else + { + // ...from an object, just use name as given + mFrom = chat.mFromName; + user_name->setValue(mFrom); + updateMinUserNameWidth(); + } + + + setTimeField(chat); + + // Set up the icon. + LLAvatarIconCtrl* icon = getChild("avatar_icon"); + + // Hacky preference to hide avatar icons for people who don't like them by overdrawing them. Will change to disable soon. -AO + bool display_mini_icon = gSavedSettings.getBOOL("ShowChatMiniIcons"); + if (!display_mini_icon) + { + icon->setColor(LLUIColorTable::instance().getColor("Transparent")); + } + + if(mSourceType != CHAT_SOURCE_AGENT || mAvatarID.isNull()) + icon->setDrawTooltip(false); + +// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f + // Don't show the context menu, info control or avatar icon tooltip if this chat was subject to @shownames=n + if ( (chat.mRlvNamesFiltered) && ((CHAT_SOURCE_AGENT == mSourceType) || (CHAT_SOURCE_OBJECT == mSourceType)) ) + { + mShowInfoCtrl = mShowContextMenu = false; + icon->setDrawTooltip(false); + } +// [/RLVa:KB] + + switch (mSourceType) + { + case CHAT_SOURCE_AGENT: + icon->setValue(chat.mFromID); + break; + case CHAT_SOURCE_OBJECT: + icon->setValue(LLSD("OBJECT_Icon")); + break; + case CHAT_SOURCE_SYSTEM: + //icon->setValue(LLSD("SL_Logo")); + // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports + if(chat.mChatType == CHAT_TYPE_RADAR) + { + icon->setValue(chat.mFromID); + } + else + { + icon->setValue(LLSD("SL_Logo")); + } + // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports + break; + case CHAT_SOURCE_UNKNOWN: + icon->setValue(LLSD("Unknown_Icon")); + } + + // In case the message came from an object, save the object info + // to be able properly show its profile. + if ( chat.mSourceType == CHAT_SOURCE_OBJECT) + { + std::string slurl = args["slurl"].asString(); + if (slurl.empty()) + { + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); + if(region) + { + LLSLURL region_slurl(region->getName(), chat.mPosAgent); + slurl = region_slurl.getLocationString(); + } + } + + LLSD payload; + payload["object_id"] = chat.mFromID; + payload["name"] = chat.mFromName; + payload["owner_id"] = chat.mOwnerID; + payload["slurl"] = LLWeb::escapeURL(slurl); + + mObjectData = payload; + } + } + + /*virtual*/ void draw() + { + LLTextBox* user_name = mUserNameTextBox; //getChild("user_name"); + LLTextBox* time_box = mTimeBoxTextBox; //getChild("time_box"); + + LLRect user_name_rect = user_name->getRect(); + S32 user_name_width = user_name_rect.getWidth(); + S32 time_box_width = time_box->getRect().getWidth(); + + if (time_box->getVisible() && user_name_width <= mMinUserNameWidth) + { + time_box->setVisible(FALSE); + + user_name_rect.mRight += time_box_width; + user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight()); + user_name->setRect(user_name_rect); + } + + if (!time_box->getVisible() && user_name_width > mMinUserNameWidth + time_box_width) + { + user_name_rect.mRight -= time_box_width; + user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight()); + user_name->setRect(user_name_rect); + + time_box->setVisible(TRUE); + } + + LLPanel::draw(); + } + + void updateMinUserNameWidth() + { + if (mUserNameFont) + { + LLTextBox* user_name = getChild("user_name"); + const LLWString& text = user_name->getWText(); + mMinUserNameWidth = mUserNameFont->getWidth(text.c_str()) + PADDING; + } + } + +// FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, EChatType chat_type) + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, EChatType chat_type, std::string& group) + { + //mFrom = av_name.mDisplayName; + //mFrom = av_name.mDisplayName; + //if (chat_type == CHAT_TYPE_IM) mFrom = LLTrans::getString("IMPrefix") + " " + mFrom; + mFrom = ""; + if (chat_type == CHAT_TYPE_IM || chat_type == CHAT_TYPE_IM_GROUP) + { + mFrom = LLTrans::getString("IMPrefix") + " "; + if(group != "") + { + mFrom += group; + } + } + mFrom += av_name.mDisplayName; + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + + LLTextBox* user_name = getChild("user_name"); + user_name->setValue( LLSD(mFrom) ); + user_name->setToolTip( av_name.mUsername ); + + if (gSavedSettings.getBOOL("NameTagShowUsernames") && + LLAvatarNameCache::useDisplayNames() ) //&& +// !av_name.mIsDisplayNameDefault) + { + LLStyle::Params style_params_name; + LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor"); + style_params_name.color(userNameColor); + style_params_name.font.name("SansSerifSmall"); + style_params_name.font.style("NORMAL"); + style_params_name.readonly_color(userNameColor); + user_name->appendText(" - " + av_name.mUsername, FALSE, style_params_name); + } + setToolTip( av_name.mUsername ); + // name might have changed, update width + updateMinUserNameWidth(); + } + +protected: + static const S32 PADDING = 20; + + void showContextMenu(S32 x,S32 y) + { +// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f + if (!mShowContextMenu) + return; +// [/RLVa:KB] + if(mSourceType == CHAT_SOURCE_SYSTEM) + //showSystemContextMenu(x,y); + // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports + { + // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports + if(mType == CHAT_TYPE_RADAR) + { + showAvatarContextMenu(x,y); + } + else + { + showSystemContextMenu(x,y); + } + } + // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports + if(mAvatarID.notNull() && mSourceType == CHAT_SOURCE_AGENT) + showAvatarContextMenu(x,y); + if(mAvatarID.notNull() && mSourceType == CHAT_SOURCE_OBJECT && SYSTEM_FROM != mFrom) + showObjectContextMenu(x,y); + } + + void showSystemContextMenu(S32 x,S32 y) + { + } + + void showObjectContextMenu(S32 x,S32 y) + { + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleObject.get(); + if(menu) + LLMenuGL::showPopup(this, menu, x, y); + } + + void showAvatarContextMenu(S32 x,S32 y) + { + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleAvatar.get(); + + if(menu) + { + bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL; + + menu->setItemEnabled("Add Friend", !is_friend); + menu->setItemEnabled("Remove Friend", is_friend); + + if(gAgentID == mAvatarID) + { + menu->setItemEnabled("Add Friend", false); + menu->setItemEnabled("Send IM", false); + menu->setItemEnabled("Remove Friend", false); + } + + if (mSessionID == LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, mAvatarID)) + { + menu->setItemVisible("Send IM", false); + } + + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, menu, x, y); + } + } + + void showInfoCtrl() + { +// if (mAvatarID.isNull() || mFrom.empty() || CHAT_SOURCE_SYSTEM == mSourceType) return; +// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f + if ( (!mShowInfoCtrl) || (mAvatarID.isNull() || mFrom.empty() || CHAT_SOURCE_SYSTEM == mSourceType) ) return; +// [/RLVa:KB] + + if (!sInfoCtrl) + { + // *TODO: Delete the button at exit. + sInfoCtrl = LLUICtrlFactory::createFromFile("inspector_info_ctrl.xml", NULL, LLPanel::child_registry_t::instance()); + if (sInfoCtrl) + { + sInfoCtrl->setCommitCallback(boost::bind(&FSChatHistoryHeader::onClickInfoCtrl, sInfoCtrl)); + } + } + + if (!sInfoCtrl) + { + llassert(sInfoCtrl != NULL); + return; + } + + LLTextBox* name = getChild("user_name"); + LLRect sticky_rect = name->getRect(); + S32 icon_x = llmin(sticky_rect.mLeft + name->getTextBoundingRect().getWidth() + 7, sticky_rect.mRight - 3); + sInfoCtrl->setOrigin(icon_x, sticky_rect.getCenterY() - sInfoCtrl->getRect().getHeight() / 2 ) ; + addChild(sInfoCtrl); + } + + void hideInfoCtrl() + { + if (!sInfoCtrl) return; + + if (sInfoCtrl->getParent() == this) + { + removeChild(sInfoCtrl); + } + } + +private: + void setTimeField(const LLChat& chat) + { + LLTextBox* time_box = getChild("time_box"); + + LLRect rect_before = time_box->getRect(); + + time_box->setValue(chat.mTimeStr); + + // set necessary textbox width to fit all text + time_box->reshapeToFitText(); + LLRect rect_after = time_box->getRect(); + + // move rect to the left to correct position... + S32 delta_pos_x = rect_before.getWidth() - rect_after.getWidth(); + S32 delta_pos_y = rect_before.getHeight() - rect_after.getHeight(); + time_box->translate(delta_pos_x, delta_pos_y); + + //... & change width of the name control + LLView* user_name = getChild("user_name"); + const LLRect& user_rect = user_name->getRect(); + user_name->reshape(user_rect.getWidth() + delta_pos_x, user_rect.getHeight()); + } + +protected: + LLHandle mPopupMenuHandleAvatar; + LLHandle mPopupMenuHandleObject; + + static LLUICtrl* sInfoCtrl; + + LLUUID mAvatarID; + LLSD mObjectData; + EChatSourceType mSourceType; + EChatType mType; // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports + std::string mFrom; + LLUUID mSessionID; +// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f + bool mShowContextMenu; + bool mShowInfoCtrl; +// [/RLVa:KB] + + S32 mMinUserNameWidth; + const LLFontGL* mUserNameFont; + LLTextBox* mUserNameTextBox; + LLTextBox* mTimeBoxTextBox; +}; + +LLUICtrl* FSChatHistoryHeader::sInfoCtrl = NULL; + +FSChatHistory::FSChatHistory(const FSChatHistory::Params& p) +// : LLUICtrl(p), // FIRE-8600: TAB out of chat history +: LLTextEditor(p), // FIRE-8600: TAB out of chat history + mMessageHeaderFilename(p.message_header), + mMessageSeparatorFilename(p.message_separator), + mLeftTextPad(p.left_text_pad), + mRightTextPad(p.right_text_pad), + mLeftWidgetPad(p.left_widget_pad), + mRightWidgetPad(p.right_widget_pad), + mTopSeparatorPad(p.top_separator_pad), + mBottomSeparatorPad(p.bottom_separator_pad), + mTopHeaderPad(p.top_header_pad), + mBottomHeaderPad(p.bottom_header_pad), + mChatInputLine(NULL), // FIRE-8602: Typing in chat history focuses chat input line + mIsLastMessageFromLog(false) +{ + // FIRE-8600: TAB out of chat history + // LLTextEditor::Params editor_params(p); + // editor_params.line_spacing.pixels = llclamp(gSavedSettings.getS32("FSFontChatLineSpacingPixels"), 0, 36); + // editor_params.rect = getLocalRect(); + // editor_params.follows.flags = FOLLOWS_ALL; + // editor_params.enabled = false; // read only + // editor_params.show_context_menu = "true"; + // mEditor = LLUICtrlFactory::create(editor_params, this); + mLineSpacingPixels=llclamp(gSavedSettings.getS32("FSFontChatLineSpacingPixels"),0,36); + // +} + +FSChatHistory::~FSChatHistory() +{ + this->clear(); +} + +void FSChatHistory::initFromParams(const FSChatHistory::Params& p) +{ +// FIRE-8600: TAB out of chat history +// static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); +// +// LLRect stack_rect = getLocalRect(); +// stack_rect.mRight -= scrollbar_size; +// LLLayoutStack::Params layout_p; +// layout_p.rect = stack_rect; +// layout_p.follows.flags = FOLLOWS_ALL; +// layout_p.orientation = LLLayoutStack::VERTICAL; +// layout_p.mouse_opaque = false; +// layout_p.tab_group = 1; +// +// LLLayoutStack* stackp = LLUICtrlFactory::create(layout_p, this); +// +// const S32 NEW_TEXT_NOTICE_HEIGHT = 20; +// +// LLLayoutPanel::Params panel_p; +// panel_p.name = "spacer"; +// panel_p.background_visible = false; +// panel_p.has_border = false; +// panel_p.mouse_opaque = false; +// panel_p.min_dim = 30; +// panel_p.auto_resize = true; +// panel_p.user_resize = false; +// panel_p.tab_group = 1; +// panel_p.tab_stop = true; +// +// stackp->addPanel(LLUICtrlFactory::create(panel_p), LLLayoutStack::ANIMATE); +// +// panel_p.name = "new_text_notice_holder"; +// LLRect new_text_notice_rect = getLocalRect(); +// new_text_notice_rect.mTop = new_text_notice_rect.mBottom + NEW_TEXT_NOTICE_HEIGHT; +// panel_p.rect = new_text_notice_rect; +// panel_p.background_opaque = true; +// panel_p.background_visible = true; +// panel_p.visible = false; +// panel_p.min_dim = 0; +// panel_p.auto_resize = false; +// panel_p.user_resize = false; +// mMoreChatPanel = LLUICtrlFactory::create(panel_p); +// +// LLTextBox::Params text_p(p.more_chat_text); +// text_p.rect = mMoreChatPanel->getLocalRect(); +// text_p.follows.flags = FOLLOWS_ALL; +// text_p.name = "more_chat_text"; +// mMoreChatText = LLUICtrlFactory::create(text_p, mMoreChatPanel); +// mMoreChatText->setClickedCallback(boost::bind(&FSChatHistory::onClickMoreText, this)); +// +// stackp->addPanel(mMoreChatPanel, LLLayoutStack::ANIMATE); + + // initialize the LLTextEditor base class first ... -Zi + LLTextEditor::initFromParams(p); + // then set up these properties, because otherwise they would get lost when we + // do this in the constructor only -Zi + setEnabled(false); + setReadOnly(true); + setShowContextMenu(true); +} +// + +/*void FSChatHistory::updateTextRect() +{ + static LLUICachedControl texteditor_border ("UITextEditorBorder", 0); + + LLRect old_text_rect = mVisibleTextRect; + mVisibleTextRect = mScroller->getContentWindowRect(); + mVisibleTextRect.stretch(-texteditor_border); + mVisibleTextRect.mLeft += mLeftTextPad; + mVisibleTextRect.mRight -= mRightTextPad; + if (mVisibleTextRect != old_text_rect) + { + needsReflow(); + } +}*/ + +LLView* FSChatHistory::getSeparator() +{ + LLPanel* separator = LLUICtrlFactory::getInstance()->createFromFile(mMessageSeparatorFilename, NULL, LLPanel::child_registry_t::instance()); + return separator; +} + +LLView* FSChatHistory::getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args) +{ + FSChatHistoryHeader* header = FSChatHistoryHeader::createInstance(mMessageHeaderFilename); + header->setup(chat, style_params, args); + return header; +} + +// FIRE-8600: TAB out of chat history +// void FSChatHistory::onClickMoreText() +// { +// mEditor->endOfDoc(); +// } +// + +void FSChatHistory::clear() +{ + mLastFromName.clear(); + // workaround: Setting the text to an empty line before clear() gets rid of + // the scrollbar, if present, which otherwise would get stuck until the next + // line was appended. -Zi + // mEditor->setText(std::string(" \n")); // FIRE-8600: TAB out of chat history + setText(std::string(" \n")); // FIRE-8600: TAB out of chat history + // mEditor->clear(); // FIRE-8600: TAB out of chat history + mLastFromID = LLUUID::null; +} + +static LLFastTimer::DeclareTimer FTM_APPEND_MESSAGE("Append Chat Message"); + +void FSChatHistory::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + mDisplayName = av_name.mDisplayName; + mDisplayName_Username = av_name.getCompleteName(); +} + +void FSChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LLStyle::Params& input_append_params) +{ + LLFastTimer _(FTM_APPEND_MESSAGE); + bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean(); + bool hide_timestamps_nearby_chat = args["hide_timestamps_nearby_chat"].asBoolean(); + // AO: Do any display name lookups in plaintext chat headers as early as possible to give the cache maximal + //time to get an answer back before it's needed. + if (use_plain_text_chat_history) + { + // make sure objects and agents always have at least something we can display as a name + mDisplayName=chat.mFromName; + mDisplayName_Username=chat.mFromName; + + // resolve display names if necessary + if (chat.mSourceType == CHAT_SOURCE_AGENT && gSavedSettings.getBOOL("UseDisplayNames")) + { + LLAvatarNameCache::get(chat.mFromID,boost::bind(&FSChatHistory::onAvatarNameCache, this, _1, _2)); + } + } + + // FIRE-8600: TAB out of chat history + // llassert(mEditor); + // if (!mEditor) + // { + // return; + // } + // + + // mEditor->setPlainText(use_plain_text_chat_history); // FIRE-8600: TAB out of chat history + setPlainText(use_plain_text_chat_history); // FIRE-8600: TAB out of chat history + + /* This system in incompatible with vertical tabs, the firestorm default. + * disabling until we can find a way to make it work without overdrawing text + * or requiring a large otherwised unused gap in the XUI. + * + + if (!mEditor->scrolledToEnd() && chat.mFromID != gAgent.getID() && !chat.mFromName.empty()) + { + mUnreadChatSources.insert(chat.mFromName); + mMoreChatPanel->setVisible(TRUE); + std::string chatters; + for (unread_chat_source_t::iterator it = mUnreadChatSources.begin(); + it != mUnreadChatSources.end();) + { + chatters += *it; + if (++it != mUnreadChatSources.end()) + { + chatters += ", "; + } + } + LLStringUtil::format_map_t args; + args["SOURCES"] = chatters; + + if (mUnreadChatSources.size() == 1) + { + mMoreChatText->setValue(LLTrans::getString("unread_chat_single", args)); + } + else + { + mMoreChatText->setValue(LLTrans::getString("unread_chat_multiple", args)); + } + S32 height = mMoreChatText->getTextPixelHeight() + 5; + mMoreChatPanel->reshape(mMoreChatPanel->getRect().getWidth(), height); + } + */ + + LLColor4 txt_color = LLUIColorTable::instance().getColor("White"); + LLColor4 header_name_color = LLUIColorTable::instance().getColor("ChatNameColor"); + LLViewerChat::getChatColor(chat,txt_color,false); + LLFontGL* fontp = LLViewerChat::getChatFont(); + std::string font_name = LLFontGL::nameFromFont(fontp); + std::string font_size = LLFontGL::sizeFromFont(fontp); + LLStyle::Params style_params; + style_params.color(txt_color); + style_params.readonly_color(txt_color); + style_params.font.name(font_name); + style_params.font.size(font_size); + style_params.font.style(input_append_params.font.style); + + std::string prefix = chat.mText.substr(0, 4); + + // FS:LO FIRE-2899 - Faded text for IMs in nearby chat + F32 FSIMChatHistoryFade = gSavedSettings.getF32("FSIMChatHistoryFade"); + + if(FSIMChatHistoryFade > 1.0f) + { + FSIMChatHistoryFade = 1.0f; + gSavedSettings.setF32("FSIMChatHistoryFade",FSIMChatHistoryFade); + } + // FS:LO FIRE-2899 - Faded text for IMs in nearby chat + + //IRC styled /me messages. + bool irc_me = prefix == "/me " || prefix == "/me'" || prefix == "/ME " || prefix == "/ME'"; + + // Delimiter after a name in header copy/past and in plain text mode + std::string delimiter = ": "; + std::string shout = LLTrans::getString("shout"); + std::string whisper = LLTrans::getString("whisper"); + if (chat.mChatType == CHAT_TYPE_SHOUT || + chat.mChatType == CHAT_TYPE_WHISPER || + // FS:TS FIRE-6049: No : in radar chat header + chat.mChatType == CHAT_TYPE_RADAR || + // FS:TS FIRE-6049: No : in radar chat header + chat.mText.compare(0, shout.length(), shout) == 0 || + chat.mText.compare(0, whisper.length(), whisper) == 0) + { + delimiter = " "; + } + + // Don't add any delimiter after name in irc styled messages + if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC) + { + delimiter = LLStringUtil::null; + + // italics for emotes -Zi + if(gSavedSettings.getBOOL("EmotesUseItalic")) + style_params.font.style = "ITALIC"; + } + + bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY; + // We graying out chat history by graying out messages that contains full date in a time string + if (message_from_log) + { + style_params.color(LLColor4::grey); + style_params.readonly_color(LLColor4::grey); + } + + // FS-1734 seperate name and text styles for moderator + + // Bold group moderators' chat -KC + //if (chat.mChatStyle == CHAT_STYLE_MODERATOR) + //{ + // // italics for emotes -Zi + // style_params.font.style = (irc_me && gSavedSettings.getBOOL("EmotesUseItalic")) ? "ITALICBOLD" : "BOLD"; + //} + bool moderator_style_active = false; + std::string moderator_name_style = ""; + std::string moderator_txt_style = ""; + U32 moderator_name_style_value = gSavedSettings.getU32("FSModNameStyle"); + U32 moderator_txt_style_value = gSavedSettings.getU32("FSModTextStyle"); + + enum ModeratorOptions + { + NORMAL, + BOLD, + ITALIC, + BOLD_ITALIC, + UNDERLINE, + BOLD_UNDERLINE, + ITALIC_UNDERLINE, + BOLD_ITALIC_UNDERLINE + }; + + if (chat.mChatStyle == CHAT_STYLE_MODERATOR) + { + moderator_style_active = true; + + switch (moderator_name_style_value) + { + case NORMAL: + moderator_name_style = "NORMAL"; + break; + case BOLD: + moderator_name_style = "BOLD"; + break; + case ITALIC: + moderator_name_style = "ITALIC"; + break; + case BOLD_ITALIC: + moderator_name_style = "BOLDITALIC"; + break; + case UNDERLINE: + moderator_name_style = "UNDERLINE"; + break; + case BOLD_UNDERLINE: + moderator_name_style = "BOLDUNDERLINE"; + break; + case ITALIC_UNDERLINE: + moderator_name_style = "ITALICUNDERLINE"; + break; + case BOLD_ITALIC_UNDERLINE: + moderator_name_style = "BOLDITALICUNDERLINE"; + break; + default: + moderator_name_style = "NORMAL"; + break; + } + style_params.font.style(moderator_name_style); + + switch (moderator_txt_style_value) + { + case NORMAL: + moderator_txt_style = "NORMAL"; + break; + case BOLD: + moderator_txt_style = "BOLD"; + break; + case ITALIC: + moderator_txt_style = "ITALIC"; + break; + case BOLD_ITALIC: + moderator_txt_style = "BOLDITALIC"; + break; + case UNDERLINE: + moderator_txt_style = "UNDERLINE"; + break; + case BOLD_UNDERLINE: + moderator_txt_style = "BOLDUNDERLINE"; + break; + case ITALIC_UNDERLINE: + moderator_txt_style = "ITALICUNDERLINE"; + break; + case BOLD_ITALIC_UNDERLINE: + moderator_txt_style = "BOLDITALICUNDERLINE"; + break; + default: + moderator_txt_style = "NORMAL"; + break; + } + style_params.font.style(moderator_txt_style); + + if ( irc_me && gSavedSettings.getBOOL("EmotesUseItalic") ) + { + if ( (ITALIC & moderator_name_style_value) != ITALIC )//HG: if ITALIC isn't one of the styles... add it + { + moderator_name_style += "ITALIC"; + style_params.font.style(moderator_name_style); + } + if ( (ITALIC & moderator_txt_style_value) != ITALIC ) + { + moderator_txt_style += "ITALIC"; + style_params.font.style(moderator_txt_style); + } + style_params.font.style(moderator_txt_style); + } + } + // FS-1734 seperate name and text styles for moderator + + if (use_plain_text_chat_history) + { + LLStyle::Params timestamp_style(style_params); + if (!message_from_log) + { + LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor"); + timestamp_style.color(timestamp_color); + timestamp_style.readonly_color(timestamp_color); + // FS-1734 seperate name and text styles for moderator + if ( moderator_style_active ) + { + timestamp_style.font.style(moderator_name_style); + } + // FS-1734 seperate name and text styles for moderator + } + // [FIRE-1641 : SJ]: Option to hide timestamps in nearby chat - only add timestamps when hide_timestamps_nearby_chat not TRUE + // mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getLength() != 0, timestamp_style); + if (!hide_timestamps_nearby_chat) + { + // mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getLength() != 0, timestamp_style); // FIRE-8600: TAB out of chat history + appendText("[" + chat.mTimeStr + "] ", getLength() != 0, timestamp_style); // FIRE-8600: TAB out of chat history + } + else + { + // mEditor->appendLineBreakSegment(timestamp_style); // FIRE-8600: TAB out of chat history + appendLineBreakSegment(timestamp_style); // FIRE-8600: TAB out of chat history + } + + if (utf8str_trim(chat.mFromName).size() != 0) + { + // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. + if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull()) + { +// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) | Added: RLVa-1.2.0f + // NOTE-RLVa: we don't need to do any @shownames or @showloc filtering here because we'll already have an existing URL + std::string url = chat.mURL; + RLV_ASSERT( (url.empty()) || (std::string::npos != url.find("objectim")) ); + if ( (url.empty()) || (std::string::npos == url.find("objectim")) ) + { +// [/RLVa:KB] + // for object IMs, create a secondlife:///app/objectim SLapp + /*std::string*/ url = LLViewerChat::getSenderSLURL(chat, args); +// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) | Added: RLVa-1.2.0f + } +// [/RLVa:KB] + + // set the link for the object name to be the objectim SLapp + // (don't let object names with hyperlinks override our objectim Url) + LLStyle::Params link_params(style_params); + link_params.color.control = "HTMLLinkColor"; + LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + link_params.color = link_color; + link_params.readonly_color = link_color; + link_params.is_link = true; + link_params.link_href = url; + + // mEditor->appendText(chat.mFromName +delimiter, false, link_params); // FIRE-8600: TAB out of chat history + appendText(chat.mFromName +delimiter, false, link_params); // FIRE-8600: TAB out of chat history + } +// else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log) +// [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) | Added: RLVa-1.2.0f + else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && !chat.mRlvNamesFiltered) +// [/RLVa:KB] + { + LLStyle::Params link_params(style_params); + link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID)); + + // Add link to avatar's inspector and delimiter to message. + // reset the style parameter for the header only -AO + link_params.color(header_name_color); + link_params.readonly_color(header_name_color); + + // FS:LO FIRE-2899 - Faded text for IMs in nearby chat + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //if(chat.mChatType == CHAT_TYPE_IM) + if(chat.mChatType == CHAT_TYPE_IM || chat.mChatType == CHAT_TYPE_IM_GROUP) + { + link_params.color.alpha = FSIMChatHistoryFade; + link_params.readonly_color.alpha = FSIMChatHistoryFade; + // FS:LO FIRE-2899 - Faded text for IMs in nearby chat + // mEditor->appendText(LLTrans::getString("IMPrefix") + " ", false, link_params); // FIRE-8600: TAB out of chat history + appendText(LLTrans::getString("IMPrefix") + " ", false, link_params); // FIRE-8600: TAB out of chat history + } + + if ((gSavedSettings.getBOOL("NameTagShowUsernames")) && (gSavedSettings.getBOOL("UseDisplayNames"))) + { + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //mEditor->appendText(mDisplayName_Username, false, link_params); + if (chat.mChatType == CHAT_TYPE_IM_GROUP) + { + // mEditor->appendText(chat.mFromNameGroup + mDisplayName_Username, false, link_params); // FIRE-8600: TAB out of chat history + appendText(chat.mFromNameGroup + mDisplayName_Username, false, link_params); // FIRE-8600: TAB out of chat history + } + else + { + // FS-1734 seperate name and text styles for moderator + if ( moderator_style_active ) + { + link_params.font.style(moderator_name_style); + } + // FS-1734 seperate name and text styles for moderator + // mEditor->appendText(mDisplayName_Username, false, link_params); // FIRE-8600: TAB out of chat history + appendText(mDisplayName_Username, false, link_params); // FIRE-8600: TAB out of chat history + } + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + } + else if (gSavedSettings.getBOOL("UseDisplayNames")) + { + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //mEditor->appendText(mDisplayName, false, link_params); + if (chat.mChatType == CHAT_TYPE_IM_GROUP) + { + // mEditor->appendText(chat.mFromNameGroup + mDisplayName, false, link_params); // FIRE-8600: TAB out of chat history + appendText(chat.mFromNameGroup + mDisplayName, false, link_params); // FIRE-8600: TAB out of chat history + } + else + { + // FS-1734 seperate name and text styles for moderator + if ( moderator_style_active ) + { + link_params.font.style(moderator_name_style); + } + // FS-1734 seperate name and text styles for moderator + // mEditor->appendText(mDisplayName, false, link_params); // FIRE-8600: TAB out of chat history + appendText(mDisplayName, false, link_params); // FIRE-8600: TAB out of chat history + } + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + } + else + { + //mEditor->appendText(chat.mFromName, false, link_params); + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + if (chat.mChatType == CHAT_TYPE_IM_GROUP) + { + // mEditor->appendText(chat.mFromNameGroup + chat.mFromName, false, link_params); // FIRE-8600: TAB out of chat history + appendText(chat.mFromNameGroup + chat.mFromName, false, link_params); // FIRE-8600: TAB out of chat history + } + else + { + // FS-1734 seperate name and text styles for moderator + if ( moderator_style_active ) + { + link_params.font.style(moderator_name_style); + } + // FS-1734 seperate name and text styles for moderator + // mEditor->appendText(chat.mFromName, false, link_params); // FIRE-8600: TAB out of chat history + appendText(chat.mFromName, false, link_params); // FIRE-8600: TAB out of chat history + } + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + } + link_params.color(txt_color); + link_params.readonly_color(txt_color); + // mEditor->appendText(delimiter, false, style_params); // FIRE-8600: TAB out of chat history + appendText(delimiter, false, style_params); // FIRE-8600: TAB out of chat history + //mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params); + } + else + { + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //if (chat.mChatType == CHAT_TYPE_IM) + if (chat.mChatType == CHAT_TYPE_IM || chat.mChatType == CHAT_TYPE_IM_GROUP) + { + // mEditor->appendText(LLTrans::getString("IMPrefix") + " " + chat.mFromName + delimiter, false, style_params); // FIRE-8600: TAB out of chat history + appendText(LLTrans::getString("IMPrefix") + " " + chat.mFromName + delimiter, false, style_params); // FIRE-8600: TAB out of chat history + } + else + { + // mEditor->appendText(chat.mFromName + delimiter, false, style_params); // FIRE-8600: TAB out of chat history + appendText(chat.mFromName + delimiter, false, style_params); // FIRE-8600: TAB out of chat history + } + } + } + } + else + { + LLView* view = NULL; + LLInlineViewSegment::Params p; + p.force_newline = true; + p.left_pad = mLeftWidgetPad; + p.right_pad = mRightWidgetPad; + + LLDate new_message_time = LLDate::now(); + + std::string tmp_from_name(chat.mFromName); + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //if (chat.mChatType == CHAT_TYPE_IM) tmp_from_name = LLTrans::getString("IMPrefix") + " " + tmp_from_name; + if (chat.mChatType == CHAT_TYPE_IM) + { + tmp_from_name = LLTrans::getString("IMPrefix") + " " + tmp_from_name; + } + else if (chat.mChatType == CHAT_TYPE_IM_GROUP) + { + tmp_from_name = LLTrans::getString("IMPrefix") + " " + chat.mFromNameGroup + tmp_from_name; + } + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + + if (mLastFromName == tmp_from_name + && mLastFromID == chat.mFromID + && mLastMessageTime.notNull() + && (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0 + && mIsLastMessageFromLog == message_from_log) //distinguish between current and previous chat session's histories + { + view = getSeparator(); + p.top_pad = mTopSeparatorPad; + p.bottom_pad = mBottomSeparatorPad; + } + else + { + // reset the style color parameter for the header only -AO + style_params.color(header_name_color); + style_params.readonly_color(header_name_color); + view = getHeader(chat, style_params, args); + style_params.color(txt_color); + style_params.readonly_color(txt_color); + + // if (mEditor->getLength() == 0) // FIRE-8600: TAB out of chat history + if (getLength() == 0) // FIRE-8600: TAB out of chat history + p.top_pad = 0; + else + p.top_pad = mTopHeaderPad; + p.bottom_pad = mBottomHeaderPad; + + } + p.view = view; + + //Prepare the rect for the view + // LLRect target_rect = mEditor->getDocumentView()->getRect(); // FIRE-8600: TAB out of chat history + LLRect target_rect = getDocumentView()->getRect(); // FIRE-8600: TAB out of chat history + // squeeze down the widget by subtracting padding off left and right + // target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad(); // FIRE-8600: TAB out of chat history + target_rect.mLeft += mLeftWidgetPad + getHPad(); // FIRE-8600: TAB out of chat history + target_rect.mRight -= mRightWidgetPad; + view->reshape(target_rect.getWidth(), view->getRect().getHeight()); + view->setOrigin(target_rect.mLeft, view->getRect().mBottom); + + std::string widget_associated_text = "\n[" + chat.mTimeStr + "] "; + if (utf8str_trim(chat.mFromName).size() != 0 && chat.mFromName != SYSTEM_FROM) + widget_associated_text += chat.mFromName + delimiter; + + // mEditor->appendWidget(p, widget_associated_text, false); // FIRE-8600: TAB out of chat history + appendWidget(p, widget_associated_text, false); // FIRE-8600: TAB out of chat history + + mLastFromName = chat.mFromName; + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //if (chat.mChatType == CHAT_TYPE_IM) mLastFromName = LLTrans::getString("IMPrefix") + " " + mLastFromName; + if (chat.mChatType == CHAT_TYPE_IM) + { + mLastFromName = LLTrans::getString("IMPrefix") + " " + mLastFromName; + } + else if (chat.mChatType == CHAT_TYPE_IM_GROUP) + { + mLastFromName = LLTrans::getString("IMPrefix") + " " + chat.mFromNameGroup + mLastFromName; + } + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + mLastFromID = chat.mFromID; + mLastMessageTime = new_message_time; + mIsLastMessageFromLog = message_from_log; + } + + if (chat.mNotifId.notNull()) + { + LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId); + if (notification != NULL) + { + LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel( + notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history); + //we can't set follows in xml since it broke toasts behavior + notify_box->setFollowsLeft(); + notify_box->setFollowsRight(); + notify_box->setFollowsTop(); + + ctrl_list_t ctrls = notify_box->getControlPanel()->getCtrlList(); + S32 offset = 0; + // Children were added by addChild() which uses push_front to insert them into list, + // so to get buttons in correct order reverse iterator is used (EXT-5906) + for (ctrl_list_t::reverse_iterator it = ctrls.rbegin(); it != ctrls.rend(); it++) + { + LLButton * button = dynamic_cast (*it); + if (button != NULL) + { + button->setOrigin( offset, + button->getRect().mBottom); + button->setLeftHPad(2 * HPAD); + button->setRightHPad(2 * HPAD); + // set zero width before perform autoResize() + button->setRect(LLRect(button->getRect().mLeft, + button->getRect().mTop, button->getRect().mLeft, + button->getRect().mBottom)); + button->setAutoResize(true); + button->autoResize(); + offset += HPAD + button->getRect().getWidth(); + button->setFollowsNone(); + } + } + + //Prepare the rect for the view + // LLRect target_rect = mEditor->getDocumentView()->getRect(); // FIRE-8600: TAB out of chat history + LLRect target_rect = getDocumentView()->getRect(); // FIRE-8600: TAB out of chat history + // squeeze down the widget by subtracting padding off left and right + // target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad(); // FIRE-8600: TAB out of chat history + target_rect.mLeft += mLeftWidgetPad + getHPad(); // FIRE-8600: TAB out of chat history + target_rect.mRight -= mRightWidgetPad; + notify_box->reshape(target_rect.getWidth(), notify_box->getRect().getHeight()); + notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom); + + LLInlineViewSegment::Params params; + params.view = notify_box; + params.left_pad = mLeftWidgetPad; + params.right_pad = mRightWidgetPad; + // mEditor->appendWidget(params, "\n", false); // FIRE-8600: TAB out of chat history + appendWidget(params, "\n", false); // FIRE-8600: TAB out of chat history + } + } + else + { + std::string message = irc_me ? chat.mText.substr(3) : chat.mText; + + + //MESSAGE TEXT PROCESSING + //*HACK getting rid of redundant sender names in system notifications sent using sender name (see EXT-5010) + if (use_plain_text_chat_history && gAgentID != chat.mFromID && chat.mFromID.notNull()) + { + std::string slurl_about = SLURL_APP_AGENT + chat.mFromID.asString() + SLURL_ABOUT; + if (message.length() > slurl_about.length() && + message.compare(0, slurl_about.length(), slurl_about) == 0) + { + message = message.substr(slurl_about.length(), message.length()-1); + } + } + + if (irc_me && !use_plain_text_chat_history) + { + message = chat.mFromName + message; + } + + // Optional muted chat history + if (chat.mMuted) + { + LLUIColor muted_text_color = LLUIColorTable::instance().getColor("ChatHistoryMutedTextColor"); + style_params.color = muted_text_color; + style_params.readonly_color = muted_text_color; + style_params.selected_color = muted_text_color; + } + // Optional muted chat history + + // FS:LO FIRE-2899 - Faded text for IMs in nearby chat + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //if(chat.mChatType == CHAT_TYPE_IM) + if(chat.mSourceType != CHAT_SOURCE_OBJECT && (chat.mChatType == CHAT_TYPE_IM || chat.mChatType == CHAT_TYPE_IM_GROUP)) // FS::LO Fix for FIRE-6334; Fade IM Text into background of chat history default setting should not be 0.5; made object IM text not fade into the background as per phoenix behavior. + { + style_params.color.alpha = FSIMChatHistoryFade; + style_params.readonly_color.alpha = FSIMChatHistoryFade; + style_params.selected_color.alpha = FSIMChatHistoryFade; + } + // FS:LO FIRE-2899 - Faded text for IMs in nearby chat + + // FIRE-7625: Option to display group chats, IM sessions and nearby chat always in uppercase + static LLCachedControl sFSChatsUppercase(gSavedSettings, "FSChatsUppercase"); + if (sFSChatsUppercase) + { + LLStringUtil::toUpper(message); + LLStringUtil::toUpper(mLastFromName); + } + // + + // mEditor->appendText(message, FALSE, style_params); // FIRE-8600: TAB out of chat history + appendText(message, FALSE, style_params); // FIRE-8600: TAB out of chat history + } + + // mEditor->blockUndo(); // FIRE-8600: TAB out of chat history + blockUndo(); // FIRE-8600: TAB out of chat history + + // automatically scroll to end when receiving chat from myself + if (chat.mFromID == gAgentID) + { + // mEditor->setCursorAndScrollToEnd(); // FIRE-8600: TAB out of chat history + setCursorAndScrollToEnd(); // FIRE-8600: TAB out of chat history + } +} + +// FIRE-8600: TAB out of chat history +// void FSChatHistory::draw() +// { +// if (mEditor->scrolledToEnd()) +// { +// mUnreadChatSources.clear(); +// mMoreChatPanel->setVisible(FALSE); +// } +// +// LLUICtrl::draw(); +// } +// + +// FIRE-8602: Typing in chat history focuses chat input line +BOOL FSChatHistory::handleUnicodeCharHere(llwchar uni_char) +{ + // do not change focus when the CTRL key is used to make copy/select all etc. possible + if(gKeyboard->currentMask(false) & MASK_CONTROL) + { + // instead, let the base class handle things + return LLTextEditor::handleUnicodeCharHere(uni_char); + } + + // we don't know which is our chat input line yet + if(!mChatInputLine) + { + // get our focus root + LLUICtrl* focusRoot=findRootMostFocusRoot(); + if(focusRoot) + { + // focus on the next item that is a text input control + focusRoot->focusNextItem(true); + // remember the control's pointer if it really is a LLLineEditor + mChatInputLine=dynamic_cast(gFocusMgr.getKeyboardFocus()); + } + } + + // do we know our chat input line now? + if(mChatInputLine) + { + // we do, so focus on it + mChatInputLine->setFocus(true); + // and let it handle the keystroke + return mChatInputLine->handleUnicodeCharHere(uni_char); + } + + // we don't know what to do, so let our base class handle the keystroke + return LLTextEditor::handleUnicodeCharHere(uni_char); +} +// diff --git a/indra/newview/fschathistory.h b/indra/newview/fschathistory.h new file mode 100644 index 0000000000..98f6c5a91e --- /dev/null +++ b/indra/newview/fschathistory.h @@ -0,0 +1,167 @@ +/** + * @file llchathistory.h + * @brief LLTextEditor base class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Original file: llchathistory.h + +#ifndef FS_CHATHISTORY_H +#define FS_CHATHISTORY_H + +#include "lltexteditor.h" +#include "lltextbox.h" +#include "llviewerchat.h" +#include "llavatarname.h" + +class LLLineEditor; // FIRE-8602: Typing in chat history focuses chat input line + +//Chat log widget allowing addition of a message as a widget +// class LLChatHistory : public LLUICtrl // FIRE-8600: TAB out of chat history +class FSChatHistory : public LLTextEditor // FIRE-8600: TAB out of chat history +{ + public: + struct Params : public LLInitParam::Block + { + //Message header filename + Optional message_header; + //Message separator filename + Optional message_separator; + //Text left padding from the scroll rect + Optional left_text_pad; + //Text right padding from the scroll rect + Optional right_text_pad; + //Widget left padding from the scroll rect + Optional left_widget_pad; + //Widget right padding from the scroll rect + Optional right_widget_pad; + //Separator top padding + Optional top_separator_pad; + //Separator bottom padding + Optional bottom_separator_pad; + //Header top padding + Optional top_header_pad; + //Header bottom padding + Optional bottom_header_pad; + + // Optional more_chat_text; // FIRE-8600: TAB out of chat history + + Params() + : message_header("message_header"), + message_separator("message_separator"), + left_text_pad("left_text_pad"), + right_text_pad("right_text_pad"), + left_widget_pad("left_widget_pad"), + right_widget_pad("right_widget_pad"), + top_separator_pad("top_separator_pad"), + bottom_separator_pad("bottom_separator_pad"), + top_header_pad("top_header_pad"), + bottom_header_pad("bottom_header_pad") // FIRE-8600: TAB out of chat history + // more_chat_text("more_chat_text") // FIRE-8600: TAB out of chat history + {} + + }; + protected: + FSChatHistory(const Params&); + friend class LLUICtrlFactory; + + // /*virtual*/ void draw(); // FIRE-8600: TAB out of chat history + /** + * Redefinition of LLTextEditor::updateTextRect() to considerate text + * left/right padding params. + */ + //virtual void updateTextRect(); + /** + * Builds a message separator. + * @return pointer to LLView separator object. + */ + LLView* getSeparator(); + /** + * Builds a message header. + * @return pointer to LLView header object. + */ + + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + LLView* getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args); + + // void onClickMoreText(); // FIRE-8600: TAB out of chat history + + public: + ~FSChatHistory(); + + void initFromParams(const Params&); + + /** + * Appends a widget message. + * If last user appended message, concurs with current user, + * separator is added before the message, otherwise header is added. + * The args LLSD contains: + * - use_plain_text_chat_history (bool) - whether to add message as plain text. + * - owner_id (LLUUID) - the owner ID for object chat + * @param chat - base chat message. + * @param args - additional arguments + * @param input_append_params - font style. + */ + void appendMessage(const LLChat& chat, const LLSD &args = LLSD(), const LLStyle::Params& input_append_params = LLStyle::Params()); + /*virtual*/ void clear(); + + private: + std::string mLastFromName; + LLUUID mLastFromID; + LLDate mLastMessageTime; + bool mIsLastMessageFromLog; + //std::string mLastMessageTimeStr; + + std::string mMessageHeaderFilename; + std::string mMessageSeparatorFilename; + + S32 mLeftTextPad; + S32 mRightTextPad; + + S32 mLeftWidgetPad; + S32 mRightWidgetPad; + + S32 mTopSeparatorPad; + S32 mBottomSeparatorPad; + S32 mTopHeaderPad; + S32 mBottomHeaderPad; + + std::string mDisplayName; + std::string mDisplayName_Username; + +// FIRE-8600: TAB out of chat history +// class LLLayoutPanel* mMoreChatPanel; +// LLTextBox* mMoreChatText; +// LLTextEditor* mEditor; +// typedef std::set unread_chat_source_t; +// unread_chat_source_t mUnreadChatSources; +// + + // FIRE-8602: Typing in chat history focuses chat input line + public: + virtual BOOL handleUnicodeCharHere(llwchar uni_char); + + LLLineEditor* mChatInputLine; + // +}; +#endif // FS_CHATHISTORY_H diff --git a/indra/newview/fsconsoleutils.cpp b/indra/newview/fsconsoleutils.cpp index 6be4bea908..d19e6cd637 100644 --- a/indra/newview/fsconsoleutils.cpp +++ b/indra/newview/fsconsoleutils.cpp @@ -92,7 +92,7 @@ bool FSConsoleUtils::ProcessChatMessage(const LLChat& chat_msg, const LLSD &args LLColor4 chatcolor; LLViewerChat::getChatColor(chat_msg, chatcolor); gConsole->addConsoleLine(consoleChat, chatcolor); - gConsole->setVisible(!LLFloaterReg::instanceVisible("nearby_chat", LLSD())); + gConsole->setVisible(!LLFloaterReg::instanceVisible("fs_nearby_chat", LLSD())); } else { @@ -115,7 +115,7 @@ bool FSConsoleUtils::ProcessChatMessage(const LLChat& chat_msg, const LLSD &args LLColor4 chatcolor; LLViewerChat::getChatColor(chat_msg, chatcolor); gConsole->addConsoleLine(consoleChat, chatcolor); - gConsole->setVisible(!LLFloaterReg::instanceVisible("nearby_chat", LLSD())); + gConsole->setVisible(!LLFloaterReg::instanceVisible("fs_nearby_chat", LLSD())); } return true; @@ -171,7 +171,7 @@ void FSConsoleUtils::onProcessChatAvatarNameLookup(const LLUUID& agent_id, const LLColor4 chatcolor; LLViewerChat::getChatColor(chat_msg, chatcolor); gConsole->addConsoleLine(consoleChat, chatcolor); - gConsole->setVisible(!LLFloaterReg::instanceVisible("nearby_chat", LLSD())); + gConsole->setVisible(!LLFloaterReg::instanceVisible("fs_nearby_chat", LLSD())); } //static @@ -268,5 +268,5 @@ void FSConsoleUtils::onProccessInstantMessageNameLookup(const LLUUID& agent_id, } gConsole->addConsoleLine("IM: " + senderName + delimiter + message, textColor); - gConsole->setVisible(!LLFloaterReg::instanceVisible("nearby_chat", LLSD())); + gConsole->setVisible(!LLFloaterReg::instanceVisible("fs_nearby_chat", LLSD())); } diff --git a/indra/newview/fscontactsfloater.cpp b/indra/newview/fscontactsfloater.cpp index e760b3dfa0..62f87ad56c 100644 --- a/indra/newview/fscontactsfloater.cpp +++ b/indra/newview/fscontactsfloater.cpp @@ -44,7 +44,10 @@ #include "llfriendcard.h" #include "llgroupactions.h" #include "llgrouplist.h" -#include "llimfloatercontainer.h" +// [FS communication UI] +//#include "llimfloatercontainer.h" +#include "fsfloaterimcontainer.h" +// [FS communication UI] #include "llnotificationsutil.h" #include "llfloatersidepanelcontainer.h" #include "llstartup.h" @@ -184,7 +187,10 @@ void FSFloaterContacts::updateGroupButtons() void FSFloaterContacts::onOpen(const LLSD& key) { - LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + // [FS communication UI] + //LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + FSFloaterIMContainer* floater_container = FSFloaterIMContainer::getInstance(); + // [FS communication UI] if (gSavedSettings.getBOOL("ContactsTornOff")) { // first set the tear-off host to the conversations container @@ -220,7 +226,10 @@ void FSFloaterContacts::openTab(const std::string& name) if (visible) { - LLIMFloaterContainer* floater_container = (LLIMFloaterContainer *) getHost(); + // [FS communication UI] + //LLIMFloaterContainer* floater_container = (LLIMFloaterContainer *) getHost(); + FSFloaterIMContainer* floater_container = (FSFloaterIMContainer *) getHost(); + // [FS communication UI] if (floater_container) { floater_container->setVisible(TRUE); diff --git a/indra/newview/fsfloaterim.cpp b/indra/newview/fsfloaterim.cpp new file mode 100644 index 0000000000..80d7ba5eca --- /dev/null +++ b/indra/newview/fsfloaterim.cpp @@ -0,0 +1,1876 @@ +/** + * @file fsfloaterim.cpp + * @brief FSFloaterIM class definition + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Original file: llimfloater.cpp + +#include "llviewerprecompiledheaders.h" + +#include "fsfloaterim.h" + +#include "llnotificationsutil.h" + +#include "llagent.h" +#include "llappviewer.h" +#include "llavatarnamecache.h" +#include "llbutton.h" +#include "llchannelmanager.h" +#include "llchiclet.h" +#include "llchicletbar.h" +#include "llfloaterabout.h" // for sysinfo button -Zi +#include "llfloaterreg.h" +#include "fsfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container +#include "llinventoryfunctions.h" +#include "lllayoutstack.h" +#include "lllineeditor.h" +#include "lllogchat.h" +#include "llpanelimcontrolpanel.h" +#include "llscreenchannel.h" +#include "llsyswellwindow.h" +#include "lltrans.h" +#include "fschathistory.h" +#include "llnotifications.h" +#include "llviewerwindow.h" +#include "llvoicechannel.h" +#include "lltransientfloatermgr.h" +#include "llinventorymodel.h" +#include "llrootview.h" +#include "llspeakers.h" +#include "llviewerchat.h" +#include "llautoreplace.h" +// [RLVa:KB] - Checked: 2010-04-09 (RLVa-1.2.0e) +#include "rlvhandler.h" +// [/RLVa:KB] + +//AO: For moving callbacks from control panel into this class +#include "llavataractions.h" +#include "llgroupactions.h" +#include "llvoicechannel.h" +//TL: for support group chat prefix +#include "fsdata.h" +#include "llversioninfo.h" +#include "llcheckboxctrl.h" + +#include "llnotificationtemplate.h" // Viewer version popup +#include "fscommon.h" + +FSFloaterIM::FSFloaterIM(const LLUUID& session_id) + : LLTransientDockableFloater(NULL, true, session_id), + mControlPanel(NULL), + mSessionID(session_id), + mLastMessageIndex(-1), + mDialog(IM_NOTHING_SPECIAL), + mChatHistory(NULL), + mInputEditor(NULL), + mSavedTitle(), + mTypingStart(), + mShouldSendTypingState(false), + mMeTyping(false), + mOtherTyping(false), + mTypingTimer(), + mTypingTimeoutTimer(), + mPositioned(false), + mSessionInitialized(false) +{ + LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionID); + if (im_session) + { + mSessionInitialized = im_session->mSessionInitialized; + + mDialog = im_session->mType; + switch(mDialog){ + case IM_NOTHING_SPECIAL: + case IM_SESSION_P2P_INVITE: + mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this); + break; + case IM_SESSION_CONFERENCE_START: + mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this); + break; + case IM_SESSION_GROUP_START: + mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this); + break; + case IM_SESSION_INVITE: + if (gAgent.isInGroup(mSessionID)) + { + mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this); + } + else + { + mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this); + } + break; + default: break; + } + } + setOverlapsScreenChannel(true); + + LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); + + setDocked(true); +} + +// virtual +BOOL FSFloaterIM::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) +{ + mInputEditor->setFocus(TRUE); + onTabInto(); + if(focus_flash) + { + gFocusMgr.triggerFocusFlash(); + } + return TRUE; +} + +void FSFloaterIM::onFocusLost() +{ + LLIMModel::getInstance()->resetActiveSessionID(); + + LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, false); +} + +void FSFloaterIM::onFocusReceived() +{ + LLIMModel::getInstance()->setActiveSessionID(mSessionID); + + LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, true); + + if (getVisible()) + { + LLIMModel::instance().sendNoUnreadMessages(mSessionID); + } + + // Give focus to input textbox + mInputEditor->setFocus(TRUE); +} + +// virtual +void FSFloaterIM::onClose(bool app_quitting) +{ + setTyping(false); + + // The source of much argument and design thrashing + // Should the window hide or the session close when the X is clicked? + // + // Last change: + // EXT-3516 X Button should end IM session, _ button should hide + + + // AO: Make sure observers are removed on close + mVoiceChannelStateChangeConnection.disconnect(); + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this); + } + + // FIRE-6077 et al: Always clean up observers when the floater dies + LLAvatarTracker::instance().removeParticularFriendObserver(mOtherParticipantUUID, this); + // FIRE-6077 et al + + gIMMgr->leaveSession(mSessionID); +} + +/* static */ +void FSFloaterIM::newIMCallback(const LLSD& data){ + + if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull()) + { + LLUUID session_id = data["session_id"].asUUID(); + + FSFloaterIM* floater = LLFloaterReg::findTypedInstance("fs_impanel", session_id); + if (floater == NULL) return; + + // update if visible, otherwise will be updated when opened + if (floater->getVisible()) + { + floater->updateMessages(); + } + } +} + +void FSFloaterIM::onVisibilityChange(const LLSD& new_visibility) +{ + bool visible = new_visibility.asBoolean(); + + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + + if (visible && voice_channel && + voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED) + { + LLFloaterReg::showInstance("voice_call", mSessionID); + } + else + { + LLFloaterReg::hideInstance("voice_call", mSessionID); + } +} + +void FSFloaterIM::onSendMsg( LLUICtrl* ctrl, void* userdata ) +{ + FSFloaterIM* self = (FSFloaterIM*) userdata; + self->sendMsg(); + self->setTyping(false); +} + +void FSFloaterIM::sendMsg() +{ + if (!gAgent.isGodlike() + && (mDialog == IM_NOTHING_SPECIAL) + && mOtherParticipantUUID.isNull()) + { + llinfos << "Cannot send IM to everyone unless you're a god." << llendl; + return; + } + + if (mInputEditor) + { + LLWString text = mInputEditor->getConvertedText(); + if(!text.empty()) + { + // Convert to UTF8 for transport + std::string utf8_text = wstring_to_utf8str(text); + + // Convert OOC and MU* style poses + utf8_text = applyAutoCloseOoc(utf8_text); + utf8_text = applyMuPose(utf8_text); + + // Support group chat prefix + static LLCachedControl chat_prefix(gSavedSettings, "FSSupportGroupChatPrefix2"); + if (chat_prefix && FSData::getInstance()->isSupportGroup(mSessionID)) + { + + // FIRE-7075: Skin indicator + static LLCachedControl FSInternalSkinCurrent(gSavedSettings, "FSInternalSkinCurrent"); + std::string skinIndicator(FSInternalSkinCurrent); + LLStringUtil::toLower(skinIndicator); + if (skinIndicator == "starlight cui") + { + skinIndicator = "sc"; // Separate "s" (StarLight) from "sc" (StarLight CUI) + } + else + { + skinIndicator = skinIndicator.substr(0, 1); // "FS 4.4.1f os", "FS 4.4.1v", "FS 4.4.1a", "FS 4.4.1s os", "FS 4.4.1m os" etc. + } + // + + if (utf8_text.find("/me ") == 0 || utf8_text.find("/me'") == 0) + { + utf8_text.insert(4,("(FS " + LLVersionInfo::getShortVersion() + skinIndicator + +#ifdef OPENSIM + " os" + +#endif + ") ")); + } + else + { + utf8_text.insert(0,("(FS " + LLVersionInfo::getShortVersion() + skinIndicator + +#ifdef OPENSIM + " os" + +#endif + ") ")); + } + } + + // Allow user to send system info. + if(mDialog == IM_NOTHING_SPECIAL && utf8_text.find("/sysinfo") == 0) + { + LLSD system_info = FSData::getSystemInfo(); + utf8_text = system_info["Part1"].asString() + system_info["Part2"].asString(); + } + // + + // Truncate for transport + // FIRE-787: break up too long chat lines into multiple messages + //utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); + // FIRE-787 + +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) ) + { + LLIMModel::LLIMSession* pIMSession = LLIMModel::instance().findIMSession(mSessionID); + RLV_ASSERT(pIMSession); + + bool fRlvFilter = !pIMSession; + if (pIMSession) + { + switch (pIMSession->mSessionType) + { + case LLIMModel::LLIMSession::P2P_SESSION: // One-on-one IM + fRlvFilter = !gRlvHandler.canSendIM(mOtherParticipantUUID); + break; + case LLIMModel::LLIMSession::GROUP_SESSION: // Group chat + fRlvFilter = !gRlvHandler.canSendIM(mSessionID); + break; + case LLIMModel::LLIMSession::ADHOC_SESSION: // Conference chat: allow if all participants can be sent an IM + { + if (!pIMSession->mSpeakers) + { + fRlvFilter = true; + break; + } + + LLSpeakerMgr::speaker_list_t speakers; + pIMSession->mSpeakers->getSpeakerList(&speakers, TRUE); + for (LLSpeakerMgr::speaker_list_t::const_iterator itSpeaker = speakers.begin(); + itSpeaker != speakers.end(); ++itSpeaker) + { + const LLSpeaker* pSpeaker = *itSpeaker; + if ( (gAgent.getID() != pSpeaker->mID) && (!gRlvHandler.canSendIM(pSpeaker->mID)) ) + { + fRlvFilter = true; + break; + } + } + } + break; + default: + fRlvFilter = true; + break; + } + } + + if (fRlvFilter) + utf8_text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM); + } +// [/RLVa:KB] + +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) ) + { + LLIMModel::LLIMSession* pIMSession = LLIMModel::instance().findIMSession(mSessionID); + RLV_ASSERT(pIMSession); + + bool fRlvFilter = !pIMSession; + if (pIMSession) + { + switch (pIMSession->mSessionType) + { + case LLIMModel::LLIMSession::P2P_SESSION: // One-on-one IM + fRlvFilter = !gRlvHandler.canSendIM(mOtherParticipantUUID); + break; + case LLIMModel::LLIMSession::GROUP_SESSION: // Group chat + fRlvFilter = !gRlvHandler.canSendIM(mSessionID); + break; + case LLIMModel::LLIMSession::ADHOC_SESSION: // Conference chat: allow if all participants can be sent an IM + { + if (!pIMSession->mSpeakers) + { + fRlvFilter = true; + break; + } + + LLSpeakerMgr::speaker_list_t speakers; + pIMSession->mSpeakers->getSpeakerList(&speakers, TRUE); + for (LLSpeakerMgr::speaker_list_t::const_iterator itSpeaker = speakers.begin(); + itSpeaker != speakers.end(); ++itSpeaker) + { + const LLSpeaker* pSpeaker = *itSpeaker; + if ( (gAgent.getID() != pSpeaker->mID) && (!gRlvHandler.canSendIM(pSpeaker->mID)) ) + { + fRlvFilter = true; + break; + } + } + } + break; + default: + fRlvFilter = true; + break; + } + } + + if (fRlvFilter) + utf8_text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM); + } +// [/RLVa:KB] + + if (mSessionInitialized) + { + LLIMModel::sendMessage(utf8_text, mSessionID, + mOtherParticipantUUID,mDialog); + } + else + { + //queue up the message to send once the session is initialized + mQueuedMsgsForInit.append(utf8_text); + } + + mInputEditor->setText(LLStringUtil::null); + + updateMessages(); + } +// [SL:KB] - Patch: Chat-NearbyChatBar | Checked: 2011-12-02 (Catznip-3.2.0d) | Added: Catznip-3.2.0d + else if (gSavedSettings.getBOOL("CloseIMOnEmptyReturn")) + { + // Close if we're the child of a floater + closeFloater(); + } +// [/SL:KB] + } +} + + + +FSFloaterIM::~FSFloaterIM() +{ + llinfos << "~FSFloaterIM, instance exists is: " << ((LLTransientFloaterMgr::getInstance()) == NULL) << llendl; + LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, (LLView*)this); + mVoiceChannelStateChangeConnection.disconnect(); + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this); + } + + LLIMModel::LLIMSession* pIMSession = LLIMModel::instance().findIMSession(mSessionID); + if ((pIMSession) && (pIMSession->mSessionType == LLIMModel::LLIMSession::P2P_SESSION)) + { + llinfos << "AO: Cleaning up stray particularFriendObservers" << llendl; + LLAvatarTracker::instance().removeParticularFriendObserver(mOtherParticipantUUID, this); + } +} + +// Callbacks previously in llcontrol_panel, moved to this floater. + +void FSFloaterIM::onViewProfileButtonClicked() +{ + llinfos << "FSFloaterIM::onViewProfileButtonClicked" << llendl; + LLAvatarActions::showProfile(mOtherParticipantUUID); +} +void FSFloaterIM::onAddFriendButtonClicked() +{ + llinfos << "FSFloaterIM::onAddFriendButtonClicked" << llendl; + //[FIX FIRE-2009: SJ] Offering friendship gives wrong status message. full_name was emtpy on call but was also obsolete + // + //LLAvatarIconCtrl* avatar_icon = getChild("avatar_icon"); + //std::string full_name = avatar_icon->getFullName(); + //LLAvatarActions::requestFriendshipDialog(mOtherParticipantUUID, full_name); + LLAvatarActions::requestFriendshipDialog(mOtherParticipantUUID); +} +void FSFloaterIM::onShareButtonClicked() +{ + llinfos << "FSFloaterIM::onShareButtonClicked" << llendl; + LLAvatarActions::share(mOtherParticipantUUID); +} +void FSFloaterIM::onTeleportButtonClicked() +{ + llinfos << "FSFloaterIM::onTeleportButtonClicked" << llendl; + LLAvatarActions::offerTeleport(mOtherParticipantUUID); +} +void FSFloaterIM::onPayButtonClicked() +{ + llinfos << "FSFloaterIM::onPayButtonClicked" << llendl; + LLAvatarActions::pay(mOtherParticipantUUID); +} +void FSFloaterIM::onGroupInfoButtonClicked() +{ + llinfos << "FSFloaterIM::onGroupInfoButtonClicked" << llendl; + LLGroupActions::show(mSessionID); +} +void FSFloaterIM::onCallButtonClicked() +{ + llinfos << "FSFloaterIM::onCallButtonClicked" << llendl; + gIMMgr->startCall(mSessionID); +} +void FSFloaterIM::onEndCallButtonClicked() +{ + llinfos << "FSFloaterIM::onEndCallButtonClicked" << llendl; + gIMMgr->endCall(mSessionID); +} +void FSFloaterIM::onOpenVoiceControlsClicked() +{ + llinfos << "FSFloaterIM::onOpenVoiceControlsClicked" << llendl; + LLFloaterReg::showInstance("voice_controls"); +} +void FSFloaterIM::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state) +{ + llinfos << "FSFloaterIM::onVoiceChannelStateChanged" << llendl; + updateButtons(new_state >= LLVoiceChannel::STATE_CALL_STARTED); +} +void FSFloaterIM::onHistoryButtonClicked() +{ + gViewerWindow->getWindow()->openFile(LLLogChat::makeLogFileName(LLIMModel::instance().getHistoryFileName(mSessionID))); +} + +// support sysinfo button -Zi +void FSFloaterIM::onSysinfoButtonClicked() +{ + LLSD system_info = FSData::getSystemInfo(); + LLSD args; + args["SYSINFO"] = system_info["Part1"].asString() + system_info["Part2"].asString(); + args["Part1"] = system_info["Part1"]; + args["Part2"] = system_info["Part2"]; + LLNotificationsUtil::add("SendSysinfoToIM",args,LLSD(),boost::bind(&FSFloaterIM::onSendSysinfo,this,_1,_2)); +} + +BOOL FSFloaterIM::onSendSysinfo(const LLSD& notification, const LLSD& response) +{ + S32 option=LLNotificationsUtil::getSelectedOption(notification,response); + + if(option==0) + { + std::string part1 = notification["substitutions"]["Part1"]; + std::string part2 = notification["substitutions"]["Part2"]; + if (mSessionInitialized) + { + LLIMModel::sendMessage(part1, mSessionID,mOtherParticipantUUID,mDialog); + LLIMModel::sendMessage(part2, mSessionID,mOtherParticipantUUID,mDialog); + } + else + { + //queue up the message to send once the session is initialized + mQueuedMsgsForInit.append(part1); + mQueuedMsgsForInit.append(part2); + } + return TRUE; + } + return FALSE; +} + +void FSFloaterIM::onSysinfoButtonVisibilityChanged(const LLSD& yes) +{ + mSysinfoButton->setVisible(yes.asBoolean() /* && mIsSupportIM */); +} +// support sysinfo button -Zi + +void FSFloaterIM::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ + // llinfos << "FSFloaterIM::onChange" << llendl; + if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) + { + return; + } + + updateCallButton(); +} + +void FSFloaterIM::updateCallButton() +{ + // llinfos << "FSFloaterIM::updateCallButton" << llendl; + // hide/show call button + bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID); + + if (!session) + { + getChild("call_btn")->setEnabled(false); + return; + } + + //bool session_initialized = session->mSessionInitialized; + bool callback_enabled = session->mCallBackEnabled; + + //[Possible FIX-FIRE-2012] GROUP and Ad-Hoc don't have session initialized --> removing that from the condition to enable_connect + //BOOL enable_connect = session_initialized + //&& voice_enabled + //&& callback_enabled; + BOOL enable_connect = voice_enabled + && callback_enabled; + //if (voice_enabled) + //{ + // llinfos << "FSFloaterIM::updateCallButton - voice enabled" << llendl; + //} + //if (session_initialized) + //{ + // llinfos << "FSFloaterIM::updateCallButton - session_initialized" << llendl; + //} + //if (callback_enabled) + //{ + // llinfos << "FSFloaterIM::updateCallButton - callback_enabled" << llendl; + //} + + getChild("call_btn")->setEnabled(enable_connect); +} + +void FSFloaterIM::updateButtons(bool is_call_started) +{ + llinfos << "FSFloaterIM::updateButtons" << llendl; + getChild("ls_control_panel")->reshape(240,20,true); + getChildView("end_call_btn_panel")->setVisible( is_call_started); + getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started); + getChildView("call_btn_panel")->setVisible( ! is_call_started); + updateCallButton(); + + // AO: force resize the widget because llpanels don't resize properly on vis change. + llinfos << "force resize the widget" << llendl; + LLIMModel::LLIMSession* pIMSession = LLIMModel::instance().findIMSession(mSessionID); + switch (pIMSession->mSessionType) + { + case LLIMModel::LLIMSession::P2P_SESSION: // One-on-one IM + { + getChild("ls_control_panel")->reshape(230,20,true); + break; + } + case LLIMModel::LLIMSession::GROUP_SESSION: // Group chat + { + getChild("ls_control_panel")->reshape(170,20,true); + break; + } + case LLIMModel::LLIMSession::ADHOC_SESSION: // Conference chat + { + getChild("ls_control_panel")->reshape(150,20,true); + break; + } + default: + break; + } + +} + +void FSFloaterIM::changed(U32 mask) +{ + llinfos << "FSFloaterIM::changed(U32 mask)" << llendl; + getChild("call_btn")->setEnabled(!LLAvatarActions::isFriend(mOtherParticipantUUID)); + + // Disable "Teleport" button if friend is offline + if(LLAvatarActions::isFriend(mOtherParticipantUUID)) + { + getChild("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mOtherParticipantUUID)); + } +} + +// Callbacks for llimcontrol panel, merged into this floater + +//virtual +BOOL FSFloaterIM::postBuild() +{ + const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID); + if (other_party_id.notNull()) + { + mOtherParticipantUUID = other_party_id; + } + + mControlPanel->setSessionId(mSessionID); + + // AO: always hide the control panel to start. + llinfos << "mControlPanel->getParent()" << mControlPanel->getParent() << llendl; + mControlPanel->getParent()->setVisible(false); + + //mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")); + + llinfos << "buttons setup in IM start" << llendl; + + LLButton* slide_left = getChild("slide_left_btn"); + slide_left->setVisible(mControlPanel->getParent()->getVisible()); + slide_left->setClickedCallback(boost::bind(&FSFloaterIM::onSlide, this)); + + LLButton* slide_right = getChild("slide_right_btn"); + slide_right->setVisible(!mControlPanel->getParent()->getVisible()); + slide_right->setClickedCallback(boost::bind(&FSFloaterIM::onSlide, this)); + + LLButton* view_profile = getChild("view_profile_btn"); + view_profile->setClickedCallback(boost::bind(&FSFloaterIM::onViewProfileButtonClicked, this)); + + LLButton* group_profile = getChild("group_info_btn"); + group_profile->setClickedCallback(boost::bind(&FSFloaterIM::onGroupInfoButtonClicked, this)); + + LLButton* call = getChild("call_btn"); + call->setClickedCallback(boost::bind(&FSFloaterIM::onCallButtonClicked, this)); + + LLButton* endcall = getChild("end_call_btn"); + endcall->setClickedCallback(boost::bind(&FSFloaterIM::onEndCallButtonClicked, this)); + + LLButton* voicectrl = getChild("voice_ctrls_btn"); + voicectrl->setClickedCallback(boost::bind(&FSFloaterIM::onOpenVoiceControlsClicked, this)); + + LLButton* share = getChild("share_btn"); + share->setClickedCallback(boost::bind(&FSFloaterIM::onShareButtonClicked, this)); + + LLButton* tp = getChild("teleport_btn"); + tp->setClickedCallback(boost::bind(&FSFloaterIM::onTeleportButtonClicked, this)); + + LLButton* pay = getChild("pay_btn"); + pay->setClickedCallback(boost::bind(&FSFloaterIM::onPayButtonClicked, this)); + + LLButton* add_friend = getChild("add_friend_btn"); + add_friend->setClickedCallback(boost::bind(&FSFloaterIM::onAddFriendButtonClicked, this)); + + LLButton* im_history = getChild("im_history_btn"); + im_history->setClickedCallback(boost::bind(&FSFloaterIM::onHistoryButtonClicked, this)); + + // support sysinfo button -Zi + mSysinfoButton=getChild("send_sysinfo_btn"); + onSysinfoButtonVisibilityChanged(FALSE); + + // extra icon controls -AO + LLButton* transl = getChild("translate_btn"); +//TT + llinfos << "transl" << (transl == NULL) << llendl; + if (transl != NULL) + transl->setVisible(true); + + // type-specfic controls + LLIMModel::LLIMSession* pIMSession = LLIMModel::instance().findIMSession(mSessionID); + if (pIMSession) + { + switch (pIMSession->mSessionType) + { + case LLIMModel::LLIMSession::P2P_SESSION: // One-on-one IM + { + llinfos << "LLIMModel::LLIMSession::P2P_SESSION" << llendl; + getChild("slide_panel")->setVisible(false); + getChild("gprofile_panel")->setVisible(false); + getChild("end_call_btn_panel")->setVisible(false); + getChild("voice_ctrls_btn_panel")->setVisible(false); + getChild("ls_control_panel")->reshape(200,20,true); + + llinfos << "AO: adding FSFloaterIM removing/adding particularfriendobserver" << llendl; + LLAvatarTracker::instance().removeParticularFriendObserver(mOtherParticipantUUID, this); + LLAvatarTracker::instance().addParticularFriendObserver(mOtherParticipantUUID, this); + + // Disable "Add friend" button for friends. + llinfos << "add_friend_btn check start" << llendl; + getChild("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mOtherParticipantUUID)); + + // Disable "Teleport" button if friend is offline + if(LLAvatarActions::isFriend(mOtherParticipantUUID)) + { + llinfos << "LLAvatarActions::isFriend - tp button" << llendl; + getChild("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mOtherParticipantUUID)); + } + + // support sysinfo button -Zi + mSysinfoButton->setClickedCallback(boost::bind(&FSFloaterIM::onSysinfoButtonClicked, this)); + // this needs to be extended to fsdata awareness, once we have it. -Zi + // mIsSupportIM=fsdata(partnerUUID).isSupport(); // pseudocode something like this + onSysinfoButtonVisibilityChanged(gSavedSettings.getBOOL("SysinfoButtonInIM")); + gSavedSettings.getControl("SysinfoButtonInIM")->getCommitSignal()->connect(boost::bind(&FSFloaterIM::onSysinfoButtonVisibilityChanged,this,_2)); + // support sysinfo button -Zi + + break; + } + case LLIMModel::LLIMSession::GROUP_SESSION: // Group chat + { + llinfos << "LLIMModel::LLIMSession::GROUP_SESSION start" << llendl; + getChild("profile_panel")->setVisible(false); + getChild("friend_panel")->setVisible(false); + getChild("tp_panel")->setVisible(false); + getChild("share_panel")->setVisible(false); + getChild("pay_panel")->setVisible(false); + getChild("end_call_btn_panel")->setVisible(false); + getChild("voice_ctrls_btn_panel")->setVisible(false); + getChild("ls_control_panel")->reshape(140,20,true); + + llinfos << "LLIMModel::LLIMSession::GROUP_SESSION end" << llendl; + break; + } + case LLIMModel::LLIMSession::ADHOC_SESSION: // Conference chat + { + llinfos << "LLIMModel::LLIMSession::ADHOC_SESSION start" << llendl; + getChild("profile_panel")->setVisible(false); + getChild("gprofile_panel")->setVisible(false); + getChild("friend_panel")->setVisible(false); + getChild("tp_panel")->setVisible(false); + getChild("share_panel")->setVisible(false); + getChild("pay_panel")->setVisible(false); + getChild("end_call_btn_panel")->setVisible(false); + getChild("voice_ctrls_btn_panel")->setVisible(false); + getChild("ls_control_panel")->reshape(120,20,true); + llinfos << "LLIMModel::LLIMSession::ADHOC_SESSION end" << llendl; + break; + } + default: + llinfos << "default buttons start" << llendl; + getChild("end_call_btn_panel")->setVisible(false); + getChild("voice_ctrls_btn_panel")->setVisible(false); + llinfos << "default buttons end" << llendl; + break; + } + } + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + if(voice_channel) + { + llinfos << "voice_channel start" << llendl; + mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&FSFloaterIM::onVoiceChannelStateChanged, this, _1, _2)); + + //call (either p2p, group or ad-hoc) can be already in started state + updateButtons(voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED); + llinfos << "voice_channel end" << llendl; + } + LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this); + + // + + + mInputEditor = getChild("chat_editor"); + // FIRE-5770: input text buffer is too small + mInputEditor->setMaxTextLength(3000); + // FIRE-5770 + // enable line history support for instant message bar + mInputEditor->setEnableLineHistory(TRUE); + // *TODO Establish LineEditor with autoreplace callback + mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2)); + + LLFontGL* font = LLViewerChat::getChatFont(); + mInputEditor->setFont(font); + + mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) ); + mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) ); + mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this ); + mInputEditor->setCommitOnFocusLost( FALSE ); + mInputEditor->setRevertOnEsc( FALSE ); + mInputEditor->setReplaceNewlinesWithSpaces( FALSE ); + mInputEditor->setPassDelete( TRUE ); + + childSetCommitCallback("chat_editor", onSendMsg, this); + + mChatHistory = getChild("chat_history"); + + LLCheckBoxCtrl* FSPrefixBox = getChild("FSSupportGroupChatPrefix_toggle"); + + BOOL isFSSupportGroup=FSData::getInstance()->isSupportGroup(mSessionID); + FSPrefixBox->setVisible(isFSSupportGroup); + + // Viewer version popup + if(isFSSupportGroup) + { + // check if the dialog was set to ignore + LLNotificationTemplatePtr templatep=LLNotifications::instance().getTemplate("FirstJoinSupportGroup"); + if(!templatep.get()->mForm->getIgnored()) + { + // if not, give the user a choice, whether to enable the version prefix or not + LLSD args; + LLNotificationsUtil::add("FirstJoinSupportGroup",args,LLSD(),boost::bind(&FSFloaterIM::enableViewerVersionCallback,this,_1,_2)); + } + } + // Viewer version popup + + setDocked(true); + + mTypingStart = LLTrans::getString("IM_typing_start_string"); + + // Disable input editor if session cannot accept text + LLIMModel::LLIMSession* im_session = + LLIMModel::instance().findIMSession(mSessionID); + if( im_session && !im_session->mTextIMPossible ) + { + mInputEditor->setEnabled(FALSE); + mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label")); + } + + if ( im_session && im_session->isP2PSessionType()) + { + // look up display name for window title + LLAvatarNameCache::get(im_session->mOtherParticipantID, + boost::bind(&FSFloaterIM::onAvatarNameCache, + this, _1, _2)); + } + else + { + std::string session_name(LLIMModel::instance().getName(mSessionID)); + updateSessionName(session_name, session_name); + } + + //*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla" + //see LLFloaterIMPanel for how it is done (IB) + + if(isChatMultiTab()) + { + return LLFloater::postBuild(); + } + else + { + return LLDockableFloater::postBuild(); + } +} + +void FSFloaterIM::updateSessionName(const std::string& ui_title, + const std::string& ui_label) +{ + mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + ui_label); + setTitle(ui_title); +} + +void FSFloaterIM::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name) +{ + // FIRE-8658: Let the user decide how the name should be displayed + // Use display name only for labels, as the extended name will be in the + // floater title + //std::string ui_title = av_name.getCompleteName(); + //updateSessionName(ui_title, av_name.mDisplayName); + //mTypingStart.setArg("[NAME]", ui_title); + + std::string name = av_name.getCompleteName(); + if (LLAvatarNameCache::useDisplayNames()) + { + switch (gSavedSettings.getS32("FSIMTabNameFormat")) + { + // Display name + case 0: + name = av_name.mDisplayName; + break; + // Username + case 1: + name = av_name.mUsername; + break; + // Display name (username) + case 2: + // Do nothing - we already set the complete name as default + break; + // Username (display name) + case 3: + if (av_name.mIsDisplayNameDefault) + { + name = av_name.mUsername; + } + else + { + name = av_name.mUsername + " (" + av_name.mDisplayName + ")"; + } + break; + default: + // Do nothing - we already set the complete name as default + break; + } + } + + updateSessionName(name, name); + mTypingStart.setArg("[NAME]", name); + llinfos << "Setting IM tab name to '" << name << "'" << llendl; + // +} + +// virtual +void FSFloaterIM::draw() +{ + if ( mMeTyping ) + { + // Time out if user hasn't typed for a while. + if ( mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS ) + { + setTyping(false); + } + } + + LLTransientDockableFloater::draw(); +} + + +// static +void* FSFloaterIM::createPanelIMControl(void* userdata) +{ + FSFloaterIM *self = (FSFloaterIM*)userdata; + self->mControlPanel = new LLPanelIMControlPanel(); + self->mControlPanel->setXMLFilename("panel_im_control_panel.xml"); + return self->mControlPanel; +} + + +// static +void* FSFloaterIM::createPanelGroupControl(void* userdata) +{ + FSFloaterIM *self = (FSFloaterIM*)userdata; + self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID); + self->mControlPanel->setXMLFilename("panel_group_control_panel.xml"); + return self->mControlPanel; +} + +// static +void* FSFloaterIM::createPanelAdHocControl(void* userdata) +{ + FSFloaterIM *self = (FSFloaterIM*)userdata; + self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID); + self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml"); + return self->mControlPanel; +} + +void FSFloaterIM::onSlide() +{ + mControlPanel->getParent()->setVisible(!mControlPanel->getParent()->getVisible()); + + gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getParent()->getVisible()); + + getChild("slide_left_btn")->setVisible(mControlPanel->getParent()->getVisible()); + getChild("slide_right_btn")->setVisible(!mControlPanel->getParent()->getVisible()); +} + +//static +FSFloaterIM* FSFloaterIM::show(const LLUUID& session_id) +{ + closeHiddenIMToasts(); + + if (!gIMMgr->hasSession(session_id)) return NULL; + + if(!isChatMultiTab()) + { + //hide all + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("fs_impanel"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); + iter != inst_list.end(); ++iter) + { + FSFloaterIM* floater = dynamic_cast(*iter); + if (floater && floater->isDocked()) + { + floater->setVisible(false); + } + } + } + + bool exist = findInstance(session_id); + + FSFloaterIM* floater = getInstance(session_id); + if (!floater) return NULL; + + if(isChatMultiTab()) + { + FSFloaterIMContainer* floater_container = FSFloaterIMContainer::getInstance(); + + // do not add existed floaters to avoid adding torn off instances + if (!exist) + { + // LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; + // TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists + LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END; + + if (floater_container) + { + floater_container->addFloater(floater, TRUE, i_pt); + } + } + + floater->openFloater(floater->getKey()); + } + else + { + // Docking may move chat window, hide it before moving, or user will see how window "jumps" + floater->setVisible(false); + + if (floater->getDockControl() == NULL) + { + LLChiclet* chiclet = + LLChicletBar::getInstance()->getChicletPanel()->findChiclet( + session_id); + if (chiclet == NULL) + { + llerror("Dock chiclet for FSFloaterIM doesn't exists", 0); + } + else + { + LLChicletBar::getInstance()->getChicletPanel()->scrollToChiclet(chiclet); + } + + // Group notices, IMs and chiclets position + //floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(), + // LLDockControl::BOTTOM)); + if (gSavedSettings.getBOOL("InternalShowGroupNoticesTopRight")) + { + floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(), + LLDockControl::BOTTOM)); + } + else + { + floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(), + LLDockControl::TOP)); + } + // Group notices, IMs and chiclets position + } + + // window is positioned, now we can show it. + floater->setVisible(TRUE); + } + + return floater; +} + +void FSFloaterIM::setDocked(bool docked, bool pop_on_undock) +{ + // update notification channel state + LLNotificationsUI::LLScreenChannel* channel = static_cast + (LLNotificationsUI::LLChannelManager::getInstance()-> + findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + + if(!isChatMultiTab()) + { + LLTransientDockableFloater::setDocked(docked, pop_on_undock); + } + + // update notification channel state + if(channel) + { + channel->updateShowToastsState(); + channel->redrawToasts(); + } +} + +void FSFloaterIM::setVisible(BOOL visible) +{ + LLNotificationsUI::LLScreenChannel* channel = static_cast + (LLNotificationsUI::LLChannelManager::getInstance()-> + findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + LLTransientDockableFloater::setVisible(visible); + + // update notification channel state + if(channel) + { + channel->updateShowToastsState(); + channel->redrawToasts(); + } + + BOOL is_minimized = visible && isChatMultiTab() + ? FSFloaterIMContainer::getInstance()->isMinimized() + : !visible; + + if (!is_minimized && mChatHistory && mInputEditor) + { + //only if floater was construced and initialized from xml + updateMessages(); + FSFloaterIMContainer* im_container = FSFloaterIMContainer::getInstance(); + + //prevent stealing focus when opening a background IM tab (EXT-5387, checking focus for EXT-6781) + // If this is docked, is the selected tab, and the im container has focus, put focus in the input ctrl -KC + bool is_active = im_container->getActiveFloater() == this && im_container->hasFocus(); + if (!isChatMultiTab() || is_active || hasFocus()) + { + mInputEditor->setFocus(TRUE); + } + } + + if(!visible) + { + LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet(mSessionID); + if(chiclet) + { + chiclet->setToggleState(false); + } + } +} + +BOOL FSFloaterIM::getVisible() +{ + if(isChatMultiTab()) + { + FSFloaterIMContainer* im_container = FSFloaterIMContainer::getInstance(); + + // Treat inactive floater as invisible. + bool is_active = im_container->getActiveFloater() == this; + + //torn off floater is always inactive + if (!is_active && getHost() != im_container) + { + return LLTransientDockableFloater::getVisible(); + } + + // getVisible() returns TRUE when Tabbed IM window is minimized. + return is_active && !im_container->isMinimized() && im_container->getVisible(); + } + else + { + return LLTransientDockableFloater::getVisible(); + } +} + +//static +bool FSFloaterIM::toggle(const LLUUID& session_id) +{ + if(!isChatMultiTab()) + { + FSFloaterIM* floater = LLFloaterReg::findTypedInstance("fs_impanel", session_id); + if (floater && floater->getVisible() && floater->hasFocus()) + { + // clicking on chiclet to close floater just hides it to maintain existing + // scroll/text entry state + floater->setVisible(false); + return false; + } + else if(floater && (!floater->isDocked() || (floater->getVisible() && !floater->hasFocus()))) + { + floater->setVisible(TRUE); + floater->setFocus(TRUE); + return true; + } + } + + // ensure the list of messages is updated when floater is made visible + show(session_id); + return true; +} + +//static +FSFloaterIM* FSFloaterIM::findInstance(const LLUUID& session_id) +{ + return LLFloaterReg::findTypedInstance("fs_impanel", session_id); +} + +FSFloaterIM* FSFloaterIM::getInstance(const LLUUID& session_id) +{ + return LLFloaterReg::getTypedInstance("fs_impanel", session_id); +} + +void FSFloaterIM::sessionInitReplyReceived(const LLUUID& im_session_id) +{ + mSessionInitialized = true; + + //will be different only for an ad-hoc im session + if (mSessionID != im_session_id) + { + mSessionID = im_session_id; + setKey(im_session_id); + mControlPanel->setSessionId(im_session_id); + } + + // updating "Call" button from group control panel here to enable it without placing into draw() (EXT-4796) + if(gAgent.isInGroup(im_session_id)) + { + mControlPanel->updateCallButton(); + } + + //*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) + + + //need to send delayed messaged collected while waiting for session initialization + if (!mQueuedMsgsForInit.size()) return; + LLSD::array_iterator iter; + for ( iter = mQueuedMsgsForInit.beginArray(); + iter != mQueuedMsgsForInit.endArray(); + ++iter) + { + LLIMModel::sendMessage(iter->asString(), mSessionID, + mOtherParticipantUUID, mDialog); + } +} + +void FSFloaterIM::updateMessages() +{ + bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory"); + // FS-1734 seperate name and text styles for moderator + //bool bold_mods_chat = gSavedSettings.getBOOL("FSBoldGroupMods"); + bool highlight_mods_chat = gSavedSettings.getBOOL("FSHighlightGroupMods"); + bool hide_timestamps_nearby_chat = gSavedSettings.getBOOL("FSHideTimestampsIM"); + + std::list messages; + + // we shouldn't reset unread message counters if IM floater doesn't have focus + if (hasFocus()) + { + LLIMModel::instance().getMessages(mSessionID, messages, mLastMessageIndex+1); + } + else + { + LLIMModel::instance().getMessagesSilently(mSessionID, messages, mLastMessageIndex+1); + } + + if (messages.size()) + { + LLSD chat_args; + chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history; + chat_args["hide_timestamps_nearby_chat"] = hide_timestamps_nearby_chat; + + LLIMModel::LLIMSession* pIMSession = LLIMModel::instance().findIMSession(mSessionID); + RLV_ASSERT(pIMSession); + + std::ostringstream message; + std::list::const_reverse_iterator iter = messages.rbegin(); + std::list::const_reverse_iterator iter_end = messages.rend(); + for (; iter != iter_end; ++iter) + { + LLSD msg = *iter; + + std::string time = msg["time"].asString(); + LLUUID from_id = msg["from_id"].asUUID(); + std::string from = msg["from"].asString(); + std::string message = msg["message"].asString(); + bool is_history = msg["is_history"].asBoolean(); + + LLChat chat; + chat.mFromID = from_id; + chat.mSessionID = mSessionID; + chat.mFromName = from; + chat.mTimeStr = time; + chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle; + + // Bold group moderators' chat -KC + // FS-1734 seperate name and text styles for moderator + //if (!is_history && bold_mods_chat && pIMSession && pIMSession->mSpeakers) + if (!is_history && highlight_mods_chat && pIMSession && pIMSession->mSpeakers) + { + LLPointer speakerp = pIMSession->mSpeakers->findSpeaker(from_id); + if (speakerp && speakerp->mIsModerator) + { + chat.mChatStyle = CHAT_STYLE_MODERATOR; + } + } + + // process offer notification + if (msg.has("notification_id")) + { + chat.mNotifId = msg["notification_id"].asUUID(); + // if notification exists - embed it + if (LLNotificationsUtil::find(chat.mNotifId) != NULL) + { + // remove embedded notification from channel + LLNotificationsUI::LLScreenChannel* channel = static_cast + (LLNotificationsUI::LLChannelManager::getInstance()-> + findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + if (getVisible()) + { + // toast will be automatically closed since it is not storable toast + channel->hideToast(chat.mNotifId); + } + } + // if notification doesn't exist - try to use next message which should be log entry + else + { + continue; + } + } + //process text message + else + { + chat.mText = message; + } + + mChatHistory->appendMessage(chat, chat_args); + mLastMessageIndex = msg["index"].asInteger(); + + // if it is a notification - next message is a notification history log, so skip it + if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL) + { + if (++iter == iter_end) + { + break; + } + else + { + mLastMessageIndex++; + } + } + } + } +} + +void FSFloaterIM::reloadMessages() +{ + mChatHistory->clear(); + mLastMessageIndex = -1; + updateMessages(); +} + +// static +void FSFloaterIM::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ) +{ + FSFloaterIM* self= (FSFloaterIM*) userdata; + + // Allow enabling the FSFloaterIM input editor only if session can accept text + LLIMModel::LLIMSession* im_session = + LLIMModel::instance().findIMSession(self->mSessionID); + //TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK) + if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled()) + { + //in disconnected state IM input editor should be disabled + self->mInputEditor->setEnabled(!gDisconnected); + } +} + +// static +void FSFloaterIM::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) +{ + FSFloaterIM* self = (FSFloaterIM*) userdata; + self->setTyping(false); +} + +// static +void FSFloaterIM::onInputEditorKeystroke(LLLineEditor* caller, void* userdata) +{ + FSFloaterIM* self = (FSFloaterIM*)userdata; + std::string text = self->mInputEditor->getText(); + if (!text.empty()) + { + self->setTyping(true); + } + else + { + // Deleting all text counts as stopping typing. + self->setTyping(false); + } +} + +void FSFloaterIM::setTyping(bool typing) +{ + if ( typing ) + { + // Started or proceeded typing, reset the typing timeout timer + mTypingTimeoutTimer.reset(); + } + + if ( mMeTyping != typing ) + { + // Typing state is changed + mMeTyping = typing; + // So, should send current state + mShouldSendTypingState = true; + // In case typing is started, send state after some delay + mTypingTimer.reset(); + } + + // Don't want to send typing indicators to multiple people, potentially too + // much network traffic. Only send in person-to-person IMs. + if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL ) + { + if ( mMeTyping ) + { + if ( mTypingTimer.getElapsedTimeF32() > 1.f ) + { + // Still typing, send 'start typing' notification + LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE); + mShouldSendTypingState = false; + } + } + else + { + // Send 'stop typing' notification immediately + LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, FALSE); + mShouldSendTypingState = false; + } + } + + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); + +} + +void FSFloaterIM::processIMTyping(const LLIMInfo* im_info, BOOL typing) +{ + if ( typing ) + { + // other user started typing + addTypingIndicator(im_info); + } + else + { + // other user stopped typing + removeTypingIndicator(im_info); + } +} + +void FSFloaterIM::processAgentListUpdates(const LLSD& body) +{ + if ( !body.isMap() ) return; + + if ( body.has("agent_updates") && body["agent_updates"].isMap() ) + { + LLSD agent_data = body["agent_updates"].get(gAgentID.asString()); + if (agent_data.isMap() && agent_data.has("info")) + { + LLSD agent_info = agent_data["info"]; + + if (agent_info.has("mutes")) + { + BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean(); + mInputEditor->setEnabled(!moderator_muted_text); + std::string label; + if (moderator_muted_text) + label = LLTrans::getString("IM_muted_text_label"); + else + label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID); + mInputEditor->setLabel(label); + + if (moderator_muted_text) + LLNotificationsUtil::add("TextChatIsMutedByModerator"); + } + } + } +} + +void FSFloaterIM::updateChatHistoryStyle() +{ + mChatHistory->clear(); + mLastMessageIndex = -1; + updateMessages(); +} + +void FSFloaterIM::processChatHistoryStyleUpdate(const LLSD& newvalue) +{ + LLFontGL* font = LLViewerChat::getChatFont(); + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("fs_impanel"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); + iter != inst_list.end(); ++iter) + { + FSFloaterIM* floater = dynamic_cast(*iter); + if (floater) + { + floater->updateChatHistoryStyle(); + floater->mInputEditor->setFont(font); + } + } + +} + +void FSFloaterIM::processSessionUpdate(const LLSD& session_update) +{ + // *TODO : verify following code when moderated mode will be implemented + if ( false && session_update.has("moderated_mode") && + session_update["moderated_mode"].has("voice") ) + { + BOOL voice_moderated = session_update["moderated_mode"]["voice"]; + const std::string session_label = LLIMModel::instance().getName(mSessionID); + + if (voice_moderated) + { + setTitle(session_label + std::string(" ") + LLTrans::getString("IM_moderated_chat_label")); + } + else + { + setTitle(session_label); + } + + // *TODO : uncomment this when/if LLPanelActiveSpeakers panel will be added + //update the speakers dropdown too + //mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated); + } +} + +BOOL FSFloaterIM::handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, EDragAndDropType cargo_type, + void *cargo_data, EAcceptance *accept, + std::string& tooltip_msg) +{ + + if (mDialog == IM_NOTHING_SPECIAL) + { + LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop, + cargo_type, cargo_data, accept); + } + + // handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites + else if (isInviteAllowed()) + { + *accept = ACCEPT_NO; + + if (cargo_type == DAD_CALLINGCARD) + { + if (dropCallingCard((LLInventoryItem*)cargo_data, drop)) + { + *accept = ACCEPT_YES_MULTI; + } + } + else if (cargo_type == DAD_CATEGORY) + { + if (dropCategory((LLInventoryCategory*)cargo_data, drop)) + { + *accept = ACCEPT_YES_MULTI; + } + } + } + return TRUE; +} + +BOOL FSFloaterIM::dropCallingCard(LLInventoryItem* item, BOOL drop) +{ + BOOL rv = isInviteAllowed(); + if(rv && item && item->getCreatorUUID().notNull()) + { + if(drop) + { + uuid_vec_t ids; + ids.push_back(item->getCreatorUUID()); + inviteToSession(ids); + } + } + else + { + // set to false if creator uuid is null. + rv = FALSE; + } + return rv; +} + +BOOL FSFloaterIM::dropCategory(LLInventoryCategory* category, BOOL drop) +{ + BOOL rv = isInviteAllowed(); + if(rv && category) + { + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLUniqueBuddyCollector buddies; + gInventory.collectDescendentsIf(category->getUUID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + buddies); + S32 count = items.count(); + if(count == 0) + { + rv = FALSE; + } + else if(drop) + { + uuid_vec_t ids; + ids.reserve(count); + for(S32 i = 0; i < count; ++i) + { + ids.push_back(items.get(i)->getCreatorUUID()); + } + inviteToSession(ids); + } + } + return rv; +} + +BOOL FSFloaterIM::isInviteAllowed() const +{ + + return ( (IM_SESSION_CONFERENCE_START == mDialog) + || (IM_SESSION_INVITE == mDialog) ); +} + +class LLSessionInviteResponder : public LLHTTPClient::Responder +{ +public: + LLSessionInviteResponder(const LLUUID& session_id) + { + mSessionID = session_id; + } + + void error(U32 statusNum, const std::string& reason) + { + llinfos << "Error inviting all agents to session" << llendl; + //throw something back to the viewer here? + } + +private: + LLUUID mSessionID; +}; + +BOOL FSFloaterIM::inviteToSession(const uuid_vec_t& ids) +{ + LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + return FALSE; + } + + S32 count = ids.size(); + + if( isInviteAllowed() && (count > 0) ) + { + llinfos << "FSFloaterIM::inviteToSession() - inviting participants" << llendl; + + std::string url = region->getCapability("ChatSessionRequest"); + + LLSD data; + + data["params"] = LLSD::emptyArray(); + for (int i = 0; i < count; i++) + { + data["params"].append(ids[i]); + } + + data["method"] = "invite"; + data["session-id"] = mSessionID; + LLHTTPClient::post( + url, + data, + new LLSessionInviteResponder( + mSessionID)); + } + else + { + llinfos << "FSFloaterIM::inviteToSession -" + << " no need to invite agents for " + << mDialog << llendl; + // successful add, because everyone that needed to get added + // was added. + } + + return TRUE; +} + +void FSFloaterIM::addTypingIndicator(const LLIMInfo* im_info) +{ + // We may have lost a "stop-typing" packet, don't add it twice + if ( im_info && !mOtherTyping ) + { + mOtherTyping = true; + + // Save and set new title + mSavedTitle = getTitle(); + setTitle (mTypingStart); + + // Update speaker + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if ( speaker_mgr ) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE); + } + } +} + +void FSFloaterIM::removeTypingIndicator(const LLIMInfo* im_info) +{ + if ( mOtherTyping ) + { + mOtherTyping = false; + + // Revert the title to saved one + setTitle(mSavedTitle); + + if ( im_info ) + { + // Update speaker + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if ( speaker_mgr ) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); + } + } + + } +} + +// static +void FSFloaterIM::closeHiddenIMToasts() +{ + class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher + { + public: + bool matches(const LLNotificationPtr notification) const + { + // "notifytoast" type of notifications is reserved for IM notifications + return "notifytoast" == notification->getType(); + } + }; + + LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getNotificationScreenChannel(); + if (channel != NULL) + { + channel->closeHiddenToasts(IMToastMatcher()); + } +} +// static +void FSFloaterIM::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + const LLSD& payload = notification["payload"]; + LLUUID session_id = payload["session_id"]; + + LLFloater* im_floater = LLFloaterReg::findInstance("fs_impanel", session_id); + if (option == 0 && im_floater != NULL) + { + im_floater->closeFloater(); + } + + return; +} + +// static +bool FSFloaterIM::isChatMultiTab() +{ + // Restart is required in order to change chat window type. + static bool is_single_window = gSavedSettings.getS32("ChatWindow") == 1; + return is_single_window; +} + +// static +void FSFloaterIM::initIMFloater() +{ + // This is called on viewer start up + // init chat window type before user changed it in preferences + isChatMultiTab(); +} + +//static +void FSFloaterIM::sRemoveTypingIndicator(const LLSD& data) +{ + LLUUID session_id = data["session_id"]; + if (session_id.isNull()) return; + + LLUUID from_id = data["from_id"]; + if (gAgentID == from_id || LLUUID::null == from_id) return; + + FSFloaterIM* floater = FSFloaterIM::findInstance(session_id); + if (!floater) return; + + if (IM_NOTHING_SPECIAL != floater->mDialog) return; + + floater->removeTypingIndicator(); +} + +void FSFloaterIM::onIMChicletCreated( const LLUUID& session_id ) +{ + + if (isChatMultiTab()) + { + FSFloaterIMContainer* im_box = FSFloaterIMContainer::getInstance(); + if (!im_box) return; + + if (FSFloaterIM::findInstance(session_id)) return; + + FSFloaterIM* new_tab = FSFloaterIM::getInstance(session_id); + + im_box->addFloater(new_tab, FALSE, LLTabContainer::END); + } + +} + +void FSFloaterIM::onClickCloseBtn() +{ + + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession( + mSessionID); + + if (session == NULL) + { + llwarns << "Empty session." << llendl; + return; + } + + bool is_call_with_chat = session->isGroupSessionType() + || session->isAdHocSessionType() || session->isP2PSessionType(); + + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + + if (is_call_with_chat && voice_channel != NULL && voice_channel->isActive()) + { + LLSD payload; + payload["session_id"] = mSessionID; + LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback); + return; + } + + LLFloater::onClickCloseBtn(); +} + +// Viewer version popup +BOOL FSFloaterIM::enableViewerVersionCallback(const LLSD& notification,const LLSD& response) +{ + S32 option=LLNotificationsUtil::getSelectedOption(notification,response); + + BOOL result=FALSE; + if(option==0) // "yes" + { + result=TRUE; + } + + gSavedSettings.setBOOL("FSSupportGroupChatPrefix2",result); + return result; +} +// + +// FIRE-3248: Disable add friend button on IM floater if friendship request accepted +void FSFloaterIM::setEnableAddFriendButton(BOOL enabled) +{ + getChild("add_friend_btn")->setEnabled(enabled); +} +// diff --git a/indra/newview/fsfloaterim.h b/indra/newview/fsfloaterim.h new file mode 100644 index 0000000000..2e1a76d538 --- /dev/null +++ b/indra/newview/fsfloaterim.h @@ -0,0 +1,225 @@ +/** + * @file llimfloater.h + * @brief LLIMFloater class definition + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Original file: llimfloater.h + +#ifndef FS_FLOATERIM_H +#define FS_FLOATERIM_H + +#include "llinstantmessage.h" +#include "lllogchat.h" +#include "lltooldraganddrop.h" +#include "lltransientdockablefloater.h" +#include "llvoicechannel.h" + +class LLAvatarName; +class LLButton; // support sysinfo button -Zi +class LLLineEditor; +class LLPanelChatControlPanel; +class FSChatHistory; +class LLInventoryItem; +class LLInventoryCategory; + +/** + * Individual IM window that appears at the bottom of the screen, + * optionally "docked" to the bottom tray. + */ +class FSFloaterIM : public LLTransientDockableFloater, LLVoiceClientStatusObserver, LLFriendObserver +{ + LOG_CLASS(FSFloaterIM); +public: + FSFloaterIM(const LLUUID& session_id); + + virtual ~FSFloaterIM(); + + // LLView overrides + /*virtual*/ BOOL postBuild(); + /*virtual*/ void setVisible(BOOL visible); + /*virtual*/ BOOL getVisible(); + // Check typing timeout timer. + /*virtual*/ void draw(); + + // LLFloater overrides + /*virtual*/ void onClose(bool app_quitting); + /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true); + + // Make IM conversion visible and update the message history + static FSFloaterIM* show(const LLUUID& session_id); + + // Toggle panel specified by session_id + // Returns true iff panel became visible + static bool toggle(const LLUUID& session_id); + + static FSFloaterIM* findInstance(const LLUUID& session_id); + + static FSFloaterIM* getInstance(const LLUUID& session_id); + + void sessionInitReplyReceived(const LLUUID& im_session_id); + + // get new messages from LLIMModel + void updateMessages(); + void reloadMessages(); + static void onSendMsg( LLUICtrl*, void*); + void sendMsg(); + + // callback for LLIMModel on new messages + // route to specific floater if it is visible + static void newIMCallback(const LLSD& data); + + //AO: Callbacks for voice handling formerly in llPanelImControlPanel + void onCallButtonClicked(); + void onEndCallButtonClicked(); + void onOpenVoiceControlsClicked(); + void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state); + void onChange(EStatusType status, const std::string &channelURI, bool proximal); + void updateButtons(bool is_call_started); + void updateCallButton(); + void changed(U32 mask); + // ## Zi: overridden to fix the IM focus bug - FIRE-3989 etc. + BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); + + // called when docked floater's position has been set by chiclet + void setPositioned(bool b) { mPositioned = b; }; + + void onVisibilityChange(const LLSD& new_visibility); + void processIMTyping(const LLIMInfo* im_info, BOOL typing); + void processAgentListUpdates(const LLSD& body); + void processSessionUpdate(const LLSD& session_update); + + void updateChatHistoryStyle(); + static void processChatHistoryStyleUpdate(const LLSD& newvalue); + + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, EDragAndDropType cargo_type, + void *cargo_data, EAcceptance *accept, + std::string& tooltip_msg); + + /** + * Returns true if chat is displayed in multi tabbed floater + * false if chat is displayed in multiple windows + */ + static bool isChatMultiTab(); + + static void initIMFloater(); + + //used as a callback on receiving new IM message + static void sRemoveTypingIndicator(const LLSD& data); + + static void onIMChicletCreated(const LLUUID& session_id); + + virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; } + + // FIRE-3248: Disable add friend button on IM floater if friendship request accepted + void setEnableAddFriendButton(BOOL enabled); + +protected: + /* virtual */ + void onClickCloseBtn(); + + // support sysinfo button -Zi + void onSysinfoButtonVisibilityChanged(const LLSD& yes); + LLButton* mSysinfoButton; + // support sysinfo button -Zi + + BOOL enableViewerVersionCallback(const LLSD& notification,const LLSD& response); // Viewer version popup +private: + // process focus events to set a currently active session + /* virtual */ void onFocusLost(); + /* virtual */ void onFocusReceived(); + + // Update the window title, input field help text, etc. + void updateSessionName(const std::string& ui_title, const std::string& ui_label); + + // For display name lookups for IM window titles + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + + BOOL dropCallingCard(LLInventoryItem* item, BOOL drop); + BOOL dropCategory(LLInventoryCategory* category, BOOL drop); + + BOOL isInviteAllowed() const; + BOOL inviteToSession(const uuid_vec_t& agent_ids); + + static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ); + static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata); + static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata); + + // AO, originally from llpaneChatControlPanel trees + void onViewProfileButtonClicked(); + void onAddFriendButtonClicked(); + void onShareButtonClicked(); + void onTeleportButtonClicked(); + void onPayButtonClicked(); + void onGroupInfoButtonClicked(); + void onHistoryButtonClicked(); + + // support sysinfo button -Zi + void onSysinfoButtonClicked(); + BOOL onSendSysinfo(const LLSD& notification,const LLSD& response); + // support sysinfo button -Zi + + // connection to voice channel state change signal + boost::signals2::connection mVoiceChannelStateChangeConnection; + + void setTyping(bool typing); + void onSlide(); + static void* createPanelIMControl(void* userdata); + static void* createPanelGroupControl(void* userdata); + static void* createPanelAdHocControl(void* userdata); + + // Add the "User is typing..." indicator. + void addTypingIndicator(const LLIMInfo* im_info); + + // Remove the "User is typing..." indicator. + void removeTypingIndicator(const LLIMInfo* im_info = NULL); + + static void closeHiddenIMToasts(); + + static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response); + + LLPanelChatControlPanel* mControlPanel; + LLUUID mSessionID; + S32 mLastMessageIndex; + + EInstantMessage mDialog; + LLUUID mOtherParticipantUUID; + FSChatHistory* mChatHistory; + LLLineEditor* mInputEditor; + bool mPositioned; + + std::string mSavedTitle; + LLUIString mTypingStart; + bool mMeTyping; + bool mOtherTyping; + bool mShouldSendTypingState; + LLFrameTimer mTypingTimer; + LLFrameTimer mTypingTimeoutTimer; + + bool mSessionInitialized; + LLSD mQueuedMsgsForInit; +}; + + +#endif // FS_FLOATERIM_H diff --git a/indra/newview/fsfloaterimcontainer.cpp b/indra/newview/fsfloaterimcontainer.cpp new file mode 100644 index 0000000000..dcba10f449 --- /dev/null +++ b/indra/newview/fsfloaterimcontainer.cpp @@ -0,0 +1,290 @@ +/** + * @file fsfloaterimcontainer.cpp + * @brief Multifloater containing active IM sessions in separate tab container tabs + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Original file: llimfloatercontainer.cpp + + +#include "llviewerprecompiledheaders.h" + +#include "fsfloaterimcontainer.h" +#include "llfloaterreg.h" +#include "llimview.h" +#include "llavatariconctrl.h" +#include "llgroupiconctrl.h" +#include "llagent.h" +#include "lltransientfloatermgr.h" +#include "fsfloaternearbychat.h" +#include "fscontactsfloater.h" +#include "llfloater.h" +#include "llviewercontrol.h" + +// +// FSFloaterIMContainer +// +FSFloaterIMContainer::FSFloaterIMContainer(const LLSD& seed) +: LLMultiFloater(seed) +{ + mAutoResize = FALSE; + LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); +} + +FSFloaterIMContainer::~FSFloaterIMContainer() +{ + mNewMessageConnection.disconnect(); + LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); +} + +BOOL FSFloaterIMContainer::postBuild() +{ + + if (!gSavedSettings.getBOOL("ContactsTornOff")) + { + addFloater(FSFloaterContacts::getInstance(), TRUE); + } + + mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&FSFloaterIMContainer::onNewMessageReceived, this, _1)); + // Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button + // mTabContainer will be initialized in LLMultiFloater::addChild() + return TRUE; +} + +void FSFloaterIMContainer::onOpen(const LLSD& key) +{ + + LLMultiFloater::onOpen(key); + + + // If we're using multitabs, and we open up for the first time + // Add localchat by default if it's not already on the screen somewhere else. -AO + // But only if it hasnt been already so we can reopen it to the same tab -KC + // Improved handling to leave most of the work to the LL tear-off code -Zi + + LLFloater* floater = FSFloaterNearbyChat::getInstance(); + if (! LLFloater::isVisible(floater) && (floater->getHost() != this)) + { + if (gSavedSettings.getBOOL("ChatHistoryTornOff")) + { + // first set the tear-off host to this floater + floater->setHost(this); + // clear the tear-off host right after, the "last host used" will still stick + floater->setHost(NULL); + // reparent to floater view + gFloaterView->addChild(floater); + } + else + { + LLMultiFloater::showFloater(floater); + } + } + +/* + if (key.isDefined()) + { + LLIMFloater* im_floater = LLIMFloater::findInstance(key.asUUID()); + if (im_floater) + { + im_floater->openFloater(); + } + } +*/ +} + +void FSFloaterIMContainer::addFloater(LLFloater* floaterp, + BOOL select_added_floater, + LLTabContainer::eInsertionPoint insertion_point) +{ + if(!floaterp) return; + + // already here + if (floaterp->getHost() == this) + { + openFloater(floaterp->getKey()); + return; + } + + if (floaterp->getName() == "imcontacts" || floaterp->getName() == "nearby_chat") + { + S32 num_locked_tabs = mTabContainer->getNumLockedTabs(); + mTabContainer->unlockTabs(); + // add contacts window as first tab + if (floaterp->getName() == "imcontacts") + { + LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::START); + gSavedSettings.setBOOL("ContactsTornOff", FALSE); + } + else + { + // add chat history as second tab if contact window is present, first tab otherwise + if (getChildView("imcontacts")) + { + // assuming contacts window is first tab, select it + mTabContainer->selectFirstTab(); + // and add ourselves after + LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::RIGHT_OF_CURRENT); + } + else + { + LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::START); + } + gSavedSettings.setBOOL("ChatHistoryTornOff", FALSE); + } + // make sure first two tabs are now locked + mTabContainer->lockTabs(num_locked_tabs + 1); + + floaterp->setCanClose(FALSE); + return; + } + +// [SL:KB] - Patch: Chat-NearbyChatBar | Checked: 2011-11-17 (Catznip-3.2.0a) | Added: Catznip-3.2.0a + LLUUID session_id = floaterp->getKey(); + if (session_id.isNull()) + { + // Re-insert the nearby chat floater at the start + insertion_point = LLTabContainer::START; + } +// [/SL:KB] + + LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); + +// LLUUID session_id = floaterp->getKey(); + + LLIconCtrl* icon = 0; + +// [SL:KB] - Patch: Chat-NearbyChatBar | Checked: 2011-11-17 (Catznip-3.2.0a) | Added: Catznip-3.2.0a + if (session_id.isNull()) + { + // Don't allow the nearby chat tab to be drag-rearranged + mTabContainer->lockTabs(1); + + // Add an icon for the nearby chat floater + LLIconCtrl::Params icon_params; + icon_params.image = LLUI::getUIImage("Command_Chat_Icon"); + icon = LLUICtrlFactory::instance().create(icon_params); + } + else if (gAgent.isInGroup(session_id, TRUE)) +// [/SL:KB] +// if(gAgent.isInGroup(session_id, TRUE)) + { + LLGroupIconCtrl::Params icon_params; + icon_params.group_id = session_id; + icon = LLUICtrlFactory::instance().create(icon_params); + + mSessions[session_id] = floaterp; + floaterp->mCloseSignal.connect(boost::bind(&FSFloaterIMContainer::onCloseFloater, this, session_id)); + } + else + { + LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id); + + LLAvatarIconCtrl::Params icon_params; + icon_params.avatar_id = avatar_id; + icon = LLUICtrlFactory::instance().create(icon_params); + + mSessions[session_id] = floaterp; + floaterp->mCloseSignal.connect(boost::bind(&FSFloaterIMContainer::onCloseFloater, this, session_id)); + } + mTabContainer->setTabImage(floaterp, icon); +} + +// [SL:KB] - Patch: Chat-NearbyChatBar | Checked: 2011-12-11 (Catznip-3.2.0d) | Added: Catznip-3.2.0d +void FSFloaterIMContainer::removeFloater(LLFloater* floaterp) +{ + // old code from FS + if (floaterp->getName() == "nearby_chat") + { + // only my friends floater now locked + mTabContainer->lockTabs(mTabContainer->getNumLockedTabs() - 1); + gSavedSettings.setBOOL("ChatHistoryTornOff", TRUE); + floaterp->setCanClose(TRUE); + } + else if (floaterp->getName() == "imcontacts") + { + // only chat floater now locked + mTabContainer->lockTabs(mTabContainer->getNumLockedTabs() - 1); + gSavedSettings.setBOOL("ContactsTornOff", TRUE); + floaterp->setCanClose(TRUE); + } + // + + + LLUUID idSession = floaterp->getKey(); + if (idSession.isNull()) + { + mTabContainer->unlockTabs(); + } + LLMultiFloater::removeFloater(floaterp); +} +// [/SL:KB] + +void FSFloaterIMContainer::onCloseFloater(LLUUID& id) +{ + mSessions.erase(id); + setFocus(TRUE); +} + +void FSFloaterIMContainer::onNewMessageReceived(const LLSD& data) +{ + LLUUID session_id = data["session_id"].asUUID(); + LLFloater* floaterp = get_ptr_in_map(mSessions, session_id); + LLFloater* current_floater = LLMultiFloater::getActiveFloater(); + + // KC: Don't flash tab on friend status changes per setting + if (floaterp && current_floater && floaterp != current_floater + && (gSavedSettings.getBOOL("FSIMChatFlashOnFriendStatusChange") || data["from_id"].asUUID() != LLUUID::null)) + { + if(LLMultiFloater::isFloaterFlashing(floaterp)) + LLMultiFloater::setFloaterFlashing(floaterp, FALSE); + LLMultiFloater::setFloaterFlashing(floaterp, TRUE); + } +} + +FSFloaterIMContainer* FSFloaterIMContainer::findInstance() +{ + return LLFloaterReg::findTypedInstance("fs_im_container"); +} + +FSFloaterIMContainer* FSFloaterIMContainer::getInstance() +{ + return LLFloaterReg::getTypedInstance("fs_im_container"); +} + +void FSFloaterIMContainer::setMinimized(BOOL b) +{ + if (isMinimized() == b) return; + + LLMultiFloater::setMinimized(b); + // Hide minimized floater (see EXT-5315) + setVisible(!b); + + if (isMinimized()) return; + + if (getActiveFloater()) + { + getActiveFloater()->setVisible(TRUE); + } +} + +// EOF diff --git a/indra/newview/fsfloaterimcontainer.h b/indra/newview/fsfloaterimcontainer.h new file mode 100644 index 0000000000..b3b8f8a106 --- /dev/null +++ b/indra/newview/fsfloaterimcontainer.h @@ -0,0 +1,76 @@ +/** + * @file fsfloaterimcontainer.h + * @brief Multifloater containing active IM sessions in separate tab container tabs + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Original file: llimfloatercontainer.h + + +#ifndef FS_FLOATERIMCONTAINER_H +#define FS_FLOATERIMCONTAINER_H + +#include +#include + +#include "llfloater.h" +#include "llmultifloater.h" +#include "llavatarpropertiesprocessor.h" +#include "llgroupmgr.h" + +class LLTabContainer; + +class FSFloaterIMContainer : public LLMultiFloater +{ +public: + FSFloaterIMContainer(const LLSD& seed); + virtual ~FSFloaterIMContainer(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); + void onCloseFloater(LLUUID& id); + + /*virtual*/ void addFloater(LLFloater* floaterp, + BOOL select_added_floater, + LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); +// [SL:KB] - Patch: Chat-NearbyChatBar | Checked: 2011-12-11 (Catznip-3.2.0d) | Added: Catznip-3.2.0d + /*virtual*/ void removeFloater(LLFloater* floaterp); +// [/SL:KB] + + static LLFloater* getCurrentVoiceFloater(); + + static FSFloaterIMContainer* findInstance(); + + static FSFloaterIMContainer* getInstance(); + + virtual void setMinimized(BOOL b); + + void onNewMessageReceived(const LLSD& data); // public so nearbychat can call it directly. TODO: handle via callback. -AO + +private: + typedef std::map avatarID_panel_map_t; + avatarID_panel_map_t mSessions; + boost::signals2::connection mNewMessageConnection; +}; + +#endif // FS_FLOATERIMCONTAINER_H diff --git a/indra/newview/fsfloaternearbychat.cpp b/indra/newview/fsfloaternearbychat.cpp new file mode 100644 index 0000000000..ff4a56f929 --- /dev/null +++ b/indra/newview/fsfloaternearbychat.cpp @@ -0,0 +1,651 @@ +/** + * @file fsfloaternearbychat.cpp + * @brief Nearby chat history scrolling panel implementation + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, Zi Ree @ Second Life + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Original file: FSFloaterNearbyChat.cpp + +#include "llviewerprecompiledheaders.h" + +#include "fsfloaternearbychat.h" + +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "llrootview.h" +//#include "llchatitemscontainerctrl.h" +#include "lliconctrl.h" +#include "llspinctrl.h" +#include "llfloatersidepanelcontainer.h" +#include "llfocusmgr.h" +#include "lllogchat.h" +#include "llresizebar.h" +#include "llresizehandle.h" +#include "llmenugl.h" +#include "llviewermenu.h"//for gMenuHolder + +#include "llnearbychathandler.h" +// #include "llnearbychatbar.h" // Remove floating chat bar +#include "fsnearbychathub.h" +#include "llchannelmanager.h" + +#include "llagent.h" // gAgent +#include "fschathistory.h" +#include "llstylemap.h" + +#include "llavatarnamecache.h" + +#include "lldraghandle.h" + +// #include "llnearbychatbar.h" // Remove floating chat bar +#include "llfloaterreg.h" +#include "lltrans.h" + +// IM +#include "llbutton.h" +#include "lllayoutstack.h" + +// [FS communication UI] +//#include "llimfloatercontainer.h" +//#include "llimfloater.h" +#include "fsfloaterim.h" +#include "fsfloaterimcontainer.h" +// [FS communication UI] +#include "lllineeditor.h" + +//AO - includes for textentry +#include "rlvhandler.h" +#include "llcommandhandler.h" +#include "llkeyboard.h" +#include "llgesturemgr.h" +#include "llmultigesture.h" + +#include "llconsole.h" + +// Moved nearby chat functionality here for now +#include "chatbar_as_cmdline.h" +#include "llanimationstates.h" // ANIM_AGENT_WHISPER, ANIM_AGENT_TALK, ANIM_AGENT_SHOUT +#include "llviewerstats.h" +// + +static const S32 RESIZE_BAR_THICKNESS = 3; + +// ## Zi // static LLRegisterPanelClassWrapper t_panel_nearby_chat("panel_nearby_chat"); + +FSFloaterNearbyChat::FSFloaterNearbyChat(const LLSD& key) + : LLDockableFloater(NULL, false, false, key) + ,mChatHistory(NULL) + ,mInputEditor(NULL) + // Optional muted chat history + ,mChatHistoryMuted(NULL) +{ +} + +FSFloaterNearbyChat::~FSFloaterNearbyChat() +{ +} + +void FSFloaterNearbyChat::updateFSUseNearbyChatConsole(const LLSD &data) +{ + FSUseNearbyChatConsole = data.asBoolean(); + + if (FSUseNearbyChatConsole) + { + LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID"))); + if(chat_channel) + { + chat_channel->removeToastsFromChannel(); + } + gConsole->setVisible(!getVisible()); + } + else + { + gConsole->setVisible(FALSE); + } +} + + +BOOL FSFloaterNearbyChat::postBuild() +{ + //menu + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + enable_registrar.add("NearbyChat.Check", boost::bind(&FSFloaterNearbyChat::onNearbyChatCheckContextMenuItem, this, _2)); + registrar.add("NearbyChat.Action", boost::bind(&FSFloaterNearbyChat::onNearbyChatContextMenuItemClicked, this, _2)); + + + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if(menu) + mPopupMenuHandle = menu->getHandle(); + + gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true); + + mInputEditor = getChild("chat_box"); + + mInputEditor->setEnabled(TRUE); + + gSavedSettings.getControl("FSNearbyChatbar")->getCommitSignal()->connect(boost::bind(&FSFloaterNearbyChat::onChatBarVisibilityChanged, this)); + gSavedSettings.getControl("FSShowChatChannel")->getCommitSignal()->connect(boost::bind(&FSFloaterNearbyChat::onChatChannelVisibilityChanged, this)); + + onChatBarVisibilityChanged(); + onChatChannelVisibilityChanged(); + + // extra icon controls -AO + LLButton* transl = getChild("translate_btn"); + transl->setVisible(true); + + childSetCommitCallback("chat_history_btn",onHistoryButtonClicked,this); + + mChatHistory = getChild("chat_history"); + + // Optional muted chat history + mChatHistoryMuted = getChild("chat_history_muted"); + + // -AO + if(isChatMultiTab()) + { + LLButton* slide_left = getChild("slide_left_btn"); + slide_left->setVisible(false); + LLButton* slide_right = getChild("slide_right_btn"); + slide_right->setVisible(false); + + FSUseNearbyChatConsole = gSavedSettings.getBOOL("FSUseNearbyChatConsole"); + gSavedSettings.getControl("FSUseNearbyChatConsole")->getSignal()->connect(boost::bind(&FSFloaterNearbyChat::updateFSUseNearbyChatConsole, this, _2)); + + return LLDockableFloater::postBuild(); + } + + if(!LLDockableFloater::postBuild()) + return false; + + return true; +} + +std::string appendTime() +{ + time_t utc_time; + utc_time = time_corrected(); + std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" + +LLTrans::getString("TimeMin")+"]"; + if (gSavedSettings.getBOOL("FSSecondsinChatTimestamps")) + { + timeStr += ":[" + +LLTrans::getString("TimeSec")+"]"; + } + + LLSD substitution; + + substitution["datetime"] = (S32) utc_time; + LLStringUtil::format (timeStr, substitution); + + return timeStr; +} + + +void FSFloaterNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) +{ + LLChat& tmp_chat = const_cast(chat); + bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory"); + bool hide_timestamps_nearby_chat = gSavedSettings.getBOOL("FSHideTimestampsNearbyChat"); + // [FIRE-1641 : SJ]: Option to hide timestamps in nearby chat - only add Timestamp when hide_timestamps_nearby_chat is not TRUE + if (!hide_timestamps_nearby_chat) + { + if(tmp_chat.mTimeStr.empty()) + tmp_chat.mTimeStr = appendTime(); + } + + + // Optional muted chat history + tmp_chat.mFromName = chat.mFromName; + LLSD chat_args = args; + chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history; + chat_args["hide_timestamps_nearby_chat"] = hide_timestamps_nearby_chat; + mChatHistoryMuted->appendMessage(chat, chat_args); + // Optional muted chat history + if (!chat.mMuted) + { + // Optional muted chat history + //tmp_chat.mFromName = chat.mFromName; + //LLSD chat_args = args; + //chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history; + //chat_args["hide_timestamps_nearby_chat"] = hide_timestamps_nearby_chat; + // <(FS:Ansariel> Optional muted chat history + mChatHistory->appendMessage(chat, chat_args); + } + + if(archive) + { + mMessageArchive.push_back(chat); + if(mMessageArchive.size()>200) + mMessageArchive.erase(mMessageArchive.begin()); + } + + // Optional muted chat history + //if (args["do_not_log"].asBoolean()) + if (args["do_not_log"].asBoolean() || chat.mMuted) + // Optional muted chat history + { + return; + } + + // AO: IF tab mode active, flash our tab + if(isChatMultiTab()) + { + LLMultiFloater* hostp = getHost(); + // KC: Don't flash tab on system messages + if (!isInVisibleChain() && hostp + && (chat.mSourceType == CHAT_SOURCE_AGENT || chat.mSourceType == CHAT_SOURCE_OBJECT)) + { + hostp->setFloaterFlashing(this, TRUE); + } + } + + if (gSavedPerAccountSettings.getBOOL("LogNearbyChat")) + { + std::string from_name = chat.mFromName; + + if (chat.mSourceType == CHAT_SOURCE_AGENT) + { + // if the chat is coming from an agent, log the complete name + LLAvatarName av_name; + LLAvatarNameCache::get(chat.mFromID, &av_name); + + if (!av_name.mIsDisplayNameDefault) + { + from_name = av_name.getCompleteName(); + } + + // Ansariel: Handle IMs in nearby chat + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //if (gSavedSettings.getBOOL("FSShowIMInChatHistory") && chat.mChatType == CHAT_TYPE_IM) + if (gSavedSettings.getBOOL("FSShowIMInChatHistory") && (chat.mChatType == CHAT_TYPE_IM || chat.mChatType == CHAT_TYPE_IM_GROUP)) + { + if (gSavedSettings.getBOOL("FSLogIMInChatHistory")) + { + //from_name = "IM: " + from_name; + if(chat.mChatType == CHAT_TYPE_IM_GROUP && chat.mFromNameGroup != "") + { + from_name = "IM: " + chat.mFromNameGroup + from_name; + } + else + { + from_name = "IM: " + from_name; + } + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + } + else return; + } + } + + LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText); + } +} + +// virtual +BOOL FSFloaterNearbyChat::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) +{ + mInputEditor->setFocus(TRUE); + onTabInto(); + if(focus_flash) + { + gFocusMgr.triggerFocusFlash(); + } + return TRUE; +} + +void FSFloaterNearbyChat::onNearbySpeakers() +{ + LLSD param; + param["people_panel_tab_name"] = "nearby_panel"; + LLFloaterSidePanelContainer::showPanel("people", "panel_people", param); +} + +// static +void FSFloaterNearbyChat::onHistoryButtonClicked(LLUICtrl* ctrl, void* userdata) +{ + gViewerWindow->getWindow()->openFile(LLLogChat::makeLogFileName("chat")); +} + +void FSFloaterNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata) +{ +} + +bool FSFloaterNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata) +{ + std::string str = userdata.asString(); + if(str == "nearby_people") + onNearbySpeakers(); + return false; +} + +void FSFloaterNearbyChat::onChatBarVisibilityChanged() +{ + getChild("chat_bar_visibility_panel")->setVisible(gSavedSettings.getBOOL("FSNearbyChatbar")); +} + +void FSFloaterNearbyChat::onChatChannelVisibilityChanged() +{ + getChild("channel_spinner_visibility_panel")->setVisible(gSavedSettings.getBOOL("FSShowChatChannel")); +} + +void FSFloaterNearbyChat::openFloater(const LLSD& key) +{ + // We override this to put nearbychat in the IM floater. -AO + if(isChatMultiTab()) + { + // [FS communication UI] + //LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + FSFloaterIMContainer* floater_container = FSFloaterIMContainer::getInstance(); + // [FS communication UI] + // only show the floater container if we are actually attached -Zi + if (floater_container && !gSavedSettings.getBOOL("ChatHistoryTornOff")) + { + floater_container->showFloater(this, LLTabContainer::START); + } + setVisible(TRUE); + LLFloater::openFloater(key); + } +} + +void FSFloaterNearbyChat::removeScreenChat() +{ + LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID"))); + if(chat_channel) + { + chat_channel->removeToastsFromChannel(); + } +} + +void FSFloaterNearbyChat::setVisible(BOOL visible) +{ + if(visible) + { + removeScreenChat(); + } + LLDockableFloater::setVisible(visible); + + // Support for chat console + static LLCachedControl chatHistoryTornOff(gSavedSettings, "ChatHistoryTornOff"); + if (FSUseNearbyChatConsole) + { + // [FS communication UI] + //LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + FSFloaterIMContainer* floater_container = FSFloaterIMContainer::getInstance(); + // [FS communication UI] + 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 +} + +void FSFloaterNearbyChat::onFocusReceived() +{ + // Give focus to input textbox + mInputEditor->setFocus(TRUE); +} + +void FSFloaterNearbyChat::onOpen(const LLSD& key ) +{ + // [FS communication UI] + //LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + FSFloaterIMContainer* floater_container = FSFloaterIMContainer::getInstance(); + // [FS communication UI] + if (floater_container) + { + if (gSavedSettings.getBOOL("ChatHistoryTornOff")) + { + // first set the tear-off host to this floater + setHost(floater_container); + // clear the tear-off host right after, the "last host used" will still stick + setHost(NULL); + // reparent the floater to the main view + gFloaterView->addChild(this); + } + else + { + floater_container->addFloater(this, FALSE); + } + } + + // We override this to put nearbychat in the IM floater. -AO + if(isChatMultiTab() && ! isVisible(this)) + { + // only show the floater container if we are actually attached -Zi + if (floater_container && !gSavedSettings.getBOOL("ChatHistoryTornOff")) + { + // make sure to show our parent floater, too + floater_container->setVisible(TRUE); + floater_container->showFloater(this, LLTabContainer::START); + } + setVisible(TRUE); + } + + LLDockableFloater::onOpen(key); +} + +void FSFloaterNearbyChat::setRect (const LLRect &rect) +{ + LLDockableFloater::setRect(rect); +} + +void FSFloaterNearbyChat::getAllowedRect(LLRect& rect) +{ + rect = gViewerWindow->getWorldViewRectScaled(); +} + +// exported here for "clrchat" command line -Zi +void FSFloaterNearbyChat::clearChatHistory() +{ + mChatHistory->clear(); + // Optional muted chat history + mChatHistoryMuted->clear(); +} + +void FSFloaterNearbyChat::updateChatHistoryStyle() +{ + clearChatHistory(); + + LLSD do_not_log; + do_not_log["do_not_log"] = true; + for(std::vector::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it) + { + // Update the messages without re-writing them to a log file. + addMessage(*it,false, do_not_log); + } +} + +//static +void FSFloaterNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue) +{ + FSFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("fs_nearby_chat", LLSD()); + if(nearby_chat) + nearby_chat->updateChatHistoryStyle(); +} + +bool isWordsName(const std::string& name) +{ + // checking to see if it's display name plus username in parentheses + S32 open_paren = name.find(" (", 0); + S32 close_paren = name.find(')', 0); + + if (open_paren != std::string::npos && + close_paren == name.length()-1) + { + return true; + } + else + { + //checking for a single space + S32 pos = name.find(' ', 0); + return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos; + } +} + +void FSFloaterNearbyChat::loadHistory() +{ + LLSD do_not_log; + do_not_log["do_not_log"] = true; + + std::list history; + LLLogChat::loadAllHistory("chat", history); + + std::list::const_iterator it = history.begin(); + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + typedef enum e_im_type + { + IM_TYPE_NONE = 0, + IM_TYPE_NORMAL, + IM_TYPE_GROUP + } EIMType; + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + while (it != history.end()) + { + EIMType im_type = IM_TYPE_NONE; // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + const LLSD& msg = *it; + + std::string from = msg[IM_FROM]; + std::string fromGroup = ""; // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + LLUUID from_id; + if (msg[IM_FROM_ID].isDefined()) + { + from_id = msg[IM_FROM_ID].asUUID(); + } + else + { + // Ansariel: Strip IM prefix so we can properly + // retrieve the UUID in case we got a + // saved IM in nearby chat history. + std::string im_prefix = "IM: "; + size_t im_prefix_found = from.find(im_prefix); + if (im_prefix_found != std::string::npos) + { + from = from.substr(im_prefix.length()); + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //im_type = true; + size_t group_im_prefix_start = from.find("["); + size_t group_im_prefix_end = from.find("] "); + if((group_im_prefix_start != std::string::npos) && (group_im_prefix_end != std::string::npos)) + { + fromGroup = from.substr(group_im_prefix_start,group_im_prefix_end+2); + from = from.substr(fromGroup.length()); + im_type = IM_TYPE_GROUP; + } + else + { + im_type = IM_TYPE_NORMAL; + } + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + } + + std::string legacy_name = gCacheName->buildLegacyName(from); + gCacheName->getUUID(legacy_name, from_id); + } + + LLChat chat; + chat.mFromName = from; + chat.mFromID = from_id; + chat.mText = msg[IM_TEXT].asString(); + chat.mTimeStr = msg[IM_TIME].asString(); + chat.mChatStyle = CHAT_STYLE_HISTORY; + + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + //if (im_type) chat.mChatType = CHAT_TYPE_IM; + if (im_type == IM_TYPE_NORMAL) + { + chat.mChatType = CHAT_TYPE_IM; + } + else if(im_type == IM_TYPE_GROUP) + { + chat.mChatType = CHAT_TYPE_IM_GROUP; + chat.mFromNameGroup = fromGroup; + } + // FS:LO FIRE-5230 - Chat Console Improvement: Replacing the "IM" in front of group chat messages with the actual group name + + chat.mSourceType = CHAT_SOURCE_AGENT; + if (from_id.isNull() && SYSTEM_FROM == from) + { + chat.mSourceType = CHAT_SOURCE_SYSTEM; + + } + else if (from_id.isNull()) + { + chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT; + } + + addMessage(chat, true, do_not_log); + + it++; + } +} + +//static +FSFloaterNearbyChat* FSFloaterNearbyChat::getInstance() +{ + return LLFloaterReg::getTypedInstance("fs_nearby_chat", LLSD()); +} + +bool FSFloaterNearbyChat::isChatMultiTab() +{ + // Restart is required in order to change chat window type. + static bool is_single_window = gSavedSettings.getS32("ChatWindow") == 1; + return is_single_window; +} + +BOOL FSFloaterNearbyChat::getVisible() +{ + if(isChatMultiTab()) + { + // [FS communication UI] + //LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance(); + FSFloaterIMContainer* im_container = FSFloaterIMContainer::getInstance(); + // [FS communication UI] + + // Treat inactive floater as invisible. + bool is_active = im_container->getActiveFloater() == this; + + //torn off floater is always inactive + if (!is_active && getHost() != im_container) + { + return LLDockableFloater::getVisible(); + } + + // getVisible() returns TRUE when Tabbed IM window is minimized. + return is_active && !im_container->isMinimized() && im_container->getVisible(); + } + else + { + return LLDockableFloater::getVisible(); + } +} diff --git a/indra/newview/fsfloaternearbychat.h b/indra/newview/fsfloaternearbychat.h new file mode 100644 index 0000000000..3e0fa60fc3 --- /dev/null +++ b/indra/newview/fsfloaternearbychat.h @@ -0,0 +1,117 @@ + /** + * @file fsfloaternearbychat.h + * @brief Nearby chat history scrolling panel implementation + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, Zi Ree @ Second Life + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Original file: llfloaternearbychat.h + +#ifndef FS_FLOATERNEARBYCHAT_H +#define FS_FLOATERNEARBYCHAT_H + +#include "lldockablefloater.h" +#include "llscrollbar.h" +#include "llviewerchat.h" + +class LLResizeBar; +class FSChatHistory; +// Nearby chat bar class +// class LLLineEditor; +#include "lllineeditor.h" +#include "llsingleton.h" +// + +class FSFloaterNearbyChat: public LLDockableFloater +{ +public: + FSFloaterNearbyChat(const LLSD& key); + ~FSFloaterNearbyChat(); + + BOOL postBuild (); + + /** @param archive true - to save a message to the chat history log */ + void addMessage (const LLChat& message,bool archive = true, const LLSD &args = LLSD()); + void onNearbyChatContextMenuItemClicked(const LLSD& userdata); + bool onNearbyChatCheckContextMenuItem(const LLSD& userdata); + + void onChatBarVisibilityChanged(); + void onChatChannelVisibilityChanged(); + + // This doesn't seem to apply anymore? It makes the chat and spin box colors + // appear wrong when focused and unfocused, so disable this. -Zi +#if 0 + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual void draw(); + + // focus overrides + /*virtual*/ void onFocusLost(); +#endif + /*virtual*/ void onFocusReceived(); + /*virtual*/ void onOpen (const LLSD& key); + + /*virtual*/ void setVisible(BOOL visible); + void openFloater(const LLSD& key); + + virtual void setRect (const LLRect &rect); + + void clearChatHistory(); + virtual void updateChatHistoryStyle(); + + static void processChatHistoryStyleUpdate(const LLSD& newvalue); + + void loadHistory(); + + static FSFloaterNearbyChat* getInstance(); + + void removeScreenChat(); + + static bool isChatMultiTab(); + + BOOL getVisible(); + + static void onHistoryButtonClicked(LLUICtrl* ctrl, void* userdata); + + // overridden to fix the multitab focus bug -Zi + BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); + + void updateFSUseNearbyChatConsole(const LLSD &data); + +private: + void getAllowedRect (LLRect& rect); + + void onNearbySpeakers (); + +private: + LLHandle mPopupMenuHandle; + FSChatHistory* mChatHistory; + // Optional muted chat history + FSChatHistory* mChatHistoryMuted; + + std::vector mMessageArchive; + LLLineEditor* mInputEditor; + + BOOL FSUseNearbyChatConsole; +}; + +#endif // FS_FLOATERNEARBYCHAT_H diff --git a/indra/newview/fsmoneytracker.cpp b/indra/newview/fsmoneytracker.cpp index 0809da7fec..c47535743c 100644 --- a/indra/newview/fsmoneytracker.cpp +++ b/indra/newview/fsmoneytracker.cpp @@ -24,7 +24,6 @@ #include "fsmoneytracker.h" #include "llfloaterreg.h" #include "llviewercontrol.h" -#include "llchathistory.h" #include "lllineeditor.h" #include "llnotificationmanager.h" #include "lltrans.h" @@ -44,7 +43,10 @@ FSMoneyTracker::~FSMoneyTracker() BOOL FSMoneyTracker::postBuild() { - mTransactionHistory = getChild("money_chat_history"); + // [FS communication UI] + //mTransactionHistory = getChild("money_chat_history"); + mTransactionHistory = getChild("money_chat_history"); + // [FS communication UI] mTransactionHistory->clear(); // Button Actions diff --git a/indra/newview/fsmoneytracker.h b/indra/newview/fsmoneytracker.h index 38847529f7..b55fd046b2 100644 --- a/indra/newview/fsmoneytracker.h +++ b/indra/newview/fsmoneytracker.h @@ -25,7 +25,10 @@ #include "llfloater.h" #include "llsingleton.h" -#include "llchathistory.h" +// [FS communication UI] +//#include "llchathistory.h" +#include "fschathistory.h" +// [FS communication UI] #include "lllineeditor.h" #include "llchat.h" #include @@ -45,7 +48,10 @@ public: private: void clear(); std::string appendTime(); - LLChatHistory* mTransactionHistory; + // [FS communication UI] + //LLChatHistory* mTransactionHistory; + FSChatHistory* mTransactionHistory; + // [FS communication UI] }; #endif // FS_MONEYTRACKER_H diff --git a/indra/newview/fsnearbychatbarlistener.cpp b/indra/newview/fsnearbychatbarlistener.cpp new file mode 100644 index 0000000000..53edba7e46 --- /dev/null +++ b/indra/newview/fsnearbychatbarlistener.cpp @@ -0,0 +1,116 @@ +/** + * @file fsnearbychatbarlistener.cpp + * @author Dave Simmons + * @date 2011-03-15 + * @brief Implementation for FSNearbyChatBarListener. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Original file: llnearbychatbarlistener.cpp + +#include "llviewerprecompiledheaders.h" + +#include "fsnearbychatbarlistener.h" +// Remove floating chat bar +// #include "llnearbychatbar.h" +#include "fsnearbychathub.h" +// + +#include "llagent.h" +#include "llchat.h" +#include "llviewercontrol.h" + + +// Remove floating chat bar +// LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChatBar & chatbar) +// : LLEventAPI("LLChatBar", +// "LLChatBar listener to (e.g.) sendChat, etc."), +// mChatbar(chatbar) +FSNearbyChatBarListener::FSNearbyChatBarListener() + : LLEventAPI("LLChatBar", + "LLChatBar listener to (e.g.) sendChat, etc.") +// +{ + add("sendChat", + "Send chat to the simulator:\n" + "[\"message\"] chat message text [required]\n" + "[\"channel\"] chat channel number [default = 0]\n" + "[\"type\"] chat type \"whisper\", \"normal\", \"shout\" [default = \"normal\"]", + &FSNearbyChatBarListener::sendChat); +} + + +// "sendChat" command +void FSNearbyChatBarListener::sendChat(LLSD const & chat_data) const +{ + // Extract the data + std::string chat_text = chat_data["message"].asString(); + + S32 channel = 0; + if (chat_data.has("channel")) + { + channel = chat_data["channel"].asInteger(); + if (channel < 0 || channel >= CHAT_CHANNEL_DEBUG) + { // Use 0 up to (but not including) CHAT_CHANNEL_DEBUG + channel = 0; + } + } + + EChatType type_o_chat = CHAT_TYPE_NORMAL; + if (chat_data.has("type")) + { + std::string type_string = chat_data["type"].asString(); + if (type_string == "whisper") + { + type_o_chat = CHAT_TYPE_WHISPER; + } + else if (type_string == "shout") + { + type_o_chat = CHAT_TYPE_SHOUT; + } + } + + // Have to prepend /42 style channel numbers + std::string chat_to_send; + if (channel == 0) + { + chat_to_send = chat_text; + } + else + { + chat_to_send += "/"; + chat_to_send += chat_data["channel"].asString(); + chat_to_send += " "; + chat_to_send += chat_text; + } + + // Send it as if it was typed in + // Remove floating chat bar + // mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, (BOOL)(channel == 0)); + // [FS communication UI] + //LLNearbyChat::instance().sendChatFromViewer(chat_to_send, type_o_chat, ((BOOL)(channel == 0)) && gSavedSettings.getBOOL("FSPlayChatAnimation")); + FSNearbyChat::instance().sendChatFromViewer(chat_to_send, type_o_chat, ((BOOL)(channel == 0)) && gSavedSettings.getBOOL("FSPlayChatAnimation")); + // [FS communication UI] + // +} + diff --git a/indra/newview/fsnearbychatbarlistener.h b/indra/newview/fsnearbychatbarlistener.h new file mode 100644 index 0000000000..286296583f --- /dev/null +++ b/indra/newview/fsnearbychatbarlistener.h @@ -0,0 +1,55 @@ +/** + * @file fsnearbychatbarlistener.h + * @author Dave Simmons + * @date 2011-03-15 + * @brief Class definition for FSNearbyChatBarListener. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Original file: llnearbychatbarlistener.h + + +#ifndef FS_NEARBYCHATBARLISTENER_H +#define FS_NEARBYCHATBARLISTENER_H + +#include "lleventapi.h" + +class LLSD; +// class LLNearbyChatBar; // Remove floating chat bar + +class FSNearbyChatBarListener : public LLEventAPI +{ +public: + // Remove floating chat bar + // LLNearbyChatBarListener(LLNearbyChatBar & chatbar); + FSNearbyChatBarListener(); + // + +private: + void sendChat(LLSD const & chat_data) const; + +// LLNearbyChatBar & mChatbar; +}; + +#endif // FS_NEARBYCHATBARLISTENER_H + diff --git a/indra/newview/llnearbychatcontrol.cpp b/indra/newview/fsnearbychatcontrol.cpp similarity index 84% rename from indra/newview/llnearbychatcontrol.cpp rename to indra/newview/fsnearbychatcontrol.cpp index 71f9e22360..ad6543d651 100644 --- a/indra/newview/llnearbychatcontrol.cpp +++ b/indra/newview/fsnearbychatcontrol.cpp @@ -1,5 +1,5 @@ /** - * @file llnearbychatcontrol.cpp + * @file fsnearbychatcontrol.cpp * @brief Nearby chat input control implementation * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ @@ -27,9 +27,12 @@ #include "llviewerprecompiledheaders.h" -#include "llnearbychatcontrol.h" -#include "llnearbychathub.h" -#include "llfloaternearbychat.h" +#include "fsnearbychatcontrol.h" +#include "fsnearbychathub.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] // #include "llviewercontrol.h" // #include "llviewerwindow.h" // #include "llrootview.h" @@ -86,7 +89,7 @@ // #include "llviewerstats.h" // -static LLDefaultChildRegistry::Register r("nearby_chat_control"); +static LLDefaultChildRegistry::Register r("fs_nearby_chat_control"); struct LLChatTypeTrigger { std::string name; @@ -98,12 +101,12 @@ static LLChatTypeTrigger sChatTypeTriggers[] = { { "/shout" , CHAT_TYPE_SHOUT} }; -LLNearbyChatControl::LLNearbyChatControl(const LLNearbyChatControl::Params& p) : +FSNearbyChatControl::FSNearbyChatControl(const FSNearbyChatControl::Params& p) : LLLineEditor(p) { setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2)); setKeystrokeCallback(onKeystroke,this); - LLNearbyChat::instance().registerChatBar(this); + FSNearbyChat::instance().registerChatBar(this); setEnableLineHistory(TRUE); setIgnoreArrowKeys( FALSE ); @@ -115,14 +118,14 @@ LLNearbyChatControl::LLNearbyChatControl(const LLNearbyChatControl::Params& p) : setFont(LLViewerChat::getChatFont()); // Register for font change notifications - LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatControl::setFont, this, _1)); + LLViewerChat::setFontChangedCallback(boost::bind(&FSNearbyChatControl::setFont, this, _1)); } -LLNearbyChatControl::~LLNearbyChatControl() +FSNearbyChatControl::~FSNearbyChatControl() { } -void LLNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) +void FSNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) { LLWString raw_text = caller->getWText(); @@ -142,7 +145,10 @@ void LLNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) if (gSavedSettings.getBOOL("FSNearbyChatbar") && gSavedSettings.getBOOL("FSShowChatChannel")) { - channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + // [FS communication UI] + //channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + // [FS communication UI] } // -Zi @@ -195,7 +201,7 @@ void LLNearbyChatControl::onKeystroke(LLLineEditor* caller,void* userdata) } } -BOOL LLNearbyChatControl::matchChatTypeTrigger(const std::string& in_str, std::string* out_str) +BOOL FSNearbyChatControl::matchChatTypeTrigger(const std::string& in_str, std::string* out_str) { U32 in_len = in_str.length(); S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); @@ -219,25 +225,25 @@ BOOL LLNearbyChatControl::matchChatTypeTrigger(const std::string& in_str, std::s } // send our focus status to the LLNearbyChat hub -void LLNearbyChatControl::onFocusReceived() +void FSNearbyChatControl::onFocusReceived() { - LLNearbyChat::instance().setFocusedInputEditor(this,TRUE); + FSNearbyChat::instance().setFocusedInputEditor(this,TRUE); LLLineEditor::onFocusReceived(); } -void LLNearbyChatControl::onFocusLost() +void FSNearbyChatControl::onFocusLost() { - LLNearbyChat::instance().setFocusedInputEditor(this,FALSE); + FSNearbyChat::instance().setFocusedInputEditor(this,FALSE); LLLineEditor::onFocusLost(); } -void LLNearbyChatControl::setFocus(BOOL focus) +void FSNearbyChatControl::setFocus(BOOL focus) { - LLNearbyChat::instance().setFocusedInputEditor(this,focus); + FSNearbyChat::instance().setFocusedInputEditor(this,focus); LLLineEditor::setFocus(focus); } -void LLNearbyChatControl::autohide() +void FSNearbyChatControl::autohide() { if(getName()=="default_chat_bar") { @@ -248,13 +254,13 @@ void LLNearbyChatControl::autohide() if(gAgentCamera.cameraMouselook() || gSavedSettings.getBOOL("AutohideChatBar")) { - LLNearbyChat::instance().showDefaultChatBar(FALSE); + FSNearbyChat::instance().showDefaultChatBar(FALSE); } } } // handle ESC key here -BOOL LLNearbyChatControl::handleKeyHere(KEY key, MASK mask ) +BOOL FSNearbyChatControl::handleKeyHere(KEY key, MASK mask ) { BOOL handled = FALSE; EChatType type = CHAT_TYPE_NORMAL; @@ -301,7 +307,7 @@ BOOL LLNearbyChatControl::handleKeyHere(KEY key, MASK mask ) LLLineEditor::onCommit(); // send chat to nearby chat hub - LLNearbyChat::instance().sendChat(getConvertedText(),type); + FSNearbyChat::instance().sendChat(getConvertedText(),type); setText(LLStringExplicit("")); autohide(); diff --git a/indra/newview/llnearbychatcontrol.h b/indra/newview/fsnearbychatcontrol.h similarity index 87% rename from indra/newview/llnearbychatcontrol.h rename to indra/newview/fsnearbychatcontrol.h index 67aefbad7a..f8af8bc156 100644 --- a/indra/newview/llnearbychatcontrol.h +++ b/indra/newview/fsnearbychatcontrol.h @@ -1,5 +1,5 @@ /** - * @file llnearbychatcontrol.h + * @file fsnearbychatcontrol.h * @brief Nearby chat input control implementation * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ @@ -25,19 +25,19 @@ * $/LicenseInfo$ */ -#ifndef LL_LLNEARBYCHATCONTROL_H -#define LL_LLNEARBYCHATCONTROL_H +#ifndef FS_NEARBYCHATCONTROL_H +#define FS_NEARBYCHATCONTROL_H #include "llchat.h" #include "lllineeditor.h" -class LLNearbyChatControl : public LLLineEditor +class FSNearbyChatControl : public LLLineEditor { public: struct Params : public LLInitParam::Block {}; - LLNearbyChatControl(const Params& p); - ~LLNearbyChatControl(); + FSNearbyChatControl(const Params& p); + ~FSNearbyChatControl(); virtual void onFocusReceived(); virtual void onFocusLost(); @@ -55,4 +55,4 @@ private: void autohide(); }; -#endif +#endif // FS_NEARBYCHATCONTROL_H diff --git a/indra/newview/llnearbychathub.cpp b/indra/newview/fsnearbychathub.cpp similarity index 91% rename from indra/newview/llnearbychathub.cpp rename to indra/newview/fsnearbychathub.cpp index 549ba381ae..dc09271183 100644 --- a/indra/newview/llnearbychathub.cpp +++ b/indra/newview/fsnearbychathub.cpp @@ -1,5 +1,5 @@ /** - * @file llnearbychat.cpp + * @file fsnearbychat.cpp * @brief @brief Nearby chat central class for handling multiple chat input controls * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ @@ -27,9 +27,12 @@ #include "llviewerprecompiledheaders.h" -#include "llnearbychathub.h" -#include "llnearbychatcontrol.h" -#include "llfloaternearbychat.h" +#include "fsnearbychathub.h" +#include "fsnearbychatcontrol.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] #include "llviewercontrol.h" #include "llviewerwindow.h" @@ -76,20 +79,20 @@ static LLChatTypeTrigger sChatTypeTriggers[] = { { "/shout" , CHAT_TYPE_SHOUT} }; -S32 LLNearbyChat::sLastSpecialChatChannel = 0; +S32 FSNearbyChat::sLastSpecialChatChannel = 0; -LLNearbyChat::LLNearbyChat() : +FSNearbyChat::FSNearbyChat() : mDefaultChatBar(NULL), mFocusedInputEditor(NULL) { - gSavedSettings.getControl("MainChatbarVisible")->getSignal()->connect(boost::bind(&LLNearbyChat::onDefaultChatBarButtonClicked, this)); + gSavedSettings.getControl("MainChatbarVisible")->getSignal()->connect(boost::bind(&FSNearbyChat::onDefaultChatBarButtonClicked, this)); } -LLNearbyChat::~LLNearbyChat() +FSNearbyChat::~FSNearbyChat() { } -void LLNearbyChat::onDefaultChatBarButtonClicked() +void FSNearbyChat::onDefaultChatBarButtonClicked() { showDefaultChatBar(gSavedSettings.getBOOL("MainChatbarVisible")); } @@ -246,12 +249,12 @@ void really_send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 } // FIRE-787 -void LLNearbyChat::sendChatFromViewer(const std::string& utf8text, EChatType type, BOOL animate) +void FSNearbyChat::sendChatFromViewer(const std::string& utf8text, EChatType type, BOOL animate) { sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); } -void LLNearbyChat::sendChatFromViewer(const LLWString& wtext, EChatType type, BOOL animate) +void FSNearbyChat::sendChatFromViewer(const LLWString& wtext, EChatType type, BOOL animate) { // Look for "/20 foo" channel chats. S32 channel = 0; @@ -262,7 +265,10 @@ void LLNearbyChat::sendChatFromViewer(const LLWString& wtext, EChatType type, BO gSavedSettings.getBOOL("FSShowChatChannel") && (channel == 0)) { - channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + // [FS communication UI] + //channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + // [FS communication UI] } std::string utf8_out_text = wstring_to_utf8str(out_text); std::string utf8_text = wstring_to_utf8str(wtext); @@ -323,7 +329,7 @@ void LLNearbyChat::sendChatFromViewer(const LLWString& wtext, EChatType type, BO send_chat_from_viewer(utf8_out_text, type, channel); } -EChatType LLNearbyChat::processChatTypeTriggers(EChatType type, std::string &str) +EChatType FSNearbyChat::processChatTypeTriggers(EChatType type, std::string &str) { U32 length = str.length(); S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); @@ -357,7 +363,7 @@ EChatType LLNearbyChat::processChatTypeTriggers(EChatType type, std::string &str // If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. // Otherwise returns input and channel 0. -LLWString LLNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel) +LLWString FSNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel) { if (mesg[0] == '/' && mesg[1] == '/') @@ -410,7 +416,7 @@ LLWString LLNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel) } } -void LLNearbyChat::sendChat(LLWString text,EChatType type) +void FSNearbyChat::sendChat(LLWString text,EChatType type) { LLWStringUtil::trim(text); @@ -432,7 +438,10 @@ void LLNearbyChat::sendChat(LLWString text,EChatType type) gSavedSettings.getBOOL("FSShowChatChannel") && (channel == 0)) { - channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + // [FS communication UI] + //channel = (S32)(LLFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + channel = (S32)(FSFloaterNearbyChat::getInstance()->getChild("ChatChannel")->get()); + // [FS communication UI] } std::string utf8text = wstring_to_utf8str(text); @@ -473,7 +482,7 @@ void LLNearbyChat::sendChat(LLWString text,EChatType type) } // all chat bars call this function and we keep the first or one that's seen as the default -void LLNearbyChat::registerChatBar(LLNearbyChatControl* chatBar) +void FSNearbyChat::registerChatBar(FSNearbyChatControl* chatBar) { // TODO: make this a Param option "is_default" if(!mDefaultChatBar || chatBar->getName()=="default_chat_bar") @@ -483,7 +492,7 @@ void LLNearbyChat::registerChatBar(LLNearbyChatControl* chatBar) } // unhide the default nearby chat bar on request (pressing Enter or a letter key) -void LLNearbyChat::showDefaultChatBar(BOOL visible,const char* text) const +void FSNearbyChat::showDefaultChatBar(BOOL visible,const char* text) const { if(!mDefaultChatBar) return; @@ -506,7 +515,7 @@ void LLNearbyChat::showDefaultChatBar(BOOL visible,const char* text) const } // We want to know which nearby chat editor (if any) currently has focus -void LLNearbyChat::setFocusedInputEditor(LLNearbyChatControl* inputEditor,BOOL focus) +void FSNearbyChat::setFocusedInputEditor(FSNearbyChatControl* inputEditor,BOOL focus) { if(focus) mFocusedInputEditor=inputEditor; @@ -519,7 +528,7 @@ void LLNearbyChat::setFocusedInputEditor(LLNearbyChatControl* inputEditor,BOOL f // for the "arrow key moves avatar when chat is empty" hack in llviewerwindow.cpp // and the hide chat bar feature in mouselook in llagent.cpp -BOOL LLNearbyChat::defaultChatBarIsIdle() const +BOOL FSNearbyChat::defaultChatBarIsIdle() const { if(mFocusedInputEditor && mFocusedInputEditor->getName()=="default_chat_bar") return mFocusedInputEditor->getText().empty(); @@ -529,7 +538,7 @@ BOOL LLNearbyChat::defaultChatBarIsIdle() const } // for the "arrow key moves avatar when chat is empty" hack in llviewerwindow.cpp -BOOL LLNearbyChat::defaultChatBarHasFocus() const +BOOL FSNearbyChat::defaultChatBarHasFocus() const { if(mFocusedInputEditor && mFocusedInputEditor->getName()=="default_chat_bar") return TRUE; diff --git a/indra/newview/llnearbychathub.h b/indra/newview/fsnearbychathub.h similarity index 81% rename from indra/newview/llnearbychathub.h rename to indra/newview/fsnearbychathub.h index 869eca7753..f900eafa15 100644 --- a/indra/newview/llnearbychathub.h +++ b/indra/newview/fsnearbychathub.h @@ -25,31 +25,31 @@ * $/LicenseInfo$ */ -#ifndef LL_LLNEARBYCHAT_H -#define LL_LLNEARBYCHAT_H +#ifndef FS_NEARBYCHAT_H +#define FS_NEARBYCHAT_H #include "llsingleton.h" #include "llviewerchat.h" -class LLNearbyChatControl; +class FSNearbyChatControl; -class LLNearbyChat : public LLSingleton +class FSNearbyChat : public LLSingleton { - friend class LLSingleton; + friend class LLSingleton; private: - LLNearbyChat(); - ~LLNearbyChat(); + FSNearbyChat(); + ~FSNearbyChat(); void sendMsg(); static S32 sLastSpecialChatChannel; - LLNearbyChatControl* mDefaultChatBar; + FSNearbyChatControl* mDefaultChatBar; void onDefaultChatBarButtonClicked(); public: - void registerChatBar(LLNearbyChatControl* chatBar); + 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; @@ -60,12 +60,12 @@ public: void sendChatFromViewer(const std::string& utf8text, EChatType type, BOOL animate); void sendChatFromViewer(const LLWString& wtext, EChatType type, BOOL animate); - void setFocusedInputEditor(LLNearbyChatControl* inputEditor,BOOL focus); + void setFocusedInputEditor(FSNearbyChatControl* inputEditor,BOOL focus); BOOL defaultChatBarIsIdle() const; BOOL defaultChatBarHasFocus() const; - LLNearbyChatControl* mFocusedInputEditor; + FSNearbyChatControl* mFocusedInputEditor; }; -#endif +#endif // FS_NEARBYCHAT_H diff --git a/indra/newview/fsnearbychatvoicemonitor.cpp b/indra/newview/fsnearbychatvoicemonitor.cpp index 127efe1936..7808e126f4 100644 --- a/indra/newview/fsnearbychatvoicemonitor.cpp +++ b/indra/newview/fsnearbychatvoicemonitor.cpp @@ -33,7 +33,7 @@ FSNearbyChatVoiceControl::Params::Params() : {} FSNearbyChatVoiceControl::FSNearbyChatVoiceControl(const FSNearbyChatVoiceControl::Params& p) : - LLNearbyChatControl(p), + FSNearbyChatControl(p), mVoiceMonitor(NULL), mOriginalTextpadLeft(p.text_pad_left), mOriginalTextpadRight(p.text_pad_right), @@ -70,5 +70,5 @@ void FSNearbyChatVoiceControl::draw() mVoiceMonitor->setVisible(FALSE); } } - LLNearbyChatControl::draw(); + FSNearbyChatControl::draw(); } diff --git a/indra/newview/fsnearbychatvoicemonitor.h b/indra/newview/fsnearbychatvoicemonitor.h index a317a0b599..ef7feceb24 100644 --- a/indra/newview/fsnearbychatvoicemonitor.h +++ b/indra/newview/fsnearbychatvoicemonitor.h @@ -23,16 +23,16 @@ #ifndef FS_NEARBYCHATVOICEMONITOR_H #define FS_NEARBYCHATVOICEMONITOR_H -#include "llnearbychatcontrol.h" +#include "fsnearbychatcontrol.h" #include "lloutputmonitorctrl.h" class LLUICtrlFactory; -class FSNearbyChatVoiceControl : public LLNearbyChatControl +class FSNearbyChatVoiceControl : public FSNearbyChatControl { public: - struct Params : public LLInitParam::Block + struct Params : public LLInitParam::Block { Optional voice_monitor_padding; Optional nearby_voice_monitor; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index f5071b06fb..1827cfc3fe 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -57,7 +57,7 @@ #include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state // Remove floating chat bar //#include "llnearbychatbar.h" -#include "llnearbychathub.h" +#include "fsnearbychathub.h" // #include "llspeakers.h" // [/SL:KB] @@ -2195,7 +2195,7 @@ void LLAgent::startTyping() } // Remove floating chat bar // LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE); - LLNearbyChat::instance().sendChatFromViewer("", CHAT_TYPE_START, FALSE); + FSNearbyChat::instance().sendChatFromViewer("", CHAT_TYPE_START, FALSE); // } @@ -2210,7 +2210,7 @@ void LLAgent::stopTyping() sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP); // Remove floating chat bar // LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); - LLNearbyChat::instance().sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); + FSNearbyChat::instance().sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); // } } @@ -2277,7 +2277,7 @@ void LLAgent::endAnimationUpdateUI() // Unhide chat bar, unless autohide is enabled gSavedSettings.setBOOL("MouseLookEnabled",FALSE); if(!gSavedSettings.getBOOL("AutohideChatBar")) - LLNearbyChat::instance().showDefaultChatBar(TRUE); + FSNearbyChat::instance().showDefaultChatBar(TRUE); // gToolBarView->setToolBarsVisible(true); @@ -2437,8 +2437,8 @@ void LLAgent::endAnimationUpdateUI() // Hide chat bar in mouselook mode, unless there is text in it gSavedSettings.setBOOL("MouseLookEnabled",TRUE); - if(LLNearbyChat::instance().defaultChatBarIsIdle()) - LLNearbyChat::instance().showDefaultChatBar(FALSE); + if(FSNearbyChat::instance().defaultChatBarIsIdle()) + FSNearbyChat::instance().showDefaultChatBar(FALSE); // // clear out camera lag effect diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 64878b8230..bd417ab10a 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -68,7 +68,10 @@ #include "llviewerobjectlist.h" #include "llviewermessage.h" // for handle_lure #include "llviewerregion.h" -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloater.h" +#include "fsfloaterim.h" +// [FS communication UI] #include "lltrans.h" #include "llcallingcard.h" #include "llslurl.h" // IDEVO @@ -200,7 +203,10 @@ static void on_avatar_name_cache_start_im(const LLUUID& agent_id, LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id); if (session_id != LLUUID::null) { - LLIMFloater::show(session_id); + // [FS communication UI] + //LLIMFloater::show(session_id); + FSFloaterIM::show(session_id); + // [FS communication UI] } make_ui_sound("UISndStartIM"); } @@ -361,7 +367,10 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids) LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array); if (session_id != LLUUID::null) { - LLIMFloater::show(session_id); + // [FS communication UI] + //LLIMFloater::show(session_id); + FSFloaterIM::show(session_id); + // [FS communication UI] } make_ui_sound("UISndStartIM"); } diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 8785742338..20db5a44d4 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -38,7 +38,10 @@ #include "llavatariconctrl.h" #include "llavatarlist.h" #include "lldraghandle.h" -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloater.h" +#include "fsfloaterim.h" +// [FS communication UI] #include "llimview.h" #include "llfloaterreg.h" #include "llparticipantlist.h" @@ -318,7 +321,10 @@ void LLCallFloater::updateSession() voice_channel && LLVoiceChannel::STATE_CONNECTED == voice_channel->getState()) { - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(session_id); + // [FS communication UI] bool show_me = !(im_floater && im_floater->getVisible()); if (show_me) { diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 1177b279ed..4b155b40a1 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -64,11 +64,17 @@ #include "lggcontactsets.h" // Remove floating chat bar // #include "llnearbychat.h" -#include "llfloaternearbychat.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] // #include "llfloaterreg.h" #include "llnotificationmanager.h" -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloater.h" +#include "fsfloaterim.h" +// ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs @@ -889,7 +895,10 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id, args["type"] = LLNotificationsUI::NT_NEARBYCHAT; if (history_only) { - LLFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); + // [FS communication UI] + //LLFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); + FSFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("fs_nearby_chat", LLSD()); + // [FS communication UI] nearby_chat->addMessage(chat, true, LLSD()); } else @@ -916,7 +925,10 @@ void LLAvatarTracker::formFriendship(const LLUUID& id) // FIRE-3248: Disable add friend button on IM floater if friendship request accepted LLUUID im_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, id); - LLIMFloater* im_floater = LLIMFloater::findInstance(im_session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(im_session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(im_session_id); + // [FS communication UI] if (im_floater) { im_floater->setEnableAddFriendButton(FALSE); @@ -942,7 +954,10 @@ void LLAvatarTracker::processTerminateFriendship(LLMessageSystem* msg, void**) // FIRE-3248: Disable add friend button on IM floater if friendship request accepted LLUUID im_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, id); - LLIMFloater* im_floater = LLIMFloater::findInstance(im_session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(im_session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(im_session_id); + // [FS communication UI] if (im_floater) { im_floater->setEnableAddFriendButton(TRUE); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index f5c64b3e49..79eee36a7d 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -26,6 +26,8 @@ #include "llviewerprecompiledheaders.h" +#if 0 + #include "llchathistory.h" #include "llavatarnamecache.h" @@ -1553,3 +1555,5 @@ BOOL LLChatHistory::handleUnicodeCharHere(llwchar uni_char) return LLTextEditor::handleUnicodeCharHere(uni_char); } // + +#endif \ No newline at end of file diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index 56217e1439..e1740d7a83 100644 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#if 0 + #ifndef LLCHATHISTORY_H_ #define LLCHATHISTORY_H_ @@ -163,3 +165,5 @@ class LLChatHistory : public LLTextEditor // FIRE-8600: TAB out of chat // }; #endif /* LLCHATHISTORY_H_ */ + +#endif \ No newline at end of file diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 64c72b9ed8..6b6876df50 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -46,7 +46,10 @@ #include "rlvhandler.h" // [/RLVa:KB] -#include "llfloaternearbychat.h" // Remove floating chat bar +// [FS communication UI] +//#include "llfloaternearbychat.h" // Remove floating chat bar +#include "fsfloaternearbychat.h" +// [FS communication UI] static const S32 msg_left_offset = 10; static const S32 msg_right_offset = 10; @@ -339,14 +342,20 @@ BOOL LLNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask) { // Remove floating chat bar // LLNearbyChatBar::getInstance()->showHistory(); - LLFloaterNearbyChat::getInstance()->setVisible(TRUE); + // [FS communication UI] + //LLFloaterNearbyChat::getInstance()->setVisible(TRUE); + FSFloaterNearbyChat::getInstance()->setVisible(TRUE); + // [FS communication UI] // // If nearby chat history is docked, we also need // to open the container floater (FIRE-6265) if (!gSavedSettings.getBOOL("ChatHistoryTornOff")) { - LLFloaterReg::showInstance("im_container"); + // [FS communication UI] + //LLFloaterReg::showInstance("im_container"); + LLFloaterReg::showInstance("fs_im_container"); + // [FS communication UI] } // return FALSE; @@ -355,14 +364,20 @@ BOOL LLNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask) // Remove floating chat bar // LLNearbyChatBar::getInstance()->showHistory(); - LLFloaterNearbyChat::getInstance()->setVisible(TRUE); + // [FS communication UI] + //LLFloaterNearbyChat::getInstance()->setVisible(TRUE); + FSFloaterNearbyChat::getInstance()->setVisible(TRUE); + // [FS communication UI] // // If nearby chat history is docked, we also need // to open the container floater (FIRE-6265) if (!gSavedSettings.getBOOL("ChatHistoryTornOff")) { - LLFloaterReg::showInstance("im_container"); + // [FS communication UI] + //LLFloaterReg::showInstance("im_container"); + LLFloaterReg::showInstance("fs_im_container"); + // [FS communication UI] } // return LLPanel::handleMouseUp(x,y,mask); diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index a661808d1f..57218f7624 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -33,7 +33,10 @@ #include "lleventtimer.h" #include "llgroupactions.h" #include "lliconctrl.h" -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloater.h" +#include "fsfloaterim.h" +// [FS communication UI] #include "llimview.h" #include "llfloaterreg.h" #include "lllocalcliprect.h" @@ -311,8 +314,12 @@ void LLIMWellChiclet::messageCountChanged(const LLSD& session_data) const LLUUID& session_id = session_data["session_id"]; const S32 counter = LLChicletBar::getInstance()->getTotalUnreadIMCount(); - const bool im_not_visible = !LLFloaterReg::instanceVisible("im_container") - && !LLFloaterReg::instanceVisible("impanel", session_id); + // [FS communication UI] + //const bool im_not_visible = !LLFloaterReg::instanceVisible("im_container") + // && !LLFloaterReg::instanceVisible("impanel", session_id); + const bool im_not_visible = !LLFloaterReg::instanceVisible("fs_im_container") + && !LLFloaterReg::instanceVisible("fs_impanel", session_id); + // [FS communication UI] setNewMessagesState(counter > mCounter && im_not_visible); @@ -607,7 +614,10 @@ bool LLIMChiclet::getShowNewMessagesIcon() void LLIMChiclet::onMouseDown() { - LLIMFloater::toggle(getSessionId()); + // [FS communication UI] + //LLIMFloater::toggle(getSessionId()); + FSFloaterIM::toggle(getSessionId()); + // [FS communication UI] setCounter(0); } @@ -756,7 +766,10 @@ void LLIMP2PChiclet::updateMenuItems() if(getSessionId().isNull()) return; - LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId()); + // [FS communication UI] + //LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId()); + FSFloaterIM* open_im_floater = FSFloaterIM::findInstance(getSessionId()); + // [FS communication UI] bool open_window_exists = open_im_floater && open_im_floater->getVisible(); mPopupMenu->getChild("Send IM")->setEnabled(!open_window_exists); @@ -1032,7 +1045,10 @@ void LLIMGroupChiclet::updateMenuItems() if(getSessionId().isNull()) return; - LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId()); + // [FS communication UI] + //LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId()); + FSFloaterIM* open_im_floater = FSFloaterIM::findInstance(getSessionId()); + // [FS communication UI] bool open_window_exists = open_im_floater && open_im_floater->getVisible(); mPopupMenu->getChild("Chat")->setEnabled(!open_window_exists); } @@ -1118,7 +1134,10 @@ void LLChicletPanel::onMessageCountChanged(const LLSD& data) LLUUID session_id = data["session_id"].asUUID(); S32 unread = data["participant_unread"].asInteger(); - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(session_id); + // [FS communication UI] if (im_floater && im_floater->getVisible() && im_floater->hasFocus()) { unread = 0; @@ -1199,7 +1218,10 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id) chiclet->setShowSpeaker(true); if (gSavedSettings.getBOOL("OpenIMOnVoice")) { - LLIMFloater::show(chiclet->getSessionId()); + // [FS communication UI] + //LLIMFloater::show(chiclet->getSessionId()); + FSFloaterIM::show(chiclet->getSessionId()); + // [FS communication UI] } } } @@ -1690,8 +1712,12 @@ bool LLChicletPanel::isAnyIMFloaterDoked() for (chiclet_list_t::iterator it = mChicletList.begin(); it != mChicletList.end(); it++) { - LLIMFloater* im_floater = LLFloaterReg::findTypedInstance( - "impanel", (*it)->getSessionId()); + // [FS communication UI] + //LLIMFloater* im_floater = LLFloaterReg::findTypedInstance( + // "impanel", (*it)->getSessionId()); + FSFloaterIM* im_floater = LLFloaterReg::findTypedInstance( + "fs_impanel", (*it)->getSessionId()); + // [FS communication UI] if (im_floater != NULL && im_floater->getVisible() && !im_floater->isMinimized() && im_floater->isDocked()) { diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp index 253bf8b1d2..6ad89a1852 100644 --- a/indra/newview/llchicletbar.cpp +++ b/indra/newview/llchicletbar.cpp @@ -34,7 +34,10 @@ // newview includes #include "llchiclet.h" -#include "llimfloater.h" // for LLIMFloater +// [FS communication UI] +//#include "llimfloater.h" // for LLIMFloater +#include "fsfloaterim.h" +// [FS communication UI] #include "llpaneltopinfobar.h" #include "llsyswellwindow.h" @@ -110,7 +113,10 @@ void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& nam chiclet->setIMSessionName(name); chiclet->setOtherParticipantId(other_participant_id); - LLIMFloater::onIMChicletCreated(session_id); + // [FS communication UI] + //LLIMFloater::onIMChicletCreated(session_id); + FSFloaterIM::onIMChicletCreated(session_id); + // [FS communication UI] } else @@ -125,7 +131,10 @@ void LLChicletBar::sessionRemoved(const LLUUID& session_id) if(getChicletPanel()) { // IM floater should be closed when session removed and associated chiclet closed - LLIMFloater* iMfloater = LLFloaterReg::findTypedInstance("impanel", session_id); + // [FS communication UI] + //LLIMFloater* iMfloater = LLFloaterReg::findTypedInstance("impanel", session_id); + FSFloaterIM* iMfloater = LLFloaterReg::findTypedInstance("fs_impanel", session_id); + // [FS communication UI] if (iMfloater != NULL) { iMfloater->closeFloater(); diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index d920cf0652..dd70e446f4 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -76,7 +76,10 @@ void LLFirstUse::otherAvatarChatFirst(bool enable) { // Remove floating chat bar // firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "chat_bar").with("direction", "top_right").with("distance", 24)); - firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "nearby_chat").with("direction", "top_right").with("distance", 24)); + // [FS communication UI] + //firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "nearby_chat").with("direction", "top_right").with("distance", 24)); + firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "fs_nearby_chat").with("direction", "top_right").with("distance", 24)); + // [FS communication UI] // } diff --git a/indra/newview/llfloaternearbychat.cpp b/indra/newview/llfloaternearbychat.cpp index 3d643c57eb..2aa64a0beb 100644 --- a/indra/newview/llfloaternearbychat.cpp +++ b/indra/newview/llfloaternearbychat.cpp @@ -27,6 +27,8 @@ #include "llviewerprecompiledheaders.h" +#if 0 + #include "llfloaternearbychat.h" #include "llviewercontrol.h" @@ -64,8 +66,12 @@ #include "llbutton.h" #include "lllayoutstack.h" -#include "llimfloatercontainer.h" -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloatercontainer.h" +//#include "llimfloater.h" +#include "fsfloaterim.h" +#include "fsfloaterimcontainer.h" +// [FS communication UI] #include "lllineeditor.h" //AO - includes for textentry @@ -349,7 +355,10 @@ void LLFloaterNearbyChat::openFloater(const LLSD& key) // We override this to put nearbychat in the IM floater. -AO if(isChatMultiTab()) { - LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + // [FS communication UI] + //LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + FSFloaterIMContainer* floater_container = FSFloaterIMContainer::getInstance(); + // [FS communication UI] // only show the floater container if we are actually attached -Zi if (floater_container && !gSavedSettings.getBOOL("ChatHistoryTornOff")) { @@ -381,7 +390,10 @@ void LLFloaterNearbyChat::setVisible(BOOL visible) static LLCachedControl chatHistoryTornOff(gSavedSettings, "ChatHistoryTornOff"); if (FSUseNearbyChatConsole) { - LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + // [FS communication UI] + //LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + FSFloaterIMContainer* floater_container = FSFloaterIMContainer::getInstance(); + // [FS communication UI] if (floater_container && !chatHistoryTornOff && !floater_container->getVisible()) { // In case the nearby chat is docked into the IM floater and the @@ -406,7 +418,10 @@ void LLFloaterNearbyChat::onFocusReceived() void LLFloaterNearbyChat::onOpen(const LLSD& key ) { - LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + // [FS communication UI] + //LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + FSFloaterIMContainer* floater_container = FSFloaterIMContainer::getInstance(); + // [FS communication UI] if (floater_container) { if (gSavedSettings.getBOOL("ChatHistoryTornOff")) @@ -612,7 +627,10 @@ BOOL LLFloaterNearbyChat::getVisible() { if(isChatMultiTab()) { - LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance(); + // [FS communication UI] + //LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance(); + FSFloaterIMContainer* im_container = FSFloaterIMContainer::getInstance(); + // [FS communication UI] // Treat inactive floater as invisible. bool is_active = im_container->getActiveFloater() == this; @@ -631,3 +649,5 @@ BOOL LLFloaterNearbyChat::getVisible() return LLDockableFloater::getVisible(); } } + +#endif \ No newline at end of file diff --git a/indra/newview/llfloaternearbychat.h b/indra/newview/llfloaternearbychat.h index 25630c6402..697fc7ab85 100644 --- a/indra/newview/llfloaternearbychat.h +++ b/indra/newview/llfloaternearbychat.h @@ -25,6 +25,8 @@ * $/LicenseInfo$ */ +#if 0 + #ifndef LL_LLFLOATERNEARBYCHAT_H #define LL_LLFLOATERNEARBYCHAT_H @@ -113,3 +115,5 @@ private: }; #endif + +#endif \ No newline at end of file diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 32d1e7723f..5113ee50d0 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -52,13 +52,19 @@ #include "llfloaterabout.h" #include "llfloaterhardwaresettings.h" #include "llfloatersidepanelcontainer.h" -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloater.h" +#include "fsfloaterim.h" +// [FS communication UI] #include "llkeyboard.h" #include "llmodaldialog.h" #include "llnavigationbar.h" // Remove floating chat bar // #include "llnearbychat.h" -#include "llfloaternearbychat.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] // #include "llnotifications.h" #include "llnotificationsutil.h" @@ -580,13 +586,16 @@ void LLFloaterPreference::saveAvatarProperties( void ) BOOL LLFloaterPreference::postBuild() { - gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2)); - - gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLFloaterNearbyChat::processChatHistoryStyleUpdate, _2)); - - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2)); - - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterNearbyChat::processChatHistoryStyleUpdate, _2)); + // [FS communication UI] + //gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2)); + //gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLFloaterNearbyChat::processChatHistoryStyleUpdate, _2)); + //gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2)); + //gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterNearbyChat::processChatHistoryStyleUpdate, _2)); + gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&FSFloaterIM::processChatHistoryStyleUpdate, _2)); + gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&FSFloaterNearbyChat::processChatHistoryStyleUpdate, _2)); + gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&FSFloaterIM::processChatHistoryStyleUpdate, _2)); + gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&FSFloaterNearbyChat::processChatHistoryStyleUpdate, _2)); + // [FS communication UI] gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged)); diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 52a5a36fda..f2f49b096c 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -53,7 +53,7 @@ #include "llviewerstats.h" // Remove floating chat bar // #include "llnearbychatbar.h" -#include "llnearbychathub.h" +#include "fsnearbychathub.h" // #include "llappearancemgr.h" #include "llgesturelistener.h" @@ -1013,7 +1013,7 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step) // Remove floating chat bar // LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); - LLNearbyChat::instance().sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); + FSNearbyChat::instance().sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); // gesture->mCurrentStep++; diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index e9cc7e2db7..04ee238fa6 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -39,7 +39,10 @@ #include "llimview.h" // for gIMMgr #include "llnotificationsutil.h" #include "llstatusbar.h" // can_afford_transaction() -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloater.h" +#include "fsfloaterim.h" +// [FS communication UI] #include "groupchatlistener.h" // [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) #include "llslurl.h" @@ -489,7 +492,10 @@ LLUUID LLGroupActions::startIM(const LLUUID& group_id) group_id); if (session_id != LLUUID::null) { - LLIMFloater::show(session_id); + // [FS communication UI] + //LLIMFloater::show(session_id); + FSFloaterIM::show(session_id); + // [FS communication UI] } make_ui_sound("UISndStartIM"); return session_id; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 565909cb6b..2f2cbfa556 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -26,6 +26,8 @@ #include "llviewerprecompiledheaders.h" +#if 0 + #include "llimfloater.h" #include "llnotificationsutil.h" @@ -1872,3 +1874,5 @@ void LLIMFloater::setEnableAddFriendButton(BOOL enabled) getChild("add_friend_btn")->setEnabled(enabled); } // + +#endif \ No newline at end of file diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index 78e16c3cbd..769b088e0d 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#if 0 + #ifndef LL_IMFLOATER_H #define LL_IMFLOATER_H @@ -221,3 +223,5 @@ private: #endif // LL_IMFLOATER_H + +#endif \ No newline at end of file diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index 7441e35799..6aec145d42 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -27,6 +27,8 @@ #include "llviewerprecompiledheaders.h" +#if 0 + #include "llimfloatercontainer.h" #include "llfloaterreg.h" #include "llimview.h" @@ -286,3 +288,5 @@ void LLIMFloaterContainer::setMinimized(BOOL b) } // EOF + +#endif \ No newline at end of file diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index 3c983a1df6..3b957f2d37 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#if 0 + #ifndef LL_LLIMFLOATERCONTAINER_H #define LL_LLIMFLOATERCONTAINER_H @@ -71,3 +73,5 @@ private: }; #endif // LL_LLIMFLOATERCONTAINER_H + +#endif \ No newline at end of file diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 8b05410742..2c2b3218ca 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -48,7 +48,10 @@ #include "llavatariconctrl.h" #include "llcallingcard.h" #include "llchat.h" -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloater.h" +#include "fsfloaterim.h" +// [FS communication UI] #include "llgroupiconctrl.h" #include "llmd5.h" #include "llmutelist.h" @@ -59,7 +62,10 @@ #include "llnotificationsutil.h" // Remove floating chat bar // #include "llnearbychat.h" -#include "llfloaternearbychat.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] // #include "llspeakers.h" //for LLIMSpeakerMgr #include "lltextbox.h" @@ -116,7 +122,10 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id, args["FROM"] = av_name.getCompleteName(); args["FROM_ID"] = msg["from_id"]; args["SESSION_ID"] = msg["session_id"]; - LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID())); + // [FS communication UI] + //LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID())); + LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&FSFloaterIM::show, msg["session_id"].asUUID())); + // [FS communication UI] } void toast_callback(const LLSD& msg){ @@ -168,7 +177,10 @@ void toast_callback(const LLSD& msg){ } // Skip toasting if we have open window of IM with this session id - LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]); + // [FS communication UI] + //LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]); + FSFloaterIM* open_im_floater = FSFloaterIM::findInstance(msg["session_id"]); + // [FS communication UI] if (open_im_floater && open_im_floater->getVisible()) { return; @@ -193,7 +205,10 @@ void LLIMModel::setActiveSessionID(const LLUUID& session_id) LLIMModel::LLIMModel() { - addNewMsgCallback(boost::bind(&LLIMFloater::newIMCallback, _1)); + // [FS communication UI] + //addNewMsgCallback(boost::bind(&LLIMFloater::newIMCallback, _1)); + addNewMsgCallback(boost::bind(&FSFloaterIM::newIMCallback, _1)); + // [FS communication UI] addNewMsgCallback(boost::bind(&toast_callback, _1)); } @@ -712,7 +727,10 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id); } - LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(old_session_id); + // [FS communication UI] if (im_floater) { im_floater->sessionInitReplyReceived(new_session_id); @@ -882,7 +900,10 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, chat.mSourceType = CHAT_SOURCE_AGENT; chat.mText = utf8_text; chat.mTimeStr = timestr; - LLFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); + // [FS communication UI] + //LLFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); + FSFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("fs_nearby_chat", LLSD()); + // [FS communication UI] nearby_chat->addMessage(chat, true, LLSD()); } // @@ -1737,7 +1758,10 @@ LLIMMgr::onConfirmForceCloseError( //only 1 option really LLUUID session_id = notification["payload"]["session_id"]; - LLFloater* floater = LLIMFloater::findInstance(session_id); + // [FS communication UI] + //LLFloater* floater = LLIMFloater::findInstance(session_id); + LLFloater* floater = FSFloaterIM::findInstance(session_id); + // [FS communication UI] if ( floater ) { floater->closeFloater(FALSE); @@ -2603,7 +2627,10 @@ LLIMMgr::LLIMMgr() mPendingInvitations = LLSD::emptyMap(); mPendingAgentListUpdates = LLSD::emptyMap(); - LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLIMFloater::sRemoveTypingIndicator, _1)); + // [FS communication UI] + //LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLIMFloater::sRemoveTypingIndicator, _1)); + LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&FSFloaterIM::sRemoveTypingIndicator, _1)); + // [FS communication UI] } // Add a message to a session. @@ -2713,7 +2740,10 @@ void LLIMMgr::addMessage( // IM Sounds only for sessions not in focus else if(PlayModeUISndNewIncomingIMSession == 3 && dialog == IM_NOTHING_SPECIAL) { - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(session_id); + // [FS communication UI] if (im_floater && !im_floater->hasFocus()) { make_ui_sound("UISndNewIncomingIMSession"); @@ -2721,7 +2751,10 @@ void LLIMMgr::addMessage( } else if(PlayModeUISndNewIncomingGroupIMSession == 3 && dialog != IM_NOTHING_SPECIAL) { - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(session_id); + // [FS communication UI] if (im_floater && !im_floater->hasFocus()) { make_ui_sound("UISndNewIncomingGroupIMSession"); @@ -2766,7 +2799,10 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess // Remove floating chat bar // LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar"); // LLNearbyChat* nearby_chat = chat_bar->findChild("nearby_chat"); - LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + // [FS communication UI] + //LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance(); + // [FS communication UI] // if(nearby_chat) @@ -3095,7 +3131,10 @@ void LLIMMgr::clearPendingInvitation(const LLUUID& session_id) void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body) { - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(session_id); + // [FS communication UI] if ( im_floater ) { im_floater->processAgentListUpdates(body); @@ -3452,7 +3491,10 @@ void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing) } // - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(session_id); + // [FS communication UI] if ( im_floater ) { @@ -3498,7 +3540,10 @@ public: speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id)); } - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(session_id); + // [FS communication UI] if ( im_floater ) { if ( body.has("session_info") ) @@ -3592,7 +3637,10 @@ public: const LLSD& input) const { LLUUID session_id = input["body"]["session_id"].asUUID(); - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(session_id); + // [FS communication UI] if ( im_floater ) { im_floater->processSessionUpdate(input["body"]["info"]); diff --git a/indra/newview/llnearbychatbarlistener.cpp b/indra/newview/llnearbychatbarlistener.cpp index 3b748caadc..a9930f7466 100644 --- a/indra/newview/llnearbychatbarlistener.cpp +++ b/indra/newview/llnearbychatbarlistener.cpp @@ -28,10 +28,13 @@ #include "llviewerprecompiledheaders.h" +#if 0 + #include "llnearbychatbarlistener.h" + // Remove floating chat bar // #include "llnearbychatbar.h" -#include "llnearbychathub.h" +#include "fsnearbychathub.h" // #include "llagent.h" @@ -105,7 +108,10 @@ void LLNearbyChatBarListener::sendChat(LLSD const & chat_data) const // Send it as if it was typed in // Remove floating chat bar // mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, (BOOL)(channel == 0)); - LLNearbyChat::instance().sendChatFromViewer(chat_to_send, type_o_chat, ((BOOL)(channel == 0)) && gSavedSettings.getBOOL("FSPlayChatAnimation")); + // [FS communication UI] + //LLNearbyChat::instance().sendChatFromViewer(chat_to_send, type_o_chat, ((BOOL)(channel == 0)) && gSavedSettings.getBOOL("FSPlayChatAnimation")); + FSNearbyChat::instance().sendChatFromViewer(chat_to_send, type_o_chat, ((BOOL)(channel == 0)) && gSavedSettings.getBOOL("FSPlayChatAnimation")); + // [FS communication UI] // } - +#endif \ No newline at end of file diff --git a/indra/newview/llnearbychatbarlistener.h b/indra/newview/llnearbychatbarlistener.h index 7e61f0298a..1cb32d392e 100644 --- a/indra/newview/llnearbychatbarlistener.h +++ b/indra/newview/llnearbychatbarlistener.h @@ -26,6 +26,7 @@ * $/LicenseInfo$ */ +#if 0 #ifndef LL_LLNEARBYCHATBARLISTENER_H #define LL_LLNEARBYCHATBARLISTENER_H @@ -51,3 +52,4 @@ private: #endif // LL_LLNEARBYCHATBARLISTENER_H +#endif \ No newline at end of file diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index e9df7e5d0a..94a6732651 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -43,7 +43,10 @@ #include "llviewerwindow.h"//for screen channel position // Remove floating chat bar // #include "llnearbychatbar.h" -#include "llfloaternearbychat.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] // #include "llrootview.h" #include "lllayoutstack.h" @@ -528,7 +531,9 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, // Optional muted chat history //return; { - LLFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); // ## Zi - Post merge fixup ## + // [FS communication UI] + FSFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("fs_nearby_chat", LLSD()); // ## Zi - Post merge fixup ## + // [FS communication UI] nearby_chat->addMessage(chat_msg, true, args); return; } @@ -559,7 +564,10 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, // ## Zi - Post merge fixup ## // LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar"); // ## Zi - Post merge fixup ## // LLNearbyChat* nearby_chat = chat_bar->findChild("nearby_chat"); - LLFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); // ## Zi - Post merge fixup ## + // [FS communication UI] + //LLFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); // ## Zi - Post merge fixup ## + FSFloaterNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("fs_nearby_chat", LLSD()); // ## Zi - Post merge fixup ## + // [FS communication UI] // Build notification data LLSD notification; notification["message"] = chat_msg.mText; diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 5c464eb775..cdc9b9b823 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -38,7 +38,10 @@ #include "llavatarname.h" -class LLIMFloater; +// [FS communication UI] +//class LLIMFloater; +class FSFloaterIM; +// [FS communication UI] namespace LLNotificationsUI { @@ -415,7 +418,10 @@ private: /** * Find IM floater based on "from_id" */ - static LLIMFloater* findIMFloater(const LLNotificationPtr& notification); + // [FS communication UI] + //static LLIMFloater* findIMFloater(const LLNotificationPtr& notification); + static FSFloaterIM* findIMFloater(const LLNotificationPtr& notification); + // [FS communication UI] // [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a /** diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 907bfa9a59..c31a1ad982 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -34,11 +34,17 @@ #include "llurlaction.h" #include "llagent.h" -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloater.h" +#include "fsfloaterim.h" +// [FS communication UI] #include "llimview.h" // Remove floating chat bar // #include "llnearbychat.h" -#include "llfloaternearbychat.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] // #include "llnotificationhandler.h" #include "llnotifications.h" @@ -296,11 +302,17 @@ bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification) } // static -LLIMFloater* LLHandlerUtil::findIMFloater(const LLNotificationPtr& notification) +// [FS communication UI] +//LLIMFloater* LLHandlerUtil::findIMFloater(const LLNotificationPtr& notification) +FSFloaterIM* LLHandlerUtil::findIMFloater(const LLNotificationPtr& notification) +// [FS communication UI] { LLUUID from_id = notification->getPayload()["from_id"]; LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id); - return LLFloaterReg::findTypedInstance("impanel", session_id); + // [FS communication UI] + //return LLFloaterReg::findTypedInstance("impanel", session_id); + return LLFloaterReg::findTypedInstance("fs_impanel", session_id); + // [FS communication UI] } // static @@ -308,7 +320,10 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification) { bool res = false; - LLIMFloater* im_floater = findIMFloater(notification); + // [FS communication UI] + //LLIMFloater* im_floater = findIMFloater(notification); + FSFloaterIM* im_floater = findIMFloater(notification); + // [FS communication UI] if (im_floater != NULL) { res = im_floater->getVisible() == TRUE; @@ -321,7 +336,10 @@ bool LLHandlerUtil::isIMFloaterFocused(const LLNotificationPtr& notification) { bool res = false; - LLIMFloater* im_floater = findIMFloater(notification); + // [FS communication UI] + //LLIMFloater* im_floater = findIMFloater(notification); + FSFloaterIM* im_floater = findIMFloater(notification); + // [FS communication UI] if (im_floater != NULL) { res = im_floater->hasFocus() == TRUE; @@ -484,7 +502,10 @@ void LLHandlerUtil::logGroupNoticeToIMGroup( // static void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type) { - LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + // [FS communication UI] + //LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance(); + // [FS communication UI] if(nearby_chat) { LLChat chat_msg(notification->getMessage()); @@ -573,7 +594,10 @@ void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification) // static void LLHandlerUtil::updateIMFLoaterMesages(const LLUUID& session_id) { - LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(session_id); + // [FS communication UI] if (im_floater != NULL && im_floater->getVisible()) { im_floater->updateMessages(); diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index 79f3c7d941..9a28828176 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -31,7 +31,10 @@ // Remove floating chat bar // #include "llnearbychat.h" // #include "llnearbychatbar.h" -#include "llfloaternearbychat.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] // #include "llnotificationhandler.h" #include "llnotifications.h" @@ -98,7 +101,10 @@ bool LLTipHandler::processNotification(const LLSD& notify) LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM); // don't show toast if Nearby Chat is opened - LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + // [FS communication UI] + //LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance(); + // [FS communication UI] // Remove floating chat bar // LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance(); // if (!nearby_chat_bar->isMinimized() && nearby_chat_bar->getVisible() && nearby_chat->getVisible()) diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index f9a009677d..0ec7f83ede 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -54,7 +54,10 @@ #include "llfloaterreg.h" #include "llfocusmgr.h" #include "llhttpsender.h" -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloater.h" +#include "fsfloaterim.h" +// [FS communication UI] #include "lllocationhistory.h" #include "llimageworker.h" @@ -65,7 +68,10 @@ #include "llmoveview.h" // Remove floating chat bar // #include "llnearbychat.h" -#include "llfloaternearbychat.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] // #include "llnotifications.h" #include "llnotificationsutil.h" @@ -1686,7 +1692,10 @@ LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim, first_sim_size_x, //so I just moved nearby history loading a few states further if (gSavedPerAccountSettings.getBOOL("LogShowHistory")) { - LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + // [FS communication UI] + //LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance(); + // [FS communication UI] if (nearby_chat) nearby_chat->loadHistory(); } display_startup(); @@ -2532,7 +2541,10 @@ LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim, first_sim_size_x, LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); - LLIMFloater::initIMFloater(); + // [FS communication UI] + //LLIMFloater::initIMFloater(); + FSFloaterIM::initIMFloater(); + // [FS communication UI] display_startup(); llassert(LLPathfindingManager::getInstance() != NULL); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index b56746297a..1c58884fba 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -40,7 +40,10 @@ #include "lltrans.h" #include "llnotificationsutil.h" #include "llviewermessage.h" -#include "llimfloater.h" +// [FS communication UI] +//#include "llimfloater.h" +#include "fsfloaterim.h" +// [FS communication UI] const S32 BOTTOM_PAD = VPAD * 3; const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding @@ -561,7 +564,10 @@ LLIMToastNotifyPanel::~LLIMToastNotifyPanel() // This may happened when IM floater reloads messages, exactly when user // changes layout of IM chat log(disable/enable plaintext mode). // See EXT-6500 - LLIMFloater* im_floater = LLIMFloater::findInstance(mSessionID); + // [FS communication UI] + //LLIMFloater* im_floater = LLIMFloater::findInstance(mSessionID); + FSFloaterIM* im_floater = FSFloaterIM::findInstance(mSessionID); + // [FS communication UI] if (im_floater != NULL && !im_floater->isDead()) { mCloseNotificationOnDestroy = false; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 2182fd5f00..e139796fa9 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -126,7 +126,10 @@ #include "llmoveview.h" // Remove floating chat bar // #include "llnearbychat.h" -#include "llfloaternearbychat.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] // #include "llpanelblockedlist.h" #include "llpanelclassified.h" @@ -153,6 +156,8 @@ #include "fscontactsfloater.h" #include "fsfloaterblocklist.h" #include "fsfloatergroup.h" +#include "fsfloaterim.h" +#include "fsfloaterimcontainer.h" #include "fsfloaterplacedetails.h" #include "fsfloaterprofile.h" #include "fsfloatersearch.h" @@ -224,7 +229,10 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); // Remove floating chat bar // LLFloaterReg::add("chat_bar", "floater_chat_bar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + // [FS communication UI] + //LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("fs_nearby_chat", "floater_fs_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + // [FS communication UI] // LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); @@ -249,8 +257,12 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + // [FS communication UI] + //LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + //LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("fs_impanel", "floater_fs_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("fs_im_container", "floater_fs_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + // [FS communication UI] LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("inventory", "floater_my_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp index 1c20b778ee..0ed0109933 100644 --- a/indra/newview/llviewergesture.cpp +++ b/indra/newview/llviewergesture.cpp @@ -42,7 +42,7 @@ #include "llagent.h" // Remove floating chat bar // #include "llnearbychatbar.h" -#include "llnearbychathub.h" +#include "fsnearbychathub.h" // // Globals @@ -135,7 +135,7 @@ void LLViewerGesture::doTrigger( BOOL send_chat ) // with the gesture animation. // Remove floating chat bar // LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); - LLNearbyChat::instance().sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); + FSNearbyChat::instance().sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); } } diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 563271913b..2442c929cf 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -33,7 +33,7 @@ #include "llagentcamera.h" // Remove floating chat bar // #include "llnearbychatbar.h" -#include "llnearbychathub.h" +#include "fsnearbychathub.h" #include "lllineeditor.h" // #include "llviewercontrol.h" @@ -582,7 +582,7 @@ void start_chat( EKeystate s ) // start chat // Remove floating chat bar // LLNearbyChatBar::startChat(NULL); - LLNearbyChat::instance().showDefaultChatBar(TRUE); + FSNearbyChat::instance().showDefaultChatBar(TRUE); // } @@ -620,7 +620,7 @@ void start_gesture( EKeystate s ) // LLNearbyChat::startChat(NULL); //} - LLNearbyChat::instance().showDefaultChatBar(TRUE,"/"); + FSNearbyChat::instance().showDefaultChatBar(TRUE,"/"); // } } diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 1fce4f43c3..55ccc8ce95 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -80,7 +80,10 @@ #include #include "llinventorydefines.h" -#include "llimfloatercontainer.h" +// [FS communication UI] +//#include "llimfloatercontainer.h" +#include "fsfloaterimcontainer.h" +// [FS communication UI] class LLFileEnableUpload : public view_listener_t @@ -662,7 +665,10 @@ class LLFileCloseWindow : public view_listener_t bool handleEvent(const LLSD& userdata) { // If the IM container is focused, try to close the selected tab instead of the container -KC - LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance(); + // [FS communication UI] + //LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance(); + FSFloaterIMContainer* im_container = FSFloaterIMContainer::getInstance(); + // [FS communication UI] if (im_container && im_container->hasFocus()) { LLFloater* floater = im_container->getActiveFloater(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index dccfb53d92..2343b144c6 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -70,7 +70,10 @@ #include "llinventorypanel.h" // Remove floating chat bar // #include "llnearbychat.h" -#include "llfloaternearbychat.h" +// [FS communication UI] +//#include "llfloaternearbychat.h" +#include "fsfloaternearbychat.h" +// [FS communication UI] // #include "llnotifications.h" #include "llnotificationsutil.h" @@ -2504,7 +2507,10 @@ void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string m // Treat like a system message and put in chat history. chat.mText = av_name.getCompleteName() + ": " + message; - LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + // [FS communication UI] + //LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance(); + // [FS communication UI] if(nearby_chat) { nearby_chat->addMessage(chat); @@ -3298,7 +3304,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // Note: lie to Nearby Chat, pretending that this is NOT an IM, because // IMs from obejcts don't open IM sessions. - LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + // [FS communication UI] + //LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance(); + // [FS communication UI] if(!chat_from_system && nearby_chat) { chat.mOwnerID = from_id; @@ -7474,7 +7483,10 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp // [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7) if (caution) { - LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + // [FS communication UI] + //LLFloaterNearbyChat* nearby_chat = LLFloaterNearbyChat::getInstance(); + FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance(); + // [FS communication UI] if(nearby_chat) { LLChat chat_msg(notice.getString()); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index f7e8f03fd2..b4e56cc39a 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -202,7 +202,7 @@ // Remove floating chat bar // #include "llnearbychat.h" -#include "llnearbychathub.h" +#include "fsnearbychathub.h" // #include "llwindowlistener.h" #include "llviewerwindowlistener.h" @@ -2110,7 +2110,7 @@ void LLViewerWindow::initWorldUI() // Autohide main chat bar if applicable BOOL visible=!gSavedSettings.getBOOL("AutohideChatBar"); - LLNearbyChat::instance().showDefaultChatBar(visible); + FSNearbyChat::instance().showDefaultChatBar(visible); gSavedSettings.setBOOL("MainChatbarVisible",visible); // } @@ -2702,8 +2702,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) // // cursor with arrow keys, so allow movement // if (chat_editor->getText().empty() // || gSavedSettings.getBOOL("ArrowKeysAlwaysMove")) - if(LLNearbyChat::instance().defaultChatBarHasFocus() && - (LLNearbyChat::instance().defaultChatBarIsIdle() || + if(FSNearbyChat::instance().defaultChatBarHasFocus() && + (FSNearbyChat::instance().defaultChatBarIsIdle() || // Attempt to speed up things a little // gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))) ArrowKeysAlwaysMove)) @@ -2782,7 +2782,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) // LLNearbyChatBar::getInstance()->startChat(NULL); // return TRUE; // } - LLNearbyChat::instance().showDefaultChatBar(TRUE); + FSNearbyChat::instance().showDefaultChatBar(TRUE); return TRUE; // } diff --git a/indra/newview/rlvui.cpp b/indra/newview/rlvui.cpp index e178a94d60..1870433fe5 100644 --- a/indra/newview/rlvui.cpp +++ b/indra/newview/rlvui.cpp @@ -590,7 +590,10 @@ bool RlvUIEnabler::canViewRegionProperties() bool RlvUIEnabler::hasOpenIM(const LLUUID& idAgent) { LLUUID idSession = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, idAgent); - return (NULL != LLFloaterReg::findInstance("impanel", idSession)); + // [FS communication UI] + //return (NULL != LLFloaterReg::findInstance("impanel", idSession)); + return (NULL != LLFloaterReg::findInstance("fs_impanel", idSession)); + // [FS communication UI] } // Checked: 2011-11-04 (RLVa-1.4.4a) | Modified: RLVa-1.4.4a diff --git a/indra/newview/skins/ansastorm/xui/en/panel_toolbar_view.xml b/indra/newview/skins/ansastorm/xui/en/panel_toolbar_view.xml index 91f3942a04..6c51233421 100644 --- a/indra/newview/skins/ansastorm/xui/en/panel_toolbar_view.xml +++ b/indra/newview/skins/ansastorm/xui/en/panel_toolbar_view.xml @@ -221,7 +221,7 @@ width="80"> + parameter="fs_nearby_chat" /> + diff --git a/indra/newview/skins/default/xui/da/floater_fs_im_session.xml b/indra/newview/skins/default/xui/da/floater_fs_im_session.xml new file mode 100644 index 0000000000..4e7b9e3d5e --- /dev/null +++ b/indra/newview/skins/default/xui/da/floater_fs_im_session.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/indra/newview/skins/default/xui/de/floater_fs_im_container.xml b/indra/newview/skins/default/xui/de/floater_fs_im_container.xml new file mode 100644 index 0000000000..5ac24a3b57 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_fs_im_container.xml @@ -0,0 +1,2 @@ + + diff --git a/indra/newview/skins/default/xui/de/floater_fs_im_session.xml b/indra/newview/skins/default/xui/de/floater_fs_im_session.xml new file mode 100644 index 0000000000..f93d65937d --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_fs_im_session.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 6ced15a978..14c666d5ac 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -379,7 +379,7 @@ width="244" user_resize="true"> - - + - - + diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index 69d57d8980..9863069273 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -106,7 +106,7 @@ function="ToggleControl" parameter="FSShowMutedChatHistory"/> - - - + parameter="fs_nearby_chat" /> + parameter="fs_nearby_chat" /> + parameter="fs_im_container" /> + parameter="fs_im_container" /> diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml index 706283898f..380654b581 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml @@ -42,7 +42,7 @@ layout="topleft" name="chat_history_lp" width="318"> - + parameter="fs_nearby_chat" /> + + + diff --git a/indra/newview/skins/default/xui/en/widgets/fs_nearby_chat_control.xml b/indra/newview/skins/default/xui/en/widgets/fs_nearby_chat_control.xml new file mode 100644 index 0000000000..bdf6b3fc8a --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/fs_nearby_chat_control.xml @@ -0,0 +1,3 @@ + + + diff --git a/indra/newview/skins/default/xui/es/floater_fs_im_container.xml b/indra/newview/skins/default/xui/es/floater_fs_im_container.xml new file mode 100644 index 0000000000..1cd752e6ec --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_fs_im_container.xml @@ -0,0 +1,2 @@ + + diff --git a/indra/newview/skins/default/xui/es/floater_fs_im_session.xml b/indra/newview/skins/default/xui/es/floater_fs_im_session.xml new file mode 100644 index 0000000000..4982da9a4c --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_fs_im_session.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/metaharper/xui/en/floater_nearby_chat.xml b/indra/newview/skins/metaharper/xui/en/floater_nearby_chat.xml index 71afb541f4..c6d1fd1d8b 100644 --- a/indra/newview/skins/metaharper/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/metaharper/xui/en/floater_nearby_chat.xml @@ -109,7 +109,7 @@ function="ToggleControl" parameter="FSShowMutedChatHistory"/> - - - + parameter="fs_nearby_chat" /> + + + + + + + + diff --git a/indra/newview/skins/starlight/xui/en/panel_toolbar_view.xml b/indra/newview/skins/starlight/xui/en/panel_toolbar_view.xml index 94a2e67c94..bdc6dc39d9 100644 --- a/indra/newview/skins/starlight/xui/en/panel_toolbar_view.xml +++ b/indra/newview/skins/starlight/xui/en/panel_toolbar_view.xml @@ -219,7 +219,7 @@ width="80"> + parameter="fs_nearby_chat" /> + + + + + + + + diff --git a/indra/newview/skins/starlightcui/xui/en/panel_nearby_chat.xml b/indra/newview/skins/starlightcui/xui/en/panel_nearby_chat.xml index 2788a869a8..7f5fa8f8f7 100644 --- a/indra/newview/skins/starlightcui/xui/en/panel_nearby_chat.xml +++ b/indra/newview/skins/starlightcui/xui/en/panel_nearby_chat.xml @@ -42,7 +42,7 @@ layout="topleft" name="chat_history_lp" width="318"> - + parameter="fs_nearby_chat" /> + + + + + + + + diff --git a/indra/newview/skins/vintage/xui/en/panel_toolbar_view.xml b/indra/newview/skins/vintage/xui/en/panel_toolbar_view.xml index 785a67318a..d2cbaf3163 100644 --- a/indra/newview/skins/vintage/xui/en/panel_toolbar_view.xml +++ b/indra/newview/skins/vintage/xui/en/panel_toolbar_view.xml @@ -218,10 +218,10 @@ top="4" width="80"> + parameter="fs_nearby_chat" /> -