diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index bd49405f34b41bb26e37ef2e54a7303fd0cada14..143edb7c4643133145334d8bc2a2a992186445c7 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -52,6 +52,11 @@ #include "llviewerwindow.h" #include "llfloaterregioninfo.h" +#include "alavataractions.h" +#include "llavataractions.h" + +const std::string OBJECT_NOT_AVATAR_NAME = "(?\?\?) (?\?\?)"; + //LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL; // Globals @@ -72,6 +77,7 @@ void LLFloaterTopObjects::show() */ LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key) : LLFloater(key), + mObjectList(nullptr), mInitialized(FALSE), mtotalScore(0.f) { @@ -83,6 +89,10 @@ LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key) mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this)); mCommitCallbackRegistrar.add("TopObjects.GetByParcelName", boost::bind(&LLFloaterTopObjects::onGetByParcelName, this)); mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this)); + mCommitCallbackRegistrar.add("TopObjects.TeleportTo", boost::bind(&LLFloaterTopObjects::onTeleportTo, this)); + mCommitCallbackRegistrar.add("TopObjects.Profile", boost::bind(&LLFloaterTopObjects::onProfile, this)); + mCommitCallbackRegistrar.add("TopObjects.Kick", boost::bind(&LLFloaterTopObjects::onEstateKick, this)); + mCommitCallbackRegistrar.add("TopObjects.Ban", boost::bind(&LLFloaterTopObjects::onEstateBan, this)); } LLFloaterTopObjects::~LLFloaterTopObjects() @@ -92,10 +102,10 @@ LLFloaterTopObjects::~LLFloaterTopObjects() // virtual BOOL LLFloaterTopObjects::postBuild() { - LLScrollListCtrl *objects_list = getChild<LLScrollListCtrl>("objects_list"); - getChild<LLUICtrl>("objects_list")->setFocus(TRUE); - objects_list->setDoubleClickCallback(onDoubleClickObjectsList, this); - objects_list->setCommitOnSelectionChange(TRUE); + mObjectList = getChild<LLScrollListCtrl>("objects_list"); + mObjectList->setFocus(TRUE); + mObjectList->setDoubleClickCallback(onDoubleClickObjectsList, this); + mObjectList->setCommitOnSelectionChange(TRUE); setDefaultBtn("show_beacon_btn"); @@ -149,8 +159,6 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) msg->getU32Fast(_PREHASH_RequestData, _PREHASH_TotalObjectCount, total_count); msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ReportType, mCurrentMode); - LLScrollListCtrl *list = getChild<LLScrollListCtrl>("objects_list"); - S32 block_count = msg->getNumberOfBlocks("ReportData"); for (S32 block = 0; block < block_count; ++block) { @@ -244,7 +252,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) columns[column_num++]["font"] = "SANSSERIF"; } element["columns"] = columns; - list->addElement(element); + mObjectList->addElement(element); mObjectListData.append(element); mObjectListIDs.push_back(task_id); @@ -252,19 +260,19 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) mtotalScore += score; } - if (total_count == 0 && list->getItemCount() == 0) + if (total_count == 0 && mObjectList->getItemCount() == 0) { - list->setCommentText(getString("none_descriptor")); + mObjectList->setCommentText(getString("none_descriptor")); } else { - list->selectFirstItem(); + mObjectList->selectFirstItem(); } if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS) { setTitle(getString("top_scripts_title")); - list->setColumnLabel("score", getString("scripts_score_label")); + mObjectList->setColumnLabel("score", getString("scripts_score_label")); LLUIString format = getString("top_scripts_text"); total_memory /= 1024; @@ -272,15 +280,15 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) format.setArg("[COUNT]", llformat("%d", total_count)); format.setArg("[TIME]", llformat("%0.3f", mtotalScore)); getChild<LLUICtrl>("title_text")->setValue(LLSD(format)); - list->setColumnLabel("URLs", getString("URLs")); - list->setColumnLabel("memory", getString("memory")); + mObjectList->setColumnLabel("URLs", getString("URLs")); + mObjectList->setColumnLabel("memory", getString("memory")); } else { setTitle(getString("top_colliders_title")); - list->setColumnLabel("score", getString("colliders_score_label")); - list->setColumnLabel("URLs", ""); - list->setColumnLabel("memory", ""); + mObjectList->setColumnLabel("score", getString("colliders_score_label")); + mObjectList->setColumnLabel("URLs", ""); + mObjectList->setColumnLabel("memory", ""); LLUIString format = getString("top_colliders_text"); format.setArg("[COUNT]", llformat("%d", total_count)); getChild<LLUICtrl>("title_text")->setValue(LLSD(format)); @@ -301,17 +309,29 @@ void LLFloaterTopObjects::onCommitObjectsList() void LLFloaterTopObjects::updateSelectionInfo() { - LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list"); - - if (!list) return; - - LLUUID object_id = list->getCurrentID(); + LLUUID object_id = mObjectList->getCurrentID(); if (object_id.isNull()) return; + LLAvatarName av_name; + if (LLAvatarNameCache::get(object_id, &av_name)) + { + bool isAvatar = (av_name.getDisplayName() != OBJECT_NOT_AVATAR_NAME); + getChild<LLButton>("profile_btn")->setEnabled(isAvatar); + getChild<LLButton>("estate_kick_btn")->setEnabled(isAvatar && object_id != gAgentID); + getChild<LLButton>("estate_ban_btn")->setEnabled(isAvatar && object_id != gAgentID); + } + else + { + getChild<LLButton>("profile_btn")->setEnabled(FALSE); + getChild<LLButton>("estate_kick_btn")->setEnabled(FALSE); + getChild<LLButton>("estate_ban_btn")->setEnabled(FALSE); + LLAvatarNameCache::get(object_id, boost::bind(&LLFloaterTopObjects::callbackAvatarName, this, _1, _2)); + } + std::string object_id_string = object_id.asString(); getChild<LLUICtrl>("id_editor")->setValue(LLSD(object_id_string)); - LLScrollListItem* sli = list->getFirstSelected(); + LLScrollListItem* sli = mObjectList->getFirstSelected(); llassert(sli); if (sli) { @@ -341,8 +361,7 @@ void LLFloaterTopObjects::returnObjects(bool all) LLViewerRegion* region = gAgent.getRegion(); if (!region) return; - LLCtrlListInterface *list = getChild<LLUICtrl>("objects_list")->getListInterface(); - if (!list || list->getItemCount() == 0) return; + if (!mObjectList || mObjectList->getItemCount() == 0) return; uuid_vec_t::iterator id_itor; @@ -351,7 +370,7 @@ void LLFloaterTopObjects::returnObjects(bool all) for (id_itor = mObjectListIDs.begin(); id_itor != mObjectListIDs.end(); ++id_itor) { LLUUID task_id = *id_itor; - if (!all && !list->isSelected(task_id)) + if (!all && !mObjectList->isSelected(task_id)) { // Selected only continue; @@ -411,11 +430,9 @@ void LLFloaterTopObjects::onReturnSelected() void LLFloaterTopObjects::clearList() { - LLCtrlListInterface *list = childGetListInterface("objects_list"); - - if (list) + if (mObjectList) { - list->operateOnAll(LLCtrlListInterface::OP_DELETE); + mObjectList->operateOnAll(LLCtrlListInterface::OP_DELETE); } mObjectListData.clear(); @@ -489,21 +506,83 @@ void LLFloaterTopObjects::onGetByParcelName() void LLFloaterTopObjects::showBeacon() { - LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list"); - if (!list) return; + if (!mObjectList) return; - LLScrollListItem* first_selected = list->getFirstSelected(); + LLScrollListItem* first_selected = mObjectList->getFirstSelected(); if (!first_selected) return; std::string name = first_selected->getColumn(1)->getValue().asString(); std::string pos_string = first_selected->getColumn(3)->getValue().asString(); - F32 x, y, z; - S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z); - if (matched != 3) return; + LLVector3 pos_agent; + S32 count = sscanf(pos_string.c_str(), "%f %f %f", pos_agent.mV + 0, pos_agent.mV + 1, pos_agent.mV + 2); + if (count != 3) return; - LLVector3 pos_agent(x, y, z); LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); - std::string tooltip(""); - LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM); + LLTracker::trackLocation(pos_global, name, std::string(), LLTracker::LOCATION_ITEM); +} + +void LLFloaterTopObjects::onProfile() +{ + if (!mObjectList) return; + + LLScrollListItem* first_selected = mObjectList->getFirstSelected(); + if (!first_selected) return; + + auto avatar_id = first_selected->getUUID(); + LLAvatarActions::showProfile(avatar_id); +} + +void LLFloaterTopObjects::onTeleportTo() +{ + if (!mObjectList) return; + + LLScrollListItem* first_selected = mObjectList->getFirstSelected(); + if (!first_selected) return; + + std::string pos_string = first_selected->getColumn(3)->getValue().asString(); + + LLVector3 pos_agent; + S32 count = sscanf(pos_string.c_str(), "%f %f %f", pos_agent.mV + 0, pos_agent.mV + 1, pos_agent.mV + 2); + if (count != 3) return; + + gAgent.teleportViaLocation(gAgent.getPosGlobalFromAgent(pos_agent)); +} + +void LLFloaterTopObjects::onEstateKick() +{ + if (!mObjectList) return; + + LLScrollListItem* first_selected = mObjectList->getFirstSelected(); + if (!first_selected) return; + + const LLUUID& objectId = first_selected->getUUID(); + ALAvatarActions::estateKick(objectId); +} + +void LLFloaterTopObjects::onEstateBan() +{ + if (!mObjectList) return; + + LLScrollListItem* first_selected = mObjectList->getFirstSelected(); + if (!first_selected) return; + + const LLUUID& objectId = first_selected->getUUID(); + ALAvatarActions::estateBan(objectId); +} + +void LLFloaterTopObjects::callbackAvatarName(const LLUUID& avatar_id, LLAvatarName av_name) +{ + if (!mObjectList) return; + + LLScrollListItem* first_selected = mObjectList->getFirstSelected(); + if (!first_selected) return; + + if (first_selected->getUUID() == avatar_id) + { + bool isAvatar = (av_name.getDisplayName() != OBJECT_NOT_AVATAR_NAME); + getChild<LLButton>("profile_btn")->setEnabled(isAvatar); + getChild<LLButton>("estate_kick_btn")->setEnabled(isAvatar && avatar_id != gAgentID); + getChild<LLButton>("estate_ban_btn")->setEnabled(isAvatar && avatar_id != gAgentID); + } } diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h index 8c7fd41916c4973df9557ab02965172fe9c92684..c87397631a77221a04a02610395cf3ae7f7567b6 100644 --- a/indra/newview/llfloatertopobjects.h +++ b/indra/newview/llfloatertopobjects.h @@ -28,8 +28,10 @@ #define LL_LLFLOATERTOPOBJECTS_H #include "llfloater.h" +#include "llavatarname.h" class LLUICtrl; +class LLScrollListCtrl; // Bits for simulator performance query flags enum LAND_STAT_FLAGS @@ -83,6 +85,13 @@ class LLFloaterTopObjects final : public LLFloater void onReturnAll(); void onReturnSelected(); + void onTeleportTo(); + void onProfile(); + void onEstateKick(); + void onEstateBan(); + + void callbackAvatarName(const LLUUID& avatar_id, const LLAvatarName av_name); + static bool callbackReturnAll(const LLSD& notification, const LLSD& response); void onGetByOwnerName(); @@ -92,6 +101,8 @@ class LLFloaterTopObjects final : public LLFloater void showBeacon(); private: + LLScrollListCtrl* mObjectList; + std::string mMethod; LLSD mObjectListData; diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml index b82fe43e74dd0270154551011399b6f67236e081..1a084654d74c9d573d883de2dfc7bbfb580c98ec 100644 --- a/indra/newview/skins/default/xui/en/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml @@ -5,7 +5,7 @@ height="350" layout="topleft" min_height="300" - min_width="450" + min_width="545" name="top_objects" help_topic="top_objects" title="Top Objects" @@ -240,12 +240,12 @@ <button follows="bottom|right" height="22" - image_overlay="Refresh_Off" + label="Refresh" layout="topleft" name="refresh_btn" right="-8" top_pad="5" - width="23"> + width="100"> <button.commit_callback function="TopObjects.Refresh" /> </button> @@ -254,10 +254,10 @@ height="23" label="Return Selected" layout="topleft" - left="112" + left="5" top_delta="0" name="return_selected_btn" - width="130"> + width="100"> <button.commit_callback function="TopObjects.ReturnSelected" /> </button> @@ -269,8 +269,59 @@ left_pad="10" name="return_all_btn" top_delta="0" - width="130"> + width="100"> <button.commit_callback function="TopObjects.ReturnAll" /> </button> + <button + follows="bottom|left" + height="23" + label="Teleport to" + layout="topleft" + left_pad="10" + name="teleport_to_btn" + top_delta="0" + width="100"> + <button.commit_callback + function="TopObjects.TeleportTo" /> + </button> + <button + enabled="false" + follows="bottom|left" + height="23" + label="Profile" + layout="topleft" + left_pad="10" + name="profile_btn" + top_delta="0" + width="100"> + <button.commit_callback + function="TopObjects.Profile" /> + </button> + <button + enabled="false" + follows="bottom|left" + height="23" + label="Estate Kick" + layout="topleft" + left_pad="10" + name="estate_kick_btn" + top_delta="0" + width="100"> + <button.commit_callback + function="TopObjects.Kick" /> + </button> + <button + enabled="false" + follows="bottom|left" + height="23" + label="Estate Ban" + layout="topleft" + left_pad="10" + name="estate_ban_btn" + top_delta="0" + width="100"> + <button.commit_callback + function="TopObjects.Ban" /> + </button> </floater>