diff options
| author | Seth ProductEngine <slitovchuk@productengine.com> | 2012-06-26 01:38:59 +0300 | 
|---|---|---|
| committer | Seth ProductEngine <slitovchuk@productengine.com> | 2012-06-26 01:38:59 +0300 | 
| commit | 0cfea7b406c87bf593d2f7cf6040d92ef99b64cf (patch) | |
| tree | df1857acbc014a559627a59bed81ab014eea74cd | |
| parent | a7831406abfe87e9bd1da8091e008edcd65b402c (diff) | |
CHUI-147 FIX Added updating conference participants in IM floater title
- The title is updated with the data from participants list widget in IM floater.
- Creating the participants list is fixed for the case of starting the ad hoc session when the session id changes upon initialization (see LLIMConversation::buildParticipantList()).
- LLEventTimer replaced with simple LLTimer to avoid crashes in LLEventTimer::tick().
- Moved the build_residents_string() code to LLAvatarActions::buildResidentsString() to use it in LLIMFloater::onParticipantsListChanged().
| -rwxr-xr-x | indra/newview/llavataractions.cpp | 35 | ||||
| -rw-r--r-- | indra/newview/llavataractions.h | 9 | ||||
| -rw-r--r-- | indra/newview/llimconversation.cpp | 34 | ||||
| -rw-r--r-- | indra/newview/llimconversation.h | 10 | ||||
| -rw-r--r-- | indra/newview/llimfloater.cpp | 93 | ||||
| -rw-r--r-- | indra/newview/llimfloater.h | 9 | ||||
| -rw-r--r-- | indra/newview/llnearbychat.cpp | 36 | ||||
| -rw-r--r-- | indra/newview/llnearbychat.h | 6 | ||||
| -rw-r--r-- | indra/newview/llparticipantlist.cpp | 1 | 
9 files changed, 151 insertions, 82 deletions
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index c9031dd26a..21367c224d 100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -529,23 +529,6 @@ namespace action_give_inventory  		return acceptable;  	} -	static void build_residents_string(const std::vector<LLAvatarName> avatar_names, std::string& residents_string) -	{ -		llassert(avatar_names.size() > 0); - -		const std::string& separator = LLTrans::getString("words_separator"); -		for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; ) -		{ -			LLAvatarName av_name = *it; -			residents_string.append(av_name.mDisplayName); -			if	(++it == avatar_names.end()) -			{ -				break; -			} -			residents_string.append(separator); -		} -	} -  	static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string)  	{  		llassert(inventory_selected_uuids.size() > 0); @@ -675,7 +658,7 @@ namespace action_give_inventory  		}  		std::string residents; -		build_residents_string(avatar_names, residents); +		LLAvatarActions::buildResidentsString(avatar_names, residents);  		std::string items;  		build_items_string(inventory_selected_uuids, items); @@ -706,7 +689,23 @@ namespace action_give_inventory  	}  } +// static +void LLAvatarActions::buildResidentsString(const std::vector<LLAvatarName> avatar_names, std::string& residents_string) +{ +	llassert(avatar_names.size() > 0); +	const std::string& separator = LLTrans::getString("words_separator"); +	for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; ) +	{ +		LLAvatarName av_name = *it; +		residents_string.append(av_name.mDisplayName); +		if	(++it == avatar_names.end()) +		{ +			break; +		} +		residents_string.append(separator); +	} +}  //static  std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs() diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 0a69ad86a3..46830eb22c 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -34,6 +34,7 @@  #include <string>  #include <vector> +class LLAvatarName;  class LLInventoryPanel;  class LLFloater; @@ -208,6 +209,14 @@ public:  	 */  	static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL); +	/** +	 * Builds a string of residents' display names separated by "words_separator" string. +	 * +	 * @param avatar_names - a vector of given avatar names from which resulting string is built +	 * @param residents_string - the resulting string +	 */ +	static void buildResidentsString(const std::vector<LLAvatarName> avatar_names, std::string& residents_string); +  	static std::set<LLUUID> getInventorySelectedUUIDs();  private: diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp index d3f3e41a29..c734c3edd2 100644 --- a/indra/newview/llimconversation.cpp +++ b/indra/newview/llimconversation.cpp @@ -42,7 +42,6 @@ const F32 REFRESH_INTERVAL = 0.2f;  LLIMConversation::LLIMConversation(const LLUUID& session_id)    : LLTransientDockableFloater(NULL, true, session_id) -  ,	LLEventTimer(REFRESH_INTERVAL)    ,  mIsP2PChat(false)    ,  mExpandCollapseBtn(NULL)    ,  mTearOffBtn(NULL) @@ -52,6 +51,7 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)    , mChatHistory(NULL)    , mInputEditor(NULL)    , mInputEditorTopPad(0) +  , mRefreshTimer(new LLTimer())  {  	mCommitCallbackRegistrar.add("IMSession.Menu.Action",  			boost::bind(&LLIMConversation::onIMSessionMenuItemClicked,  this, _2)); @@ -67,6 +67,10 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)  			boost::bind(&LLIMConversation::onIMShowModesMenuItemCheck,   this, _2));  	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",  			boost::bind(&LLIMConversation::onIMShowModesMenuItemEnable,  this, _2)); + +	// Zero expiry time is set only once to allow initial update. +	mRefreshTimer->setTimerExpirySec(0); +	mRefreshTimer->start();  }  LLIMConversation::~LLIMConversation() @@ -76,6 +80,8 @@ LLIMConversation::~LLIMConversation()  		delete mParticipantList;  		mParticipantList = NULL;  	} + +	delete mRefreshTimer;  }  BOOL LLIMConversation::postBuild() @@ -120,19 +126,22 @@ BOOL LLIMConversation::postBuild()  } -BOOL LLIMConversation::tick() +void LLIMConversation::draw()  { -	// This check is needed until LLFloaterReg::removeInstance() is synchronized with deleting the floater -	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy(). -	if (isDead()) return false; +	LLTransientDockableFloater::draw(); -	// Need to resort the participant list if it's in sort by recent speaker order. -	if (mParticipantList) +	if (mRefreshTimer->hasExpired())  	{ -		mParticipantList->update(); -	} +		if (mParticipantList) +		{ +			mParticipantList->update(); +		} -	return false; +		refresh(); + +		// Restart the refresh timer +		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL); +	}  }  void LLIMConversation::buildParticipantList() @@ -144,10 +153,11 @@ void LLIMConversation::buildParticipantList()  	}  	else  	{ +		LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(mSessionID);  		// for group and ad-hoc chat we need to include agent into list -		if(!mIsP2PChat && !mParticipantList && mSessionID.notNull()) +		if(!mIsP2PChat && mSessionID.notNull() && speaker_manager)  		{ -			LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(mSessionID); +			delete mParticipantList; // remove the old list and create a new one if the session id has changed  			mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false);  		}  	} diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h index 47c98d6f8b..50663137ac 100644 --- a/indra/newview/llimconversation.h +++ b/indra/newview/llimconversation.h @@ -40,7 +40,6 @@ class LLChatHistory;  class LLIMConversation  	: public LLTransientDockableFloater -	, public LLEventTimer  {  public: @@ -65,6 +64,7 @@ public:  	/*virtual*/ void onOpen(const LLSD& key);  	/*virtual*/ void onClose(bool app_quitting);  	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void draw();  protected: @@ -89,8 +89,6 @@ protected:  	void buildParticipantList();  	void onSortMenuItemClicked(const LLSD& userdata); -	/*virtual*/ BOOL tick(); -  	bool mIsNearbyChat;  	bool mIsP2PChat; @@ -103,6 +101,9 @@ protected:  	LLButton* mCloseBtn;  private: +	/// Refreshes the floater at a constant rate. +	virtual void refresh() = 0; +  	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.  	void updateHeaderAndToolbar(); @@ -113,10 +114,11 @@ private:  	 */  	void reshapeChatHistory(); -  	LLChatHistory* mChatHistory;  	LLChatEntry* mInputEditor;  	int mInputEditorTopPad; // padding between input field and chat history + +	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.  }; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 9ea4bec069..6a5bf153d4 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -105,6 +105,18 @@ void LLIMFloater::onFocusReceived()  	}  } +// virtual +void LLIMFloater::refresh() +{ +	if (mMeTyping) +	{ +		// Time out if user hasn't typed for a while. +		if (mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS) +		{ +			setTyping(false); +		} +	} +}  /* static */  void LLIMFloater::newIMCallback(const LLSD& data) @@ -188,6 +200,7 @@ void LLIMFloater::sendMsg()  LLIMFloater::~LLIMFloater()  { +	mParticipantsListRefreshConnection.disconnect();  	mVoiceChannelStateChangeConnection.disconnect();  	if(LLVoiceClient::instanceExists())  	{ @@ -225,6 +238,8 @@ void LLIMFloater::initIMFloater()  	boundVoiceChannel(); +	mTypingStart = LLTrans::getString("IM_typing_start_string"); +  	// Show control panel in torn off floaters only.  	mParticipantListPanel->setVisible(!getHost() && gSavedSettings.getBOOL("IMShowControlPanel")); @@ -246,6 +261,20 @@ void LLIMFloater::initIMFloater()  	{  		std::string session_name(LLIMModel::instance().getName(mSessionID));  		updateSessionName(session_name, session_name); + +		// For ad hoc conferences we should update the title with participants names. +		if ((IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID)) +						|| mDialog == IM_SESSION_CONFERENCE_START) +		{ +			if (mParticipantsListRefreshConnection.connected()) +			{ +				mParticipantsListRefreshConnection.disconnect(); +			} + +			LLAvatarList* avatar_list = getChild<LLAvatarList>("speakers_list"); +			mParticipantsListRefreshConnection = avatar_list->setRefreshCompleteCallback( +					boost::bind(&LLIMFloater::onParticipantsListChanged, this, _1)); +		}  	}  } @@ -273,8 +302,6 @@ BOOL LLIMFloater::postBuild()  	setDocked(true); -	mTypingStart = LLTrans::getString("IM_typing_start_string"); -  	LLButton* add_btn = getChild<LLButton>("add_btn");  	// Allow to add chat participants depending on the session type @@ -341,7 +368,9 @@ bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)         for (uuid_vec_t::const_iterator id = uuids.begin();                         id != uuids.end(); ++id)         { -               if (*id == mOtherParticipantUUID) +    	   	   // Skip this check for ad hoc conferences, +    	       // conference participants should be listed in mSession->mInitialTargetIDs. +               if (mIsP2PChat && *id == mOtherParticipantUUID)                 {                         return false;                 } @@ -411,11 +440,6 @@ void LLIMFloater::onCallButtonClicked()  	}  } -/*void LLIMFloater::onOpenVoiceControlsClicked() -{ -	LLFloaterReg::showInstance("voice_controls"); -}*/ -  void LLIMFloater::onChange(EStatusType status, const std::string &channelURI, bool proximal)  {  	if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL) @@ -448,28 +472,55 @@ void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,  	mTypingStart.setArg("[NAME]", ui_title);  } -// virtual -BOOL LLIMFloater::tick() +void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)  { -	// This check is needed until LLFloaterReg::removeInstance() is synchronized with deleting the floater -	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy(). -	if (isDead()) +	LLAvatarList* avatar_list = dynamic_cast<LLAvatarList*>(ctrl); +	if (!avatar_list)  	{ -		return false; +		return;  	} -	BOOL parents_retcode = LLIMConversation::tick(); +	bool all_names_resolved = true; +	std::vector<LLSD> participants_uuids; -	if ( mMeTyping ) +	avatar_list->getValues(participants_uuids); + +	// Check whether we have all participants names in LLAvatarNameCache +	for (std::vector<LLSD>::const_iterator it = participants_uuids.begin(); it != participants_uuids.end(); ++it)  	{ -		// Time out if user hasn't typed for a while. -		if ( mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS ) +		const LLUUID& id = it->asUUID(); +		LLAvatarName av_name; +		if (!LLAvatarNameCache::get(id, &av_name))  		{ -			setTyping(false); +			all_names_resolved = false; + +			// If a name is not found in cache, request it and continue the process recursively +			// until all ids are resolved into names. +			LLAvatarNameCache::get(id, +					boost::bind(&LLIMFloater::onParticipantsListChanged, this, avatar_list)); +			break;  		}  	} -	return parents_retcode; +	if (all_names_resolved) +	{ +		std::vector<LLAvatarName> avatar_names; +		std::vector<LLSD>::const_iterator it = participants_uuids.begin(); +		for (; it != participants_uuids.end(); ++it) +		{ +			const LLUUID& id = it->asUUID(); +			LLAvatarName av_name; +			if (LLAvatarNameCache::get(id, &av_name)) +			{ +				avatar_names.push_back(av_name); +			} +		} + +		std::string ui_title; +		LLAvatarActions::buildResidentsString(avatar_names, ui_title); + +		updateSessionName(ui_title, ui_title); +	}  }  //static @@ -737,8 +788,6 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)  	{  		initIMSession(im_session_id); -		boundVoiceChannel(); -  		buildParticipantList();  	} diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index 6847efedf1..23f9e75e21 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -66,7 +66,6 @@ public:  	/*virtual*/ void setVisible(BOOL visible);  	/*virtual*/ BOOL getVisible();  	// Check typing timeout timer. -	/*virtual*/ BOOL tick();  	static LLIMFloater* findInstance(const LLUUID& session_id);  	static LLIMFloater* getInstance(const LLUUID& session_id); @@ -131,12 +130,18 @@ private:  	/* virtual */ void onFocusLost();  	/* virtual */ void onFocusReceived(); +	/*virtual*/ void refresh(); +  	// Update the window title, input field help text, etc.  	void updateSessionName(const std::string& ui_title, const std::string& ui_label);  	// For display name lookups for IM window titles  	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); +	/// Updates the list of ad hoc conference participants +	/// in an IM floater title. +	void onParticipantsListChanged(LLUICtrl* ctrl); +  	bool dropPerson(LLUUID* person_id, bool drop);  	BOOL isInviteAllowed() const; @@ -193,6 +198,8 @@ private:  	// connection to voice channel state change signal  	boost::signals2::connection mVoiceChannelStateChangeConnection; + +	boost::signals2::connection mParticipantsListRefreshConnection;  };  #endif  // LL_IMFLOATER_H diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 29ab4384cb..369ca699c5 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -186,6 +186,21 @@ BOOL LLNearbyChat::postBuild()  	return LLIMConversation::postBuild();  } +// virtual +void LLNearbyChat::refresh() +{ +	displaySpeakingIndicator(); +	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState()); + +	// *HACK: Update transparency type depending on whether our children have focus. +	// This is needed because this floater is chrome and thus cannot accept focus, so +	// the transparency type setting code from LLFloater::setFocus() isn't reached. +	if (getTransparencyType() != TT_DEFAULT) +	{ +		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE); +	} +} +  void LLNearbyChat::onNearbySpeakers()  {  	LLSD param; @@ -389,27 +404,6 @@ void LLNearbyChat::showHistory()  	storeRectControl();  } - -BOOL LLNearbyChat::tick() -{ -	// This check is needed until LLFloaterReg::removeInstance() is synchronized with deleting the floater -	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy(). -	if (isDead()) return false; - -	displaySpeakingIndicator(); -	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState()); - -	// *HACK: Update transparency type depending on whether our children have focus. -	// This is needed because this floater is chrome and thus cannot accept focus, so -	// the transparency type setting code from LLFloater::setFocus() isn't reached. -	if (getTransparencyType() != TT_DEFAULT) -	{ -		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE); -	} - -	return LLIMConversation::tick(); -} -  std::string LLNearbyChat::getCurrentChat()  {  	return mChatBox ? mChatBox->getText() : LLStringUtil::null; diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index c9aa69a912..db367f0b59 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -73,8 +73,6 @@ public:  	LLChatEntry* getChatBox() { return mChatBox; } -	//virtual void draw(); -  	std::string getCurrentChat();  	virtual BOOL handleKeyHere( KEY key, MASK mask ); @@ -119,8 +117,6 @@ protected:  	S32 mExpandedHeight; -	/*virtual*/ BOOL tick(); -  private:  	void	getAllowedRect		(LLRect& rect); @@ -128,6 +124,8 @@ private:  	void appendMessage(const LLChat& chat, const LLSD &args = 0);  	void	onNearbySpeakers	(); +	/*virtual*/ void refresh(); +  	LLHandle<LLView>	mPopupMenuHandle;  	std::vector<LLChat> mMessageArchive;  	LLChatHistory*		mChatHistory; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 59d26edff2..47518a365f 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -475,6 +475,7 @@ void LLParticipantList::update()  {  	mSpeakerMgr->update(true); +	// Need to resort the participant list if it's in sort by recent speaker order.  	if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder() && !isHovered())  	{  		// Resort avatar list  | 
