diff options
Diffstat (limited to 'indra/newview/llimpanel.cpp')
-rw-r--r-- | indra/newview/llimpanel.cpp | 978 |
1 files changed, 0 insertions, 978 deletions
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp deleted file mode 100644 index c194dc05b0..0000000000 --- a/indra/newview/llimpanel.cpp +++ /dev/null @@ -1,978 +0,0 @@ -/** - * @file llimpanel.cpp - * @brief LLIMPanel class definition - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llimpanel.h" - -#include "indra_constants.h" -#include "llfloaterreg.h" -#include "llfocusmgr.h" -#include "llfontgl.h" -#include "llrect.h" -#include "llerror.h" -#include "llmultifloater.h" -#include "llstring.h" -#include "message.h" -#include "lltextbox.h" - -#include "llagent.h" -#include "llbutton.h" -#include "llcallingcard.h" -#include "llchannelmanager.h" -#include "llchat.h" -#include "llchiclet.h" -#include "llconsole.h" -#include "llgroupactions.h" -#include "llfloater.h" -#include "llfloateractivespeakers.h" -#include "llavataractions.h" -#include "llinventory.h" -#include "llinventorymodel.h" -#include "llfloaterinventory.h" -#include "lliconctrl.h" -#include "llkeyboard.h" -#include "lllineeditor.h" -#include "llpanelimcontrolpanel.h" -#include "llrecentpeople.h" -#include "llresmgr.h" -#include "lltooldraganddrop.h" -#include "lltrans.h" -#include "lltabcontainer.h" -#include "llviewertexteditor.h" -#include "llviewermessage.h" -#include "llviewerstats.h" -#include "llviewercontrol.h" -#include "lluictrlfactory.h" -#include "llviewerwindow.h" -#include "llvoicechannel.h" -#include "lllogchat.h" -#include "llweb.h" -#include "llhttpclient.h" -#include "llmutelist.h" -#include "llstylemap.h" -#include "llappviewer.h" - -// -// Constants -// -const S32 LINE_HEIGHT = 16; -const S32 MIN_WIDTH = 200; -const S32 MIN_HEIGHT = 130; - -// -// Statics -// -// -static std::string sTitleString = "Instant Message with [NAME]"; -static std::string sTypingStartString = "[NAME]: ..."; -static std::string sSessionStartString = "Starting session with [NAME] please wait."; - - -// -// LLFloaterIMPanel -// - -LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label, - const LLUUID& session_id, - const LLUUID& other_participant_id, - const std::vector<LLUUID>& ids, - EInstantMessage dialog) -: LLFloater(session_id), - mInputEditor(NULL), - mHistoryEditor(NULL), - mSessionUUID(session_id), - mSessionLabel(session_label), - mSessionInitialized(FALSE), - mSessionStartMsgPos(0), - mOtherParticipantUUID(other_participant_id), - mDialog(dialog), - mSessionInitialTargetIDs(ids), - mTyping(FALSE), - mOtherTyping(FALSE), - mTypingLineStartIndex(0), - mSentTypingState(TRUE), - mNumUnreadMessages(0), - mShowSpeakersOnConnect(TRUE), - mTextIMPossible(TRUE), - mProfileButtonEnabled(TRUE), - mCallBackEnabled(TRUE), - mSpeakerPanel(NULL), - mFirstKeystrokeTimer(), - mLastKeystrokeTimer() -{ - std::string xml_filename; - switch(mDialog) - { - case IM_SESSION_GROUP_START: - mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); - xml_filename = "floater_instant_message_group.xml"; - break; - case IM_SESSION_INVITE: - mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); - if (gAgent.isInGroup(mSessionUUID)) - { - xml_filename = "floater_instant_message_group.xml"; - } - else // must be invite to ad hoc IM - { - xml_filename = "floater_instant_message_ad_hoc.xml"; - } - break; - case IM_SESSION_P2P_INVITE: - xml_filename = "floater_instant_message.xml"; - break; - case IM_SESSION_CONFERENCE_START: - mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this); - xml_filename = "floater_instant_message_ad_hoc.xml"; - break; - // just received text from another user - case IM_NOTHING_SPECIAL: - - xml_filename = "floater_instant_message.xml"; - - mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionUUID); - mProfileButtonEnabled = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionUUID); - mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionUUID); - break; - default: - LL_WARNS() << "Unknown session type" << LL_ENDL; - xml_filename = "floater_instant_message.xml"; - break; - } - - LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, NULL); - - setTitle(mSessionLabel); - mInputEditor->setMaxTextLength(DB_IM_MSG_STR_LEN); - // enable line history support for instant message bar - mInputEditor->setEnableLineHistory(TRUE); - - //*TODO we probably need the same "awaiting message" thing in LLFloaterIMSession - LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionUUID); - if (!im_session) - { - llerror("im session with id " + mSessionUUID.asString() + " does not exist!", 0); - return; - } - - mSessionInitialized = im_session->mSessionInitialized; - if (!mSessionInitialized) - { - //locally echo a little "starting session" message - LLUIString session_start = sSessionStartString; - - session_start.setArg("[NAME]", getTitle()); - mSessionStartMsgPos = - mHistoryEditor->getWText().length(); - - addHistoryLine( - session_start, - LLUIColorTable::instance().getColor("SystemChatColor"), - false); - } -} - - -LLFloaterIMPanel::~LLFloaterIMPanel() -{ - //delete focus lost callback - mFocusCallbackConnection.disconnect(); -} - -BOOL LLFloaterIMPanel::postBuild() -{ - setVisibleCallback(boost::bind(&LLFloaterIMPanel::onVisibilityChange, this, _2)); - - mInputEditor = getChild<LLLineEditor>("chat_editor"); - mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) ); - mFocusCallbackConnection = mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this)); - mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this ); - mInputEditor->setCommitCallback( onCommitChat, this ); - mInputEditor->setCommitOnFocusLost( FALSE ); - mInputEditor->setRevertOnEsc( FALSE ); - mInputEditor->setReplaceNewlinesWithSpaces( FALSE ); - - childSetAction("profile_callee_btn", onClickProfile, this); - childSetAction("group_info_btn", onClickGroupInfo, this); - - childSetAction("start_call_btn", onClickStartCall, this); - childSetAction("end_call_btn", onClickEndCall, this); - childSetAction("send_btn", onClickSend, this); - childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this); - - childSetAction("moderator_kick_speaker", onKickSpeaker, this); - //LLButton* close_btn = getChild<LLButton>("close_btn"); - //close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this); - - mHistoryEditor = getChild<LLViewerTextEditor>("im_history"); - - if ( IM_SESSION_GROUP_START == mDialog ) - { - childSetEnabled("profile_btn", FALSE); - } - - if(!mProfileButtonEnabled) - { - childSetEnabled("profile_callee_btn", FALSE); - } - - sTitleString = getString("title_string"); - sTypingStartString = getString("typing_start_string"); - sSessionStartString = getString("session_start_string"); - - if (mSpeakerPanel) - { - mSpeakerPanel->refreshSpeakers(); - } - - if (mDialog == IM_NOTHING_SPECIAL) - { - childSetAction("mute_btn", onClickMuteVoice, this); - childSetCommitCallback("speaker_volume", onVolumeChange, this); - } - - setDefaultBtn("send_btn"); - return TRUE; -} - -void* LLFloaterIMPanel::createSpeakersPanel(void* data) -{ - LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)data; - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(floaterp->mSessionUUID); - floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(speaker_mgr, TRUE); - return floaterp->mSpeakerPanel; -} - -//static -void LLFloaterIMPanel::onClickMuteVoice(void* user_data) -{ - LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data; - if (floaterp) - { - BOOL is_muted = LLMuteList::getInstance()->isMuted(floaterp->mOtherParticipantUUID, LLMute::flagVoiceChat); - - LLMute mute(floaterp->mOtherParticipantUUID, floaterp->getTitle(), LLMute::AGENT); - if (!is_muted) - { - LLMuteList::getInstance()->add(mute, LLMute::flagVoiceChat); - } - else - { - LLMuteList::getInstance()->remove(mute, LLMute::flagVoiceChat); - } - } -} - -//static -void LLFloaterIMPanel::onVolumeChange(LLUICtrl* source, void* user_data) -{ - LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data; - if (floaterp) - { - LLVoiceClient::getInstance()->setUserVolume(floaterp->mOtherParticipantUUID, (F32)source->getValue().asReal()); - } -} - - -// virtual -void LLFloaterIMPanel::draw() -{ - LLViewerRegion* region = gAgent.getRegion(); - - BOOL enable_connect = (region && region->getCapability("ChatSessionRequest") != "") - && mSessionInitialized - && LLVoiceClient::getInstance()->voiceEnabled() - && mCallBackEnabled; - - // hide/show start call and end call buttons - LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID); - if (!voice_channel) - return; - - childSetVisible("end_call_btn", LLVoiceClient::getInstance()->voiceEnabled() && voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED); - childSetVisible("start_call_btn", LLVoiceClient::getInstance()->voiceEnabled() && voice_channel->getState() < LLVoiceChannel::STATE_CALL_STARTED); - childSetEnabled("start_call_btn", enable_connect); - childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty()); - - LLPointer<LLSpeaker> self_speaker; - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID); - if (speaker_mgr) - { - self_speaker = speaker_mgr->findSpeaker(gAgent.getID()); - } - if(!mTextIMPossible) - { - mInputEditor->setEnabled(FALSE); - mInputEditor->setLabel(getString("unavailable_text_label")); - } - else if (self_speaker.notNull() && self_speaker->mModeratorMutedText) - { - mInputEditor->setEnabled(FALSE); - mInputEditor->setLabel(getString("muted_text_label")); - } - else - { - mInputEditor->setEnabled(TRUE); - mInputEditor->setLabel(getString("default_text_label")); - } - - // show speakers window when voice first connects - if (mShowSpeakersOnConnect && voice_channel->isActive()) - { - childSetVisible("active_speakers_panel", TRUE); - mShowSpeakersOnConnect = FALSE; - } - childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel")); - - if (mTyping) - { - // Time out if user hasn't typed for a while. - if (mLastKeystrokeTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS) - { - setTyping(FALSE); - } - - // If we are typing, and it's been a little while, send the - // typing indicator - if (!mSentTypingState - && mFirstKeystrokeTimer.getElapsedTimeF32() > 1.f) - { - sendTypingState(TRUE); - mSentTypingState = TRUE; - } - } - - // use embedded panel if available - if (mSpeakerPanel) - { - if (mSpeakerPanel->getVisible()) - { - mSpeakerPanel->refreshSpeakers(); - } - } - else - { - // refresh volume and mute checkbox - childSetVisible("speaker_volume", LLVoiceClient::getInstance()->voiceEnabled() && voice_channel->isActive()); - childSetValue("speaker_volume", LLVoiceClient::getInstance()->getUserVolume(mOtherParticipantUUID)); - - childSetValue("mute_btn", LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat)); - childSetVisible("mute_btn", LLVoiceClient::getInstance()->voiceEnabled() && voice_channel->isActive()); - } - LLFloater::draw(); -} - -class LLSessionInviteResponder : public LLHTTPClient::Responder -{ - LOG_CLASS(LLSessionInviteResponder); -public: - LLSessionInviteResponder(const LLUUID& session_id) - { - mSessionID = session_id; - } - -protected: - void httpFailure() - { - LL_WARNS() << "Error inviting all agents to session " << dumpResponse() << LL_ENDL; - //throw something back to the viewer here? - } - -private: - LLUUID mSessionID; -}; - -BOOL LLFloaterIMPanel::inviteToSession(const std::vector<LLUUID>& ids) -{ - LLViewerRegion* region = gAgent.getRegion(); - if (!region) - { - return FALSE; - } - - S32 count = ids.size(); - - if( isInviteAllowed() && (count > 0) ) - { - LL_INFOS() << "LLFloaterIMPanel::inviteToSession() - inviting participants" << LL_ENDL; - - 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"] = mSessionUUID; - LLHTTPClient::post( - url, - data, - new LLSessionInviteResponder( - mSessionUUID)); - } - else - { - LL_INFOS() << "LLFloaterIMPanel::inviteToSession -" - << " no need to invite agents for " - << mDialog << LL_ENDL; - // successful add, because everyone that needed to get added - // was added. - } - - return TRUE; -} - -void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4& color, bool log_to_file, const LLUUID& source, const std::string& name) -{ - // start tab flashing when receiving im for background session from user - if (source != LLUUID::null) - { - LLMultiFloater* hostp = getHost(); - if( !isInVisibleChain() - && hostp - && source != gAgent.getID()) - { - hostp->setFloaterFlashing(this, TRUE); - } - } - - // Now we're adding the actual line of text, so erase the - // "Foo is typing..." text segment, and the optional timestamp - // if it was present. JC - removeTypingIndicator(NULL); - - // Actually add the line - std::string timestring; - bool prepend_newline = true; - if (gSavedSettings.getBOOL("IMShowTimestamps")) - { - timestring = mHistoryEditor->appendTime(prepend_newline); - prepend_newline = false; - } - - std::string separator_string(": "); - - // 'name' is a sender name that we want to hotlink so that clicking on it opens a profile. - if (!name.empty()) // If name exists, then add it to the front of the message. - { - // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. - if (name == SYSTEM_FROM) - { - mHistoryEditor->appendText(name + separator_string, prepend_newline, LLStyle::Params().color(color)); - } - else - { - // Convert the name to a hotlink and add to message. - mHistoryEditor->appendText(name + separator_string, prepend_newline, LLStyleMap::instance().lookupAgent(source)); - } - prepend_newline = false; - } - mHistoryEditor->appendText(utf8msg, prepend_newline, LLStyle::Params().color(color)); - mHistoryEditor->blockUndo(); - - if (!isInVisibleChain()) - { - mNumUnreadMessages++; - } -} - - -void LLFloaterIMPanel::setInputFocus( BOOL b ) -{ - mInputEditor->setFocus( b ); -} - - -void LLFloaterIMPanel::selectAll() -{ - mInputEditor->selectAll(); -} - - -void LLFloaterIMPanel::selectNone() -{ - mInputEditor->deselect(); -} - -BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask ) -{ - BOOL handled = FALSE; - if( KEY_RETURN == key && mask == MASK_NONE) - { - sendMsg(); - handled = TRUE; - } - else if ( KEY_ESCAPE == key ) - { - handled = TRUE; - gFocusMgr.setKeyboardFocus(NULL); - } - - // May need to call base class LLPanel::handleKeyHere if not handled - // in order to tab between buttons. JNC 1.2.2002 - return handled; -} - -BOOL LLFloaterIMPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - - if (mDialog == IM_NOTHING_SPECIAL) - { - LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionUUID, drop, - cargo_type, cargo_data, accept); - } - - // handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites - else if (isInviteAllowed()) - { - *accept = ACCEPT_NO; - - if (cargo_type == DAD_CALLINGCARD) - { - if (dropCallingCard((LLInventoryItem*)cargo_data, drop)) - { - *accept = ACCEPT_YES_MULTI; - } - } - else if (cargo_type == DAD_CATEGORY) - { - if (dropCategory((LLInventoryCategory*)cargo_data, drop)) - { - *accept = ACCEPT_YES_MULTI; - } - } - } - return TRUE; -} - -BOOL LLFloaterIMPanel::dropCallingCard(LLInventoryItem* item, BOOL drop) -{ - BOOL rv = isInviteAllowed(); - if(rv && item && item->getCreatorUUID().notNull()) - { - if(drop) - { - std::vector<LLUUID> ids; - ids.push_back(item->getCreatorUUID()); - inviteToSession(ids); - } - } - else - { - // set to false if creator uuid is null. - rv = FALSE; - } - return rv; -} - -BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop) -{ - BOOL rv = isInviteAllowed(); - if(rv && category) - { - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - LLUniqueBuddyCollector buddies; - gInventory.collectDescendentsIf(category->getUUID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - buddies); - S32 count = items.count(); - if(count == 0) - { - rv = FALSE; - } - else if(drop) - { - std::vector<LLUUID> ids; - ids.reserve(count); - for(S32 i = 0; i < count; ++i) - { - ids.push_back(items.get(i)->getCreatorUUID()); - } - inviteToSession(ids); - } - } - return rv; -} - -BOOL LLFloaterIMPanel::isInviteAllowed() const -{ - - return ( (IM_SESSION_CONFERENCE_START == mDialog) - || (IM_SESSION_INVITE == mDialog) ); -} - - -// static -void LLFloaterIMPanel::onTabClick(void* userdata) -{ - LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; - self->setInputFocus(TRUE); -} - - -// static -void LLFloaterIMPanel::onClickProfile( void* userdata ) -{ - // Bring up the Profile window - LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; - - if (self->getOtherParticipantID().notNull()) - { - LLAvatarActions::showProfile(self->getOtherParticipantID()); - } -} - -// static -void LLFloaterIMPanel::onClickGroupInfo( void* userdata ) -{ - // Bring up the Profile window - LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; - - LLGroupActions::show(self->mSessionUUID); - -} - -// static -void LLFloaterIMPanel::onClickClose( void* userdata ) -{ - LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; - if(self) - { - self->closeFloater(); - } -} - -// static -void LLFloaterIMPanel::onClickStartCall(void* userdata) -{ - LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; - - gIMMgr->startCall(self->mSessionUUID); -} - -// static -void LLFloaterIMPanel::onClickEndCall(void* userdata) -{ - LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; - - gIMMgr->endCall(self->mSessionUUID); -} - -// static -void LLFloaterIMPanel::onClickSend(void* userdata) -{ - LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata; - self->sendMsg(); -} - -// static -void LLFloaterIMPanel::onClickToggleActiveSpeakers(void* userdata) -{ - LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata; - - self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel")); -} - -// static -void LLFloaterIMPanel::onCommitChat(LLUICtrl* caller, void* userdata) -{ - LLFloaterIMPanel* self= (LLFloaterIMPanel*) userdata; - self->sendMsg(); -} - -// static -void LLFloaterIMPanel::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ) -{ - LLFloaterIMPanel* self= (LLFloaterIMPanel*) userdata; - self->mHistoryEditor->setCursorAndScrollToEnd(); -} - -// static -void LLFloaterIMPanel::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) -{ - LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; - self->setTyping(FALSE); -} - -// static -void LLFloaterIMPanel::onInputEditorKeystroke(LLLineEditor* caller, void* userdata) -{ - LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata; - std::string text = self->mInputEditor->getText(); - if (!text.empty()) - { - self->setTyping(TRUE); - } - else - { - // Deleting all text counts as stopping typing. - self->setTyping(FALSE); - } -} - -// virtual -void LLFloaterIMPanel::onClose(bool app_quitting) -{ - setTyping(FALSE); - - gIMMgr->leaveSession(mSessionUUID); - - // *HACK hide the voice floater - LLFloaterReg::hideInstance("voice_call", mSessionUUID); -} - -void LLFloaterIMPanel::onVisibilityChange(const LLSD& new_visibility) -{ - if (new_visibility.asBoolean()) - { - mNumUnreadMessages = 0; - } - - LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID); - if (voice_channel && voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED) - { - if (new_visibility.asBoolean()) - LLFloaterReg::showInstance("voice_call", mSessionUUID); - else - LLFloaterReg::hideInstance("voice_call", mSessionUUID); - } -} - -void LLFloaterIMPanel::sendMsg() -{ - if (!gAgent.isGodlike() - && (mDialog == IM_NOTHING_SPECIAL) - && mOtherParticipantUUID.isNull()) - { - LL_INFOS() << "Cannot send IM to everyone unless you're a god." << LL_ENDL; - return; - } - - if (mInputEditor) - { - LLWString text = mInputEditor->getConvertedText(); - if(!text.empty()) - { - // store sent line in history, duplicates will get filtered - if (mInputEditor) mInputEditor->updateHistory(); - // Truncate and convert to UTF8 for transport - std::string utf8_text = wstring_to_utf8str(text); - utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); - - if ( mSessionInitialized ) - { - LLIMModel::sendMessage(utf8_text, - mSessionUUID, - mOtherParticipantUUID, - mDialog); - - } - else - { - //queue up the message to send once the session is - //initialized - mQueuedMsgsForInit.append(utf8_text); - } - } - - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_IM_COUNT); - - mInputEditor->setText(LLStringUtil::null); - } - - // Don't need to actually send the typing stop message, the other - // client will infer it from receiving the message. - mTyping = FALSE; - mSentTypingState = TRUE; -} - -void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update) -{ - if ( - session_update.has("moderated_mode") && - session_update["moderated_mode"].has("voice") ) - { - BOOL voice_moderated = session_update["moderated_mode"]["voice"]; - - if (voice_moderated) - { - setTitle(mSessionLabel + std::string(" ") + getString("moderated_chat_label")); - } - else - { - setTitle(mSessionLabel); - } - - - //update the speakers dropdown too, if it's available - if (mSpeakerPanel) - { - mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated); - } - } -} - -void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) -{ - mSessionUUID = session_id; - mSessionInitialized = TRUE; - - //we assume the history editor hasn't moved at all since - //we added the starting session message - //so, we count how many characters to remove - S32 chars_to_remove = mHistoryEditor->getWText().length() - - mSessionStartMsgPos; - mHistoryEditor->removeTextFromEnd(chars_to_remove); - - //and now, send the queued msg - LLSD::array_iterator iter; - for ( iter = mQueuedMsgsForInit.beginArray(); - iter != mQueuedMsgsForInit.endArray(); - ++iter) - { - LLIMModel::sendMessage( - iter->asString(), - mSessionUUID, - mOtherParticipantUUID, - mDialog); - } -} - -void LLFloaterIMPanel::setTyping(BOOL typing) -{ - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID); - if (typing) - { - // Every time you type something, reset this timer - mLastKeystrokeTimer.reset(); - - if (!mTyping) - { - // You just started typing. - mFirstKeystrokeTimer.reset(); - - // Will send typing state after a short delay. - mSentTypingState = FALSE; - } - - if (speaker_mgr) - speaker_mgr->setSpeakerTyping(gAgent.getID(), TRUE); - } - else - { - if (mTyping) - { - // you just stopped typing, send state immediately - sendTypingState(FALSE); - mSentTypingState = TRUE; - } - if (speaker_mgr) - speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); - } - - mTyping = typing; -} - -void LLFloaterIMPanel::sendTypingState(BOOL typing) -{ - // Don't want to send typing indicators to multiple people, potentially too - // much network traffic. Only send in person-to-person IMs. - if (mDialog != IM_NOTHING_SPECIAL) return; - - LLIMModel::instance().sendTypingState(mSessionUUID, mOtherParticipantUUID, typing); -} - - -void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, BOOL typing) -{ - if (typing) - { - // other user started typing - addTypingIndicator(im_info->mName); - } - else - { - // other user stopped typing - removeTypingIndicator(im_info); - } -} - - -void LLFloaterIMPanel::addTypingIndicator(const std::string &name) -{ - // we may have lost a "stop-typing" packet, don't add it twice - if (!mOtherTyping) - { - mTypingLineStartIndex = mHistoryEditor->getWText().length(); - LLUIString typing_start = sTypingStartString; - typing_start.setArg("[NAME]", name); - addHistoryLine(typing_start, LLUIColorTable::instance().getColor("SystemChatColor"), false); - mOtherTypingName = name; - mOtherTyping = TRUE; - } - // MBW -- XXX -- merge from release broke this (argument to this function changed from an LLIMInfo to a name) - // Richard will fix. -// mSpeakers->setSpeakerTyping(im_info->mFromID, TRUE); -} - - -void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info) -{ - if (mOtherTyping) - { - // Must do this first, otherwise addHistoryLine calls us again. - mOtherTyping = FALSE; - - S32 chars_to_remove = mHistoryEditor->getWText().length() - mTypingLineStartIndex; - mHistoryEditor->removeTextFromEnd(chars_to_remove); - if (im_info) - { - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID); - if (speaker_mgr) - { - speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); - } - } - } -} - -//static -void LLFloaterIMPanel::onKickSpeaker(void* user_data) -{ - -} |