From 486bdf32845e248ec4923224f1f4ea5d239ac0f3 Mon Sep 17 00:00:00 2001 From: AlexanderP ProductEngine Date: Fri, 9 Nov 2012 12:45:36 +0200 Subject: CHUI-337 FIXED: To avoid confusion with a classes "...conversation..." and in accordance with the naming convention in the project, some classes and corresponding files should be renamed: LLIMConversation -> LLFloaterIMSessionTab LLIMFloater -> LLFloaterIMSession LLNearbyChat -> LLFloaterIMNearbyChat LLIMFloaterContainer -> LLFloaterIMContainer LLNearbyChatBarListener -> LLFloaterIMNearbyChatListener LLNearbyChatHandler -> LLFloaterIMNearbyChatHandler --- indra/newview/llfloaterimsessiontab.cpp | 743 ++++++++++++++++++++++++++++++++ 1 file changed, 743 insertions(+) create mode 100644 indra/newview/llfloaterimsessiontab.cpp (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp new file mode 100644 index 0000000000..a47c9177a1 --- /dev/null +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -0,0 +1,743 @@ +/** + * @file llfloaterimsessiontab.cpp + * @brief LLFloaterIMSessionTab class implements the common behavior of LNearbyChatBar + * @brief and LLFloaterIMSession for hosting both in LLIMContainer + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterimsessiontab.h" + +#include "llagent.h" +#include "llavataractions.h" +#include "llchatentry.h" +#include "llchathistory.h" +#include "llchiclet.h" +#include "llchicletbar.h" +#include "lldraghandle.h" +#include "llfloaterreg.h" +#include "llfloaterimsession.h" +#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container +#include "lllayoutstack.h" +#include "llfloaterimnearbychat.h" + +const F32 REFRESH_INTERVAL = 0.2f; + +LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) + : LLTransientDockableFloater(NULL, true, session_id) + , mIsP2PChat(false) + , mExpandCollapseBtn(NULL) + , mTearOffBtn(NULL) + , mCloseBtn(NULL) + , mSessionID(session_id.asUUID()) + , mConversationsRoot(NULL) + , mChatHistory(NULL) + , mInputEditor(NULL) + , mInputEditorTopPad(0) + , mRefreshTimer(new LLTimer()) + , mIsHostAttached(false) +{ + mSession = LLIMModel::getInstance()->findIMSession(mSessionID); + + mCommitCallbackRegistrar.add("IMSession.Menu.Action", + boost::bind(&LLFloaterIMSessionTab::onIMSessionMenuItemClicked, this, _2)); + mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem", + boost::bind(&LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck, this, _2)); + mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem", + boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck, this, _2)); + mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable", + boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable, this, _2)); + + // Zero expiry time is set only once to allow initial update. + mRefreshTimer->setTimerExpirySec(0); + mRefreshTimer->start(); +} + +LLFloaterIMSessionTab::~LLFloaterIMSessionTab() +{ + delete mRefreshTimer; +} + +//static +LLFloaterIMSessionTab* LLFloaterIMSessionTab::findConversation(const LLUUID& uuid) +{ + LLFloaterIMSessionTab* conv; + + if (uuid.isNull()) + { + conv = LLFloaterReg::findTypedInstance("nearby_chat"); + } + else + { + conv = LLFloaterReg::findTypedInstance("impanel", LLSD(uuid)); + } + + return conv; +}; + +//static +LLFloaterIMSessionTab* LLFloaterIMSessionTab::getConversation(const LLUUID& uuid) +{ + LLFloaterIMSessionTab* conv; + + if (uuid.isNull()) + { + conv = LLFloaterReg::getTypedInstance("nearby_chat"); + } + else + { + conv = LLFloaterReg::getTypedInstance("impanel", LLSD(uuid)); + } + + return conv; +}; + +void LLFloaterIMSessionTab::setVisible(BOOL visible) +{ + LLTransientDockableFloater::setVisible(visible); + + if(visible) + { + LLFloaterIMSessionTab::addToHost(mSessionID); + } + setFocus(visible); +} + +/*virtual*/ +void LLFloaterIMSessionTab::setFocus(BOOL focus) +{ + LLTransientDockableFloater::setFocus(focus); + + //Redirect focus to input editor + if (focus) + { + updateMessages(); + + if (mInputEditor) + { + mInputEditor->setFocus(TRUE); + } + } +} + + +void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id) +{ + if ((session_id.notNull() && !gIMMgr->hasSession(session_id)) + || !LLFloaterIMSessionTab::isChatMultiTab()) + { + return; + } + + // Get the floater: this will create the instance if it didn't exist + LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(session_id); + if (conversp) + { + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + + // Do not add again existing floaters + if (floater_container && !conversp->isHostAttached()) + { + conversp->setHostAttached(true); + + if (!conversp->isNearbyChat() + || gSavedSettings.getBOOL("NearbyChatIsNotTornOff")) + { + floater_container->addFloater(conversp, TRUE, LLTabContainer::END); + } + else + { + // setting of the "potential" host for Nearby Chat: this sequence sets + // LLFloater::mHostHandle = NULL (a current host), but + // LLFloater::mLastHostHandle = floater_container (a "future" host) + conversp->setHost(floater_container); + conversp->setHost(NULL); + } + // Added floaters share some state (like sort order) with their host + conversp->setSortOrder(floater_container->getSortOrder()); + } + } +} + +BOOL LLFloaterIMSessionTab::postBuild() +{ + BOOL result; + + mCloseBtn = getChild("close_btn"); + mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this)); + + mExpandCollapseBtn = getChild("expand_collapse_btn"); + mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onSlide, this)); + + mTearOffBtn = getChild("tear_off_btn"); + mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this)); + + mParticipantListPanel = getChild("speakers_list_panel"); + + // Create a root view folder for all participants + LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel); + LLFolderView::Params p(LLUICtrlFactory::getDefaultParams()); + p.rect = LLRect(0, 0, getRect().getWidth(), 0); + p.parent_panel = mParticipantListPanel; + p.listener = base_item; + p.view_model = &mConversationViewModel; + p.root = NULL; + p.use_ellipses = true; + mConversationsRoot = LLUICtrlFactory::create(p); + mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); + + // Add a scroller for the folder (participant) view + LLRect scroller_view_rect = mParticipantListPanel->getRect(); + scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams()); + scroller_params.rect(scroller_view_rect); + LLScrollContainer* scroller = LLUICtrlFactory::create(scroller_params); + scroller->setFollowsAll(); + + // Insert that scroller into the panel widgets hierarchy and folder view + mParticipantListPanel->addChild(scroller); + scroller->addChild(mConversationsRoot); + mConversationsRoot->setScrollContainer(scroller); + mConversationsRoot->setFollowsAll(); + mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox); + + + mChatHistory = getChild("chat_history"); + + mInputEditor = getChild("chat_editor"); + mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatHistory, this)); + mInputEditor->setCommitOnFocusLost( FALSE ); + mInputEditor->setPassDelete(TRUE); + mInputEditor->setFont(LLViewerChat::getChatFont()); + + mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop; + + setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE); + + buildConversationViewParticipant(); + + mSaveRect = isTornOff(); + initRectControl(); + + if (isChatMultiTab()) + { + result = LLFloater::postBuild(); + } + else + { + result = LLDockableFloater::postBuild(); + } + + refreshConversation(); + + return result; +} + +LLParticipantList* LLFloaterIMSessionTab::getParticipantList() +{ + return dynamic_cast(LLFloaterIMContainer::getInstance()->getSessionModel(mSessionID)); +} + +void LLFloaterIMSessionTab::draw() +{ + if (mRefreshTimer->hasExpired()) + { + if (getParticipantList()) + { + getParticipantList()->update(); + } + + refreshConversation(); + + // Restart the refresh timer + mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL); + } + + LLTransientDockableFloater::draw(); +} + +void LLFloaterIMSessionTab::enableDisableCallBtn() +{ + getChildView("voice_call_btn")->setEnabled( + mSessionID.notNull() + && mSession + && mSession->mSessionInitialized + && LLVoiceClient::getInstance()->voiceEnabled() + && LLVoiceClient::getInstance()->isVoiceWorking() + && mSession->mCallBackEnabled); +} + +void LLFloaterIMSessionTab::onFocusReceived() +{ + setBackgroundOpaque(true); + + if (mSessionID.notNull() && isInVisibleChain()) + { + LLIMModel::instance().sendNoUnreadMessages(mSessionID); + } + + LLTransientDockableFloater::onFocusReceived(); + + LLFloaterIMContainer* container = LLFloaterReg::getTypedInstance("im_container"); + if (container) + { + container->selectConversationPair(mSessionID, true); + } +} + +void LLFloaterIMSessionTab::onFocusLost() +{ + setBackgroundOpaque(false); + LLTransientDockableFloater::onFocusLost(); +} + +std::string LLFloaterIMSessionTab::appendTime() +{ + time_t utc_time; + utc_time = time_corrected(); + std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" + +LLTrans::getString("TimeMin")+"]"; + + LLSD substitution; + + substitution["datetime"] = (S32) utc_time; + LLStringUtil::format (timeStr, substitution); + + return timeStr; +} + +void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args) +{ + // Update the participant activity time + LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance(); + if (im_box) + { + im_box->setTimeNow(mSessionID,chat.mFromID); + } + + + LLChat& tmp_chat = const_cast(chat); + + if(tmp_chat.mTimeStr.empty()) + tmp_chat.mTimeStr = appendTime(); + + if (!chat.mMuted) + { + tmp_chat.mFromName = chat.mFromName; + LLSD chat_args; + if (args) chat_args = args; + chat_args["use_plain_text_chat_history"] = + gSavedSettings.getBOOL("PlainTextChatHistory"); + chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime"); + chat_args["show_names_for_p2p_conv"] = + !mIsP2PChat || gSavedSettings.getBOOL("IMShowNamesForP2PConv"); + + if (mChatHistory) + { + mChatHistory->appendMessage(chat, chat_args); + } + } +} + + +void LLFloaterIMSessionTab::buildConversationViewParticipant() +{ + // Clear the widget list since we are rebuilding afresh from the model + conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); + while (widget_it != mConversationsWidgets.end()) + { + removeConversationViewParticipant(widget_it->first); + // Iterators are invalidated by erase so we need to pick begin again + widget_it = mConversationsWidgets.begin(); + } + + // Get the model list + LLParticipantList* item = getParticipantList(); + if (!item) + { + // Nothing to do if the model list is empty + return; + } + + // Create the participants widgets now + LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin(); + LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd(); + while (current_participant_model != end_participant_model) + { + LLConversationItem* participant_model = dynamic_cast(*current_participant_model); + addConversationViewParticipant(participant_model); + current_participant_model++; + } +} + +void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model) +{ + // Check if the model already has an associated view + LLUUID uuid = participant_model->getUUID(); + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid); + + // If not already present, create the participant view and attach it to the root, otherwise, just refresh it + if (widget) + { + updateConversationViewParticipant(uuid); // overkill? + } + else + { + LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model); + mConversationsWidgets[uuid] = participant_view; + participant_view->addToFolder(mConversationsRoot); + participant_view->setVisible(TRUE); + refreshConversation(); + } +} + +void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& participant_id) +{ + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id); + if (widget) + { + mConversationsRoot->extractItem(widget); + delete widget; + mConversationsWidgets.erase(participant_id); + refreshConversation(); + } +} + +void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id) +{ + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id); + if (widget) + { + widget->refresh(); + } + refreshConversation(); +} + +void LLFloaterIMSessionTab::refreshConversation() +{ + // Note: We collect participants names to change the session name only in the case of ad-hoc conversations + bool is_ad_hoc = (mSession ? mSession->isAdHocSessionType() : false); + uuid_vec_t participants_uuids; // uuids vector for building the added participants name string + // For P2P chat, we still need to update the session name who may have changed (switch display name for instance) + if (mIsP2PChat && mSession) + { + participants_uuids.push_back(mSession->mOtherParticipantID); + } + + conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); + while (widget_it != mConversationsWidgets.end()) + { + // Add the participant to the list except if it's the agent itself (redundant) + if (is_ad_hoc && (widget_it->first != gAgentID)) + { + participants_uuids.push_back(widget_it->first); + } + widget_it->second->refresh(); + widget_it->second->setVisible(TRUE); + ++widget_it; + } + if (is_ad_hoc || mIsP2PChat) + { + // Build the session name and update it + std::string session_name; + if (participants_uuids.size() != 0) + { + LLAvatarActions::buildResidentsString(participants_uuids, session_name); + } + else + { + session_name = LLIMModel::instance().getName(mSessionID); + } + updateSessionName(session_name); + } + mConversationViewModel.requestSortAll(); + mConversationsRoot->arrangeAll(); + mConversationsRoot->update(); + updateHeaderAndToolbar(); + refresh(); +} + +// Copied from LLFloaterIMContainer::createConversationViewParticipant(). Refactor opportunity! +LLConversationViewParticipant* LLFloaterIMSessionTab::createConversationViewParticipant(LLConversationItem* item) +{ + LLRect panel_rect = mParticipantListPanel->getRect(); + + LLConversationViewParticipant::Params params; + params.name = item->getDisplayName(); + params.root = mConversationsRoot; + params.listener = item; + params.rect = LLRect (0, 24, panel_rect.getWidth(), 0); // *TODO: use conversation_view_participant.xml itemHeight value in lieu of 24 + params.tool_tip = params.name; + params.participant_id = item->getUUID(); + + return LLUICtrlFactory::create(params); +} + +void LLFloaterIMSessionTab::setSortOrder(const LLConversationSort& order) +{ + mConversationViewModel.setSorter(order); + mConversationsRoot->arrangeAll(); + refreshConversation(); +} + +void LLFloaterIMSessionTab::onIMSessionMenuItemClicked(const LLSD& userdata) +{ + std::string item = userdata.asString(); + + if (item == "compact_view" || item == "expanded_view") + { + gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view"); + } + else + { + bool prev_value = gSavedSettings.getBOOL(item); + gSavedSettings.setBOOL(item, !prev_value); + } + + LLFloaterIMSessionTab::processChatHistoryStyleUpdate(); +} + + +bool LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck(const LLSD& userdata) +{ + std::string item = userdata.asString(); + bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory"); + + return is_plain_text_mode? item == "compact_view" : item == "expanded_view"; +} + + +bool LLFloaterIMSessionTab::onIMShowModesMenuItemCheck(const LLSD& userdata) +{ + return gSavedSettings.getBOOL(userdata.asString()); +} + +// enable/disable states for the "show time" and "show names" items of the show-modes menu +bool LLFloaterIMSessionTab::onIMShowModesMenuItemEnable(const LLSD& userdata) +{ + std::string item = userdata.asString(); + bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory"); + bool is_not_names = (item != "IMShowNamesForP2PConv"); + return (plain_text && (is_not_names || mIsP2PChat)); +} + +void LLFloaterIMSessionTab::hideOrShowTitle() +{ + const LLFloater::Params& default_params = LLFloater::getDefaultParams(); + S32 floater_header_size = default_params.header_height; + LLView* floater_contents = getChild("contents_view"); + + LLRect floater_rect = getLocalRect(); + S32 top_border_of_contents = floater_rect.mTop - (isTornOff()? floater_header_size : 0); + LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents); + LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom); + mDragHandle->setShape(handle_rect); + mDragHandle->setVisible(isTornOff()); + floater_contents->setShape(contents_rect); +} + +void LLFloaterIMSessionTab::updateSessionName(const std::string& name) +{ + mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name); +} + +void LLFloaterIMSessionTab::hideAllStandardButtons() +{ + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + if (mButtons[i]) + { + // Hide the standard header buttons in a docked IM floater. + mButtons[i]->setVisible(false); + } + } +} + +void LLFloaterIMSessionTab::updateHeaderAndToolbar() +{ + // prevent start conversation before its container + LLFloaterIMContainer::getInstance(); + + bool is_torn_off = checkIfTornOff(); + if (!is_torn_off) + { + hideAllStandardButtons(); + } + + hideOrShowTitle(); + + // Participant list should be visible only in torn off floaters. + bool is_participant_list_visible = + is_torn_off + && gSavedSettings.getBOOL("IMShowControlPanel") + && !mIsP2PChat; + + mParticipantListPanel->setVisible(is_participant_list_visible); + + // Display collapse image (<<) if the floater is hosted + // or if it is torn off but has an open control panel. + bool is_expanded = !is_torn_off || is_participant_list_visible; + mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon")); + + // toggle floater's drag handle and title visibility + if (mDragHandle) + { + mDragHandle->setTitleVisible(is_torn_off); + } + + // The button (>>) should be disabled for torn off P2P conversations. + mExpandCollapseBtn->setEnabled(!is_torn_off || !mIsP2PChat); + + mTearOffBtn->setImageOverlay(getString(is_torn_off? "return_icon" : "tear_off_icon")); + mTearOffBtn->setToolTip(getString(!is_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window")); + + mCloseBtn->setVisible(!is_torn_off && !mIsNearbyChat); + + enableDisableCallBtn(); + + showTranslationCheckbox(); +} + +void LLFloaterIMSessionTab::reshapeChatHistory() +{ + LLRect chat_rect = mChatHistory->getRect(); + LLRect input_rect = mInputEditor->getRect(); + + int delta_height = chat_rect.mBottom - (input_rect.mTop + mInputEditorTopPad); + + chat_rect.setLeftTopAndSize(chat_rect.mLeft, chat_rect.mTop, chat_rect.getWidth(), chat_rect.getHeight() + delta_height); + mChatHistory->setShape(chat_rect); +} + +void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show) +{ + getChild("translate_chat_checkbox_lp")->setVisible(mIsNearbyChat? show : FALSE); +} + +// static +void LLFloaterIMSessionTab::processChatHistoryStyleUpdate() +{ + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); + iter != inst_list.end(); ++iter) + { + LLFloaterIMSession* floater = dynamic_cast(*iter); + if (floater) + { + floater->reloadMessages(); + } + } + + LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance("nearby_chat"); + if (nearby_chat) + { + nearby_chat->reloadMessages(); + } +} + +void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive) +{ + getChild("voice_call_btn")->setImageOverlay( + callIsActive? getString("call_btn_stop") : getString("call_btn_start")); + enableDisableCallBtn(); + +} + +void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self) +{ + LLFloaterIMContainer* host_floater = dynamic_cast(self->getHost()); + if (host_floater) + { + // Hide the messages pane if a floater is hosted in the Conversations + host_floater->collapseMessagesPane(true); + } + else ///< floater is torn off + { + if (!self->mIsP2PChat) + { + bool expand = !self->mParticipantListPanel->getVisible(); + + // Expand/collapse the IM control panel + self->mParticipantListPanel->setVisible(expand); + + gSavedSettings.setBOOL("IMShowControlPanel", expand); + + self->mExpandCollapseBtn->setImageOverlay(self->getString(expand ? "collapse_icon" : "expand_icon")); + } + } +} + +/*virtual*/ +void LLFloaterIMSessionTab::onOpen(const LLSD& key) +{ + if (!checkIfTornOff()) + { + LLFloaterIMContainer* host_floater = dynamic_cast(getHost()); + // Show the messages pane when opening a floater hosted in the Conversations + host_floater->collapseMessagesPane(false); + } +} + +// virtual +void LLFloaterIMSessionTab::onClose(bool app_quitting) +{ + // Always suppress the IM from the conversations list on close if present for any reason + if (LLFloaterIMSessionTab::isChatMultiTab()) + { + LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance(); + if (im_box) + { + im_box->removeConversationListItem(mKey); + } + } +} + +void LLFloaterIMSessionTab::onTearOffClicked() +{ + setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE); + mSaveRect = isTornOff(); + initRectControl(); + LLFloater::onClickTearOff(this); + refreshConversation(); +} + +// static +bool LLFloaterIMSessionTab::isChatMultiTab() +{ + // Restart is required in order to change chat window type. + return true; +} + +bool LLFloaterIMSessionTab::checkIfTornOff() +{ + bool isTorn = !getHost(); + + if (isTorn != isTornOff()) + { + setTornOff(isTorn); + refreshConversation(); + } + + return isTorn; +} -- cgit v1.3 From 3d42133ecb7671d8284bc0309f8df9e6e7f2df9c Mon Sep 17 00:00:00 2001 From: AlexanderP ProductEngine Date: Fri, 9 Nov 2012 17:04:21 +0200 Subject: CHUI-362 WIP (Torn off conversation name is highlighted when selected in conversation list with different conversation showing in message panel): implemented the stub panel and a control of it's visibility --- indra/newview/llfloaterimcontainer.cpp | 12 +++++++ indra/newview/llfloaterimcontainer.h | 3 ++ indra/newview/llfloaterimsessiontab.cpp | 1 + .../skins/default/xui/en/floater_im_container.xml | 42 +++++++++++++++++++++- 4 files changed, 57 insertions(+), 1 deletion(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 2789b78c2d..994a76189a 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -141,6 +141,8 @@ BOOL LLFloaterIMContainer::postBuild() // mTabContainer will be initialized in LLMultiFloater::addChild() setTabContainer(getChild("im_box_tab_container")); + mStubPanel = getChild("stub_panel"); + mStubTextBox = getChild("stub_textbox"); mConversationsStack = getChild("conversations_stack"); mConversationsPane = getChild("conversations_layout_panel"); @@ -494,6 +496,16 @@ void LLFloaterIMContainer::tabClose() } } +void LLFloaterIMContainer::showStub(bool stub_is_visible) +{ + if (stub_is_visible) + { + mTabContainer->hideAllTabs(); + } + + mStubPanel->setVisible(stub_is_visible); +} + void LLFloaterIMContainer::setVisible(BOOL visible) { LLFloaterIMNearbyChat* nearby_chat; if (visible) diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index f65e946dad..a09cde60f5 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -71,6 +71,7 @@ public: BOOL selectConversationPair(const LLUUID& session_id, bool select_widget); /*virtual*/ void tabClose(); + void showStub(bool visible); static LLFloater* getCurrentVoiceFloater(); static LLFloaterIMContainer* findInstance(); @@ -146,6 +147,8 @@ private: void openNearbyChat(); LLButton* mExpandCollapseBtn; + LLPanel* mStubPanel; + LLTextBox* mStubTextBox; LLLayoutPanel* mMessagesPane; LLLayoutPanel* mConversationsPane; LLLayoutStack* mConversationsStack; diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index c39319b373..3a1cc2880a 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -313,6 +313,7 @@ void LLFloaterIMSessionTab::onFocusReceived() if (container) { container->selectConversationPair(mSessionID, true); + container->showStub(! getHost()); } } diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index 590ce45c33..e3db3d52ed 100644 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -124,7 +124,47 @@ left="0" name="im_box_tab_container" top="0" - width="412"/> + width="412"> + + + This conversation is in a separate window. + + + Bring it back. + + + -- cgit v1.3 From 99181a9777b7e42ed6e863a074789f37aa6b43f8 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 9 Nov 2012 19:06:00 -0800 Subject: CHUI-479 : WIP : Fixed the missing agent appearance in torn off dialogs by adding a consistency check and rebuild. --- indra/newview/llfloaterimsessiontab.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index a47c9177a1..c39319b373 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -263,11 +263,21 @@ void LLFloaterIMSessionTab::draw() { if (mRefreshTimer->hasExpired()) { - if (getParticipantList()) + LLParticipantList* item = getParticipantList(); + if (item) { - getParticipantList()->update(); + // Update all model items + item->update(); + // If the model and view list diverge in count, rebuild + // Note: this happens sometimes right around init (add participant events fire but get dropped) and is the cause + // of missing participants, often, the user agent itself. As there will be no other event fired, there's + // no other choice but get those inconsistencies regularly (and lightly) checked and scrubbed. + if (item->getChildrenCount() != mConversationsWidgets.size()) + { + buildConversationViewParticipant(); + } } - + refreshConversation(); // Restart the refresh timer @@ -376,7 +386,7 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant() LLParticipantList* item = getParticipantList(); if (!item) { - // Nothing to do if the model list is empty + // Nothing to do if the model list is inexistent return; } @@ -470,7 +480,8 @@ void LLFloaterIMSessionTab::refreshConversation() session_name = LLIMModel::instance().getName(mSessionID); } updateSessionName(session_name); - } + } + mConversationViewModel.requestSortAll(); mConversationsRoot->arrangeAll(); mConversationsRoot->update(); -- cgit v1.3 From e15921e42b4ac14504b22b0acbb349aa6d19664b Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 14 Nov 2012 10:37:52 -0800 Subject: CHUI-479 : WIP : Small refactoring to allow participant to be added to session whether or not its parent folder is. --- indra/newview/llconversationview.cpp | 21 +++++++++++++-------- indra/newview/llconversationview.h | 1 + indra/newview/llfloaterimsessiontab.cpp | 1 + 3 files changed, 15 insertions(+), 8 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 295dd2ae6d..ad334869fb 100755 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -460,21 +460,26 @@ void LLConversationViewParticipant::refresh() void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder) { - //Add the item to the folder (conversation) + // Add the item to the folder (conversation) LLFolderViewItem::addToFolder(folder); - //Now retrieve the folder (conversation) UUID, which is the speaker session + // Retrieve the folder (conversation) UUID, which is also the speaker session UUID LLConversationItem* vmi = this->getParentFolder() ? dynamic_cast(this->getParentFolder()->getViewModelItem()) : NULL; - if(vmi) + if (vmi) { - //Allows speaking icon image to be loaded based on mUUID - mAvatarIcon->setValue(mUUID); - - //Allows the speaker indicator to be activated based on the user and conversation - mSpeakingIndicator->setSpeakerId(mUUID, vmi->getUUID()); + addToSession(vmi->getUUID()); } } +void LLConversationViewParticipant::addToSession(const LLUUID& session_id) +{ + //Allows speaking icon image to be loaded based on mUUID + mAvatarIcon->setValue(mUUID); + + //Allows the speaker indicator to be activated based on the user and conversation + mSpeakingIndicator->setSpeakerId(mUUID, session_id); +} + void LLConversationViewParticipant::onInfoBtnClick() { LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mUUID)); diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index cc6995c207..3610ac67de 100755 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -121,6 +121,7 @@ public: bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); } virtual void refresh(); void addToFolder(LLFolderViewFolder* folder); + void addToSession(const LLUUID& session_id); /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index c39319b373..e78422145d 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -417,6 +417,7 @@ void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* p LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model); mConversationsWidgets[uuid] = participant_view; participant_view->addToFolder(mConversationsRoot); + participant_view->addToSession(mSessionID); participant_view->setVisible(TRUE); refreshConversation(); } -- cgit v1.3 From 70b9dd6ee6af483bf1c96631bb25fd6a3703b351 Mon Sep 17 00:00:00 2001 From: William Todd Stinson Date: Thu, 15 Nov 2012 10:41:53 -0800 Subject: CHUI-524: FIX Removing a function call that results in a circular logic loop and an eventual stack overflow crash. --- indra/newview/llfloaterimsessiontab.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 3a1cc2880a..26a97ea422 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -313,7 +313,13 @@ void LLFloaterIMSessionTab::onFocusReceived() if (container) { container->selectConversationPair(mSessionID, true); + // XXX stinson 11/15/2012 : calling show stub from this focus handler results in a circular + // logic loop of function calls that eventually result in a stack overflow. + // See CHUI-524 for documentation +#define XXX_STINSON_HACK_CHUI_524 1 +#if !XXX_STINSON_HACK_CHUI_524 container->showStub(! getHost()); +#endif } } -- cgit v1.3 From e89616aac812a7c6080d577f8a284f6df56a51ea Mon Sep 17 00:00:00 2001 From: William Todd Stinson Date: Thu, 15 Nov 2012 15:11:22 -0800 Subject: Backed out changeset: 80bab29003f8 Removing hack fix for CHUI-524. --- indra/newview/llfloaterimsessiontab.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 26a97ea422..3a1cc2880a 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -313,13 +313,7 @@ void LLFloaterIMSessionTab::onFocusReceived() if (container) { container->selectConversationPair(mSessionID, true); - // XXX stinson 11/15/2012 : calling show stub from this focus handler results in a circular - // logic loop of function calls that eventually result in a stack overflow. - // See CHUI-524 for documentation -#define XXX_STINSON_HACK_CHUI_524 1 -#if !XXX_STINSON_HACK_CHUI_524 container->showStub(! getHost()); -#endif } } -- cgit v1.3 From 16f5a67e6550c2041b69b5c8523ad9884d7110f1 Mon Sep 17 00:00:00 2001 From: maksymsproductengine Date: Thu, 15 Nov 2012 23:35:14 +0200 Subject: CHUI-442 FIXED Nearby chat does not open conversations floater when clicking first nearby chat toast in a session --- indra/newview/llfloaterimsessiontab.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 3a1cc2880a..da77ca0079 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -165,6 +165,11 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id) || gSavedSettings.getBOOL("NearbyChatIsNotTornOff")) { floater_container->addFloater(conversp, TRUE, LLTabContainer::END); + + if (!floater_container->getVisible()) + { + LLFloaterReg::toggleInstanceOrBringToFront("im_container"); + } } else { -- cgit v1.3 From ed3f43aec48097c56d617a8948d2577624762a88 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 16 Nov 2012 11:14:12 -0800 Subject: CHUI-479 : WIP : Tracing of LLIMModel::processSessionInitializedReply (to be deleted). --- indra/newview/llfloaterimcontainer.cpp | 25 +++++++++++++++++++++++-- indra/newview/llfloaterimsessiontab.cpp | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 2707e3dcbb..af090338d7 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -98,6 +98,7 @@ LLFloaterIMContainer::~LLFloaterIMContainer() void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) { + llinfos << "Merov debug : sessionAdded, uuid = " << session_id << ", name = " << name << llendl; addConversationListItem(session_id); LLFloaterIMSessionTab::addToHost(session_id); } @@ -109,14 +110,33 @@ void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std: void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id) { + llinfos << "Merov debug : sessionVoiceOrIMStarted, uuid = " << session_id << llendl; addConversationListItem(session_id); LLFloaterIMSessionTab::addToHost(session_id); } void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) { - // *TODO: We should do this *without* delete and recreate - addConversationListItem(new_session_id, removeConversationListItem(old_session_id)); + llinfos << "Merov debug : sessionIDUpdated, old_session_id = " << old_session_id << ", new_session_id = " << new_session_id << llendl; + // Retrieve the session LLFloaterIMSessionTab + // just close it: that should erase the mSession, close the tab and remove the list item + // *TODO : take the mSessions element (pointing to the tab) out of the list + //bool change_focus = removeConversationListItem(old_session_id); + // *TODO : detach the old tab from the host + // *TODO : delete the tab (that's one thing that's reentrant) + LLFloater* floaterp = get_ptr_in_map(mSessions, old_session_id); + if (floaterp) + { + llinfos << "Merov debug : closeFloater, start" << llendl; + floaterp->closeFloater(); + llinfos << "Merov debug : closeFloater, end" << llendl; + } + bool change_focus = false; + llinfos << "Merov debug : addConversationListItem" << llendl; + addConversationListItem(new_session_id, change_focus); + llinfos << "Merov debug : addToHost" << llendl; + LLFloaterIMSessionTab::addToHost(new_session_id); + llinfos << "Merov debug : end sessionIDUpdated" << llendl; } void LLFloaterIMContainer::sessionRemoved(const LLUUID& session_id) @@ -1300,6 +1320,7 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID& bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus) { + llinfos << "Merov debug : removeConversationListItem, uuid = " << uuid << llendl; // Delete the widget and the associated conversation item // Note : since the mConversationsItems is also the listener to the widget, deleting // the widget will also delete its listener diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 6b13f5f381..6fbc713590 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -721,6 +721,7 @@ void LLFloaterIMSessionTab::onClose(bool app_quitting) LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance(); if (im_box) { + llinfos << "Merov debug : LLFloaterIMSessionTab::onClose, mKey = " << mKey << llendl; im_box->removeConversationListItem(mKey); } } -- cgit v1.3 From e298c2ded8e25a28127c668cf30a74a25c139041 Mon Sep 17 00:00:00 2001 From: AlexanderP ProductEngine Date: Fri, 16 Nov 2012 22:36:12 +0200 Subject: CHUI-487, CHUI-488 FIXED (Enable flashing FUI button behavior and Implement Flashing Conversations panel line item behavior): implemented FUI button flashing; clean up code --- indra/llui/CMakeLists.txt | 2 + indra/llui/llbutton.cpp | 46 ++++++++---------- indra/llui/llbutton.h | 6 +-- indra/llui/llflashtimer.cpp | 80 ++++++++++++++++++++++++++++++++ indra/llui/llflashtimer.h | 67 +++++++++++++++++++++++++++ indra/llui/llfolderviewitem.cpp | 15 +++--- indra/llui/llfolderviewitem.h | 3 +- indra/llui/lltabcontainer.cpp | 4 +- indra/newview/CMakeLists.txt | 2 - indra/newview/llflashtimer.cpp | 82 --------------------------------- indra/newview/llflashtimer.h | 66 -------------------------- indra/newview/llfloaterimcontainer.cpp | 14 ++++-- indra/newview/llfloaterimcontainer.h | 2 +- indra/newview/llfloaterimsessiontab.cpp | 10 ++++ 14 files changed, 206 insertions(+), 193 deletions(-) create mode 100644 indra/llui/llflashtimer.cpp create mode 100644 indra/llui/llflashtimer.h delete mode 100644 indra/newview/llflashtimer.cpp delete mode 100644 indra/newview/llflashtimer.h (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 80cec6c9f3..ccc7aa8cec 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -47,6 +47,7 @@ set(llui_SOURCE_FILES lleditmenuhandler.cpp llf32uictrl.cpp llfiltereditor.cpp + llflashtimer.cpp llflatlistview.cpp llfloater.cpp llfloaterreg.cpp @@ -153,6 +154,7 @@ set(llui_HEADER_FILES lleditmenuhandler.h llf32uictrl.h llfiltereditor.h + llflashtimer.h llflatlistview.h llfloater.h llfloaterreg.h diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 3b9076ee54..8a34e221b1 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -170,17 +170,18 @@ LLButton::LLButton(const LLButton::Params& p) mMouseUpSignal(NULL), mHeldDownSignal(NULL), mUseDrawContextAlpha(p.use_draw_context_alpha), - mHandleRightMouse(p.handle_right_mouse), - mButtonFlashCount(p.button_flash_count), - mButtonFlashRate(p.button_flash_rate) + mHandleRightMouse(p.handle_right_mouse) { + // If optional parameter "p.button_flash_count" is not provided, LLFlashTimer will be + // used instead it a "default" value from gSavedSettings.getS32("FlashCount")). + // Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod"); + S32 flash_count = p.button_flash_count || 0; + F32 flash_rate = p.button_flash_rate || 0.0; // + mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate); + static LLUICachedControl llbutton_orig_h_pad ("UIButtonOrigHPad", 0); static Params default_params(LLUICtrlFactory::getDefaultParams()); -if (this->getName() == "chat") -{ -bool q = false; -q = !q; -} + if (!p.label_selected.isProvided()) { mSelectedLabel = mUnselectedLabel; @@ -271,6 +272,7 @@ LLButton::~LLButton() delete mMouseDownSignal; delete mMouseUpSignal; delete mHeldDownSignal; + delete mFlashingTimer; } // HACK: Committing a button is the same as instantly clicking it. @@ -595,22 +597,11 @@ void LLButton::draw() { static LLCachedControl sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true); F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency(); - bool flash = FALSE; - if( mFlashing) - { - if ( sEnableButtonFlashing) - { - F32 elapsed = mFlashingTimer.getElapsedTimeF32(); - S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f); - // flash on or off? - flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f); - } - else - { // otherwise just highlight button in flash color - flash = true; - } - } + mFlashing = mFlashingTimer->isFlashing(); + + bool flash = mFlashing && + (!sEnableButtonFlashing || mFlashingTimer->isHighlight()); bool pressed_by_keyboard = FALSE; if (hasFocus()) @@ -955,10 +946,13 @@ void LLButton::setToggleState(BOOL b) void LLButton::setFlashing( BOOL b ) { - if ((bool)b != mFlashing) + if (b) + { + mFlashingTimer->startFlashing(); + } + else { - mFlashing = b; - mFlashingTimer.reset(); + mFlashingTimer->stopFlashing(); } } diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index deaa0823c6..92548298f5 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -30,6 +30,7 @@ #include "lluuid.h" #include "llbadgeowner.h" #include "llcontrol.h" +#include "llflashtimer.h" #include "lluictrl.h" #include "v4color.h" #include "llframetimer.h" @@ -201,6 +202,7 @@ public: void setHighlight(bool b); void setFlashing( BOOL b ); BOOL getFlashing() const { return mFlashing; } + LLFlashTimer* getFlashTimer() {return mFlashingTimer;} void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } LLFontGL::HAlign getHAlign() const { return mHAlign; } @@ -285,8 +287,6 @@ protected: LLFrameTimer mMouseDownTimer; bool mNeedsHighlight; - S32 mButtonFlashCount; - F32 mButtonFlashRate; void drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size); void resetMouseDownTimer(); @@ -373,7 +373,7 @@ protected: bool mForcePressedState; bool mDisplayPressedState; - LLFrameTimer mFlashingTimer; + LLFlashTimer* mFlashingTimer; bool mHandleRightMouse; }; diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp new file mode 100644 index 0000000000..c572a83ff5 --- /dev/null +++ b/indra/llui/llflashtimer.cpp @@ -0,0 +1,80 @@ +/** + * @file llflashtimer.cpp + * @brief LLFlashTimer class implementation + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#include "../newview/llviewerprecompiledheaders.h" + +#include "llflashtimer.h" +#include "../newview/llviewercontrol.h" +#include "lleventtimer.h" + +LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period) + : LLEventTimer(period) + , mCallback(cb) + , mCurrentTickCount(0) + , mIsFlashing(false) +{ + mEventTimer.stop(); + + // By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973. + // Due to Timer is implemented as derived class from EventTimer it is impossible to change period + // in runtime. So, both settings are made as required restart. + mFlashCount = 2 * ((count>0)? count : gSavedSettings.getS32("FlashCount")); + if (mPeriod<=0) + { + mPeriod = gSavedSettings.getF32("FlashPeriod"); + } +} + +BOOL LLFlashTimer::tick() +{ + mIsHighlight = !(mCurrentTickCount % 2); + if (mCallback) + { + mCallback(mIsHighlight); + } + + if (++mCurrentTickCount >= mFlashCount) + { + mEventTimer.stop(); + } + + return FALSE; +} + +void LLFlashTimer::startFlashing() +{ + mCurrentTickCount = 0; + mIsFlashing = true; + mEventTimer.start(); +} + +void LLFlashTimer::stopFlashing() +{ + mIsFlashing = false; + mIsHighlight = false; + mEventTimer.stop(); +} + + diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h new file mode 100644 index 0000000000..2ef6ebcc8a --- /dev/null +++ b/indra/llui/llflashtimer.h @@ -0,0 +1,67 @@ +/** + * @file llflashtimer.h + * @brief LLFlashTimer class implementation + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_FLASHTIMER_H +#define LL_FLASHTIMER_H + +#include "lleventtimer.h" + +class LLFlashTimer : public LLEventTimer +{ +public: + + typedef boost::function callback_t; + + /** + * Constructor. + * + * @param count - how many times callback should be called (twice to not change original state) + * @param period - how frequently callback should be called + * @param cb - callback to be called each tick + */ + LLFlashTimer(callback_t cb = NULL, S32 count = 0, F32 period = 0.0); + ~LLFlashTimer() {}; + + /*virtual*/ BOOL tick(); + + void startFlashing(); + void stopFlashing(); + + bool isFlashing() {return mIsFlashing;} + bool isHighlight() {return mIsHighlight;} + +private: + callback_t mCallback; + /** + * How many times parent will blink. + */ + S32 mFlashCount; + S32 mCurrentTickCount; + bool mIsHighlight; + bool mIsFlashing; +}; + +#endif /* LL_FLASHTIMER_H */ diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 90568f344a..d65f53cd4d 100755 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -23,8 +23,9 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ +#include "../newview/llviewerprecompiledheaders.h" -#include "../newview/llflashtimer.h" +#include "llflashtimer.h" #include "linden_common.h" #include "llfolderviewitem.h" @@ -164,17 +165,19 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) } } +// Destroys the object +LLFolderViewItem::~LLFolderViewItem() +{ + delete mFlashTimer; + mViewModelItem = NULL; +} + BOOL LLFolderViewItem::postBuild() { refresh(); return TRUE; } -// Destroys the object -LLFolderViewItem::~LLFolderViewItem( void ) -{ - mViewModelItem = NULL; -} LLFolderView* LLFolderViewItem::getRoot() { diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index c16d65206f..c8d6c37b04 100755 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -26,10 +26,10 @@ #ifndef LLFOLDERVIEWITEM_H #define LLFOLDERVIEWITEM_H +#include "llflashtimer.h" #include "llview.h" #include "lluiimage.h" -class LLFlashTimer; class LLFolderView; class LLFolderViewModelItem; class LLFolderViewFolder; @@ -163,6 +163,7 @@ public: S32 getIconPad(); S32 getTextPad(); + LLFlashTimer* getFlashTimer() {return mFlashTimer;} // If 'selection' is 'this' then note that otherwise ignore. // Returns TRUE if this item ends up being selected. virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus); diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index c24eb2ee90..d1f77830a6 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -506,8 +506,8 @@ void LLTabContainer::draw() } } - mPrevArrowBtn->setFlashing(FALSE); - mNextArrowBtn->setFlashing(FALSE); + mPrevArrowBtn->getFlashTimer()->stopFlashing(); + mNextArrowBtn->getFlashTimer()->stopFlashing(); } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 574fdc495a..f652c9e50c 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -178,7 +178,6 @@ set(viewer_SOURCE_FILES llfilepicker.cpp llfilteredwearablelist.cpp llfirstuse.cpp - llflashtimer.cpp llflexibleobject.cpp llfloaterabout.cpp llfloaterbvhpreview.cpp @@ -763,7 +762,6 @@ set(viewer_HEADER_FILES llfilepicker.h llfilteredwearablelist.h llfirstuse.h - llflashtimer.h llflexibleobject.h llfloaterabout.h llfloaterbvhpreview.h diff --git a/indra/newview/llflashtimer.cpp b/indra/newview/llflashtimer.cpp deleted file mode 100644 index 2feacfa218..0000000000 --- a/indra/newview/llflashtimer.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file llflashtimer.cpp - * @brief LLFlashTimer class implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2012, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - - -#include "llviewerprecompiledheaders.h" - -#include "llflashtimer.h" -#include "llviewercontrol.h" -#include "lleventtimer.h" - -LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period) - : LLEventTimer(period) - , mCallback(cb) - , mCurrentTickCount(0) - , mIsFlashing(false) -{ - mEventTimer.stop(); - - // By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973. - // Due to Timer is implemented as derived class from EventTimer it is impossible to change period - // in runtime. So, both settings are made as required restart. - mFlashCount = 2 * ((count>0)? count : gSavedSettings.getS32("FlashCount")); - if (mPeriod<=0) - { - mPeriod = gSavedSettings.getF32("FlashPeriod"); - } -} - -BOOL LLFlashTimer::tick() -{ - mIsHighlight = !(mCurrentTickCount % 2); - if (mCallback) - { - mCallback(mIsHighlight); - } - - if (++mCurrentTickCount >= mFlashCount) - { - mEventTimer.stop(); - } - - return FALSE; -} - -void LLFlashTimer::startFlashing() -{ - mCurrentTickCount = 0; - mIsFlashing = true; - mEventTimer.start(); -} - -void LLFlashTimer::stopFlashing() -{ - mIsFlashing = false; - mIsHighlight = false; - mEventTimer.stop(); -} - - diff --git a/indra/newview/llflashtimer.h b/indra/newview/llflashtimer.h deleted file mode 100644 index c030edfc52..0000000000 --- a/indra/newview/llflashtimer.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file llflashtimer.h - * @brief LLFlashTimer class implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2012, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_FLASHTIMER_H -#define LL_FLASHTIMER_H - -#include "lleventtimer.h" - -class LLFlashTimer : public LLEventTimer -{ -public: - - typedef boost::function callback_t; - - /** - * Constructor. - * - * @param count - how many times callback should be called (twice to not change original state) - * @param period - how frequently callback should be called - * @param cb - callback to be called each tick - */ - LLFlashTimer(callback_t cb = NULL, S32 count = 0, F32 period = 0.0); - ~LLFlashTimer() {}; - - /*virtual*/ BOOL tick(); - - void startFlashing(); - void stopFlashing(); - bool isFlashing() {return mIsFlashing;} - bool isHighlight() {return mIsHighlight;} - -private: - callback_t mCallback; - /** - * How many times Well will blink. - */ - S32 mFlashCount; - S32 mCurrentTickCount; - bool mIsHighlight; - bool mIsFlashing; -}; - -#endif /* LL_FLASHTIMER_H */ diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index da6f3a484d..90ddeef5bb 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -41,6 +41,7 @@ #include "llcallbacklist.h" #include "llgroupactions.h" #include "llgroupiconctrl.h" +#include "llflashtimer.h" #include "llfloateravatarpicker.h" #include "llfloaterpreference.h" #include "llimview.h" @@ -1594,17 +1595,22 @@ void LLFloaterIMContainer::reSelectConversation() { selectFloater(session_floater); } - } -void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id) +void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes) { LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id); if (widget) { - widget->; + if (is_flashes) + { + widget->getFlashTimer()->startFlashing(); + } + else + { + widget->getFlashTimer()->stopFlashing(); + } } - } // EOF diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 443688668b..9112b54018 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -164,7 +164,7 @@ public: void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id); void setNearbyDistances(); void reSelectConversation(); - void flashConversationItemWidget(const LLUUID& session_id); + void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes); private: LLConversationViewSession* createConversationItemWidget(LLConversationItem* item); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 69b42cdd6d..42e7e6cb55 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -40,6 +40,7 @@ #include "llfloaterimsession.h" #include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container #include "lllayoutstack.h" +#include "lltoolbarview.h" #include "llfloaterimnearbychat.h" const F32 REFRESH_INTERVAL = 0.2f; @@ -328,11 +329,20 @@ std::string LLFloaterIMSessionTab::appendTime() void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args) { + // Update the participant activity time LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance(); if (im_box) { im_box->setTimeNow(mSessionID,chat.mFromID); + + // TODO: Warning! The next two lines of code are included below only temporarily + // to demonstrate the correct format call the appropriate functions. + // They should be moved to the right places when working on CHUI-486. ~Alex ProductEngine. + // ---- start demo ---- + im_box->flashConversationItemWidget(mSessionID, true); // flashing of the conversation's item + gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat" + // ---- end demo ----- } -- cgit v1.3 From 249b44d01ced4ba5bb8b8b9147d7836a7d492d5b Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 16 Nov 2012 21:01:57 -0800 Subject: CHUI-479 : Fixed : Rebuild the root on the LLFloaterIMSession when modifying the session ID --- indra/newview/llfloaterimcontainer.cpp | 42 ++++++++----------- indra/newview/llfloaterimsessiontab.cpp | 72 +++++++++++++++++---------------- indra/newview/llfloaterimsessiontab.h | 1 + 3 files changed, 55 insertions(+), 60 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index af090338d7..bd692aa850 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -117,26 +117,20 @@ void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id) void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) { - llinfos << "Merov debug : sessionIDUpdated, old_session_id = " << old_session_id << ", new_session_id = " << new_session_id << llendl; - // Retrieve the session LLFloaterIMSessionTab - // just close it: that should erase the mSession, close the tab and remove the list item - // *TODO : take the mSessions element (pointing to the tab) out of the list - //bool change_focus = removeConversationListItem(old_session_id); - // *TODO : detach the old tab from the host - // *TODO : delete the tab (that's one thing that's reentrant) - LLFloater* floaterp = get_ptr_in_map(mSessions, old_session_id); - if (floaterp) - { - llinfos << "Merov debug : closeFloater, start" << llendl; - floaterp->closeFloater(); - llinfos << "Merov debug : closeFloater, end" << llendl; - } - bool change_focus = false; - llinfos << "Merov debug : addConversationListItem" << llendl; + // The general strategy when a session id is modified is to delete all related objects and create them anew. + + // Note however that the LLFloaterIMSession has its session id updated through a call to sessionInitReplyReceived() + // and do not need to be deleted and recreated (trying this creates loads of problems). We do need however to suppress + // its related mSessions record as it's indexed with the wrong id. + // Grabbing the updated LLFloaterIMSession and readding it in mSessions will eventually be done by addConversationListItem(). + mSessions.erase(old_session_id); + + // Delete the model and participants related to the old session + bool change_focus = removeConversationListItem(old_session_id); + + // Create a new conversation with the new id addConversationListItem(new_session_id, change_focus); - llinfos << "Merov debug : addToHost" << llendl; LLFloaterIMSessionTab::addToHost(new_session_id); - llinfos << "Merov debug : end sessionIDUpdated" << llendl; } void LLFloaterIMContainer::sessionRemoved(const LLUUID& session_id) @@ -483,14 +477,14 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event) else if (type == "update_session") { session_view->refresh(); - if (conversation_floater) - { - conversation_floater->refreshConversation(); - } } mConversationViewModel.requestSortAll(); mConversationsRoot->arrangeAll(); + if (conversation_floater) + { + conversation_floater->refreshConversation(); + } return false; } @@ -1253,10 +1247,6 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID& return item_it->second; } - // Remove the conversation item that might exist already: it'll be recreated anew further down anyway - // and nothing wrong will happen removing it if it doesn't exist - removeConversationListItem(uuid,false); - // Create a conversation session model LLConversationItemSession* item = NULL; LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid)); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 6fbc713590..22131eac49 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -52,6 +52,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) , mCloseBtn(NULL) , mSessionID(session_id.asUUID()) , mConversationsRoot(NULL) + , mScroller(NULL) , mChatHistory(NULL) , mInputEditor(NULL) , mInputEditorTopPad(0) @@ -68,10 +69,6 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck, this, _2)); mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable", boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable, this, _2)); - - // Zero expiry time is set only once to allow initial update. - mRefreshTimer->setTimerExpirySec(0); - mRefreshTimer->start(); } LLFloaterIMSessionTab::~LLFloaterIMSessionTab() @@ -195,33 +192,16 @@ BOOL LLFloaterIMSessionTab::postBuild() mParticipantListPanel = getChild("speakers_list_panel"); - // Create a root view folder for all participants - LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel); - LLFolderView::Params p(LLUICtrlFactory::getDefaultParams()); - p.rect = LLRect(0, 0, getRect().getWidth(), 0); - p.parent_panel = mParticipantListPanel; - p.listener = base_item; - p.view_model = &mConversationViewModel; - p.root = NULL; - p.use_ellipses = true; - mConversationsRoot = LLUICtrlFactory::create(p); - mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); - // Add a scroller for the folder (participant) view LLRect scroller_view_rect = mParticipantListPanel->getRect(); scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams()); scroller_params.rect(scroller_view_rect); - LLScrollContainer* scroller = LLUICtrlFactory::create(scroller_params); - scroller->setFollowsAll(); - - // Insert that scroller into the panel widgets hierarchy and folder view - mParticipantListPanel->addChild(scroller); - scroller->addChild(mConversationsRoot); - mConversationsRoot->setScrollContainer(scroller); - mConversationsRoot->setFollowsAll(); - mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox); + mScroller = LLUICtrlFactory::create(scroller_params); + mScroller->setFollowsAll(); + // Insert that scroller into the panel widgets hierarchy + mParticipantListPanel->addChild(mScroller); mChatHistory = getChild("chat_history"); @@ -235,8 +215,6 @@ BOOL LLFloaterIMSessionTab::postBuild() setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE); - buildConversationViewParticipant(); - mSaveRect = isTornOff(); initRectControl(); @@ -249,8 +227,14 @@ BOOL LLFloaterIMSessionTab::postBuild() result = LLDockableFloater::postBuild(); } + // Now ready to build the conversation and participants list + buildConversationViewParticipant(); refreshConversation(); - + + // Zero expiry time is set only once to allow initial update. + mRefreshTimer->setTimerExpirySec(0); + mRefreshTimer->start(); + return result; } @@ -276,9 +260,8 @@ void LLFloaterIMSessionTab::draw() { buildConversationViewParticipant(); } + refreshConversation(); } - - refreshConversation(); // Restart the refresh timer mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL); @@ -390,7 +373,31 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant() // Nothing to do if the model list is inexistent return; } - + + // Create or recreate the root folder: this is a dummy folder (not shown) but required by the LLFolderView architecture + // We need to redo this when rebuilding as the session id (mSessionID) *may* have changed + if (mConversationsRoot) + { + // Remove the old root if any + mScroller->removeChild(mConversationsRoot); + } + // Create the root using an ad-hoc base item + LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel); + LLFolderView::Params p(LLUICtrlFactory::getDefaultParams()); + p.rect = LLRect(0, 0, getRect().getWidth(), 0); + p.parent_panel = mParticipantListPanel; + p.listener = base_item; + p.view_model = &mConversationViewModel; + p.root = NULL; + p.use_ellipses = true; + mConversationsRoot = LLUICtrlFactory::create(p); + mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); + // Attach that root to the scroller + mScroller->addChild(mConversationsRoot); + mConversationsRoot->setScrollContainer(mScroller); + mConversationsRoot->setFollowsAll(); + mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox); + // Create the participants widgets now LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin(); LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd(); @@ -420,7 +427,6 @@ void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* p participant_view->addToFolder(mConversationsRoot); participant_view->addToSession(mSessionID); participant_view->setVisible(TRUE); - refreshConversation(); } } @@ -432,7 +438,6 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part mConversationsRoot->extractItem(widget); delete widget; mConversationsWidgets.erase(participant_id); - refreshConversation(); } } @@ -443,7 +448,6 @@ void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& part { widget->refresh(); } - refreshConversation(); } void LLFloaterIMSessionTab::refreshConversation() diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 8f5a8c2c1b..b765d121de 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -146,6 +146,7 @@ protected: conversations_widgets_map mConversationsWidgets; LLConversationViewModel mConversationViewModel; LLFolderView* mConversationsRoot; + LLScrollContainer* mScroller; LLChatHistory* mChatHistory; LLChatEntry* mInputEditor; -- cgit v1.3 From 2d25eb18adc0c2c97c63a8e02f2274362672137c Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sat, 17 Nov 2012 13:24:41 -0800 Subject: CHUI-479 : Clean up unecessary tracking code --- indra/newview/llconversationview.cpp | 8 -------- indra/newview/llfloaterimcontainer.cpp | 2 -- indra/newview/llfloaterimsessiontab.cpp | 1 - indra/newview/lloutputmonitorctrl.cpp | 27 ++------------------------- indra/newview/llspeakingindicatormanager.cpp | 8 -------- indra/newview/llspeakingindicatormanager.h | 2 +- 6 files changed, 3 insertions(+), 45 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index d971c943f0..64618fabba 100755 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -308,7 +308,6 @@ void LLConversationViewSession::refresh() } // Update all speaking indicators - llinfos << "Merov debug : LLConversationViewSession::refresh, updateSpeakingIndicators" << llendl; LLSpeakingIndicatorManager::updateSpeakingIndicators(); // Do the regular upstream refresh @@ -455,7 +454,6 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height) void LLConversationViewParticipant::onCurrentVoiceSessionChanged(const LLUUID& session_id) { - llinfos << "Merov debug : onCurrentVoiceSessionChanged begin, uuid = " << mUUID << ", session_id = " << session_id << llendl; LLConversationItemParticipant* participant_model = dynamic_cast(getViewModelItem()); if (participant_model) @@ -477,12 +475,6 @@ void LLConversationViewParticipant::refresh() // *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat mSpeakingIndicator->setIsMuted(participant_model->isMuted()); - //LLConversationItemSession* parent_session = participant_model->getParentSession(); - //if (parent_session) - //{ - // bool is_active = (parent_session->getUUID() == session_id); - // mSpeakingIndicator->switchIndicator(is_active); - //} // Do the regular upstream refresh LLFolderViewItem::refresh(); diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index bd692aa850..78b930984f 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -110,7 +110,6 @@ void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std: void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id) { - llinfos << "Merov debug : sessionVoiceOrIMStarted, uuid = " << session_id << llendl; addConversationListItem(session_id); LLFloaterIMSessionTab::addToHost(session_id); } @@ -1310,7 +1309,6 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID& bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus) { - llinfos << "Merov debug : removeConversationListItem, uuid = " << uuid << llendl; // Delete the widget and the associated conversation item // Note : since the mConversationsItems is also the listener to the widget, deleting // the widget will also delete its listener diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 22131eac49..c2c6e739e9 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -725,7 +725,6 @@ void LLFloaterIMSessionTab::onClose(bool app_quitting) LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance(); if (im_box) { - llinfos << "Merov debug : LLFloaterIMSessionTab::onClose, mKey = " << mKey << llendl; im_box->removeConversationListItem(mKey); } } diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 536f1fbd73..e4621a7fc3 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -48,8 +48,6 @@ LLColor4 LLOutputMonitorCtrl::sColorBound; //F32 LLOutputMonitorCtrl::sRectWidthRatio = 0.f; //F32 LLOutputMonitorCtrl::sRectHeightRatio = 0.f; -static LLUUID test_uuid("c684ce33-89fb-4544-8f7b-dae243c8b214"); - LLOutputMonitorCtrl::Params::Params() : draw_border("draw_border"), image_mute("image_mute"), @@ -280,44 +278,24 @@ BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask) void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/, bool show_other_participants_speaking /* = false */) { - bool test_on = (speaker_id == test_uuid); - if (test_on) - { - llinfos << "Merov debug : setSpeakerId, this = " << this << ", session_id = " << session_id << llendl; - } if (speaker_id.isNull() && mSpeakerId.notNull()) { LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this); } - if (speaker_id.isNull() || speaker_id == mSpeakerId) + if (speaker_id.isNull() || (speaker_id == mSpeakerId)) { - if (test_on) - { - llinfos << "Merov debug : setSpeakerId, nothing done because mSpeakerId == speaker_id" << llendl; - } return; } if (mSpeakerId.notNull()) { - if (test_on) - { - llinfos << "Merov debug : setSpeakerId, unregisterSpeakingIndicator" << llendl; - } // Unregister previous registration to avoid crash. EXT-4782. - if (getTargetSessionID() == session_id) - { - LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this); - } + LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this); } mShowParticipantsSpeaking = show_other_participants_speaking; mSpeakerId = speaker_id; - if (test_on) - { - llinfos << "Merov debug : setSpeakerId, registerSpeakingIndicator" << llendl; - } LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this, session_id); //mute management @@ -345,7 +323,6 @@ void LLOutputMonitorCtrl::onChange() // virtual void LLOutputMonitorCtrl::switchIndicator(bool switch_on) { - llinfos << "Merov debug : switchIndicator, mSpeakerId = " << mSpeakerId << ", switch_on = " << switch_on << llendl; // ensure indicator is visible in case it is not in visible chain // to be called when parent became visible next time to notify parent that visibility is changed. setVisible(TRUE); diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp index d9f9ed5966..76da7d1aee 100644 --- a/indra/newview/llspeakingindicatormanager.cpp +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -155,7 +155,6 @@ void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_i BOOL is_in_same_voice = LLVoiceClient::getInstance()->isParticipant(speaker_id); speakers_uuids.insert(speaker_id); - llinfos << "Merov debug : registerSpeakingIndicator call switchSpeakerIndicators, switch = " << is_in_same_voice << llendl; switchSpeakerIndicators(speakers_uuids, is_in_same_voice); } @@ -196,7 +195,6 @@ SpeakingIndicatorManager::~SpeakingIndicatorManager() void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/) { - llinfos << "Merov debug : sOnCurrentChannelChanged call switchSpeakerIndicators, FALSE" << llendl; switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE); mSwitchedIndicatorsOn.clear(); } @@ -210,16 +208,12 @@ void SpeakingIndicatorManager::onParticipantsChanged() LL_DEBUGS("SpeakingIndicator") << "Switching all OFF, count: " << mSwitchedIndicatorsOn.size() << LL_ENDL; // switch all indicators off - llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, FALSE" << llendl; switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE); - llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, end FALSE switch" << llendl; mSwitchedIndicatorsOn.clear(); LL_DEBUGS("SpeakingIndicator") << "Switching all ON, count: " << speakers_uuids.size() << LL_ENDL; // then switch current voice participants indicators on - llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, TRUE" << llendl; switchSpeakerIndicators(speakers_uuids, TRUE); - llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, end TRUE switch" << llendl; } void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on) @@ -230,7 +224,6 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea { session_id = voice_channel->getSessionID(); } - llinfos << "Merov debug : switchSpeakerIndicators, switch_on = " << switch_on << ", voice channel = " << session_id << llendl; speaker_ids_t::const_iterator it_uuid = speakers_uuids.begin(); for (; it_uuid != speakers_uuids.end(); ++it_uuid) @@ -255,7 +248,6 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea } was_switched_on = was_switched_on || switch_current_on; - llinfos << "Merov debug : indicator for " << *it_uuid << ", switch_current_on = " << switch_current_on << ", session = " << indicator->getTargetSessionID() << llendl; indicator->switchIndicator(switch_current_on); } diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h index 8ee368e258..e5afcd1cb7 100644 --- a/indra/newview/llspeakingindicatormanager.h +++ b/indra/newview/llspeakingindicatormanager.h @@ -37,7 +37,7 @@ public: virtual ~LLSpeakingIndicator(){} virtual void switchIndicator(bool switch_on) = 0; -//private: +private: friend class SpeakingIndicatorManager; // Accessors for target voice session UUID. // They are intended to be used only from SpeakingIndicatorManager to ensure target session is -- cgit v1.3 From 834ded33ae4926b59074f00c13fa3dbf228a3ba0 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 19 Nov 2012 18:41:52 -0800 Subject: CHUI-470 : Fixed : Enable contextual menu in torn off conversations --- indra/llui/llfolderview.h | 1 - indra/newview/llfloaterimcontainer.cpp | 3 +++ indra/newview/llfloaterimcontainer.h | 11 ++++++---- indra/newview/llfloaterimsessiontab.cpp | 39 +++++++++++++++++++++++++++++++++ indra/newview/llfloaterimsessiontab.h | 4 ++++ indra/newview/llinventoryfunctions.cpp | 2 +- 6 files changed, 54 insertions(+), 6 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 487391a477..525efe425a 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -148,7 +148,6 @@ public: virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); virtual std::set getSelectionList() const; - S32 getNumSelectedItems() { return mSelectedItems.size(); } // Make sure if ancestor is selected, descendants are not void sanitizeSelection(); diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index aebfdb5bce..65a8aee4ce 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -869,6 +869,7 @@ void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids) void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS) { + // *TODO : This is where we need to handle a *list* of participant correctly if(selectedIDS.size() > 0) { const LLUUID& userID = selectedIDS.front(); @@ -981,6 +982,8 @@ void LLFloaterIMContainer::doToSelected(const LLSD& userdata) if(conversationItem != NULL) { getParticipantUUIDs(selected_uuids); + + llinfos << "Merov debug : doToSelected, command = " << command << ", name = " << conversationItem->getName() << ", uuid size = " << selected_uuids.size() << llendl; if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT) { diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index afc8d00174..78c312629d 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -99,6 +99,13 @@ public: void onNearbyChatClosed(); + // Handling of lists of participants is public so to be common with llfloatersessiontab + // *TODO : Find a better place for this. + void doToSelected(const LLSD& userdata); + bool checkContextMenuItem(const LLSD& userdata); + bool enableContextMenuItem(const LLSD& userdata); + void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS); + private: typedef std::map avatarID_panel_map_t; avatarID_panel_map_t mSessions; @@ -127,12 +134,8 @@ private: void getSelectedUUIDs(uuid_vec_t& selected_uuids); const LLConversationItem * getCurSelectedViewModelItem(); void getParticipantUUIDs(uuid_vec_t& selected_uuids); - void doToSelected(const LLSD& userdata); void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS); - void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS); void doToSelectedGroup(const LLSD& userdata); - bool checkContextMenuItem(const LLSD& userdata); - bool enableContextMenuItem(const LLSD& userdata); static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response); bool enableModerateContextMenuItem(const std::string& userdata); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 69b42cdd6d..ef36a485a8 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -69,6 +69,12 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck, this, _2)); mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable", boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable, this, _2)); + + // Right click menu handling + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + mEnableCallbackRegistrar.add("Avatar.CheckItem", boost::bind(&LLFloaterIMContainer::checkContextMenuItem, floater_container, _2)); + mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMContainer::enableContextMenuItem, floater_container, _2)); + mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2)); } LLFloaterIMSessionTab::~LLFloaterIMSessionTab() @@ -395,6 +401,7 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant() p.view_model = &mConversationViewModel; p.root = NULL; p.use_ellipses = true; + p.options_menu = "menu_conversation.xml"; mConversationsRoot = LLUICtrlFactory::create(p); mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); // Attach that root to the scroller @@ -763,3 +770,35 @@ bool LLFloaterIMSessionTab::checkIfTornOff() return isTorn; } + +void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata) +{ + // Get the list of selected items in the tab + // Note: By construction, those can only be participants so we do not check if they are sessions or something else + std::string command = userdata.asString(); + uuid_vec_t selected_uuids; + getSelectedUUIDs(selected_uuids); + + llinfos << "Merov debug : doToSelected, command = " << command << ", uuid size = " << selected_uuids.size() << llendl; + + // Perform the command (IM, profile, etc...) on the list using the general conversation container method + // *TODO : Move this method to LLAvatarActions + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + floater_container->doToParticipants(command, selected_uuids); +} + +void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids) +{ + const std::set selected_items = mConversationsRoot->getSelectionList(); + + std::set::const_iterator it = selected_items.begin(); + const std::set::const_iterator it_end = selected_items.end(); + + for (; it != it_end; ++it) + { + LLConversationItem* conversation_item = static_cast((*it)->getViewModelItem()); + selected_uuids.push_back(conversation_item->getUUID()); + } +} + + diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index b765d121de..5980416dff 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -157,6 +157,10 @@ protected: LLButton* mCloseBtn; private: + // Handling selection and contextual menu + void getSelectedUUIDs(uuid_vec_t& selected_uuids); + void doToSelected(const LLSD& userdata); + /// Refreshes the floater at a constant rate. virtual void refresh() = 0; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 1ae6fd91ce..1426567196 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1068,7 +1068,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root if ("delete" == action) { LLSD args; - args["QUESTION"] = LLTrans::getString(root->getNumSelectedItems() > 1 ? "DeleteItems" : "DeleteItem"); + args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" : "DeleteItem"); LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root)); return; } -- cgit v1.3 From 380b82c7ee562877d25b9b67c1ebf5b79b126fad Mon Sep 17 00:00:00 2001 From: AlexanderP ProductEngine Date: Tue, 20 Nov 2012 12:55:38 +0200 Subject: CHUI-487, CHUI-488 Commented out demo --- indra/newview/llfloaterimsessiontab.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 42e7e6cb55..9795df78ae 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -340,8 +340,8 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args) // to demonstrate the correct format call the appropriate functions. // They should be moved to the right places when working on CHUI-486. ~Alex ProductEngine. // ---- start demo ---- - im_box->flashConversationItemWidget(mSessionID, true); // flashing of the conversation's item - gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat" + // im_box->flashConversationItemWidget(mSessionID, true); // flashing of the conversation's item + // gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat" // ---- end demo ----- } -- cgit v1.3 From 1ece38912188650c9bc5a1cf906ca4a88acc21c4 Mon Sep 17 00:00:00 2001 From: AlexanderP ProductEngine Date: Tue, 20 Nov 2012 19:17:25 +0200 Subject: CHUI-528, CHUI-536, CHUI-538, CHUI-540 Built single processor of different types of notifications --- indra/newview/llfloaterimsessiontab.cpp | 8 --- indra/newview/llimview.cpp | 110 +++++++++++++++++--------------- 2 files changed, 59 insertions(+), 59 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 9795df78ae..a21ee07d47 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -335,14 +335,6 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args) if (im_box) { im_box->setTimeNow(mSessionID,chat.mFromID); - - // TODO: Warning! The next two lines of code are included below only temporarily - // to demonstrate the correct format call the appropriate functions. - // They should be moved to the right places when working on CHUI-486. ~Alex ProductEngine. - // ---- start demo ---- - // im_box->flashConversationItemWidget(mSessionID, true); // flashing of the conversation's item - // gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat" - // ---- end demo ----- } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index a4e356f6a9..f0e2f45db3 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -114,76 +114,84 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id, LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID())); } -void toast_callback(const LLSD& msg){ - // do not show toast in do not disturb mode or it goes from agent - if (gAgent.isDoNotDisturb() || gAgent.getID() == msg["from_id"]) - { - return; - } +void on_new_message(const LLSD& msg) +{ + std::string action; + LLUUID participant_id = msg["from_id"].asUUID(); + LLUUID session_id = msg["session_id"]; + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); - // Skip toasting if we have open window of IM with this session id - LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(msg["session_id"]); - if ( - open_im_floater - && open_im_floater->isInVisibleChain() - && open_im_floater->hasFocus() - && !open_im_floater->isMinimized() - && !(open_im_floater->getHost() - && open_im_floater->getHost()->isMinimized()) - ) + // determine action for this session + if (session_id.isNull()) { - return; + action = gSavedSettings.getString("NotificationNearbyChatOptions"); } - - // Skip toasting for system messages - if (msg["from_id"].asUUID() == LLUUID::null) - { - return; - } - - // *NOTE Skip toasting if the user disable it in preferences/debug settings ~Alexandrea - LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession( - msg["session_id"]); - - - //Ignore P2P Friend/Non-Friend toasts - if(session->isP2PSessionType()) + else if(session->isP2PSessionType()) { - //Ignores non-friends - if((LLAvatarTracker::instance().getBuddyInfo(msg["from_id"]) == NULL) - && (gSavedSettings.getString("NotificationNonFriendIMOptions") != "toast")) + if (LLAvatarTracker::instance().isBuddy(msg["from_id"].asUUID())) { - return; + action = gSavedSettings.getString("NotificationFriendIMOptions"); } - //Ignores friends - else if(gSavedSettings.getString("NotificationFriendIMOptions") != "toast") + else { - return; + action = gSavedSettings.getString("NotificationNonFriendIMOptions"); } } - //Ignore Ad Hoc Toasts - else if(session->isAdHocSessionType() - && (gSavedSettings.getString("NotificationConferenceIMOptions") != "toast")) + else if(session->isAdHocSessionType()) { - return; + action = gSavedSettings.getString("NotificationConferenceIMOptions"); } - //Ignore Group Toasts - else if(session->isGroupSessionType() - && (gSavedSettings.getString("NotificationGroupChatOptions") != "toast")) + else if(session->isGroupSessionType()) { - return; + action = gSavedSettings.getString("NotificationGroupChatOptions"); } - //Show toast - LLAvatarNameCache::get(msg["from_id"].asUUID(), - boost::bind(&on_avatar_name_cache_toast, - _1, _2, msg)); + // do not show notification in "do not disturb" mode or it goes from agent + if (gAgent.isDoNotDisturb() || gAgent.getID() == participant_id) + { + return; + } + + if ("toast" == action) + { + // Skip toasting if we have open window of IM with this session id + LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(msg["session_id"]); + if ( + open_im_floater + && open_im_floater->isInVisibleChain() + && open_im_floater->hasFocus() + && !open_im_floater->isMinimized() + && !(open_im_floater->getHost() + && open_im_floater->getHost()->isMinimized()) + ) + { + return; + } + + // Skip toasting for system messages + if (participant_id.isNull()) + { + return; + } + + //Show toast + LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); + } + else if ("flash" == action) + { + LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance("im_container"); + if (im_box) + { + im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item + } + gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat" + } } LLIMModel::LLIMModel() { addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1)); - addNewMsgCallback(boost::bind(&toast_callback, _1)); + addNewMsgCallback(boost::bind(&on_new_message, _1)); } LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg) -- cgit v1.3 From da5792fcecd1e0a3d84634c0a81bd16d4c04488f Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Wed, 21 Nov 2012 15:14:47 +0200 Subject: CHUI-533 FIXED Check that mConversationsRoot is not null --- indra/newview/llfloaterimsessiontab.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index a21ee07d47..0057ed3231 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -496,8 +496,11 @@ void LLFloaterIMSessionTab::refreshConversation() } mConversationViewModel.requestSortAll(); - mConversationsRoot->arrangeAll(); - mConversationsRoot->update(); + if(mConversationsRoot != NULL) + { + mConversationsRoot->arrangeAll(); + mConversationsRoot->update(); + } updateHeaderAndToolbar(); refresh(); } -- cgit v1.3 From a12464b9cbc40d4584d6968db2092a56fa3f4bc6 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 21 Nov 2012 11:46:38 -0800 Subject: CHUI-429, CHUI-511, CHUI-388 : Multiselection and menus in torn off dialogs --- indra/newview/llconversationmodel.cpp | 7 +- indra/newview/llfloaterimcontainer.cpp | 225 ++++++++++----------- indra/newview/llfloaterimcontainer.h | 1 + indra/newview/llfloaterimsessiontab.cpp | 18 +- indra/newview/llfloaterimsessiontab.h | 1 + .../skins/default/xui/en/menu_conversation.xml | 12 +- 6 files changed, 142 insertions(+), 122 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 1c56bd672d..0837a49095 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -27,7 +27,6 @@ #include "llviewerprecompiledheaders.h" -#include "llagent.h" #include "llavatarnamecache.h" #include "llavataractions.h" #include "llevents.h" @@ -422,10 +421,8 @@ void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags) menuentry_vec_t items; menuentry_vec_t disabled_items; - if(gAgent.getID() != mUUID) - { - buildParticipantMenuOptions(items); - } + buildParticipantMenuOptions(items); + hide_context_entries(menu, items, disabled_items); } diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 65a8aee4ce..079cd71039 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -869,68 +869,83 @@ void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids) void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS) { - // *TODO : This is where we need to handle a *list* of participant correctly - if(selectedIDS.size() > 0) + if (selectedIDS.size() == 1) { const LLUUID& userID = selectedIDS.front(); - if(gAgent.getID() != userID) + if ("view_profile" == command) { - if ("view_profile" == command) - { - LLAvatarActions::showProfile(userID); - } - else if("im" == command) - { - LLAvatarActions::startIM(userID); - } - else if("offer_teleport" == command) - { - LLAvatarActions::offerTeleport(selectedIDS); - } - else if("voice_call" == command) - { - LLAvatarActions::startCall(userID); - } - else if("chat_history" == command) - { - LLAvatarActions::viewChatHistory(userID); - } - else if("add_friend" == command) - { - LLAvatarActions::requestFriendshipDialog(userID); - } - else if("remove_friend" == command) - { - LLAvatarActions::removeFriendDialog(userID); - } - else if("invite_to_group" == command) - { - LLAvatarActions::inviteToGroup(userID); - } - else if("map" == command) - { - LLAvatarActions::showOnMap(userID); - } - else if("share" == command) - { - LLAvatarActions::share(userID); - } - else if("pay" == command) - { - LLAvatarActions::pay(userID); - } - else if("block_unblock" == command) - { - LLAvatarActions::toggleBlock(userID); - } - else if("selected" == command || "mute_all" == command || "unmute_all" == command) - { - moderateVoice(command, userID); - } - else if ("toggle_allow_text_chat" == command) - { - toggleAllowTextChat(userID); - } + LLAvatarActions::showProfile(userID); + } + else if ("im" == command) + { + LLAvatarActions::startIM(userID); + } + else if ("offer_teleport" == command) + { + LLAvatarActions::offerTeleport(selectedIDS); + } + else if ("voice_call" == command) + { + LLAvatarActions::startCall(userID); + } + else if ("chat_history" == command) + { + LLAvatarActions::viewChatHistory(userID); + } + else if ("add_friend" == command) + { + LLAvatarActions::requestFriendshipDialog(userID); + } + else if ("remove_friend" == command) + { + LLAvatarActions::removeFriendDialog(userID); + } + else if ("invite_to_group" == command) + { + LLAvatarActions::inviteToGroup(userID); + } + else if ("map" == command) + { + LLAvatarActions::showOnMap(userID); + } + else if ("share" == command) + { + LLAvatarActions::share(userID); + } + else if ("pay" == command) + { + LLAvatarActions::pay(userID); + } + else if ("block_unblock" == command) + { + LLAvatarActions::toggleBlock(userID); + } + else if ("selected" == command || "mute_all" == command || "unmute_all" == command) + { + moderateVoice(command, userID); + } + else if ("toggle_allow_text_chat" == command) + { + toggleAllowTextChat(userID); + } + } + else if (selectedIDS.size() > 1) + { + if ("im" == command) + { + LLAvatarActions::startConference(selectedIDS); + } + else if ("offer_teleport" == command) + { + LLAvatarActions::offerTeleport(selectedIDS); + } + else if ("voice_call" == command) + { + LLAvatarActions::startAdhocCall(selectedIDS); + } + else if ("remove_friend" == command) + { + LLAvatarActions::removeFriendsDialog(selectedIDS); } } } @@ -1021,75 +1036,61 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata) uuid_vec_t uuids; getParticipantUUIDs(uuids); - if(item == std::string("can_activate_group")) + if (item == std::string("can_activate_group")) { LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID(); return gAgent.getGroupID() != selected_group_id; } + + return enableContextMenuItem(item, uuids); +} - if(uuids.size() <= 0) +bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_vec_t& uuids) +{ + // If nothing is selected, everything needs to be disabled + if (uuids.size() <= 0) { return false; } + + // Extract the single select info + bool is_single_select = (uuids.size() == 1); + const LLUUID& single_id = uuids.front(); + + // Handle options that are applicable to all including the user agent + if ("can_view_profile" == item) + { + return is_single_select; + } + + // Beyond that point, if only the user agent is selected, everything is disabled + if (is_single_select && (single_id == gAgentID)) + { + return false; + } - // Note: can_block and can_delete is used only for one person selected menu - // so we don't need to go over all uuids. - + // Handle all other options if (item == std::string("can_block")) { - const LLUUID& id = uuids.front(); - return LLAvatarActions::canBlock(id); + return (is_single_select ? LLAvatarActions::canBlock(single_id) : false); } else if (item == std::string("can_add")) { // We can add friends if: - // - there are selected people - // - and there are no friends among selection yet. - - //EXT-7389 - disable for more than 1 - if(uuids.size() > 1) - { - return false; - } - - bool result = true; - - uuid_vec_t::const_iterator - id = uuids.begin(), - uuids_end = uuids.end(); - - for (;id != uuids_end; ++id) - { - if ( LLAvatarActions::isFriend(*id) ) - { - result = false; - break; - } - } - - return result; + // - there is only 1 selected avatar (EXT-7389) + // - this avatar is not a friend yet + return (is_single_select ? !LLAvatarActions::isFriend(single_id) : false); } else if (item == std::string("can_delete")) { // We can remove friends if: // - there are selected people - // - and there are only friends among selection. - - bool result = (uuids.size() > 0); - - uuid_vec_t::const_iterator - id = uuids.begin(), - uuids_end = uuids.end(); - - for (;id != uuids_end; ++id) + // - and there are only friends among the selection + bool result = true; + for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id) { - if ( !LLAvatarActions::isFriend(*id) ) - { - result = false; - break; - } + result &= LLAvatarActions::isFriend(*id); } - return result; } else if (item == std::string("can_call")) @@ -1098,21 +1099,19 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata) } else if (item == std::string("can_show_on_map")) { - const LLUUID& id = uuids.front(); - - return (LLAvatarTracker::instance().isBuddyOnline(id) && is_agent_mappable(id)) - || gAgent.isGodlike(); + return (is_single_select ? (LLAvatarTracker::instance().isBuddyOnline(single_id) && is_agent_mappable(single_id)) || gAgent.isGodlike() : false); } - else if(item == std::string("can_offer_teleport")) + else if (item == std::string("can_offer_teleport")) { return LLAvatarActions::canOfferTeleport(uuids); } - else if("can_moderate_voice" == item || "can_allow_text_chat" == item || "can_mute" == item || "can_unmute" == item) + else if ("can_moderate_voice" == item || "can_allow_text_chat" == item || "can_mute" == item || "can_unmute" == item) { return enableModerateContextMenuItem(item); } - return false; + // By default, options that not explicitely disabled are enabled + return true; } bool LLFloaterIMContainer::checkContextMenuItem(const LLSD& userdata) diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 78c312629d..3d82ccfc21 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -104,6 +104,7 @@ public: void doToSelected(const LLSD& userdata); bool checkContextMenuItem(const LLSD& userdata); bool enableContextMenuItem(const LLSD& userdata); + bool enableContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS); void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS); private: diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index ef36a485a8..751b3c9db8 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -73,7 +73,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) // Right click menu handling LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); mEnableCallbackRegistrar.add("Avatar.CheckItem", boost::bind(&LLFloaterIMContainer::checkContextMenuItem, floater_container, _2)); - mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMContainer::enableContextMenuItem, floater_container, _2)); + mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2)); mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2)); } @@ -787,6 +787,22 @@ void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata) floater_container->doToParticipants(command, selected_uuids); } +bool LLFloaterIMSessionTab::enableContextMenuItem(const LLSD& userdata) +{ + // Get the list of selected items in the tab + // Note: By construction, those can only be participants so we do not check if they are sessions or something else + std::string command = userdata.asString(); + uuid_vec_t selected_uuids; + getSelectedUUIDs(selected_uuids); + + llinfos << "Merov debug : enableContextMenuItem, command = " << command << ", uuid size = " << selected_uuids.size() << llendl; + + // Perform the command (IM, profile, etc...) on the list using the general conversation container method + // *TODO : Move this method to LLAvatarActions + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + return floater_container->enableContextMenuItem(command, selected_uuids); +} + void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids) { const std::set selected_items = mConversationsRoot->getSelectionList(); diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 5980416dff..0154839287 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -160,6 +160,7 @@ private: // Handling selection and contextual menu void getSelectedUUIDs(uuid_vec_t& selected_uuids); void doToSelected(const LLSD& userdata); + bool enableContextMenuItem(const LLSD& userdata); /// Refreshes the floater at a constant rate. virtual void refresh() = 0; diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml index 2e9bda5804..908b2c174f 100644 --- a/indra/newview/skins/default/xui/en/menu_conversation.xml +++ b/indra/newview/skins/default/xui/en/menu_conversation.xml @@ -30,12 +30,14 @@ layout="topleft" name="view_profile"> + + + + + + + + - + Date: Wed, 21 Nov 2012 18:15:24 -0800 Subject: CHUI-429 : Completed this though it still doesn't work on Nearby Chat. --- indra/newview/llfloaterimcontainer.cpp | 42 +++++++++++++++++++-------------- indra/newview/llfloaterimcontainer.h | 7 +++--- indra/newview/llfloaterimnearbychat.cpp | 21 +++++++++-------- indra/newview/llfloaterimnearbychat.h | 2 +- indra/newview/llfloaterimsessiontab.cpp | 26 +++++++++++--------- indra/newview/llfloaterimsessiontab.h | 4 +++- 6 files changed, 58 insertions(+), 44 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 079cd71039..a56705d969 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -98,7 +98,6 @@ LLFloaterIMContainer::~LLFloaterIMContainer() void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) { - llinfos << "Merov debug : sessionAdded, uuid = " << session_id << ", name = " << name << llendl; addConversationListItem(session_id); LLFloaterIMSessionTab::addToHost(session_id); } @@ -998,8 +997,6 @@ void LLFloaterIMContainer::doToSelected(const LLSD& userdata) { getParticipantUUIDs(selected_uuids); - llinfos << "Merov debug : doToSelected, command = " << command << ", name = " << conversationItem->getName() << ", uuid size = " << selected_uuids.size() << llendl; - if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT) { doToParticipants(command, selected_uuids); @@ -1070,22 +1067,25 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v } // Handle all other options - if (item == std::string("can_block")) + if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item)) + { + // Those menu items are enable only if a single avatar is selected + return is_single_select; + } + else if ("can_block" == item) { return (is_single_select ? LLAvatarActions::canBlock(single_id) : false); } - else if (item == std::string("can_add")) + else if ("can_add" == item) { // We can add friends if: // - there is only 1 selected avatar (EXT-7389) - // - this avatar is not a friend yet + // - this avatar is not already a friend return (is_single_select ? !LLAvatarActions::isFriend(single_id) : false); } - else if (item == std::string("can_delete")) + else if ("can_delete" == item) { - // We can remove friends if: - // - there are selected people - // - and there are only friends among the selection + // We can remove friends if there are only friends among the selection bool result = true; for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id) { @@ -1093,20 +1093,21 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v } return result; } - else if (item == std::string("can_call")) + else if ("can_call" == item) { return LLAvatarActions::canCall(); } - else if (item == std::string("can_show_on_map")) + else if ("can_show_on_map" == item) { return (is_single_select ? (LLAvatarTracker::instance().isBuddyOnline(single_id) && is_agent_mappable(single_id)) || gAgent.isGodlike() : false); } - else if (item == std::string("can_offer_teleport")) + else if ("can_offer_teleport" == item) { return LLAvatarActions::canOfferTeleport(uuids); } - else if ("can_moderate_voice" == item || "can_allow_text_chat" == item || "can_mute" == item || "can_unmute" == item) + else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item)) { + // *TODO : get that out of here... return enableModerateContextMenuItem(item); } @@ -1117,14 +1118,19 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v bool LLFloaterIMContainer::checkContextMenuItem(const LLSD& userdata) { std::string item = userdata.asString(); - uuid_vec_t mUUIDs; - getParticipantUUIDs(mUUIDs); + uuid_vec_t uuids; + getParticipantUUIDs(uuids); + + return checkContextMenuItem(item, uuids); +} - if(mUUIDs.size() > 0 ) +bool LLFloaterIMContainer::checkContextMenuItem(const std::string& item, uuid_vec_t& uuids) +{ + if (uuids.size() == 1) { if ("is_blocked" == item) { - return LLAvatarActions::isBlocked(mUUIDs.front()); + return LLAvatarActions::isBlocked(uuids.front()); } else if ("is_allowed_text_chat" == item) { diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 3d82ccfc21..bec0c3ef14 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -101,9 +101,7 @@ public: // Handling of lists of participants is public so to be common with llfloatersessiontab // *TODO : Find a better place for this. - void doToSelected(const LLSD& userdata); - bool checkContextMenuItem(const LLSD& userdata); - bool enableContextMenuItem(const LLSD& userdata); + bool checkContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS); bool enableContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS); void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS); @@ -135,6 +133,9 @@ private: void getSelectedUUIDs(uuid_vec_t& selected_uuids); const LLConversationItem * getCurSelectedViewModelItem(); void getParticipantUUIDs(uuid_vec_t& selected_uuids); + void doToSelected(const LLSD& userdata); + bool checkContextMenuItem(const LLSD& userdata); + bool enableContextMenuItem(const LLSD& userdata); void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS); void doToSelectedGroup(const LLSD& userdata); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 5867eb3e84..7002342c0b 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -112,6 +112,7 @@ BOOL LLFloaterIMNearbyChat::postBuild() { setIsSingleInstance(TRUE); BOOL result = LLFloaterIMSessionTab::postBuild(); + mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this)); mInputEditor->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this)); mInputEditor->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this)); @@ -122,24 +123,24 @@ BOOL LLFloaterIMNearbyChat::postBuild() // mOutputMonitor->setVisible(FALSE); // Register for font change notifications - LLViewerChat::setFontChangedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatFontChange, this, _1)); +// LLViewerChat::setFontChangedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatFontChange, this, _1)); // title must be defined BEFORE call addConversationListItem() because // it is used for show the item's name in the conversations list setTitle(LLTrans::getString("NearbyChatTitle")); //for menu - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; +// LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; +// LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - enable_registrar.add("NearbyChat.Check", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatCheckContextMenuItem, this, _2)); - registrar.add("NearbyChat.Action", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatContextMenuItemClicked, this, _2)); +// enable_registrar.add("NearbyChat.Check", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatCheckContextMenuItem, this, _2)); +// registrar.add("NearbyChat.Action", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatContextMenuItemClicked, this, _2)); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if(menu) - { - mPopupMenuHandle = menu->getHandle(); - } +// LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +// if(menu) +// { +// mPopupMenuHandle = menu->getHandle(); +// } // obsolete, but may be needed for backward compatibility? gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true); diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h index 1479746fbd..5ed639136b 100644 --- a/indra/newview/llfloaterimnearbychat.h +++ b/indra/newview/llfloaterimnearbychat.h @@ -117,7 +117,7 @@ private: /*virtual*/ void refresh(); - LLHandle mPopupMenuHandle; +// LLHandle mPopupMenuHandle; std::vector mMessageArchive; }; diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 751b3c9db8..3fb24f52c4 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -71,8 +71,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable, this, _2)); // Right click menu handling - LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); - mEnableCallbackRegistrar.add("Avatar.CheckItem", boost::bind(&LLFloaterIMContainer::checkContextMenuItem, floater_container, _2)); + mEnableCallbackRegistrar.add("Avatar.CheckItem", boost::bind(&LLFloaterIMSessionTab::checkContextMenuItem, this, _2)); mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2)); mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2)); } @@ -774,35 +773,40 @@ bool LLFloaterIMSessionTab::checkIfTornOff() void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata) { // Get the list of selected items in the tab - // Note: By construction, those can only be participants so we do not check if they are sessions or something else std::string command = userdata.asString(); uuid_vec_t selected_uuids; getSelectedUUIDs(selected_uuids); - llinfos << "Merov debug : doToSelected, command = " << command << ", uuid size = " << selected_uuids.size() << llendl; - // Perform the command (IM, profile, etc...) on the list using the general conversation container method - // *TODO : Move this method to LLAvatarActions LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + // Note: By construction, those can only be participants so we can call doToParticipants() directly floater_container->doToParticipants(command, selected_uuids); } bool LLFloaterIMSessionTab::enableContextMenuItem(const LLSD& userdata) { // Get the list of selected items in the tab - // Note: By construction, those can only be participants so we do not check if they are sessions or something else std::string command = userdata.asString(); uuid_vec_t selected_uuids; getSelectedUUIDs(selected_uuids); - llinfos << "Merov debug : enableContextMenuItem, command = " << command << ", uuid size = " << selected_uuids.size() << llendl; - - // Perform the command (IM, profile, etc...) on the list using the general conversation container method - // *TODO : Move this method to LLAvatarActions + // Perform the item enable test on the list using the general conversation container method LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); return floater_container->enableContextMenuItem(command, selected_uuids); } +bool LLFloaterIMSessionTab::checkContextMenuItem(const LLSD& userdata) +{ + // Get the list of selected items in the tab + std::string command = userdata.asString(); + uuid_vec_t selected_uuids; + getSelectedUUIDs(selected_uuids); + + // Perform the item check on the list using the general conversation container method + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + return floater_container->checkContextMenuItem(command, selected_uuids); +} + void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids) { const std::set selected_items = mConversationsRoot->getSelectionList(); diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 0154839287..8efa0955fc 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -158,9 +158,11 @@ protected: private: // Handling selection and contextual menu - void getSelectedUUIDs(uuid_vec_t& selected_uuids); void doToSelected(const LLSD& userdata); bool enableContextMenuItem(const LLSD& userdata); + bool checkContextMenuItem(const LLSD& userdata); + + void getSelectedUUIDs(uuid_vec_t& selected_uuids); /// Refreshes the floater at a constant rate. virtual void refresh() = 0; -- cgit v1.3 From a83676e1ab6ae6c12e28c5f568ac933c2e97408c Mon Sep 17 00:00:00 2001 From: "maxim@mnikolenko" Date: Fri, 23 Nov 2012 19:56:59 +0200 Subject: CHUI-530 FIXED Don't switch to new conversation automatically --- indra/newview/llfloaterimsessiontab.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 0057ed3231..dcf1b52118 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -162,7 +162,7 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id) if (!conversp->isNearbyChat() || gSavedSettings.getBOOL("NearbyChatIsNotTornOff")) { - floater_container->addFloater(conversp, TRUE, LLTabContainer::END); + floater_container->addFloater(conversp, FALSE, LLTabContainer::END); if (!floater_container->getVisible()) { -- cgit v1.3 From 47a1a0468156153155f5e9b6c720b9b6cb62c263 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 30 Nov 2012 14:12:46 -0800 Subject: CHUI-570 : Fixed : Take the typing state when updating the title, also make refresh update less frequent (perf). --- indra/newview/llfloaterimsession.cpp | 26 +++++++++++--------------- indra/newview/llfloaterimsession.h | 1 - indra/newview/llfloaterimsessiontab.cpp | 2 +- 3 files changed, 12 insertions(+), 17 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index e1dc5b91d0..0162b0ecd0 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -66,7 +66,6 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id) : LLFloaterIMSessionTab(session_id), mLastMessageIndex(-1), mDialog(IM_NOTHING_SPECIAL), - mSavedTitle(), mTypingStart(), mShouldSendTypingState(false), mMeTyping(false), @@ -504,9 +503,13 @@ void LLFloaterIMSession::onVoiceChannelStateChanged( void LLFloaterIMSession::updateSessionName(const std::string& name) { - LLFloaterIMSessionTab::updateSessionName(name); - setTitle(name); - mTypingStart.setArg("[NAME]", name); + if (!name.empty()) + { + LLFloaterIMSessionTab::updateSessionName(name); + mTypingStart.setArg("[NAME]", name); + setTitle (mOtherTyping ? mTypingStart.getString() : name); + } + llinfos << "Merov debug : updateSessionName, title = " << name << ", typing title = " << mTypingStart.getString() << llendl; } //static @@ -1095,14 +1098,10 @@ BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids) void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info) { // We may have lost a "stop-typing" packet, don't add it twice - if ( im_info && !mOtherTyping ) + 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 ) @@ -1114,18 +1113,15 @@ void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info) void LLFloaterIMSession::removeTypingIndicator(const LLIMInfo* im_info) { - if ( mOtherTyping ) + if (mOtherTyping) { mOtherTyping = false; - // Revert the title to saved one - setTitle(mSavedTitle); - - if ( im_info ) + if (im_info) { // Update speaker LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); - if ( speaker_mgr ) + if (speaker_mgr) { speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); } diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index f4ec2d457d..72a320041f 100644 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -174,7 +174,6 @@ private: LLUUID mOtherParticipantUUID; bool mPositioned; - std::string mSavedTitle; LLUIString mTypingStart; bool mMeTyping; bool mOtherTyping; diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 6e58a66bcd..d43381041b 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -43,7 +43,7 @@ #include "lltoolbarview.h" #include "llfloaterimnearbychat.h" -const F32 REFRESH_INTERVAL = 0.2f; +const F32 REFRESH_INTERVAL = 1.0f; LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) : LLTransientDockableFloater(NULL, true, session_id) -- cgit v1.3 From f888a3fd00ca32275ab2da6437cb011b3ab78f89 Mon Sep 17 00:00:00 2001 From: MaximB ProductEngine Date: Mon, 3 Dec 2012 16:21:48 +0200 Subject: CHUI-556 (Tooltip on call button incorrect when call is active) --- indra/newview/llfloaterimsessiontab.cpp | 7 ++++++- indra/newview/skins/default/xui/en/floater_im_session.xml | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index d43381041b..08c2b951df 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -691,8 +691,13 @@ void LLFloaterIMSessionTab::processChatHistoryStyleUpdate() void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive) { - getChild("voice_call_btn")->setImageOverlay( + LLButton* voiceButton = getChild("voice_call_btn"); + voiceButton->setImageOverlay( callIsActive? getString("call_btn_stop") : getString("call_btn_start")); + + voiceButton->setToolTip( + callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip")); + enableDisableCallBtn(); } 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 1d74f1bc25..faf54774f6 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -43,6 +43,12 @@ + + Date: Mon, 3 Dec 2012 16:19:46 -0800 Subject: CHUI-571: Now when the 'Chat Preference' is set to 'Open Conversations window' the conversation line item with flash. The only time it does not flash is when the the conversation line item is already focused. Also fixed various focusing bugs when navigating between conversations and participants. --- indra/llui/llfolderviewitem.cpp | 7 ++++++- indra/newview/llconversationview.cpp | 18 ++++++++++++++---- indra/newview/llfloaterimcontainer.cpp | 26 +++++++++++++++++--------- indra/newview/llfloaterimnearbychathandler.cpp | 5 ----- indra/newview/llfloaterimsessiontab.cpp | 2 +- indra/newview/llimview.cpp | 6 ++++++ 6 files changed, 44 insertions(+), 20 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 261f53d6b6..9b54a7a467 100755 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -501,7 +501,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) // No handler needed for focus lost since this class has no // state that depends on it. gFocusMgr.setMouseCapture( this ); - + if (!mIsSelected) { if(mask & MASK_CONTROL) @@ -518,6 +518,11 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) } make_ui_sound("UISndClick"); } + //Just re-select the item since it is clicked without ctrl or shift + else if(!(mask & (MASK_CONTROL | MASK_SHIFT))) + { + getRoot()->setSelection(this, FALSE); + } else { mSelectPending = TRUE; diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 1b1d61e6d6..a696fbdb47 100755 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -218,9 +218,15 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask ) { LLConversationItem* item = dynamic_cast(getViewModelItem()); LLUUID session_id = item? item->getUUID() : LLUUID(); + //Will try to select a child node and then itself (if a child was not selected) BOOL result = LLFolderViewFolder::handleMouseDown(x, y, mask); - (LLFloaterReg::getTypedInstance("im_container"))-> - selectConversationPair(session_id, false); + + //This node (conversation) was selected and a child (participant) was not + if(result && getRoot()->getCurSelectedItem() == this) + { + (LLFloaterReg::getTypedInstance("im_container"))-> + selectConversationPair(session_id, false); + } return result; } @@ -548,8 +554,12 @@ BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask ) } LLUUID session_id = item? item->getUUID() : LLUUID(); BOOL result = LLFolderViewItem::handleMouseDown(x, y, mask); - (LLFloaterReg::getTypedInstance("im_container"))-> - selectConversationPair(session_id, false); + + if(result) + { + (LLFloaterReg::getTypedInstance("im_container"))-> + selectConversationPair(session_id, false); + } return result; } diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index a04b8d79d6..3a80491dae 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -1165,21 +1165,16 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id) selectConversation(session_id); } -// Will select only the conversation item void LLFloaterIMContainer::selectConversation(const LLUUID& session_id) { - LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id); - if (widget) - { - (widget->getRoot())->setSelection(widget, FALSE, FALSE); + selectConversationPair(session_id, true); } -} - // Synchronous select the conversation item and the conversation floater BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget) { BOOL handled = TRUE; + LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); /* widget processing */ if (select_widget) @@ -1198,7 +1193,7 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool // Store the active session setSelectedSession(session_id); - LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); + if (session_floater->getHost()) { @@ -1207,13 +1202,13 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool // Switch to the conversation floater that is being selected selectFloater(session_floater); } + } // Set the focus on the selected floater if (!session_floater->hasFocus()) { session_floater->setFocus(TRUE); } - } return handled; } @@ -1627,13 +1622,26 @@ void LLFloaterIMContainer::reSelectConversation() void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes) { + //Finds the conversation line item to flash using the session_id LLConversationViewSession * widget = dynamic_cast(get_ptr_in_map(mConversationsWidgets,session_id)); + LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); + if (widget) { + //Start flash if (is_flashes) { + //Only flash when conversation is not active + if(session_floater + && (!session_floater->isInVisibleChain()) //conversation floater not displayed + || + (session_floater->isInVisibleChain() && session_floater->hasFocus() == false)) //conversation floater is displayed but doesn't have focus + + { widget->getFlashTimer()->startFlashing(); } + } + //Stop flash else { widget->getFlashTimer()->stopFlashing(); diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index d9c461e836..903c903381 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -619,11 +619,6 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, chat["message"] = toast_msg; channel->addChat(chat); } - //Will show Conversations floater when chat preference is set - else if(gSavedSettings.getString("NotificationNearbyChatOptions") == "openconversations") - { - LLFloaterReg::showInstance("im_container"); - } } } diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 6e58a66bcd..efc7be6dd6 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -306,7 +306,7 @@ void LLFloaterIMSessionTab::onFocusReceived() LLFloaterIMContainer* container = LLFloaterReg::getTypedInstance("im_container"); if (container) { - container->selectConversationPair(mSessionID, true); + container->selectConversationPair(mSessionID, ! getHost()); container->showStub(! getHost()); } } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index e5dda7e8d8..b6fd3ec9c8 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -191,6 +191,12 @@ void on_new_message(const LLSD& msg) } else if("openconversations" == action) { + LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance("im_container"); + if (im_box) + { + im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item + } + LLFloaterReg::showInstance("im_container"); } } -- cgit v1.3 From 8642088d65ec340b50661e2a3bf74820ec595010 Mon Sep 17 00:00:00 2001 From: Gilbert Gonzales Date: Tue, 4 Dec 2012 19:23:36 -0800 Subject: CHUI-571: Fixed bug where when the converation floater was torn off and a new im received, the incorrect conversation would be displayed and focused. In order to do this removed the conversation floater panels from being focused immediately when set visible. Also there was a bug when showing the stub panel for torn off conversations. The tab container was not setting the stub panel index properly to 0, which is where the stub panel existed in the tab container's list. This is post code review submit. Will submit another with minor code review changes. --- indra/llui/lltabcontainer.cpp | 3 ++- indra/newview/llfloaterimcontainer.cpp | 14 +++----------- indra/newview/llfloaterimnearbychat.cpp | 1 - indra/newview/llfloaterimsession.cpp | 1 - indra/newview/llfloaterimsessiontab.cpp | 2 +- indra/newview/llimview.cpp | 20 ++++++++++++++++---- 6 files changed, 22 insertions(+), 19 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 3c1dfc1184..0dd63c2632 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1559,7 +1559,8 @@ BOOL LLTabContainer::setTab(S32 which) void LLTabContainer::hideAllTabs() { - setCurrentPanelIndex(-1); + + setCurrentPanelIndex(0); for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { (* iter)->mTabPanel->setVisible(FALSE); diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index c1daea0aeb..d50581a314 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -546,8 +546,10 @@ void LLFloaterIMContainer::setVisible(BOOL visible) // *TODO: find a way to move this to XML as a default panel or something like that LLSD name("nearby_chat"); LLFloaterReg::toggleInstanceOrBringToFront(name); + setSelectedSession(LLUUID(NULL)); } openNearbyChat(); + selectConversationPair(getSelectedSession(), false); } nearby_chat = LLFloaterReg::findTypedInstance("nearby_chat"); @@ -571,7 +573,6 @@ void LLFloaterIMContainer::setVisible(BOOL visible) // Now, do the normal multifloater show/hide LLMultiFloater::setVisible(visible); - } void LLFloaterIMContainer::collapseMessagesPane(bool collapse) @@ -1624,22 +1625,13 @@ void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, { //Finds the conversation line item to flash using the session_id LLConversationViewSession * widget = dynamic_cast(get_ptr_in_map(mConversationsWidgets,session_id)); - LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); if (widget) { //Start flash if (is_flashes) { - //Only flash when conversation is not active - if(session_floater - && (!session_floater->isInVisibleChain()) //conversation floater not displayed - || - (session_floater->isInVisibleChain() && session_floater->hasFocus() == false)) //conversation floater is displayed but doesn't have focus - - { - widget->getFlashTimer()->startFlashing(); - } + widget->getFlashTimer()->startFlashing(); } //Stop flash else diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index a20fce876c..80a41e2f37 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -228,7 +228,6 @@ void LLFloaterIMNearbyChat::setVisible(BOOL visible) { removeScreenChat(); } - setFocus(visible); } // virtual diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 212b0df712..cb730c6237 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -629,7 +629,6 @@ void LLFloaterIMSession::setVisible(BOOL visible) } - setFocus(visible); } BOOL LLFloaterIMSession::getVisible() diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index d04fa2674d..da25f95ffe 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -60,6 +60,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) , mRefreshTimer(new LLTimer()) , mIsHostAttached(false) { + setAutoFocus(FALSE); mSession = LLIMModel::getInstance()->findIMSession(mSessionID); mCommitCallbackRegistrar.add("IMSession.Menu.Action", @@ -124,7 +125,6 @@ void LLFloaterIMSessionTab::setVisible(BOOL visible) { LLFloaterIMSessionTab::addToHost(mSessionID); } - setFocus(visible); } /*virtual*/ diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index b6fd3ec9c8..821e62c4e6 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -192,12 +192,24 @@ void on_new_message(const LLSD& msg) else if("openconversations" == action) { LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance("im_container"); - if (im_box) + LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); + + //Don't flash and show conversation floater when conversation already active (has focus) + if(session_floater + && (!session_floater->isInVisibleChain()) //conversation floater not displayed + || + (session_floater->isInVisibleChain() && session_floater->hasFocus() == false)) //conversation floater is displayed but doesn't have focus + { - im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item + //Flash line item + if (im_box) + { + im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item + } + + //Surface conversations floater + LLFloaterReg::showInstance("im_container"); } - - LLFloaterReg::showInstance("im_container"); } } -- cgit v1.3 From 272d438ce299fab146e9a30046b7591de7467511 Mon Sep 17 00:00:00 2001 From: MaximB ProductEngine Date: Thu, 6 Dec 2012 18:23:30 +0200 Subject: CHUI-576 (Group moderation menus do not work in torn off dialogs) --- indra/newview/llfloaterimcontainer.cpp | 20 +++++++++++++------- indra/newview/llfloaterimsessiontab.cpp | 12 ++++++++++++ indra/newview/llfloaterimsessiontab.h | 1 + 3 files changed, 26 insertions(+), 7 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index c1daea0aeb..257c17a058 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -850,8 +850,16 @@ const LLConversationItem * LLFloaterIMContainer::getCurSelectedViewModelItem() mConversationsRoot->getCurSelectedItem() && mConversationsRoot->getCurSelectedItem()->getViewModelItem()) { - conversationItem = static_cast(mConversationsRoot->getCurSelectedItem()->getViewModelItem()); - } + LLFloaterIMSessionTab *selectedSession = LLFloaterIMSessionTab::getConversation(mSelectedSession); + if (selectedSession && selectedSession->isTornOff()) + { + conversationItem = selectedSession->getCurSelectedViewModelItem(); + } + else + { + conversationItem = static_cast(mConversationsRoot->getCurSelectedItem()->getViewModelItem()); + } + } return conversationItem; } @@ -1532,21 +1540,19 @@ void LLFloaterIMContainer::moderateVoiceParticipant(const LLUUID& avatar_id, boo LLSpeakerMgr * LLFloaterIMContainer::getSpeakerMgrForSelectedParticipant() { - LLFolderViewItem * selected_folder_itemp = mConversationsRoot->getCurSelectedItem(); - if (NULL == selected_folder_itemp) + LLFolderViewItem *selectedItem = mConversationsRoot->getCurSelectedItem(); + if (NULL == selectedItem) { llwarns << "Current selected item is null" << llendl; return NULL; } - LLFolderViewFolder * conversation_itemp = selected_folder_itemp->getParentFolder(); - conversations_widgets_map::const_iterator iter = mConversationsWidgets.begin(); conversations_widgets_map::const_iterator end = mConversationsWidgets.end(); const LLUUID * conversation_uuidp = NULL; while(iter != end) { - if (iter->second == conversation_itemp) + if (iter->second == selectedItem || iter->second == selectedItem->getParentFolder()) { conversation_uuidp = &iter->first; break; diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index d04fa2674d..85d1b1fb49 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -831,4 +831,16 @@ void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids) } } +LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem() +{ + LLConversationItem *conversationItem = NULL; + if(mConversationsRoot && + mConversationsRoot->getCurSelectedItem() && + mConversationsRoot->getCurSelectedItem()->getViewModelItem()) + { + conversationItem = static_cast(mConversationsRoot->getCurSelectedItem()->getViewModelItem()) ; + } + + return conversationItem; +} diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 8efa0955fc..4851904074 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -94,6 +94,7 @@ public: virtual void onTearOffClicked(); virtual void updateMessages() {} + LLConversationItem* getCurSelectedViewModelItem(); protected: -- cgit v1.3 From 935b3326254f75af876b6c9aeb1648ac3a9802cf Mon Sep 17 00:00:00 2001 From: "maxim@mnikolenko" Date: Fri, 7 Dec 2012 15:03:32 +0200 Subject: CHUI-427 FIXED Voice button is added to Conversations floater. --- indra/newview/llfloaterimcontainer.cpp | 13 +++++++++++++ indra/newview/llfloaterimcontainer.h | 2 ++ indra/newview/llfloaterimsessiontab.cpp | 3 ++- .../newview/skins/default/xui/en/floater_im_container.xml | 15 ++++++++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) (limited to 'indra/newview/llfloaterimsessiontab.cpp') diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index b8a37da3fa..bd99e88a9d 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -206,6 +206,7 @@ BOOL LLFloaterIMContainer::postBuild() mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onExpandCollapseButtonClicked, this)); mStubCollapseBtn = getChild("stub_collapse_btn"); mStubCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onStubCollapseButtonClicked, this)); + getChild("speak_btn")->setClickedCallback(boost::bind(&LLFloaterIMContainer::onSpeakButtonClicked, this)); childSetAction("add_btn", boost::bind(&LLFloaterIMContainer::onAddButtonClicked, this)); @@ -341,6 +342,11 @@ void LLFloaterIMContainer::onStubCollapseButtonClicked() collapseMessagesPane(true); } +void LLFloaterIMContainer::onSpeakButtonClicked() +{ + LLAgent::toggleMicrophone("speak"); + updateSpeakBtnState(); +} void LLFloaterIMContainer::onExpandCollapseButtonClicked() { if (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed() @@ -1672,6 +1678,13 @@ void LLFloaterIMContainer::reSelectConversation() } } +void LLFloaterIMContainer::updateSpeakBtnState() +{ + LLButton* mSpeakBtn = getChild("speak_btn"); + mSpeakBtn->setToggleState(LLVoiceClient::getInstance()->getUserPTTState()); + mSpeakBtn->setEnabled(LLAgent::isActionAllowed("speak")); +} + void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes) { //Finds the conversation line item to flash using the session_id diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index c9987bffe8..92985c036a 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -117,6 +117,7 @@ private: void onExpandCollapseButtonClicked(); void onStubCollapseButtonClicked(); void processParticipantsStyleUpdate(); + void onSpeakButtonClicked(); void collapseConversationsPane(bool collapse); @@ -172,6 +173,7 @@ public: void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id); void setNearbyDistances(); void reSelectConversation(); + void updateSpeakBtnState(); void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes); private: diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index b50b8c2d32..0567ea3d8a 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -698,7 +698,8 @@ void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive) voiceButton->setToolTip( callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip")); - enableDisableCallBtn(); + LLFloaterIMContainer::getInstance()->updateSpeakBtnState(); + enableDisableCallBtn(); } diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index 152c897120..a3648f3c9d 100644 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -73,13 +73,26 @@ image_hover_unselected="Toolbar_Middle_Over" image_overlay="Conv_toolbar_plus" image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" + image_unselected="Toolbar_Middle_Off" layout="topleft" top="5" left_pad="4" name="add_btn" tool_tip="Start a new conversation" width="31"/> + + + + + + Location: + + + + + + + + - - (Locations, images, web, search history) - - - - + border="true" + follows="left|top|right|bottom" + height="408" + label="Communication" + layout="topleft" + left="102" + name="im" + top="1" + width="517"> + + + log in to change + + + + + + (Locations, images, web, search history) + + + + + + - - Chat Logs: - - - - - - - - - Location of logs: - - - +