// create a floater and update internal representation for // consistency. Returns the pointer, caller (the class instance since // it is a private method) is not responsible for deleting the // pointer. Add the floater to this but do not select it. LLFloaterIMPanel* LLIMMgr::createFloater( const LLUUID& session_id, const LLUUID& other_participant_id, const std::string& session_label, const EInstantMessage& dialog, const std::vector<LLUUID>& ids, bool user_initiated) { if (session_id.isNull()) { LL_WARNS() << "Creating LLFloaterIMPanel with null session ID" << LL_ENDL; } LL_INFOS() << "LLIMMgr::createFloater: from " << other_participant_id << " in session " << session_id << LL_ENDL; LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label, session_id, other_participant_id, dialog, ids); LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt); static LLCachedControl<bool> tear_off("OtherChatsTornOff"); if (tear_off) { LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater); // removal sets up relationship for re-attach gFloaterView->addChild(floater); // reparent to floater view LLFloater* focused_floater = gFloaterView->getFocusedFloater(); // obtain the focused floater floater->open(); // make the new chat floater appear static LLCachedControl<bool> minimize("OtherChatsTornOffAndMinimized"); if (focused_floater != NULL) // there was a focused floater { floater->setMinimized(minimize); // so minimize this one, for now, if desired focused_floater->setFocus(true); // and work around focus being removed by focusing on the last } else if (minimize) { floater->setFocus(false); // work around focus being granted to new floater floater->setMinimized(true); } } mFloaters.insert(floater->getHandle()); return floater; }
void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) { S32 count = msg->getNumberOfBlocksFast(_PREHASH_AgentBlock); BOOL chat_notify = gSavedSettings.getBOOL("ChatOnlineNotification"); lldebugs << "Received " << count << " online notifications **** " << llendl; if(count > 0) { LLUUID agent_id; const LLRelationship* info = NULL; LLUUID tracking_id; if(mTrackingData) { tracking_id = mTrackingData->mAvatarID; } BOOL notify = FALSE; LLSD args; for(S32 i = 0; i < count; ++i) { msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_AgentID, agent_id, i); info = getBuddyInfo(agent_id); if(info) { setBuddyOnline(agent_id,online); if(chat_notify) { std::string fullname; LLAvatarName avatar_name; if (LLAvatarNameCache::get(agent_id, &avatar_name)) { static S32* sPhoenixNameSystem = rebind_llcontrol<S32>("PhoenixNameSystem", &gSavedSettings, true); switch (*sPhoenixNameSystem) { case 0 : fullname = avatar_name.getLegacyName(); break; case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; case 2 : fullname = avatar_name.mDisplayName; break; default : fullname = avatar_name.getCompleteName(); break; } notify = TRUE; args["NAME"] = fullname; } } } else { llwarns << "Received online notification for unknown buddy: " << agent_id << " is " << (online ? "ONLINE" : "OFFLINE") << llendl; } if(tracking_id == agent_id) { // we were tracking someone who went offline deleteTrackingData(); } // *TODO: get actual inventory id gInventory.addChangedMask(LLInventoryObserver::CALLING_CARD, LLUUID::null); } if(notify) { // Popup a notify box with online status of this agent LLNotificationPtr notification = LLNotifications::instance().add(online ? "FriendOnline" : "FriendOffline", args); // If there's an open IM session with this agent, send a notification there too. LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id); LLFloaterIMPanel *floater = gIMMgr->findFloaterBySession(session_id); if (floater) { std::string notifyMsg = notification->getMessage(); if (!notifyMsg.empty()) floater->addHistoryLine(notifyMsg,gSavedSettings.getColor4("SystemChatColor")); } } mModifyMask |= LLFriendObserver::ONLINE; instance().notifyObservers(); gInventory.notifyObservers(); } }
// Add a message to a session. void LLIMMgr::addMessage( const LLUUID& session_id, const LLUUID& target_id, const std::string& from, const std::string& msg, const std::string& session_name, EInstantMessage dialog, U32 parent_estate_id, const LLUUID& region_id, const LLVector3& position, bool link_name) // If this is true, then we insert the name and link it to a profile { LLUUID other_participant_id = target_id; // don't process muted IMs if (LLMuteList::getInstance()->isMuted( other_participant_id, LLMute::flagTextChat) && !LLMuteList::getInstance()->isLinden(from)) { return; } //not sure why...but if it is from ourselves we set the target_id //to be NULL if( other_participant_id == gAgent.getID() ) { other_participant_id = LLUUID::null; } LLFloaterIMPanel* floater; LLUUID new_session_id = session_id; if (new_session_id.isNull()) { //no session ID...compute new one new_session_id = computeSessionID(dialog, other_participant_id); } floater = findFloaterBySession(new_session_id); if (!floater) { floater = findFloaterBySession(other_participant_id); if (floater) { llinfos << "found the IM session " << session_id << " by participant " << other_participant_id << llendl; } } // create IM window as necessary if(!floater) { if (gIMMgr->getIgnoreGroupListCount() > 0 && gAgent.isInGroup(session_id)) { // Check to see if we're blocking this group's chat LLGroupData* group_data = NULL; // Search for this group in the agent's groups list LLDynamicArray<LLGroupData>::iterator i; for (i = gAgent.mGroups.begin(); i != gAgent.mGroups.end(); i++) { if (i->mID == session_id) { group_data = &*i; break; } } // If the group is in our list then return if (group_data && gIMMgr->getIgnoreGroup(group_data->mID)) { return; } } std::string name = from; if(!session_name.empty() && session_name.size()>1) { name = session_name; } floater = createFloater( new_session_id, other_participant_id, name, dialog, FALSE); // When we get a new IM, and if you are a god, display a bit // of information about the source. This is to help liaisons // when answering questions. if(gAgent.isGodlike()) { // *TODO:translate (low priority, god ability) std::ostringstream bonus_info; bonus_info << "*** parent estate: " << parent_estate_id << ((parent_estate_id == 1) ? ", mainland" : "") << ((parent_estate_id == 5) ? ", teen" : ""); // once we have web-services (or something) which returns // information about a region id, we can print this out // and even have it link to map-teleport or something. //<< "*** region_id: " << region_id << std::endl //<< "*** position: " << position << std::endl; floater->addHistoryLine(bonus_info.str(), gSavedSettings.getColor4("SystemChatColor")); } make_ui_sound("UISndNewIncomingIMSession"); } // now add message to floater bool is_from_system = target_id.isNull() || (from == SYSTEM_FROM); const LLColor4& color = ( is_from_system ? gSavedSettings.getColor4("SystemChatColor") : gSavedSettings.getColor("IMChatColor")); if ( !link_name ) { floater->addHistoryLine(msg,color); // No name to prepend, so just add the message normally } else { if( other_participant_id == session_id ) { // The name can be bogus on InWorldz floater->addHistoryLine(msg, color, true, LLUUID::null, from); } else { // Insert linked name to front of message floater->addHistoryLine(msg, color, true, other_participant_id, from); } } LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance(LLSD()); if( !chat_floater->getVisible() && !floater->getVisible()) { //if the IM window is not open and the floater is not visible (i.e. not torn off) LLFloater* previouslyActiveFloater = chat_floater->getActiveFloater(); // select the newly added floater (or the floater with the new line added to it). // it should be there. chat_floater->selectFloater(floater); //there was a previously unseen IM, make that old tab flashing //it is assumed that the most recently unseen IM tab is the one current selected/active if ( previouslyActiveFloater && getIMReceived() ) { chat_floater->setFloaterFlashing(previouslyActiveFloater, TRUE); } //notify of a new IM notifyNewIM(); mIMUnreadCount++; } }
// Add a message to a session. void LLIMMgr::addMessage( const LLUUID& session_id, const LLUUID& target_id, const std::string& from, const std::string& msg, const std::string& session_name, EInstantMessage dialog, U32 parent_estate_id, const LLUUID& region_id, const LLVector3& position, bool link_name) // If this is true, then we insert the name and link it to a profile { LLUUID other_participant_id = target_id; // don't process muted IMs if (LLMuteList::getInstance()->isMuted( other_participant_id, LLMute::flagTextChat) && !LLMuteList::getInstance()->isLinden(from)) { return; } LLUUID new_session_id = session_id; if (new_session_id.isNull()) { //no session ID...compute new one new_session_id = computeSessionID(dialog, other_participant_id); } LLFloaterIMPanel* floater = findFloaterBySession(new_session_id); if (!floater) { floater = findFloaterBySession(other_participant_id); if (floater) { LL_INFOS() << "found the IM session " << new_session_id << " by participant " << other_participant_id << LL_ENDL; } } if (LLVOAvatar* from_avatar = find_avatar_from_object(target_id)) from_avatar->mIdleTimer.reset(); // Not idle, message sent to somewhere // create IM window as necessary if(!floater) { // Return now if we're blocking this group's chat or conferences if (gAgent.isInGroup(session_id) ? getIgnoreGroup(session_id) : dialog != IM_NOTHING_SPECIAL && dialog != IM_SESSION_P2P_INVITE && block_conference(other_participant_id)) return; std::string name = (session_name.size() > 1) ? session_name : from; floater = createFloater(new_session_id, other_participant_id, name, dialog); // When we get a new IM, and if you are a god, display a bit // of information about the source. This is to help liaisons // when answering questions. if(gAgent.isGodlike()) { std::ostringstream bonus_info; bonus_info << LLTrans::getString("***")+ " "+ LLTrans::getString("IMParentEstate") + LLTrans::getString(":") + " " << parent_estate_id << ((parent_estate_id == 1) ? LLTrans::getString(",") + LLTrans::getString("IMMainland") : "") << ((parent_estate_id == 5) ? LLTrans::getString(",") + LLTrans::getString ("IMTeen") : ""); // once we have web-services (or something) which returns // information about a region id, we can print this out // and even have it link to map-teleport or something. //<< "*** region_id: " << region_id << std::endl //<< "*** position: " << position << std::endl; floater->addHistoryLine(bonus_info.str(), gSavedSettings.getColor4("SystemChatColor")); } make_ui_sound("UISndNewIncomingIMSession"); } // now add message to floater LLColor4 color = agent_chat_color(other_participant_id, from, false); if (dialog == IM_BUSY_AUTO_RESPONSE) { color *= .75f; color += LLColor4::transparent*.25f; } if ( !link_name ) { floater->addHistoryLine(msg,color); // No name to prepend, so just add the message normally } else { if( other_participant_id == session_id ) { // The name can be bogus on InWorldz floater->addHistoryLine(msg, color, true, LLUUID::null, from); } else { // Insert linked name to front of message floater->addHistoryLine(msg, color, true, other_participant_id, from); } } if (!gIMMgr->getFloaterOpen() && floater->getParent() != gFloaterView) { // If the chat floater is closed and not torn off) notify of a new IM mIMUnreadCount++; } }
void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) { S32 count = msg->getNumberOfBlocksFast(_PREHASH_AgentBlock); BOOL chat_notify = gSavedSettings.getBOOL("ChatOnlineNotification"); lldebugs << "Received " << count << " online notifications **** " << llendl; if(count > 0) { LLUUID agent_id; const LLRelationship* info = NULL; LLUUID tracking_id; if(mTrackingData) { tracking_id = mTrackingData->mAvatarID; } BOOL notify = FALSE; LLStringUtil::format_map_t args; for(S32 i = 0; i < count; ++i) { msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_AgentID, agent_id, i); info = getBuddyInfo(agent_id); if(info) { setBuddyOnline(agent_id,online); if(chat_notify) { std::string first, last; if(gCacheName->getName(agent_id, first, last)) { notify = TRUE; args["[FIRST]"] = first; args["[LAST]"] = last; } } } else { llwarns << "Received online notification for unknown buddy: " << agent_id << " is " << (online ? "ONLINE" : "OFFLINE") << llendl; } if(tracking_id == agent_id) { // we were tracking someone who went offline deleteTrackingData(); } // *TODO: get actual inventory id gInventory.addChangedMask(LLInventoryObserver::CALLING_CARD, LLUUID::null); } if(notify) { // Popup a notify box with online status of this agent LLNotifyBox::showXml(online ? "FriendOnline" : "FriendOffline", args); // If there's an open IM session with this agent, send a notification there too. LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id); LLFloaterIMPanel *floater = gIMMgr->findFloaterBySession(session_id); if (floater) { LLUIString notifyMsg = LLNotifyBox::getTemplateMessage((online ? "FriendOnline" : "FriendOffline"),args); if (!notifyMsg.empty()) floater->addHistoryLine(notifyMsg,gSavedSettings.getColor4("SystemChatColor")); } } mModifyMask |= LLFriendObserver::ONLINE; instance().notifyObservers(); gInventory.notifyObservers(); } }
// Add a message to a session. void LLIMMgr::addMessage( const LLUUID& session_id, const LLUUID& target_id, const std::string& from, const std::string& msg, const std::string& session_name, EInstantMessage dialog, U32 parent_estate_id, const LLUUID& region_id, const LLVector3& position, bool link_name) // If this is true, then we insert the name and link it to a profile { LLUUID other_participant_id = target_id; BOOL is_linden = LLMuteList::getInstance()->isLinden(other_participant_id); // don't process muted IMs if (LLMuteList::getInstance()->isMuted( other_participant_id, LLMute::flagTextChat) && !is_linden) { return; } //not sure why...but if it is from ourselves we set the target_id //to be NULL if( other_participant_id == gAgent.getID() ) { other_participant_id = LLUUID::null; } LLFloaterIMPanel* floater; LLUUID new_session_id = session_id; if (new_session_id.isNull()) { //no session ID...compute new one new_session_id = computeSessionID(dialog, other_participant_id); } floater = findFloaterBySession(new_session_id); if (!floater) { floater = findFloaterBySession(other_participant_id); if (floater) { llinfos << "found the IM session " << session_id << " by participant " << other_participant_id << llendl; } } // create IM window as necessary if(!floater) { std::string name = from; if(!session_name.empty() && session_name.size()>1) { name = session_name; } floater = createFloater( new_session_id, other_participant_id, name, dialog, FALSE); // When we get a new IM, and if you are a god, display a bit // of information about the source. This is to help liaisons // when answering questions. if(gAgent.isGodlike()) { // *TODO:translate (low priority, god ability) std::ostringstream bonus_info; bonus_info << "*** parent estate: " << parent_estate_id << ((parent_estate_id == 1) ? ", mainland" : "") << ((parent_estate_id == 5) ? ", teen" : ""); // once we have web-services (or something) which returns // information about a region id, we can print this out // and even have it link to map-teleport or something. //<< "*** region_id: " << region_id << std::endl //<< "*** position: " << position << std::endl; floater->addHistoryLine(bonus_info.str(), gSavedSettings.getColor4("SystemChatColor")); } make_ui_sound("UISndNewIncomingIMSession"); } // now add message to floater bool is_from_system = target_id.isNull() || (from == SYSTEM_FROM); bool is_encrypted = (msg.substr(0, 3) == "\xe2\x80\xa7"); LLColor4 color; //Phoenix:KC - color chat from friends. taking care not to color when RLV hide names is in effect, lol static BOOL* sPhoenixColorFriendsChat = rebind_llcontrol<BOOL>("PhoenixColorFriendsChat", &gSavedSettings, true); static BOOL* sPhoenixColorLindensChat = rebind_llcontrol<BOOL>("PhoenixColorLindensChat", &gSavedSettings, true); if (is_from_system) { color = gSavedSettings.getColor4("SystemChatColor"); } else if (is_encrypted) { color = gSavedSettings.getColor4("PhoenixIMEncryptedChatColor"); } else if (target_id == gAgent.getID()) { color = gSavedSettings.getColor("UserChatColor"); } else if (*sPhoenixColorFriendsChat && LLAvatarTracker::instance().isBuddy(other_participant_id) && (!rlv_handler_t::isEnabled() || !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))) { color = gSavedSettings.getColor4("PhoenixFriendChatColor"); } else if (*sPhoenixColorLindensChat && is_linden) { color = gSavedSettings.getColor4("PhoenixLindensChatColor"); } else { color = gSavedSettings.getColor4("IMChatColor"); } if ( !link_name ) { floater->addHistoryLine(msg,color); // No name to prepend, so just add the message normally } else { floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message } LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance(LLSD()); if( !chat_floater->getVisible() && !floater->getVisible()) { //if the IM window is not open and the floater is not visible (i.e. not torn off) LLFloater* previouslyActiveFloater = chat_floater->getActiveFloater(); // select the newly added floater (or the floater with the new line added to it). // it should be there. chat_floater->selectFloater(floater); //there was a previously unseen IM, make that old tab flashing //it is assumed that the most recently unseen IM tab is the one current selected/active if ( previouslyActiveFloater && getIMReceived() ) { chat_floater->setFloaterFlashing(previouslyActiveFloater, TRUE); } //notify of a new IM notifyNewIM(); mIMUnreadCount++; } }
// static void LLFloaterIMPanel::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) { LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; self->setTyping(FALSE); }
// static void LLFloaterIMPanel::onClickToggleActiveSpeakers(void* userdata) { LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata; self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel")); }
// static void LLFloaterIMPanel::onClickSend(void* userdata) { LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata; self->sendMsg(); }
// static void LLFloaterIMPanel::onTabClick(void* userdata) { LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; self->setInputFocus(TRUE); }