From b94d2ff4c5bd26ffe821a6f40c2bc5883ae2ebba Mon Sep 17 00:00:00 2001
From: James Cook <james@lindenlab.com>
Date: Mon, 2 Nov 2009 12:03:00 -0800
Subject: [PATCH] EXT-462 Fixed freeze/eject commands in right-click and avatar
 inspector menus

We were incorrectly only enabling them for gods.  They now properly enable
for region/land owners.
---
 indra/newview/llinspectavatar.cpp             |  37 +++++-
 indra/newview/llviewermenu.cpp                | 109 ++++++++++--------
 indra/newview/llviewermenu.h                  |   8 ++
 .../xui/en/menu_inspect_avatar_gear.xml       |   6 +-
 4 files changed, 105 insertions(+), 55 deletions(-)

diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 99580d0918..bfad2b1624 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -107,9 +107,12 @@ private:
 	void onClickPay();
 	void onClickBlock();
 	void onClickReport();
+	void onClickFreeze();
+	void onClickEject();
 	void onClickZoomIn();  
 	void onClickFindOnMap();
 	bool onVisibleFindOnMap();
+	bool onVisibleFreezeEject();
 	void onClickMuteVolume();
 	void onVolumeChange(const LLSD& data);
 	
@@ -190,11 +193,16 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
 	mCommitCallbackRegistrar.add("InspectAvatar.InviteToGroup",	boost::bind(&LLInspectAvatar::onClickInviteToGroup, this));	
 	mCommitCallbackRegistrar.add("InspectAvatar.Pay",	boost::bind(&LLInspectAvatar::onClickPay, this));	
 	mCommitCallbackRegistrar.add("InspectAvatar.Block",	boost::bind(&LLInspectAvatar::onClickBlock, this));	
+	mCommitCallbackRegistrar.add("InspectAvatar.Freeze",
+		boost::bind(&LLInspectAvatar::onClickFreeze, this));	
+	mCommitCallbackRegistrar.add("InspectAvatar.Eject",
+		boost::bind(&LLInspectAvatar::onClickEject, this));	
 	mCommitCallbackRegistrar.add("InspectAvatar.Report",	boost::bind(&LLInspectAvatar::onClickReport, this));	
 	mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap",	boost::bind(&LLInspectAvatar::onClickFindOnMap, this));	
 	mCommitCallbackRegistrar.add("InspectAvatar.ZoomIn", boost::bind(&LLInspectAvatar::onClickZoomIn, this));
 	mVisibleCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap",	boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this));	
-
+	mVisibleCallbackRegistrar.add("InspectAvatar.VisibleFreezeEject",	
+		boost::bind(&LLInspectAvatar::onVisibleFreezeEject, this));	
 
 	// can't make the properties request until the widgets are constructed
 	// as it might return immediately, so do it in postBuild.
@@ -437,13 +445,13 @@ void LLInspectAvatar::nameUpdatedCallback(
 void LLInspectAvatar::onClickAddFriend()
 {
 	LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName);
+	closeFloater();
 }
 
 void LLInspectAvatar::onClickViewProfile()
 {
-	// hide inspector when showing profile
-	setFocus(FALSE);
 	LLAvatarActions::showProfile(mAvatarID);
+	closeFloater();
 }
 
 bool LLInspectAvatar::onVisibleFindOnMap()
@@ -451,24 +459,33 @@ bool LLInspectAvatar::onVisibleFindOnMap()
 	return gAgent.isGodlike() || is_agent_mappable(mAvatarID);
 }
 
+bool LLInspectAvatar::onVisibleFreezeEject()
+{
+	return enable_freeze_eject( LLSD(mAvatarID) );
+}
+
 void LLInspectAvatar::onClickIM()
 { 
 	LLAvatarActions::startIM(mAvatarID);
+	closeFloater();
 }
 
 void LLInspectAvatar::onClickTeleport()
 {
 	LLAvatarActions::offerTeleport(mAvatarID);
+	closeFloater();
 }
 
 void LLInspectAvatar::onClickInviteToGroup()
 {
 	LLAvatarActions::inviteToGroup(mAvatarID);
+	closeFloater();
 }
 
 void LLInspectAvatar::onClickPay()
 {
 	LLAvatarActions::pay(mAvatarID);
+	closeFloater();
 }
 
 void LLInspectAvatar::onClickBlock()
