diff options
-rw-r--r-- | indra/llui/lltextbase.cpp | 6 | ||||
-rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
-rwxr-xr-x | indra/newview/llavataractions.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llavataractions.h | 4 | ||||
-rw-r--r-- | indra/newview/llblocklist.cpp | 22 | ||||
-rw-r--r-- | indra/newview/llchathistory.cpp | 47 | ||||
-rw-r--r-- | indra/newview/llimconversation.cpp | 12 | ||||
-rw-r--r-- | indra/newview/llimconversation.h | 2 | ||||
-rw-r--r-- | indra/newview/llimfloater.cpp | 137 | ||||
-rw-r--r-- | indra/newview/llimfloater.h | 2 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.cpp | 23 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.h | 2 | ||||
-rw-r--r-- | indra/newview/llimview.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llnearbychat.cpp | 64 | ||||
-rw-r--r-- | indra/newview/llnearbychat.h | 2 | ||||
-rw-r--r-- | indra/newview/llpanelpeoplemenus.cpp | 2 | ||||
-rwxr-xr-x | indra/newview/llviewermessage.cpp | 27 |
17 files changed, 234 insertions, 136 deletions
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 3b3bc64c5b..a7bc6bbb77 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -510,7 +510,7 @@ void LLTextBase::drawText() } else if (text_len <= 0 && !mLabel.empty() && !hasFocus()) { - text_len = mLabel.length(); + text_len = mLabel.getWString().length(); } S32 selection_left = -1; @@ -1816,7 +1816,7 @@ void LLTextBase::resetLabel() style->setColor(mTentativeFgColor); LLStyleConstSP sp(style); - LLTextSegmentPtr label = new LLLabelTextSegment(sp, 0, getLabel().length() + 1, *this); + LLTextSegmentPtr label = new LLLabelTextSegment(sp, 0, mLabel.getWString().length() + 1, *this); insertSegment(label); } } @@ -2988,7 +2988,7 @@ const LLWString& LLLabelTextSegment::getWText() const /*virtual*/ const S32 LLLabelTextSegment::getLength() const { - return mEditor.getLabel().length(); + return mEditor.getWlabel().length(); } // diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4a586b02af..da3ff2d1ee 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1639,6 +1639,17 @@ <key>Value</key> <string /> </map> + <key>NearbyChatIsNotTornOff</key> + <map> + <key>Comment</key> + <string>saving torn-off state of the nearby chat between sessions</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>CloseChatOnReturn</key> <map> <key>Comment</key> diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index fb32bcbd60..6babdc1f44 100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -235,7 +235,7 @@ void LLAvatarActions::startCall(const LLUUID& id) } // static -void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids) +void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids, const LLUUID& floater_id) { if (ids.size() == 0) { @@ -252,7 +252,7 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids) // create the new ad hoc voice session const std::string title = LLTrans::getString("conference-title"); LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, - ids[0], id_array, true); + ids[0], id_array, true, floater_id); if (session_id == LLUUID::null) { return; diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 46830eb22c..259e87c336 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -82,9 +82,9 @@ public: static void startCall(const LLUUID& id); /** - * Start an ad-hoc conference voice call with multiple users + * Start an ad-hoc conference voice call with multiple users in a specific IM floater. */ - static void startAdhocCall(const uuid_vec_t& ids); + static void startAdhocCall(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null); /** * Start conference chat with the given avatars in a specific IM floater. diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp index cb68f677eb..066cb71677 100644 --- a/indra/newview/llblocklist.cpp +++ b/indra/newview/llblocklist.cpp @@ -195,7 +195,13 @@ bool LLBlockList::isActionEnabled(const LLSD& userdata) const std::string command_name = userdata.asString(); - if ("unblock_item" == command_name || "profile_item" == command_name) + if ("profile_item" == command_name) + { + LLBlockedListItem* item = getBlockedItem(); + action_enabled = item && (LLMute::AGENT == item->getType()); + } + + if ("unblock_item" == command_name) { action_enabled = getSelectedItem() != NULL; } @@ -227,10 +233,6 @@ void LLBlockList::onCustomAction(const LLSD& userdata) LLAvatarActions::showProfile(item->getUUID()); break; - case LLMute::OBJECT: - LLFloaterSidePanelContainer::showPanel("inventory", LLSD().with("id", item->getUUID())); - break; - default: break; } @@ -267,9 +269,15 @@ bool LLBlockListNameTypeComparator::doCompare(const LLBlockedListItem* blocked_i LLMute::EType type1 = blocked_item1->getType(); LLMute::EType type2 = blocked_item2->getType(); - if (type1 != type2) + // if mute type is LLMute::BY_NAME or LLMute::OBJECT it means that this mute is an object + bool both_mutes_are_objects = (LLMute::OBJECT == type1 || LLMute::BY_NAME == type1) && (LLMute::OBJECT == type2 || LLMute::BY_NAME == type2); + + // mute types may be different, but since both LLMute::BY_NAME and LLMute::OBJECT types represent objects + // it's needed to perform additional checking of both_mutes_are_objects variable + if (type1 != type2 && !both_mutes_are_objects) { - return type1 > type2; + // objects in block list go first, so return true if mute type is not an avatar + return LLMute::AGENT != type1; } return NAME_COMPARATOR.compare(blocked_item1, blocked_item2); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index dcd6d25888..80be753d9e 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -734,17 +734,23 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } LLColor4 txt_color = LLUIColorTable::instance().getColor("White"); + LLColor4 name_color(txt_color); + LLViewerChat::getChatColor(chat,txt_color); LLFontGL* fontp = LLViewerChat::getChatFont(); std::string font_name = LLFontGL::nameFromFont(fontp); std::string font_size = LLFontGL::sizeFromFont(fontp); - LLStyle::Params style_params; - style_params.color(txt_color); - style_params.readonly_color(txt_color); - style_params.font.name(font_name); - style_params.font.size(font_size); - style_params.font.style(input_append_params.font.style); + LLStyle::Params body_message_params; + body_message_params.color(txt_color); + body_message_params.readonly_color(txt_color); + body_message_params.font.name(font_name); + body_message_params.font.size(font_size); + body_message_params.font.style(input_append_params.font.style); + + LLStyle::Params name_params(body_message_params); + name_params.color(name_color); + name_params.readonly_color(name_color); std::string prefix = chat.mText.substr(0, 4); @@ -767,7 +773,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC) { delimiter = LLStringUtil::null; - style_params.font.style = "ITALIC"; + name_params.font.style = "ITALIC"; } bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY; @@ -775,18 +781,20 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL if (message_from_log) { txt_color = LLColor4::grey; - style_params.color(txt_color); - style_params.readonly_color(txt_color); + body_message_params.color(txt_color); + body_message_params.readonly_color(txt_color); + name_params.color(txt_color); + name_params.readonly_color(txt_color); } bool prependNewLineState = mEditor->getText().size() != 0; - // show timestamps and names in the compact mode + // compact mode: show a timestamp and name if (use_plain_text_chat_history) { square_brackets = chat.mFromName == SYSTEM_FROM; - LLStyle::Params timestamp_style(style_params); + LLStyle::Params timestamp_style(body_message_params); // out of the timestamp if (args["show_time"].asBoolean()) @@ -804,7 +812,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL // out the opening square bracket (if need) if (square_brackets) { - mEditor->appendText("[", prependNewLineState, style_params); + mEditor->appendText("[", prependNewLineState, body_message_params); prependNewLineState = false; } @@ -819,7 +827,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL // set the link for the object name to be the objectim SLapp // (don't let object names with hyperlinks override our objectim Url) - LLStyle::Params link_params(style_params); + LLStyle::Params link_params(body_message_params); LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); link_params.color = link_color; link_params.readonly_color = link_color; @@ -831,7 +839,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log) { - LLStyle::Params link_params(style_params); + LLStyle::Params link_params(body_message_params); link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID)); if (from_me) @@ -852,7 +860,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL else { mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, - prependNewLineState, style_params); + prependNewLineState, body_message_params); prependNewLineState = false; } } @@ -880,7 +888,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } else { - view = getHeader(chat, style_params, args); + view = getHeader(chat, name_params, args); if (mEditor->getText().size() == 0) p.top_pad = 0; else @@ -909,6 +917,9 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mIsLastMessageFromLog = message_from_log; } + // body of the message processing + + // notify processing if (chat.mNotifId.notNull()) { LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId); @@ -932,6 +943,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mEditor->appendWidget(params, "\n", false); } } + + // usual messages showing else { std::string message = irc_me ? chat.mText.substr(3) : chat.mText; @@ -959,7 +972,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL message += "]"; } - mEditor->appendText(message, prependNewLineState, style_params); + mEditor->appendText(message, prependNewLineState, body_message_params); prependNewLineState = false; } diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp index acdd7ba46a..3c6c5c3898 100644 --- a/indra/newview/llimconversation.cpp +++ b/indra/newview/llimconversation.cpp @@ -55,12 +55,6 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id) { mCommitCallbackRegistrar.add("IMSession.Menu.Action", boost::bind(&LLIMConversation::onIMSessionMenuItemClicked, this, _2)); -// mCommitCallbackRegistrar.add("IMSession.ExpCollapseBtn.Click", -// boost::bind(&LLIMConversation::onSlide, this)); -// mCommitCallbackRegistrar.add("IMSession.CloseBtn.Click", -// boost::bind(&LLFloater::onClickClose, this)); - mCommitCallbackRegistrar.add("IMSession.TearOffBtn.Click", - boost::bind(&LLIMConversation::onTearOffClicked, this)); mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem", boost::bind(&LLIMConversation::onIMCompactExpandedMenuItemCheck, this, _2)); mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem", @@ -254,9 +248,7 @@ void LLIMConversation::updateHeaderAndToolbar() if (mDragHandle) { mDragHandle->setTitleVisible(!is_hosted); - setCanDrag(!is_hosted); } - setCanResize(!is_hosted); // The button (>>) should be disabled for torn off P2P conversations. mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat); @@ -349,8 +341,6 @@ void LLIMConversation::onOpen(const LLSD& key) host_floater->collapseMessagesPane(false); } - setCanResize(TRUE); - updateHeaderAndToolbar(); } @@ -370,7 +360,7 @@ void LLIMConversation::onClose(bool app_quitting) void LLIMConversation::onTearOffClicked() { - onClickTearOff(this); + LLFloater::onClickTearOff(this); updateHeaderAndToolbar(); } diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h index 50663137ac..682779a44b 100644 --- a/indra/newview/llimconversation.h +++ b/indra/newview/llimconversation.h @@ -78,7 +78,7 @@ protected: bool onIMShowModesMenuItemCheck(const LLSD& userdata); bool onIMShowModesMenuItemEnable(const LLSD& userdata); static void onSlide(LLIMConversation *self); - void onTearOffClicked(); + virtual void onTearOffClicked(); // refresh a visual state of the Call button void updateCallBtnState(bool callIsActive); diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 9d3c0f98ce..a506f0f9f3 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -322,7 +322,7 @@ BOOL LLIMFloater::postBuild() void LLIMFloater::onAddButtonClicked() { - LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::onAvatarPicked, this, _1, _2), TRUE, TRUE); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::addSessionParticipants, this, _1), TRUE, TRUE); if (!picker) { return; @@ -337,55 +337,94 @@ void LLIMFloater::onAddButtonClicked() } } -void LLIMFloater::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) +bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids) { - if (mIsP2PChat) - { - mStartConferenceInSameFloater = true; - onClose(false); + if (!mSession + || mDialog == IM_SESSION_GROUP_START + || mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID)) + { + return false; + } - uuid_vec_t temp_ids; - temp_ids.push_back(mOtherParticipantUUID); - temp_ids.insert(temp_ids.end(), ids.begin(), ids.end()); + if (mIsP2PChat) + { + // For a P2P session just check if we are not adding the other participant. - LLAvatarActions::startConference(temp_ids, mSessionID); - } - else - { - inviteToSession(ids); - } + 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<LLSpeaker>& speaker = *it; + if (*id == speaker->mID) + { + return false; + } + } + } + } + + return true; } -bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids) +void LLIMFloater::addSessionParticipants(const uuid_vec_t& uuids) { - if (!mSession - || mDialog == IM_SESSION_GROUP_START - || mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID)) - { - return false; - } + if (mIsP2PChat) + { + mStartConferenceInSameFloater = true; - for (uuid_vec_t::const_iterator id = uuids.begin(); - id != uuids.end(); ++id) - { - // Skip this check for ad hoc conferences, - // conference participants should be listed in mSession->mInitialTargetIDs. - if (mIsP2PChat && *id == mOtherParticipantUUID) - { - return false; - } - - for (uuid_vec_t::const_iterator target_id = mSession->mInitialTargetIDs.begin(); - target_id != mSession->mInitialTargetIDs.end(); ++target_id) - { - if (*id == *target_id) - { - return false; - } - } - } + 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()); + + 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(); - return true; + // then we can close the current session + gIMMgr->leaveSession(mSessionID); + LLIMConversation::onClose(false); + + // 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); + } + } + else + { + inviteToSession(uuids); + } } void LLIMFloater::boundVoiceChannel() @@ -1096,19 +1135,7 @@ bool LLIMFloater::dropPerson(LLUUID* person_id, bool drop) res = canAddSelectedToChat(ids); if(res && drop) { - if (mIsP2PChat) - { - mStartConferenceInSameFloater = true; - onClose(false); - - ids.push_back(mOtherParticipantUUID); - - LLAvatarActions::startConference(ids, mSessionID); - } - else - { - inviteToSession(ids); - } + addSessionParticipants(ids); } } diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index 23f9e75e21..2e8fc84746 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -152,7 +152,7 @@ private: static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata); void setTyping(bool typing); void onAddButtonClicked(); - void onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names); + void addSessionParticipants(const uuid_vec_t& uuids); bool canAddSelectedToChat(const uuid_vec_t& uuids); void onCallButtonClicked(); diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index d343c8be24..e9144a4969 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -37,6 +37,7 @@ #include "llagent.h" #include "llavataractions.h" #include "llavatariconctrl.h" +#include "llavatarnamecache.h" #include "llgroupiconctrl.h" #include "llfloateravatarpicker.h" #include "llimview.h" @@ -74,8 +75,15 @@ LLIMFloaterContainer::~LLIMFloaterContainer() void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id) { - LLIMFloater::show(session_id); -}; + LLIMFloater::show(session_id); +} + +void LLIMFloaterContainer::sessionRemoved(const LLUUID& session_id) +{ + LLIMFloater* floaterp = LLIMFloater::findInstance(session_id); + LLFloater::onClickClose(floaterp); + removeConversationListItem(floaterp); +} BOOL LLIMFloaterContainer::postBuild() { @@ -110,6 +118,8 @@ BOOL LLIMFloaterContainer::postBuild() collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed")); collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed")); + LLAvatarNameCache::addUseDisplayNamesCallback( + boost::bind(&LLIMConversation::processChatHistoryStyleUpdate)); return TRUE; } @@ -306,9 +316,8 @@ void LLIMFloaterContainer::setVisible(BOOL visible) if (visible) { // Make sure we have the Nearby Chat present when showing the conversation container - LLUUID nearbychat_uuid = LLUUID::null; // Hacky but true: the session id for nearby chat is always null - LLFloater* floaterp = findConversationItem(nearbychat_uuid); - if (floaterp == NULL) + LLFloater* nearby_chat = LLFloaterReg::findInstance("chat_bar"); + if (nearby_chat == NULL) { // If not found, force the creation of the nearby chat conversation panel // *TODO: find a way to move this to XML as a default panel or something like that @@ -540,10 +549,6 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF mFloater(floaterp), mContainer(containerp) { - // Hack: the nearby chat has no name so we catch that case and impose one - // Of course, we won't be doing this in the final code - if (name == "") - mName = "Nearby Chat"; } LLConversationItem::LLConversationItem() : diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index 8f0ec27905..0d988b5b73 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -238,7 +238,7 @@ public: // LLIMSessionObserver observe triggers /*virtual*/ void sessionAdded(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 sessionRemoved(const LLUUID& session_id); /*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {}; private: diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 79018ec366..cdbb7c7cca 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -2583,7 +2583,6 @@ LLUUID LLIMMgr::addSession( LLDynamicArray<LLUUID> ids; ids.put(other_participant_id); LLUUID session_id = addSession(name, dialog, other_participant_id, ids, voice); - notifyObserverSessionVoiceOrIMStarted(session_id); return session_id; } @@ -2653,6 +2652,8 @@ LLUUID LLIMMgr::addSession( noteMutedUsers(session_id, ids); } + notifyObserverSessionVoiceOrIMStarted(session_id); + return session_id; } diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index a81d6b4025..384762549a 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -158,6 +158,10 @@ BOOL LLNearbyChat::postBuild() enableResizeCtrls(true, true, false); + // title must be defined BEFORE call addToHost() because + // it is used for show the item's name in the conversations list + setTitle(getString("NearbyChatTitle")); + addToHost(); //for menu @@ -182,7 +186,6 @@ BOOL LLNearbyChat::postBuild() loadHistory(); } - setTitle(getString("NearbyChatTitle")); return LLIMConversation::postBuild(); } @@ -342,15 +345,36 @@ void LLNearbyChat::enableDisableCallBtn() getChildView("voice_call_btn")->setEnabled(false /*btn_enabled*/); } +void LLNearbyChat::onTearOffClicked() +{ + LLIMConversation::onTearOffClicked(); + + LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); + + // see CHUI-170: Save torn-off state of the nearby chat between sessions + BOOL in_the_multifloater = (getHost() == im_box); + gSavedSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater); +} + void LLNearbyChat::addToHost() { - if (LLIMConversation::isChatMultiTab()) + if ( LLIMConversation::isChatMultiTab()) { LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); - if (im_box) { - im_box->addFloater(this, FALSE, LLTabContainer::END); + if (gSavedSettings.getBOOL("NearbyChatIsNotTornOff")) + { + im_box->addFloater(this, TRUE, LLTabContainer::END); + } + else + { + // setting of the "potential" host: this sequence sets + // LLFloater::mHostHandle = NULL (a current host), but + // LLFloater::mLastHostHandle = im_box (a "future" host) + setHost(im_box); + setHost(NULL); + } } } } @@ -364,20 +388,18 @@ void LLNearbyChat::onOpen(const LLSD& key) bool LLNearbyChat::applyRectControl() { - bool rect_controlled = LLFloater::applyRectControl(); + bool is_torn_off = getHost() == NULL; -/* if (!mNearbyChat->getVisible()) + // Resize is limited to torn off floaters. + // A hosted floater is not resizable. + if (is_torn_off) { - reshape(getRect().getWidth(), getMinHeight()); - enableResizeCtrls(true, true, false); - } - else - {*/ enableResizeCtrls(true); - setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); -// } + } - return rect_controlled; + setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); + + return LLFloater::applyRectControl(); } void LLNearbyChat::onChatFontChange(LLFontGL* fontp) @@ -408,9 +430,17 @@ void LLNearbyChat::showHistory() { openFloater(); setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); - reshape(getRect().getWidth(), mExpandedHeight); - enableResizeCtrls(true); - storeRectControl(); + + bool is_torn_off = getHost() == NULL; + + // Reshape and enable resize controls only if it's a torn off floater. + // Otherwise all the size changes should be handled by LLIMFloaterContainer. + if (is_torn_off) + { + reshape(getRect().getWidth(), mExpandedHeight); + enableResizeCtrls(true); + storeRectControl(); + } } std::string LLNearbyChat::getCurrentChat() diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 61404df942..90feb71488 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -101,6 +101,8 @@ protected: void onToggleNearbyChatPanel(); + /*virtual*/ void onTearOffClicked(); + static LLWString stripChannelNumber(const LLWString &mesg, S32* channel); EChatType processChatTypeTriggers(EChatType type, std::string &str); diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index ac2109dda4..c9eebe24d3 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -82,7 +82,7 @@ LLContextMenu* NearbyMenu::createMenu() // registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs)); // *TODO: unimplemented registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startConference, mUUIDs, LLUUID::null)); - registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startAdhocCall, mUUIDs)); + registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startAdhocCall, mUUIDs, LLUUID::null)); registrar.add("Avatar.OfferTeleport", boost::bind(&NearbyMenu::offerTeleport, this)); registrar.add("Avatar.RemoveFriend",boost::bind(&LLAvatarActions::removeFriendsDialog, mUUIDs)); // registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::startIM, mUUIDs)); // *TODO: unimplemented diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index b0e36d756d..03c113ecb3 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1495,7 +1495,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& } LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); - llassert(notification_ptr != NULL); // For muting, we need to add the mute, then decline the offer. // This must be done here because: @@ -1518,7 +1517,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& bool busy = gAgent.getBusy(); - LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm())); + LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm()); switch(button) { @@ -1564,7 +1563,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& break; } - modified_form->setElementEnabled("Show", false); + if (modified_form != NULL) + { + modified_form->setElementEnabled("Show", false); + } break; // end switch (mIM) @@ -1581,7 +1583,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& break; case IOR_MUTE: - modified_form->setElementEnabled("Mute", false); + if (modified_form != NULL) + { + modified_form->setElementEnabled("Mute", false); + } // MUTE falls through to decline case IOR_DECLINE: { @@ -1618,8 +1623,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& busy_message(gMessageSystem, mFromID); } - modified_form->setElementEnabled("Show", false); - modified_form->setElementEnabled("Discard", false); + if (modified_form != NULL) + { + modified_form->setElementEnabled("Show", false); + modified_form->setElementEnabled("Discard", false); + } break; } @@ -1641,8 +1649,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& delete this; } - notification_ptr->updateForm(modified_form); - notification_ptr->repost(); + if (notification_ptr != NULL) + { + notification_ptr->updateForm(modified_form); + notification_ptr->repost(); + } return false; } |