/indra/newview/llfloatertopobjects.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 502 lines · 354 code · 76 blank · 72 comment · 43 complexity · b858e06ea5f12daadb027593f468111f MD5 · raw file

  1. /**
  2. * @file llfloatertopobjects.cpp
  3. * @brief Shows top colliders, top scripts, etc.
  4. *
  5. * $LicenseInfo:firstyear=2005&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. #include "llviewerprecompiledheaders.h"
  27. #include "llfloatertopobjects.h"
  28. // library includes
  29. #include "message.h"
  30. #include "llavatarnamecache.h"
  31. #include "llfontgl.h"
  32. #include "llagent.h"
  33. #include "llbutton.h"
  34. #include "llfloatergodtools.h"
  35. #include "llfloaterreg.h"
  36. #include "llnotificationsutil.h"
  37. #include "llparcel.h"
  38. #include "llscrolllistctrl.h"
  39. #include "llscrolllistitem.h"
  40. #include "llscrolllistcell.h"
  41. #include "lllineeditor.h"
  42. #include "lltextbox.h"
  43. #include "lltracker.h"
  44. #include "llviewermessage.h"
  45. #include "llviewerparcelmgr.h"
  46. #include "llviewerregion.h"
  47. #include "lluictrlfactory.h"
  48. #include "llviewerwindow.h"
  49. //LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL;
  50. // Globals
  51. // const U32 TIME_STR_LENGTH = 30;
  52. /*
  53. // static
  54. void LLFloaterTopObjects::show()
  55. {
  56. if (sInstance)
  57. {
  58. sInstance->setVisibleAndFrontmost();
  59. return;
  60. }
  61. sInstance = new LLFloaterTopObjects();
  62. sInstance->center();
  63. }
  64. */
  65. LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key)
  66. : LLFloater(key),
  67. mInitialized(FALSE),
  68. mtotalScore(0.f)
  69. {
  70. mCommitCallbackRegistrar.add("TopObjects.ShowBeacon", boost::bind(&LLFloaterTopObjects::onClickShowBeacon, this));
  71. mCommitCallbackRegistrar.add("TopObjects.ReturnSelected", boost::bind(&LLFloaterTopObjects::onReturnSelected, this));
  72. mCommitCallbackRegistrar.add("TopObjects.ReturnAll", boost::bind(&LLFloaterTopObjects::onReturnAll, this));
  73. mCommitCallbackRegistrar.add("TopObjects.DisableSelected", boost::bind(&LLFloaterTopObjects::onDisableSelected, this));
  74. mCommitCallbackRegistrar.add("TopObjects.DisableAll", boost::bind(&LLFloaterTopObjects::onDisableAll, this));
  75. mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this));
  76. mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this));
  77. mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this));
  78. mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this));
  79. }
  80. LLFloaterTopObjects::~LLFloaterTopObjects()
  81. {
  82. }
  83. // virtual
  84. BOOL LLFloaterTopObjects::postBuild()
  85. {
  86. LLScrollListCtrl *objects_list = getChild<LLScrollListCtrl>("objects_list");
  87. getChild<LLUICtrl>("objects_list")->setFocus(TRUE);
  88. objects_list->setDoubleClickCallback(onDoubleClickObjectsList, this);
  89. objects_list->setCommitOnSelectionChange(TRUE);
  90. setDefaultBtn("show_beacon_btn");
  91. /*
  92. LLLineEditor* line_editor = getChild<LLLineEditor>("owner_name_editor");
  93. if (line_editor)
  94. {
  95. line_editor->setCommitOnFocusLost(FALSE);
  96. line_editor->setCommitCallback(onGetByOwnerName, this);
  97. }
  98. line_editor = getChild<LLLineEditor>("object_name_editor");
  99. if (line_editor)
  100. {
  101. line_editor->setCommitOnFocusLost(FALSE);
  102. line_editor->setCommitCallback(onGetByObjectName, this);
  103. }*/
  104. mCurrentMode = STAT_REPORT_TOP_SCRIPTS;
  105. mFlags = 0;
  106. mFilter.clear();
  107. return TRUE;
  108. }
  109. // static
  110. void LLFloaterTopObjects::setMode(U32 mode)
  111. {
  112. LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
  113. if(!instance) return;
  114. instance->mCurrentMode = mode;
  115. }
  116. // static
  117. void LLFloaterTopObjects::handle_land_reply(LLMessageSystem* msg, void** data)
  118. {
  119. LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
  120. if(!instance) return;
  121. // Make sure dialog is on screen
  122. LLFloaterReg::showInstance("top_objects");
  123. instance->handleReply(msg, data);
  124. //HACK: for some reason sometimes top scripts originally comes back
  125. //with no results even though they're there
  126. if (!instance->mObjectListIDs.size() && !instance->mInitialized)
  127. {
  128. instance->onRefresh();
  129. instance->mInitialized = TRUE;
  130. }
  131. }
  132. void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
  133. {
  134. U32 request_flags;
  135. U32 total_count;
  136. msg->getU32Fast(_PREHASH_RequestData, _PREHASH_RequestFlags, request_flags);
  137. msg->getU32Fast(_PREHASH_RequestData, _PREHASH_TotalObjectCount, total_count);
  138. msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ReportType, mCurrentMode);
  139. LLScrollListCtrl *list = getChild<LLScrollListCtrl>("objects_list");
  140. S32 block_count = msg->getNumberOfBlocks("ReportData");
  141. for (S32 block = 0; block < block_count; ++block)
  142. {
  143. U32 task_local_id;
  144. U32 time_stamp = 0;
  145. LLUUID task_id;
  146. F32 location_x, location_y, location_z;
  147. F32 score;
  148. std::string name_buf;
  149. std::string owner_buf;
  150. F32 mono_score = 0.f;
  151. bool have_extended_data = false;
  152. S32 public_urls = 0;
  153. msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block);
  154. msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block);
  155. msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationX, location_x, block);
  156. msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationY, location_y, block);
  157. msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationZ, location_z, block);
  158. msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block);
  159. msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block);
  160. msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block);
  161. if(msg->has("DataExtended"))
  162. {
  163. have_extended_data = true;
  164. msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
  165. msg->getF32("DataExtended", "MonoScore", mono_score, block);
  166. msg->getS32("DataExtended", "PublicURLs", public_urls, block);
  167. }
  168. LLSD element;
  169. element["id"] = task_id;
  170. LLSD columns;
  171. columns[0]["column"] = "score";
  172. columns[0]["value"] = llformat("%0.3f", score);
  173. columns[0]["font"] = "SANSSERIF";
  174. columns[1]["column"] = "name";
  175. columns[1]["value"] = name_buf;
  176. columns[1]["font"] = "SANSSERIF";
  177. // Owner names can have trailing spaces sent from server
  178. LLStringUtil::trim(owner_buf);
  179. if (LLAvatarNameCache::useDisplayNames())
  180. {
  181. // ...convert hard-coded name from server to a username
  182. // *TODO: Send owner_id from server and look up display name
  183. owner_buf = LLCacheName::buildUsername(owner_buf);
  184. }
  185. else
  186. {
  187. // ...just strip out legacy "Resident" name
  188. owner_buf = LLCacheName::cleanFullName(owner_buf);
  189. }
  190. columns[2]["column"] = "owner";
  191. columns[2]["value"] = owner_buf;
  192. columns[2]["font"] = "SANSSERIF";
  193. columns[3]["column"] = "location";
  194. columns[3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z);
  195. columns[3]["font"] = "SANSSERIF";
  196. columns[4]["column"] = "time";
  197. columns[4]["type"] = "date";
  198. columns[4]["value"] = LLDate((time_t)time_stamp);
  199. columns[4]["font"] = "SANSSERIF";
  200. if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS
  201. && have_extended_data)
  202. {
  203. columns[5]["column"] = "mono_time";
  204. columns[5]["value"] = llformat("%0.3f", mono_score);
  205. columns[5]["font"] = "SANSSERIF";
  206. columns[6]["column"] = "URLs";
  207. columns[6]["value"] = llformat("%d", public_urls);
  208. columns[6]["font"] = "SANSSERIF";
  209. }
  210. element["columns"] = columns;
  211. list->addElement(element);
  212. mObjectListData.append(element);
  213. mObjectListIDs.push_back(task_id);
  214. mtotalScore += score;
  215. }
  216. if (total_count == 0 && list->getItemCount() == 0)
  217. {
  218. list->setCommentText(getString("none_descriptor"));
  219. }
  220. else
  221. {
  222. list->selectFirstItem();
  223. }
  224. if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS)
  225. {
  226. setTitle(getString("top_scripts_title"));
  227. list->setColumnLabel("score", getString("scripts_score_label"));
  228. list->setColumnLabel("mono_time", getString("scripts_mono_time_label"));
  229. LLUIString format = getString("top_scripts_text");
  230. format.setArg("[COUNT]", llformat("%d", total_count));
  231. format.setArg("[TIME]", llformat("%0.1f", mtotalScore));
  232. getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
  233. }
  234. else
  235. {
  236. setTitle(getString("top_colliders_title"));
  237. list->setColumnLabel("score", getString("colliders_score_label"));
  238. list->setColumnLabel("mono_time", "");
  239. LLUIString format = getString("top_colliders_text");
  240. format.setArg("[COUNT]", llformat("%d", total_count));
  241. getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
  242. }
  243. }
  244. void LLFloaterTopObjects::onCommitObjectsList()
  245. {
  246. updateSelectionInfo();
  247. }
  248. void LLFloaterTopObjects::updateSelectionInfo()
  249. {
  250. LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
  251. if (!list) return;
  252. LLUUID object_id = list->getCurrentID();
  253. if (object_id.isNull()) return;
  254. std::string object_id_string = object_id.asString();
  255. getChild<LLUICtrl>("id_editor")->setValue(LLSD(object_id_string));
  256. LLScrollListItem* sli = list->getFirstSelected();
  257. llassert(sli);
  258. if (sli)
  259. {
  260. getChild<LLUICtrl>("object_name_editor")->setValue(sli->getColumn(1)->getValue().asString());
  261. getChild<LLUICtrl>("owner_name_editor")->setValue(sli->getColumn(2)->getValue().asString());
  262. }
  263. }
  264. // static
  265. void LLFloaterTopObjects::onDoubleClickObjectsList(void* data)
  266. {
  267. LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
  268. self->showBeacon();
  269. }
  270. // static
  271. void LLFloaterTopObjects::onClickShowBeacon()
  272. {
  273. showBeacon();
  274. }
  275. void LLFloaterTopObjects::doToObjects(int action, bool all)
  276. {
  277. LLMessageSystem *msg = gMessageSystem;
  278. LLViewerRegion* region = gAgent.getRegion();
  279. if (!region) return;
  280. LLCtrlListInterface *list = getChild<LLUICtrl>("objects_list")->getListInterface();
  281. if (!list || list->getItemCount() == 0) return;
  282. uuid_vec_t::iterator id_itor;
  283. bool start_message = true;
  284. for (id_itor = mObjectListIDs.begin(); id_itor != mObjectListIDs.end(); ++id_itor)
  285. {
  286. LLUUID task_id = *id_itor;
  287. if (!all && !list->isSelected(task_id))
  288. {
  289. // Selected only
  290. continue;
  291. }
  292. if (start_message)
  293. {
  294. if (action == ACTION_RETURN)
  295. {
  296. msg->newMessageFast(_PREHASH_ParcelReturnObjects);
  297. }
  298. else
  299. {
  300. msg->newMessageFast(_PREHASH_ParcelDisableObjects);
  301. }
  302. msg->nextBlockFast(_PREHASH_AgentData);
  303. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  304. msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
  305. msg->nextBlockFast(_PREHASH_ParcelData);
  306. msg->addS32Fast(_PREHASH_LocalID, -1); // Whole region
  307. msg->addS32Fast(_PREHASH_ReturnType, RT_NONE);
  308. start_message = false;
  309. }
  310. msg->nextBlockFast(_PREHASH_TaskIDs);
  311. msg->addUUIDFast(_PREHASH_TaskID, task_id);
  312. if (msg->isSendFullFast(_PREHASH_TaskIDs))
  313. {
  314. msg->sendReliable(region->getHost());
  315. start_message = true;
  316. }
  317. }
  318. if (!start_message)
  319. {
  320. msg->sendReliable(region->getHost());
  321. }
  322. }
  323. //static
  324. bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD& response)
  325. {
  326. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  327. LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
  328. if(!instance) return false;
  329. if (option == 0)
  330. {
  331. instance->doToObjects(ACTION_RETURN, true);
  332. }
  333. return false;
  334. }
  335. void LLFloaterTopObjects::onReturnAll()
  336. {
  337. LLNotificationsUtil::add("ReturnAllTopObjects", LLSD(), LLSD(), &callbackReturnAll);
  338. }
  339. void LLFloaterTopObjects::onReturnSelected()
  340. {
  341. doToObjects(ACTION_RETURN, false);
  342. }
  343. //static
  344. bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response)
  345. {
  346. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  347. LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
  348. if(!instance) return false;
  349. if (option == 0)
  350. {
  351. instance->doToObjects(ACTION_DISABLE, true);
  352. }
  353. return false;
  354. }
  355. void LLFloaterTopObjects::onDisableAll()
  356. {
  357. LLNotificationsUtil::add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll);
  358. }
  359. void LLFloaterTopObjects::onDisableSelected()
  360. {
  361. doToObjects(ACTION_DISABLE, false);
  362. }
  363. void LLFloaterTopObjects::clearList()
  364. {
  365. LLCtrlListInterface *list = childGetListInterface("objects_list");
  366. if (list)
  367. {
  368. list->operateOnAll(LLCtrlListInterface::OP_DELETE);
  369. }
  370. mObjectListData.clear();
  371. mObjectListIDs.clear();
  372. mtotalScore = 0.f;
  373. }
  374. void LLFloaterTopObjects::onRefresh()
  375. {
  376. U32 mode = STAT_REPORT_TOP_SCRIPTS;
  377. U32 flags = 0;
  378. std::string filter = "";
  379. mode = mCurrentMode;
  380. flags = mFlags;
  381. filter = mFilter;
  382. clearList();
  383. LLMessageSystem *msg = gMessageSystem;
  384. msg->newMessageFast(_PREHASH_LandStatRequest);
  385. msg->nextBlockFast(_PREHASH_AgentData);
  386. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
  387. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
  388. msg->nextBlockFast(_PREHASH_RequestData);
  389. msg->addU32Fast(_PREHASH_ReportType, mode);
  390. msg->addU32Fast(_PREHASH_RequestFlags, flags);
  391. msg->addStringFast(_PREHASH_Filter, filter);
  392. msg->addS32Fast(_PREHASH_ParcelLocalID, 0);
  393. msg->sendReliable(gAgent.getRegionHost());
  394. mFilter.clear();
  395. mFlags = 0;
  396. }
  397. void LLFloaterTopObjects::onGetByObjectName()
  398. {
  399. mFlags = STAT_FILTER_BY_OBJECT;
  400. mFilter = getChild<LLUICtrl>("object_name_editor")->getValue().asString();
  401. onRefresh();
  402. }
  403. void LLFloaterTopObjects::onGetByOwnerName()
  404. {
  405. mFlags = STAT_FILTER_BY_OWNER;
  406. mFilter = getChild<LLUICtrl>("owner_name_editor")->getValue().asString();
  407. onRefresh();
  408. }
  409. void LLFloaterTopObjects::showBeacon()
  410. {
  411. LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
  412. if (!list) return;
  413. LLScrollListItem* first_selected = list->getFirstSelected();
  414. if (!first_selected) return;
  415. std::string name = first_selected->getColumn(1)->getValue().asString();
  416. std::string pos_string = first_selected->getColumn(3)->getValue().asString();
  417. F32 x, y, z;
  418. S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z);
  419. if (matched != 3) return;
  420. LLVector3 pos_agent(x, y, z);
  421. LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
  422. std::string tooltip("");
  423. LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM);
  424. }