llinspectavatar.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:23k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llinspectavatar.cpp
  3.  *
  4.  * $LicenseInfo:firstyear=2009&license=viewergpl$
  5.  * 
  6.  * Copyright (c) 2009-2010, Linden Research, Inc.
  7.  * 
  8.  * Second Life Viewer Source Code
  9.  * The source code in this file ("Source Code") is provided by Linden Lab
  10.  * to you under the terms of the GNU General Public License, version 2.0
  11.  * ("GPL"), unless you have obtained a separate licensing agreement
  12.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  13.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  14.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  15.  * 
  16.  * There are special exceptions to the terms and conditions of the GPL as
  17.  * it is applied to this Source Code. View the full text of the exception
  18.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  19.  * online at
  20.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  21.  * 
  22.  * By copying, modifying or distributing this software, you acknowledge
  23.  * that you have read and understood your obligations described above,
  24.  * and agree to abide by those obligations.
  25.  * 
  26.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  27.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  28.  * COMPLETENESS OR PERFORMANCE.
  29.  * $/LicenseInfo$
  30.  */
  31. #include "llviewerprecompiledheaders.h"
  32. #include "llinspectavatar.h"
  33. // viewer files
  34. #include "llagent.h"
  35. #include "llagentdata.h"
  36. #include "llavataractions.h"
  37. #include "llavatarpropertiesprocessor.h"
  38. #include "llcallingcard.h"
  39. #include "lldateutil.h"
  40. #include "llfloaterreporter.h"
  41. #include "llfloaterworldmap.h"
  42. #include "llimview.h"
  43. #include "llinspect.h"
  44. #include "llmutelist.h"
  45. #include "llpanelblockedlist.h"
  46. #include "llstartup.h"
  47. #include "llspeakers.h"
  48. #include "llviewermenu.h"
  49. #include "llvoiceclient.h"
  50. #include "llviewerobjectlist.h"
  51. #include "lltransientfloatermgr.h"
  52. // Linden libraries
  53. #include "llfloater.h"
  54. #include "llfloaterreg.h"
  55. #include "llmenubutton.h"
  56. #include "lltooltip.h" // positionViewNearMouse()
  57. #include "lluictrl.h"
  58. #include "llavatariconctrl.h"
  59. class LLFetchAvatarData;
  60. //////////////////////////////////////////////////////////////////////////////
  61. // LLInspectAvatar
  62. //////////////////////////////////////////////////////////////////////////////
  63. // Avatar Inspector, a small information window used when clicking
  64. // on avatar names in the 2D UI and in the ambient inspector widget for
  65. // the 3D world.
  66. class LLInspectAvatar : public LLInspect, LLTransientFloater
  67. {
  68. friend class LLFloaterReg;
  69. public:
  70. // avatar_id - Avatar ID for which to show information
  71. // Inspector will be positioned relative to current mouse position
  72. LLInspectAvatar(const LLSD& avatar_id);
  73. virtual ~LLInspectAvatar();
  74. /*virtual*/ BOOL postBuild(void);
  75. // Because floater is single instance, need to re-parse data on each spawn
  76. // (for example, inspector about same avatar but in different position)
  77. /*virtual*/ void onOpen(const LLSD& avatar_id);
  78. // When closing they should close their gear menu 
  79. /*virtual*/ void onClose(bool app_quitting);
  80. // Update view based on information from avatar properties processor
  81. void processAvatarData(LLAvatarData* data);
  82. // override the inspector mouse leave so timer is only paused if 
  83. // gear menu is not open
  84. /* virtual */ void onMouseLeave(S32 x, S32 y, MASK mask);
  85. virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
  86. private:
  87. // Make network requests for all the data to display in this view.
  88. // Used on construction and if avatar id changes.
  89. void requestUpdate();
  90. // Set the volume slider to this user's current client-side volume setting,
  91. // hiding/disabling if the user is not nearby.
  92. void updateVolumeSlider();
  93. // Shows/hides moderator panel depending on voice state 
  94. void updateModeratorPanel();
  95. // Moderator ability to enable/disable voice chat for avatar
  96. void toggleSelectedVoice(bool enabled);
  97. // Button callbacks
  98. void onClickAddFriend();
  99. void onClickViewProfile();
  100. void onClickIM();
  101. void onClickCall();
  102. void onClickTeleport();
  103. void onClickInviteToGroup();
  104. void onClickPay();
  105. void onClickShare();
  106. void onToggleMute();
  107. void onClickReport();
  108. void onClickFreeze();
  109. void onClickEject();
  110. void onClickZoomIn();  
  111. void onClickFindOnMap();
  112. bool onVisibleFindOnMap();
  113. bool onVisibleFreezeEject();
  114. bool onVisibleZoomIn();
  115. void onClickMuteVolume();
  116. void onVolumeChange(const LLSD& data);
  117. bool enableMute();
  118. bool enableUnmute();
  119. // Is used to determine if "Add friend" option should be enabled in gear menu
  120. bool isNotFriend();
  121. // Callback for gCacheName to look up avatar name
  122. void nameUpdatedCallback(
  123.  const LLUUID& id,
  124.  const std::string& first,
  125.  const std::string& last,
  126.  BOOL is_group);
  127. private:
  128. LLUUID mAvatarID;
  129. // Need avatar name information to spawn friend add request
  130. std::string mAvatarName;
  131. // an in-flight request for avatar properties from LLAvatarPropertiesProcessor
  132. // is represented by this object
  133. LLFetchAvatarData* mPropertiesRequest;
  134. };
  135. //////////////////////////////////////////////////////////////////////////////
  136. // LLFetchAvatarData
  137. //////////////////////////////////////////////////////////////////////////////
  138. // This object represents a pending request for avatar properties information
  139. class LLFetchAvatarData : public LLAvatarPropertiesObserver
  140. {
  141. public:
  142. // If the inspector closes it will delete the pending request object, so the
  143. // inspector pointer will be valid for the lifetime of this object
  144. LLFetchAvatarData(const LLUUID& avatar_id, LLInspectAvatar* inspector)
  145. : mAvatarID(avatar_id),
  146. mInspector(inspector)
  147. {
  148. LLAvatarPropertiesProcessor* processor = 
  149. LLAvatarPropertiesProcessor::getInstance();
  150. // register ourselves as an observer
  151. processor->addObserver(mAvatarID, this);
  152. // send a request (duplicates will be suppressed inside the avatar
  153. // properties processor)
  154. processor->sendAvatarPropertiesRequest(mAvatarID);
  155. }
  156. ~LLFetchAvatarData()
  157. {
  158. // remove ourselves as an observer
  159. LLAvatarPropertiesProcessor::getInstance()->
  160. removeObserver(mAvatarID, this);
  161. }
  162. void processProperties(void* data, EAvatarProcessorType type)
  163. {
  164. // route the data to the inspector
  165. if (data
  166. && type == APT_PROPERTIES)
  167. {
  168. LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
  169. mInspector->processAvatarData(avatar_data);
  170. }
  171. }
  172. // Store avatar ID so we can un-register the observer on destruction
  173. LLUUID mAvatarID;
  174. LLInspectAvatar* mInspector;
  175. };
  176. LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
  177. : LLInspect( LLSD() ), // single_instance, doesn't really need key
  178. mAvatarID(), // set in onOpen()  *Note: we used to show partner's name but we dont anymore --angela 3rd Dec* 
  179. mAvatarName(),
  180. mPropertiesRequest(NULL)
  181. {
  182. mCommitCallbackRegistrar.add("InspectAvatar.ViewProfile", boost::bind(&LLInspectAvatar::onClickViewProfile, this));
  183. mCommitCallbackRegistrar.add("InspectAvatar.AddFriend", boost::bind(&LLInspectAvatar::onClickAddFriend, this));
  184. mCommitCallbackRegistrar.add("InspectAvatar.IM",
  185. boost::bind(&LLInspectAvatar::onClickIM, this));
  186. mCommitCallbackRegistrar.add("InspectAvatar.Call", boost::bind(&LLInspectAvatar::onClickCall, this));
  187. mCommitCallbackRegistrar.add("InspectAvatar.Teleport", boost::bind(&LLInspectAvatar::onClickTeleport, this));
  188. mCommitCallbackRegistrar.add("InspectAvatar.InviteToGroup", boost::bind(&LLInspectAvatar::onClickInviteToGroup, this));
  189. mCommitCallbackRegistrar.add("InspectAvatar.Pay", boost::bind(&LLInspectAvatar::onClickPay, this));
  190. mCommitCallbackRegistrar.add("InspectAvatar.Share", boost::bind(&LLInspectAvatar::onClickShare, this));
  191. mCommitCallbackRegistrar.add("InspectAvatar.ToggleMute", boost::bind(&LLInspectAvatar::onToggleMute, this));
  192. mCommitCallbackRegistrar.add("InspectAvatar.Freeze",
  193. boost::bind(&LLInspectAvatar::onClickFreeze, this));
  194. mCommitCallbackRegistrar.add("InspectAvatar.Eject",
  195. boost::bind(&LLInspectAvatar::onClickEject, this));
  196. mCommitCallbackRegistrar.add("InspectAvatar.Report", boost::bind(&LLInspectAvatar::onClickReport, this));
  197. mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap", boost::bind(&LLInspectAvatar::onClickFindOnMap, this));
  198. mCommitCallbackRegistrar.add("InspectAvatar.ZoomIn", boost::bind(&LLInspectAvatar::onClickZoomIn, this));
  199. mCommitCallbackRegistrar.add("InspectAvatar.DisableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, false));
  200. mCommitCallbackRegistrar.add("InspectAvatar.EnableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, true));
  201. mEnableCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap", boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this));
  202. mEnableCallbackRegistrar.add("InspectAvatar.VisibleFreezeEject",
  203. boost::bind(&LLInspectAvatar::onVisibleFreezeEject, this));
  204. mEnableCallbackRegistrar.add("InspectAvatar.VisibleZoomIn", 
  205. boost::bind(&LLInspectAvatar::onVisibleZoomIn, this));
  206. mEnableCallbackRegistrar.add("InspectAvatar.Gear.Enable", boost::bind(&LLInspectAvatar::isNotFriend, this));
  207. mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableCall", boost::bind(&LLAvatarActions::canCall));
  208. mEnableCallbackRegistrar.add("InspectAvatar.EnableMute", boost::bind(&LLInspectAvatar::enableMute, this));
  209. mEnableCallbackRegistrar.add("InspectAvatar.EnableUnmute", boost::bind(&LLInspectAvatar::enableUnmute, this));
  210. // can't make the properties request until the widgets are constructed
  211. // as it might return immediately, so do it in postBuild.
  212. LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
  213. LLTransientFloater::init(this);
  214. }
  215. LLInspectAvatar::~LLInspectAvatar()
  216. {
  217. // clean up any pending requests so they don't call back into a deleted
  218. // view
  219. delete mPropertiesRequest;
  220. mPropertiesRequest = NULL;
  221. LLTransientFloaterMgr::getInstance()->removeControlView(this);
  222. }
  223. /*virtual*/
  224. BOOL LLInspectAvatar::postBuild(void)
  225. {
  226. getChild<LLUICtrl>("add_friend_btn")->setCommitCallback(
  227. boost::bind(&LLInspectAvatar::onClickAddFriend, this) );
  228. getChild<LLUICtrl>("view_profile_btn")->setCommitCallback(
  229. boost::bind(&LLInspectAvatar::onClickViewProfile, this) );
  230. getChild<LLUICtrl>("mute_btn")->setCommitCallback(
  231. boost::bind(&LLInspectAvatar::onClickMuteVolume, this) );
  232. getChild<LLUICtrl>("volume_slider")->setCommitCallback(
  233. boost::bind(&LLInspectAvatar::onVolumeChange, this, _2));
  234. return TRUE;
  235. }
  236. // Multiple calls to showInstance("inspect_avatar", foo) will provide different
  237. // LLSD for foo, which we will catch here.
  238. //virtual
  239. void LLInspectAvatar::onOpen(const LLSD& data)
  240. {
  241. // Start open animation
  242. LLInspect::onOpen(data);
  243. // Extract appropriate avatar id
  244. mAvatarID = data["avatar_id"];
  245. BOOL self = mAvatarID == gAgent.getID();
  246. getChild<LLUICtrl>("gear_self_btn")->setVisible(self);
  247. getChild<LLUICtrl>("gear_btn")->setVisible(!self);
  248. // Position the inspector relative to the mouse cursor
  249. // Similar to how tooltips are positioned
  250. // See LLToolTipMgr::createToolTip
  251. if (data.has("pos"))
  252. {
  253. LLUI::positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
  254. }
  255. else
  256. {
  257. LLUI::positionViewNearMouse(this);
  258. }
  259. // can't call from constructor as widgets are not built yet
  260. requestUpdate();
  261. updateVolumeSlider();
  262. updateModeratorPanel();
  263. }
  264. // virtual
  265. void LLInspectAvatar::onClose(bool app_quitting)
  266. {  
  267.   getChild<LLMenuButton>("gear_btn")->hideMenu();
  268. }
  269. void LLInspectAvatar::requestUpdate()
  270. {
  271. // Don't make network requests when spawning from the debug menu at the
  272. // login screen (which is useful to work on the layout).
  273. if (mAvatarID.isNull())
  274. {
  275. if (LLStartUp::getStartupState() >= STATE_STARTED)
  276. {
  277. // once we're running we don't want to show the test floater
  278. // for bogus LLUUID::null links
  279. closeFloater();
  280. }
  281. return;
  282. }
  283. // Clear out old data so it doesn't flash between old and new
  284. getChild<LLUICtrl>("user_name")->setValue("");
  285. getChild<LLUICtrl>("user_subtitle")->setValue("");
  286. getChild<LLUICtrl>("user_details")->setValue("");
  287. // Make a new request for properties
  288. delete mPropertiesRequest;
  289. mPropertiesRequest = new LLFetchAvatarData(mAvatarID, this);
  290. // You can't re-add someone as a friend if they are already your friend
  291. bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL;
  292. bool is_self = (mAvatarID == gAgentID);
  293. if (is_self)
  294. {
  295. getChild<LLUICtrl>("add_friend_btn")->setVisible(false);
  296. getChild<LLUICtrl>("im_btn")->setVisible(false);
  297. }
  298. else if (is_friend)
  299. {
  300. getChild<LLUICtrl>("add_friend_btn")->setVisible(false);
  301. getChild<LLUICtrl>("im_btn")->setVisible(true);
  302. }
  303. else
  304. {
  305. getChild<LLUICtrl>("add_friend_btn")->setVisible(true);
  306. getChild<LLUICtrl>("im_btn")->setVisible(false);
  307. }
  308. // Use an avatar_icon even though the image id will come down with the
  309. // avatar properties because the avatar_icon code maintains a cache of icons
  310. // and this may result in the image being visible sooner.
  311. // *NOTE: This may generate a duplicate avatar properties request, but that
  312. // will be suppressed internally in the avatar properties processor.
  313. //remove avatar id from cache to get fresh info
  314. LLAvatarIconIDCache::getInstance()->remove(mAvatarID);
  315. childSetValue("avatar_icon", LLSD(mAvatarID) );
  316. gCacheName->get(mAvatarID, FALSE,
  317. boost::bind(&LLInspectAvatar::nameUpdatedCallback,
  318. this, _1, _2, _3, _4));
  319. }
  320. void LLInspectAvatar::processAvatarData(LLAvatarData* data)
  321. {
  322. LLStringUtil::format_map_t args;
  323. args["[BORN_ON]"] = data->born_on;
  324. args["[AGE]"] = LLDateUtil::ageFromDate(data->born_on, LLDate::now());
  325. args["[SL_PROFILE]"] = data->about_text;
  326. args["[RW_PROFILE"] = data->fl_about_text;
  327. args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(data);
  328. std::string payment_info = LLAvatarPropertiesProcessor::paymentInfo(data);
  329. args["[PAYMENTINFO]"] = payment_info;
  330. args["[COMMA]"] = (payment_info.empty() ? "" : ",");
  331. std::string subtitle = getString("Subtitle", args);
  332. getChild<LLUICtrl>("user_subtitle")->setValue( LLSD(subtitle) );
  333. std::string details = getString("Details", args);
  334. getChild<LLUICtrl>("user_details")->setValue( LLSD(details) );
  335. // Delete the request object as it has been satisfied
  336. delete mPropertiesRequest;
  337. mPropertiesRequest = NULL;
  338. }
  339. // For the avatar inspector, we only want to unpause the fade timer 
  340. // if neither the gear menu or self gear menu are open
  341. void LLInspectAvatar::onMouseLeave(S32 x, S32 y, MASK mask)
  342. {
  343. LLMenuGL* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu();
  344. LLMenuGL* gear_menu_self = getChild<LLMenuButton>("gear_self_btn")->getMenu();
  345. if ( gear_menu && gear_menu->getVisible() &&
  346.  gear_menu_self && gear_menu_self->getVisible() )
  347. {
  348. return;
  349. }
  350. if(childHasVisiblePopupMenu())
  351. {
  352. return;
  353. }
  354. mOpenTimer.unpause();
  355. }
  356. void LLInspectAvatar::updateModeratorPanel()
  357. {
  358. bool enable_moderator_panel = false;
  359.     if (LLVoiceChannel::getCurrentVoiceChannel() &&
  360. mAvatarID != gAgent.getID())
  361.     {
  362. LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
  363. if (session_id != LLUUID::null)
  364. {
  365. LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
  366. if (speaker_mgr)
  367. {
  368. LLPointer<LLSpeaker> self_speakerp = speaker_mgr->findSpeaker(gAgent.getID());
  369. LLPointer<LLSpeaker> selected_speakerp = speaker_mgr->findSpeaker(mAvatarID);
  370. if(speaker_mgr->isVoiceActive() && selected_speakerp && 
  371. selected_speakerp->isInVoiceChannel() &&
  372. ((self_speakerp && self_speakerp->mIsModerator) || gAgent.isGodlike()))
  373. {
  374. getChild<LLUICtrl>("enable_voice")->setVisible(selected_speakerp->mModeratorMutedVoice);
  375. getChild<LLUICtrl>("disable_voice")->setVisible(!selected_speakerp->mModeratorMutedVoice);
  376. enable_moderator_panel = true;
  377. }
  378. }
  379. }
  380. }
  381. if (enable_moderator_panel)
  382. {
  383. if (!getChild<LLUICtrl>("moderator_panel")->getVisible())
  384. {
  385. getChild<LLUICtrl>("moderator_panel")->setVisible(true);
  386. // stretch the floater so it can accommodate the moderator panel
  387. reshape(getRect().getWidth(), getRect().getHeight() + getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());
  388. }
  389. }
  390. else if (getChild<LLUICtrl>("moderator_panel")->getVisible())
  391. {
  392. getChild<LLUICtrl>("moderator_panel")->setVisible(false);
  393. // shrink the inspector floater back to original size
  394. reshape(getRect().getWidth(), getRect().getHeight() - getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());
  395. }
  396. }
  397. void LLInspectAvatar::toggleSelectedVoice(bool enabled)
  398. {
  399. LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
  400. LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
  401. if (speaker_mgr)
  402. {
  403. if (!gAgent.getRegion())
  404. return;
  405. std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
  406. LLSD data;
  407. data["method"] = "mute update";
  408. data["session-id"] = session_id;
  409. data["params"] = LLSD::emptyMap();
  410. data["params"]["agent_id"] = mAvatarID;
  411. data["params"]["mute_info"] = LLSD::emptyMap();
  412. // ctrl value represents ability to type, so invert
  413. data["params"]["mute_info"]["voice"] = !enabled;
  414. class MuteVoiceResponder : public LLHTTPClient::Responder
  415. {
  416. public:
  417. MuteVoiceResponder(const LLUUID& session_id)
  418. {
  419. mSessionID = session_id;
  420. }
  421. virtual void error(U32 status, const std::string& reason)
  422. {
  423. llwarns << status << ": " << reason << llendl;
  424. if ( gIMMgr )
  425. {
  426. //403 == you're not a mod
  427. //should be disabled if you're not a moderator
  428. if ( 403 == status )
  429. {
  430. gIMMgr->showSessionEventError(
  431. "mute",
  432. "not_a_moderator",
  433. mSessionID);
  434. }
  435. else
  436. {
  437. gIMMgr->showSessionEventError(
  438. "mute",
  439. "generic",
  440. mSessionID);
  441. }
  442. }
  443. }
  444. private:
  445. LLUUID mSessionID;
  446. };
  447. LLHTTPClient::post(
  448. url,
  449. data,
  450. new MuteVoiceResponder(speaker_mgr->getSessionID()));
  451. }
  452. closeFloater();
  453. }
  454. void LLInspectAvatar::updateVolumeSlider()
  455. {
  456. bool voice_enabled = gVoiceClient->getVoiceEnabled(mAvatarID);
  457. // Do not display volume slider and mute button if it 
  458. // is ourself or we are not in a voice channel together
  459. if (!voice_enabled || (mAvatarID == gAgent.getID()))
  460. {
  461. getChild<LLUICtrl>("mute_btn")->setVisible(false);
  462. getChild<LLUICtrl>("volume_slider")->setVisible(false);
  463. }
  464. else 
  465. {
  466. getChild<LLUICtrl>("mute_btn")->setVisible(true);
  467. getChild<LLUICtrl>("volume_slider")->setVisible(true);
  468. // By convention, we only display and toggle voice mutes, not all mutes
  469. bool is_muted = LLMuteList::getInstance()->
  470. isMuted(mAvatarID, LLMute::flagVoiceChat);
  471. LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
  472. bool is_linden = LLStringUtil::endsWith(mAvatarName, " Linden");
  473. mute_btn->setEnabled( !is_linden);
  474. mute_btn->setValue( is_muted );
  475. LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
  476. volume_slider->setEnabled( !is_muted );
  477. const F32 DEFAULT_VOLUME = 0.5f;
  478. F32 volume;
  479. if (is_muted)
  480. {
  481. // it's clearer to display their volume as zero
  482. volume = 0.f;
  483. }
  484. else
  485. {
  486. // actual volume
  487. volume = gVoiceClient->getUserVolume(mAvatarID);
  488. // *HACK: Voice client doesn't have any data until user actually
  489. // says something.
  490. if (volume == 0.f)
  491. {
  492. volume = DEFAULT_VOLUME;
  493. }
  494. }
  495. volume_slider->setValue( (F64)volume );
  496. }
  497. }
  498. void LLInspectAvatar::onClickMuteVolume()
  499. {
  500. // By convention, we only display and toggle voice mutes, not all mutes
  501. LLMuteList* mute_list = LLMuteList::getInstance();
  502. bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
  503. LLMute mute(mAvatarID, mAvatarName, LLMute::AGENT);
  504. if (!is_muted)
  505. {
  506. mute_list->add(mute, LLMute::flagVoiceChat);
  507. }
  508. else
  509. {
  510. mute_list->remove(mute, LLMute::flagVoiceChat);
  511. }
  512. updateVolumeSlider();
  513. }
  514. void LLInspectAvatar::onVolumeChange(const LLSD& data)
  515. {
  516. F32 volume = (F32)data.asReal();
  517. gVoiceClient->setUserVolume(mAvatarID, volume);
  518. }
  519. void LLInspectAvatar::nameUpdatedCallback(
  520. const LLUUID& id,
  521. const std::string& first,
  522. const std::string& last,
  523. BOOL is_group)
  524. {
  525. if (id == mAvatarID)
  526. {
  527. mAvatarName = first + " " + last;
  528. childSetValue("user_name", LLSD(mAvatarName) );
  529. }
  530. }
  531. void LLInspectAvatar::onClickAddFriend()
  532. {
  533. LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName);
  534. closeFloater();
  535. }
  536. void LLInspectAvatar::onClickViewProfile()
  537. {
  538. LLAvatarActions::showProfile(mAvatarID);
  539. closeFloater();
  540. }
  541. bool LLInspectAvatar::isNotFriend()
  542. {
  543. return !LLAvatarActions::isFriend(mAvatarID);
  544. }
  545. bool LLInspectAvatar::onVisibleFindOnMap()
  546. {
  547. return gAgent.isGodlike() || is_agent_mappable(mAvatarID);
  548. }
  549. bool LLInspectAvatar::onVisibleFreezeEject()
  550. {
  551. return enable_freeze_eject( LLSD(mAvatarID) );
  552. }
  553. bool LLInspectAvatar::onVisibleZoomIn()
  554. {
  555. return gObjectList.findObject(mAvatarID);
  556. }
  557. void LLInspectAvatar::onClickIM()
  558. LLAvatarActions::startIM(mAvatarID);
  559. closeFloater();
  560. }
  561. void LLInspectAvatar::onClickCall()
  562. LLAvatarActions::startCall(mAvatarID);
  563. closeFloater();
  564. }
  565. void LLInspectAvatar::onClickTeleport()
  566. {
  567. LLAvatarActions::offerTeleport(mAvatarID);
  568. closeFloater();
  569. }
  570. void LLInspectAvatar::onClickInviteToGroup()
  571. {
  572. LLAvatarActions::inviteToGroup(mAvatarID);
  573. closeFloater();
  574. }
  575. void LLInspectAvatar::onClickPay()
  576. {
  577. LLAvatarActions::pay(mAvatarID);
  578. closeFloater();
  579. }
  580. void LLInspectAvatar::onClickShare()
  581. {
  582. LLAvatarActions::share(mAvatarID);
  583. closeFloater();
  584. }
  585. void LLInspectAvatar::onToggleMute()
  586. {
  587. LLMute mute(mAvatarID, mAvatarName, LLMute::AGENT);
  588. if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
  589. {
  590. LLMuteList::getInstance()->remove(mute);
  591. }
  592. else
  593. {
  594. LLMuteList::getInstance()->add(mute);
  595. }
  596. LLPanelBlockedList::showPanelAndSelect(mute.mID);
  597. closeFloater();
  598. }
  599. void LLInspectAvatar::onClickReport()
  600. {
  601. LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName);
  602. closeFloater();
  603. }
  604. void LLInspectAvatar::onClickFreeze()
  605. {
  606. handle_avatar_freeze( LLSD(mAvatarID) );
  607. closeFloater();
  608. }
  609. void LLInspectAvatar::onClickEject()
  610. {
  611. handle_avatar_eject( LLSD(mAvatarID) );
  612. closeFloater();
  613. }
  614. void LLInspectAvatar::onClickZoomIn() 
  615. {
  616. handle_zoom_to_object(mAvatarID);
  617. closeFloater();
  618. }
  619. void LLInspectAvatar::onClickFindOnMap()
  620. {
  621. gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName);
  622. LLFloaterReg::showInstance("world_map");
  623. }
  624. bool LLInspectAvatar::enableMute()
  625. {
  626. bool is_linden = LLStringUtil::endsWith(mAvatarName, " Linden");
  627. bool is_self = mAvatarID == gAgent.getID();
  628. if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName))
  629. {
  630. return true;
  631. }
  632. else
  633. {
  634. return false;
  635. }
  636. }
  637. bool LLInspectAvatar::enableUnmute()
  638. {
  639. bool is_linden = LLStringUtil::endsWith(mAvatarName, " Linden");
  640. bool is_self = mAvatarID == gAgent.getID();
  641. if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName))
  642. {
  643. return true;
  644. }
  645. else
  646. {
  647. return false;
  648. }
  649. }
  650. //////////////////////////////////////////////////////////////////////////////
  651. // LLInspectAvatarUtil
  652. //////////////////////////////////////////////////////////////////////////////
  653. void LLInspectAvatarUtil::registerFloater()
  654. {
  655. LLFloaterReg::add("inspect_avatar", "inspect_avatar.xml",
  656.   &LLFloaterReg::build<LLInspectAvatar>);
  657. }