diff options
Diffstat (limited to 'indra/newview')
42 files changed, 479 insertions, 314 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e607c3ad15..093e4f4894 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10303,6 +10303,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>VoiceDefaultInternalLevel</key> +    <map> +      <key>Comment</key> +      <string>Internal level of voice set by default. Is equivalent to 0.5 (from 0.0-1.0 range) external voice level (internal = 400 * external^2).</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>100</integer> +    </map>      <key>VoiceEarLocation</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 40c9bb6afa..bb14c41cec 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -263,18 +263,9 @@ bool LLAvatarActions::isCalling(const LLUUID &id)  }  //static -bool LLAvatarActions::canCall(const LLUUID &id) +bool LLAvatarActions::canCall()  { -	// For now we do not need to check whether passed UUID is ID of agent's friend. -	// Use common check of Voice Client state. -	{ -		// don't need to check online/offline status because "usual resident" (resident that is not a friend) -		// can be only ONLINE. There is no way to see "usual resident" in OFFLINE status. If we see "usual -		// resident" it automatically means that the resident is ONLINE. So to make a call to the "usual resident" -		// we need to check only that "our" voice is enabled. -		return LLVoiceClient::voiceEnabled(); -	} - +		return LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();  }  // static diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index a4504ae679..ebfd40b796 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -129,10 +129,10 @@ public:  	static bool isCalling(const LLUUID &id);  	/** -	 * @return true if call to the resident can be made (resident is online and voice is enabled) +	 * @return true if call to the resident can be made  	 */ -	static bool canCall(const LLUUID &id); +	static bool canCall();  	/**  	 * Invite avatar to a group.  	 */	 diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 66ab32f3e8..2bcd097717 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -440,17 +440,17 @@ LLAvatarListItem::icon_color_map_t& LLAvatarListItem::getItemIconColorMap()  // static  void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)  { +	//speaking indicator width + padding +	S32 speaking_indicator_width = avatar_item->getRect().getWidth() - avatar_item->mSpeakingIndicator->getRect().mLeft; +  	//profile btn width + padding -	S32 profile_btn_width = avatar_item->getRect().getWidth() - avatar_item->mProfileBtn->getRect().mLeft; +	S32 profile_btn_width = avatar_item->mSpeakingIndicator->getRect().mLeft - avatar_item->mProfileBtn->getRect().mLeft;  	//info btn width + padding  	S32 info_btn_width = avatar_item->mProfileBtn->getRect().mLeft - avatar_item->mInfoBtn->getRect().mLeft; -	//speaking indicator width + padding -	S32 speaking_indicator_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mSpeakingIndicator->getRect().mLeft; -  	// last interaction time textbox width + padding -	S32 last_interaction_time_width = avatar_item->mSpeakingIndicator->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft; +	S32 last_interaction_time_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;  	// icon width + padding  	S32 icon_width = avatar_item->mAvatarName->getRect().mLeft - avatar_item->mAvatarIcon->getRect().mLeft; @@ -462,9 +462,9 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)  	sChildrenWidths[--index] = icon_width;  	sChildrenWidths[--index] = 0; // for avatar name we don't need its width, it will be calculated as "left available space"  	sChildrenWidths[--index] = last_interaction_time_width; -	sChildrenWidths[--index] = speaking_indicator_width;  	sChildrenWidths[--index] = info_btn_width;  	sChildrenWidths[--index] = profile_btn_width; +	sChildrenWidths[--index] = speaking_indicator_width;  }  void LLAvatarListItem::updateChildren() diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 479a4833cb..61c0a8660e 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -129,9 +129,9 @@ private:  	 * @see updateChildren()  	 */  	typedef enum e_avatar_item_child { +		ALIC_SPEAKER_INDICATOR,  		ALIC_PROFILE_BUTTON,  		ALIC_INFO_BUTTON, -		ALIC_SPEAKER_INDICATOR,  		ALIC_INTERACTION_TIME,  		ALIC_NAME,  		ALIC_ICON, diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index d4c8adadc6..d9df537e03 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -43,6 +43,7 @@  #include "llavatariconctrl.h"  #include "llavatarlist.h"  #include "llbottomtray.h" +#include "lldraghandle.h"  #include "llimfloater.h"  #include "llfloaterreg.h"  #include "llparticipantlist.h" @@ -158,6 +159,11 @@ BOOL LLCallFloater::postBuild()  	connectToChannel(LLVoiceChannel::getCurrentVoiceChannel()); +	setIsChrome(true); +	//chrome="true" hides floater caption  +	if (mDragHandle) +		mDragHandle->setTitleVisible(TRUE); +  	return TRUE;  } diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index a46cd84b60..d6a7edee5b 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -550,8 +550,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_  		if (mLastFromName == chat.mFromName   			&& mLastFromID == chat.mFromID  			&& mLastMessageTime.notNull()  -			&& (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0  -			) +			&& (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0 +			&& mLastMessageTimeStr.size() == chat.mTimeStr.size())  //*HACK to distinguish between current and previous chat session's histories  		{  			view = getSeparator();  			p.top_pad = mTopSeparatorPad; @@ -585,6 +585,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_  		mLastFromName = chat.mFromName;  		mLastFromID = chat.mFromID;  		mLastMessageTime = new_message_time; +		mLastMessageTimeStr = chat.mTimeStr;  	}  	std::string message = irc_me ? chat.mText.substr(3) : chat.mText; diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index f2d403f639..c2c60e60cf 100644 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -125,6 +125,8 @@ class LLChatHistory : public LLUICtrl  		std::string mLastFromName;  		LLUUID mLastFromID;  		LLDate mLastMessageTime; +		std::string mLastMessageTimeStr; +  		std::string mMessageHeaderFilename;  		std::string mMessageSeparatorFilename; diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 29f415bd43..c71764c2e5 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -75,7 +75,7 @@ LLFloaterGroupPicker::~LLFloaterGroupPicker()  void LLFloaterGroupPicker::setPowersMask(U64 powers_mask)  {  	mPowersMask = powers_mask; -	postBuild(); +	init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID(), mPowersMask);  } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index eeda3f133c..e77c93b5f8 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1430,6 +1430,7 @@ BOOL LLPanelPreference::postBuild()  	if (hasChild("media_enabled"))  	{  		bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia"); +		getChild<LLCheckBoxCtrl>("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2));  		getChild<LLCheckBoxCtrl>("media_enabled")->set(media_enabled);  		getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(media_enabled);  	} @@ -1486,6 +1487,14 @@ void LLPanelPreference::saveSettings()  	}	  } +void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& value) +{ +	if (checkbox && checkbox->getValue()) +	{ +		LLNotificationsUtil::add("FriendsAndGroupsOnly"); +	} +} +  void LLPanelPreference::cancel()  {  	for (control_values_map_t::iterator iter =  mSavedValues.begin(); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 4ec2d277a8..8778d76a5a 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -167,6 +167,9 @@ public:  	virtual void saveSettings();  private: +	//for "Only friends and groups can call or IM me" +	static void showFriendsOnlyWarning(LLUICtrl*, const LLSD&); +  	typedef std::map<LLControlVariable*, LLSD> control_values_map_t;  	control_values_map_t mSavedValues; diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 2efae0c8db..4a1eb51dbe 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -324,7 +324,7 @@ void LLFloaterReporter::setFromAvatar(const LLUUID& avatar_id, const std::string  	std::string avatar_link = LLSLURL::buildCommand("agent", mObjectID, "inspect");  	childSetText("owner_name", avatar_link); -	childSetText("object_name", avatar_name); // name +	childSetText("object_name", avatar_name);  	childSetText("abuser_name_edit", avatar_name);  } diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index e75d35bea4..e01709aa3a 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -48,6 +48,7 @@  #include "lltextutil.h"  #include "llviewercontrol.h"	// for gSavedSettings  #include "llviewermenu.h"		// for gMenuHolder +#include "llvoiceclient.h"  static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");  S32 LLGroupListItem::sIconWidth = 0; @@ -271,6 +272,9 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)  	if (userdata.asString() == "activate")  		return gAgent.getGroupID() != selected_group_id; +	if (userdata.asString() == "call") +		return LLVoiceClient::voiceEnabled()&&gVoiceClient->voiceWorking(); +  	return real_group_selected;  } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index c2a7969c0d..32b0cbff38 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1680,6 +1680,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)  	case LLVoiceChannel::STATE_ERROR :  		getChild<LLTextBox>("noanswer")->setVisible(true);  		getChild<LLButton>("Cancel")->setVisible(false); +		setCanClose(true);  		mLifetimeTimer.start();  		break;  	case LLVoiceChannel::STATE_HUNG_UP : @@ -1692,6 +1693,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)  			getChild<LLTextBox>("nearby")->setVisible(true);  		}  		getChild<LLButton>("Cancel")->setVisible(false); +		setCanClose(true);  		mLifetimeTimer.start();  	} diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 7ee4c64f8f..c1666f5666 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -52,23 +52,15 @@  #include <boost/tokenizer.hpp> -#include "llcrc.h" -#include "lldir.h"  #include "lldispatcher.h" -#include "llsdserialize.h"  #include "llxfermanager.h" -#include "message.h"  #include "llagent.h"  #include "llviewergenericmessage.h"	// for gGenericDispatcher -#include "llviewerwindow.h"  #include "llworld.h" //for particle system banning -#include "llchat.h"  #include "llimpanel.h"  #include "llimview.h"  #include "llnotifications.h" -#include "lluistring.h" -#include "llviewerobject.h"   #include "llviewerobjectlist.h"  #include "lltrans.h" @@ -219,61 +211,17 @@ LLMuteList* LLMuteList::getInstance()  // LLMuteList()  //-----------------------------------------------------------------------------  LLMuteList::LLMuteList() : -	mIsLoaded(FALSE), -	mUserVolumesLoaded(FALSE) +	mIsLoaded(FALSE)  {  	gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList);  } -void LLMuteList::loadUserVolumes() -{ -	// call once, after LLDir::setLindenUserDir() has been called -	if (mUserVolumesLoaded) -		return; -	mUserVolumesLoaded = TRUE; -	 -	// load per-resident voice volume information -	// conceptually, this is part of the mute list information, although it is only stored locally -	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml"); - -	LLSD settings_llsd; -	llifstream file; -	file.open(filename); -	if (file.is_open()) -	{ -		LLSDSerialize::fromXML(settings_llsd, file); -	} - -	for (LLSD::map_const_iterator iter = settings_llsd.beginMap(); -		 iter != settings_llsd.endMap(); ++iter) -	{ -		mUserVolumeSettings.insert(std::make_pair(LLUUID(iter->first), (F32)iter->second.asReal())); -	} -} -  //-----------------------------------------------------------------------------  // ~LLMuteList()  //-----------------------------------------------------------------------------  LLMuteList::~LLMuteList()  { -	// If we quit from the login screen we will not have an SL account -	// name.  Don't try to save, otherwise we'll dump a file in -	// C:\Program Files\SecondLife\ or similar. JC -	std::string user_dir = gDirUtilp->getLindenUserDir(); -	if (!user_dir.empty()) -	{ -		std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml"); -		LLSD settings_llsd; - -		for(user_volume_map_t::iterator iter = mUserVolumeSettings.begin(); iter != mUserVolumeSettings.end(); ++iter) -		{ -			settings_llsd[iter->first.asString()] = iter->second; -		} -		llofstream file; -		file.open(filename); -		LLSDSerialize::toPrettyXML(settings_llsd, file); -	}  }  BOOL LLMuteList::isLinden(const std::string& name) const @@ -715,8 +663,6 @@ BOOL LLMuteList::isMuted(const LLUUID& id, const std::string& name, U32 flags) c  //-----------------------------------------------------------------------------  void LLMuteList::requestFromServer(const LLUUID& agent_id)  { -	loadUserVolumes(); -	  	std::string agent_id_string;  	std::string filename;  	agent_id.toString(agent_id_string); @@ -751,26 +697,6 @@ void LLMuteList::cache(const LLUUID& agent_id)  	}  } -void LLMuteList::setSavedResidentVolume(const LLUUID& id, F32 volume) -{ -	// store new value in volume settings file -	mUserVolumeSettings[id] = volume; -} - -F32 LLMuteList::getSavedResidentVolume(const LLUUID& id) -{ -	const F32 DEFAULT_VOLUME = 0.5f; - -	user_volume_map_t::iterator found_it = mUserVolumeSettings.find(id); -	if (found_it != mUserVolumeSettings.end()) -	{ -		return found_it->second; -	} -	//FIXME: assumes default, should get this from somewhere -	return DEFAULT_VOLUME; -} - -  //-----------------------------------------------------------------------------  // Static message handlers  //----------------------------------------------------------------------------- diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 409b637bf2..e1e81a24b4 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -127,12 +127,7 @@ public:  	// call this method on logout to save everything.  	void cache(const LLUUID& agent_id); -	void setSavedResidentVolume(const LLUUID& id, F32 volume); -	F32 getSavedResidentVolume(const LLUUID& id); -  private: -	void loadUserVolumes(); -	  	BOOL loadFromFile(const std::string& filename);  	BOOL saveToFile(const std::string& filename); @@ -179,12 +174,8 @@ private:  	observer_set_t mObservers;  	BOOL mIsLoaded; -	BOOL mUserVolumesLoaded;  	friend class LLDispatchEmptyMuteList; - -	typedef std::map<LLUUID, F32> user_volume_map_t;  -	user_volume_map_t mUserVolumeSettings;  };  class LLMuteListObserver diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index a7c1e73328..0a8d020b4f 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -101,6 +101,11 @@ BOOL LLNearbyChat::postBuild()  			getDockTongue(), LLDockControl::TOP, boost::bind(&LLNearbyChat::getAllowedRect, this, _1)));  	} +	setIsChrome(true); +	//chrome="true" hides floater caption  +	if (mDragHandle) +		mDragHandle->setTitleVisible(TRUE); +  	return true;  } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 85e95ca1d6..fe5b20813a 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -165,6 +165,8 @@ BOOL LLPanelAvatarNotes::postBuild()  	resetControls();  	resetData(); +	gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this); +  	return TRUE;  } @@ -337,6 +339,8 @@ LLPanelAvatarNotes::~LLPanelAvatarNotes()  	if(getAvatarId().notNull())  	{  		LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); +		if(LLVoiceClient::getInstance()) +			LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);  	}  } @@ -346,6 +350,17 @@ void LLPanelAvatarNotes::changed(U32 mask)  	childSetEnabled("teleport", LLAvatarTracker::instance().isBuddyOnline(getAvatarId()));  } +// virtual +void LLPanelAvatarNotes::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ +	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) +	{ +		return; +	} + +	childSetEnabled("call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking()); +} +  void LLPanelAvatarNotes::setAvatarId(const LLUUID& id)  {  	if(id.notNull()) @@ -437,7 +452,6 @@ void LLPanelProfileTab::updateButtons()  	bool enable_map_btn = is_avatar_online && gAgent.isGodlike() || is_agent_mappable(getAvatarId());  	childSetEnabled("show_on_map_btn", enable_map_btn); -	childSetEnabled("call", LLAvatarActions::canCall(getAvatarId()));  }  ////////////////////////////////////////////////////////////////////////// @@ -485,6 +499,8 @@ BOOL LLPanelAvatarProfile::postBuild()  	pic = getChild<LLTextureCtrl>("real_world_pic");  	pic->setFallbackImageName("default_profile_picture.j2c"); +	gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this); +  	resetControls();  	resetData(); @@ -568,8 +584,6 @@ void LLPanelAvatarProfile::processProfileProperties(const LLAvatarData* avatar_d  	fillPartnerData(avatar_data); -	fillOnlineStatus(avatar_data); -  	fillAccountStatus(avatar_data);  } @@ -637,21 +651,6 @@ void LLPanelAvatarProfile::fillPartnerData(const LLAvatarData* avatar_data)  	}  } -void LLPanelAvatarProfile::fillOnlineStatus(const LLAvatarData* avatar_data) -{ -	bool online = avatar_data->flags & AVATAR_ONLINE; -	if(LLAvatarActions::isFriend(avatar_data->avatar_id)) -	{ -		// Online status NO could be because they are hidden -		// If they are a friend, we may know the truth! -		online = LLAvatarTracker::instance().isBuddyOnline(avatar_data->avatar_id); -	} -	childSetValue("online_status", online ? -		"Online" : "Offline"); -	childSetColor("online_status", online ?  -		LLColor4::green : LLColor4::red); -} -  void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data)  {  	LLStringUtil::format_map_t args; @@ -757,6 +756,8 @@ LLPanelAvatarProfile::~LLPanelAvatarProfile()  	if(getAvatarId().notNull())  	{  		LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); +		if(LLVoiceClient::getInstance()) +			LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);  	}  } @@ -766,6 +767,17 @@ void LLPanelAvatarProfile::changed(U32 mask)  	childSetEnabled("teleport", LLAvatarTracker::instance().isBuddyOnline(getAvatarId()));  } +// virtual +void LLPanelAvatarProfile::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ +	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) +	{ +		return; +	} + +	childSetEnabled("call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking()); +} +  void LLPanelAvatarProfile::setAvatarId(const LLUUID& id)  {  	if(id.notNull()) diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 22efa5dc35..ce59f1e93d 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -36,6 +36,7 @@  #include "llpanel.h"  #include "llavatarpropertiesprocessor.h"  #include "llcallingcard.h" +#include "llvoiceclient.h"  class LLComboBox;  class LLLineEditor; @@ -122,6 +123,7 @@ private:  class LLPanelAvatarProfile  	: public LLPanelProfileTab  	, public LLFriendObserver +	, public LLVoiceClientStatusObserver  {  public:  	LLPanelAvatarProfile(); @@ -134,6 +136,10 @@ public:  	 */  	virtual void changed(U32 mask); +	// Implements LLVoiceClientStatusObserver::onChange() to enable the call +	// button when voice is available +	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); +  	/*virtual*/ void setAvatarId(const LLUUID& id);  	/** @@ -172,11 +178,6 @@ protected:  	virtual void fillPartnerData(const LLAvatarData* avatar_data);  	/** -	 * Fills Avatar's online status. -	 */ -	virtual void fillOnlineStatus(const LLAvatarData* avatar_data); - -	/**  	 * Fills account status.  	 */  	virtual void fillAccountStatus(const LLAvatarData* avatar_data); @@ -257,6 +258,7 @@ private:  class LLPanelAvatarNotes   	: public LLPanelProfileTab  	, public LLFriendObserver +	, public LLVoiceClientStatusObserver  {  public:  	LLPanelAvatarNotes(); @@ -269,6 +271,10 @@ public:  	 */  	virtual void changed(U32 mask); +	// Implements LLVoiceClientStatusObserver::onChange() to enable the call +	// button when voice is available +	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); +  	/*virtual*/ void onOpen(const LLSD& key);  	/*virtual*/ BOOL postBuild(); diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index c30ef3221d..1d447a22d7 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -101,6 +101,8 @@ LLPanelGroup::LLPanelGroup()  LLPanelGroup::~LLPanelGroup()  {  	LLGroupMgr::getInstance()->removeObserver(this); +	if(LLVoiceClient::getInstance()) +		LLVoiceClient::getInstance()->removeObserver(this);  }  void LLPanelGroup::onOpen(const LLSD& key) @@ -188,6 +190,8 @@ BOOL LLPanelGroup::postBuild()  	if(panel_general)  		panel_general->setupCtrls(this); + +	gVoiceClient->addObserver(this);  	return TRUE;  } @@ -300,6 +304,17 @@ void LLPanelGroup::changed(LLGroupChange gc)  	update(gc);  } +// virtual +void LLPanelGroup::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ +	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) +	{ +		return; +	} + +	childSetEnabled("btn_call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking()); +} +  void LLPanelGroup::notifyObservers()  {  	changed(GC_ALL); @@ -356,6 +371,13 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)  	for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)  		(*it)->setGroupID(group_id); +	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); +	if(gdatap) +	{ +		childSetValue("group_name", gdatap->mName); +		childSetToolTip("group_name",gdatap->mName); +	} +  	LLButton* button_apply = findChild<LLButton>("btn_apply");  	LLButton* button_refresh = findChild<LLButton>("btn_refresh");  	LLButton* button_create = findChild<LLButton>("btn_create"); @@ -457,17 +479,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)  	}  	reposButtons(); - -	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); - -	if(gdatap) -	{ -		childSetValue("group_name", gdatap->mName); -		childSetToolTip("group_name",gdatap->mName); -		 -		//group data is already present, call update manually -		update(GC_ALL); -	}  }  bool LLPanelGroup::apply(LLPanelGroupTab* tab) diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 7ea5e67b44..8c84695677 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -35,6 +35,7 @@  #include "llgroupmgr.h"  #include "llpanel.h"  #include "lltimer.h" +#include "llvoiceclient.h"  struct LLOfferInfo; @@ -47,7 +48,8 @@ class LLAgent;  class LLPanelGroup : public LLPanel, -					 public LLGroupMgrObserver  +					 public LLGroupMgrObserver, +					 public LLVoiceClientStatusObserver  {  public:  	LLPanelGroup(); @@ -64,6 +66,10 @@ public:  	// Group manager observer trigger.  	virtual void changed(LLGroupChange gc); +	// Implements LLVoiceClientStatusObserver::onChange() to enable the call +	// button when voice is available +	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); +  	void showNotice(const std::string& subject,  					const std::string& message,  					const bool& has_inventory, diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index a334eb9d68..ff1e43b526 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -64,21 +64,52 @@ void LLPanelChatControlPanel::onOpenVoiceControlsClicked()  	LLFloaterReg::showInstance("voice_controls");  } +void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ +	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) +	{ +		return; +	} + +	updateCallButton(); +} +  void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)  {  	updateButtons(new_state >= LLVoiceChannel::STATE_CALL_STARTED);  } +void LLPanelChatControlPanel::updateCallButton() +{ +	// hide/show call button +	bool voice_enabled = LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking(); + +	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId); +	if (!session) return; + +	bool session_initialized = session->mSessionInitialized; +	bool callback_enabled = session->mCallBackEnabled; + +	BOOL enable_connect = session_initialized +		&& voice_enabled +		&& callback_enabled; +	childSetEnabled("call_btn", enable_connect); +} +  void LLPanelChatControlPanel::updateButtons(bool is_call_started)  {  	childSetVisible("end_call_btn_panel", is_call_started);  	childSetVisible("voice_ctrls_btn_panel", is_call_started);  	childSetVisible("call_btn_panel", ! is_call_started); +	updateCallButton(); +	  }  LLPanelChatControlPanel::~LLPanelChatControlPanel()  {  	mVoiceChannelStateChangeConnection.disconnect(); +	if(LLVoiceClient::getInstance()) +		LLVoiceClient::getInstance()->removeObserver(this);  }  BOOL LLPanelChatControlPanel::postBuild() @@ -87,26 +118,9 @@ BOOL LLPanelChatControlPanel::postBuild()  	childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this));  	childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this)); -	return TRUE; -} - -void LLPanelChatControlPanel::draw() -{ -	// hide/show start call and end call buttons -	bool voice_enabled = LLVoiceClient::voiceEnabled(); - -	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId); -	if (!session) return; +	gVoiceClient->addObserver(this); -	bool session_initialized = session->mSessionInitialized; -	bool callback_enabled = session->mCallBackEnabled; - -	BOOL enable_connect = session_initialized -		&& voice_enabled -		&& callback_enabled; -	childSetEnabled("call_btn", enable_connect); - -	LLPanel::draw(); +	return TRUE;  }  void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id) @@ -266,6 +280,8 @@ void LLPanelGroupControlPanel::draw()  	// Need to resort the participant list if it's in sort by recent speaker order.  	if (mParticipantList)  		mParticipantList->updateRecentSpeakersOrder(); +	//* TODO: find better way to properly enable call button for group and remove this call from draw() +	updateCallButton();  	LLPanelChatControlPanel::draw();  } diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index 25fdf944c9..3ab505a084 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -39,7 +39,9 @@  class LLParticipantList; -class LLPanelChatControlPanel : public LLPanel +class LLPanelChatControlPanel  +	: public LLPanel +	, public LLVoiceClientStatusObserver  {  public:  	LLPanelChatControlPanel() : @@ -47,15 +49,21 @@ public:  	~LLPanelChatControlPanel();  	virtual BOOL postBuild(); -	virtual void draw();  	void onCallButtonClicked();  	void onEndCallButtonClicked();  	void onOpenVoiceControlsClicked(); +	// Implements LLVoiceClientStatusObserver::onChange() to enable the call +	// button when voice is available +	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); +  	virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);  	void updateButtons(bool is_call_started); +	 +	// Enables/disables call button depending on voice availability +	void updateCallButton();  	virtual void setSessionId(const LLUUID& session_id);  	const LLUUID& getSessionId() { return mSessionId; } diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp index ece93125b3..0f0fb4b94e 100644 --- a/indra/newview/llpanelme.cpp +++ b/indra/newview/llpanelme.cpp @@ -198,8 +198,6 @@ void LLPanelMyProfileEdit::processProfileProperties(const LLAvatarData* avatar_d  {  	fillCommonData(avatar_data); -	fillOnlineStatus(avatar_data); -  	fillPartnerData(avatar_data);  	fillAccountStatus(avatar_data); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index c14b282488..b01cdcc832 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -462,6 +462,9 @@ LLPanelPeople::~LLPanelPeople()  	delete mFriendListUpdater;  	delete mRecentListUpdater; +	if(LLVoiceClient::getInstance()) +		LLVoiceClient::getInstance()->removeObserver(this); +  	LLView::deleteViewByHandle(mGroupPlusMenuHandle);  	LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);  	LLView::deleteViewByHandle(mFriendsViewSortMenuHandle); @@ -612,6 +615,8 @@ BOOL LLPanelPeople::postBuild()  	if(recent_view_sort)  		mRecentViewSortMenuHandle  = recent_view_sort->getHandle(); +	gVoiceClient->addObserver(this); +  	// call this method in case some list is empty and buttons can be in inconsistent state  	updateButtons(); @@ -621,6 +626,17 @@ BOOL LLPanelPeople::postBuild()  	return TRUE;  } +// virtual +void LLPanelPeople::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ +	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) +	{ +		return; +	} +	 +	updateButtons(); +} +  void LLPanelPeople::updateFriendList()  {  	if (!mOnlineFriendList || !mAllFriendList) @@ -775,41 +791,20 @@ void LLPanelPeople::updateButtons()  		}  	} +	bool enable_calls = gVoiceClient->voiceWorking() && gVoiceClient->voiceEnabled(); +  	buttonSetEnabled("teleport_btn",		friends_tab_active && item_selected && isFriendOnline(selected_uuids.front()));  	buttonSetEnabled("view_profile_btn",	item_selected);  	buttonSetEnabled("im_btn",				multiple_selected); // allow starting the friends conference for multiple selection -	buttonSetEnabled("call_btn",			multiple_selected && canCall()); +	buttonSetEnabled("call_btn",			multiple_selected && enable_calls);  	buttonSetEnabled("share_btn",			item_selected); // not implemented yet  	bool none_group_selected = item_selected && selected_id.isNull();  	buttonSetEnabled("group_info_btn", !none_group_selected); -	buttonSetEnabled("group_call_btn", !none_group_selected); +	buttonSetEnabled("group_call_btn", !none_group_selected && enable_calls);  	buttonSetEnabled("chat_btn", !none_group_selected);  } -bool LLPanelPeople::canCall() -{ -	std::vector<LLUUID> selected_uuids; -	getCurrentItemIDs(selected_uuids); - -	bool result = false; - -	std::vector<LLUUID>::const_iterator -		id = selected_uuids.begin(), -		uuids_end = selected_uuids.end(); - -	for (;id != uuids_end; ++id) -	{ -		if (LLAvatarActions::canCall(*id)) -		{ -			result = true; -			break; -		} -	} - -	return result; -} -  std::string LLPanelPeople::getActiveTabName() const  {  	return mTabContainer->getCurrentPanel()->getName(); diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 7580fdbeef..6d3d436156 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -36,13 +36,16 @@  #include <llpanel.h>  #include "llcallingcard.h" // for avatar tracker +#include "llvoiceclient.h"  class LLFilterEditor;  class LLTabContainer;  class LLAvatarList;  class LLGroupList; -class LLPanelPeople : public LLPanel +class LLPanelPeople  +	: public LLPanel +	, public LLVoiceClientStatusObserver  {  	LOG_CLASS(LLPanelPeople);  public: @@ -52,6 +55,9 @@ public:  	/*virtual*/ BOOL 	postBuild();  	/*virtual*/ void	onOpen(const LLSD& key);  	/*virtual*/ bool	notifyChildren(const LLSD& info); +	// Implements LLVoiceClientStatusObserver::onChange() to enable call buttons +	// when voice is available +	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);  	// internals  	class Updater; @@ -73,7 +79,6 @@ private:  	bool					isFriendOnline(const LLUUID& id);  	bool					isItemsFreeOfFriends(const std::vector<LLUUID>& uuids); -	bool 					canCall();  	void					updateButtons();  	std::string				getActiveTabName() const; diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index c1c10e6022..d9651a6045 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -183,20 +183,7 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)  	}  	else if (item == std::string("can_call"))  	{ -		bool result = false; -		std::vector<LLUUID>::const_iterator -			id = mUUIDs.begin(), -			uuids_end = mUUIDs.end(); - -		for (;id != uuids_end; ++id) -		{ -			if (LLAvatarActions::canCall(*id)) -			{ -				result = true; -				break; -			} -		} -		return result; +		return LLAvatarActions::canCall();  	}  	return false;  } diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index a4f0e55a93..a8a9717750 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -384,6 +384,10 @@ void LLPanelPlaces::onOpen(const LLSD& key)  	// Otherwise stop using land selection and deselect land.  	if (mPlaceInfoType == AGENT_INFO_TYPE)  	{ +		// We don't know if we are already added to LLViewerParcelMgr observers list +		// so try to remove observer not to add an extra one. +		parcel_mgr->removeObserver(mParcelObserver); +  		parcel_mgr->addObserver(mParcelObserver);  		parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());  	} @@ -898,6 +902,8 @@ void LLPanelPlaces::changedParcelSelection()  	if (!region || !parcel)  		return; +	LLVector3d prev_pos_global = mPosGlobal; +  	// If agent is inside the selected parcel show agent's region<X, Y, Z>,  	// otherwise show region<X, Y, Z> of agent's selection point.  	bool is_current_parcel = is_agent_in_selected_parcel(parcel); @@ -914,7 +920,13 @@ void LLPanelPlaces::changedParcelSelection()  		}  	} -	mPlaceProfile->resetLocation(); +	// Reset location info only if global position is changed +	// to reduce unnecessary text and icons updates. +	if (prev_pos_global != mPosGlobal) +	{ +		mPlaceProfile->resetLocation(); +	} +  	mPlaceProfile->displaySelectedParcelInfo(parcel, region, mPosGlobal, is_current_parcel);  	updateVerbs(); diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp index 7832f63e6a..044036ea50 100644 --- a/indra/newview/llpanelprofileview.cpp +++ b/indra/newview/llpanelprofileview.cpp @@ -101,8 +101,6 @@ void LLPanelProfileView::onOpen(const LLSD& key)  		id = key["id"];  	} -	// subscribe observer to get online status. Request will be sent by LLPanelAvatarProfile itself -	mAvatarStatusObserver->subscribe();  	if(id.notNull() && getAvatarId() != id)  	{  		setAvatarId(id); @@ -111,12 +109,9 @@ void LLPanelProfileView::onOpen(const LLSD& key)  	// Update the avatar name.  	gCacheName->get(getAvatarId(), FALSE,  		boost::bind(&LLPanelProfileView::onAvatarNameCached, this, _1, _2, _3, _4)); -/* -// disable this part of code according to EXT-2022. See processOnlineStatus -	// status should only show if viewer has permission to view online/offline. EXT-453  -	mStatusText->setVisible(isGrantedToSeeOnlineStatus()); +  	updateOnlineStatus(); -*/ +  	LLPanelProfile::onOpen(key);  } @@ -164,27 +159,43 @@ bool LLPanelProfileView::isGrantedToSeeOnlineStatus()  	// *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status.  	// When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer  	// see comments for ChangeUserRights template message. EXT-453. -//	return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); -	return true; +	// If GRANT_ONLINE_STATUS flag is changed it will be applied when viewer restarts. EXT-3880 +	return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);  } +// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880  void LLPanelProfileView::updateOnlineStatus()  { +	// set text box visible to show online status for non-friends who has not set in Preferences +	// "Only Friends & Groups can see when I am online" +	mStatusText->setVisible(TRUE); +  	const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());  	if (NULL == relationship) -		return; +	{ +		// this is non-friend avatar. Status will be updated from LLAvatarPropertiesProcessor. +		// in LLPanelProfileView::processOnlineStatus() -	bool online = relationship->isOnline(); +		// subscribe observer to get online status. Request will be sent by LLPanelAvatarProfile itself. +		// do not subscribe for friend avatar because online status can be wrong overridden +		// via LLAvatarData::flags if Preferences: "Only Friends & Groups can see when I am online" is set. +		mAvatarStatusObserver->subscribe(); +		return; +	} +	// For friend let check if he allowed me to see his status -	std::string status = getString(online ? "status_online" : "status_offline"); +	// status should only show if viewer has permission to view online/offline. EXT-453, EXT-3880 +	mStatusText->setVisible(isGrantedToSeeOnlineStatus()); -	mStatusText->setValue(status); +	bool online = relationship->isOnline(); +	processOnlineStatus(online);  }  void LLPanelProfileView::processOnlineStatus(bool online)  { -	mAvatarIsOnline = online; -	mStatusText->setVisible(online); +	std::string status = getString(online ? "status_online" : "status_offline"); + +	mStatusText->setValue(status);  }  void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string& first_name, const std::string& last_name, BOOL is_group) @@ -193,17 +204,4 @@ void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string&  	getChild<LLUICtrl>("user_name", FALSE)->setValue(first_name + " " + last_name);  } -void LLPanelProfileView::togglePanel(LLPanel* panel, const LLSD& key) -{ -	// *TODO: unused method? - -	LLPanelProfile::togglePanel(panel); -	if(FALSE == panel->getVisible()) -	{ -		// LLPanelProfile::togglePanel shows/hides all children, -		// we don't want to display online status for non friends, so re-hide it here -		mStatusText->setVisible(mAvatarIsOnline); -	} -} -  // EOF diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h index 5dc617d4a0..9b87e146a8 100644 --- a/indra/newview/llpanelprofileview.h +++ b/indra/newview/llpanelprofileview.h @@ -64,8 +64,6 @@ public:  	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void togglePanel(LLPanel* panel, const LLSD& key = LLSD()); -  	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,  						   BOOL drop, EDragAndDropType cargo_type,  						   void *cargo_data, EAcceptance *accept, @@ -81,8 +79,21 @@ public:  protected:  	void onBackBtnClick(); -	bool isGrantedToSeeOnlineStatus(); // deprecated after EXT-2022 is implemented -	void updateOnlineStatus(); // deprecated after EXT-2022 is implemented +	bool isGrantedToSeeOnlineStatus(); + +	/** +	 * Displays avatar's online status if possible. +	 * +	 * Requirements from EXT-3880: +	 * For friends: +	 * - Online when online and privacy settings allow to show +	 * - Offline when offline and privacy settings allow to show +	 * - Else: nothing +	 * For other avatars: +	 *  - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online" +	 *  - Else: Offline +	 */ +	void updateOnlineStatus();  	void processOnlineStatus(bool online);  private: @@ -96,7 +107,6 @@ private:  	LLTextBox* mStatusText;  	AvatarStatusObserver* mAvatarStatusObserver; -	bool mAvatarIsOnline;  };  #endif //LL_LLPANELPROFILEVIEW_H diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 88b706fb6b..c0302eee9e 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -628,7 +628,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&  	}  	else if (item == "can_call")  	{ -		return LLVoiceClient::voiceEnabled(); +		return LLVoiceClient::voiceEnabled()&&gVoiceClient->voiceWorking();  	}  	return true; diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 9608cd1263..6f9a1ccdbe 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -70,8 +70,6 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy  	{  		mDisplayName = name;  	} - -	gVoiceClient->setUserVolume(id, LLMuteList::getInstance()->getSavedResidentVolume(id));  } diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp index c9bfe178ce..9d39aa5182 100644 --- a/indra/newview/lltransientdockablefloater.cpp +++ b/indra/newview/lltransientdockablefloater.cpp @@ -48,6 +48,14 @@ LLTransientDockableFloater::LLTransientDockableFloater(LLDockControl* dockContro  LLTransientDockableFloater::~LLTransientDockableFloater()  {  	LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this); +	LLView* dock = getDockWidget(); +	LLTransientFloaterMgr::getInstance()->removeControlView( +			LLTransientFloaterMgr::DOCKED, this); +	if (dock != NULL) +	{ +		LLTransientFloaterMgr::getInstance()->removeControlView( +				LLTransientFloaterMgr::DOCKED, dock); +	}  }  void LLTransientDockableFloater::setVisible(BOOL visible) @@ -55,18 +63,18 @@ void LLTransientDockableFloater::setVisible(BOOL visible)  	LLView* dock = getDockWidget();  	if(visible && isDocked())  	{ -		LLTransientFloaterMgr::getInstance()->addControlView(this); +		LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, this);  		if (dock != NULL)  		{ -			LLTransientFloaterMgr::getInstance()->addControlView(dock); +			LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, dock);  		}  	}  	else  	{ -		LLTransientFloaterMgr::getInstance()->removeControlView(this); +		LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, this);  		if (dock != NULL)  		{ -			LLTransientFloaterMgr::getInstance()->removeControlView(dock); +			LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, dock);  		}  	} @@ -78,18 +86,18 @@ void LLTransientDockableFloater::setDocked(bool docked, bool pop_on_undock)  	LLView* dock = getDockWidget();  	if(docked)  	{ -		LLTransientFloaterMgr::getInstance()->addControlView(this); +		LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, this);  		if (dock != NULL)  		{ -			LLTransientFloaterMgr::getInstance()->addControlView(dock); +			LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, dock);  		}  	}  	else  	{ -		LLTransientFloaterMgr::getInstance()->removeControlView(this); +		LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, this);  		if (dock != NULL)  		{ -			LLTransientFloaterMgr::getInstance()->removeControlView(dock); +			LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, dock);  		}  	} diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp index 8f1a738453..d82403070b 100644 --- a/indra/newview/lltransientfloatermgr.cpp +++ b/indra/newview/lltransientfloatermgr.cpp @@ -46,6 +46,7 @@ LLTransientFloaterMgr::LLTransientFloaterMgr()  			&LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3));  	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>())); +	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(DOCKED, std::set<LLView*>()));  	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(IM, std::set<LLView*>()));  } @@ -132,7 +133,8 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,  		return;  	} -	bool hide = isControlClicked(mGroupControls.find(GLOBAL)->second, x, y); +	bool hide = isControlClicked(mGroupControls.find(DOCKED)->second, x, y) +			&& isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);  	if (hide)  	{  		hideTransientFloaters(x, y); diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h index 1f99325a7f..9c5ae295f2 100644 --- a/indra/newview/lltransientfloatermgr.h +++ b/indra/newview/lltransientfloatermgr.h @@ -51,7 +51,7 @@ protected:  public:  	enum ETransientGroup  	{ -		GLOBAL, IM +		GLOBAL, DOCKED, IM  	};  	void registerTransientFloater(LLTransientFloater* floater); diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index c84afa5af1..8ca0fd6ef6 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -37,8 +37,10 @@  // library includes  #include "llnotificationsutil.h" +#include "llsdserialize.h"  #include "llsdutil.h" +  // project includes  #include "llvoavatar.h"  #include "llbufferstream.h" @@ -1092,6 +1094,119 @@ static void killGateway()  #endif +class LLSpeakerVolumeStorage : public LLSingleton<LLSpeakerVolumeStorage> +{ +	LOG_CLASS(LLSpeakerVolumeStorage); +public: + +	/** +	 * Sets internal voluem level for specified user. +	 * +	 * @param[in] speaker_id - LLUUID of user to store volume level for +	 * @param[in] volume - internal volume level to be stored for user. +	 */ +	void storeSpeakerVolume(const LLUUID& speaker_id, S32 volume); + +	/** +	 * Gets stored internal volume level for specified speaker. +	 * +	 * If specified user is not found default level will be returned. It is equivalent of  +	 * external level 0.5 from the 0.0..1.0 range. +	 * Default internal level is calculated as: internal = 400 * external^2 +	 * Maps 0.0 to 1.0 to internal values 0-400 with default 0.5 == 100 +	 * +	 * @param[in] speaker_id - LLUUID of user to get his volume level +	 */ +	S32 getSpeakerVolume(const LLUUID& speaker_id); + +private: +	friend class LLSingleton<LLSpeakerVolumeStorage>; +	LLSpeakerVolumeStorage(); +	~LLSpeakerVolumeStorage(); + +	const static std::string SETTINGS_FILE_NAME; + +	void load(); +	void save(); + +	typedef std::map<LLUUID, S32> speaker_data_map_t; +	speaker_data_map_t mSpeakersData; +}; + +const std::string LLSpeakerVolumeStorage::SETTINGS_FILE_NAME = "volume_settings.xml"; + +LLSpeakerVolumeStorage::LLSpeakerVolumeStorage() +{ +	load(); +} + +LLSpeakerVolumeStorage::~LLSpeakerVolumeStorage() +{ +	save(); +} + +void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, S32 volume) +{ +	mSpeakersData[speaker_id] = volume; +} + +S32 LLSpeakerVolumeStorage::getSpeakerVolume(const LLUUID& speaker_id) +{ +	// default internal level of user voice. +	const static LLUICachedControl<S32> DEFAULT_INTERNAL_VOLUME_LEVEL("VoiceDefaultInternalLevel", 100); +	S32 ret_val = DEFAULT_INTERNAL_VOLUME_LEVEL; +	speaker_data_map_t::const_iterator it = mSpeakersData.find(speaker_id); +	 +	if (it != mSpeakersData.end()) +	{ +		ret_val = it->second; +	} +	return ret_val; +} + +void LLSpeakerVolumeStorage::load() +{ +	// load per-resident voice volume information +	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SETTINGS_FILE_NAME); + +	LLSD settings_llsd; +	llifstream file; +	file.open(filename); +	if (file.is_open()) +	{ +		LLSDSerialize::fromXML(settings_llsd, file); +	} + +	for (LLSD::map_const_iterator iter = settings_llsd.beginMap(); +		iter != settings_llsd.endMap(); ++iter) +	{ +		mSpeakersData.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger())); +	} +} + +void LLSpeakerVolumeStorage::save() +{ +	// If we quit from the login screen we will not have an SL account +	// name.  Don't try to save, otherwise we'll dump a file in +	// C:\Program Files\SecondLife\ or similar. JC +	std::string user_dir = gDirUtilp->getLindenUserDir(); +	if (!user_dir.empty()) +	{ +		std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SETTINGS_FILE_NAME); +		LLSD settings_llsd; + +		for(speaker_data_map_t::const_iterator iter = mSpeakersData.begin(); iter != mSpeakersData.end(); ++iter) +		{ +			settings_llsd[iter->first.asString()] = iter->second; +		} + +		llofstream file; +		file.open(filename); +		LLSDSerialize::toPrettyXML(settings_llsd, file); +	} +} + +  ///////////////////////////////////////////////////////////////////////////////////////////////  LLVoiceClient::LLVoiceClient() : @@ -4914,7 +5029,9 @@ LLVoiceClient::participantState *LLVoiceClient::sessionState::addParticipant(con  		}  		mParticipantsByUUID.insert(participantUUIDMap::value_type(&(result->mAvatarID), result)); -		 + +		result->mUserVolume = LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(result->mAvatarID); +  		LL_DEBUGS("Voice") << "participant \"" << result->mURI << "\" added." << LL_ENDL;  	} @@ -5853,6 +5970,11 @@ bool LLVoiceClient::voiceEnabled()  	return gSavedSettings.getBOOL("EnableVoiceChat") && !gSavedSettings.getBOOL("CmdLineDisableVoice");  } +bool LLVoiceClient::voiceWorking() +{ +	return (stateLoggedIn <= mState) && (mState <= stateLeavingSession); +} +  void LLVoiceClient::setLipSyncEnabled(BOOL enabled)  {  	mLipSyncEnabled = enabled; @@ -6158,6 +6280,9 @@ void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)  			participant->mUserVolume = llclamp(ivol, 0, 400);  			participant->mVolumeDirty = TRUE;  			mAudioSession->mVolumeDirty = TRUE; + +			// store this volume setting for future sessions +			LLSpeakerVolumeStorage::getInstance()->storeSpeakerVolume(id, participant->mUserVolume);  		}  	}  } diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 6231c6ba29..8f668dff19 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -191,6 +191,8 @@ static	void updatePosition(void);  		void inputUserControlState(bool down); // interpret any sort of up-down mic-open control input according to ptt-toggle prefs  		void setVoiceEnabled(bool enabled);  		static bool voiceEnabled(); +		// Checks is voice working judging from mState +		bool voiceWorking();  		void setUsePTT(bool usePTT);  		void setPTTIsToggle(bool PTTIsToggle);  		bool getPTTIsToggle(); diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 613530b7aa..d2e5473157 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -11,7 +11,7 @@   can_dock="false"   can_minimize="true"   can_close="true" - visible="true" + visible="false"   width="360"   can_resize="true"   min_width="250" diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml index f473a51ff6..c4411db8c5 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -56,7 +56,7 @@               height="18"               default_icon_name="Generic_Person"               layout="topleft" -             left="0" +             left="5"               name="user_icon"               top="0"               width="18" /> @@ -78,6 +78,7 @@               follows="top|right"               height="16"               layout="topleft" +             right="-3"               name="speaking_indicator"               left_pad="5"               visible="true" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 960da7a274..41f4621d66 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -244,6 +244,16 @@ Save all changes to clothing/body parts?    <notification     icon="alertmodal.tga" +   name="FriendsAndGroupsOnly" +   type="alertmodal"> +    Non-friends won't know that you've choosen to ignore their calls and instant messages. +    <usetemplate +     name="okbutton" +     yestext="Yes"/> +  </notification> + +  <notification +   icon="alertmodal.tga"     name="GrantModifyRights"     type="alertmodal">  Granting modify rights to another Resident allows them to change, delete or take ANY objects you may have in-world. Be VERY careful when handing out this permission. diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index 615ade99a2..c605975c8e 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -65,28 +65,18 @@       height="15"       layout="topleft"       left_pad="5" +     right="-72"       name="last_interaction"       text_color="LtGray_50"       value="0s"       width="24" /> -    <output_monitor -     auto_update="true" -     follows="right" -     draw_border="false" -     height="16" -     layout="topleft" -     left_pad="5" -     mouse_opaque="true" -     name="speaking_indicator" -     visible="true" -     width="20" />      <button       follows="right"       height="16"       image_pressed="Info_Press"       image_unselected="Info_Over"       left_pad="3" -     right="-31" +     right="-53"       name="info_btn"       top_delta="-2"       width="16" /> @@ -96,9 +86,21 @@       image_overlay="ForwardArrow_Off"       layout="topleft"       left_pad="5" -     right="-3" +     right="-28"       name="profile_btn"       tool_tip="View profile"       top_delta="-2"       width="20" /> +    <output_monitor +     auto_update="true" +     follows="right" +     draw_border="false" +     height="16" +     layout="topleft" +     left_pad="5" +     right="-3" +     mouse_opaque="true" +     name="speaking_indicator" +     visible="true" +     width="20" />  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml index 2075d7e05b..db156f7877 100644 --- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml @@ -2,7 +2,7 @@  <panel   border="false"   follows="all" - height="380" + height="420"   label="Land & L$"   layout="topleft"   left="0" @@ -237,7 +237,7 @@      </text>      <tab_container       follows="all" -     height="173" +     height="180"       halign="center"       layout="topleft"       left="0" @@ -250,7 +250,7 @@          <panel           border="false"           follows="all" -         height="173" +         height="180"           label="PLANNING"           layout="topleft"           left="0" @@ -275,7 +275,7 @@        <panel           border="false"           follows="all" -         height="173" +         height="180"           label="DETAILS"           layout="topleft"           left="0" @@ -296,41 +296,44 @@               word_wrap="true">                  Loading...              </text_editor> + +          <button +             height="20" +             image_overlay="Arrow_Left_Off" +             layout="topleft" +             left="5" +             name="earlier_details_button" +             tool_tip="Go back in time" +             top_pad="10" +             width="25" />              <button -	     follows="left|top" -	     height="18" -	     image_overlay="Arrow_Left_Off" -	     layout="topleft" -	     name="earlier_details_button" -	     tool_tip="Back" -             right="-45" -             bottom="0" -	     width="25" /> -             <button -	     follows="left|top" -	     height="18" -	     image_overlay="Arrow_Right_Off" -	     layout="topleft" -	     left_pad="10" -       name="later_details_button" -	     tool_tip="Next" -	     width="25" /> -        </panel> +             height="20" +             image_overlay="Arrow_Right_Off" +             layout="topleft" +             left_pad="5" +             name="later_details_button" +             tool_tip="Go forward in time" +             top_delta="0" +             width="25" />   + + +      </panel>        <panel           border="false"           follows="all" -         height="173" +         height="180"           label="SALES"           layout="topleft"           left_delta="0"           help_topic="group_money_sales_tab" +         mouse_opaque="false"           name="group_money_sales_tab"           top="0"           width="300">              <text_editor               type="string"               follows="all" -             height="140" +             height="130"               layout="topleft"               left="0"               max_length="4096" @@ -340,25 +343,24 @@               word_wrap="true">                  Loading...              </text_editor> -                         <button -             bottom="0" -	     follows="left|top" -	     height="18" -	     image_overlay="Arrow_Left_Off" -	     layout="topleft" -	     name="earlier_sales_button" -	     tool_tip="Back" -         right="-45" -	     width="25" /> -             <button -	     follows="left|top" -	     height="18" -	     image_overlay="Arrow_Right_Off" -	     layout="topleft" -	     left_pad="10" -         name="later_sales_button" -	     tool_tip="Next" -	     width="25" /> +            <button +             height="20" +             image_overlay="Arrow_Left_Off" +             layout="topleft" +             left="5" +             name="earlier_sales_button" +             tool_tip="Go back in time" +             top_pad="10" +             width="25" /> +            <button +             height="20" +             image_overlay="Arrow_Right_Off" +             layout="topleft" +             left_pad="5" +             name="later_sales_button" +             tool_tip="Go forward in time" +             top_delta="0" +             width="25" />          </panel>      </tab_container>  </panel> | 
