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/llfloaterimsession.cpp | 1202 ++++++++++++++++++++++++++++++++++ 1 file changed, 1202 insertions(+) create mode 100644 indra/newview/llfloaterimsession.cpp (limited to 'indra/newview/llfloaterimsession.cpp') diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp new file mode 100644 index 0000000000..0c622e07c4 --- /dev/null +++ b/indra/newview/llfloaterimsession.cpp @@ -0,0 +1,1202 @@ +/** + * @file llfloaterimsession.cpp + * @brief LLFloaterIMSession class definition + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterimsession.h" + +#include "lldraghandle.h" +#include "llnotificationsutil.h" + +#include "llagent.h" +#include "llappviewer.h" +#include "llavataractions.h" +#include "llavatarnamecache.h" +#include "llbutton.h" +#include "llchannelmanager.h" +#include "llchiclet.h" +#include "llchicletbar.h" +#include "llfloaterreg.h" +#include "llfloateravatarpicker.h" +#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container +#include "llinventoryfunctions.h" +//#include "lllayoutstack.h" +#include "llchatentry.h" +#include "lllogchat.h" +#include "llscreenchannel.h" +#include "llsyswellwindow.h" +#include "lltrans.h" +#include "llchathistory.h" +#include "llnotifications.h" +#include "llviewerwindow.h" +#include "lltransientfloatermgr.h" +#include "llinventorymodel.h" +#include "llrootview.h" +#include "llspeakers.h" +#include "llviewerchat.h" +#include "llnotificationmanager.h" +#include "llautoreplace.h" + +floater_showed_signal_t LLFloaterIMSession::sIMFloaterShowedSignal; + +LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id) + : LLFloaterIMSessionTab(session_id), + mLastMessageIndex(-1), + mDialog(IM_NOTHING_SPECIAL), + mSavedTitle(), + mTypingStart(), + mShouldSendTypingState(false), + mMeTyping(false), + mOtherTyping(false), + mTypingTimer(), + mTypingTimeoutTimer(), + mPositioned(false), + mSessionInitialized(false), + mStartConferenceInSameFloater(false) +{ + mIsNearbyChat = false; + + initIMSession(session_id); + + setOverlapsScreenChannel(true); + + LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); + + setDocked(true); +} + + +// virtual +void LLFloaterIMSession::refresh() +{ + if (mMeTyping) +{ + // Time out if user hasn't typed for a while. + if (mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS) + { + setTyping(false); + } + } +} + +// virtual +void LLFloaterIMSession::onClickCloseBtn() +{ + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID); + + if (session != NULL) + { + bool is_call_with_chat = session->isGroupSessionType() + || session->isAdHocSessionType() || session->isP2PSessionType(); + + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + + if (is_call_with_chat && voice_channel != NULL + && voice_channel->isActive()) + { + LLSD payload; + payload["session_id"] = mSessionID; + LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback); + return; + } + } + else + { + llwarns << "Empty session with id: " << (mSessionID.asString()) << llendl; + return; + } + + LLFloaterIMSessionTab::onClickCloseBtn(); +} + +/* static */ +void LLFloaterIMSession::newIMCallback(const LLSD& data) +{ + if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull()) + { + LLUUID session_id = data["session_id"].asUUID(); + + LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance("impanel", session_id); + + // update if visible, otherwise will be updated when opened + if (floater && floater->getVisible()) + { + floater->updateMessages(); + } + } +} + +void LLFloaterIMSession::onVisibilityChange(const LLSD& new_visibility) +{ + bool visible = new_visibility.asBoolean(); + + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + + if (visible && voice_channel && + voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED) + { + LLFloaterReg::showInstance("voice_call", mSessionID); + } + else + { + LLFloaterReg::hideInstance("voice_call", mSessionID); + } +} + +void LLFloaterIMSession::onSendMsg( LLUICtrl* ctrl, void* userdata ) +{ + LLFloaterIMSession* self = (LLFloaterIMSession*) userdata; + self->sendMsgFromInputEditor(); + self->setTyping(false); +} + +void LLFloaterIMSession::sendMsgFromInputEditor() +{ + if (gAgent.isGodlike() + || (mDialog != IM_NOTHING_SPECIAL) + || !mOtherParticipantUUID.isNull()) + { + if (mInputEditor) + { + LLWString text = mInputEditor->getWText(); + LLWStringUtil::trim(text); + LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines. + if(!text.empty()) + { + // Truncate and convert to UTF8 for transport + std::string utf8_text = wstring_to_utf8str(text); + + sendMsg(utf8_text); + + mInputEditor->setText(LLStringUtil::null); + } + } + } + else + { + llinfos << "Cannot send IM to everyone unless you're a god." << llendl; + } +} + +void LLFloaterIMSession::sendMsg(const std::string& msg) +{ + const std::string utf8_text = utf8str_truncate(msg, MAX_MSG_BUF_SIZE - 1); + + if (mSessionInitialized) + { + LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog); + } + else + { + //queue up the message to send once the session is initialized + mQueuedMsgsForInit.append(utf8_text); + } + + updateMessages(); +} + +LLFloaterIMSession::~LLFloaterIMSession() +{ + mVoiceChannelStateChangeConnection.disconnect(); + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver(this); + } + + LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); +} + + +void LLFloaterIMSession::initIMSession(const LLUUID& session_id) +{ + // Change the floater key to bind it to a new session. + setKey(session_id); + + mSessionID = session_id; + mSession = LLIMModel::getInstance()->findIMSession(mSessionID); + + if (mSession) + { + mIsP2PChat = mSession->isP2PSessionType(); + mSessionInitialized = mSession->mSessionInitialized; + mDialog = mSession->mType; + } +} + +void LLFloaterIMSession::initIMFloater() +{ + const LLUUID& other_party_id = + LLIMModel::getInstance()->getOtherParticipantID(mSessionID); + if (other_party_id.notNull()) + { + mOtherParticipantUUID = other_party_id; + } + + boundVoiceChannel(); + + mTypingStart = LLTrans::getString("IM_typing_start_string"); + + // Show control panel in torn off floaters only. + mParticipantListPanel->setVisible(!getHost() && gSavedSettings.getBOOL("IMShowControlPanel")); + + // Disable input editor if session cannot accept text + if ( mSession && !mSession->mTextIMPossible ) + { + mInputEditor->setEnabled(FALSE); + mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label")); + } + + if (!mIsP2PChat) + { + std::string session_name(LLIMModel::instance().getName(mSessionID)); + updateSessionName(session_name); + } +} + +//virtual +BOOL LLFloaterIMSession::postBuild() +{ + BOOL result = LLFloaterIMSessionTab::postBuild(); + + mInputEditor->setMaxTextLength(1023); + // enable line history support for instant message bar + // XXX stinson TODO : resolve merge by adding autoreplace to text editors +#if 0 + // *TODO Establish LineEditor with autoreplace callback + mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2)); +#endif + + mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) ); + mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) ); + mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) ); + mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this)); + + setDocked(true); + + LLButton* add_btn = getChild("add_btn"); + + // Allow to add chat participants depending on the session type + add_btn->setEnabled(isInviteAllowed()); + add_btn->setClickedCallback(boost::bind(&LLFloaterIMSession::onAddButtonClicked, this)); + + childSetAction("voice_call_btn", boost::bind(&LLFloaterIMSession::onCallButtonClicked, this)); + + LLVoiceClient::getInstance()->addObserver(this); + + //*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla" + //see LLFloaterIMPanel for how it is done (IB) + + initIMFloater(); + + return result; +} + +void LLFloaterIMSession::onAddButtonClicked() +{ + LLView * button = findChild("toolbar_panel")->findChild("add_btn"); + LLFloater* root_floater = gFloaterView->getParentFloater(this); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterIMSession::addSessionParticipants, this, _1), TRUE, TRUE, FALSE, root_floater->getName(), button); + if (!picker) + { + return; + } + + // Need to disable 'ok' button when selected users are already in conversation. + picker->setOkBtnEnableCb(boost::bind(&LLFloaterIMSession::canAddSelectedToChat, this, _1)); + + if (root_floater) + { + root_floater->addDependentFloater(picker); + } +} + +bool LLFloaterIMSession::canAddSelectedToChat(const uuid_vec_t& uuids) +{ + if (!mSession + || mDialog == IM_SESSION_GROUP_START + || mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID)) + { + return false; + } + + if (mIsP2PChat) + { + // For a P2P session just check if we are not adding the other participant. + + for (uuid_vec_t::const_iterator id = uuids.begin(); + id != uuids.end(); ++id) + { + if (*id == mOtherParticipantUUID) + { + return false; + } + } + } + else + { + // For a conference session we need to check against the list from LLSpeakerMgr, + // because this list may change when participants join or leave the session. + + LLSpeakerMgr::speaker_list_t speaker_list; + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + speaker_mgr->getSpeakerList(&speaker_list, true); + } + + for (uuid_vec_t::const_iterator id = uuids.begin(); + id != uuids.end(); ++id) + { + for (LLSpeakerMgr::speaker_list_t::const_iterator it = speaker_list.begin(); + it != speaker_list.end(); ++it) + { + const LLPointer& speaker = *it; + if (*id == speaker->mID) + { + return false; + } + } + } + } + + return true; +} + +void LLFloaterIMSession::addSessionParticipants(const uuid_vec_t& uuids) +{ + if (mIsP2PChat) + { + LLSD payload; + LLSD args; + + LLNotificationsUtil::add("ConfirmAddingChatParticipants", args, payload, + boost::bind(&LLFloaterIMSession::addP2PSessionParticipants, this, _1, _2, uuids)); + } + else + { + // remember whom we have invited, to notify others later, when the invited ones actually join + mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end()); + + inviteToSession(uuids); + } +} + +void LLFloaterIMSession::addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) + { + return; + } + + mStartConferenceInSameFloater = true; + + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + + // first check whether this is a voice session + bool is_voice_call = voice_channel != NULL && voice_channel->isActive(); + + uuid_vec_t temp_ids; + + // Add the initial participant of a P2P session + temp_ids.push_back(mOtherParticipantUUID); + temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end()); + + // then we can close the current session + onClose(false); + + // we start a new session so reset the initialization flag + mSessionInitialized = false; + + // remember whom we have invited, to notify others later, when the invited ones actually join + mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end()); + + // Start a new ad hoc voice call if we invite new participants to a P2P call, + // or start a text chat otherwise. + if (is_voice_call) + { + LLAvatarActions::startAdhocCall(temp_ids, mSessionID); + } + else + { + LLAvatarActions::startConference(temp_ids, mSessionID); + } +} + +void LLFloaterIMSession::sendParticipantsAddedNotification(const uuid_vec_t& uuids) +{ + std::string names_string; + LLAvatarActions::buildResidentsString(uuids, names_string); + LLStringUtil::format_map_t args; + args["[NAME]"] = names_string; + + sendMsg(getString(uuids.size() > 1 ? "multiple_participants_added" : "participant_added", args)); +} + +void LLFloaterIMSession::boundVoiceChannel() +{ + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + if(voice_channel) + { + mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback( + boost::bind(&LLFloaterIMSession::onVoiceChannelStateChanged, this, _1, _2)); + + //call (either p2p, group or ad-hoc) can be already in started state + bool callIsActive = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED; + updateCallBtnState(callIsActive); + } +} + +void LLFloaterIMSession::onCallButtonClicked() +{ + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + if (voice_channel) + { + bool is_call_active = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED; + if (is_call_active) + { + gIMMgr->endCall(mSessionID); + } + else + { + gIMMgr->startCall(mSessionID); + } + } +} + +void LLFloaterIMSession::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ + if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL) + { + enableDisableCallBtn(); + } +} + +void LLFloaterIMSession::onVoiceChannelStateChanged( + const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state) +{ + bool callIsActive = new_state >= LLVoiceChannel::STATE_CALL_STARTED; + updateCallBtnState(callIsActive); +} + +void LLFloaterIMSession::updateSessionName(const std::string& name) +{ + LLFloaterIMSessionTab::updateSessionName(name); + setTitle(name); + mTypingStart.setArg("[NAME]", name); +} + +//static +LLFloaterIMSession* LLFloaterIMSession::show(const LLUUID& session_id) +{ + closeHiddenIMToasts(); + + if (!gIMMgr->hasSession(session_id)) + return NULL; + + // Test the existence of the floater before we try to create it + bool exist = findInstance(session_id); + + // Get the floater: this will create the instance if it didn't exist + LLFloaterIMSession* floater = getInstance(session_id); + if (!floater) + return NULL; + + LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance(); + + // Do not add again existing floaters + if (!exist) + { + // LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; + // TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists + LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END; + if (floater_container) + { + floater_container->addFloater(floater, TRUE, i_pt); + } + } + + floater->openFloater(floater->getKey()); + + floater->setVisible(TRUE); + + return floater; +} +//static +LLFloaterIMSession* LLFloaterIMSession::findInstance(const LLUUID& session_id) +{ + LLFloaterIMSession* conversation = + LLFloaterReg::findTypedInstance("impanel", session_id); + + return conversation; +} + +LLFloaterIMSession* LLFloaterIMSession::getInstance(const LLUUID& session_id) +{ + LLFloaterIMSession* conversation = + LLFloaterReg::getTypedInstance("impanel", session_id); + + return conversation; +} + +void LLFloaterIMSession::onClose(bool app_quitting) +{ + setTyping(false); + + // The source of much argument and design thrashing + // Should the window hide or the session close when the X is clicked? + // + // Last change: + // EXT-3516 X Button should end IM session, _ button should hide + gIMMgr->leaveSession(mSessionID); + + // Clean up the conversation *after* the session has been ended + LLFloaterIMSessionTab::onClose(app_quitting); +} + +void LLFloaterIMSession::setDocked(bool docked, bool pop_on_undock) +{ + // update notification channel state + LLNotificationsUI::LLScreenChannel* channel = static_cast + (LLNotificationsUI::LLChannelManager::getInstance()-> + findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + + if(!isChatMultiTab()) + { + LLTransientDockableFloater::setDocked(docked, pop_on_undock); + } + + // update notification channel state + if(channel) + { + channel->updateShowToastsState(); + channel->redrawToasts(); + } +} + +void LLFloaterIMSession::setVisible(BOOL visible) +{ + LLNotificationsUI::LLScreenChannel* channel = static_cast + (LLNotificationsUI::LLChannelManager::getInstance()-> + findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + + LLFloaterIMSessionTab::setVisible(visible); + + // update notification channel state + if(channel) + { + channel->updateShowToastsState(); + channel->redrawToasts(); + } + + if(!visible) + { + LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet(mSessionID); + if(chiclet) + { + chiclet->setToggleState(false); + } + } + + if (visible && isInVisibleChain()) + { + sIMFloaterShowedSignal(mSessionID); + + } + + setFocus(visible); +} + +BOOL LLFloaterIMSession::getVisible() +{ + bool visible; + + if(isChatMultiTab()) + { + LLFloaterIMContainer* im_container = + LLFloaterIMContainer::getInstance(); + + // Treat inactive floater as invisible. + bool is_active = im_container->getActiveFloater() == this; + + //torn off floater is always inactive + if (!is_active && getHost() != im_container) + { + visible = LLTransientDockableFloater::getVisible(); + } + else + { + // getVisible() returns TRUE when Tabbed IM window is minimized. + visible = is_active && !im_container->isMinimized() + && im_container->getVisible(); + } + } + else + { + visible = LLTransientDockableFloater::getVisible(); + } + + return visible; +} + +//static +bool LLFloaterIMSession::toggle(const LLUUID& session_id) +{ + if(!isChatMultiTab()) + { + LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance( + "impanel", session_id); + if (floater && floater->getVisible() && floater->hasFocus()) + { + // clicking on chiclet to close floater just hides it to maintain existing + // scroll/text entry state + floater->setVisible(false); + return false; + } + else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus())) + { + floater->setVisible(TRUE); + floater->setFocus(TRUE); + return true; + } + } + + // ensure the list of messages is updated when floater is made visible + show(session_id); + return true; +} + +void LLFloaterIMSession::sessionInitReplyReceived(const LLUUID& im_session_id) +{ + mSessionInitialized = true; + + //will be different only for an ad-hoc im session + if (mSessionID != im_session_id) + { + initIMSession(im_session_id); + buildConversationViewParticipant(); + } + + initIMFloater(); + + //*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) + + //need to send delayed messages collected while waiting for session initialization + if (mQueuedMsgsForInit.size()) + { + LLSD::array_iterator iter; + for ( iter = mQueuedMsgsForInit.beginArray(); + iter != mQueuedMsgsForInit.endArray(); ++iter) + { + LLIMModel::sendMessage(iter->asString(), mSessionID, + mOtherParticipantUUID, mDialog); + } + + mQueuedMsgsForInit.clear(); + } +} + +void LLFloaterIMSession::updateMessages() +{ + std::list messages; + + // we shouldn't reset unread message counters if IM floater doesn't have focus + LLIMModel::instance().getMessages( + mSessionID, messages, mLastMessageIndex + 1, hasFocus()); + + if (messages.size()) + { + std::ostringstream message; + std::list::const_reverse_iterator iter = messages.rbegin(); + std::list::const_reverse_iterator iter_end = messages.rend(); + for (; iter != iter_end; ++iter) + { + LLSD msg = *iter; + + std::string time = msg["time"].asString(); + LLUUID from_id = msg["from_id"].asUUID(); + std::string from = msg["from"].asString(); + std::string message = msg["message"].asString(); + bool is_history = msg["is_history"].asBoolean(); + + LLChat chat; + chat.mFromID = from_id; + chat.mSessionID = mSessionID; + chat.mFromName = from; + chat.mTimeStr = time; + chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle; + + // process offer notification + if (msg.has("notification_id")) + { + chat.mNotifId = msg["notification_id"].asUUID(); + // if notification exists - embed it + if (LLNotificationsUtil::find(chat.mNotifId) != NULL) + { + // remove embedded notification from channel + LLNotificationsUI::LLScreenChannel* channel = static_cast + (LLNotificationsUI::LLChannelManager::getInstance()-> + findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + if (getVisible()) + { + // toast will be automatically closed since it is not storable toast + channel->hideToast(chat.mNotifId); + } + } + // if notification doesn't exist - try to use next message which should be log entry + else + { + continue; + } + } + //process text message + else + { + chat.mText = message; + } + + // Add the message to the chat log + appendMessage(chat); + mLastMessageIndex = msg["index"].asInteger(); + + // if it is a notification - next message is a notification history log, so skip it + if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL) + { + if (++iter == iter_end) + { + break; + } + else + { + mLastMessageIndex++; + } + } + } + } +} + +void LLFloaterIMSession::reloadMessages() +{ + mChatHistory->clear(); + mLastMessageIndex = -1; + updateMessages(); + mInputEditor->setFont(LLViewerChat::getChatFont()); +} + +// static +void LLFloaterIMSession::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ) +{ + LLFloaterIMSession* self= (LLFloaterIMSession*) userdata; + + // Allow enabling the LLFloaterIMSession input editor only if session can accept text + LLIMModel::LLIMSession* im_session = + LLIMModel::instance().findIMSession(self->mSessionID); + //TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK) + if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled()) + { + //in disconnected state IM input editor should be disabled + self->mInputEditor->setEnabled(!gDisconnected); + } +} + +// static +void LLFloaterIMSession::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) +{ + LLFloaterIMSession* self = (LLFloaterIMSession*) userdata; + self->setTyping(false); +} + +// static +void LLFloaterIMSession::onInputEditorKeystroke(LLTextEditor* caller, void* userdata) +{ + LLFloaterIMSession* self = (LLFloaterIMSession*)userdata; + std::string text = self->mInputEditor->getText(); + + // Deleting all text counts as stopping typing. + self->setTyping(!text.empty()); +} + +void LLFloaterIMSession::setTyping(bool typing) +{ + if ( typing ) + { + // Started or proceeded typing, reset the typing timeout timer + mTypingTimeoutTimer.reset(); + } + + if ( mMeTyping != typing ) + { + // Typing state is changed + mMeTyping = typing; + // So, should send current state + mShouldSendTypingState = true; + // In case typing is started, send state after some delay + mTypingTimer.reset(); + } + + // Don't want to send typing indicators to multiple people, potentially too + // much network traffic. Only send in person-to-person IMs. + if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL ) + { + // Still typing, send 'start typing' notification or + // send 'stop typing' notification immediately + if (!mMeTyping || mTypingTimer.getElapsedTimeF32() > 1.f) + { + LLIMModel::instance().sendTypingState(mSessionID, + mOtherParticipantUUID, mMeTyping); + mShouldSendTypingState = false; + } + } + + if (!mIsNearbyChat) + { + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + { + speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); + } + } +} + +void LLFloaterIMSession::processIMTyping(const LLIMInfo* im_info, BOOL typing) +{ + if ( typing ) + { + // other user started typing + addTypingIndicator(im_info); + } + else + { + // other user stopped typing + removeTypingIndicator(im_info); + } +} + +void LLFloaterIMSession::processAgentListUpdates(const LLSD& body) +{ + uuid_vec_t joined_uuids; + + if (body.isMap() && body.has("agent_updates") && body["agent_updates"].isMap()) + { + LLSD::map_const_iterator update_it; + for(update_it = body["agent_updates"].beginMap(); + update_it != body["agent_updates"].endMap(); + ++update_it) + { + LLUUID agent_id(update_it->first); + LLSD agent_data = update_it->second; + + if (agent_data.isMap()) + { + // store the new participants in joined_uuids + if (agent_data.has("transition") && agent_data["transition"].asString() == "ENTER") + { + joined_uuids.push_back(agent_id); + } + + // process the moderator mutes + if (agent_id == gAgentID && agent_data.has("info") && agent_data["info"].has("mutes")) + { + BOOL moderator_muted_text = agent_data["info"]["mutes"]["text"].asBoolean(); + mInputEditor->setEnabled(!moderator_muted_text); + std::string label; + if (moderator_muted_text) + label = LLTrans::getString("IM_muted_text_label"); + else + label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID); + mInputEditor->setLabel(label); + + if (moderator_muted_text) + LLNotificationsUtil::add("TextChatIsMutedByModerator"); + } + } + } + } + + // the vectors need to be sorted for computing the intersection and difference + std::sort(mInvitedParticipants.begin(), mInvitedParticipants.end()); + std::sort(joined_uuids.begin(), joined_uuids.end()); + + uuid_vec_t intersection; // uuids of invited residents who have joined the conversation + std::set_intersection(mInvitedParticipants.begin(), mInvitedParticipants.end(), + joined_uuids.begin(), joined_uuids.end(), + std::back_inserter(intersection)); + + if (intersection.size() > 0) + { + sendParticipantsAddedNotification(intersection); + } + + // Remove all joined participants from invited array. + // The difference between the two vectors (the elements in mInvitedParticipants which are not in joined_uuids) + // is placed at the beginning of mInvitedParticipants, then all other elements are erased. + mInvitedParticipants.erase(std::set_difference(mInvitedParticipants.begin(), mInvitedParticipants.end(), + joined_uuids.begin(), joined_uuids.end(), + mInvitedParticipants.begin()), + mInvitedParticipants.end()); +} + +void LLFloaterIMSession::processSessionUpdate(const LLSD& session_update) +{ + // *TODO : verify following code when moderated mode will be implemented + if ( false && session_update.has("moderated_mode") && + session_update["moderated_mode"].has("voice") ) + { + BOOL voice_moderated = session_update["moderated_mode"]["voice"]; + const std::string session_label = LLIMModel::instance().getName(mSessionID); + + if (voice_moderated) + { + setTitle(session_label + std::string(" ") + + LLTrans::getString("IM_moderated_chat_label")); + } + else + { + setTitle(session_label); + } + + // *TODO : uncomment this when/if LLPanelActiveSpeakers panel will be added + //update the speakers dropdown too + //mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated); + } +} + +// virtual +BOOL LLFloaterIMSession::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + if (cargo_type == DAD_PERSON) + { + if (dropPerson(static_cast(cargo_data), drop)) + { + *accept = ACCEPT_YES_MULTI; + } + else + { + *accept = ACCEPT_NO; + } + } + else if (mDialog == IM_NOTHING_SPECIAL) + { + LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop, + cargo_type, cargo_data, accept); + } + + return TRUE; +} + +bool LLFloaterIMSession::dropPerson(LLUUID* person_id, bool drop) +{ + bool res = person_id && person_id->notNull(); + if(res) + { + uuid_vec_t ids; + ids.push_back(*person_id); + + res = canAddSelectedToChat(ids); + if(res && drop) + { + addSessionParticipants(ids); + } + } + + return res; +} + +BOOL LLFloaterIMSession::isInviteAllowed() const +{ + return ( (IM_SESSION_CONFERENCE_START == mDialog) + || (IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID)) + || mIsP2PChat); +} + +class LLSessionInviteResponder : public LLHTTPClient::Responder +{ +public: + LLSessionInviteResponder(const LLUUID& session_id) + { + mSessionID = session_id; + } + + void error(U32 statusNum, const std::string& reason) + { + llinfos << "Error inviting all agents to session" << llendl; + //throw something back to the viewer here? + } + +private: + LLUUID mSessionID; +}; + +BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids) +{ + LLViewerRegion* region = gAgent.getRegion(); + bool is_region_exist = region != NULL; + + if (is_region_exist) + { + S32 count = ids.size(); + + if( isInviteAllowed() && (count > 0) ) + { + llinfos << "LLFloaterIMSession::inviteToSession() - inviting participants" << llendl; + + std::string url = region->getCapability("ChatSessionRequest"); + + LLSD data; + data["params"] = LLSD::emptyArray(); + for (int i = 0; i < count; i++) + { + data["params"].append(ids[i]); + } + data["method"] = "invite"; + data["session-id"] = mSessionID; + LLHTTPClient::post(url, data,new LLSessionInviteResponder(mSessionID)); + } + else + { + llinfos << "LLFloaterIMSession::inviteToSession -" + << " no need to invite agents for " + << mDialog << llendl; + // successful add, because everyone that needed to get added + // was added. + } + } + + return is_region_exist; +} + +void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info) +{ + // We may have lost a "stop-typing" packet, don't add it twice + if ( im_info && !mOtherTyping ) + { + mOtherTyping = true; + + // Save and set new title + mSavedTitle = getTitle(); + setTitle (mTypingStart); + + // Update speaker + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if ( speaker_mgr ) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE); + } + } +} + +void LLFloaterIMSession::removeTypingIndicator(const LLIMInfo* im_info) +{ + if ( mOtherTyping ) + { + mOtherTyping = false; + + // Revert the title to saved one + setTitle(mSavedTitle); + + if ( im_info ) + { + // Update speaker + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if ( speaker_mgr ) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); + } + } + } +} + +// static +void LLFloaterIMSession::closeHiddenIMToasts() +{ + class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher + { + public: + bool matches(const LLNotificationPtr notification) const + { + // "notifytoast" type of notifications is reserved for IM notifications + return "notifytoast" == notification->getType(); + } + }; + + LLNotificationsUI::LLScreenChannel* channel = + LLNotificationsUI::LLChannelManager::getNotificationScreenChannel(); + if (channel != NULL) + { + channel->closeHiddenToasts(IMToastMatcher()); + } +} +// static +void LLFloaterIMSession::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + const LLSD& payload = notification["payload"]; + LLUUID session_id = payload["session_id"]; + + LLFloater* im_floater = findInstance(session_id); + if (option == 0 && im_floater != NULL) + { + im_floater->closeFloater(); + } + + return; +} + +// static +void LLFloaterIMSession::sRemoveTypingIndicator(const LLSD& data) +{ + LLUUID session_id = data["session_id"]; + if (session_id.isNull()) + return; + + LLUUID from_id = data["from_id"]; + if (gAgentID == from_id || LLUUID::null == from_id) + return; + + LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(session_id); + if (!floater) + return; + + if (IM_NOTHING_SPECIAL != floater->mDialog) + return; + + floater->removeTypingIndicator(); +} + +// static +void LLFloaterIMSession::onIMChicletCreated( const LLUUID& session_id ) +{ + LLFloaterIMSession::addToHost(session_id); +} + +boost::signals2::connection LLFloaterIMSession::setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb) +{ + return LLFloaterIMSession::sIMFloaterShowedSignal.connect(cb); +} -- cgit v1.3 From 29e9f792bb9595dbacbc8a4b584b5bf62e7db6c6 Mon Sep 17 00:00:00 2001 From: AlexanderP ProductEngine Date: Tue, 13 Nov 2012 21:20:05 +0200 Subject: CHUI-512 FIXED (New incoming conversations take focus in message panel only and do not show toasts). Rejected update message when floater hasn't focus --- indra/newview/llfloaterimsession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llfloaterimsession.cpp') diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 0c622e07c4..e1dc5b91d0 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -142,7 +142,7 @@ void LLFloaterIMSession::newIMCallback(const LLSD& data) LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance("impanel", session_id); // update if visible, otherwise will be updated when opened - if (floater && floater->getVisible()) + if (floater && (floater->getHost()? floater->hasFocus() : floater->getVisible())) { floater->updateMessages(); } -- 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/llfloaterimsession.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 eab0ec402e7ea1eb151408b913c6f4e14c9c8cbe Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 30 Nov 2012 14:34:23 -0800 Subject: CHUI-570 : Delete a stray debug comment log. --- indra/newview/llfloaterimsession.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/newview/llfloaterimsession.cpp') diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 0162b0ecd0..212b0df712 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -509,7 +509,6 @@ void LLFloaterIMSession::updateSessionName(const std::string& name) mTypingStart.setArg("[NAME]", name); setTitle (mOtherTyping ? mTypingStart.getString() : name); } - llinfos << "Merov debug : updateSessionName, title = " << name << ", typing title = " << mTypingStart.getString() << llendl; } //static -- cgit v1.3 From f1155c4fa5e9a4eaa5b4d452fc46a2246fb305bd Mon Sep 17 00:00:00 2001 From: maksymsproductengine Date: Tue, 4 Dec 2012 04:14:51 +0200 Subject: CHUI-573 FIXED Notification chiclet shown when object chiclets are shown --- indra/newview/llchiclet.cpp | 882 +-------------------- indra/newview/llchiclet.h | 555 +------------ indra/newview/llchicletbar.cpp | 104 +-- indra/newview/llchicletbar.h | 16 - indra/newview/llfloaterimsession.cpp | 10 +- indra/newview/llscriptfloater.cpp | 121 ++- indra/newview/llsyswellwindow.cpp | 289 +------ indra/newview/llsyswellwindow.h | 66 +- .../default/textures/bottomtray/Notices_Unread.png | Bin 3693 -> 0 bytes .../textures/bottomtray/VoicePTT_Lvl1_Dark.png | Bin 602 -> 0 bytes .../textures/bottomtray/VoicePTT_Lvl2_Dark.png | Bin 669 -> 0 bytes .../textures/bottomtray/VoicePTT_Lvl3_Dark.png | Bin 639 -> 0 bytes .../textures/bottomtray/VoicePTT_Off_Dark.png | Bin 547 -> 0 bytes .../textures/bottomtray/VoicePTT_On_Dark.png | Bin 526 -> 0 bytes indra/newview/skins/default/textures/textures.xml | 8 - .../skins/default/xui/da/menu_im_well_button.xml | 4 - .../xui/da/menu_notification_well_button.xml | 4 - .../skins/default/xui/de/menu_im_well_button.xml | 4 - .../xui/de/menu_notification_well_button.xml | 4 - .../xui/en/menu_notification_well_button.xml | 16 - .../skins/default/xui/en/panel_activeim_row.xml | 97 --- .../skins/default/xui/en/panel_chiclet_bar.xml | 44 - .../default/xui/en/widgets/chiclet_im_adhoc.xml | 55 -- .../default/xui/en/widgets/chiclet_im_group.xml | 56 -- .../default/xui/en/widgets/chiclet_im_p2p.xml | 56 -- .../skins/default/xui/es/menu_im_well_button.xml | 4 - .../xui/es/menu_notification_well_button.xml | 4 - .../skins/default/xui/fr/menu_im_well_button.xml | 4 - .../xui/fr/menu_notification_well_button.xml | 4 - .../skins/default/xui/it/menu_im_well_button.xml | 4 - .../xui/it/menu_notification_well_button.xml | 4 - .../skins/default/xui/ja/menu_im_well_button.xml | 4 - .../xui/ja/menu_notification_well_button.xml | 4 - .../skins/default/xui/pl/menu_im_well_button.xml | 4 - .../xui/pl/menu_notification_well_button.xml | 4 - .../skins/default/xui/pt/menu_im_well_button.xml | 4 - .../xui/pt/menu_notification_well_button.xml | 4 - .../skins/default/xui/ru/menu_im_well_button.xml | 4 - .../xui/ru/menu_notification_well_button.xml | 4 - .../skins/default/xui/tr/menu_im_well_button.xml | 4 - .../xui/tr/menu_notification_well_button.xml | 4 - .../skins/default/xui/zh/menu_im_well_button.xml | 4 - .../xui/zh/menu_notification_well_button.xml | 4 - 43 files changed, 100 insertions(+), 2363 deletions(-) delete mode 100644 indra/newview/skins/default/textures/bottomtray/Notices_Unread.png delete mode 100644 indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png delete mode 100644 indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png delete mode 100644 indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png delete mode 100644 indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png delete mode 100644 indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png delete mode 100644 indra/newview/skins/default/xui/da/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/da/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/de/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/de/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/en/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/en/panel_activeim_row.xml delete mode 100644 indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml delete mode 100644 indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml delete mode 100644 indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml delete mode 100644 indra/newview/skins/default/xui/es/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/es/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/fr/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/fr/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/it/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/it/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/ja/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/ja/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/pl/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/pl/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/pt/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/pt/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/ru/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/ru/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/tr/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/tr/menu_notification_well_button.xml delete mode 100644 indra/newview/skins/default/xui/zh/menu_im_well_button.xml delete mode 100644 indra/newview/skins/default/xui/zh/menu_notification_well_button.xml (limited to 'indra/newview/llfloaterimsession.cpp') diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index a665aeb6bd..1acbdd32b7 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -27,35 +27,15 @@ #include "llviewerprecompiledheaders.h" // must be first include #include "llchiclet.h" -#include "llagent.h" -#include "llavataractions.h" -#include "llchicletbar.h" -#include "lleventtimer.h" -#include "llgroupactions.h" -#include "lliconctrl.h" #include "llfloaterimsession.h" #include "llfloaterimcontainer.h" -#include "llimview.h" #include "llfloaterreg.h" #include "lllocalcliprect.h" -#include "llmenugl.h" #include "llnotifications.h" -#include "llnotificationsutil.h" -#include "lloutputmonitorctrl.h" #include "llscriptfloater.h" -#include "llspeakers.h" -#include "lltextbox.h" -#include "llvoiceclient.h" -#include "llgroupmgr.h" -#include "llnotificationmanager.h" -#include "lltransientfloatermgr.h" -#include "llsyswellwindow.h" +#include "llsingleton.h" static LLDefaultChildRegistry::Register t1("chiclet_panel"); -static LLDefaultChildRegistry::Register t2("chiclet_notification"); -static LLDefaultChildRegistry::Register t3("chiclet_im_p2p"); -static LLDefaultChildRegistry::Register t4("chiclet_im_group"); -static LLDefaultChildRegistry::Register t5("chiclet_im_adhoc"); static LLDefaultChildRegistry::Register t6("chiclet_script"); static LLDefaultChildRegistry::Register t7("chiclet_offer"); @@ -66,192 +46,6 @@ boost::signals2::signal(button_params); - addChild(mButton); - - - mFlashToLitTimer = new LLFlashTimer(boost::bind(&LLSysWellChiclet::changeLitState, this, _1)); -} - -LLSysWellChiclet::~LLSysWellChiclet() -{ - delete mFlashToLitTimer; -} - -void LLSysWellChiclet::setCounter(S32 counter) -{ - // do nothing if the same counter is coming. EXT-3678. - if (counter == mCounter) return; - - // note same code in LLChicletNotificationCounterCtrl::setCounter(S32 counter) - std::string s_count; - if(counter != 0) - { - static std::string more_messages_exist("+"); - std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : ""); - s_count = llformat("%d%s" - , llmin(counter, mMaxDisplayedCount) - , more_messages.c_str() - ); - } - - mButton->setLabel(s_count); - - mCounter = counter; -} - -boost::signals2::connection LLSysWellChiclet::setClickCallback( - const commit_callback_t& cb) -{ - return mButton->setClickedCallback(cb); -} - -void LLSysWellChiclet::setToggleState(BOOL toggled) { - mButton->setToggleState(toggled); -} - -void LLSysWellChiclet::changeLitState(bool blink) -{ - setNewMessagesState(!mIsNewMessagesState); -} - -void LLSysWellChiclet::setNewMessagesState(bool new_messages) -{ - /* - Emulate 4 states of button by background images, see detains in EXT-3147 - xml attribute Description - image_unselected "Unlit" - there are no new messages - image_selected "Unlit" + "Selected" - there are no new messages and the Well is open - image_pressed "Lit" - there are new messages - image_pressed_selected "Lit" + "Selected" - there are new messages and the Well is open - */ - mButton->setForcePressedState(new_messages); - - mIsNewMessagesState = new_messages; -} - -void LLSysWellChiclet::updateWidget(bool is_window_empty) -{ - mButton->setEnabled(!is_window_empty); - - if (LLChicletBar::instanceExists()) - { - LLChicletBar::getInstance()->showWellButton(getName(), !is_window_empty); - } -} -// virtual -BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - if(!mContextMenu) - { - createMenu(); - } - if (mContextMenu) - { - mContextMenu->show(x, y); - LLMenuGL::showPopup(this, mContextMenu, x, y); - } - return TRUE; -} - -/************************************************************************/ -/* LLNotificationChiclet implementation */ -/************************************************************************/ -LLNotificationChiclet::LLNotificationChiclet(const Params& p) -: LLSysWellChiclet(p), - mUreadSystemNotifications(0) -{ - mNotificationChannel.reset(new ChicletNotificationChannel(this)); - // ensure that notification well window exists, to synchronously - // handle toast add/delete events. - LLNotificationWellWindow::getInstance()->setSysWellChiclet(this); -} - -void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data) -{ - std::string action = user_data.asString(); - if("close all" == action) - { - LLNotificationWellWindow::getInstance()->closeAll(); - } -} - -bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data) -{ - std::string item = user_data.asString(); - if (item == "can close all") - { - return mUreadSystemNotifications != 0; - } - return true; -} - -void LLNotificationChiclet::createMenu() -{ - if(mContextMenu) - { - llwarns << "Menu already exists" << llendl; - return; - } - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("NotificationWellChicletMenu.Action", - boost::bind(&LLNotificationChiclet::onMenuItemClicked, this, _2)); - - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - enable_registrar.add("NotificationWellChicletMenu.EnableItem", - boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2)); - - mContextMenu = LLUICtrlFactory::getInstance()->createFromFile - ("menu_notification_well_button.xml", - LLMenuGL::sMenuContainer, - LLViewerMenuHolderGL::child_registry_t::instance()); -} - -/*virtual*/ -void LLNotificationChiclet::setCounter(S32 counter) -{ - LLSysWellChiclet::setCounter(counter); - updateWidget(getCounter() == 0); - -} - -bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification ) -{ - if( !(notification->canLogToIM() && notification->hasFormElements()) - && (!notification->getPayload().has("give_inventory_notification") - || notification->getPayload()["give_inventory_notification"])) - { - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - LLChiclet::Params::Params() : show_counter("show_counter", true) , enable_counter("enable_counter", false) @@ -303,7 +97,9 @@ LLSD LLChiclet::getValue() const void LLChiclet::setValue(const LLSD& value) { if(value.isUUID()) + { setSessionId(value.asUUID()); + } } ////////////////////////////////////////////////////////////////////////// @@ -315,12 +111,9 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p) , mShowSpeaker(false) , mDefaultWidth(p.rect().getWidth()) , mNewMessagesIcon(NULL) -, mSpeakerCtrl(NULL) -, mCounterCtrl(NULL) , mChicletButton(NULL) , mPopupMenu(NULL) { - enableCounterControl(p.enable_counter); } /* virtual*/ @@ -331,107 +124,14 @@ BOOL LLIMChiclet::postBuild() mChicletButton->setDoubleClickCallback(boost::bind(&LLIMChiclet::onMouseDown, this)); return TRUE; } -void LLIMChiclet::setShowSpeaker(bool show) -{ - bool needs_resize = getShowSpeaker() != show; - if(needs_resize) - { - mShowSpeaker = show; - } - - toggleSpeakerControl(); -} - -void LLIMChiclet::enableCounterControl(bool enable) -{ - mCounterEnabled = enable; - if(!enable) - { - LLChiclet::setShowCounter(false); - } -} - -void LLIMChiclet::setShowCounter(bool show) -{ - if(!mCounterEnabled) - { - return; - } - - bool needs_resize = getShowCounter() != show; - if(needs_resize) - { - LLChiclet::setShowCounter(show); - toggleCounterControl(); - } -} - -void LLIMChiclet::initSpeakerControl() -{ - // virtual -} void LLIMChiclet::setRequiredWidth() { - bool show_speaker = getShowSpeaker(); - bool show_counter = getShowCounter(); S32 required_width = mDefaultWidth; - - if (show_counter) - { - required_width += mCounterCtrl->getRect().getWidth(); - } - if (show_speaker) - { - required_width += mSpeakerCtrl->getRect().getWidth(); - } - reshape(required_width, getRect().getHeight()); - onChicletSizeChanged(); } -void LLIMChiclet::toggleSpeakerControl() -{ - if(getShowSpeaker()) - { - // move speaker to the right of chiclet icon - LLRect speaker_rc = mSpeakerCtrl->getRect(); - speaker_rc.setLeftTopAndSize(mDefaultWidth, speaker_rc.mTop, speaker_rc.getWidth(), speaker_rc.getHeight()); - mSpeakerCtrl->setRect(speaker_rc); - - if(getShowCounter()) - { - // move speaker to the right of counter - mSpeakerCtrl->translate(mCounterCtrl->getRect().getWidth(), 0); - } - - initSpeakerControl(); - } - - setRequiredWidth(); - mSpeakerCtrl->setSpeakerId(LLUUID::null); - mSpeakerCtrl->setVisible(getShowSpeaker()); -} - -void LLIMChiclet::setCounter(S32 counter) -{ - if (mCounterCtrl->getCounter() == counter) - { - return; - } - - mCounterCtrl->setCounter(counter); - setShowCounter(counter); - setShowNewMessagesIcon(counter); -} - -void LLIMChiclet::toggleCounterControl() -{ - setRequiredWidth(); - mCounterCtrl->setVisible(getShowCounter()); -} - void LLIMChiclet::setShowNewMessagesIcon(bool show) { if(mNewMessagesIcon) @@ -449,7 +149,6 @@ bool LLIMChiclet::getShowNewMessagesIcon() void LLIMChiclet::onMouseDown() { LLFloaterIMSession::toggle(getSessionId()); - setCounter(0); } void LLIMChiclet::setToggleState(bool toggle) @@ -457,52 +156,6 @@ void LLIMChiclet::setToggleState(bool toggle) mChicletButton->setToggleState(toggle); } -void LLIMChiclet::draw() -{ - LLUICtrl::draw(); -} - -// static -LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id) -{ - EType type = TYPE_UNKNOWN; - - if(session_id.isNull()) - return type; - - EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id); - if (IM_COUNT == im_type) - { - llassert_always(0 && "IM session not found"); // should never happen - return type; - } - - switch(im_type) - { - case IM_NOTHING_SPECIAL: - case IM_SESSION_P2P_INVITE: - type = TYPE_IM; - break; - case IM_SESSION_GROUP_START: - case IM_SESSION_INVITE: - if (gAgent.isInGroup(session_id)) - { - type = TYPE_GROUP; - } - else - { - type = TYPE_AD_HOC; - } - break; - case IM_SESSION_CONFERENCE_START: - type = TYPE_AD_HOC; - default: - break; - } - - return type; -} - BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) { if(!mPopupMenu) @@ -534,382 +187,6 @@ bool LLIMChiclet::canCreateMenu() return true; } -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLIMP2PChiclet::Params::Params() -: avatar_icon("avatar_icon") -, chiclet_button("chiclet_button") -, unread_notifications("unread_notifications") -, speaker("speaker") -, new_message_icon("new_message_icon") -, show_speaker("show_speaker") -{ -} - -LLIMP2PChiclet::LLIMP2PChiclet(const Params& p) -: LLIMChiclet(p) -, mChicletIconCtrl(NULL) -{ - LLButton::Params button_params = p.chiclet_button; - mChicletButton = LLUICtrlFactory::create(button_params); - addChild(mChicletButton); - - LLIconCtrl::Params new_msg_params = p.new_message_icon; - mNewMessagesIcon = LLUICtrlFactory::create(new_msg_params); - addChild(mNewMessagesIcon); - - LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; - mChicletIconCtrl = LLUICtrlFactory::create(avatar_params); - addChild(mChicletIconCtrl); - - LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; - mCounterCtrl = LLUICtrlFactory::create(unread_params); - addChild(mCounterCtrl); - - setCounter(getCounter()); - setShowCounter(getShowCounter()); - - LLChicletSpeakerCtrl::Params speaker_params = p.speaker; - mSpeakerCtrl = LLUICtrlFactory::create(speaker_params); - addChild(mSpeakerCtrl); - - sendChildToFront(mNewMessagesIcon); - setShowSpeaker(p.show_speaker); -} - -void LLIMP2PChiclet::initSpeakerControl() -{ - mSpeakerCtrl->setSpeakerId(getOtherParticipantId()); -} - -void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id) -{ - LLIMChiclet::setOtherParticipantId(other_participant_id); - mChicletIconCtrl->setValue(getOtherParticipantId()); -} - -void LLIMP2PChiclet::updateMenuItems() -{ - if(!mPopupMenu) - return; - if(getSessionId().isNull()) - return; - - LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(getSessionId()); - bool open_window_exists = open_im_floater && open_im_floater->getVisible(); - mPopupMenu->getChild("Send IM")->setEnabled(!open_window_exists); - - bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId()); - mPopupMenu->getChild("Add Friend")->setEnabled(!is_friend); -} - -void LLIMP2PChiclet::createPopupMenu() -{ - if(!canCreateMenu()) - return; - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2)); - - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile - ("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -} - -void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data) -{ - std::string level = user_data.asString(); - LLUUID other_participant_id = getOtherParticipantId(); - - if("profile" == level) - { - LLAvatarActions::showProfile(other_participant_id); - } - else if("im" == level) - { - LLAvatarActions::startIM(other_participant_id); - } - else if("add" == level) - { - LLAvatarActions::requestFriendshipDialog(other_participant_id); - } - else if("end" == level) - { - LLAvatarActions::endIM(other_participant_id); - } -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLAdHocChiclet::Params::Params() -: avatar_icon("avatar_icon") -, chiclet_button("chiclet_button") -, unread_notifications("unread_notifications") -, speaker("speaker") -, new_message_icon("new_message_icon") -, show_speaker("show_speaker") -, avatar_icon_color("avatar_icon_color", LLColor4::green) -{ -} - -LLAdHocChiclet::LLAdHocChiclet(const Params& p) -: LLIMChiclet(p) -, mChicletIconCtrl(NULL) -{ - LLButton::Params button_params = p.chiclet_button; - mChicletButton = LLUICtrlFactory::create(button_params); - addChild(mChicletButton); - - LLIconCtrl::Params new_msg_params = p.new_message_icon; - mNewMessagesIcon = LLUICtrlFactory::create(new_msg_params); - addChild(mNewMessagesIcon); - - LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; - mChicletIconCtrl = LLUICtrlFactory::create(avatar_params); - //Make the avatar modified - mChicletIconCtrl->setColor(p.avatar_icon_color); - addChild(mChicletIconCtrl); - - LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; - mCounterCtrl = LLUICtrlFactory::create(unread_params); - addChild(mCounterCtrl); - - setCounter(getCounter()); - setShowCounter(getShowCounter()); - - LLChicletSpeakerCtrl::Params speaker_params = p.speaker; - mSpeakerCtrl = LLUICtrlFactory::create(speaker_params); - addChild(mSpeakerCtrl); - - sendChildToFront(mNewMessagesIcon); - setShowSpeaker(p.show_speaker); -} - -void LLAdHocChiclet::setSessionId(const LLUUID& session_id) -{ - LLChiclet::setSessionId(session_id); - LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id); - mChicletIconCtrl->setValue(im_session->mOtherParticipantID); -} - -void LLAdHocChiclet::draw() -{ - switchToCurrentSpeaker(); - LLIMChiclet::draw(); -} - -void LLAdHocChiclet::initSpeakerControl() -{ - switchToCurrentSpeaker(); -} - -void LLAdHocChiclet::switchToCurrentSpeaker() -{ - LLUUID speaker_id; - LLSpeakerMgr::speaker_list_t speaker_list; - - LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE); - for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i) - { - LLPointer s = *i; - if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING) - { - speaker_id = s->mID; - break; - } - } - - mSpeakerCtrl->setSpeakerId(speaker_id); -} - -void LLAdHocChiclet::createPopupMenu() -{ - if(!canCreateMenu()) - return; - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("IMChicletMenu.Action", boost::bind(&LLAdHocChiclet::onMenuItemClicked, this, _2)); - - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile - ("menu_imchiclet_adhoc.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -} - -void LLAdHocChiclet::onMenuItemClicked(const LLSD& user_data) -{ - std::string level = user_data.asString(); - LLUUID group_id = getSessionId(); - - if("end" == level) - { - LLGroupActions::endIM(group_id); - } -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLIMGroupChiclet::Params::Params() -: group_icon("group_icon") -, chiclet_button("chiclet_button") -, unread_notifications("unread_notifications") -, speaker("speaker") -, new_message_icon("new_message_icon") -, show_speaker("show_speaker") -{ -} - -LLIMGroupChiclet::LLIMGroupChiclet(const Params& p) -: LLIMChiclet(p) -, LLGroupMgrObserver(LLUUID::null) -, mChicletIconCtrl(NULL) -{ - LLButton::Params button_params = p.chiclet_button; - mChicletButton = LLUICtrlFactory::create(button_params); - addChild(mChicletButton); - - LLIconCtrl::Params new_msg_params = p.new_message_icon; - mNewMessagesIcon = LLUICtrlFactory::create(new_msg_params); - addChild(mNewMessagesIcon); - - LLChicletGroupIconCtrl::Params avatar_params = p.group_icon; - mChicletIconCtrl = LLUICtrlFactory::create(avatar_params); - addChild(mChicletIconCtrl); - - LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; - mCounterCtrl = LLUICtrlFactory::create(unread_params); - addChild(mCounterCtrl); - - setCounter(getCounter()); - setShowCounter(getShowCounter()); - - LLChicletSpeakerCtrl::Params speaker_params = p.speaker; - mSpeakerCtrl = LLUICtrlFactory::create(speaker_params); - addChild(mSpeakerCtrl); - - sendChildToFront(mNewMessagesIcon); - setShowSpeaker(p.show_speaker); -} - -LLIMGroupChiclet::~LLIMGroupChiclet() -{ - LLGroupMgr::getInstance()->removeObserver(this); -} - -void LLIMGroupChiclet::draw() -{ - if(getShowSpeaker()) - { - switchToCurrentSpeaker(); - } - LLIMChiclet::draw(); -} - -void LLIMGroupChiclet::initSpeakerControl() -{ - switchToCurrentSpeaker(); -} - -void LLIMGroupChiclet::switchToCurrentSpeaker() -{ - LLUUID speaker_id; - LLSpeakerMgr::speaker_list_t speaker_list; - - LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE); - for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i) - { - LLPointer s = *i; - if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING) - { - speaker_id = s->mID; - break; - } - } - - mSpeakerCtrl->setSpeakerId(speaker_id); -} - -void LLIMGroupChiclet::setSessionId(const LLUUID& session_id) -{ - LLChiclet::setSessionId(session_id); - - LLGroupMgr* grp_mgr = LLGroupMgr::getInstance(); - LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id); - if (group_data && group_data->mInsigniaID.notNull()) - { - mChicletIconCtrl->setValue(group_data->mInsigniaID); - } - else - { - if(getSessionId() != mID) - { - grp_mgr->removeObserver(this); - mID = getSessionId(); - grp_mgr->addObserver(this); - } - grp_mgr->sendGroupPropertiesRequest(session_id); - } -} - -void LLIMGroupChiclet::changed(LLGroupChange gc) -{ - if (GC_PROPERTIES == gc) - { - LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId()); - if (group_data) - { - mChicletIconCtrl->setValue(group_data->mInsigniaID); - } - } -} - -void LLIMGroupChiclet::updateMenuItems() -{ - if(!mPopupMenu) - return; - if(getSessionId().isNull()) - return; - - LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(getSessionId()); - bool open_window_exists = open_im_floater && open_im_floater->getVisible(); - mPopupMenu->getChild("Chat")->setEnabled(!open_window_exists); -} - -void LLIMGroupChiclet::createPopupMenu() -{ - if(!canCreateMenu()) - return; - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2)); - - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile - ("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -} - -void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data) -{ - std::string level = user_data.asString(); - LLUUID group_id = getSessionId(); - - if("group chat" == level) - { - LLGroupActions::startIM(group_id); - } - else if("info" == level) - { - LLGroupActions::show(group_id); - } - else if("end" == level) - { - LLGroupActions::endIM(group_id); - } -} - - ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -964,20 +241,6 @@ void LLChicletPanel::onMessageCountChanged(const LLSD& data) { unread = 0; } - - std::list chiclets = LLIMChiclet::sFindChicletsSignal(session_id); - std::list::iterator iter; - for (iter = chiclets.begin(); iter != chiclets.end(); iter++) { - LLChiclet* chiclet = *iter; - if (chiclet != NULL) - { - chiclet->setCounter(unread); - } - else - { - llwarns << "Unable to set counter for chiclet " << session_id << llendl; - } - } } void LLChicletPanel::objectChicletCallback(const LLSD& data) @@ -992,10 +255,6 @@ void LLChicletPanel::objectChicletCallback(const LLSD& data) LLIMChiclet* chiclet = dynamic_cast(*iter); if (chiclet != NULL) { - if(data.has("unread")) - { - chiclet->setCounter(data["unread"]); - } chiclet->setShowNewMessagesIcon(new_message); } } @@ -1037,7 +296,6 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id) LLIMChiclet* chiclet = dynamic_cast(*it); if(chiclet) { - chiclet->setShowSpeaker(true); if (gSavedSettings.getBOOL("OpenIMOnVoice")) { LLFloaterIMContainer::getInstance()->showConversation(session_id); @@ -1045,20 +303,6 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id) } } - if(!s_previous_active_voice_session_id.isNull() && s_previous_active_voice_session_id != session_id) - { - chiclets = LLIMChiclet::sFindChicletsSignal(s_previous_active_voice_session_id); - - for(std::list::iterator it = chiclets.begin(); it != chiclets.end(); ++it) - { - LLIMChiclet* chiclet = dynamic_cast(*it); - if(chiclet) - { - chiclet->setShowSpeaker(false); - } - } - } - s_previous_active_voice_session_id = session_id; } @@ -1544,85 +788,6 @@ bool LLChicletPanel::isAnyIMFloaterDoked() return res; } -S32 LLChicletPanel::getTotalUnreadIMCount() -{ - S32 count = 0; - chiclet_list_t::const_iterator it = mChicletList.begin(); - for( ; mChicletList.end() != it; ++it) - { - LLIMChiclet* chiclet = dynamic_cast(*it); - if(chiclet) - { - count += chiclet->getCounter(); - } - } - return count; -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -LLChicletNotificationCounterCtrl::Params::Params() -: max_displayed_count("max_displayed_count", 99) -{ -} - -LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p) - : LLTextBox(p) - , mCounter(0) - , mInitialWidth(0) - , mMaxDisplayedCount(p.max_displayed_count) -{ - mInitialWidth = getRect().getWidth(); -} - -void LLChicletNotificationCounterCtrl::setCounter(S32 counter) -{ - mCounter = counter; - - // note same code in LLSysWellChiclet::setCounter(S32 counter) - std::string s_count; - if(counter != 0) - { - static std::string more_messages_exist("+"); - std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : ""); - s_count = llformat("%d%s" - , llmin(counter, mMaxDisplayedCount) - , more_messages.c_str() - ); - } - - if(mCounter != 0) - { - setText(s_count); - } - else - { - setText(std::string("")); - } -} - -LLRect LLChicletNotificationCounterCtrl::getRequiredRect() -{ - LLRect rc; - S32 text_width = getTextPixelWidth(); - - rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth); - - return rc; -} - -void LLChicletNotificationCounterCtrl::setValue(const LLSD& value) -{ - if(value.isInteger()) - setCounter(value.asInteger()); -} - -LLSD LLChicletNotificationCounterCtrl::getValue() const -{ - return LLSD(getCounter()); -} - ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -1632,28 +797,6 @@ LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p) { } -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLChicletGroupIconCtrl::LLChicletGroupIconCtrl(const Params& p) -: LLIconCtrl(p) -, mDefaultIcon(p.default_icon) -{ - setValue(LLUUID::null); -} - -void LLChicletGroupIconCtrl::setValue(const LLSD& value ) -{ - if(value.asUUID().isNull()) - { - LLIconCtrl::setValue(mDefaultIcon); - } - else - { - LLIconCtrl::setValue(value); - } -} ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -1681,15 +824,6 @@ void LLChicletInvOfferIconCtrl::setValue(const LLSD& value ) ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p) - : LLOutputMonitorCtrl(p) -{ -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - LLScriptChiclet::Params::Params() : icon("icon") , chiclet_button("chiclet_button") @@ -1725,11 +859,6 @@ void LLScriptChiclet::setSessionId(const LLUUID& session_id) setToolTip(LLScriptFloaterManager::getObjectName(session_id)); } -void LLScriptChiclet::setCounter(S32 counter) -{ - setShowNewMessagesIcon( counter > 0 ); -} - void LLScriptChiclet::onMouseDown() { LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId()); @@ -1808,11 +937,6 @@ void LLInvOfferChiclet::setSessionId(const LLUUID& session_id) } } -void LLInvOfferChiclet::setCounter(S32 counter) -{ - setShowNewMessagesIcon( counter > 0 ); -} - void LLInvOfferChiclet::onMouseDown() { LLScriptFloaterManager::instance().toggleScriptFloater(getSessionId()); diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 7f72c7f9e2..bd6c1a3e71 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -29,75 +29,10 @@ #include "llavatariconctrl.h" #include "llbutton.h" -#include "llflashtimer.h" -#include "llpanel.h" -#include "lltextbox.h" -#include "lloutputmonitorctrl.h" -#include "llgroupmgr.h" -#include "llimview.h" -#include "llnotifications.h" class LLMenuGL; class LLFloaterIMSession; -/** - * Class for displaying amount of messages/notifications(unread). - */ -class LLChicletNotificationCounterCtrl : public LLTextBox -{ -public: - - struct Params : public LLInitParam::Block - { - /** - * Contains maximum displayed count of unread messages. Default value is 9. - * - * If count is less than "max_unread_count" will be displayed as is. - * Otherwise 9+ will be shown (for default value). - */ - Optional max_displayed_count; - - Params(); - }; - - /** - * Sets number of notifications - */ - virtual void setCounter(S32 counter); - - /** - * Returns number of notifications - */ - virtual S32 getCounter() const { return mCounter; } - - /** - * Returns width, required to display amount of notifications in text form. - * Width is the only valid value. - */ - /*virtual*/ LLRect getRequiredRect(); - - /** - * Sets number of notifications using LLSD - */ - /*virtual*/ void setValue(const LLSD& value); - - /** - * Returns number of notifications wrapped in LLSD - */ - /*virtual*/ LLSD getValue() const; - -protected: - - LLChicletNotificationCounterCtrl(const Params& p); - friend class LLUICtrlFactory; - -private: - - S32 mCounter; - S32 mInitialWidth; - S32 mMaxDisplayedCount; -}; - /** * Class for displaying avatar's icon in P2P chiclet. */ @@ -121,35 +56,6 @@ protected: friend class LLUICtrlFactory; }; -/** - * Class for displaying group's icon in Group chiclet. - */ -class LLChicletGroupIconCtrl : public LLIconCtrl -{ -public: - - struct Params : public LLInitParam::Block - { - Optional default_icon; - - Params() - : default_icon("default_icon", "Generic_Group") - {} - }; - - /** - * Sets icon, if value is LLUUID::null - default icon will be set. - */ - virtual void setValue(const LLSD& value ); - -protected: - - LLChicletGroupIconCtrl(const Params& p); - friend class LLUICtrlFactory; - - std::string mDefaultIcon; -}; - /** * Class for displaying icon in inventory offer chiclet. */ @@ -183,23 +89,6 @@ private: std::string mDefaultIcon; }; -/** - * Class for displaying of speaker's voice indicator - */ -class LLChicletSpeakerCtrl : public LLOutputMonitorCtrl -{ -public: - - struct Params : public LLInitParam::Block - { - Params(){}; - }; -protected: - - LLChicletSpeakerCtrl(const Params&p); - friend class LLUICtrlFactory; -}; - /** * Base class for all chiclets. */ @@ -227,26 +116,6 @@ public: */ virtual const LLUUID& getSessionId() const { return mSessionId; } - /** - * Sets number of unread notifications. - */ - virtual void setCounter(S32 counter) = 0; - - /** - * Returns number of unread notifications. - */ - virtual S32 getCounter() = 0; - - /** - * Sets show counter state. - */ - virtual void setShowCounter(bool show) { mShowCounter = show; } - - /** - * Returns show counter state. - */ - virtual bool getShowCounter() {return mShowCounter;}; - /** * Connects chiclet clicked event with callback. */ @@ -324,62 +193,6 @@ public: * It is used for default setting up of chicklet:click handler, etc. */ BOOL postBuild(); - /** - * Sets IM session name. This name will be displayed in chiclet tooltip. - */ - virtual void setIMSessionName(const std::string& name) { setToolTip(name); } - - /** - * Sets id of person/group user is chatting with. - * Session id should be set before calling this - */ - virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; } - - /** - * Gets id of person/group user is chatting with. - */ - virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; } - - /** - * Init Speaker Control with speaker's ID - */ - virtual void initSpeakerControl(); - - /** - * set status (Shows/Hide) for voice control. - */ - virtual void setShowSpeaker(bool show); - - /** - * Returns voice chat status control visibility. - */ - virtual bool getShowSpeaker() {return mShowSpeaker;}; - - /** - * Shows/Hides for voice control for a chiclet. - */ - virtual void toggleSpeakerControl(); - - /** - * Sets number of unread messages. Will update chiclet's width if number text - * exceeds size of counter and notify it's parent about size change. - */ - virtual void setCounter(S32); - - /** - * Enables/disables the counter control for a chiclet. - */ - virtual void enableCounterControl(bool enable); - - /** - * Sets show counter state. - */ - virtual void setShowCounter(bool show); - - /** - * Shows/Hides for counter control for a chiclet. - */ - virtual void toggleCounterControl(); /** * Sets required width for a chiclet according to visible controls. @@ -396,21 +209,6 @@ public: */ virtual bool getShowNewMessagesIcon(); - virtual void draw(); - - /** - * Determine whether given ID refers to a group or an IM chat session. - * - * This is used when we need to chose what IM chiclet (P2P/group) - * class to instantiate. - * - * @param session_id session ID. - * @return TYPE_GROUP in case of group chat session, - * TYPE_IM in case of P2P session, - * TYPE_UNKNOWN otherwise. - */ - static EType getIMSessionType(const LLUUID& session_id); - /** * The action taken on mouse down event. * @@ -452,8 +250,6 @@ protected: S32 mDefaultWidth; LLIconCtrl* mNewMessagesIcon; - LLChicletNotificationCounterCtrl* mCounterCtrl; - LLChicletSpeakerCtrl* mSpeakerCtrl; LLButton* mChicletButton; /** the id of another participant, either an avatar id or a group id*/ @@ -481,137 +277,6 @@ public: sFindChicletsSignal; }; -/** - * Implements P2P chiclet. - */ -class LLIMP2PChiclet : public LLIMChiclet -{ -public: - struct Params : public LLInitParam::Block - { - Optional chiclet_button; - - Optional avatar_icon; - - Optional unread_notifications; - - Optional speaker; - - Optional new_message_icon; - - Optional show_speaker; - - Params(); - }; - - /* virtual */ void setOtherParticipantId(const LLUUID& other_participant_id); - - /** - * Init Speaker Control with speaker's ID - */ - /*virtual*/ void initSpeakerControl(); - - /** - * Returns number of unread messages. - */ - /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } - -protected: - LLIMP2PChiclet(const Params& p); - friend class LLUICtrlFactory; - - /** - * Creates chiclet popup menu. Will create P2P or Group IM Chat menu - * based on other participant's id. - */ - virtual void createPopupMenu(); - - /** - * Processes clicks on chiclet popup menu. - */ - virtual void onMenuItemClicked(const LLSD& user_data); - - /** - * Enables/disables menus based on relationship with other participant. - * Enables/disables "show session" menu item depending on visible IM floater existence. - */ - virtual void updateMenuItems(); - -private: - - LLChicletAvatarIconCtrl* mChicletIconCtrl; -}; - -/** - * Implements AD-HOC chiclet. - */ -class LLAdHocChiclet : public LLIMChiclet -{ -public: - struct Params : public LLInitParam::Block - { - Optional chiclet_button; - - Optional avatar_icon; - - Optional unread_notifications; - - Optional speaker; - - Optional new_message_icon; - - Optional show_speaker; - - Optional avatar_icon_color; - - Params(); - }; - - /** - * Sets session id. - * Session ID for group chat is actually Group ID. - */ - /*virtual*/ void setSessionId(const LLUUID& session_id); - - /** - * Keep Speaker Control with actual speaker's ID - */ - /*virtual*/ void draw(); - - /** - * Init Speaker Control with speaker's ID - */ - /*virtual*/ void initSpeakerControl(); - - /** - * Returns number of unread messages. - */ - /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } - -protected: - LLAdHocChiclet(const Params& p); - friend class LLUICtrlFactory; - - /** - * Creates chiclet popup menu. Will create AdHoc Chat menu - * based on other participant's id. - */ - virtual void createPopupMenu(); - - /** - * Processes clicks on chiclet popup menu. - */ - virtual void onMenuItemClicked(const LLSD& user_data); - - /** - * Finds a current speaker and resets the SpeakerControl with speaker's ID - */ - /*virtual*/ void switchToCurrentSpeaker(); - -private: - - LLChicletAvatarIconCtrl* mChicletIconCtrl; -}; /** * Chiclet for script floaters. @@ -633,10 +298,6 @@ public: /*virtual*/ void setSessionId(const LLUUID& session_id); - /*virtual*/ void setCounter(S32 counter); - - /*virtual*/ S32 getCounter() { return 0; } - /** * Toggle script floater */ @@ -682,10 +343,6 @@ public: /*virtual*/ void setSessionId(const LLUUID& session_id); - /*virtual*/ void setCounter(S32 counter); - - /*virtual*/ S32 getCounter() { return 0; } - /** * Toggle script floater */ @@ -709,214 +366,6 @@ private: LLChicletInvOfferIconCtrl* mChicletIconCtrl; }; -/** - * Implements Group chat chiclet. - */ -class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver -{ -public: - - struct Params : public LLInitParam::Block - { - Optional chiclet_button; - - Optional group_icon; - - Optional unread_notifications; - - Optional speaker; - - Optional new_message_icon; - - Optional show_speaker; - - Params(); - }; - - /** - * Sets session id. - * Session ID for group chat is actually Group ID. - */ - /*virtual*/ void setSessionId(const LLUUID& session_id); - - /** - * Keep Speaker Control with actual speaker's ID - */ - /*virtual*/ void draw(); - - /** - * Callback for LLGroupMgrObserver, we get this when group data is available or changed. - * Sets group icon. - */ - /*virtual*/ void changed(LLGroupChange gc); - - /** - * Init Speaker Control with speaker's ID - */ - /*virtual*/ void initSpeakerControl(); - - /** - * Returns number of unread messages. - */ - /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } - - ~LLIMGroupChiclet(); - -protected: - LLIMGroupChiclet(const Params& p); - friend class LLUICtrlFactory; - - /** - * Finds a current speaker and resets the SpeakerControl with speaker's ID - */ - /*virtual*/ void switchToCurrentSpeaker(); - - /** - * Creates chiclet popup menu. Will create P2P or Group IM Chat menu - * based on other participant's id. - */ - virtual void createPopupMenu(); - - /** - * Processes clicks on chiclet popup menu. - */ - virtual void onMenuItemClicked(const LLSD& user_data); - - /** - * Enables/disables "show session" menu item depending on visible IM floater existence. - */ - virtual void updateMenuItems(); - -private: - - LLChicletGroupIconCtrl* mChicletIconCtrl; -}; - -/** - * Implements notification chiclet. Used to display total amount of unread messages - * across all IM sessions, total amount of system notifications. See EXT-3147 for details - */ -class LLSysWellChiclet : public LLChiclet -{ -public: - - struct Params : public LLInitParam::Block - { - Optional button; - - Optional unread_notifications; - - /** - * Contains maximum displayed count of unread messages. Default value is 9. - * - * If count is less than "max_unread_count" will be displayed as is. - * Otherwise 9+ will be shown (for default value). - */ - Optional max_displayed_count; - - Params(); - }; - - /*virtual*/ void setCounter(S32 counter); - - // *TODO: mantipov: seems getCounter is not necessary for LLNotificationChiclet - // but inherited interface requires it to implement. - // Probably it can be safe removed. - /*virtual*/S32 getCounter() { return mCounter; } - - boost::signals2::connection setClickCallback(const commit_callback_t& cb); - - /*virtual*/ ~LLSysWellChiclet(); - - void setToggleState(BOOL toggled); - - void setNewMessagesState(bool new_messages); - //this method should change a widget according to state of the SysWellWindow - virtual void updateWidget(bool is_window_empty); - -protected: - - LLSysWellChiclet(const Params& p); - friend class LLUICtrlFactory; - - /** - * Change Well 'Lit' state from 'Lit' to 'Unlit' and vice-versa. - * - * There is an assumption that it will be called 2*N times to do not change its start state. - * @see FlashToLitTimer - */ - void changeLitState(bool blink); - - /** - * Displays menu. - */ - virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - - virtual void createMenu() = 0; - -protected: - class FlashToLitTimer; - LLButton* mButton; - S32 mCounter; - S32 mMaxDisplayedCount; - bool mIsNewMessagesState; - - LLFlashTimer* mFlashToLitTimer; - LLContextMenu* mContextMenu; -}; - -class LLNotificationChiclet : public LLSysWellChiclet -{ - LOG_CLASS(LLNotificationChiclet); - - friend class LLUICtrlFactory; -public: - struct Params : public LLInitParam::Block{}; - -protected: - struct ChicletNotificationChannel : public LLNotificationChannel - { - ChicletNotificationChannel(LLNotificationChiclet* chiclet) - : LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString())), - mChiclet(chiclet) - { - // connect counter handlers to the signals - connectToChannel("Group Notifications"); - connectToChannel("Offer"); - connectToChannel("Notifications"); - } - - static bool filterNotification(LLNotificationPtr notify); - // connect counter updaters to the corresponding signals - /*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); } - /*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); } - - LLNotificationChiclet* const mChiclet; - }; - - boost::scoped_ptr mNotificationChannel; - - LLNotificationChiclet(const Params& p); - - /** - * Processes clicks on chiclet menu. - */ - void onMenuItemClicked(const LLSD& user_data); - - /** - * Enables chiclet menu items. - */ - bool enableMenuItem(const LLSD& user_data); - - /** - * Creates menu. - */ - /*virtual*/ void createMenu(); - - /*virtual*/ void setCounter(S32 counter); - S32 mUreadSystemNotifications; -}; - /** * Storage class for all IM chiclets. Provides mechanism to display, * scroll, create, remove chiclets. @@ -1018,9 +467,7 @@ public: S32 getMinWidth() const { return mMinWidth; } - S32 getTotalUnreadIMCount(); - - S32 notifyParent(const LLSD& info); + /*virtual*/ S32 notifyParent(const LLSD& info); /** * Toggle chiclet by session id ON and toggle OFF all other chiclets. diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp index cfcde64e7b..fde7764129 100644 --- a/indra/newview/llchicletbar.cpp +++ b/indra/newview/llchicletbar.cpp @@ -25,18 +25,11 @@ */ #include "llviewerprecompiledheaders.h" // must be first include - #include "llchicletbar.h" -// library includes -#include "llfloaterreg.h" -#include "lllayoutstack.h" - -// newview includes #include "llchiclet.h" -#include "llfloaterimsession.h" // for LLFloaterIMSession +#include "lllayoutstack.h" #include "llpaneltopinfobar.h" -#include "llsyswellwindow.h" namespace { @@ -60,106 +53,11 @@ LLChicletBar::LLChicletBar(const LLSD&) buildFromFile("panel_chiclet_bar.xml"); } -LLChicletBar::~LLChicletBar() -{ -} - -LLIMChiclet* LLChicletBar::createIMChiclet(const LLUUID& session_id) -{ - LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(session_id); - - switch (im_chiclet_type) - { - case LLIMChiclet::TYPE_IM: - return getChicletPanel()->createChiclet(session_id); - case LLIMChiclet::TYPE_GROUP: - return getChicletPanel()->createChiclet(session_id); - case LLIMChiclet::TYPE_AD_HOC: - return getChicletPanel()->createChiclet(session_id); - case LLIMChiclet::TYPE_UNKNOWN: - break; - } - - return NULL; -} - -//virtual -void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) -{ - if (!getChicletPanel()) return; - - LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id); - if (!session) return; - - // no need to spawn chiclets for participants in P2P calls called through Avaline - if (session->isP2P() && session->isOtherParticipantAvaline()) return; - - // Do not spawn chiclet when using the new multitab conversation UI - if (LLFloaterIMSessionTab::isChatMultiTab()) - { - LLFloaterIMSessionTab::addToHost(session_id); - return; - } - - if (getChicletPanel()->findChiclet(session_id)) return; - - LLIMChiclet* chiclet = createIMChiclet(session_id); - if(chiclet) - { - chiclet->setIMSessionName(name); - chiclet->setOtherParticipantId(other_participant_id); - - LLFloaterIMSession::onIMChicletCreated(session_id); - - } - else - { - llwarns << "Could not create chiclet" << llendl; - } -} - -//virtual -void LLChicletBar::sessionRemoved(const LLUUID& session_id) -{ - if(getChicletPanel()) - { - // IM floater should be closed when session removed and associated chiclet closed - LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance("impanel", session_id); - if (im_floater != NULL && !im_floater->getStartConferenceInSameFloater()) - { - // Close the IM floater only if we are not planning to close the P2P chat - // and start a new conference in the same floater. - im_floater->closeFloater(); - } - - getChicletPanel()->removeChiclet(session_id); - } -} - -void LLChicletBar::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) -{ - //this is only needed in case of outgoing ad-hoc/group chat sessions - LLChicletPanel* chiclet_panel = getChicletPanel(); - if (chiclet_panel) - { - //it should be ad-hoc im chiclet or group im chiclet - LLChiclet* chiclet = chiclet_panel->findChiclet(old_session_id); - if (chiclet) chiclet->setSessionId(new_session_id); - } -} - -S32 LLChicletBar::getTotalUnreadIMCount() -{ - return getChicletPanel()->getTotalUnreadIMCount(); -} - BOOL LLChicletBar::postBuild() { mToolbarStack = getChild("toolbar_stack"); mChicletPanel = getChild("chiclet_list"); - showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty()); - LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this)); LLPanelTopInfoBar::instance().setVisibleCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this)); diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h index dc991ca772..956c82cb77 100644 --- a/indra/newview/llchicletbar.h +++ b/indra/newview/llchicletbar.h @@ -28,7 +28,6 @@ #define LL_LLCHICLETBAR_H #include "llpanel.h" -#include "llimview.h" class LLChicletPanel; class LLIMChiclet; @@ -38,32 +37,17 @@ class LLLayoutStack; class LLChicletBar : public LLSingleton , public LLPanel - , public LLIMSessionObserver { LOG_CLASS(LLChicletBar); friend class LLSingleton; public: - ~LLChicletBar(); BOOL postBuild(); LLChicletPanel* getChicletPanel() { return mChicletPanel; } - // LLIMSessionObserver observe triggers - /*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg); - /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}; - /*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {}; - /*virtual*/ void sessionRemoved(const LLUUID& session_id); - /*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); - - S32 getTotalUnreadIMCount(); - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); - /** - * Creates IM Chiclet based on session type (IM chat or Group chat) - */ - LLIMChiclet* createIMChiclet(const LLUUID& session_id); /** * Shows/hides panel with specified well button (IM or Notification) diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 212b0df712..9829ae713c 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -616,10 +616,14 @@ void LLFloaterIMSession::setVisible(BOOL visible) if(!visible) { - LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet(mSessionID); - if(chiclet) + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - chiclet->setToggleState(false); + LLIMChiclet * chicletp = chiclet_panelp->findChiclet(mSessionID); + if(NULL != chicletp) + { + chicletp->setToggleState(false); + } } } diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp index dc12192697..0e0da6bdc7 100644 --- a/indra/newview/llscriptfloater.cpp +++ b/indra/newview/llscriptfloater.cpp @@ -95,7 +95,12 @@ bool LLScriptFloater::toggle(const LLUUID& notification_id) show(notification_id); } - LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(notification_id, true); + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) + { + chiclet_panelp->setChicletToggleState(notification_id, true); + } + return true; } @@ -206,10 +211,14 @@ void LLScriptFloater::setVisible(BOOL visible) if(!visible) { - LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet(getNotificationId()); - if(chiclet) + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - chiclet->setToggleState(false); + LLIMChiclet * chicletp = chiclet_panelp->findChiclet(getNotificationId()); + if(NULL != chicletp) + { + chicletp->setToggleState(false); + } } } } @@ -218,15 +227,19 @@ void LLScriptFloater::onMouseDown() { if(getNotificationId().notNull()) { - // Remove new message icon - LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet(getNotificationId()); - if (chiclet == NULL) + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - llerror("Dock chiclet for LLScriptFloater doesn't exist", 0); - } - else - { - chiclet->setShowNewMessagesIcon(false); + LLIMChiclet * chicletp = chiclet_panelp->findChiclet(getNotificationId()); + // Remove new message icon + if (NULL == chicletp) + { + llerror("Dock chiclet for LLScriptFloater doesn't exist", 0); + } + else + { + chicletp->setShowNewMessagesIcon(false); + } } } } @@ -262,7 +275,11 @@ void LLScriptFloater::onFocusLost() { if(getNotificationId().notNull()) { - LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), false); + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) + { + chiclet_panelp->setChicletToggleState(getNotificationId(), false); + } } } @@ -271,7 +288,11 @@ void LLScriptFloater::onFocusReceived() // first focus will be received before setObjectId() call - don't toggle chiclet if(getNotificationId().notNull()) { - LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), true); + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) + { + chiclet_panelp->setChicletToggleState(getNotificationId(), true); + } } } @@ -279,28 +300,30 @@ void LLScriptFloater::dockToChiclet(bool dock) { if (getDockControl() == NULL) { - LLChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet(getNotificationId()); - if (chiclet == NULL) - { - llwarns << "Dock chiclet for LLScriptFloater doesn't exist" << llendl; - return; - } - else + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - LLChicletBar::getInstance()->getChicletPanel()->scrollToChiclet(chiclet); - } + LLChiclet * chicletp = chiclet_panelp->findChiclet(getNotificationId()); + if (NULL == chicletp) + { + llwarns << "Dock chiclet for LLScriptFloater doesn't exist" << llendl; + return; + } - // Stop saving position while we dock floater - bool save = getSavePosition(); - setSavePosition(false); + chiclet_panelp->scrollToChiclet(chicletp); - setDockControl(new LLDockControl(chiclet, this, getDockTongue(), - LLDockControl::BOTTOM)); + // Stop saving position while we dock floater + bool save = getSavePosition(); + setSavePosition(false); - setDocked(dock); + setDockControl(new LLDockControl(chicletp, this, getDockTongue(), + LLDockControl::BOTTOM)); - // Restore saving - setSavePosition(save); + setDocked(dock); + + // Restore saving + setSavePosition(save); + } } } @@ -347,11 +370,15 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id) script_notification_map_t::const_iterator it = findUsingObjectId(object_id); if(it != mNotifications.end()) { - LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet(it->first); - if(chiclet) + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - // Pass the new_message icon state further. - set_new_message = chiclet->getShowNewMessagesIcon(); + LLIMChiclet * chicletp = chiclet_panelp->findChiclet(it->first); + if(NULL != chicletp) + { + // Pass the new_message icon state further. + set_new_message = chicletp->getShowNewMessagesIcon(); + } } LLScriptFloater* floater = LLFloaterReg::findTypedInstance("script_floater", it->first); @@ -367,14 +394,18 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id) mNotifications.insert(std::make_pair(notification_id, object_id)); - // Create inventory offer chiclet for offer type notifications - if( OBJ_GIVE_INVENTORY == obj_type ) + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) { - LLChicletBar::instance().getChicletPanel()->createChiclet(notification_id); - } - else - { - LLChicletBar::getInstance()->getChicletPanel()->createChiclet(notification_id); + // Create inventory offer chiclet for offer type notifications + if( OBJ_GIVE_INVENTORY == obj_type ) + { + chiclet_panelp->createChiclet(notification_id); + } + else + { + chiclet_panelp->createChiclet(notification_id); + } } LLIMWellWindow::getInstance()->addObjectRow(notification_id, set_new_message); @@ -410,7 +441,11 @@ void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id) // remove related chiclet if (LLChicletBar::instanceExists()) { - LLChicletBar::getInstance()->getChicletPanel()->removeChiclet(notification_id); + LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); + if (NULL != chiclet_panelp) + { + chiclet_panelp->removeChiclet(notification_id); + } } LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance(); diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 3605129d48..8a43855a7d 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -23,35 +23,23 @@ * $/LicenseInfo$ */ - #include "llviewerprecompiledheaders.h" // must be first include - #include "llsyswellwindow.h" -#include "llagent.h" -#include "llavatarnamecache.h" - -#include "llflatlistview.h" -#include "llfloaterreg.h" -#include "llnotifications.h" - -#include "llscriptfloater.h" -#include "llviewercontrol.h" -#include "llviewerwindow.h" - #include "llchiclet.h" #include "llchicletbar.h" -#include "lltoastpanel.h" +#include "llflatlistview.h" +#include "llfloaterreg.h" #include "llnotificationmanager.h" #include "llnotificationsutil.h" +#include "llscriptfloater.h" #include "llspeakers.h" -#include "lltoolbarview.h" +#include "lltoastpanel.h" //--------------------------------------------------------------------------------- LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLTransientDockableFloater(NULL, true, key), mChannel(NULL), mMessageList(NULL), - mSysWellChiclet(NULL), NOTIFICATION_WELL_ANCHOR_NAME("notification_well_panel"), IM_WELL_ANCHOR_NAME("im_well_panel"), mIsReshapedByUser(false) @@ -68,10 +56,6 @@ BOOL LLSysWellWindow::postBuild() // get a corresponding channel initChannel(); - // click on SysWell Window should clear "new message" state (and 'Lit' status). EXT-3147. - // mouse up callback is not called in this case. - setMouseDownCallback(boost::bind(&LLSysWellWindow::releaseNewMessagesState, this)); - return LLTransientDockableFloater::postBuild(); } @@ -95,14 +79,6 @@ void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask) setVisible(TRUE); } -void LLSysWellWindow::setSysWellChiclet(LLSysWellChiclet* chiclet) -{ - mSysWellChiclet = chiclet; - if(NULL != mSysWellChiclet) - { - mSysWellChiclet->updateWidget(isWindowEmpty()); - } -} //--------------------------------------------------------------------------------- LLSysWellWindow::~LLSysWellWindow() { @@ -113,10 +89,6 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id) { if(mMessageList->removeItemByValue(id)) { - if (NULL != mSysWellChiclet) - { - mSysWellChiclet->updateWidget(isWindowEmpty()); - } reshapeWindow(); } else @@ -170,11 +142,6 @@ void LLSysWellWindow::setVisible(BOOL visible) mChannel->updateShowToastsState(); mChannel->redrawToasts(); } - - if (visible) - { - releaseNewMessagesState(); - } } //--------------------------------------------------------------------------------- @@ -224,135 +191,12 @@ void LLSysWellWindow::reshapeWindow() } } -void LLSysWellWindow::releaseNewMessagesState() -{ - if (NULL != mSysWellChiclet) - { - mSysWellChiclet->setNewMessagesState(false); - } -} - //--------------------------------------------------------------------------------- bool LLSysWellWindow::isWindowEmpty() { return mMessageList->size() == 0; } -/************************************************************************/ -/* RowPanel implementation */ -/************************************************************************/ - -//--------------------------------------------------------------------------------- -LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, - S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) : - LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent) -{ - buildFromFile( "panel_activeim_row.xml"); - - // Choose which of the pre-created chiclets (IM/group) to use. - // The other one gets hidden. - - LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(sessionId); - switch (im_chiclet_type) - { - case LLIMChiclet::TYPE_GROUP: - mChiclet = getChild("group_chiclet"); - break; - case LLIMChiclet::TYPE_AD_HOC: - mChiclet = getChild("adhoc_chiclet"); - break; - case LLIMChiclet::TYPE_UNKNOWN: // assign mChiclet a non-null value anyway - case LLIMChiclet::TYPE_IM: - mChiclet = getChild("p2p_chiclet"); - break; - } - - // Initialize chiclet. - mChiclet->setChicletSizeChangedCallback(boost::bind(&LLIMWellWindow::RowPanel::onChicletSizeChanged, this, mChiclet, _2)); - mChiclet->enableCounterControl(true); - mChiclet->setCounter(chicletCounter); - mChiclet->setSessionId(sessionId); - mChiclet->setIMSessionName(name); - mChiclet->setOtherParticipantId(otherParticipantId); - mChiclet->setVisible(true); - - if (im_chiclet_type == LLIMChiclet::TYPE_IM) - { - LLAvatarNameCache::get(otherParticipantId, - boost::bind(&LLIMWellWindow::RowPanel::onAvatarNameCache, - this, _1, _2)); - } - else - { - LLTextBox* contactName = getChild("contact_name"); - contactName->setValue(name); - } - - mCloseBtn = getChild("hide_btn"); - mCloseBtn->setCommitCallback(boost::bind(&LLIMWellWindow::RowPanel::onClosePanel, this)); -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::RowPanel::onAvatarNameCache(const LLUUID& agent_id, - const LLAvatarName& av_name) -{ - LLTextBox* contactName = getChild("contact_name"); - contactName->setValue( av_name.getCompleteName() ); -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::RowPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param) -{ - LLTextBox* text = getChild("contact_name"); - S32 new_text_left = mChiclet->getRect().mRight + CHICLET_HPAD; - LLRect text_rect = text->getRect(); - text_rect.mLeft = new_text_left; - text->setShape(text_rect); -} - -//--------------------------------------------------------------------------------- -LLIMWellWindow::RowPanel::~RowPanel() -{ -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::RowPanel::onClosePanel() -{ - gIMMgr->leaveSession(mChiclet->getSessionId()); - // This row panel will be removed from the list in LLSysWellWindow::sessionRemoved(). -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask) -{ - setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected")); -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask) -{ - setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected")); -} - -//--------------------------------------------------------------------------------- -// virtual -BOOL LLIMWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask) -{ - // Pass the mouse down event to the chiclet (EXT-596). - if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown() - { - mChiclet->onMouseDown(); - return TRUE; - } - - return LLPanel::handleMouseDown(x, y, mask); -} - -// virtual -BOOL LLIMWellWindow::RowPanel::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - return mChiclet->handleRightMouseDown(x, y, mask); -} /************************************************************************/ /* ObjectRowPanel implementation */ /************************************************************************/ @@ -490,9 +334,7 @@ void LLNotificationWellWindow::addItem(LLSysWellItem::Params p) LLSysWellItem* new_item = new LLSysWellItem(p); if (mMessageList->addItem(new_item, value, ADD_TOP)) { - mSysWellChiclet->updateWidget(isWindowEmpty()); reshapeWindow(); - new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1)); new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1)); } @@ -576,9 +418,6 @@ void LLNotificationWellWindow::onAdd( LLNotificationPtr notify ) removeItemByID(notify->getID()); } - - - /************************************************************************/ /* LLIMWellWindow implementation */ /************************************************************************/ @@ -588,12 +427,10 @@ void LLNotificationWellWindow::onAdd( LLNotificationPtr notify ) LLIMWellWindow::LLIMWellWindow(const LLSD& key) : LLSysWellWindow(key) { - LLIMMgr::getInstance()->addSessionObserver(this); } LLIMWellWindow::~LLIMWellWindow() { - LLIMMgr::getInstance()->removeSessionObserver(this); } // static @@ -614,47 +451,11 @@ BOOL LLIMWellWindow::postBuild() BOOL rv = LLSysWellWindow::postBuild(); setTitle(getString("title_im_well_window")); - LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findIMChiclet, this, _1)); LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findObjectChiclet, this, _1)); return rv; } -//virtual -void LLIMWellWindow::sessionAdded(const LLUUID& session_id, - const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) -{ - LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id); - if (!session) return; - - // no need to spawn chiclets for participants in P2P calls called through Avaline - if (session->isP2P() && session->isOtherParticipantAvaline()) return; - - if (mMessageList->getItemByValue(session_id)) return; - - addIMRow(session_id, 0, name, other_participant_id); - reshapeWindow(); -} - -//virtual -void LLIMWellWindow::sessionRemoved(const LLUUID& sessionId) -{ - delIMRow(sessionId); - reshapeWindow(); -} - -//virtual -void LLIMWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) -{ - //for outgoing ad-hoc and group im sessions only - LLChiclet* chiclet = findIMChiclet(old_session_id); - if (chiclet) - { - chiclet->setSessionId(new_session_id); - mMessageList->updateValue(old_session_id, new_session_id); - } -} - LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id) { if (!mMessageList) return NULL; @@ -671,66 +472,6 @@ LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id) ////////////////////////////////////////////////////////////////////////// // PRIVATE METHODS -LLChiclet* LLIMWellWindow::findIMChiclet(const LLUUID& sessionId) -{ - if (!mMessageList) return NULL; - - LLChiclet* res = NULL; - RowPanel* panel = mMessageList->getTypedItemByValue(sessionId); - if (panel != NULL) - { - res = panel->mChiclet; - } - - return res; -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter, - const std::string& name, const LLUUID& otherParticipantId) -{ - RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId); - if (!mMessageList->addItem(item, sessionId)) - { - llwarns << "Unable to add IM Row into the list, sessionID: " << sessionId - << ", name: " << name - << ", other participant ID: " << otherParticipantId - << llendl; - - item->die(); - } -} - -//--------------------------------------------------------------------------------- -void LLIMWellWindow::delIMRow(const LLUUID& sessionId) -{ - //fix for EXT-3252 - //without this line LLIMWellWindow receive onFocusLost - //and hide itself. It was becaue somehow LLIMChicklet was in focus group for - //LLIMWellWindow... - //But I didn't find why this happen.. - gFocusMgr.clearLastFocusForGroup(this); - - if (!mMessageList->removeItemByValue(sessionId)) - { - llwarns << "Unable to remove IM Row from the list, sessionID: " << sessionId - << llendl; - } - - // remove all toasts that belong to this session from a screen - if(mChannel) - mChannel->removeToastsBySessionID(sessionId); - - // hide chiclet window if there are no items left - if(isWindowEmpty()) - { - setVisible(FALSE); - } - else - { - setFocus(true); - } -} void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_message/* = false*/) { @@ -761,21 +502,6 @@ void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id) } } - -void LLIMWellWindow::addIMRow(const LLUUID& session_id) -{ - if (hasIMRow(session_id)) return; - - LLIMModel* im_model = LLIMModel::getInstance(); - addIMRow(session_id, 0, im_model->getName(session_id), im_model->getOtherParticipantID(session_id)); - reshapeWindow(); -} - -bool LLIMWellWindow::hasIMRow(const LLUUID& session_id) -{ - return mMessageList->getItemByValue(session_id); -} - void LLIMWellWindow::closeAll() { // Generate an ignorable alert dialog if there is an active voice IM sesion @@ -820,13 +546,6 @@ void LLIMWellWindow::closeAllImpl() { LLPanel* panel = mMessageList->getItemByValue(*iter); - RowPanel* im_panel = dynamic_cast (panel); - if (im_panel) - { - gIMMgr->leaveSession(*iter); - continue; - } - ObjectRowPanel* obj_panel = dynamic_cast (panel); if (obj_panel) { diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index d6480f1fc6..406ab1b59e 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -27,32 +27,26 @@ #ifndef LL_LLSYSWELLWINDOW_H #define LL_LLSYSWELLWINDOW_H -#include "llsyswellitem.h" - -#include "lltransientdockablefloater.h" -#include "llbutton.h" -#include "llscreenchannel.h" -#include "llscrollcontainer.h" #include "llimview.h" #include "llnotifications.h" - -#include "boost/shared_ptr.hpp" +#include "llscreenchannel.h" +#include "llsyswellitem.h" +#include "lltransientdockablefloater.h" class LLAvatarName; -class LLFlatListView; class LLChiclet; +class LLFlatListView; class LLIMChiclet; class LLScriptChiclet; class LLSysWellChiclet; - class LLSysWellWindow : public LLTransientDockableFloater { public: LOG_CLASS(LLSysWellWindow); LLSysWellWindow(const LLSD& key); - ~LLSysWellWindow(); + virtual ~LLSysWellWindow(); BOOL postBuild(); // other interface functions @@ -72,8 +66,6 @@ public: void onStartUpToastClick(S32 x, S32 y, MASK mask); - void setSysWellChiclet(LLSysWellChiclet* chiclet); - // size constants for the window and for its elements static const S32 MAX_WINDOW_HEIGHT = 200; static const S32 MIN_WINDOW_WIDTH = 318; @@ -87,17 +79,11 @@ protected: virtual const std::string& getAnchorViewName() = 0; void reshapeWindow(); - void releaseNewMessagesState(); // pointer to a corresponding channel's instance LLNotificationsUI::LLScreenChannel* mChannel; LLFlatListView* mMessageList; - /** - * Reference to an appropriate Well chiclet to release "new message" state. EXT-3147 - */ - LLSysWellChiclet* mSysWellChiclet; - bool mIsReshapedByUser; }; @@ -157,7 +143,7 @@ private: * * It contains a list list of all active IM sessions. */ -class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass +class LLIMWellWindow : public LLSysWellWindow, LLInitClass { public: LLIMWellWindow(const LLSD& key); @@ -169,59 +155,19 @@ public: /*virtual*/ BOOL postBuild(); - // LLIMSessionObserver observe triggers - /*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg); - /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {} - /*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {}; - /*virtual*/ void sessionRemoved(const LLUUID& session_id); - /*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id); - void addObjectRow(const LLUUID& notification_id, bool new_message = false); void removeObjectRow(const LLUUID& notification_id); - - void addIMRow(const LLUUID& session_id); - bool hasIMRow(const LLUUID& session_id); - void closeAll(); protected: /*virtual*/ const std::string& getAnchorViewName() { return IM_WELL_ANCHOR_NAME; } private: - LLChiclet * findIMChiclet(const LLUUID& sessionId); LLChiclet* findObjectChiclet(const LLUUID& notification_id); - void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId); - void delIMRow(const LLUUID& sessionId); bool confirmCloseAll(const LLSD& notification, const LLSD& response); void closeAllImpl(); - /** - * Scrolling row panel. - */ - class RowPanel: public LLPanel - { - public: - RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, S32 chicletCounter, - const std::string& name, const LLUUID& otherParticipantId); - virtual ~RowPanel(); - void onMouseEnter(S32 x, S32 y, MASK mask); - void onMouseLeave(S32 x, S32 y, MASK mask); - BOOL handleMouseDown(S32 x, S32 y, MASK mask); - BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - - private: - static const S32 CHICLET_HPAD = 10; - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); - void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param); - void onClosePanel(); - public: - LLIMChiclet* mChiclet; - private: - LLButton* mCloseBtn; - const LLSysWellWindow* mParent; - }; - class ObjectRowPanel: public LLPanel { public: diff --git a/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png b/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png deleted file mode 100644 index 0ac5b72b8f..0000000000 Binary files a/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png deleted file mode 100644 index 857fa1e047..0000000000 Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png deleted file mode 100644 index 453bb53673..0000000000 Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png deleted file mode 100644 index 135a66ca0d..0000000000 Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png deleted file mode 100644 index a63aec5e6d..0000000000 Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png deleted file mode 100644 index 1719eb3e84..0000000000 Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 8d9fa52309..bf6e933dfd 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -365,8 +365,6 @@ with the same filename but different name - - @@ -654,12 +652,6 @@ with the same filename but different name - - - - - - diff --git a/indra/newview/skins/default/xui/da/menu_im_well_button.xml b/indra/newview/skins/default/xui/da/menu_im_well_button.xml deleted file mode 100644 index 4889230919..0000000000 --- a/indra/newview/skins/default/xui/da/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/da/menu_notification_well_button.xml b/indra/newview/skins/default/xui/da/menu_notification_well_button.xml deleted file mode 100644 index 40b35b5fdd..0000000000 --- a/indra/newview/skins/default/xui/da/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/de/menu_im_well_button.xml b/indra/newview/skins/default/xui/de/menu_im_well_button.xml deleted file mode 100644 index f464b71f4a..0000000000 --- a/indra/newview/skins/default/xui/de/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/de/menu_notification_well_button.xml b/indra/newview/skins/default/xui/de/menu_notification_well_button.xml deleted file mode 100644 index 0f2784f160..0000000000 --- a/indra/newview/skins/default/xui/de/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/en/menu_notification_well_button.xml b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml deleted file mode 100644 index 263ac40f4e..0000000000 --- a/indra/newview/skins/default/xui/en/menu_notification_well_button.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml deleted file mode 100644 index 9369d1b5cf..0000000000 --- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - TestString PleaseIgnore - - - - diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml deleted file mode 100644 index 0e29ed0d0b..0000000000 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml deleted file mode 100644 index 77011139bf..0000000000 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml deleted file mode 100644 index 8b56a8f0f6..0000000000 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - diff --git a/indra/newview/skins/default/xui/es/menu_im_well_button.xml b/indra/newview/skins/default/xui/es/menu_im_well_button.xml deleted file mode 100644 index c8f6c217cc..0000000000 --- a/indra/newview/skins/default/xui/es/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/es/menu_notification_well_button.xml b/indra/newview/skins/default/xui/es/menu_notification_well_button.xml deleted file mode 100644 index 0562d35be7..0000000000 --- a/indra/newview/skins/default/xui/es/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/fr/menu_im_well_button.xml b/indra/newview/skins/default/xui/fr/menu_im_well_button.xml deleted file mode 100644 index 8ef1529e6b..0000000000 --- a/indra/newview/skins/default/xui/fr/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml deleted file mode 100644 index 323bfdbf16..0000000000 --- a/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/it/menu_im_well_button.xml b/indra/newview/skins/default/xui/it/menu_im_well_button.xml deleted file mode 100644 index 9e471b771c..0000000000 --- a/indra/newview/skins/default/xui/it/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/it/menu_notification_well_button.xml b/indra/newview/skins/default/xui/it/menu_notification_well_button.xml deleted file mode 100644 index 8c82e30f0e..0000000000 --- a/indra/newview/skins/default/xui/it/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/ja/menu_im_well_button.xml b/indra/newview/skins/default/xui/ja/menu_im_well_button.xml deleted file mode 100644 index 3397004bd7..0000000000 --- a/indra/newview/skins/default/xui/ja/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml deleted file mode 100644 index 913bae8958..0000000000 --- a/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/pl/menu_im_well_button.xml b/indra/newview/skins/default/xui/pl/menu_im_well_button.xml deleted file mode 100644 index 207bc2211b..0000000000 --- a/indra/newview/skins/default/xui/pl/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml deleted file mode 100644 index bd3d42f9b1..0000000000 --- a/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/pt/menu_im_well_button.xml b/indra/newview/skins/default/xui/pt/menu_im_well_button.xml deleted file mode 100644 index 2d37cefd6f..0000000000 --- a/indra/newview/skins/default/xui/pt/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml deleted file mode 100644 index 43ad4134ec..0000000000 --- a/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/ru/menu_im_well_button.xml b/indra/newview/skins/default/xui/ru/menu_im_well_button.xml deleted file mode 100644 index 5a5bde61b9..0000000000 --- a/indra/newview/skins/default/xui/ru/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml deleted file mode 100644 index 4d067e232a..0000000000 --- a/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/tr/menu_im_well_button.xml b/indra/newview/skins/default/xui/tr/menu_im_well_button.xml deleted file mode 100644 index c3e559a723..0000000000 --- a/indra/newview/skins/default/xui/tr/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml deleted file mode 100644 index 39c66268f5..0000000000 --- a/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml b/indra/newview/skins/default/xui/zh/menu_im_well_button.xml deleted file mode 100644 index 4b9b4b2758..0000000000 --- a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml deleted file mode 100644 index b629f73584..0000000000 --- a/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - -- 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/llfloaterimsession.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 68b61bdec620014f30d6e9c63726d96fa7f4382a Mon Sep 17 00:00:00 2001 From: Gilbert Gonzales Date: Fri, 14 Dec 2012 16:01:14 -0800 Subject: CHUI-520: Now when have a P2P conversation torn off a voice indicator icon will be displayed allowing the user to adjust the voice volume when clicked. Also did a code cleanup on conversationview.h/cpp which was showing the speaking indicator icon too soon when joining another voice session. This was due to calling switchIndicator(..) directly inside ::onCurrentVoiceSessionChanged. The proper solution is to wait for SpeeakingIndicatorManager::switchSpeakerIndicators() call switchIndicators(). --- indra/newview/llconversationview.cpp | 24 ---------------------- indra/newview/llconversationview.h | 1 - indra/newview/llfloaterimsession.cpp | 18 ++++++++++++++++ indra/newview/llfloaterimsession.h | 1 + indra/newview/llfloaterimsessiontab.cpp | 3 +++ indra/newview/llfloaterimsessiontab.h | 1 + indra/newview/lloutputmonitorctrl.cpp | 2 ++ .../skins/default/xui/en/floater_im_session.xml | 12 +++++++++++ 8 files changed, 37 insertions(+), 25 deletions(-) (limited to 'indra/newview/llfloaterimsession.cpp') diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 527c0ad233..71d668d047 100755 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -341,14 +341,6 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi if (vmi) { bool is_active = vmi->getUUID() == session_id; - bool is_nearby = vmi->getType() == LLConversationItem::CONV_SESSION_NEARBY; - - if (is_nearby) - { - mSpeakingIndicator->setSpeakerId(is_active ? gAgentID : LLUUID::null); - } - - mSpeakingIndicator->switchIndicator(is_active); mCallIconLayoutPanel->setVisible(is_active); } } @@ -409,7 +401,6 @@ BOOL LLConversationViewParticipant::postBuild() mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this)); mInfoBtn->setVisible(false); - mActiveVoiceChannelConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLConversationViewParticipant::onCurrentVoiceSessionChanged, this, _1)); mSpeakingIndicator = getChild("speaking_indicator"); if (!sStaticInitialized) @@ -479,21 +470,6 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height) return arranged; } -void LLConversationViewParticipant::onCurrentVoiceSessionChanged(const LLUUID& session_id) -{ - LLConversationItemParticipant* participant_model = dynamic_cast(getViewModelItem()); - - if (participant_model) - { - LLConversationItemSession* parent_session = participant_model->getParentSession(); - if (parent_session) - { - bool is_active = (parent_session->getUUID() == session_id); - mSpeakingIndicator->switchIndicator(is_active); - } - } -} - void LLConversationViewParticipant::refresh() { // Refresh the participant view from its model data diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index fb2834f26a..a9333020e9 100755 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -146,7 +146,6 @@ protected: void onInfoBtnClick(); private: - void onCurrentVoiceSessionChanged(const LLUUID& session_id); LLAvatarIconCtrl* mAvatarIcon; LLButton * mInfoBtn; diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 3001029968..a0ca7286f1 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -101,6 +101,24 @@ void LLFloaterIMSession::refresh() } } +// virtual +void LLFloaterIMSession::onTearOffClicked() +{ + LLFloaterIMSessionTab::onTearOffClicked(); + + if(mIsP2PChat) + { + if(isTornOff()) + { + mSpeakingIndicator->setSpeakerId(mOtherParticipantUUID, mSessionID); + } + else + { + mSpeakingIndicator->setSpeakerId(LLUUID::null); + } + } +} + // virtual void LLFloaterIMSession::onClickCloseBtn() { diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index 72a320041f..1d8957b1d9 100644 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -135,6 +135,7 @@ private: /*virtual*/ void refresh(); + /*virtual*/ void onTearOffClicked(); /*virtual*/ void onClickCloseBtn(); // Update the window title and input field help text diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 0eb0289f49..ab588e489f 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -54,6 +54,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id) , mSessionID(session_id.asUUID()) , mConversationsRoot(NULL) , mScroller(NULL) + , mSpeakingIndicator(NULL) , mChatHistory(NULL) , mInputEditor(NULL) , mInputEditorTopPad(0) @@ -206,6 +207,8 @@ BOOL LLFloaterIMSessionTab::postBuild() mScroller = LLUICtrlFactory::create(scroller_params); mScroller->setFollowsAll(); + mSpeakingIndicator = getChild("speaking_indicator"); + // Insert that scroller into the panel widgets hierarchy mParticipantListPanel->addChild(mScroller); diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 4851904074..cd0bcd481c 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -149,6 +149,7 @@ protected: LLFolderView* mConversationsRoot; LLScrollContainer* mScroller; + LLOutputMonitorCtrl* mSpeakingIndicator; LLChatHistory* mChatHistory; LLChatEntry* mInputEditor; int mInputEditorTopPad; // padding between input field and chat history diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 02841e9831..f6e3c0cac0 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -260,6 +260,8 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s if (speaker_id.isNull() && mSpeakerId.notNull()) { LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this); + switchIndicator(false); + mSpeakerId = speaker_id; } if (speaker_id.isNull() || (speaker_id == mSpeakerId)) 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 faf54774f6..e4b127b7b9 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -106,6 +106,18 @@ name="voice_call_btn" tool_tip="Open voice connection" 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: - - - +