@@ -476,11 +493,25 @@ void LLInspectAvatar::onClickBlock()
 	LLMute mute(mAvatarID, mAvatarName, LLMute::AGENT);
 	LLMuteList::getInstance()->add(mute);
 	LLPanelBlockedList::showPanelAndSelect(mute.mID);
+	closeFloater();
 }
 
 void LLInspectAvatar::onClickReport()
 {
 	LLFloaterReporter::showFromObject(mAvatarID);
+	closeFloater();
+}
+
+void LLInspectAvatar::onClickFreeze()
+{
+	handle_avatar_freeze( LLSD(mAvatarID) );
+	closeFloater();
+}
+
+void LLInspectAvatar::onClickEject()
+{
+	handle_avatar_eject( LLSD(mAvatarID) );
+	closeFloater();
 }
 
 void LLInspectAvatar::onClickZoomIn() 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 864cf9d57b..9da9ff5ce7 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -2963,11 +2963,20 @@ bool callback_freeze(const LLSD& notification, const LLSD& response)
 }
 
 
-class LLAvatarFreeze : public view_listener_t
+void handle_avatar_freeze(const LLSD& avatar_id)
 {
-	bool handleEvent(const LLSD& userdata)
-	{
-		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+		// Use avatar_id if available, otherwise default to right-click avatar
+		LLVOAvatar* avatar = NULL;
+		if (avatar_id.asUUID().notNull())
+		{
+			avatar = find_avatar_from_object(avatar_id.asUUID());
+		}
+		else
+		{
+			avatar = find_avatar_from_object(
+				LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+		}
+
 		if( avatar )
 		{
 			std::string fullname = avatar->getFullname();
@@ -2991,9 +3000,7 @@ class LLAvatarFreeze : public view_listener_t
 							callback_freeze);
 			}
 		}
-		return true;
-	}
-};
+}
 
 class LLAvatarVisibleDebug : public view_listener_t
 {
@@ -3003,14 +3010,6 @@ class LLAvatarVisibleDebug : public view_listener_t
 	}
 };
 
-class LLAvatarEnableDebug : public view_listener_t
-{
-	bool handleEvent(const LLSD& userdata)
-	{
-		return gAgent.isGodlike();
-	}
-};
-
 class LLAvatarDebug : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -3087,11 +3086,20 @@ bool callback_eject(const LLSD& notification, const LLSD& response)
 	return false;
 }
 
-class LLAvatarEject : public view_listener_t
+void handle_avatar_eject(const LLSD& avatar_id)
 {
-	bool handleEvent(const LLSD& userdata)
-	{
-		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+		// Use avatar_id if available, otherwise default to right-click avatar
+		LLVOAvatar* avatar = NULL;
+		if (avatar_id.asUUID().notNull())
+		{
+			avatar = find_avatar_from_object(avatar_id.asUUID());
+		}
+		else
+		{
+			avatar = find_avatar_from_object(
+				LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+		}
+
 		if( avatar )
 		{
 			LLSD payload;
@@ -3142,38 +3150,41 @@ class LLAvatarEject : public view_listener_t
 				}
 			}
 		}
-		return true;
-	}
-};
+}
 
-class LLAvatarEnableFreezeEject : public view_listener_t
+bool enable_freeze_eject(const LLSD& avatar_id)
 {
-	bool handleEvent(const LLSD& userdata)
+	// Use avatar_id if available, otherwise default to right-click avatar
+	LLVOAvatar* avatar = NULL;
+	if (avatar_id.asUUID().notNull())
 	{
-		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
-		bool new_value = (avatar != NULL);
+		avatar = find_avatar_from_object(avatar_id.asUUID());
+	}
+	else
+	{
+		avatar = find_avatar_from_object(
+			LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+	}
+	if (!avatar) return false;
 
-		if (new_value)
-		{
-			const LLVector3& pos = avatar->getPositionRegion();
-			const LLVector3d& pos_global = avatar->getPositionGlobal();
-			LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global)->getParcel();
-			LLViewerRegion* region = avatar->getRegion();
-			new_value = (region != NULL);
-						
-			if (new_value)
-			{
-				new_value = region->isOwnedSelf(pos);
-				if (!new_value || region->isOwnedGroup(pos))
-				{
-					new_value = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_ADMIN);
-				}
-			}
-		}
+	// Gods can always freeze
+	if (gAgent.isGodlike()) return true;
 
