PageRenderTime 45ms CodeModel.GetById 2ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llpanelimcontrolpanel.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 431 lines | 301 code | 86 blank | 44 comment | 28 complexity | 5f039506db63f7fa031f929f0ac51827 MD5 | raw file
  1/** 
  2 * @file llpanelavatar.cpp
  3 * @brief LLPanelAvatar and related class implementations
  4 *
  5 * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llfloaterreg.h"
 30
 31#include "llpanelimcontrolpanel.h"
 32
 33#include "llagent.h"
 34#include "llappviewer.h" // for gDisconnected
 35#include "llavataractions.h"
 36#include "llavatariconctrl.h"
 37#include "llbutton.h"
 38#include "llgroupactions.h"
 39#include "llavatarlist.h"
 40#include "llparticipantlist.h"
 41#include "llimview.h"
 42#include "llvoicechannel.h"
 43#include "llspeakers.h"
 44#include "lltrans.h"
 45
 46void LLPanelChatControlPanel::onCallButtonClicked()
 47{
 48	gIMMgr->startCall(mSessionId);
 49}
 50
 51void LLPanelChatControlPanel::onEndCallButtonClicked()
 52{
 53	gIMMgr->endCall(mSessionId);
 54}
 55
 56void LLPanelChatControlPanel::onOpenVoiceControlsClicked()
 57{
 58	LLFloaterReg::showInstance("voice_controls");
 59}
 60
 61void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &channelURI, bool proximal)
 62{
 63	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
 64	{
 65		return;
 66	}
 67
 68	updateCallButton();
 69}
 70
 71void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
 72{
 73	updateButtons(new_state);
 74}
 75
 76void LLPanelChatControlPanel::updateCallButton()
 77{
 78	// hide/show call button
 79	bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
 80
 81	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
 82	
 83	if (!session) 
 84	{
 85		getChildView("call_btn")->setEnabled(false);
 86		return;
 87	}
 88
 89	bool session_initialized = session->mSessionInitialized;
 90	bool callback_enabled = session->mCallBackEnabled;
 91
 92	BOOL enable_connect = session_initialized
 93		&& voice_enabled
 94		&& callback_enabled;
 95	getChildView("call_btn")->setEnabled(enable_connect);
 96}
 97
 98void LLPanelChatControlPanel::updateButtons(LLVoiceChannel::EState state)
 99{
100	bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;
101	getChildView("end_call_btn_panel")->setVisible( is_call_started);
102	getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started && findChild<LLView>("voice_ctrls_btn_panel"));
103	getChildView("call_btn_panel")->setVisible( ! is_call_started);
104	
105	getChildView("volume_ctrl_panel")->setVisible(state == LLVoiceChannel::STATE_CONNECTED);
106	
107	updateCallButton();
108	
109}
110
111LLPanelChatControlPanel::~LLPanelChatControlPanel()
112{
113	mVoiceChannelStateChangeConnection.disconnect();
114	if(LLVoiceClient::instanceExists())
115	{
116		LLVoiceClient::getInstance()->removeObserver(this);
117	}
118}
119
120BOOL LLPanelChatControlPanel::postBuild()
121{
122	childSetAction("call_btn", boost::bind(&LLPanelChatControlPanel::onCallButtonClicked, this));
123	childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this));
124	childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this));
125
126	LLVoiceClient::getInstance()->addObserver(this);
127
128	return TRUE;
129}
130
131void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
132{
133	//Method is called twice for AdHoc and Group chat. Second time when server init reply received
134	mSessionId = session_id;
135	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionId);
136	if(voice_channel)
137	{
138		mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&LLPanelChatControlPanel::onVoiceChannelStateChanged, this, _1, _2));
139		
140		//call (either p2p, group or ad-hoc) can be already in started state
141		updateButtons(voice_channel->getState());
142	}
143}
144
145LLPanelIMControlPanel::LLPanelIMControlPanel()
146{
147}
148
149LLPanelIMControlPanel::~LLPanelIMControlPanel()
150{
151	LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
152}
153
154BOOL LLPanelIMControlPanel::postBuild()
155{
156	childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this));
157	childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this));
158
159	childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this));
160	childSetAction("teleport_btn", boost::bind(&LLPanelIMControlPanel::onTeleportButtonClicked, this));
161	childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this));
162
163	childSetAction("mute_btn", boost::bind(&LLPanelIMControlPanel::onClickMuteVolume, this));
164	childSetAction("block_btn", boost::bind(&LLPanelIMControlPanel::onClickBlock, this));
165	childSetAction("unblock_btn", boost::bind(&LLPanelIMControlPanel::onClickUnblock, this));
166	
167	getChild<LLUICtrl>("volume_slider")->setCommitCallback(boost::bind(&LLPanelIMControlPanel::onVolumeChange, this, _2));
168
169	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId()));
170
171	setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this));
172	
173	return LLPanelChatControlPanel::postBuild();
174}
175
176void LLPanelIMControlPanel::draw()
177{
178	bool is_muted = LLMuteList::getInstance()->isMuted(mAvatarID);
179
180	getChild<LLUICtrl>("block_btn_panel")->setVisible(!is_muted);
181	getChild<LLUICtrl>("unblock_btn_panel")->setVisible(is_muted);
182
183	if (getChildView("volume_ctrl_panel")->getVisible())
184	{
185
186		bool is_muted_voice = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat);
187
188		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
189		mute_btn->setValue( is_muted_voice );
190
191		LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
192		volume_slider->setEnabled( !is_muted_voice );
193
194		F32 volume;
195
196		if (is_muted_voice)
197		{
198			// it's clearer to display their volume as zero
199			volume = 0.f;
200		}
201		else
202		{
203			// actual volume
204			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
205		}
206		volume_slider->setValue( (F64)volume );
207	}
208
209	LLPanelChatControlPanel::draw();
210}
211
212void LLPanelIMControlPanel::onClickMuteVolume()
213{
214	// By convention, we only display and toggle voice mutes, not all mutes
215	LLMuteList* mute_list = LLMuteList::getInstance();
216	bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
217
218	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
219	if (!is_muted)
220	{
221		mute_list->add(mute, LLMute::flagVoiceChat);
222	}
223	else
224	{
225		mute_list->remove(mute, LLMute::flagVoiceChat);
226	}
227}
228
229void LLPanelIMControlPanel::onClickBlock()
230{
231	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
232	
233	LLMuteList::getInstance()->add(mute);
234}
235
236void LLPanelIMControlPanel::onClickUnblock()
237{
238	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
239
240	LLMuteList::getInstance()->remove(mute);
241}
242
243void LLPanelIMControlPanel::onVolumeChange(const LLSD& data)
244{
245	F32 volume = (F32)data.asReal();
246	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
247}
248
249void LLPanelIMControlPanel::onTeleportButtonClicked()
250{
251	LLAvatarActions::offerTeleport(mAvatarID);
252}
253void LLPanelIMControlPanel::onPayButtonClicked()
254{
255	LLAvatarActions::pay(mAvatarID);
256}
257
258void LLPanelIMControlPanel::onViewProfileButtonClicked()
259{
260	LLAvatarActions::showProfile(mAvatarID);
261}
262
263void LLPanelIMControlPanel::onAddFriendButtonClicked()
264{
265	LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
266	std::string full_name = avatar_icon->getFullName();
267	LLAvatarActions::requestFriendshipDialog(mAvatarID, full_name);
268}
269
270void LLPanelIMControlPanel::onShareButtonClicked()
271{
272	LLAvatarActions::share(mAvatarID);
273}
274
275void LLPanelIMControlPanel::onFocusReceived()
276{
277	// Disable all the buttons (Call, Teleport, etc) if disconnected.
278	if (gDisconnected)
279	{
280		setAllChildrenEnabled(FALSE);
281	}
282}
283
284void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)
285{
286	LLPanelChatControlPanel::setSessionId(session_id);
287
288	LLIMModel& im_model = LLIMModel::instance();
289
290	LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
291	mAvatarID = im_model.getOtherParticipantID(session_id);
292	LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this);
293
294	// Disable "Add friend" button for friends.
295	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID));
296	
297	// Disable "Teleport" button if friend is offline
298	if(LLAvatarActions::isFriend(mAvatarID))
299	{
300		getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID));
301	}
302
303	getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(mAvatarID);
304
305	// Disable most profile buttons if the participant is
306	// not really an SL avatar (e.g., an Avaline caller).
307	LLIMModel::LLIMSession* im_session =
308		im_model.findIMSession(session_id);
309	if( im_session && !im_session->mOtherParticipantIsAvatar )
310	{
311		getChildView("view_profile_btn")->setEnabled(FALSE);
312		getChildView("add_friend_btn")->setEnabled(FALSE);
313
314		getChildView("share_btn")->setEnabled(FALSE);
315		getChildView("teleport_btn")->setEnabled(FALSE);
316		getChildView("pay_btn")->setEnabled(FALSE);
317
318        getChild<LLTextBox>("avatar_name")->setValue(im_session->mName);
319        getChild<LLTextBox>("avatar_name")->setToolTip(im_session->mName);
320	}
321	else
322	{
323		// If the participant is an avatar, fetch the currect name
324		gCacheName->get(mAvatarID, false,
325			boost::bind(&LLPanelIMControlPanel::onNameCache, this, _1, _2, _3));
326	}
327}
328
329//virtual
330void LLPanelIMControlPanel::changed(U32 mask)
331{
332	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID));
333	
334	// Disable "Teleport" button if friend is offline
335	if(LLAvatarActions::isFriend(mAvatarID))
336	{
337		getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID));
338	}
339}
340
341void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group)
342{
343	if ( id == mAvatarID )
344	{
345		std::string avatar_name = full_name;
346		getChild<LLTextBox>("avatar_name")->setValue(avatar_name);
347		getChild<LLTextBox>("avatar_name")->setToolTip(avatar_name);
348
349		bool is_linden = LLStringUtil::endsWith(full_name, " Linden");
350		getChild<LLUICtrl>("mute_btn")->setEnabled( !is_linden);
351	}
352}
353
354LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id):
355mParticipantList(NULL)
356{
357}
358
359BOOL LLPanelGroupControlPanel::postBuild()
360{
361	childSetAction("group_info_btn", boost::bind(&LLPanelGroupControlPanel::onGroupInfoButtonClicked, this));
362
363	return LLPanelChatControlPanel::postBuild();
364}
365
366LLPanelGroupControlPanel::~LLPanelGroupControlPanel()
367{
368	delete mParticipantList;
369	mParticipantList = NULL;
370}
371
372// virtual
373void LLPanelGroupControlPanel::draw()
374{
375	// Need to resort the participant list if it's in sort by recent speaker order.
376	if (mParticipantList)
377		mParticipantList->updateRecentSpeakersOrder();
378	LLPanelChatControlPanel::draw();
379}
380
381void LLPanelGroupControlPanel::onGroupInfoButtonClicked()
382{
383	LLGroupActions::show(mGroupID);
384}
385
386void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata)
387{
388	// TODO: Check this code when when sort order menu will be added. (EM)
389	if (false && !mParticipantList)
390		return;
391
392	std::string chosen_item = userdata.asString();
393
394	if (chosen_item == "sort_name")
395	{
396		mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME);
397	}
398
399}
400
401void LLPanelGroupControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
402{
403	LLPanelChatControlPanel::onVoiceChannelStateChanged(old_state, new_state);
404	mParticipantList->setSpeakingIndicatorsVisible(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
405}
406
407void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
408{
409	LLPanelChatControlPanel::setSessionId(session_id);
410
411	mGroupID = session_id;
412
413	// for group and Ad-hoc chat we need to include agent into list 
414	if(!mParticipantList)
415	{
416		LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id);
417		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true,false);
418	}
419}
420
421
422LLPanelAdHocControlPanel::LLPanelAdHocControlPanel(const LLUUID& session_id):LLPanelGroupControlPanel(session_id)
423{
424}
425
426BOOL LLPanelAdHocControlPanel::postBuild()
427{
428	//We don't need LLPanelGroupControlPanel::postBuild() to be executed as there is no group_info_btn at AdHoc chat
429	return LLPanelChatControlPanel::postBuild();
430}
431