diff options
| author | Ychebotarev ProductEngine <ychebotarev@productengine.com> | 2010-01-25 13:32:17 +0200 | 
|---|---|---|
| committer | Ychebotarev ProductEngine <ychebotarev@productengine.com> | 2010-01-25 13:32:17 +0200 | 
| commit | 088056c5bf4adc589c7fcc65236b90a466e59705 (patch) | |
| tree | 9f3967255a46a396adf51fd39d3859cfa385e633 | |
| parent | 7fc90e2385c6376599818a3a7a3d815535671178 (diff) | |
| parent | 149c56ae429b0dc8ebf349027fe855066b3447f7 (diff) | |
merge
--HG--
branch : product-engine
50 files changed, 538 insertions, 417 deletions
| 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 d9767bc573..d9df537e03 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -94,22 +94,6 @@ static void* create_non_avatar_caller(void*)  	return new LLNonAvatarCaller;  } -LLCallFloater::LLAvatarListItemRemoveTimer::LLAvatarListItemRemoveTimer(callback_t remove_cb, F32 period, const LLUUID& speaker_id) -: LLEventTimer(period) -, mRemoveCallback(remove_cb) -, mSpeakerId(speaker_id) -{ -} - -BOOL LLCallFloater::LLAvatarListItemRemoveTimer::tick() -{ -	if (mRemoveCallback) -	{ -		mRemoveCallback(mSpeakerId); -	} -	return TRUE; -} -  LLVoiceChannel* LLCallFloater::sCurrentVoiceCanel = NULL;  LLCallFloater::LLCallFloater(const LLSD& key) @@ -123,10 +107,9 @@ LLCallFloater::LLCallFloater(const LLSD& key)  , mSpeakingIndicator(NULL)  , mIsModeratorMutedVoice(false)  , mInitParticipantsVoiceState(false) -, mVoiceLeftRemoveDelay(10)  {  	static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10); -	mVoiceLeftRemoveDelay = voice_left_remove_delay; +	mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay);  	mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL);  	LLVoiceClient::getInstance()->addObserver(this); @@ -136,6 +119,7 @@ LLCallFloater::LLCallFloater(const LLSD& key)  LLCallFloater::~LLCallFloater()  {  	resetVoiceRemoveTimers(); +	delete mSpeakerDelayRemover;  	delete mParticipants;  	mParticipants = NULL; @@ -654,33 +638,11 @@ void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state)  void LLCallFloater::setVoiceRemoveTimer(const LLUUID& voice_speaker_id)  { - -	// If there is already a started timer for the current panel don't do anything. -	bool no_timer_for_current_panel = true; -	if (mVoiceLeftTimersMap.size() > 0) -	{ -		timers_map::iterator found_it = mVoiceLeftTimersMap.find(voice_speaker_id); -		if (found_it != mVoiceLeftTimersMap.end()) -		{ -			no_timer_for_current_panel = false; -		} -	} - -	if (no_timer_for_current_panel) -	{ -		// Starting a timer to remove an avatar row panel after timeout -		mVoiceLeftTimersMap.insert(timer_pair(voice_speaker_id, -			new LLAvatarListItemRemoveTimer(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), mVoiceLeftRemoveDelay, voice_speaker_id))); -	} +	mSpeakerDelayRemover->setActionTimer(voice_speaker_id);  } -void LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id) +bool LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)  { -	if (mVoiceLeftTimersMap.size() > 0) -	{ -		mVoiceLeftTimersMap.erase(mVoiceLeftTimersMap.find(voice_speaker_id)); -	} -  	LLAvatarList::uuid_vector_t& speaker_uuids = mAvatarList->getIDs();  	LLAvatarList::uuid_vector_t::iterator pos = std::find(speaker_uuids.begin(), speaker_uuids.end(), voice_speaker_id);  	if(pos != speaker_uuids.end()) @@ -688,34 +650,19 @@ void LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)  		speaker_uuids.erase(pos);  		mAvatarList->setDirty();  	} + +	return false;  }  void LLCallFloater::resetVoiceRemoveTimers()  { -	if (mVoiceLeftTimersMap.size() > 0) -	{ -		for (timers_map::iterator iter = mVoiceLeftTimersMap.begin(); -			iter != mVoiceLeftTimersMap.end(); ++iter) -		{ -			delete iter->second; -		} -	} -	mVoiceLeftTimersMap.clear(); +	mSpeakerDelayRemover->removeAllTimers();  }  void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id)  { -	// Remove the timer if it has been already started -	if (mVoiceLeftTimersMap.size() > 0) -	{ -		timers_map::iterator found_it = mVoiceLeftTimersMap.find(voice_speaker_id); -		if (found_it != mVoiceLeftTimersMap.end()) -		{ -			delete found_it->second; -			mVoiceLeftTimersMap.erase(found_it); -		} -	} +	mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id);  }  bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id) diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index 096594aaa2..eded3a426b 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -44,6 +44,8 @@ class LLNonAvatarCaller;  class LLOutputMonitorCtrl;  class LLParticipantList;  class LLSpeakerMgr; +class LLSpeakersDelayActionsStorage; +  /**   * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron on the Speak button.   * It can be torn-off and freely positioned onscreen. @@ -169,7 +171,7 @@ private:  	 *  	 * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list.  	 */ -	void removeVoiceLeftParticipant(const LLUUID& voice_speaker_id); +	bool removeVoiceLeftParticipant(const LLUUID& voice_speaker_id);  	/**  	 * Deletes all timers from the list to prevent started timers from ticking after destruction @@ -240,32 +242,11 @@ private:  	boost::signals2::connection mAvatarListRefreshConnection; +  	/** -	 * class LLAvatarListItemRemoveTimer -	 *  -	 * Implements a timer that removes avatar list item of a participant -	 * who has left the call. +	 * time out speakers when they are not part of current session  	 */ -	class LLAvatarListItemRemoveTimer : public LLEventTimer -	{ -	public: -		typedef boost::function<void(const LLUUID&)> callback_t; - -		LLAvatarListItemRemoveTimer(callback_t remove_cb, F32 period, const LLUUID& speaker_id); -		virtual ~LLAvatarListItemRemoveTimer() {}; - -		virtual BOOL tick(); - -	private: -		callback_t		mRemoveCallback; -		LLUUID			mSpeakerId; -	}; - -	typedef std::pair<LLUUID, LLAvatarListItemRemoveTimer*> timer_pair; -	typedef std::map<LLUUID, LLAvatarListItemRemoveTimer*> timers_map; - -	timers_map		mVoiceLeftTimersMap; -	S32				mVoiceLeftRemoveDelay; +	LLSpeakersDelayActionsStorage* mSpeakerDelayRemover;  	/**  	 * Stores reference to current voice channel. diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index fb94657278..0e42ff09d8 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -51,6 +51,7 @@  #include "llinventorymodel.h"  #include "llfloaterworldmap.h"  #include "lllandmarkactions.h" +#include "llnotificationsutil.h"  #include "llsidetray.h"  #include "lltoggleablemenu.h"  #include "llviewerinventory.h" @@ -975,6 +976,10 @@ BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)  void copy_slurl_to_clipboard_cb(std::string& slurl)  {  	gClipboard.copyFromString(utf8str_to_wstring(slurl)); + +	LLSD args; +	args["SLURL"] = slurl; +	LLNotificationsUtil::add("CopySLURL", args);  } 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/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index e0f2fca580..4a1eb51dbe 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -277,13 +277,8 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)  				{  					object_owner.append("Unknown");  				} -				childSetText("object_name", object_owner); -				std::string owner_link = -					LLSLURL::buildCommand("agent", mObjectID, "inspect"); -				childSetText("owner_name", owner_link); -				childSetText("abuser_name_edit", object_owner); -				mAbuserID = object_id; -				mOwnerName = object_owner; + +				setFromAvatar(object_id, object_owner);  			}  			else  			{ @@ -305,7 +300,6 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)  	}  } -  void LLFloaterReporter::onClickSelectAbuser()  {  	gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE )); @@ -323,6 +317,17 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,  } +void LLFloaterReporter::setFromAvatar(const LLUUID& avatar_id, const std::string& avatar_name) +{ +	mAbuserID = mObjectID = avatar_id; +	mOwnerName = avatar_name; + +	std::string avatar_link = LLSLURL::buildCommand("agent", mObjectID, "inspect"); +	childSetText("owner_name", avatar_link); +	childSetText("object_name", avatar_name); +	childSetText("abuser_name_edit", avatar_name); +} +  // static  void LLFloaterReporter::onClickSend(void *userdata)  { @@ -458,9 +463,8 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)  	}  } -  // static -void LLFloaterReporter::showFromObject(const LLUUID& object_id) +void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_name)  {  	LLFloaterReporter* f = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter"); @@ -469,8 +473,11 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id)  	LLAgentUI::buildFullname(fullname);  	f->childSetText("reporter_field", fullname); -	// Request info for this object -	f->getObjectInfo(object_id); +	if (avatar_name.empty()) +		// Request info for this object +		f->getObjectInfo(object_id); +	else +		f->setFromAvatar(object_id, avatar_name);  	// Need to deselect on close  	f->mDeselectOnClose = TRUE; @@ -479,6 +486,18 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id)  } +// static +void LLFloaterReporter::showFromObject(const LLUUID& object_id) +{ +	show(object_id); +} + +// static +void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name) +{ +	show(avatar_id, avatar_name); +} +  void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)  {  	childSetText("object_name", object_name); diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index cc2dfb2f98..7c6473f975 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -93,6 +93,7 @@ public:  	static void showFromMenu(EReportType report_type);  	static void showFromObject(const LLUUID& object_id); +	static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name);  	static void onClickSend			(void *userdata);  	static void onClickCancel		(void *userdata); @@ -109,6 +110,8 @@ public:  	void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id);  private: +	static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null); +  	void takeScreenshot();  	void sendReportViaCaps(std::string url);  	void uploadImage(); @@ -121,6 +124,7 @@ private:  	void enableControls(BOOL own_avatar);  	void getObjectInfo(const LLUUID& object_id);  	void callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids); +	void setFromAvatar(const LLUUID& avatar_id, const std::string& avatar_name = LLStringUtil::null);  private:  	EReportType		mReportType; 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 ff20a55358..c2a7969c0d 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -55,6 +55,7 @@  #include "llfloaterchatterbox.h"  #include "llimfloater.h"  #include "llgroupiconctrl.h" +#include "llmd5.h"  #include "llmutelist.h"  #include "llrecentpeople.h"  #include "llviewermessage.h" @@ -215,12 +216,14 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&  		mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionID);  	} +	buildHistoryFileName(); +  	if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )  	{  		std::list<LLSD> chat_history;  		//involves parsing of a chat history -		LLLogChat::loadAllHistory(mName, chat_history); +		LLLogChat::loadAllHistory(mHistoryFileName, chat_history);  		addMessagesFromHistory(chat_history);  	}  } @@ -467,6 +470,44 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline()  	return !mOtherParticipantIsAvatar;  } +void LLIMModel::LLIMSession::buildHistoryFileName() +{ +	mHistoryFileName = mName; +	 +	//ad-hoc requires sophisticated chat history saving schemes +	if (isAdHoc()) +	{ +		//in case of outgoing ad-hoc sessions +		if (mInitialTargetIDs.size()) +		{ +			std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end()); +			mHistoryFileName = mName + " hash" + generateHash(sorted_uuids); +			return; +		} +		 +		//in case of incoming ad-hoc sessions +		mHistoryFileName = mName + " " + LLLogChat::timestamp(true) + " " + mSessionID.asString().substr(0, 4); +	} +} + +//static +std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids) +{ +	LLMD5 md5_uuid; +	 +	std::set<LLUUID>::const_iterator it = sorted_uuids.begin(); +	while (it != sorted_uuids.end()) +	{ +		md5_uuid.update((unsigned char*)(*it).mData, 16); +		it++; +	} +	md5_uuid.finalize(); + +	LLUUID participants_md5_hash; +	md5_uuid.raw_digest((unsigned char*) participants_md5_hash.mData); +	return participants_md5_hash.asString(); +} +  void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id)  { @@ -614,11 +655,11 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,  	return true;  } -bool LLIMModel::logToFile(const std::string& session_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) +bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)  {  	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))  	{ -		LLLogChat::saveHistory(session_name, from, from_id, utf8_text); +		LLLogChat::saveHistory(file_name, from, from_id, utf8_text);  		return true;  	}  	else @@ -629,15 +670,7 @@ bool LLIMModel::logToFile(const std::string& session_name, const std::string& fr  bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)  { -	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) -	{ -		LLLogChat::saveHistory(LLIMModel::getInstance()->getName(session_id), from, from_id, utf8_text); -		return true; -	} -	else -	{ -		return false; -	} +	return logToFile(LLIMModel::getInstance()->getHistoryFileName(session_id), from, from_id, utf8_text);  }  bool LLIMModel::proccessOnlineOfflineNotification( @@ -782,6 +815,18 @@ LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const  	return session->mSpeakers;  } +const std::string& LLIMModel::getHistoryFileName(const LLUUID& session_id) const +{ +	LLIMSession* session = findIMSession(session_id); +	if (!session) +	{ +		llwarns << "session " << session_id << " does not exist " << llendl; +		return LLStringUtil::null; +	} + +	return session->mHistoryFileName; +} +  // TODO get rid of other participant ID  void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing)  diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index a226d66b12..a3b4f78af0 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -69,6 +69,8 @@ public:  		void addMessagesFromHistory(const std::list<LLSD>& history);  		void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time);  		void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction); +		 +		/** @deprecated */  		static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata);  		bool isAdHoc(); @@ -80,12 +82,20 @@ public:  		bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}  		bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;} +		//*TODO make private +		/** ad-hoc sessions involve sophisticated chat history file naming schemes */ +		void buildHistoryFileName(); + +		//*TODO make private +		static std::string generateHash(const std::set<LLUUID>& sorted_uuids); +  		LLUUID mSessionID;  		std::string mName;  		EInstantMessage mType;  		SType mSessionType;  		LLUUID mOtherParticipantID;  		std::vector<LLUUID> mInitialTargetIDs; +		std::string mHistoryFileName;  		// connection to voice channel state change signal  		boost::signals2::connection mVoiceChannelStateChangeConnection; @@ -231,6 +241,8 @@ public:  	*/  	LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const; +	const std::string& getHistoryFileName(const LLUUID& session_id) const; +  	static void sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id);  	static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,  						  const std::vector<LLUUID>& ids, EInstantMessage dialog); @@ -243,7 +255,7 @@ public:  	/**  	 * Saves an IM message into a file  	 */ -	bool logToFile(const std::string& session_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); +	bool logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);  private: diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 0374a1d25b..4b0539337b 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -689,7 +689,7 @@ void LLInspectAvatar::onToggleMute()  void LLInspectAvatar::onClickReport()  { -	LLFloaterReporter::showFromObject(mAvatarID); +	LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName);  	closeFloater();  } diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 4e5aaeb66a..dc187bf36c 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -237,15 +237,15 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)  	messages.back()[IM_TEXT] = im_text;  } -void LLLogChat::loadAllHistory(const std::string& session_name, std::list<LLSD>& messages) +void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& messages)  { -	if (session_name.empty()) +	if (file_name.empty())  	{  		llwarns << "Session name is Empty!" << llendl;  		return ;  	} -	LLFILE* fptr = LLFile::fopen(makeLogFileName(session_name), "r");		/*Flawfinder: ignore*/ +	LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");		/*Flawfinder: ignore*/  	if (!fptr) return;	//No previous conversation with this name.  	char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/ diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index 3d3f5c4458..4290e4bbc0 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -56,7 +56,7 @@ public:  		                    void (*callback)(ELogLineType, const LLSD&, void*),   							void* userdata); -	static void loadAllHistory(const std::string& session_name, std::list<LLSD>& messages); +	static void loadAllHistory(const std::string& file_name, std::list<LLSD>& messages);  private:  	static std::string cleanFileName(std::string filename);  }; 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 86bdee7c7d..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; - -	bool session_initialized = session->mSessionInitialized; -	bool callback_enabled = session->mCallBackEnabled; - -	BOOL enable_connect = session_initialized -		&& voice_enabled -		&& callback_enabled; -	childSetEnabled("call_btn", enable_connect); +	gVoiceClient->addObserver(this); -	LLPanel::draw(); +	return TRUE;  }  void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id) @@ -245,7 +259,6 @@ void LLPanelIMControlPanel::nameUpdatedCallback(const LLUUID& id, const std::str  LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id):  mParticipantList(NULL)  { -	mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id);  }  BOOL LLPanelGroupControlPanel::postBuild() @@ -267,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();  } @@ -304,7 +319,10 @@ void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)  	// for group and Ad-hoc chat we need to include agent into list   	if(!mParticipantList) -		mParticipantList = new LLParticipantList(mSpeakerManager, getChild<LLAvatarList>("speakers_list"), true,false); +	{ +		LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id); +		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true,false); +	}  } diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index c18be5a6df..3ab505a084 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -37,11 +37,11 @@  #include "llvoicechannel.h"  #include "llcallingcard.h" -class LLSpeakerMgr; -class LLAvatarList;  class LLParticipantList; -class LLPanelChatControlPanel : public LLPanel +class LLPanelChatControlPanel  +	: public LLPanel +	, public LLVoiceClientStatusObserver  {  public:  	LLPanelChatControlPanel() : @@ -49,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; } @@ -110,7 +116,6 @@ public:  protected:  	LLUUID mGroupID; -	LLSpeakerMgr* mSpeakerManager;  	LLParticipantList* mParticipantList; 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/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index b80eb9db38..0c10f11bfc 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -34,26 +34,20 @@  #include "llpanelplaceinfo.h" -#include "roles_constants.h"  #include "llsdutil.h" -#include "llsecondlifeurls.h"  #include "llsdutil_math.h" +  #include "llregionhandle.h" -#include "message.h"  #include "lliconctrl.h"  #include "lltextbox.h"  #include "llagent.h" -#include "llavatarpropertiesprocessor.h"  #include "llexpandabletextbox.h"  #include "llpanelpick.h"  #include "lltexturectrl.h" -#include "llviewerinventory.h" -#include "llviewerparcelmgr.h"  #include "llviewerregion.h" -#include "llviewertexteditor.h"  LLPanelPlaceInfo::LLPanelPlaceInfo()  :	LLPanel(), @@ -265,25 +259,6 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)  	}  } -// virtual -void LLPanelPlaceInfo::handleVisibilityChange(BOOL new_visibility) -{ -	LLPanel::handleVisibilityChange(new_visibility); - -	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); -	if (!parcel_mgr) -		return; - -	// Remove land selection when panel hides. -	if (!new_visibility) -	{ -		if (!parcel_mgr->selectionEmpty()) -		{ -			parcel_mgr->deselectLand(); -		} -	} -} -  void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)  {  	std::string region_name = mRegionName->getText(); diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 7dfc7b2444..3091f7ed24 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -94,7 +94,6 @@ public:  	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);  	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); -	/*virtual*/ void handleVisibilityChange (BOOL new_visibility);  	// Create a pick for the location specified  	// by global_pos. diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 402d50ba9c..d892e2885b 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -257,6 +257,25 @@ void LLPanelPlaceProfile::processParcelInfo(const LLParcelData& parcel_data)  	}  } +// virtual +void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility) +{ +	LLPanel::handleVisibilityChange(new_visibility); + +	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); +	if (!parcel_mgr) +		return; + +	// Remove land selection when panel hides. +	if (!new_visibility) +	{ +		if (!parcel_mgr->selectionEmpty()) +		{ +			parcel_mgr->deselectUnused(); +		} +	} +} +  void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,  													LLViewerRegion* region,  													const LLVector3d& pos_global, diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h index 8c30ca92fb..8ca9526875 100644 --- a/indra/newview/llpanelplaceprofile.h +++ b/indra/newview/llpanelplaceprofile.h @@ -52,6 +52,8 @@ public:  	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); +	/*virtual*/ void handleVisibilityChange(BOOL new_visibility); +  	// Displays information about the currently selected parcel  	// without sending a request to the server.  	// If is_current_parcel true shows "You Are Here" banner. diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index b037674c37..a4f0e55a93 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -289,89 +289,92 @@ BOOL LLPanelPlaces::postBuild()  void LLPanelPlaces::onOpen(const LLSD& key)  { -	if(!mPlaceProfile || !mLandmarkInfo || key.size() == 0) +	if (!mPlaceProfile || !mLandmarkInfo)  		return; -	mFilterEditor->clear(); -	onFilterEdit("", false); - -	mPlaceInfoType = key["type"].asString(); -	mPosGlobal.setZero(); -	mItem = NULL; -	isLandmarkEditModeOn = false; -	togglePlaceInfoPanel(TRUE); - -	if (mPlaceInfoType == AGENT_INFO_TYPE) -	{ -		mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT); -	} -	else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) +	if (key.size() != 0)  	{ -		mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK); +		mFilterEditor->clear(); +		onFilterEdit("", false); -		if (key.has("x") && key.has("y") && key.has("z")) +		mPlaceInfoType = key["type"].asString(); +		mPosGlobal.setZero(); +		mItem = NULL; +		isLandmarkEditModeOn = false; +		togglePlaceInfoPanel(TRUE); + +		if (mPlaceInfoType == AGENT_INFO_TYPE)  		{ -			mPosGlobal = LLVector3d(key["x"].asReal(), -									key["y"].asReal(), -									key["z"].asReal()); +			mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT);  		} -		else +		else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)  		{ -			mPosGlobal = gAgent.getPositionGlobal(); -		} - -		mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal); +			mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK); -		// Disable Save button because there is no item to save yet. -		// The button will be enabled in onLandmarkLoaded callback. -		mSaveBtn->setEnabled(FALSE); -	} -	else if (mPlaceInfoType == LANDMARK_INFO_TYPE) -	{ -		mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK); +			if (key.has("x") && key.has("y") && key.has("z")) +			{ +				mPosGlobal = LLVector3d(key["x"].asReal(), +										key["y"].asReal(), +										key["z"].asReal()); +			} +			else +			{ +				mPosGlobal = gAgent.getPositionGlobal(); +			} -		LLInventoryItem* item = gInventory.getItem(key["id"].asUUID()); -		if (!item) -			return; +			mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal); -		setItem(item); -	} -	else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE) -	{ -		if (key.has("id")) +			// Disable Save button because there is no item to save yet. +			// The button will be enabled in onLandmarkLoaded callback. +			mSaveBtn->setEnabled(FALSE); +		} +		else if (mPlaceInfoType == LANDMARK_INFO_TYPE)  		{ -			LLUUID parcel_id = key["id"].asUUID(); -			mPlaceProfile->setParcelID(parcel_id); +			mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK); + +			LLInventoryItem* item = gInventory.getItem(key["id"].asUUID()); +			if (!item) +				return; -			// query the server to get the global 3D position of this -			// parcel - we need this for teleport/mapping functions. -			mRemoteParcelObserver->setParcelID(parcel_id); +			setItem(item);  		} -		else +		else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)  		{ -			mPosGlobal = LLVector3d(key["x"].asReal(), -									key["y"].asReal(), -									key["z"].asReal()); -			mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); +			if (key.has("id")) +			{ +				LLUUID parcel_id = key["id"].asUUID(); +				mPlaceProfile->setParcelID(parcel_id); + +				// query the server to get the global 3D position of this +				// parcel - we need this for teleport/mapping functions. +				mRemoteParcelObserver->setParcelID(parcel_id); +			} +			else +			{ +				mPosGlobal = LLVector3d(key["x"].asReal(), +										key["y"].asReal(), +										key["z"].asReal()); +				mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); +			} + +			mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE);  		} +		else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) +		{ +			S32 index = key["id"].asInteger(); -		mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE); -	} -	else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) -	{ -		S32 index = key["id"].asInteger(); +			const LLTeleportHistoryStorage::slurl_list_t& hist_items = +						LLTeleportHistoryStorage::getInstance()->getItems(); -		const LLTeleportHistoryStorage::slurl_list_t& hist_items = -					LLTeleportHistoryStorage::getInstance()->getItems(); +			mPosGlobal = hist_items[index].mGlobalPos; -		mPosGlobal = hist_items[index].mGlobalPos; +			mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY); +			mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); +		} -		mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY); -		mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); +		updateVerbs();  	} -	updateVerbs(); -  	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();  	if (!parcel_mgr)  		return; @@ -388,9 +391,12 @@ void LLPanelPlaces::onOpen(const LLSD& key)  	{  		parcel_mgr->removeObserver(mParcelObserver); +		// Clear the reference to selection to allow its removal in deselectUnused(). +		mParcel.clear(); +  		if (!parcel_mgr->selectionEmpty())  		{ -			parcel_mgr->deselectLand(); +			parcel_mgr->deselectUnused();  		}  	}  } @@ -765,23 +771,23 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)  		mPickPanel->reshape(rect.getWidth(), rect.getHeight());  		mPickPanel->setRect(rect);  	} -    else if (item == "add_to_favbar") -    { -        if ( mItem.notNull() )  -        { -            const LLUUID& favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); -            if ( favorites_id.notNull() ) -            { -                copy_inventory_item(gAgent.getID(), -                                    mItem->getPermissions().getOwner(), -                                    mItem->getUUID(), -                                    favorites_id, -                                    std::string(), -                                    LLPointer<LLInventoryCallback>(NULL)); -                llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl; -            } -        } -    } +	else if (item == "add_to_favbar") +	{ +		if ( mItem.notNull() ) +		{ +			const LLUUID& favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); +			if ( favorites_id.notNull() ) +			{ +				copy_inventory_item(gAgent.getID(), +									mItem->getPermissions().getOwner(), +									mItem->getUUID(), +									favorites_id, +									std::string(), +									LLPointer<LLInventoryCallback>(NULL)); +				llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl; +			} +		} +	}  }  void LLPanelPlaces::onBackButtonClicked() @@ -826,6 +832,14 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  			mLandmarkInfo->setVisible(FALSE);  		} +		else if (mPlaceInfoType == AGENT_INFO_TYPE) +		{ +			LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); + +			// Clear reference to parcel selection when closing place profile panel. +			// LLViewerParcelMgr removes the selection if it has 1 reference to it. +			mParcel.clear(); +		}  	}  	else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE ||  			 mPlaceInfoType == LANDMARK_INFO_TYPE) @@ -858,6 +872,20 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  	}  } +// virtual +void LLPanelPlaces::handleVisibilityChange(BOOL new_visibility) +{ +	LLPanel::handleVisibilityChange(new_visibility); + +	if (!new_visibility && mPlaceInfoType == AGENT_INFO_TYPE) +	{ +		LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); + +		// Clear reference to parcel selection when closing places panel. +		mParcel.clear(); +	} +} +  void LLPanelPlaces::changedParcelSelection()  {  	if (!mPlaceProfile) diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 27b5911ebb..0eba7f3afc 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -97,6 +97,8 @@ private:  	void togglePickPanel(BOOL visible);  	void togglePlaceInfoPanel(BOOL visible); +	/*virtual*/ void handleVisibilityChange(BOOL new_visibility); +  	void updateVerbs();  	LLPanelPlaceInfo* getCurrentInfoPanel(); 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/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 9c4825763b..2b846d33fc 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1103,7 +1103,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)  	{  		if (op == TEXTURE_CANCEL)  			mViewModel->resetDirty(); -		else +		// If the "no_commit_on_selection" parameter is set +		// we get dirty only when user presses OK in the picker +		// (i.e. op == TEXTURE_SELECT) or texture changes via DnD. +		else if (mCommitOnSelection || op == TEXTURE_SELECT)  			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?  		if( floaterp->isDirty() ) @@ -1125,7 +1128,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)  			{  				// If the "no_commit_on_selection" parameter is set  				// we commit only when user presses OK in the picker -				// (i.e. op == TEXTURE_SELECT) or changes texture via DnD. +				// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.  				if (mCommitOnSelection || op == TEXTURE_SELECT)  					onCommit();  			} @@ -1165,6 +1168,9 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,  		{  			if(doDrop(item))  			{ +				if (!mCommitOnSelection) +					mViewModel->setDirty(); +  				// This removes the 'Multiple' overlay, since  				// there is now only one texture selected.  				setTentative( FALSE );  diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 023329a9b2..8ca92c3d87 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -74,7 +74,8 @@ public:  		Optional<std::string>	default_image_name;  		Optional<bool>			allow_no_texture;  		Optional<bool>			can_apply_immediately; -		Optional<bool>			no_commit_on_selection; // don't commit unless it's DnD or OK button press +		Optional<bool>			no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty +														// only on DnD or when OK is pressed in the picker  		Optional<S32>			label_width;  		Optional<LLUIColor>		border_color; 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/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 7487fa9997..0358efc0af 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1472,7 +1472,12 @@ void inventory_offer_handler(LLOfferInfo* info)  	{  		LLStringUtil::truncate(msg, indx);  	} -	 + +	if(LLAssetType::AT_LANDMARK == info->mType) +	{ +		msg = LLViewerInventoryItem::getDisplayName(msg); +	} +  	LLSD args;  	args["[OBJECTNAME]"] = msg; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index c84afa5af1..e52d6a089b 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -5853,6 +5853,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; 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/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml index 6adf2a5950..b365040c20 100644 --- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml +++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml @@ -10,6 +10,8 @@   image_selected="transparent.j2c"   image_unselected="transparent.j2c"   image_pressed="Favorite_Link_Over" + image_hover_selected="Favorite_Link_Over" + image_hover_unselected="Favorite_Link_Over"   hover_glow_amount="0.15"   label_shadow="false"   layout="topleft" 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/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_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index de3de45718..38e9219b5b 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -418,7 +418,6 @@ image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well                 name="Unread"                 image_overlay="Notices_Unread"                 image_overlay_alignment="center" -               pad_right="15"                 tool_tip="Notifications"                 width="35" >                    <button.init_callback diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index 673052c3b5..0893c204e7 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -67,6 +67,7 @@ background_visible="true"       layout="topleft"       left="20"       name="insignia" +     no_commit_on_selection="true"       tool_tip="Click to choose a picture"       top_pad="5"       width="100" /> diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml index 34cde61252..4894ae01da 100644 --- a/indra/newview/skins/default/xui/en/panel_my_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <panel   follows="all" - height="535" + height="500"   label="Profile"   layout="topleft"   left="0" @@ -41,7 +41,7 @@       layout="topleft"       left="0"       top="0" -     height="535" +     height="480"       width="313"       border_size="0">        <layout_panel @@ -50,7 +50,7 @@           layout="topleft"           top="0"           left="0" -         height="505" +         height="480"           user_resize="false"           width="313">          <scroll_container @@ -60,7 +60,7 @@           left="0"           name="profile_scroll"           opaque="true" -         height="505" +         height="480"           width="313"           top="0">            <panel @@ -374,8 +374,9 @@           follows="bottom|right"           height="23"           left="20" -	 top="0" +	 top="5"           label="Edit Profile" +         layout="topleft"           name="edit_profile_btn"           tool_tip="Edit your personal information"           width="130" /> @@ -384,7 +385,9 @@           height="23"           label="Edit Appearance"           left_pad="10" +         layout="topleft"           name="edit_appearance_btn" +         top="5"           tool_tip="Create/edit your appearance: physical data, clothes and etc."           width="130" />   </layout_panel> | 
