From 11adf324c7c163b286e42da759767f9aa779aaaf Mon Sep 17 00:00:00 2001 From: Alexei Arabadji Date: Thu, 17 Dec 2009 11:46:02 +0200 Subject: =?UTF-8?q?implemented=20EXT-3395=20=E2=80=9CDocked=20IM/Chat=20wi?= =?UTF-8?q?ndows=20shouldn't=20hide=20when=20voice=20control=20panel=20is?= =?UTF-8?q?=20opened=E2=80=9D,=20reverted=20changes=20from=206658:6a771495?= =?UTF-8?q?9726;=20made=20LLCallFloater=20non-unique=20dockable;=20added?= =?UTF-8?q?=20LLCallFloater=20to=20control=20list=20of=20Transient=20Manag?= =?UTF-8?q?er;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --HG-- branch : product-engine --- indra/llui/lldockablefloater.cpp | 8 ++------ indra/newview/llcallfloater.cpp | 5 ++++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index 9dc7861992..63faf44f9d 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -38,8 +38,6 @@ //static LLHandle LLDockableFloater::sInstanceHandle; -static const std::string VOICE_FLOATER("floater_voice_controls"), IM_FLOATER("panel_im"); - //static void LLDockableFloater::init(LLDockableFloater* thiz) { @@ -116,11 +114,9 @@ void LLDockableFloater::resetInstance() { if (mUniqueDocking && sInstanceHandle.get() != this) { - if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked() - && (getName() != VOICE_FLOATER || sInstanceHandle.get()->getName() != IM_FLOATER) - && (getName() != IM_FLOATER || sInstanceHandle.get()->getName() != VOICE_FLOATER)) + if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked()) { - sInstanceHandle.get()->setVisible(FALSE); + sInstanceHandle.get()->setVisible(FALSE); } sInstanceHandle = getHandle(); } diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 2f5523e04d..5f45abc922 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -44,6 +44,7 @@ #include "llbottomtray.h" #include "llparticipantlist.h" #include "llspeakers.h" +#include "lltransientfloatermgr.h" class LLNonAvatarCaller : public LLAvatarListItem @@ -77,7 +78,7 @@ static void* create_non_avatar_caller(void*) } LLCallFloater::LLCallFloater(const LLSD& key) -: LLDockableFloater(NULL, key) +: LLDockableFloater(NULL, false, key) , mSpeakerManager(NULL) , mPaticipants(NULL) , mAvatarList(NULL) @@ -89,6 +90,7 @@ LLCallFloater::LLCallFloater(const LLSD& key) { mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL); LLVoiceClient::getInstance()->addObserver(this); + LLTransientFloaterMgr::getInstance()->addControlView(this); } LLCallFloater::~LLCallFloater() @@ -103,6 +105,7 @@ LLCallFloater::~LLCallFloater() { gVoiceClient->removeObserver(this); } + LLTransientFloaterMgr::getInstance()->removeControlView(this); } // virtual -- cgit v1.2.3 From 5370d9f35bc5aac49dbb8f065c13f094879ed436 Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Wed, 16 Dec 2009 14:44:55 +0200 Subject: Work on EXT-3431 Implement 'mute/unmute everyone else' moderation in the voice control panel -- code refactored: moderator actions are moved from UI to IM Speaker Manager (and just called from UI). --HG-- branch : product-engine --- indra/newview/llparticipantlist.cpp | 102 +++++------------------------------- indra/newview/llspeakers.cpp | 99 ++++++++++++++++++++++++++++++++++ indra/newview/llspeakers.h | 28 ++++++++++ 3 files changed, 141 insertions(+), 88 deletions(-) diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 2c5f1b094e..93e5b8fa15 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -49,43 +49,6 @@ #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally #endif -class ModerationResponder : public LLHTTPClient::Responder -{ -public: - ModerationResponder(const LLUUID& session_id) - { - mSessionID = session_id; - } - - virtual void error(U32 status, const std::string& reason) - { - llwarns << status << ": " << reason << llendl; - - if ( gIMMgr ) - { - //403 == you're not a mod - //should be disabled if you're not a moderator - if ( 403 == status ) - { - gIMMgr->showSessionEventError( - "mute", - "not_a_mod_error", - mSessionID); - } - else - { - gIMMgr->showSessionEventError( - "mute", - "generic_request_error", - mSessionID); - } - } - } - -private: - LLUUID mSessionID; -}; - LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list, bool use_context_menu/* = true*/): mSpeakerMgr(data_source), mAvatarList(avatar_list), @@ -471,22 +434,13 @@ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const void LLParticipantList::LLParticipantListMenu::toggleAllowTextChat(const LLSD& userdata) { - const LLUUID speaker_id = mUUIDs.front(); - std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); - LLSD data; - data["method"] = "mute update"; - data["session-id"] = mParent.mSpeakerMgr->getSessionID(); - data["params"] = LLSD::emptyMap(); - data["params"]["agent_id"] = speaker_id; - data["params"]["mute_info"] = LLSD::emptyMap(); - //current value represents ability to type, so invert - data["params"]["mute_info"]["text"] = !mParent.mSpeakerMgr->findSpeaker(speaker_id)->mModeratorMutedText; - - LLHTTPClient::post( - url, - data, - new ModerationResponder(mParent.mSpeakerMgr->getSessionID())); + LLIMSpeakerMgr* mgr = dynamic_cast(mParent.mSpeakerMgr); + if (mgr) + { + const LLUUID speaker_id = mUUIDs.front(); + mgr->toggleAllowTextChat(speaker_id); + } } void LLParticipantList::LLParticipantListMenu::toggleMute(const LLSD& userdata, U32 flags) @@ -565,47 +519,19 @@ void LLParticipantList::LLParticipantListMenu::moderateVoice(const LLSD& userdat void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute) { - if (gAgentID == avatar_id) return; // do not process myself - - LLPointer speakerp = mParent.mSpeakerMgr->findSpeaker(avatar_id); - if (!speakerp) return; - - // *NOTE: mantipov: probably this condition will be incorrect when avatar will be blocked for - // text chat via moderation (LLSpeaker::mModeratorMutedText == TRUE) - bool is_in_voice = speakerp->mStatus <= LLSpeaker::STATUS_VOICE_ACTIVE || speakerp->mStatus == LLSpeaker::STATUS_MUTED; - - // do not send voice moderation changes for avatars not in voice channel - if (!is_in_voice) return; - - std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); - LLSD data; - data["method"] = "mute update"; - data["session-id"] = mParent.mSpeakerMgr->getSessionID(); - data["params"] = LLSD::emptyMap(); - data["params"]["agent_id"] = avatar_id; - data["params"]["mute_info"] = LLSD::emptyMap(); - data["params"]["mute_info"]["voice"] = !unmute; - - LLHTTPClient::post( - url, - data, - new ModerationResponder(mParent.mSpeakerMgr->getSessionID())); + LLIMSpeakerMgr* mgr = dynamic_cast(mParent.mSpeakerMgr); + if (mgr) + { + mgr->moderateVoiceParticipant(avatar_id, unmute); + } } void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute) { - LLSpeakerMgr::speaker_list_t speakers; - mParent.mSpeakerMgr->getSpeakerList(&speakers, FALSE); - - for (LLSpeakerMgr::speaker_list_t::iterator iter = speakers.begin(); - iter != speakers.end(); ++iter) + LLIMSpeakerMgr* mgr = dynamic_cast(mParent.mSpeakerMgr); + if (mgr) { - LLSpeaker* speakerp = (*iter).get(); - LLUUID speaker_id = speakerp->mID; - - if (excluded_avatar_id == speaker_id) continue; - - moderateVoiceParticipant(speaker_id, unmute); + mgr->moderateVoiceOtherParticipants(excluded_avatar_id, unmute); } } diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 261bdbcfc0..1b9fee650e 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -36,6 +36,7 @@ #include "llagent.h" #include "llappviewer.h" +#include "llimview.h" #include "llmutelist.h" #include "llsdutil.h" #include "lluicolortable.h" @@ -575,6 +576,104 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update) } } +class ModerationResponder : public LLHTTPClient::Responder +{ +public: + ModerationResponder(const LLUUID& session_id) + { + mSessionID = session_id; + } + + virtual void error(U32 status, const std::string& reason) + { + llwarns << status << ": " << reason << llendl; + + if ( gIMMgr ) + { + //403 == you're not a mod + //should be disabled if you're not a moderator + if ( 403 == status ) + { + gIMMgr->showSessionEventError( + "mute", + "not_a_mod_error", + mSessionID); + } + else + { + gIMMgr->showSessionEventError( + "mute", + "generic_request_error", + mSessionID); + } + } + } + +private: + LLUUID mSessionID; +}; + +void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id) +{ + std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); + LLSD data; + data["method"] = "mute update"; + data["session-id"] = getSessionID(); + data["params"] = LLSD::emptyMap(); + data["params"]["agent_id"] = speaker_id; + data["params"]["mute_info"] = LLSD::emptyMap(); + //current value represents ability to type, so invert + data["params"]["mute_info"]["text"] = !findSpeaker(speaker_id)->mModeratorMutedText; + + LLHTTPClient::post(url, data, new ModerationResponder(getSessionID())); +} + +void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute) +{ + if (gAgentID == avatar_id) return; // do not process myself + + LLPointer speakerp = findSpeaker(avatar_id); + if (!speakerp) return; + + // *NOTE: mantipov: probably this condition will be incorrect when avatar will be blocked for + // text chat via moderation (LLSpeaker::mModeratorMutedText == TRUE) + bool is_in_voice = speakerp->mStatus <= LLSpeaker::STATUS_VOICE_ACTIVE || speakerp->mStatus == LLSpeaker::STATUS_MUTED; + + // do not send voice moderation changes for avatars not in voice channel + if (!is_in_voice) return; + + std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); + LLSD data; + data["method"] = "mute update"; + data["session-id"] = getSessionID(); + data["params"] = LLSD::emptyMap(); + data["params"]["agent_id"] = avatar_id; + data["params"]["mute_info"] = LLSD::emptyMap(); + data["params"]["mute_info"]["voice"] = !unmute; + + LLHTTPClient::post( + url, + data, + new ModerationResponder(getSessionID())); +} + +void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute) +{ + LLSpeakerMgr::speaker_list_t speakers; + getSpeakerList(&speakers, FALSE); + + for (LLSpeakerMgr::speaker_list_t::iterator iter = speakers.begin(); + iter != speakers.end(); ++iter) + { + LLSpeaker* speakerp = (*iter).get(); + LLUUID speaker_id = speakerp->mID; + + if (excluded_avatar_id == speaker_id) continue; + + moderateVoiceParticipant(speaker_id, unmute); + } +} + // // LLActiveSpeakerMgr diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index 04046a8587..6f7a1d2c49 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -158,6 +158,34 @@ public: void updateSpeakers(const LLSD& update); void setSpeakers(const LLSD& speakers); + + void toggleAllowTextChat(const LLUUID& speaker_id); + + /** + * Mutes/Unmutes avatar for current group voice chat. + * + * It only marks avatar as muted for session and does not use local Agent's Block list. + * It does not mute Agent itself. + * + * @param[in] avatar_id UUID of avatar to be processed + * @param[in] unmute if false - specified avatar will be muted, otherwise - unmuted. + * + * @see moderateVoiceOtherParticipants() + */ + void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute); + + /** + * Mutes/Unmutes all avatars except specified for current group voice chat. + * + * It only marks avatars as muted for session and does not use local Agent's Block list. + * It based call moderateVoiceParticipant() for each avatar should be muted/unmuted. + * + * @param[in] excluded_avatar_id UUID of avatar NOT to be processed + * @param[in] unmute if true - avatars will be muted, otherwise - unmuted. + * + * @see moderateVoiceParticipant() + */ + void moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute); protected: virtual void updateSpeakerList(); }; -- cgit v1.2.3 From 0ec2bacfac207451386b55006f94e917f1277edc Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Wed, 16 Dec 2009 18:14:15 +0200 Subject: Work on EXT-3431 Implement 'mute/unmute everyone else' moderation in the voice control panel -- changed behavior of 'mute/unmute everyone else' action to disable/enable voice chat and allow/disallow selected participant Improvements to have more intellectual processing of several following requests is necessary --HG-- branch : product-engine --- indra/newview/llimview.cpp | 5 +++++ indra/newview/llspeakers.cpp | 37 +++++++++++++++++++++++++++++++++++++ indra/newview/llspeakers.h | 7 +++++++ 3 files changed, 49 insertions(+) diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 1d56fc0cab..ad30b844a9 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -2733,6 +2733,11 @@ public: { im_floater->processSessionUpdate(input["body"]["info"]); } + LLIMSpeakerMgr* im_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id); + if (im_mgr) + { + im_mgr->processSessionUpdate(input["body"]["info"]); + } } }; diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 1b9fee650e..da7910d8b4 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -659,6 +659,11 @@ void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmu void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute) { + // TODO: mantipov: add more intellectual processing of several following requests + + mReverseVoiceModeratedAvatarID = excluded_avatar_id; + moderateVoiceSession(getSessionID(), !unmute); +/* LLSpeakerMgr::speaker_list_t speakers; getSpeakerList(&speakers, FALSE); @@ -672,6 +677,38 @@ void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avata moderateVoiceParticipant(speaker_id, unmute); } +*/ +} + +void LLIMSpeakerMgr::processSessionUpdate(const LLSD& session_update) +{ + if (mReverseVoiceModeratedAvatarID.isNull()) return; + + if (session_update.has("moderated_mode") && + session_update["moderated_mode"].has("voice")) + { + BOOL voice_moderated = session_update["moderated_mode"]["voice"]; + + moderateVoiceParticipant(mReverseVoiceModeratedAvatarID, voice_moderated); + + mReverseVoiceModeratedAvatarID = LLUUID::null; + } +} + +void LLIMSpeakerMgr::moderateVoiceSession(const LLUUID& session_id, bool disallow_voice) +{ + std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); + LLSD data; + data["method"] = "session update"; + data["session-id"] = session_id; + data["params"] = LLSD::emptyMap(); + + data["params"]["update_info"] = LLSD::emptyMap(); + + data["params"]["update_info"]["moderated_mode"] = LLSD::emptyMap(); + data["params"]["update_info"]["moderated_mode"]["voice"] = disallow_voice; + + LLHTTPClient::post(url, data, new ModerationResponder(session_id)); } diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index 6f7a1d2c49..55d2351cbf 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -186,8 +186,15 @@ public: * @see moderateVoiceParticipant() */ void moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute); + + void processSessionUpdate(const LLSD& session_update); + protected: virtual void updateSpeakerList(); + + void moderateVoiceSession(const LLUUID& session_id, bool disallow_voice); + + LLUUID mReverseVoiceModeratedAvatarID; }; class LLActiveSpeakerMgr : public LLSpeakerMgr, public LLSingleton -- cgit v1.2.3 From e921eac328f60a44b2671cba6ea0bf09c03c14f3 Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Wed, 16 Dec 2009 19:19:42 +0200 Subject: Fixed line endings to unix format --HG-- branch : product-engine --- indra/newview/llspeakers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index da7910d8b4..6bbd3c6687 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -662,7 +662,7 @@ void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avata // TODO: mantipov: add more intellectual processing of several following requests mReverseVoiceModeratedAvatarID = excluded_avatar_id; - moderateVoiceSession(getSessionID(), !unmute); + moderateVoiceSession(getSessionID(), !unmute); /* LLSpeakerMgr::speaker_list_t speakers; getSpeakerList(&speakers, FALSE); -- cgit v1.2.3 From d2b0245d5886d823bf8ad343d61c6c6f0babc274 Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Wed, 16 Dec 2009 20:43:12 +0200 Subject: rename values to be more descriptive --HG-- branch : product-engine --- indra/newview/llspeakers.cpp | 6 +++--- indra/newview/llspeakers.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 6bbd3c6687..6e5a867426 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -657,12 +657,12 @@ void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmu new ModerationResponder(getSessionID())); } -void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute) +void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute_everyone_else) { // TODO: mantipov: add more intellectual processing of several following requests mReverseVoiceModeratedAvatarID = excluded_avatar_id; - moderateVoiceSession(getSessionID(), !unmute); + moderateVoiceSession(getSessionID(), !unmute_everyone_else); /* LLSpeakerMgr::speaker_list_t speakers; getSpeakerList(&speakers, FALSE); @@ -675,7 +675,7 @@ void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avata if (excluded_avatar_id == speaker_id) continue; - moderateVoiceParticipant(speaker_id, unmute); + moderateVoiceParticipant(speaker_id, unmute_everyone_else); } */ } diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index 55d2351cbf..1a8c23f56a 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -181,11 +181,11 @@ public: * It based call moderateVoiceParticipant() for each avatar should be muted/unmuted. * * @param[in] excluded_avatar_id UUID of avatar NOT to be processed - * @param[in] unmute if true - avatars will be muted, otherwise - unmuted. + * @param[in] unmute_everyone_else if false - avatars will be muted, otherwise - unmuted. * * @see moderateVoiceParticipant() */ - void moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute); + void moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute_everyone_else); void processSessionUpdate(const LLSD& session_update); -- cgit v1.2.3 From 82929ee43b4fb7db6435f419d3e2818684b49eae Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Thu, 17 Dec 2009 13:00:16 +0200 Subject: Work on EXT-3431 Implement 'mute/unmute everyone else' moderation in the voice control panel -- added comment to test scenario when "Moderator sends the same second request before first response is come" --HG-- branch : product-engine --- indra/newview/llspeakers.cpp | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 6e5a867426..3861a96355 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -659,25 +659,27 @@ void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmu void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute_everyone_else) { - // TODO: mantipov: add more intellectual processing of several following requests + // *TODO: mantipov: add more intellectual processing of several following requests if it is needed. + /* + Such situation should be tested: + "Moderator sends the same second request before first response is come" + Moderator sends "mute everyone else" for A and then for B + two requests to disallow voice chat are sent + UUID of B is stored. + Then first response (to disallow voice chat) is come + request to allow voice for stored avatar (B) + Then second response (to disallow voice chat) is come + have nothing to do, the latest selected speaker is already enabled + + What can happen? + If request to allow voice for stored avatar (B) is processed on server BEFORE + second request to disallow voice chat all speakers will be disabled on voice. + But I'm not sure such situation is possible. + See EXT-3431. + */ mReverseVoiceModeratedAvatarID = excluded_avatar_id; moderateVoiceSession(getSessionID(), !unmute_everyone_else); -/* - LLSpeakerMgr::speaker_list_t speakers; - getSpeakerList(&speakers, FALSE); - - for (LLSpeakerMgr::speaker_list_t::iterator iter = speakers.begin(); - iter != speakers.end(); ++iter) - { - LLSpeaker* speakerp = (*iter).get(); - LLUUID speaker_id = speakerp->mID; - - if (excluded_avatar_id == speaker_id) continue; - - moderateVoiceParticipant(speaker_id, unmute_everyone_else); - } -*/ } void LLIMSpeakerMgr::processSessionUpdate(const LLSD& session_update) -- cgit v1.2.3 From b4bb8428b9072081855a289df95b600a800d4f82 Mon Sep 17 00:00:00 2001 From: Denis Serdjuk Date: Thu, 17 Dec 2009 13:26:53 +0200 Subject: fixed bug EXT-3371 Favorites Bar button widths not implemented correctly --HG-- branch : product-engine --- indra/newview/llfavoritesbar.cpp | 338 +++++++++------------ indra/newview/llfavoritesbar.h | 8 +- .../skins/default/xui/en/panel_navigation_bar.xml | 1 + 3 files changed, 155 insertions(+), 192 deletions(-) diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 17b0710813..da0a9727a9 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -370,6 +370,7 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) mLandingTab(NULL), mLastTab(NULL), mTabsHighlightEnabled(TRUE) + , mUpdateDropDownItems(true) { // Register callback for menus with current registrar (will be parent panel's registrar) LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Favorites.DoToSelected", @@ -589,16 +590,15 @@ void LLFavoritesBarCtrl::changed(U32 mask) } else { - updateButtons(getRect().getWidth()); + updateButtons(); } } //virtual void LLFavoritesBarCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) { - updateButtons(width); - LLUICtrl::reshape(width, height, called_from_parent); + updateButtons(); } void LLFavoritesBarCtrl::draw() @@ -637,7 +637,7 @@ LLXMLNodePtr LLFavoritesBarCtrl::getButtonXMLNode() return buttonXMLNode; } -void LLFavoritesBarCtrl::updateButtons(U32 bar_width) +void LLFavoritesBarCtrl::updateButtons() { mItems.clear(); @@ -652,139 +652,142 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) return; } - S32 buttonWidth = 120; //default value - buttonXMLNode->getAttributeS32("width", buttonWidth); - S32 buttonHGap = 2; // default value - buttonXMLNode->getAttributeS32("left", buttonHGap); - - S32 count = mItems.count(); - S32 buttons_space = bar_width - buttonHGap; - - S32 first_drop_down_item = count; - - // Calculating, how much buttons can fit in the bar - S32 buttons_width = 0; - for (S32 i = 0; i < count; ++i) + const child_list_t* childs = getChildList(); + child_list_const_iter_t child_it = childs->begin(); + int first_changed_item_index = 0; + int rightest_point = getRect().mRight - mChevronButton->getRect().getWidth(); + //lets find first changed button + while (child_it != childs->end()) { - buttons_width += buttonWidth + buttonHGap; - if (buttons_width > buttons_space) + LLFavoriteLandmarkButton* button = dynamic_cast (*child_it); + if (button) { - // There is no space for all buttons. - // Calculating the number of buttons, that are fit with chevron button - buttons_space -= mChevronButton->getRect().getWidth() + buttonHGap; - while (i >= 0 && buttons_width > buttons_space) + // an child's order and mItems should be same + if (button->getLandmarkId() != mItems[first_changed_item_index]->getUUID() // sort order has been changed + || button->getLabelSelected() != mItems[first_changed_item_index]->getDisplayName() // favorite's name has been changed + || button->getRect().mRight < rightest_point) // favbar's width has been changed { - buttons_width -= buttonWidth + buttonHGap; - i--; + break; } - first_drop_down_item = i + 1; // First item behind visible items - - break; + first_changed_item_index++; } + child_it++; } + // now first_changed_item_index should contains a number of button that need to change - bool recreate_buttons = true; - - // If inventory items are not changed up to mFirstDropDownItem, no need to recreate them - if (mFirstDropDownItem == first_drop_down_item && (mItemNamesCache.size() == count || mItemNamesCache.size() == mFirstDropDownItem)) + if (first_changed_item_index < mItems.count()) { - S32 i; - for (i = 0; i < mFirstDropDownItem; ++i) + mUpdateDropDownItems = true; + // Rebuild the buttons only + // child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator + + while (child_it != childs->end()) { - if (mItemNamesCache.get(i) != mItems.get(i)->getName()) + //lets remove other landmarks button and rebuild it + child_list_const_iter_t cur_it = child_it++; + LLFavoriteLandmarkButton* button = + dynamic_cast (*cur_it); + if (button) { - break; + removeChild(button); + delete button; } } - if (i == mFirstDropDownItem) + // we have to remove ChevronButton to make sure that the last item will be LandmarkButton to get the right aligning + if (mChevronButton->getParent() == this) { - recreate_buttons = false; + removeChild(mChevronButton); } - } - - if (recreate_buttons) - { - mFirstDropDownItem = first_drop_down_item; - - mItemNamesCache.clear(); - for (S32 i = 0; i < mFirstDropDownItem; i++) + int last_right_edge = 0; + if (getChildList()->size() > 0) { - mItemNamesCache.put(mItems.get(i)->getName()); + last_right_edge = getChildList()->back()->getRect().mRight; } - - // Rebuild the buttons only - // child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ) + //last_right_edge is saving coordinates + LLButton* last_new_button = NULL; + int j = first_changed_item_index; + for (; j < mItems.count(); j++) { - child_list_const_iter_t cur_it = child_it++; - LLView* viewp = *cur_it; - LLButton* button = dynamic_cast(viewp); - if (button && (button != mChevronButton)) + last_new_button = createButton(mItems[j], buttonXMLNode, last_right_edge); + if (!last_new_button) { - removeChild(button); - delete button; + break; } - } - - createButtons(mItems, buttonXMLNode, buttonWidth, buttonHGap); - } + sendChildToBack(last_new_button); + last_right_edge = last_new_button->getRect().mRight; - // Chevron button - if (mFirstDropDownItem != count) - { - // Chevron button should stay right aligned - LLRect rect; - rect.setOriginAndSize(bar_width - mChevronButton->getRect().getWidth() - buttonHGap, 0, mChevronButton->getRect().getWidth(), mChevronButton->getRect().getHeight()); - mChevronButton->setRect(rect); - mChevronButton->setVisible(TRUE); + mLastTab = last_new_button; + } + mFirstDropDownItem = j; + // Chevron button + if (mFirstDropDownItem < mItems.count()) + { + S32 buttonHGap = 2; // default value + buttonXMLNode->getAttributeS32("left", buttonHGap); + LLRect rect; + // Chevron button should stay right aligned + rect.setOriginAndSize(getRect().mRight - mChevronButton->getRect().getWidth() - buttonHGap, 0, + mChevronButton->getRect().getWidth(), + mChevronButton->getRect().getHeight()); + + addChild(mChevronButton); + mChevronButton->setRect(rect); + mChevronButton->setVisible(TRUE); + } } else { - // Hide chevron button if all items are visible on bar - mChevronButton->setVisible(FALSE); + mUpdateDropDownItems = false; } } - -void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &items, const LLXMLNodePtr &buttonXMLNode, S32 buttonWidth, S32 buttonHGap) +LLButton* LLFavoritesBarCtrl::createButton(const LLPointer item, LLXMLNodePtr &buttonXMLNode, S32 x_offset) { - S32 curr_x = buttonHGap; - // Adding buttons + S32 def_button_width = 120; + buttonXMLNode->getAttributeS32("width", def_button_width); + S32 button_x_delta = 2; // default value + buttonXMLNode->getAttributeS32("left", button_x_delta); + S32 curr_x = x_offset; + /** + * WORKAROUND: + * there are some problem with displaying of fonts in buttons. + * Empty space (or ...) is displaying instead of last symbols, even though the width of the button is enough. + * Problem will gone, if we stretch out the button. For that reason I have to put additional 10 pixels. + */ + int requred_width = mFont->getWidth(item->getDisplayName()) + 10; + int width = requred_width > def_button_width? def_button_width : requred_width; LLFavoriteLandmarkButton* fav_btn = NULL; - mLandingTab = mLastTab = NULL; - for(S32 i = mFirstDropDownItem -1, j = 0; i >= 0; i--) + // do we have a place for next button + double buttonHGap + mChevronButton ? + if(curr_x + width + 2*button_x_delta + mChevronButton->getRect().getWidth() > getRect().mRight ) { - LLViewerInventoryItem* item = items.get(j++); - - fav_btn = LLUICtrlFactory::defaultBuilder(buttonXMLNode, this, NULL); - if (NULL == fav_btn) - { - llwarns << "Unable to create button for landmark: " << item->getName() << llendl; - continue; - } - - fav_btn->setLandmarkID(item->getUUID()); - - // change only left and save bottom - fav_btn->setOrigin(curr_x, fav_btn->getRect().mBottom); - fav_btn->setFont(mFont); - fav_btn->setName(item->getName()); - fav_btn->setLabel(item->getName()); - fav_btn->setToolTip(item->getName()); - fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); - fav_btn->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 )); - - fav_btn->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4)); - fav_btn->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4)); - - sendChildToBack(fav_btn); - - curr_x += buttonWidth + buttonHGap; + return NULL; } - - mLastTab = fav_btn; + fav_btn = LLUICtrlFactory::defaultBuilder(buttonXMLNode, this, NULL); + if (NULL == fav_btn) + { + llwarns << "Unable to create LLFavoriteLandmarkButton widget: " << item->getName() << llendl; + return NULL; + } + + LLRect butt_rect (fav_btn->getRect()); + fav_btn->setLandmarkID(item->getUUID()); + butt_rect.setOriginAndSize(curr_x + button_x_delta, fav_btn->getRect().mBottom, width, fav_btn->getRect().getHeight()); + + fav_btn->setRect(butt_rect); + // change only left and save bottom + fav_btn->setFont(mFont); + fav_btn->setName(item->getName()); + fav_btn->setLabel(item->getName()); + fav_btn->setToolTip(item->getName()); + fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); + fav_btn->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 )); + + fav_btn->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4)); + fav_btn->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4)); + + return fav_btn; } @@ -844,99 +847,61 @@ void LLFavoritesBarCtrl::showDropDownMenu() LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get(); - if(menu) + if (menu) { if (!menu->toggleVisibility()) return; - mItems.clear(); - - if (!collectFavoriteItems(mItems)) - { - return; - } - - S32 count = mItems.count(); - - // Check it there are changed items, since last call - if (mItemNamesCache.size() == count) - { - S32 i; - for (i = mFirstDropDownItem; i < count; i++) - { - if (mItemNamesCache.get(i) != mItems.get(i)->getName()) - { - break; - } - } - - // Check passed, just show the menu - if (i == count) - { - menu->buildDrawLabels(); - menu->updateParent(LLMenuGL::sMenuContainer); - - if (menu->getButtonRect().isEmpty()) - { - menu->setButtonRect(mChevronButton->getRect(), this); - } - - LLMenuGL::showPopup(this, menu, getRect().getWidth() - menu->getRect().getWidth(), 0); - return; - } - } - - // Add menu items to cache, if there is only names of buttons - if (mItemNamesCache.size() == mFirstDropDownItem) + U32 max_width = llmin(DROP_DOWN_MENU_WIDTH, getRect().getWidth()); + if (mUpdateDropDownItems) { - for (S32 i = mFirstDropDownItem; i < count; i++) - { - mItemNamesCache.put(mItems.get(i)->getName()); - } - } - - menu->empty(); + menu->empty(); - U32 max_width = llmin(DROP_DOWN_MENU_WIDTH, getRect().getWidth()); - U32 widest_item = 0; + U32 widest_item = 0; - for(S32 i = mFirstDropDownItem; i < count; i++) - { - LLViewerInventoryItem* item = mItems.get(i); - const std::string& item_name = item->getName(); - - LLFavoriteLandmarkMenuItem::Params item_params; - item_params.name(item_name); - item_params.label(item_name); - - item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); - LLFavoriteLandmarkMenuItem *menu_item = LLUICtrlFactory::create(item_params); - menu_item->initFavoritesBarPointer(this); - menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4)); - menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4)); - menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4)); - menu_item->setLandmarkID(item->getUUID()); - - // Check whether item name wider than menu - if (menu_item->getNominalWidth() > max_width) + for (S32 i = mFirstDropDownItem; i < mItems.count(); i++) { - S32 chars_total = item_name.length(); - S32 chars_fitted = 1; - menu_item->setLabel(LLStringExplicit("")); - S32 label_space = max_width - menu_item->getFont()->getWidth("...") - - menu_item->getNominalWidth(); // This returns width of menu item with empty label (pad pixels) - - while (chars_fitted < chars_total && menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space) + LLViewerInventoryItem* item = mItems.get(i); + const std::string& item_name = item->getName(); + + LLFavoriteLandmarkMenuItem::Params item_params; + item_params.name(item_name); + item_params.label(item_name); + + item_params.on_click.function(boost::bind( + &LLFavoritesBarCtrl::onButtonClick, this, + item->getUUID())); + LLFavoriteLandmarkMenuItem *menu_item = LLUICtrlFactory::create(item_params); + menu_item->initFavoritesBarPointer(this); + menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3, _4)); + menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4)); + menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4)); + menu_item->setLandmarkID(item->getUUID()); + + // Check whether item name wider than menu + if (menu_item->getNominalWidth() > max_width) { - chars_fitted++; + S32 chars_total = item_name.length(); + S32 chars_fitted = 1; + menu_item->setLabel(LLStringExplicit("")); + S32 label_space = max_width - menu_item->getFont()->getWidth("...") - + menu_item->getNominalWidth();// This returns width of menu item with empty label (pad pixels) + + while (chars_fitted < chars_total + && menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space) + { + chars_fitted++; + } + chars_fitted--; // Rolling back one char, that doesn't fit + + menu_item->setLabel(item_name.substr(0, chars_fitted) + + "..."); } - chars_fitted--; // Rolling back one char, that doesn't fit + widest_item = llmax(widest_item, menu_item->getNominalWidth()); - menu_item->setLabel(item_name.substr(0, chars_fitted) + "..."); + menu->addChild(menu_item); } - widest_item = llmax(widest_item, menu_item->getNominalWidth()); - - menu->addChild(menu_item); + mUpdateDropDownItems = false; } menu->buildDrawLabels(); @@ -945,7 +910,6 @@ void LLFavoritesBarCtrl::showDropDownMenu() menu->setButtonRect(mChevronButton->getRect(), this); LLMenuGL::showPopup(this, menu, getRect().getWidth() - max_width, 0); - } } diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index b2fe3cc651..9ac734baff 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -74,8 +74,8 @@ public: void setLandingTab(LLUICtrl* tab) { mLandingTab = tab; } protected: - void updateButtons(U32 bar_width); - void createButtons(const LLInventoryModel::item_array_t &items, const LLXMLNodePtr &root, S32 buttonWidth, S32 buttonHGap); + void updateButtons(); + LLButton* createButton(const LLPointer item, LLXMLNodePtr &root, S32 x_offset ); LLXMLNodePtr getButtonXMLNode(); BOOL collectFavoriteItems(LLInventoryModel::item_array_t &items); @@ -101,9 +101,7 @@ protected: LLUUID mFavoriteFolderId; const LLFontGL *mFont; S32 mFirstDropDownItem; - - typedef LLDynamicArray item_names_array_t; - item_names_array_t mItemNamesCache; + bool mUpdateDropDownItems; LLUUID mSelectedItemID; diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index e8e4a9dbb2..74265a51ca 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -149,6 +149,7 @@ Date: Thu, 17 Dec 2009 13:53:59 +0200 Subject: fixed normal bug (EXT-3435) All voice notifications should look similar and according to the Voice UI Spec - added new voice notification that replaced notification toasts - now LLOutgoingCallDialog manages visibility of its controls on its own --HG-- branch : product-engine --- indra/newview/llimview.cpp | 117 +++++++++++++-------- indra/newview/llimview.h | 7 +- indra/newview/llvoicechannel.cpp | 5 +- .../skins/default/xui/en/floater_outgoing_call.xml | 26 ++++- 4 files changed, 104 insertions(+), 51 deletions(-) diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index ad30b844a9..28d9f2170d 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -93,7 +93,8 @@ const static std::string ADHOC_NAME_SUFFIX(" Conference"); std::string LLCallDialogManager::sPreviousSessionlName = ""; std::string LLCallDialogManager::sCurrentSessionlName = ""; LLIMModel::LLIMSession* LLCallDialogManager::sSession = NULL; - +LLVoiceChannel::EState LLCallDialogManager::sOldState = LLVoiceChannel::STATE_READY; +const LLUUID LLOutgoingCallDialog::OCD_KEY = LLUUID("7CF78E11-0CFE-498D-ADB9-1417BF03DDB4"); // // Globals // @@ -1280,12 +1281,22 @@ void LLCallDialogManager::onVoiceChannelChanged(const LLUUID &session_id) void LLCallDialogManager::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction) { LLSD mCallDialogPayload; - LLOutgoingCallDialog* ocd; + LLOutgoingCallDialog* ocd = NULL; + + if(sOldState == new_state) + { + return; + } + + sOldState = new_state; mCallDialogPayload["session_id"] = sSession->mSessionID; mCallDialogPayload["session_name"] = sSession->mName; mCallDialogPayload["other_user_id"] = sSession->mOtherParticipantID; mCallDialogPayload["old_channel_name"] = sPreviousSessionlName; + mCallDialogPayload["state"] = new_state; + mCallDialogPayload["disconnected_channel_name"] = sSession->mName; + mCallDialogPayload["session_type"] = sSession->mSessionType; switch(new_state) { @@ -1295,46 +1306,10 @@ void LLCallDialogManager::onVoiceChannelStateChanged(const LLVoiceChannel::EStat { return; } - - ocd = dynamic_cast(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE)); - if (ocd) - { - ocd->getChild("calling")->setVisible(true); - ocd->getChild("leaving")->setVisible(true); - ocd->getChild("connecting")->setVisible(false); - ocd->getChild("noanswer")->setVisible(false); - ocd->getChild("Cancel")->setVisible(true); - } - return; - - case LLVoiceChannel::STATE_RINGING : - ocd = dynamic_cast(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE)); - if (ocd) - { - ocd->getChild("calling")->setVisible(false); - ocd->getChild("leaving")->setVisible(true); - ocd->getChild("connecting")->setVisible(true); - ocd->getChild("noanswer")->setVisible(false); - ocd->getChild("Cancel")->setVisible(true); - } - return; - - case LLVoiceChannel::STATE_ERROR : - mCallDialogPayload["start_timer"] = true; - ocd = dynamic_cast(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE)); - if (ocd) - { - ocd->getChild("calling")->setVisible(false); - ocd->getChild("leaving")->setVisible(false); - ocd->getChild("connecting")->setVisible(false); - ocd->getChild("noanswer")->setVisible(true); - ocd->getChild("Cancel")->setVisible(false); - } - return; + break; case LLVoiceChannel::STATE_CONNECTED : - case LLVoiceChannel::STATE_HUNG_UP : - ocd = dynamic_cast(LLFloaterReg::showInstance("outgoing_call", mCallDialogPayload, TRUE)); + ocd = LLFloaterReg::findTypedInstance("outgoing_call", LLOutgoingCallDialog::OCD_KEY); if (ocd) { ocd->closeFloater(); @@ -1345,6 +1320,11 @@ void LLCallDialogManager::onVoiceChannelStateChanged(const LLVoiceChannel::EStat break; } + ocd = LLFloaterReg::getTypedInstance("outgoing_call", LLOutgoingCallDialog::OCD_KEY); + if(ocd) + { + ocd->show(mCallDialogPayload); + } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1374,12 +1354,13 @@ void LLCallDialog::onOpen(const LLSD& key) LLOutgoingCallDialog::LLOutgoingCallDialog(const LLSD& payload) : LLCallDialog(payload) { - LLOutgoingCallDialog* instance = LLFloaterReg::findTypedInstance("outgoing_call", payload); + LLOutgoingCallDialog* instance = LLFloaterReg::findTypedInstance("outgoing_call", LLOutgoingCallDialog::OCD_KEY); if(instance && instance->getVisible()) { instance->onCancel(instance); } } + void LLOutgoingCallDialog::draw() { if (lifetimeHasExpired()) @@ -1408,10 +1389,14 @@ void LLOutgoingCallDialog::onLifetimeExpired() closeFloater(); } -void LLOutgoingCallDialog::onOpen(const LLSD& key) +void LLOutgoingCallDialog::show(const LLSD& key) { - LLCallDialog::onOpen(key); + mPayload = key; + + // hide all text at first + hideAllText(); + // customize text strings // tell the user which voice channel they are leaving if (!mPayload["old_channel_name"].asString().empty()) { @@ -1422,6 +1407,12 @@ void LLOutgoingCallDialog::onOpen(const LLSD& key) childSetTextArg("leaving", "[CURRENT_CHAT]", getString("localchat")); } + if (!mPayload["disconnected_channel_name"].asString().empty()) + { + childSetTextArg("nearby", "[VOICE_CHANNEL_NAME]", mPayload["disconnected_channel_name"].asString()); + childSetTextArg("nearby_P2P", "[VOICE_CHANNEL_NAME]", mPayload["disconnected_channel_name"].asString()); + } + std::string callee_name = mPayload["session_name"].asString(); if (callee_name == "anonymous") { @@ -1438,12 +1429,48 @@ void LLOutgoingCallDialog::onOpen(const LLSD& key) // stop timer by default mLifetimeTimer.stop(); - if(mPayload.has("start_timer")) + + // show only necessary strings and controls + switch(mPayload["state"].asInteger()) { - mLifetimeTimer.reset(); + case LLVoiceChannel::STATE_CALL_STARTED : + getChild("calling")->setVisible(true); + getChild("leaving")->setVisible(true); + break; + case LLVoiceChannel::STATE_RINGING : + getChild("leaving")->setVisible(true); + getChild("connecting")->setVisible(true); + break; + case LLVoiceChannel::STATE_ERROR : + getChild("noanswer")->setVisible(true); + getChild("Cancel")->setVisible(false); + mLifetimeTimer.start(); + break; + case LLVoiceChannel::STATE_HUNG_UP : + if (mPayload["session_type"].asInteger() == LLIMModel::LLIMSession::P2P_SESSION) + { + getChild("nearby_P2P")->setVisible(true); + } + else + { + getChild("nearby")->setVisible(true); + } + getChild("Cancel")->setVisible(false); + mLifetimeTimer.start(); } + + openFloater(LLOutgoingCallDialog::OCD_KEY); } +void LLOutgoingCallDialog::hideAllText() +{ + getChild("calling")->setVisible(false); + getChild("leaving")->setVisible(false); + getChild("connecting")->setVisible(false); + getChild("nearby_P2P")->setVisible(false); + getChild("nearby")->setVisible(false); + getChild("noanswer")->setVisible(false); +} //static void LLOutgoingCallDialog::onCancel(void* user_data) diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 6eb3f3d07f..09f0c9df71 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -467,6 +467,7 @@ protected: static std::string sPreviousSessionlName; static std::string sCurrentSessionlName; static LLIMModel::LLIMSession* sSession; + static LLVoiceChannel::EState sOldState; }; class LLCallDialog : public LLDockableFloater @@ -504,14 +505,18 @@ public: LLOutgoingCallDialog(const LLSD& payload); /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); + void show(const LLSD& key); static void onCancel(void* user_data); + static const LLUUID OCD_KEY; // check timer state /*virtual*/ void draw(); private: + + // hide all text boxes + void hideAllText(); // lifetime timer for NO_ANSWER notification LLTimer mLifetimeTimer; // lifetime duration for NO_ANSWER notification diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index fd4e7bb91f..60a2c3b638 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -229,7 +229,6 @@ void LLVoiceChannel::handleStatusChange(EStatusType type) { // if forceably removed from channel // update the UI and revert to default channel - LLNotificationsUtil::add("VoiceChannelDisconnected", mNotifyArgs); deactivate(); } mIgnoreNextSessionLeave = FALSE; @@ -741,6 +740,7 @@ void LLVoiceChannelP2P::handleStatusChange(EStatusType type) case STATUS_LEFT_CHANNEL: if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended) { + // *TODO: use it to show DECLINE voice notification if (mState == STATE_RINGING) { // other user declined call @@ -748,8 +748,7 @@ void LLVoiceChannelP2P::handleStatusChange(EStatusType type) } else { - // other user hung up - LLNotificationsUtil::add("VoiceChannelDisconnectedP2P", mNotifyArgs); + // other user hung up } deactivate(); } diff --git a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml index ae4d5042ef..c6bc093c6c 100644 --- a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml +++ b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml @@ -69,7 +69,29 @@ Calling [CALLEE_NAME] word_wrap="true"> No Answer. Please try again later. - + You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to Nearby Voice Chat. + + + [VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to Nearby Voice Chat. + + Leaving [CURRENT_CHAT]. -