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

游戏引擎

开发平台:

C++ Builder

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