PageRenderTime 310ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/newview/llfloaterscriptlimits.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1361 lines | 1030 code | 222 blank | 109 comment | 130 complexity | 7e720e4ff4c36289332954d15c8af9c0 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llfloaterscriptlimits.cpp
  3. * @author Gabriel Lee
  4. * @brief Implementation of the region info and controls floater and panels.
  5. *
  6. * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #include "llviewerprecompiledheaders.h"
  28. #include "llfloaterscriptlimits.h"
  29. // library includes
  30. #include "llavatarnamecache.h"
  31. #include "llsdutil.h"
  32. #include "llsdutil_math.h"
  33. #include "message.h"
  34. #include "llagent.h"
  35. #include "llfloateravatarpicker.h"
  36. #include "llfloaterland.h"
  37. #include "llfloaterreg.h"
  38. #include "llregionhandle.h"
  39. #include "llscrolllistctrl.h"
  40. #include "llscrolllistitem.h"
  41. #include "llparcel.h"
  42. #include "lltabcontainer.h"
  43. #include "lltracker.h"
  44. #include "lltrans.h"
  45. #include "llviewercontrol.h"
  46. #include "lluictrlfactory.h"
  47. #include "llviewerparcelmgr.h"
  48. #include "llviewerregion.h"
  49. #include "llviewerwindow.h"
  50. ///----------------------------------------------------------------------------
  51. /// LLFloaterScriptLimits
  52. ///----------------------------------------------------------------------------
  53. // debug switches, won't work in release
  54. #ifndef LL_RELEASE_FOR_DOWNLOAD
  55. // dump responder replies to llinfos for debugging
  56. //#define DUMP_REPLIES_TO_LLINFOS
  57. #ifdef DUMP_REPLIES_TO_LLINFOS
  58. #include "llsdserialize.h"
  59. #include "llwindow.h"
  60. #endif
  61. // use fake LLSD responses to check the viewer side is working correctly
  62. // I'm syncing this with the server side efforts so hopfully we can keep
  63. // the to-ing and fro-ing between the two teams to a minimum
  64. //#define USE_FAKE_RESPONSES
  65. #ifdef USE_FAKE_RESPONSES
  66. const S32 FAKE_NUMBER_OF_URLS = 329;
  67. const S32 FAKE_AVAILABLE_URLS = 731;
  68. const S32 FAKE_AMOUNT_OF_MEMORY = 66741;
  69. const S32 FAKE_AVAILABLE_MEMORY = 895577;
  70. #endif
  71. #endif
  72. const S32 SIZE_OF_ONE_KB = 1024;
  73. LLFloaterScriptLimits::LLFloaterScriptLimits(const LLSD& seed)
  74. : LLFloater(seed)
  75. {
  76. }
  77. BOOL LLFloaterScriptLimits::postBuild()
  78. {
  79. // a little cheap and cheerful - if there's an about land panel open default to showing parcel info,
  80. // otherwise default to showing attachments (avatar appearance)
  81. bool selectParcelPanel = false;
  82. LLFloaterLand* instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
  83. if(instance)
  84. {
  85. if(instance->isShown())
  86. {
  87. selectParcelPanel = true;
  88. }
  89. }
  90. mTab = getChild<LLTabContainer>("scriptlimits_panels");
  91. if(!mTab)
  92. {
  93. llwarns << "Error! couldn't get scriptlimits_panels, aborting Script Information setup" << llendl;
  94. return FALSE;
  95. }
  96. // contruct the panels
  97. std::string land_url = gAgent.getRegion()->getCapability("LandResources");
  98. if (!land_url.empty())
  99. {
  100. LLPanelScriptLimitsRegionMemory* panel_memory;
  101. panel_memory = new LLPanelScriptLimitsRegionMemory;
  102. mInfoPanels.push_back(panel_memory);
  103. panel_memory->buildFromFile( "panel_script_limits_region_memory.xml");
  104. mTab->addTabPanel(panel_memory);
  105. }
  106. std::string attachment_url = gAgent.getRegion()->getCapability("AttachmentResources");
  107. if (!attachment_url.empty())
  108. {
  109. LLPanelScriptLimitsAttachment* panel_attachments = new LLPanelScriptLimitsAttachment;
  110. mInfoPanels.push_back(panel_attachments);
  111. panel_attachments->buildFromFile("panel_script_limits_my_avatar.xml");
  112. mTab->addTabPanel(panel_attachments);
  113. }
  114. if(mInfoPanels.size() > 0)
  115. {
  116. mTab->selectTab(0);
  117. }
  118. if(!selectParcelPanel && (mInfoPanels.size() > 1))
  119. {
  120. mTab->selectTab(1);
  121. }
  122. return TRUE;
  123. }
  124. LLFloaterScriptLimits::~LLFloaterScriptLimits()
  125. {
  126. }
  127. // public
  128. void LLFloaterScriptLimits::refresh()
  129. {
  130. for(info_panels_t::iterator iter = mInfoPanels.begin();
  131. iter != mInfoPanels.end(); ++iter)
  132. {
  133. (*iter)->refresh();
  134. }
  135. }
  136. ///----------------------------------------------------------------------------
  137. // Base class for panels
  138. ///----------------------------------------------------------------------------
  139. LLPanelScriptLimitsInfo::LLPanelScriptLimitsInfo()
  140. : LLPanel()
  141. {
  142. }
  143. // virtual
  144. BOOL LLPanelScriptLimitsInfo::postBuild()
  145. {
  146. refresh();
  147. return TRUE;
  148. }
  149. // virtual
  150. void LLPanelScriptLimitsInfo::updateChild(LLUICtrl* child_ctr)
  151. {
  152. }
  153. ///----------------------------------------------------------------------------
  154. // Responders
  155. ///----------------------------------------------------------------------------
  156. void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content)
  157. {
  158. //we don't need to test with a fake respose here (shouldn't anyway)
  159. #ifdef DUMP_REPLIES_TO_LLINFOS
  160. LLSDNotationStreamer notation_streamer(content);
  161. std::ostringstream nice_llsd;
  162. nice_llsd << notation_streamer;
  163. OSMessageBox(nice_llsd.str(), "main cap response:", 0);
  164. llinfos << "main cap response:" << content << llendl;
  165. #endif
  166. // at this point we have an llsd which should contain ether one or two urls to the services we want.
  167. // first we look for the details service:
  168. if(content.has("ScriptResourceDetails"))
  169. {
  170. LLHTTPClient::get(content["ScriptResourceDetails"], new fetchScriptLimitsRegionDetailsResponder(mInfo));
  171. }
  172. else
  173. {
  174. LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
  175. if(!instance)
  176. {
  177. llwarns << "Failed to get llfloaterscriptlimits instance" << llendl;
  178. }
  179. }
  180. // then the summary service:
  181. if(content.has("ScriptResourceSummary"))
  182. {
  183. LLHTTPClient::get(content["ScriptResourceSummary"], new fetchScriptLimitsRegionSummaryResponder(mInfo));
  184. }
  185. }
  186. void fetchScriptLimitsRegionInfoResponder::error(U32 status, const std::string& reason)
  187. {
  188. llwarns << "Error from responder " << reason << llendl;
  189. }
  190. void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
  191. {
  192. #ifdef USE_FAKE_RESPONSES
  193. LLSD fake_content;
  194. LLSD summary = LLSD::emptyMap();
  195. LLSD available = LLSD::emptyArray();
  196. LLSD available_urls = LLSD::emptyMap();
  197. LLSD available_memory = LLSD::emptyMap();
  198. LLSD used = LLSD::emptyArray();
  199. LLSD used_urls = LLSD::emptyMap();
  200. LLSD used_memory = LLSD::emptyMap();
  201. used_urls["type"] = "urls";
  202. used_urls["amount"] = FAKE_NUMBER_OF_URLS;
  203. available_urls["type"] = "urls";
  204. available_urls["amount"] = FAKE_AVAILABLE_URLS;
  205. used_memory["type"] = "memory";
  206. used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY;
  207. available_memory["type"] = "memory";
  208. available_memory["amount"] = FAKE_AVAILABLE_MEMORY;
  209. //summary response:{'summary':{'available':[{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'},{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'}],'used':[{'amount':i329,'type':'urls'},{'amount':i66741,'type':'memory'}]}}
  210. used.append(used_urls);
  211. used.append(used_memory);
  212. available.append(available_urls);
  213. available.append(available_memory);
  214. summary["available"] = available;
  215. summary["used"] = used;
  216. fake_content["summary"] = summary;
  217. const LLSD& content = fake_content;
  218. #else
  219. const LLSD& content = content_ref;
  220. #endif
  221. #ifdef DUMP_REPLIES_TO_LLINFOS
  222. LLSDNotationStreamer notation_streamer(content);
  223. std::ostringstream nice_llsd;
  224. nice_llsd << notation_streamer;
  225. OSMessageBox(nice_llsd.str(), "summary response:", 0);
  226. llwarns << "summary response:" << *content << llendl;
  227. #endif
  228. LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
  229. if(!instance)
  230. {
  231. llwarns << "Failed to get llfloaterscriptlimits instance" << llendl;
  232. }
  233. else
  234. {
  235. LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
  236. if(tab)
  237. {
  238. LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
  239. if(panel_memory)
  240. {
  241. panel_memory->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
  242. LLButton* btn = panel_memory->getChild<LLButton>("refresh_list_btn");
  243. if(btn)
  244. {
  245. btn->setEnabled(true);
  246. }
  247. panel_memory->setRegionSummary(content);
  248. }
  249. }
  250. }
  251. }
  252. void fetchScriptLimitsRegionSummaryResponder::error(U32 status, const std::string& reason)
  253. {
  254. llwarns << "Error from responder " << reason << llendl;
  255. }
  256. void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref)
  257. {
  258. #ifdef USE_FAKE_RESPONSES
  259. /*
  260. Updated detail service, ** denotes field added:
  261. result (map)
  262. +-parcels (array of maps)
  263. +-id (uuid)
  264. +-local_id (S32)**
  265. +-name (string)
  266. +-owner_id (uuid) (in ERS as owner, but owner_id in code)
  267. +-objects (array of maps)
  268. +-id (uuid)
  269. +-name (string)
  270. +-owner_id (uuid) (in ERS as owner, in code as owner_id)
  271. +-owner_name (sting)**
  272. +-location (map)**
  273. +-x (float)
  274. +-y (float)
  275. +-z (float)
  276. +-resources (map) (this is wrong in the ERS but right in code)
  277. +-type (string)
  278. +-amount (int)
  279. */
  280. LLSD fake_content;
  281. LLSD resource = LLSD::emptyMap();
  282. LLSD location = LLSD::emptyMap();
  283. LLSD object = LLSD::emptyMap();
  284. LLSD objects = LLSD::emptyArray();
  285. LLSD parcel = LLSD::emptyMap();
  286. LLSD parcels = LLSD::emptyArray();
  287. resource["urls"] = FAKE_NUMBER_OF_URLS;
  288. resource["memory"] = FAKE_AMOUNT_OF_MEMORY;
  289. location["x"] = 128.0f;
  290. location["y"] = 128.0f;
  291. location["z"] = 0.0f;
  292. object["id"] = LLUUID("d574a375-0c6c-fe3d-5733-da669465afc7");
  293. object["name"] = "Gabs fake Object!";
  294. object["owner_id"] = LLUUID("8dbf2d41-69a0-4e5e-9787-0c9d297bc570");
  295. object["owner_name"] = "Gabs Linden";
  296. object["location"] = location;
  297. object["resources"] = resource;
  298. objects.append(object);
  299. parcel["id"] = LLUUID("da05fb28-0d20-e593-2728-bddb42dd0160");
  300. parcel["local_id"] = 42;
  301. parcel["name"] = "Gabriel Linden\'s Sub Plot";
  302. parcel["objects"] = objects;
  303. parcels.append(parcel);
  304. fake_content["parcels"] = parcels;
  305. const LLSD& content = fake_content;
  306. #else
  307. const LLSD& content = content_ref;
  308. #endif
  309. #ifdef DUMP_REPLIES_TO_LLINFOS
  310. LLSDNotationStreamer notation_streamer(content);
  311. std::ostringstream nice_llsd;
  312. nice_llsd << notation_streamer;
  313. OSMessageBox(nice_llsd.str(), "details response:", 0);
  314. llinfos << "details response:" << content << llendl;
  315. #endif
  316. LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
  317. if(!instance)
  318. {
  319. llwarns << "Failed to get llfloaterscriptlimits instance" << llendl;
  320. }
  321. else
  322. {
  323. LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
  324. if(tab)
  325. {
  326. LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
  327. if(panel_memory)
  328. {
  329. panel_memory->setRegionDetails(content);
  330. }
  331. else
  332. {
  333. llwarns << "Failed to get scriptlimits memory panel" << llendl;
  334. }
  335. }
  336. else
  337. {
  338. llwarns << "Failed to get scriptlimits_panels" << llendl;
  339. }
  340. }
  341. }
  342. void fetchScriptLimitsRegionDetailsResponder::error(U32 status, const std::string& reason)
  343. {
  344. llwarns << "Error from responder " << reason << llendl;
  345. }
  346. void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)
  347. {
  348. #ifdef USE_FAKE_RESPONSES
  349. // just add the summary, as that's all I'm testing currently!
  350. LLSD fake_content = LLSD::emptyMap();
  351. LLSD summary = LLSD::emptyMap();
  352. LLSD available = LLSD::emptyArray();
  353. LLSD available_urls = LLSD::emptyMap();
  354. LLSD available_memory = LLSD::emptyMap();
  355. LLSD used = LLSD::emptyArray();
  356. LLSD used_urls = LLSD::emptyMap();
  357. LLSD used_memory = LLSD::emptyMap();
  358. used_urls["type"] = "urls";
  359. used_urls["amount"] = FAKE_NUMBER_OF_URLS;
  360. available_urls["type"] = "urls";
  361. available_urls["amount"] = FAKE_AVAILABLE_URLS;
  362. used_memory["type"] = "memory";
  363. used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY;
  364. available_memory["type"] = "memory";
  365. available_memory["amount"] = FAKE_AVAILABLE_MEMORY;
  366. used.append(used_urls);
  367. used.append(used_memory);
  368. available.append(available_urls);
  369. available.append(available_memory);
  370. summary["available"] = available;
  371. summary["used"] = used;
  372. fake_content["summary"] = summary;
  373. fake_content["attachments"] = content_ref["attachments"];
  374. const LLSD& content = fake_content;
  375. #else
  376. const LLSD& content = content_ref;
  377. #endif
  378. #ifdef DUMP_REPLIES_TO_LLINFOS
  379. LLSDNotationStreamer notation_streamer(content);
  380. std::ostringstream nice_llsd;
  381. nice_llsd << notation_streamer;
  382. OSMessageBox(nice_llsd.str(), "attachment response:", 0);
  383. llinfos << "attachment response:" << content << llendl;
  384. #endif
  385. LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
  386. if(!instance)
  387. {
  388. llwarns << "Failed to get llfloaterscriptlimits instance" << llendl;
  389. }
  390. else
  391. {
  392. LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
  393. if(tab)
  394. {
  395. LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel");
  396. if(panel)
  397. {
  398. panel->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
  399. LLButton* btn = panel->getChild<LLButton>("refresh_list_btn");
  400. if(btn)
  401. {
  402. btn->setEnabled(true);
  403. }
  404. panel->setAttachmentDetails(content);
  405. }
  406. else
  407. {
  408. llwarns << "Failed to get script_limits_my_avatar_panel" << llendl;
  409. }
  410. }
  411. else
  412. {
  413. llwarns << "Failed to get scriptlimits_panels" << llendl;
  414. }
  415. }
  416. }
  417. void fetchScriptLimitsAttachmentInfoResponder::error(U32 status, const std::string& reason)
  418. {
  419. llwarns << "Error from responder " << reason << llendl;
  420. }
  421. ///----------------------------------------------------------------------------
  422. // Memory Panel
  423. ///----------------------------------------------------------------------------
  424. LLPanelScriptLimitsRegionMemory::~LLPanelScriptLimitsRegionMemory()
  425. {
  426. if(!mParcelId.isNull())
  427. {
  428. LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
  429. mParcelId.setNull();
  430. }
  431. };
  432. BOOL LLPanelScriptLimitsRegionMemory::getLandScriptResources()
  433. {
  434. LLSD body;
  435. std::string url = gAgent.getRegion()->getCapability("LandResources");
  436. if (!url.empty())
  437. {
  438. body["parcel_id"] = mParcelId;
  439. LLSD info;
  440. info["parcel_id"] = mParcelId;
  441. LLHTTPClient::post(url, body, new fetchScriptLimitsRegionInfoResponder(info));
  442. return TRUE;
  443. }
  444. else
  445. {
  446. return FALSE;
  447. }
  448. }
  449. void LLPanelScriptLimitsRegionMemory::processParcelInfo(const LLParcelData& parcel_data)
  450. {
  451. if(!getLandScriptResources())
  452. {
  453. std::string msg_error = LLTrans::getString("ScriptLimitsRequestError");
  454. getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_error));
  455. }
  456. else
  457. {
  458. std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
  459. getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
  460. }
  461. }
  462. void LLPanelScriptLimitsRegionMemory::setParcelID(const LLUUID& parcel_id)
  463. {
  464. if (!parcel_id.isNull())
  465. {
  466. if(!mParcelId.isNull())
  467. {
  468. LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
  469. mParcelId.setNull();
  470. }
  471. mParcelId = parcel_id;
  472. LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this);
  473. LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id);
  474. }
  475. else
  476. {
  477. std::string msg_error = LLTrans::getString("ScriptLimitsRequestError");
  478. getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_error));
  479. }
  480. }
  481. // virtual
  482. void LLPanelScriptLimitsRegionMemory::setErrorStatus(U32 status, const std::string& reason)
  483. {
  484. llwarns << "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<llendl;
  485. }
  486. // callback from the name cache with an owner name to add to the list
  487. void LLPanelScriptLimitsRegionMemory::onNameCache(
  488. const LLUUID& id,
  489. const std::string& full_name)
  490. {
  491. LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
  492. if(!list)
  493. {
  494. return;
  495. }
  496. std::string name;
  497. if (LLAvatarNameCache::useDisplayNames())
  498. {
  499. name = LLCacheName::buildUsername(full_name);
  500. }
  501. else
  502. {
  503. name = full_name;
  504. }
  505. std::vector<LLSD>::iterator id_itor;
  506. for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor)
  507. {
  508. LLSD element = *id_itor;
  509. if(element["owner_id"].asUUID() == id)
  510. {
  511. LLScrollListItem* item = list->getItem(element["id"].asUUID());
  512. if(item)
  513. {
  514. item->getColumn(3)->setValue(LLSD(name));
  515. element["columns"][3]["value"] = name;
  516. }
  517. }
  518. }
  519. }
  520. void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
  521. {
  522. LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
  523. if(!list)
  524. {
  525. llwarns << "Error getting the scripts_list control" << llendl;
  526. return;
  527. }
  528. S32 number_parcels = content["parcels"].size();
  529. LLStringUtil::format_map_t args_parcels;
  530. args_parcels["[PARCELS]"] = llformat ("%d", number_parcels);
  531. std::string msg_parcels = LLTrans::getString("ScriptLimitsParcelsOwned", args_parcels);
  532. getChild<LLUICtrl>("parcels_listed")->setValue(LLSD(msg_parcels));
  533. uuid_vec_t names_requested;
  534. // This makes the assumption that all objects will have the same set
  535. // of attributes, ie they will all have, or none will have locations
  536. // This is a pretty safe assumption as it's reliant on server version.
  537. bool has_locations = false;
  538. bool has_local_ids = false;
  539. for(S32 i = 0; i < number_parcels; i++)
  540. {
  541. std::string parcel_name = content["parcels"][i]["name"].asString();
  542. LLUUID parcel_id = content["parcels"][i]["id"].asUUID();
  543. S32 number_objects = content["parcels"][i]["objects"].size();
  544. S32 local_id = 0;
  545. if(content["parcels"][i].has("local_id"))
  546. {
  547. // if any locations are found flag that we can use them and turn on the highlight button
  548. has_local_ids = true;
  549. local_id = content["parcels"][i]["local_id"].asInteger();
  550. }
  551. for(S32 j = 0; j < number_objects; j++)
  552. {
  553. S32 size = content["parcels"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB;
  554. S32 urls = content["parcels"][i]["objects"][j]["resources"]["urls"].asInteger();
  555. std::string name_buf = content["parcels"][i]["objects"][j]["name"].asString();
  556. LLUUID task_id = content["parcels"][i]["objects"][j]["id"].asUUID();
  557. LLUUID owner_id = content["parcels"][i]["objects"][j]["owner_id"].asUUID();
  558. // This field may not be sent by all server versions, but it's OK if
  559. // it uses the LLSD default of false
  560. bool is_group_owned = content["parcels"][i]["objects"][j]["is_group_owned"].asBoolean();
  561. F32 location_x = 0.0f;
  562. F32 location_y = 0.0f;
  563. F32 location_z = 0.0f;
  564. if(content["parcels"][i]["objects"][j].has("location"))
  565. {
  566. // if any locations are found flag that we can use them and turn on the highlight button
  567. LLVector3 vec = ll_vector3_from_sd(content["parcels"][i]["objects"][j]["location"]);
  568. has_locations = true;
  569. location_x = vec.mV[0];
  570. location_y = vec.mV[1];
  571. location_z = vec.mV[2];
  572. }
  573. std::string owner_buf;
  574. // in the future the server will give us owner names, so see if we're there yet:
  575. if(content["parcels"][i]["objects"][j].has("owner_name"))
  576. {
  577. owner_buf = content["parcels"][i]["objects"][j]["owner_name"].asString();
  578. }
  579. // ...and if not use the slightly more painful method of disovery:
  580. else
  581. {
  582. BOOL name_is_cached;
  583. if (is_group_owned)
  584. {
  585. name_is_cached = gCacheName->getGroupName(owner_id, owner_buf);
  586. }
  587. else
  588. {
  589. name_is_cached = gCacheName->getFullName(owner_id, owner_buf); // username
  590. if (LLAvatarNameCache::useDisplayNames())
  591. {
  592. owner_buf = LLCacheName::buildUsername(owner_buf);
  593. }
  594. }
  595. if(!name_is_cached)
  596. {
  597. if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end())
  598. {
  599. names_requested.push_back(owner_id);
  600. gCacheName->get(owner_id, is_group_owned, // username
  601. boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache,
  602. this, _1, _2));
  603. }
  604. }
  605. }
  606. LLScrollListItem::Params item_params;
  607. item_params.value = task_id;
  608. LLScrollListCell::Params cell_params;
  609. cell_params.font = LLFontGL::getFontSansSerif();
  610. cell_params.column = "size";
  611. cell_params.value = size;
  612. item_params.columns.add(cell_params);
  613. cell_params.column = "urls";
  614. cell_params.value = urls;
  615. item_params.columns.add(cell_params);
  616. cell_params.column = "name";
  617. cell_params.value = name_buf;
  618. item_params.columns.add(cell_params);
  619. cell_params.column = "owner";
  620. cell_params.value = owner_buf;
  621. item_params.columns.add(cell_params);
  622. cell_params.column = "parcel";
  623. cell_params.value = parcel_name;
  624. item_params.columns.add(cell_params);
  625. cell_params.column = "location";
  626. cell_params.value = has_locations
  627. ? llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z)
  628. : "";
  629. item_params.columns.add(cell_params);
  630. list->addRow(item_params);
  631. LLSD element;
  632. element["owner_id"] = owner_id;
  633. element["id"] = task_id;
  634. element["local_id"] = local_id;
  635. mObjectListItems.push_back(element);
  636. }
  637. }
  638. if (has_locations)
  639. {
  640. LLButton* btn = getChild<LLButton>("highlight_btn");
  641. if(btn)
  642. {
  643. btn->setVisible(true);
  644. }
  645. }
  646. if (has_local_ids)
  647. {
  648. LLButton* btn = getChild<LLButton>("return_btn");
  649. if(btn)
  650. {
  651. btn->setVisible(true);
  652. }
  653. }
  654. // save the structure to make object return easier
  655. mContent = content;
  656. }
  657. void LLPanelScriptLimitsRegionMemory::setRegionSummary(LLSD content)
  658. {
  659. if(content["summary"]["used"][0]["type"].asString() == std::string("memory"))
  660. {
  661. mParcelMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB;
  662. mParcelMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB;
  663. mGotParcelMemoryUsed = true;
  664. }
  665. else if(content["summary"]["used"][1]["type"].asString() == std::string("memory"))
  666. {
  667. mParcelMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB;
  668. mParcelMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB;
  669. mGotParcelMemoryUsed = true;
  670. }
  671. else
  672. {
  673. llwarns << "summary doesn't contain memory info" << llendl;
  674. return;
  675. }
  676. if(content["summary"]["used"][0]["type"].asString() == std::string("urls"))
  677. {
  678. mParcelURLsUsed = content["summary"]["used"][0]["amount"].asInteger();
  679. mParcelURLsMax = content["summary"]["available"][0]["amount"].asInteger();
  680. mGotParcelURLsUsed = true;
  681. }
  682. else if(content["summary"]["used"][1]["type"].asString() == std::string("urls"))
  683. {
  684. mParcelURLsUsed = content["summary"]["used"][1]["amount"].asInteger();
  685. mParcelURLsMax = content["summary"]["available"][1]["amount"].asInteger();
  686. mGotParcelURLsUsed = true;
  687. }
  688. else
  689. {
  690. llwarns << "summary doesn't contain urls info" << llendl;
  691. return;
  692. }
  693. if((mParcelMemoryUsed >= 0) && (mParcelMemoryMax >= 0))
  694. {
  695. S32 parcel_memory_available = mParcelMemoryMax - mParcelMemoryUsed;
  696. LLStringUtil::format_map_t args_parcel_memory;
  697. args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed);
  698. args_parcel_memory["[MAX]"] = llformat ("%d", mParcelMemoryMax);
  699. args_parcel_memory["[AVAILABLE]"] = llformat ("%d", parcel_memory_available);
  700. std::string msg_parcel_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_parcel_memory);
  701. getChild<LLUICtrl>("memory_used")->setValue(LLSD(msg_parcel_memory));
  702. }
  703. if((mParcelURLsUsed >= 0) && (mParcelURLsMax >= 0))
  704. {
  705. S32 parcel_urls_available = mParcelURLsMax - mParcelURLsUsed;
  706. LLStringUtil::format_map_t args_parcel_urls;
  707. args_parcel_urls["[COUNT]"] = llformat ("%d", mParcelURLsUsed);
  708. args_parcel_urls["[MAX]"] = llformat ("%d", mParcelURLsMax);
  709. args_parcel_urls["[AVAILABLE]"] = llformat ("%d", parcel_urls_available);
  710. std::string msg_parcel_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_parcel_urls);
  711. getChild<LLUICtrl>("urls_used")->setValue(LLSD(msg_parcel_urls));
  712. }
  713. }
  714. BOOL LLPanelScriptLimitsRegionMemory::postBuild()
  715. {
  716. childSetAction("refresh_list_btn", onClickRefresh, this);
  717. childSetAction("highlight_btn", onClickHighlight, this);
  718. childSetAction("return_btn", onClickReturn, this);
  719. std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
  720. getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
  721. LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
  722. if(!list)
  723. {
  724. return FALSE;
  725. }
  726. //set all columns to resizable mode even if some columns will be empty
  727. for(S32 column = 0; column < list->getNumColumns(); column++)
  728. {
  729. LLScrollListColumn* columnp = list->getColumn(column);
  730. columnp->mHeader->setHasResizableElement(TRUE);
  731. }
  732. return StartRequestChain();
  733. }
  734. BOOL LLPanelScriptLimitsRegionMemory::StartRequestChain()
  735. {
  736. LLUUID region_id;
  737. LLFloaterLand* instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
  738. if(!instance)
  739. {
  740. getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
  741. //might have to do parent post build here
  742. //if not logic below could use early outs
  743. return FALSE;
  744. }
  745. LLParcel* parcel = instance->getCurrentSelectedParcel();
  746. LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  747. LLUUID current_region_id = gAgent.getRegion()->getRegionID();
  748. if ((region) && (parcel))
  749. {
  750. LLVector3 parcel_center = parcel->getCenterpoint();
  751. region_id = region->getRegionID();
  752. if(region_id != current_region_id)
  753. {
  754. std::string msg_wrong_region = LLTrans::getString("ScriptLimitsRequestWrongRegion");
  755. getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_wrong_region));
  756. return FALSE;
  757. }
  758. LLVector3d pos_global = region->getCenterGlobal();
  759. LLSD body;
  760. std::string url = region->getCapability("RemoteParcelRequest");
  761. if (!url.empty())
  762. {
  763. body["location"] = ll_sd_from_vector3(parcel_center);
  764. if (!region_id.isNull())
  765. {
  766. body["region_id"] = region_id;
  767. }
  768. if (!pos_global.isExactlyZero())
  769. {
  770. U64 region_handle = to_region_handle(pos_global);
  771. body["region_handle"] = ll_sd_from_U64(region_handle);
  772. }
  773. LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
  774. }
  775. else
  776. {
  777. llwarns << "Can't get parcel info for script information request" << region_id
  778. << ". Region: " << region->getName()
  779. << " does not support RemoteParcelRequest" << llendl;
  780. std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError");
  781. getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
  782. }
  783. }
  784. else
  785. {
  786. std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestNoParcelSelected");
  787. getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
  788. }
  789. return LLPanelScriptLimitsInfo::postBuild();
  790. }
  791. void LLPanelScriptLimitsRegionMemory::clearList()
  792. {
  793. LLCtrlListInterface *list = childGetListInterface("scripts_list");
  794. if (list)
  795. {
  796. list->operateOnAll(LLCtrlListInterface::OP_DELETE);
  797. }
  798. mGotParcelMemoryUsed = false;
  799. mGotParcelMemoryMax = false;
  800. mGotParcelURLsUsed = false;
  801. mGotParcelURLsMax = false;
  802. LLStringUtil::format_map_t args_parcel_memory;
  803. std::string msg_empty_string("");
  804. getChild<LLUICtrl>("memory_used")->setValue(LLSD(msg_empty_string));
  805. getChild<LLUICtrl>("urls_used")->setValue(LLSD(msg_empty_string));
  806. getChild<LLUICtrl>("parcels_listed")->setValue(LLSD(msg_empty_string));
  807. mObjectListItems.clear();
  808. }
  809. // static
  810. void LLPanelScriptLimitsRegionMemory::onClickRefresh(void* userdata)
  811. {
  812. LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
  813. if(instance)
  814. {
  815. LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
  816. if(tab)
  817. {
  818. LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
  819. if(panel_memory)
  820. {
  821. //To stop people from hammering the refesh button and accidentally dosing themselves - enough requests can crash the viewer!
  822. //turn the button off, then turn it on when we get a response
  823. LLButton* btn = panel_memory->getChild<LLButton>("refresh_list_btn");
  824. if(btn)
  825. {
  826. btn->setEnabled(false);
  827. }
  828. panel_memory->clearList();
  829. panel_memory->StartRequestChain();
  830. }
  831. }
  832. return;
  833. }
  834. else
  835. {
  836. llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after refresh button clicked" << llendl;
  837. return;
  838. }
  839. }
  840. void LLPanelScriptLimitsRegionMemory::showBeacon()
  841. {
  842. LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list");
  843. if (!list) return;
  844. LLScrollListItem* first_selected = list->getFirstSelected();
  845. if (!first_selected) return;
  846. std::string name = first_selected->getColumn(2)->getValue().asString();
  847. std::string pos_string = first_selected->getColumn(5)->getValue().asString();
  848. F32 x, y, z;
  849. S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z);
  850. if (matched != 3) return;
  851. LLVector3 pos_agent(x, y, z);
  852. LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
  853. std::string tooltip("");
  854. LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM);
  855. }
  856. // static
  857. void LLPanelScriptLimitsRegionMemory::onClickHighlight(void* userdata)
  858. {
  859. LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
  860. if(instance)
  861. {
  862. LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
  863. if(tab)
  864. {
  865. LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
  866. if(panel)
  867. {
  868. panel->showBeacon();
  869. }
  870. }
  871. return;
  872. }
  873. else
  874. {
  875. llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl;
  876. return;
  877. }
  878. }
  879. void LLPanelScriptLimitsRegionMemory::returnObjectsFromParcel(S32 local_id)
  880. {
  881. LLMessageSystem *msg = gMessageSystem;
  882. LLViewerRegion* region = gAgent.getRegion();
  883. if (!region) return;
  884. LLCtrlListInterface *list = childGetListInterface("scripts_list");
  885. if (!list || list->getItemCount() == 0) return;
  886. std::vector<LLSD>::iterator id_itor;
  887. bool start_message = true;
  888. for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor)
  889. {
  890. LLSD element = *id_itor;
  891. if (!list->isSelected(element["id"].asUUID()))
  892. {
  893. // Selected only
  894. continue;
  895. }
  896. if(element["local_id"].asInteger() != local_id)
  897. {
  898. // Not the parcel we are looking for
  899. continue;
  900. }
  901. if (start_message)
  902. {
  903. msg->newMessageFast(_PREHASH_ParcelReturnObjects);
  904. msg->nextBlockFast(_PREHASH_AgentData);
  905. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  906. msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
  907. msg->nextBlockFast(_PREHASH_ParcelData);
  908. msg->addS32Fast(_PREHASH_LocalID, element["local_id"].asInteger());
  909. msg->addU32Fast(_PREHASH_ReturnType, RT_LIST);
  910. start_message = false;
  911. }
  912. msg->nextBlockFast(_PREHASH_TaskIDs);
  913. msg->addUUIDFast(_PREHASH_TaskID, element["id"].asUUID());
  914. if (msg->isSendFullFast(_PREHASH_TaskIDs))
  915. {
  916. msg->sendReliable(region->getHost());
  917. start_message = true;
  918. }
  919. }
  920. if (!start_message)
  921. {
  922. msg->sendReliable(region->getHost());
  923. }
  924. }
  925. void LLPanelScriptLimitsRegionMemory::returnObjects()
  926. {
  927. if(!mContent.has("parcels"))
  928. {
  929. return;
  930. }
  931. S32 number_parcels = mContent["parcels"].size();
  932. // a message per parcel containing all objects to be returned from that parcel
  933. for(S32 i = 0; i < number_parcels; i++)
  934. {
  935. S32 local_id = 0;
  936. if(mContent["parcels"][i].has("local_id"))
  937. {
  938. local_id = mContent["parcels"][i]["local_id"].asInteger();
  939. returnObjectsFromParcel(local_id);
  940. }
  941. }
  942. onClickRefresh(NULL);
  943. }
  944. // static
  945. void LLPanelScriptLimitsRegionMemory::onClickReturn(void* userdata)
  946. {
  947. LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
  948. if(instance)
  949. {
  950. LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
  951. if(tab)
  952. {
  953. LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
  954. if(panel)
  955. {
  956. panel->returnObjects();
  957. }
  958. }
  959. return;
  960. }
  961. else
  962. {
  963. llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl;
  964. return;
  965. }
  966. }
  967. ///----------------------------------------------------------------------------
  968. // Attachment Panel
  969. ///----------------------------------------------------------------------------
  970. BOOL LLPanelScriptLimitsAttachment::requestAttachmentDetails()
  971. {
  972. LLSD body;
  973. std::string url = gAgent.getRegion()->getCapability("AttachmentResources");
  974. if (!url.empty())
  975. {
  976. LLHTTPClient::get(url, body, new fetchScriptLimitsAttachmentInfoResponder());
  977. return TRUE;
  978. }
  979. else
  980. {
  981. return FALSE;
  982. }
  983. }
  984. void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content)
  985. {
  986. LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
  987. if(!list)
  988. {
  989. return;
  990. }
  991. S32 number_attachments = content["attachments"].size();
  992. for(int i = 0; i < number_attachments; i++)
  993. {
  994. std::string humanReadableLocation = "";
  995. if(content["attachments"][i].has("location"))
  996. {
  997. std::string actualLocation = content["attachments"][i]["location"];
  998. humanReadableLocation = LLTrans::getString(actualLocation.c_str());
  999. }
  1000. S32 number_objects = content["attachments"][i]["objects"].size();
  1001. for(int j = 0; j < number_objects; j++)
  1002. {
  1003. LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID();
  1004. S32 size = 0;
  1005. if(content["attachments"][i]["objects"][j]["resources"].has("memory"))
  1006. {
  1007. size = content["attachments"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB;
  1008. }
  1009. S32 urls = 0;
  1010. if(content["attachments"][i]["objects"][j]["resources"].has("urls"))
  1011. {
  1012. urls = content["attachments"][i]["objects"][j]["resources"]["urls"].asInteger();
  1013. }
  1014. std::string name = content["attachments"][i]["objects"][j]["name"].asString();
  1015. LLSD element;
  1016. element["id"] = task_id;
  1017. element["columns"][0]["column"] = "size";
  1018. element["columns"][0]["value"] = llformat("%d", size);
  1019. element["columns"][0]["font"] = "SANSSERIF";
  1020. element["columns"][1]["column"] = "urls";
  1021. element["columns"][1]["value"] = llformat("%d", urls);
  1022. element["columns"][1]["font"] = "SANSSERIF";
  1023. element["columns"][2]["column"] = "name";
  1024. element["columns"][2]["value"] = name;
  1025. element["columns"][2]["font"] = "SANSSERIF";
  1026. element["columns"][3]["column"] = "location";
  1027. element["columns"][3]["value"] = humanReadableLocation;
  1028. element["columns"][3]["font"] = "SANSSERIF";
  1029. list->addElement(element);
  1030. }
  1031. }
  1032. setAttachmentSummary(content);
  1033. getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
  1034. LLButton* btn = getChild<LLButton>("refresh_list_btn");
  1035. if(btn)
  1036. {
  1037. btn->setEnabled(true);
  1038. }
  1039. }
  1040. BOOL LLPanelScriptLimitsAttachment::postBuild()
  1041. {
  1042. childSetAction("refresh_list_btn", onClickRefresh, this);
  1043. std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
  1044. getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
  1045. return requestAttachmentDetails();
  1046. }
  1047. void LLPanelScriptLimitsAttachment::clearList()
  1048. {
  1049. LLCtrlListInterface *list = childGetListInterface("scripts_list");
  1050. if (list)
  1051. {
  1052. list->operateOnAll(LLCtrlListInterface::OP_DELETE);
  1053. }
  1054. std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
  1055. getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
  1056. }
  1057. void LLPanelScriptLimitsAttachment::setAttachmentSummary(LLSD content)
  1058. {
  1059. if(content["summary"]["used"][0]["type"].asString() == std::string("memory"))
  1060. {
  1061. mAttachmentMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB;
  1062. mAttachmentMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB;
  1063. mGotAttachmentMemoryUsed = true;
  1064. }
  1065. else if(content["summary"]["used"][1]["type"].asString() == std::string("memory"))
  1066. {
  1067. mAttachmentMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB;
  1068. mAttachmentMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB;
  1069. mGotAttachmentMemoryUsed = true;
  1070. }
  1071. else
  1072. {
  1073. llwarns << "attachment details don't contain memory summary info" << llendl;
  1074. return;
  1075. }
  1076. if(content["summary"]["used"][0]["type"].asString() == std::string("urls"))
  1077. {
  1078. mAttachmentURLsUsed = content["summary"]["used"][0]["amount"].asInteger();
  1079. mAttachmentURLsMax = content["summary"]["available"][0]["amount"].asInteger();
  1080. mGotAttachmentURLsUsed = true;
  1081. }
  1082. else if(content["summary"]["used"][1]["type"].asString() == std::string("urls"))
  1083. {
  1084. mAttachmentURLsUsed = content["summary"]["used"][1]["amount"].asInteger();
  1085. mAttachmentURLsMax = content["summary"]["available"][1]["amount"].asInteger();
  1086. mGotAttachmentURLsUsed = true;
  1087. }
  1088. else
  1089. {
  1090. llwarns << "attachment details don't contain urls summary info" << llendl;
  1091. return;
  1092. }
  1093. if((mAttachmentMemoryUsed >= 0) && (mAttachmentMemoryMax >= 0))
  1094. {
  1095. S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed;
  1096. LLStringUtil::format_map_t args_attachment_memory;
  1097. args_attachment_memory["[COUNT]"] = llformat ("%d", mAttachmentMemoryUsed);
  1098. args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax);
  1099. args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available);
  1100. std::string msg_attachment_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_attachment_memory);
  1101. getChild<LLUICtrl>("memory_used")->setValue(LLSD(msg_attachment_memory));
  1102. }
  1103. if((mAttachmentURLsUsed >= 0) && (mAttachmentURLsMax >= 0))
  1104. {
  1105. S32 attachment_urls_available = mAttachmentURLsMax - mAttachmentURLsUsed;
  1106. LLStringUtil::format_map_t args_attachment_urls;
  1107. args_attachment_urls["[COUNT]"] = llformat ("%d", mAttachmentURLsUsed);
  1108. args_attachment_urls["[MAX]"] = llformat ("%d", mAttachmentURLsMax);
  1109. args_attachment_urls["[AVAILABLE]"] = llformat ("%d", attachment_urls_available);
  1110. std::string msg_attachment_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_attachment_urls);
  1111. getChild<LLUICtrl>("urls_used")->setValue(LLSD(msg_attachment_urls));
  1112. }
  1113. }
  1114. // static
  1115. void LLPanelScriptLimitsAttachment::onClickRefresh(void* userdata)
  1116. {
  1117. LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
  1118. if(instance)
  1119. {
  1120. LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
  1121. LLPanelScriptLimitsAttachment* panel_attachments = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel");
  1122. LLButton* btn = panel_attachments->getChild<LLButton>("refresh_list_btn");
  1123. //To stop people from hammering the refesh button and accidentally dosing themselves - enough requests can crash the viewer!
  1124. //turn the button off, then turn it on when we get a response
  1125. if(btn)
  1126. {
  1127. btn->setEnabled(false);
  1128. }
  1129. panel_attachments->clearList();
  1130. panel_attachments->requestAttachmentDetails();
  1131. return;
  1132. }
  1133. else
  1134. {
  1135. llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after refresh button clicked" << llendl;
  1136. return;
  1137. }
  1138. }