-		return new_value;
+	// Estate owners / managers can freeze
+	// Parcel owners can also freeze
+	const LLVector3& pos = avatar->getPositionRegion();
+	const LLVector3d& pos_global = avatar->getPositionGlobal();
+	LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global)->getParcel();
+	LLViewerRegion* region = avatar->getRegion();
+	if (!region) return false;
+				
+	bool new_value = region->isOwnedSelf(pos);
+	if (!new_value || region->isOwnedGroup(pos))
+	{
+		new_value = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_ADMIN);
 	}
-};
+	return new_value;
+}
 
 class LLAvatarGiveCard : public view_listener_t
 {
@@ -8021,18 +8032,18 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute");
 	view_listener_t::addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend");
 	view_listener_t::addMenu(new LLAvatarAddContact(), "Avatar.AddContact");
-	view_listener_t::addMenu(new LLAvatarFreeze(), "Avatar.Freeze");
+	commit.add("Avatar.Freeze", boost::bind(&handle_avatar_freeze, LLSD()));
 	view_listener_t::addMenu(new LLAvatarDebug(), "Avatar.Debug");
 	view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug");
-	view_listener_t::addMenu(new LLAvatarEnableDebug(), "Avatar.EnableDebug");
 	view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup");
 	view_listener_t::addMenu(new LLAvatarGiveCard(), "Avatar.GiveCard");
-	view_listener_t::addMenu(new LLAvatarEject(), "Avatar.Eject");
+	commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD()));
 	view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM");
 	view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
 	
 	view_listener_t::addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend");
-	view_listener_t::addMenu(new LLAvatarEnableFreezeEject(), "Avatar.EnableFreezeEject");
+	enable.add("Avatar.EnableFreezeEject", boost::bind(&enable_freeze_eject, _2));
+	visible.add("Avatar.EnableFreezeEject", boost::bind(&enable_freeze_eject, _2));
 
 	// Object pie menu
 	view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 6d32df2bc5..b65878b5e6 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -101,6 +101,14 @@ void handle_take_copy();
 void handle_look_at_selection(const LLSD& param);
 void handle_zoom_to_object(LLUUID object_id);
 
+// Takes avatar UUID, or if no UUID passed, uses last selected object
+void handle_avatar_freeze(const LLSD& avatar_id);
+
+// Takes avatar UUID, or if no UUID passed, uses last selected object
+void handle_avatar_eject(const LLSD& avatar_id);
+
+bool enable_freeze_eject(const LLSD& avatar_id);
+
 // Can anyone take a free copy of the object?
 // *TODO: Move to separate file
 bool anyone_copy_selection(LLSelectNode* nodep);
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
index edff1a093a..6049476a43 100644
--- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
@@ -68,7 +68,7 @@
     <menu_item_call.on_click
      function="InspectAvatar.Freeze"/>
     <menu_item_call.on_visible
-     function="IsGodCustomerService"/>
+     function="InspectAvatar.VisibleFreezeEject"/>
   </menu_item_call>
   <menu_item_call
    label="Eject"
@@ -76,13 +76,13 @@
     <menu_item_call.on_click
      function="InspectAvatar.Eject"/>
     <menu_item_call.on_visible
-     function="IsGodCustomerService"/>
+     function="InspectAvatar.VisibleFreezeEject"/>
   </menu_item_call>
   <menu_item_call
    label="Debug"
    name="debug">
     <menu_item_call.on_click
-     function="InspectAvatar.Debug"/>
+     function="Avatar.Debug"/>
     <menu_item_call.on_visible
      function="IsGodCustomerService"/>
   </menu_item_call>
-- 
GitLab