PageRenderTime 27ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llfloaterland.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2190 lines | 1619 code | 367 blank | 204 comment | 191 complexity | a2c4dd8b628eb57b9406d692d136107c MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llfloaterland.cpp
  3. * @brief "About Land" floater, allowing display and editing of land parcel properties.
  4. *
  5. * $LicenseInfo:firstyear=2002&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 <sstream>
  28. #include <time.h>
  29. #include "llfloaterland.h"
  30. #include "llavatarnamecache.h"
  31. #include "llfocusmgr.h"
  32. #include "llnotificationsutil.h"
  33. #include "llparcel.h"
  34. #include "message.h"
  35. #include "llagent.h"
  36. #include "llagentaccess.h"
  37. #include "llbutton.h"
  38. #include "llcheckboxctrl.h"
  39. #include "llcombobox.h"
  40. #include "llfloaterreg.h"
  41. #include "llfloateravatarpicker.h"
  42. #include "llfloaterauction.h"
  43. #include "llfloatergroups.h"
  44. #include "llfloaterscriptlimits.h"
  45. #include "llavataractions.h"
  46. #include "lllineeditor.h"
  47. #include "llnamelistctrl.h"
  48. #include "llpanellandaudio.h"
  49. #include "llpanellandmedia.h"
  50. #include "llradiogroup.h"
  51. #include "llresmgr.h" // getMonetaryString
  52. #include "llscrolllistctrl.h"
  53. #include "llscrolllistitem.h"
  54. #include "llscrolllistcell.h"
  55. #include "llselectmgr.h"
  56. #include "llslurl.h"
  57. #include "llspinctrl.h"
  58. #include "lltabcontainer.h"
  59. #include "lltextbox.h"
  60. #include "lltexturectrl.h"
  61. #include "lluiconstants.h"
  62. #include "lluictrlfactory.h"
  63. #include "llviewertexturelist.h" // LLUIImageList
  64. #include "llviewermessage.h"
  65. #include "llviewerparcelmgr.h"
  66. #include "llviewerregion.h"
  67. #include "llviewerstats.h"
  68. #include "llviewertexteditor.h"
  69. #include "llviewerwindow.h"
  70. #include "llviewercontrol.h"
  71. #include "roles_constants.h"
  72. #include "lltrans.h"
  73. #include "llgroupactions.h"
  74. static std::string OWNER_ONLINE = "0";
  75. static std::string OWNER_OFFLINE = "1";
  76. static std::string OWNER_GROUP = "2";
  77. static std::string MATURITY = "[MATURITY]";
  78. // constants used in callbacks below - syntactic sugar.
  79. static const BOOL BUY_GROUP_LAND = TRUE;
  80. static const BOOL BUY_PERSONAL_LAND = FALSE;
  81. LLPointer<LLParcelSelection> LLPanelLandGeneral::sSelectionForBuyPass = NULL;
  82. // Statics
  83. LLParcelSelectionObserver* LLFloaterLand::sObserver = NULL;
  84. S32 LLFloaterLand::sLastTab = 0;
  85. // Local classes
  86. class LLParcelSelectionObserver : public LLParcelObserver
  87. {
  88. public:
  89. virtual void changed() { LLFloaterLand::refreshAll(); }
  90. };
  91. // class needed to get full access to textbox inside checkbox, because LLCheckBoxCtrl::setLabel() has string as its argument.
  92. // It was introduced while implementing EXT-4706
  93. class LLCheckBoxWithTBAcess : public LLCheckBoxCtrl
  94. {
  95. public:
  96. LLTextBox* getTextBox()
  97. {
  98. return mLabel;
  99. }
  100. };
  101. // inserts maturity info(icon and text) into target textbox
  102. // names_floater - pointer to floater which contains strings with maturity icons filenames
  103. // str_to_parse is string in format "txt1[MATURITY]txt2" where maturity icon and text will be inserted instead of [MATURITY]
  104. void insert_maturity_into_textbox(LLTextBox* target_textbox, LLFloater* names_floater, std::string str_to_parse);
  105. //---------------------------------------------------------------------------
  106. // LLFloaterLand
  107. //---------------------------------------------------------------------------
  108. void send_parcel_select_objects(S32 parcel_local_id, U32 return_type,
  109. uuid_list_t* return_ids = NULL)
  110. {
  111. LLMessageSystem *msg = gMessageSystem;
  112. LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  113. if (!region) return;
  114. // Since new highlight will be coming in, drop any highlights
  115. // that exist right now.
  116. LLSelectMgr::getInstance()->unhighlightAll();
  117. msg->newMessageFast(_PREHASH_ParcelSelectObjects);
  118. msg->nextBlockFast(_PREHASH_AgentData);
  119. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  120. msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
  121. msg->nextBlockFast(_PREHASH_ParcelData);
  122. msg->addS32Fast(_PREHASH_LocalID, parcel_local_id);
  123. msg->addU32Fast(_PREHASH_ReturnType, return_type);
  124. // Throw all return ids into the packet.
  125. // TODO: Check for too many ids.
  126. if (return_ids)
  127. {
  128. uuid_list_t::iterator end = return_ids->end();
  129. for (uuid_list_t::iterator it = return_ids->begin();
  130. it != end;
  131. ++it)
  132. {
  133. msg->nextBlockFast(_PREHASH_ReturnIDs);
  134. msg->addUUIDFast(_PREHASH_ReturnID, (*it));
  135. }
  136. }
  137. else
  138. {
  139. // Put in a null key so that the message is complete.
  140. msg->nextBlockFast(_PREHASH_ReturnIDs);
  141. msg->addUUIDFast(_PREHASH_ReturnID, LLUUID::null);
  142. }
  143. msg->sendReliable(region->getHost());
  144. }
  145. LLParcel* LLFloaterLand::getCurrentSelectedParcel()
  146. {
  147. return mParcel->getParcel();
  148. };
  149. //static
  150. LLPanelLandObjects* LLFloaterLand::getCurrentPanelLandObjects()
  151. {
  152. LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
  153. if(land_instance)
  154. {
  155. return land_instance->mPanelObjects;
  156. }
  157. else
  158. {
  159. return NULL;
  160. }
  161. }
  162. //static
  163. LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant()
  164. {
  165. LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
  166. if(land_instance)
  167. {
  168. return land_instance->mPanelCovenant;
  169. }
  170. else
  171. {
  172. return NULL;
  173. }
  174. }
  175. // static
  176. void LLFloaterLand::refreshAll()
  177. {
  178. LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
  179. if(land_instance)
  180. {
  181. land_instance->refresh();
  182. }
  183. }
  184. void LLFloaterLand::onOpen(const LLSD& key)
  185. {
  186. // moved from triggering show instance in llviwermenu.cpp
  187. if (LLViewerParcelMgr::getInstance()->selectionEmpty())
  188. {
  189. LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal());
  190. }
  191. // Done automatically when the selected parcel's properties arrive
  192. // (and hence we have the local id).
  193. // LLViewerParcelMgr::getInstance()->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER);
  194. mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
  195. // Refresh even if not over a region so we don't get an
  196. // uninitialized dialog. The dialog is 0-region aware.
  197. refresh();
  198. }
  199. void LLFloaterLand::onVisibilityChange(const LLSD& visible)
  200. {
  201. if (!visible.asBoolean())
  202. {
  203. // Might have been showing owned objects
  204. LLSelectMgr::getInstance()->unhighlightAll();
  205. // Save which panel we had open
  206. sLastTab = mTabLand->getCurrentPanelIndex();
  207. }
  208. }
  209. LLFloaterLand::LLFloaterLand(const LLSD& seed)
  210. : LLFloater(seed)
  211. {
  212. mFactoryMap["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this);
  213. mFactoryMap["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this);
  214. mFactoryMap["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this);
  215. mFactoryMap["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this);
  216. mFactoryMap["land_audio_panel"] = LLCallbackMap(createPanelLandAudio, this);
  217. mFactoryMap["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this);
  218. mFactoryMap["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this);
  219. sObserver = new LLParcelSelectionObserver();
  220. LLViewerParcelMgr::getInstance()->addObserver( sObserver );
  221. }
  222. BOOL LLFloaterLand::postBuild()
  223. {
  224. setVisibleCallback(boost::bind(&LLFloaterLand::onVisibilityChange, this, _2));
  225. LLTabContainer* tab = getChild<LLTabContainer>("landtab");
  226. mTabLand = (LLTabContainer*) tab;
  227. if (tab)
  228. {
  229. tab->selectTab(sLastTab);
  230. }
  231. return TRUE;
  232. }
  233. // virtual
  234. LLFloaterLand::~LLFloaterLand()
  235. {
  236. LLViewerParcelMgr::getInstance()->removeObserver( sObserver );
  237. delete sObserver;
  238. sObserver = NULL;
  239. }
  240. // public
  241. void LLFloaterLand::refresh()
  242. {
  243. mPanelGeneral->refresh();
  244. mPanelObjects->refresh();
  245. mPanelOptions->refresh();
  246. mPanelAudio->refresh();
  247. mPanelMedia->refresh();
  248. mPanelAccess->refresh();
  249. mPanelCovenant->refresh();
  250. }
  251. void* LLFloaterLand::createPanelLandGeneral(void* data)
  252. {
  253. LLFloaterLand* self = (LLFloaterLand*)data;
  254. self->mPanelGeneral = new LLPanelLandGeneral(self->mParcel);
  255. return self->mPanelGeneral;
  256. }
  257. // static
  258. void* LLFloaterLand::createPanelLandCovenant(void* data)
  259. {
  260. LLFloaterLand* self = (LLFloaterLand*)data;
  261. self->mPanelCovenant = new LLPanelLandCovenant(self->mParcel);
  262. return self->mPanelCovenant;
  263. }
  264. // static
  265. void* LLFloaterLand::createPanelLandObjects(void* data)
  266. {
  267. LLFloaterLand* self = (LLFloaterLand*)data;
  268. self->mPanelObjects = new LLPanelLandObjects(self->mParcel);
  269. return self->mPanelObjects;
  270. }
  271. // static
  272. void* LLFloaterLand::createPanelLandOptions(void* data)
  273. {
  274. LLFloaterLand* self = (LLFloaterLand*)data;
  275. self->mPanelOptions = new LLPanelLandOptions(self->mParcel);
  276. return self->mPanelOptions;
  277. }
  278. // static
  279. void* LLFloaterLand::createPanelLandAudio(void* data)
  280. {
  281. LLFloaterLand* self = (LLFloaterLand*)data;
  282. self->mPanelAudio = new LLPanelLandAudio(self->mParcel);
  283. return self->mPanelAudio;
  284. }
  285. // static
  286. void* LLFloaterLand::createPanelLandMedia(void* data)
  287. {
  288. LLFloaterLand* self = (LLFloaterLand*)data;
  289. self->mPanelMedia = new LLPanelLandMedia(self->mParcel);
  290. return self->mPanelMedia;
  291. }
  292. // static
  293. void* LLFloaterLand::createPanelLandAccess(void* data)
  294. {
  295. LLFloaterLand* self = (LLFloaterLand*)data;
  296. self->mPanelAccess = new LLPanelLandAccess(self->mParcel);
  297. return self->mPanelAccess;
  298. }
  299. //---------------------------------------------------------------------------
  300. // LLPanelLandGeneral
  301. //---------------------------------------------------------------------------
  302. LLPanelLandGeneral::LLPanelLandGeneral(LLParcelSelectionHandle& parcel)
  303. : LLPanel(),
  304. mUncheckedSell(FALSE),
  305. mParcel(parcel)
  306. {
  307. }
  308. BOOL LLPanelLandGeneral::postBuild()
  309. {
  310. mEditName = getChild<LLLineEditor>("Name");
  311. mEditName->setCommitCallback(onCommitAny, this);
  312. getChild<LLLineEditor>("Name")->setPrevalidate(LLTextValidate::validateASCIIPrintableNoPipe);
  313. mEditDesc = getChild<LLTextEditor>("Description");
  314. mEditDesc->setCommitOnFocusLost(TRUE);
  315. mEditDesc->setCommitCallback(onCommitAny, this);
  316. // No prevalidate function - historically the prevalidate function was broken,
  317. // allowing residents to put in characters like U+2661 WHITE HEART SUIT, so
  318. // preserve that ability.
  319. mTextSalePending = getChild<LLTextBox>("SalePending");
  320. mTextOwnerLabel = getChild<LLTextBox>("Owner:");
  321. mTextOwner = getChild<LLTextBox>("OwnerText");
  322. mContentRating = getChild<LLTextBox>("ContentRatingText");
  323. mLandType = getChild<LLTextBox>("LandTypeText");
  324. mBtnProfile = getChild<LLButton>("Profile...");
  325. mBtnProfile->setClickedCallback(boost::bind(&LLPanelLandGeneral::onClickProfile, this));
  326. mTextGroupLabel = getChild<LLTextBox>("Group:");
  327. mTextGroup = getChild<LLTextBox>("GroupText");
  328. mBtnSetGroup = getChild<LLButton>("Set...");
  329. mBtnSetGroup->setCommitCallback(boost::bind(&LLPanelLandGeneral::onClickSetGroup, this));
  330. mCheckDeedToGroup = getChild<LLCheckBoxCtrl>( "check deed");
  331. childSetCommitCallback("check deed", onCommitAny, this);
  332. mBtnDeedToGroup = getChild<LLButton>("Deed...");
  333. mBtnDeedToGroup->setClickedCallback(onClickDeed, this);
  334. mCheckContributeWithDeed = getChild<LLCheckBoxCtrl>( "check contrib");
  335. childSetCommitCallback("check contrib", onCommitAny, this);
  336. mSaleInfoNotForSale = getChild<LLTextBox>("Not for sale.");
  337. mSaleInfoForSale1 = getChild<LLTextBox>("For Sale: Price L$[PRICE].");
  338. mBtnSellLand = getChild<LLButton>("Sell Land...");
  339. mBtnSellLand->setClickedCallback(onClickSellLand, this);
  340. mSaleInfoForSale2 = getChild<LLTextBox>("For sale to");
  341. mSaleInfoForSaleObjects = getChild<LLTextBox>("Sell with landowners objects in parcel.");
  342. mSaleInfoForSaleNoObjects = getChild<LLTextBox>("Selling with no objects in parcel.");
  343. mBtnStopSellLand = getChild<LLButton>("Cancel Land Sale");
  344. mBtnStopSellLand->setClickedCallback(onClickStopSellLand, this);
  345. mTextClaimDateLabel = getChild<LLTextBox>("Claimed:");
  346. mTextClaimDate = getChild<LLTextBox>("DateClaimText");
  347. mTextPriceLabel = getChild<LLTextBox>("PriceLabel");
  348. mTextPrice = getChild<LLTextBox>("PriceText");
  349. mTextDwell = getChild<LLTextBox>("DwellText");
  350. mBtnBuyLand = getChild<LLButton>("Buy Land...");
  351. mBtnBuyLand->setClickedCallback(onClickBuyLand, (void*)&BUY_PERSONAL_LAND);
  352. // note: on region change this will not be re checked, should not matter on Agni as
  353. // 99% of the time all regions will return the same caps. In case of an erroneous setting
  354. // to enabled the floater will just throw an error when trying to get it's cap
  355. std::string url = gAgent.getRegion()->getCapability("LandResources");
  356. if (!url.empty())
  357. {
  358. mBtnScriptLimits = getChild<LLButton>("Scripts...");
  359. if(mBtnScriptLimits)
  360. {
  361. mBtnScriptLimits->setClickedCallback(onClickScriptLimits, this);
  362. }
  363. }
  364. else
  365. {
  366. mBtnScriptLimits = getChild<LLButton>("Scripts...");
  367. if(mBtnScriptLimits)
  368. {
  369. mBtnScriptLimits->setVisible(false);
  370. }
  371. }
  372. mBtnBuyGroupLand = getChild<LLButton>("Buy For Group...");
  373. mBtnBuyGroupLand->setClickedCallback(onClickBuyLand, (void*)&BUY_GROUP_LAND);
  374. mBtnBuyPass = getChild<LLButton>("Buy Pass...");
  375. mBtnBuyPass->setClickedCallback(onClickBuyPass, this);
  376. mBtnReleaseLand = getChild<LLButton>("Abandon Land...");
  377. mBtnReleaseLand->setClickedCallback(onClickRelease, NULL);
  378. mBtnReclaimLand = getChild<LLButton>("Reclaim Land...");
  379. mBtnReclaimLand->setClickedCallback(onClickReclaim, NULL);
  380. mBtnStartAuction = getChild<LLButton>("Linden Sale...");
  381. mBtnStartAuction->setClickedCallback(onClickStartAuction, this);
  382. return TRUE;
  383. }
  384. // virtual
  385. LLPanelLandGeneral::~LLPanelLandGeneral()
  386. { }
  387. // public
  388. void LLPanelLandGeneral::refresh()
  389. {
  390. mBtnStartAuction->setVisible(gAgent.isGodlike());
  391. LLParcel *parcel = mParcel->getParcel();
  392. bool region_owner = false;
  393. LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  394. if(regionp && (regionp->getOwner() == gAgent.getID()))
  395. {
  396. region_owner = true;
  397. mBtnReleaseLand->setVisible(FALSE);
  398. mBtnReclaimLand->setVisible(TRUE);
  399. }
  400. else
  401. {
  402. mBtnReleaseLand->setVisible(TRUE);
  403. mBtnReclaimLand->setVisible(FALSE);
  404. }
  405. if (!parcel)
  406. {
  407. // nothing selected, disable panel
  408. mEditName->setEnabled(FALSE);
  409. mEditName->setText(LLStringUtil::null);
  410. mEditDesc->setEnabled(FALSE);
  411. mEditDesc->setText(getString("no_selection_text"));
  412. mTextSalePending->setText(LLStringUtil::null);
  413. mTextSalePending->setEnabled(FALSE);
  414. mBtnDeedToGroup->setEnabled(FALSE);
  415. mBtnSetGroup->setEnabled(FALSE);
  416. mBtnStartAuction->setEnabled(FALSE);
  417. mCheckDeedToGroup ->set(FALSE);
  418. mCheckDeedToGroup ->setEnabled(FALSE);
  419. mCheckContributeWithDeed->set(FALSE);
  420. mCheckContributeWithDeed->setEnabled(FALSE);
  421. mTextOwner->setText(LLStringUtil::null);
  422. mContentRating->setText(LLStringUtil::null);
  423. mLandType->setText(LLStringUtil::null);
  424. mBtnProfile->setLabel(getString("profile_text"));
  425. mBtnProfile->setEnabled(FALSE);
  426. mTextClaimDate->setText(LLStringUtil::null);
  427. mTextGroup->setText(LLStringUtil::null);
  428. mTextPrice->setText(LLStringUtil::null);
  429. mSaleInfoForSale1->setVisible(FALSE);
  430. mSaleInfoForSale2->setVisible(FALSE);
  431. mSaleInfoForSaleObjects->setVisible(FALSE);
  432. mSaleInfoForSaleNoObjects->setVisible(FALSE);
  433. mSaleInfoNotForSale->setVisible(FALSE);
  434. mBtnSellLand->setVisible(FALSE);
  435. mBtnStopSellLand->setVisible(FALSE);
  436. mTextPriceLabel->setText(LLStringUtil::null);
  437. mTextDwell->setText(LLStringUtil::null);
  438. mBtnBuyLand->setEnabled(FALSE);
  439. mBtnScriptLimits->setEnabled(FALSE);
  440. mBtnBuyGroupLand->setEnabled(FALSE);
  441. mBtnReleaseLand->setEnabled(FALSE);
  442. mBtnReclaimLand->setEnabled(FALSE);
  443. mBtnBuyPass->setEnabled(FALSE);
  444. }
  445. else
  446. {
  447. // something selected, hooray!
  448. BOOL is_leased = (LLParcel::OS_LEASED == parcel->getOwnershipStatus());
  449. BOOL region_xfer = FALSE;
  450. if(regionp
  451. && !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL))
  452. {
  453. region_xfer = TRUE;
  454. }
  455. if (regionp)
  456. {
  457. insert_maturity_into_textbox(mContentRating, gFloaterView->getParentFloater(this), MATURITY);
  458. mLandType->setText(regionp->getLocalizedSimProductName());
  459. }
  460. // estate owner/manager cannot edit other parts of the parcel
  461. BOOL estate_manager_sellable = !parcel->getAuctionID()
  462. && gAgent.canManageEstate()
  463. // estate manager/owner can only sell parcels owned by estate owner
  464. && regionp
  465. && (parcel->getOwnerID() == regionp->getOwner());
  466. BOOL owner_sellable = region_xfer && !parcel->getAuctionID()
  467. && LLViewerParcelMgr::isParcelModifiableByAgent(
  468. parcel, GP_LAND_SET_SALE_INFO);
  469. BOOL can_be_sold = owner_sellable || estate_manager_sellable;
  470. const LLUUID &owner_id = parcel->getOwnerID();
  471. BOOL is_public = parcel->isPublic();
  472. // Is it owned?
  473. if (is_public)
  474. {
  475. mTextSalePending->setText(LLStringUtil::null);
  476. mTextSalePending->setEnabled(FALSE);
  477. mTextOwner->setText(getString("public_text"));
  478. mTextOwner->setEnabled(FALSE);
  479. mBtnProfile->setEnabled(FALSE);
  480. mTextClaimDate->setText(LLStringUtil::null);
  481. mTextClaimDate->setEnabled(FALSE);
  482. mTextGroup->setText(getString("none_text"));
  483. mTextGroup->setEnabled(FALSE);
  484. mBtnStartAuction->setEnabled(FALSE);
  485. }
  486. else
  487. {
  488. if(!is_leased && (owner_id == gAgent.getID()))
  489. {
  490. mTextSalePending->setText(getString("need_tier_to_modify"));
  491. mTextSalePending->setEnabled(TRUE);
  492. }
  493. else if(parcel->getAuctionID())
  494. {
  495. mTextSalePending->setText(getString("auction_id_text"));
  496. mTextSalePending->setTextArg("[ID]", llformat("%u", parcel->getAuctionID()));
  497. mTextSalePending->setEnabled(TRUE);
  498. }
  499. else
  500. {
  501. // not the owner, or it is leased
  502. mTextSalePending->setText(LLStringUtil::null);
  503. mTextSalePending->setEnabled(FALSE);
  504. }
  505. //refreshNames();
  506. mTextOwner->setEnabled(TRUE);
  507. // We support both group and personal profiles
  508. mBtnProfile->setEnabled(TRUE);
  509. if (parcel->getGroupID().isNull())
  510. {
  511. // Not group owned, so "Profile"
  512. mBtnProfile->setLabel(getString("profile_text"));
  513. mTextGroup->setText(getString("none_text"));
  514. mTextGroup->setEnabled(FALSE);
  515. }
  516. else
  517. {
  518. // Group owned, so "Info"
  519. mBtnProfile->setLabel(getString("info_text"));
  520. //mTextGroup->setText("HIPPOS!");//parcel->getGroupName());
  521. mTextGroup->setEnabled(TRUE);
  522. }
  523. // Display claim date
  524. time_t claim_date = parcel->getClaimDate();
  525. std::string claim_date_str = getString("time_stamp_template");
  526. LLSD substitution;
  527. substitution["datetime"] = (S32) claim_date;
  528. LLStringUtil::format (claim_date_str, substitution);
  529. mTextClaimDate->setText(claim_date_str);
  530. mTextClaimDate->setEnabled(is_leased);
  531. BOOL enable_auction = (gAgent.getGodLevel() >= GOD_LIAISON)
  532. && (owner_id == GOVERNOR_LINDEN_ID)
  533. && (parcel->getAuctionID() == 0);
  534. mBtnStartAuction->setEnabled(enable_auction);
  535. }
  536. // Display options
  537. BOOL can_edit_identity = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_IDENTITY);
  538. mEditName->setEnabled(can_edit_identity);
  539. mEditDesc->setEnabled(can_edit_identity);
  540. BOOL can_edit_agent_only = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_NO_POWERS);
  541. mBtnSetGroup->setEnabled(can_edit_agent_only && !parcel->getIsGroupOwned());
  542. const LLUUID& group_id = parcel->getGroupID();
  543. // Can only allow deeding if you own it and it's got a group.
  544. BOOL enable_deed = (owner_id == gAgent.getID()
  545. && group_id.notNull()
  546. && gAgent.isInGroup(group_id));
  547. // You don't need special powers to allow your object to
  548. // be deeded to the group.
  549. mCheckDeedToGroup->setEnabled(enable_deed);
  550. mCheckDeedToGroup->set( parcel->getAllowDeedToGroup() );
  551. mCheckContributeWithDeed->setEnabled(enable_deed && parcel->getAllowDeedToGroup());
  552. mCheckContributeWithDeed->set(parcel->getContributeWithDeed());
  553. // Actually doing the deeding requires you to have GP_LAND_DEED
  554. // powers in the group.
  555. BOOL can_deed = gAgent.hasPowerInGroup(group_id, GP_LAND_DEED);
  556. mBtnDeedToGroup->setEnabled( parcel->getAllowDeedToGroup()
  557. && group_id.notNull()
  558. && can_deed
  559. && !parcel->getIsGroupOwned()
  560. );
  561. mEditName->setText( parcel->getName() );
  562. mEditDesc->setText( parcel->getDesc() );
  563. BOOL for_sale = parcel->getForSale();
  564. mBtnSellLand->setVisible(FALSE);
  565. mBtnStopSellLand->setVisible(FALSE);
  566. // show pricing information
  567. S32 area;
  568. S32 claim_price;
  569. S32 rent_price;
  570. F32 dwell = DWELL_NAN;
  571. LLViewerParcelMgr::getInstance()->getDisplayInfo(&area,
  572. &claim_price,
  573. &rent_price,
  574. &for_sale,
  575. &dwell);
  576. // Area
  577. LLUIString price = getString("area_size_text");
  578. price.setArg("[AREA]", llformat("%d",area));
  579. mTextPriceLabel->setText(getString("area_text"));
  580. mTextPrice->setText(price.getString());
  581. if (dwell == DWELL_NAN)
  582. {
  583. mTextDwell->setText(LLTrans::getString("LoadingData"));
  584. }
  585. else
  586. {
  587. mTextDwell->setText(llformat("%.0f", dwell));
  588. }
  589. if (for_sale)
  590. {
  591. mSaleInfoForSale1->setVisible(TRUE);
  592. mSaleInfoForSale2->setVisible(TRUE);
  593. if (parcel->getSellWithObjects())
  594. {
  595. mSaleInfoForSaleObjects->setVisible(TRUE);
  596. mSaleInfoForSaleNoObjects->setVisible(FALSE);
  597. }
  598. else
  599. {
  600. mSaleInfoForSaleObjects->setVisible(FALSE);
  601. mSaleInfoForSaleNoObjects->setVisible(TRUE);
  602. }
  603. mSaleInfoNotForSale->setVisible(FALSE);
  604. F32 cost_per_sqm = 0.0f;
  605. if (area > 0)
  606. {
  607. cost_per_sqm = (F32)parcel->getSalePrice() / (F32)area;
  608. }
  609. S32 price = parcel->getSalePrice();
  610. mSaleInfoForSale1->setTextArg("[PRICE]", LLResMgr::getInstance()->getMonetaryString(price));
  611. mSaleInfoForSale1->setTextArg("[PRICE_PER_SQM]", llformat("%.1f", cost_per_sqm));
  612. if (can_be_sold)
  613. {
  614. mBtnStopSellLand->setVisible(TRUE);
  615. }
  616. }
  617. else
  618. {
  619. mSaleInfoForSale1->setVisible(FALSE);
  620. mSaleInfoForSale2->setVisible(FALSE);
  621. mSaleInfoForSaleObjects->setVisible(FALSE);
  622. mSaleInfoForSaleNoObjects->setVisible(FALSE);
  623. mSaleInfoNotForSale->setVisible(TRUE);
  624. if (can_be_sold)
  625. {
  626. mBtnSellLand->setVisible(TRUE);
  627. }
  628. }
  629. refreshNames();
  630. mBtnBuyLand->setEnabled(
  631. LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false));
  632. mBtnScriptLimits->setEnabled(true);
  633. // LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false));
  634. mBtnBuyGroupLand->setEnabled(
  635. LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, true));
  636. if(region_owner)
  637. {
  638. mBtnReclaimLand->setEnabled(
  639. !is_public && (parcel->getOwnerID() != gAgent.getID()));
  640. }
  641. else
  642. {
  643. BOOL is_owner_release = LLViewerParcelMgr::isParcelOwnedByAgent(parcel, GP_LAND_RELEASE);
  644. BOOL is_manager_release = (gAgent.canManageEstate() &&
  645. regionp &&
  646. (parcel->getOwnerID() != regionp->getOwner()));
  647. BOOL can_release = is_owner_release || is_manager_release;
  648. mBtnReleaseLand->setEnabled( can_release );
  649. }
  650. BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();;
  651. mBtnBuyPass->setEnabled(use_pass);
  652. }
  653. }
  654. // public
  655. void LLPanelLandGeneral::refreshNames()
  656. {
  657. LLParcel *parcel = mParcel->getParcel();
  658. if (!parcel)
  659. {
  660. mTextOwner->setText(LLStringUtil::null);
  661. mTextGroup->setText(LLStringUtil::null);
  662. return;
  663. }
  664. std::string owner;
  665. if (parcel->getIsGroupOwned())
  666. {
  667. owner = getString("group_owned_text");
  668. }
  669. else
  670. {
  671. // Figure out the owner's name
  672. owner = LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString();
  673. }
  674. if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus())
  675. {
  676. owner += getString("sale_pending_text");
  677. }
  678. mTextOwner->setText(owner);
  679. std::string group;
  680. if (!parcel->getGroupID().isNull())
  681. {
  682. group = LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString();
  683. }
  684. mTextGroup->setText(group);
  685. if (parcel->getForSale())
  686. {
  687. const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
  688. if(auth_buyer_id.notNull())
  689. {
  690. std::string name;
  691. name = LLSLURL("agent", auth_buyer_id, "inspect").getSLURLString();
  692. mSaleInfoForSale2->setTextArg("[BUYER]", name);
  693. }
  694. else
  695. {
  696. mSaleInfoForSale2->setTextArg("[BUYER]", getString("anyone"));
  697. }
  698. }
  699. }
  700. // virtual
  701. void LLPanelLandGeneral::draw()
  702. {
  703. LLPanel::draw();
  704. }
  705. void LLPanelLandGeneral::onClickSetGroup()
  706. {
  707. LLFloater* parent_floater = gFloaterView->getParentFloater(this);
  708. LLFloaterGroupPicker* fg = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID()));
  709. if (fg)
  710. {
  711. fg->setSelectGroupCallback( boost::bind(&LLPanelLandGeneral::setGroup, this, _1 ));
  712. if (parent_floater)
  713. {
  714. LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
  715. fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
  716. parent_floater->addDependentFloater(fg);
  717. }
  718. }
  719. }
  720. void LLPanelLandGeneral::onClickProfile()
  721. {
  722. LLParcel* parcel = mParcel->getParcel();
  723. if (!parcel) return;
  724. if (parcel->getIsGroupOwned())
  725. {
  726. const LLUUID& group_id = parcel->getGroupID();
  727. LLGroupActions::show(group_id);
  728. }
  729. else
  730. {
  731. const LLUUID& avatar_id = parcel->getOwnerID();
  732. LLAvatarActions::showProfile(avatar_id);
  733. }
  734. }
  735. // public
  736. void LLPanelLandGeneral::setGroup(const LLUUID& group_id)
  737. {
  738. LLParcel* parcel = mParcel->getParcel();
  739. if (!parcel) return;
  740. // Set parcel properties and send message
  741. parcel->setGroupID(group_id);
  742. //parcel->setGroupName(group_name);
  743. //mTextGroup->setText(group_name);
  744. // Send update
  745. LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate(parcel);
  746. // Update UI
  747. refresh();
  748. }
  749. // static
  750. void LLPanelLandGeneral::onClickBuyLand(void* data)
  751. {
  752. BOOL* for_group = (BOOL*)data;
  753. LLViewerParcelMgr::getInstance()->startBuyLand(*for_group);
  754. }
  755. // static
  756. void LLPanelLandGeneral::onClickScriptLimits(void* data)
  757. {
  758. LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
  759. LLParcel* parcel = panelp->mParcel->getParcel();
  760. if(parcel != NULL)
  761. {
  762. LLFloaterReg::showInstance("script_limits");
  763. }
  764. }
  765. // static
  766. void LLPanelLandGeneral::onClickDeed(void*)
  767. {
  768. //LLParcel* parcel = mParcel->getParcel();
  769. //if (parcel)
  770. //{
  771. LLViewerParcelMgr::getInstance()->startDeedLandToGroup();
  772. //}
  773. }
  774. // static
  775. void LLPanelLandGeneral::onClickRelease(void*)
  776. {
  777. LLViewerParcelMgr::getInstance()->startReleaseLand();
  778. }
  779. // static
  780. void LLPanelLandGeneral::onClickReclaim(void*)
  781. {
  782. lldebugs << "LLPanelLandGeneral::onClickReclaim()" << llendl;
  783. LLViewerParcelMgr::getInstance()->reclaimParcel();
  784. }
  785. // static
  786. BOOL LLPanelLandGeneral::enableBuyPass(void* data)
  787. {
  788. LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
  789. LLParcel* parcel = panelp != NULL ? panelp->mParcel->getParcel() : LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
  790. return (parcel != NULL) && (parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned());
  791. }
  792. // static
  793. void LLPanelLandGeneral::onClickBuyPass(void* data)
  794. {
  795. LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
  796. LLParcel* parcel = panelp != NULL ? panelp->mParcel->getParcel() : LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
  797. if (!parcel) return;
  798. S32 pass_price = parcel->getPassPrice();
  799. std::string parcel_name = parcel->getName();
  800. F32 pass_hours = parcel->getPassHours();
  801. std::string cost, time;
  802. cost = llformat("%d", pass_price);
  803. time = llformat("%.2f", pass_hours);
  804. LLSD args;
  805. args["COST"] = cost;
  806. args["PARCEL_NAME"] = parcel_name;
  807. args["TIME"] = time;
  808. // creating pointer on selection to avoid deselection of parcel until we are done with buying pass (EXT-6464)
  809. sSelectionForBuyPass = LLViewerParcelMgr::getInstance()->getParcelSelection();
  810. LLNotificationsUtil::add("LandBuyPass", args, LLSD(), cbBuyPass);
  811. }
  812. // static
  813. void LLPanelLandGeneral::onClickStartAuction(void* data)
  814. {
  815. LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
  816. LLParcel* parcelp = panelp->mParcel->getParcel();
  817. if(parcelp)
  818. {
  819. if(parcelp->getForSale())
  820. {
  821. LLNotificationsUtil::add("CannotStartAuctionAlreadyForSale");
  822. }
  823. else
  824. {
  825. //LLFloaterAuction::showInstance();
  826. LLFloaterReg::showInstance("auction");
  827. }
  828. }
  829. }
  830. // static
  831. bool LLPanelLandGeneral::cbBuyPass(const LLSD& notification, const LLSD& response)
  832. {
  833. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  834. if (0 == option)
  835. {
  836. // User clicked OK
  837. LLViewerParcelMgr::getInstance()->buyPass();
  838. }
  839. // we are done with buying pass, additional selection is no longer needed
  840. sSelectionForBuyPass = NULL;
  841. return false;
  842. }
  843. // static
  844. void LLPanelLandGeneral::onCommitAny(LLUICtrl *ctrl, void *userdata)
  845. {
  846. LLPanelLandGeneral *panelp = (LLPanelLandGeneral *)userdata;
  847. LLParcel* parcel = panelp->mParcel->getParcel();
  848. if (!parcel)
  849. {
  850. return;
  851. }
  852. // Extract data from UI
  853. std::string name = panelp->mEditName->getText();
  854. std::string desc = panelp->mEditDesc->getText();
  855. // Valid data from UI
  856. // Stuff data into selected parcel
  857. parcel->setName(name);
  858. parcel->setDesc(desc);
  859. BOOL allow_deed_to_group= panelp->mCheckDeedToGroup->get();
  860. BOOL contribute_with_deed = panelp->mCheckContributeWithDeed->get();
  861. parcel->setParcelFlag(PF_ALLOW_DEED_TO_GROUP, allow_deed_to_group);
  862. parcel->setContributeWithDeed(contribute_with_deed);
  863. // Send update to server
  864. LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
  865. // Might have changed properties, so let's redraw!
  866. panelp->refresh();
  867. }
  868. // static
  869. void LLPanelLandGeneral::onClickSellLand(void* data)
  870. {
  871. LLViewerParcelMgr::getInstance()->startSellLand();
  872. }
  873. // static
  874. void LLPanelLandGeneral::onClickStopSellLand(void* data)
  875. {
  876. LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
  877. LLParcel* parcel = panelp->mParcel->getParcel();
  878. parcel->setParcelFlag(PF_FOR_SALE, FALSE);
  879. parcel->setSalePrice(0);
  880. parcel->setAuthorizedBuyerID(LLUUID::null);
  881. LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate(parcel);
  882. }
  883. //---------------------------------------------------------------------------
  884. // LLPanelLandObjects
  885. //---------------------------------------------------------------------------
  886. LLPanelLandObjects::LLPanelLandObjects(LLParcelSelectionHandle& parcel)
  887. : LLPanel(),
  888. mParcel(parcel),
  889. mParcelObjectBonus(NULL),
  890. mSWTotalObjects(NULL),
  891. mObjectContribution(NULL),
  892. mTotalObjects(NULL),
  893. mOwnerObjects(NULL),
  894. mBtnShowOwnerObjects(NULL),
  895. mBtnReturnOwnerObjects(NULL),
  896. mGroupObjects(NULL),
  897. mBtnShowGroupObjects(NULL),
  898. mBtnReturnGroupObjects(NULL),
  899. mOtherObjects(NULL),
  900. mBtnShowOtherObjects(NULL),
  901. mBtnReturnOtherObjects(NULL),
  902. mSelectedObjects(NULL),
  903. mCleanOtherObjectsTime(NULL),
  904. mOtherTime(0),
  905. mBtnRefresh(NULL),
  906. mBtnReturnOwnerList(NULL),
  907. mOwnerList(NULL),
  908. mFirstReply(TRUE),
  909. mSelectedCount(0),
  910. mSelectedIsGroup(FALSE)
  911. {
  912. }
  913. BOOL LLPanelLandObjects::postBuild()
  914. {
  915. mFirstReply = TRUE;
  916. mParcelObjectBonus = getChild<LLTextBox>("parcel_object_bonus");
  917. mSWTotalObjects = getChild<LLTextBox>("objects_available");
  918. mObjectContribution = getChild<LLTextBox>("object_contrib_text");
  919. mTotalObjects = getChild<LLTextBox>("total_objects_text");
  920. mOwnerObjects = getChild<LLTextBox>("owner_objects_text");
  921. mBtnShowOwnerObjects = getChild<LLButton>("ShowOwner");
  922. mBtnShowOwnerObjects->setClickedCallback(onClickShowOwnerObjects, this);
  923. mBtnReturnOwnerObjects = getChild<LLButton>("ReturnOwner...");
  924. mBtnReturnOwnerObjects->setClickedCallback(onClickReturnOwnerObjects, this);
  925. mGroupObjects = getChild<LLTextBox>("group_objects_text");
  926. mBtnShowGroupObjects = getChild<LLButton>("ShowGroup");
  927. mBtnShowGroupObjects->setClickedCallback(onClickShowGroupObjects, this);
  928. mBtnReturnGroupObjects = getChild<LLButton>("ReturnGroup...");
  929. mBtnReturnGroupObjects->setClickedCallback(onClickReturnGroupObjects, this);
  930. mOtherObjects = getChild<LLTextBox>("other_objects_text");
  931. mBtnShowOtherObjects = getChild<LLButton>("ShowOther");
  932. mBtnShowOtherObjects->setClickedCallback(onClickShowOtherObjects, this);
  933. mBtnReturnOtherObjects = getChild<LLButton>("ReturnOther...");
  934. mBtnReturnOtherObjects->setClickedCallback(onClickReturnOtherObjects, this);
  935. mSelectedObjects = getChild<LLTextBox>("selected_objects_text");
  936. mCleanOtherObjectsTime = getChild<LLLineEditor>("clean other time");
  937. mCleanOtherObjectsTime->setFocusLostCallback(boost::bind(onLostFocus, _1, this));
  938. mCleanOtherObjectsTime->setCommitCallback(onCommitClean, this);
  939. getChild<LLLineEditor>("clean other time")->setPrevalidate(LLTextValidate::validateNonNegativeS32);
  940. mBtnRefresh = getChild<LLButton>("Refresh List");
  941. mBtnRefresh->setClickedCallback(onClickRefresh, this);
  942. mBtnReturnOwnerList = getChild<LLButton>("Return objects...");
  943. mBtnReturnOwnerList->setClickedCallback(onClickReturnOwnerList, this);
  944. mIconAvatarOnline = LLUIImageList::getInstance()->getUIImage("icon_avatar_online.tga", 0);
  945. mIconAvatarOffline = LLUIImageList::getInstance()->getUIImage("icon_avatar_offline.tga", 0);
  946. mIconGroup = LLUIImageList::getInstance()->getUIImage("icon_group.tga", 0);
  947. mOwnerList = getChild<LLNameListCtrl>("owner list");
  948. mOwnerList->sortByColumnIndex(3, FALSE);
  949. childSetCommitCallback("owner list", onCommitList, this);
  950. mOwnerList->setDoubleClickCallback(onDoubleClickOwner, this);
  951. mOwnerList->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
  952. return TRUE;
  953. }
  954. // virtual
  955. LLPanelLandObjects::~LLPanelLandObjects()
  956. { }
  957. // static
  958. void LLPanelLandObjects::onDoubleClickOwner(void *userdata)
  959. {
  960. LLPanelLandObjects *self = (LLPanelLandObjects *)userdata;
  961. LLScrollListItem* item = self->mOwnerList->getFirstSelected();
  962. if (item)
  963. {
  964. LLUUID owner_id = item->getUUID();
  965. // Look up the selected name, for future dialog box use.
  966. const LLScrollListCell* cell;
  967. cell = item->getColumn(1);
  968. if (!cell)
  969. {
  970. return;
  971. }
  972. // Is this a group?
  973. BOOL is_group = cell->getValue().asString() == OWNER_GROUP;
  974. if (is_group)
  975. {
  976. LLGroupActions::show(owner_id);
  977. }
  978. else
  979. {
  980. LLAvatarActions::showProfile(owner_id);
  981. }
  982. }
  983. }
  984. // public
  985. void LLPanelLandObjects::refresh()
  986. {
  987. LLParcel *parcel = mParcel->getParcel();
  988. mBtnShowOwnerObjects->setEnabled(FALSE);
  989. mBtnShowGroupObjects->setEnabled(FALSE);
  990. mBtnShowOtherObjects->setEnabled(FALSE);
  991. mBtnReturnOwnerObjects->setEnabled(FALSE);
  992. mBtnReturnGroupObjects->setEnabled(FALSE);
  993. mBtnReturnOtherObjects->setEnabled(FALSE);
  994. mCleanOtherObjectsTime->setEnabled(FALSE);
  995. mBtnRefresh-> setEnabled(FALSE);
  996. mBtnReturnOwnerList-> setEnabled(FALSE);
  997. mSelectedOwners.clear();
  998. mOwnerList->deleteAllItems();
  999. mOwnerList->setEnabled(FALSE);
  1000. if (!parcel)
  1001. {
  1002. mSWTotalObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1003. mSWTotalObjects->setTextArg("[TOTAL]", llformat("%d", 0));
  1004. mSWTotalObjects->setTextArg("[AVAILABLE]", llformat("%d", 0));
  1005. mObjectContribution->setTextArg("[COUNT]", llformat("%d", 0));
  1006. mTotalObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1007. mOwnerObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1008. mGroupObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1009. mOtherObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1010. mSelectedObjects->setTextArg("[COUNT]", llformat("%d", 0));
  1011. }
  1012. else
  1013. {
  1014. S32 sw_max = parcel->getSimWideMaxPrimCapacity();
  1015. S32 sw_total = parcel->getSimWidePrimCount();
  1016. S32 max = llround(parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus());
  1017. S32 total = parcel->getPrimCount();
  1018. S32 owned = parcel->getOwnerPrimCount();
  1019. S32 group = parcel->getGroupPrimCount();
  1020. S32 other = parcel->getOtherPrimCount();
  1021. S32 selected = parcel->getSelectedPrimCount();
  1022. F32 parcel_object_bonus = parcel->getParcelPrimBonus();
  1023. mOtherTime = parcel->getCleanOtherTime();
  1024. // Can't have more than region max tasks, regardless of parcel
  1025. // object bonus factor.
  1026. LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  1027. if (region)
  1028. {
  1029. S32 max_tasks_per_region = (S32)region->getMaxTasks();
  1030. sw_max = llmin(sw_max, max_tasks_per_region);
  1031. max = llmin(max, max_tasks_per_region);
  1032. }
  1033. if (parcel_object_bonus != 1.0f)
  1034. {
  1035. mParcelObjectBonus->setVisible(TRUE);
  1036. mParcelObjectBonus->setTextArg("[BONUS]", llformat("%.2f", parcel_object_bonus));
  1037. }
  1038. else
  1039. {
  1040. mParcelObjectBonus->setVisible(FALSE);
  1041. }
  1042. if (sw_total > sw_max)
  1043. {
  1044. mSWTotalObjects->setText(getString("objects_deleted_text"));
  1045. mSWTotalObjects->setTextArg("[DELETED]", llformat("%d", sw_total - sw_max));
  1046. }
  1047. else
  1048. {
  1049. mSWTotalObjects->setText(getString("objects_available_text"));
  1050. mSWTotalObjects->setTextArg("[AVAILABLE]", llformat("%d", sw_max - sw_total));
  1051. }
  1052. mSWTotalObjects->setTextArg("[COUNT]", llformat("%d", sw_total));
  1053. mSWTotalObjects->setTextArg("[MAX]", llformat("%d", sw_max));
  1054. mObjectContribution->setTextArg("[COUNT]", llformat("%d", max));
  1055. mTotalObjects->setTextArg("[COUNT]", llformat("%d", total));
  1056. mOwnerObjects->setTextArg("[COUNT]", llformat("%d", owned));
  1057. mGroupObjects->setTextArg("[COUNT]", llformat("%d", group));
  1058. mOtherObjects->setTextArg("[COUNT]", llformat("%d", other));
  1059. mSelectedObjects->setTextArg("[COUNT]", llformat("%d", selected));
  1060. mCleanOtherObjectsTime->setText(llformat("%d", mOtherTime));
  1061. BOOL can_return_owned = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_RETURN_GROUP_OWNED);
  1062. BOOL can_return_group_set = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_RETURN_GROUP_SET);
  1063. BOOL can_return_other = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_RETURN_NON_GROUP);
  1064. if (can_return_owned || can_return_group_set || can_return_other)
  1065. {
  1066. if (owned && can_return_owned)
  1067. {
  1068. mBtnShowOwnerObjects->setEnabled(TRUE);
  1069. mBtnReturnOwnerObjects->setEnabled(TRUE);
  1070. }
  1071. if (group && can_return_group_set)
  1072. {
  1073. mBtnShowGroupObjects->setEnabled(TRUE);
  1074. mBtnReturnGroupObjects->setEnabled(TRUE);
  1075. }
  1076. if (other && can_return_other)
  1077. {
  1078. mBtnShowOtherObjects->setEnabled(TRUE);
  1079. mBtnReturnOtherObjects->setEnabled(TRUE);
  1080. }
  1081. mCleanOtherObjectsTime->setEnabled(TRUE);
  1082. mBtnRefresh->setEnabled(TRUE);
  1083. }
  1084. }
  1085. }
  1086. // virtual
  1087. void LLPanelLandObjects::draw()
  1088. {
  1089. LLPanel::draw();
  1090. }
  1091. void send_other_clean_time_message(S32 parcel_local_id, S32 other_clean_time)
  1092. {
  1093. LLMessageSystem *msg = gMessageSystem;
  1094. LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  1095. if (!region) return;
  1096. msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime);
  1097. msg->nextBlockFast(_PREHASH_AgentData);
  1098. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  1099. msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
  1100. msg->nextBlockFast(_PREHASH_ParcelData);
  1101. msg->addS32Fast(_PREHASH_LocalID, parcel_local_id);
  1102. msg->addS32Fast(_PREHASH_OtherCleanTime, other_clean_time);
  1103. msg->sendReliable(region->getHost());
  1104. }
  1105. void send_return_objects_message(S32 parcel_local_id, S32 return_type,
  1106. uuid_list_t* owner_ids = NULL)
  1107. {
  1108. LLMessageSystem *msg = gMessageSystem;
  1109. LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  1110. if (!region) return;
  1111. msg->newMessageFast(_PREHASH_ParcelReturnObjects);
  1112. msg->nextBlockFast(_PREHASH_AgentData);
  1113. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  1114. msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
  1115. msg->nextBlockFast(_PREHASH_ParcelData);
  1116. msg->addS32Fast(_PREHASH_LocalID, parcel_local_id);
  1117. msg->addU32Fast(_PREHASH_ReturnType, (U32) return_type);
  1118. // Dummy task id, not used
  1119. msg->nextBlock("TaskIDs");
  1120. msg->addUUID("TaskID", LLUUID::null);
  1121. // Throw all return ids into the packet.
  1122. // TODO: Check for too many ids.
  1123. if (owner_ids)
  1124. {
  1125. uuid_list_t::iterator end = owner_ids->end();
  1126. for (uuid_list_t::iterator it = owner_ids->begin();
  1127. it != end;
  1128. ++it)
  1129. {
  1130. msg->nextBlockFast(_PREHASH_OwnerIDs);
  1131. msg->addUUIDFast(_PREHASH_OwnerID, (*it));
  1132. }
  1133. }
  1134. else
  1135. {
  1136. msg->nextBlockFast(_PREHASH_OwnerIDs);
  1137. msg->addUUIDFast(_PREHASH_OwnerID, LLUUID::null);
  1138. }
  1139. msg->sendReliable(region->getHost());
  1140. }
  1141. bool LLPanelLandObjects::callbackReturnOwnerObjects(const LLSD& notification, const LLSD& response)
  1142. {
  1143. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1144. LLParcel *parcel = mParcel->getParcel();
  1145. if (0 == option)
  1146. {
  1147. if (parcel)
  1148. {
  1149. LLUUID owner_id = parcel->getOwnerID();
  1150. LLSD args;
  1151. if (owner_id == gAgentID)
  1152. {
  1153. LLNotificationsUtil::add("OwnedObjectsReturned");
  1154. }
  1155. else
  1156. {
  1157. args["NAME"] = LLSLURL("agent", owner_id, "completename").getSLURLString();
  1158. LLNotificationsUtil::add("OtherObjectsReturned", args);
  1159. }
  1160. send_return_objects_message(parcel->getLocalID(), RT_OWNER);
  1161. }
  1162. }
  1163. LLSelectMgr::getInstance()->unhighlightAll();
  1164. LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
  1165. refresh();
  1166. return false;
  1167. }
  1168. bool LLPanelLandObjects::callbackReturnGroupObjects(const LLSD& notification, const LLSD& response)
  1169. {
  1170. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1171. LLParcel *parcel = mParcel->getParcel();
  1172. if (0 == option)
  1173. {
  1174. if (parcel)
  1175. {
  1176. std::string group_name;
  1177. gCacheName->getGroupName(parcel->getGroupID(), group_name);
  1178. LLSD args;
  1179. args["GROUPNAME"] = group_name;
  1180. LLNotificationsUtil::add("GroupObjectsReturned", args);
  1181. send_return_objects_message(parcel->getLocalID(), RT_GROUP);
  1182. }
  1183. }
  1184. LLSelectMgr::getInstance()->unhighlightAll();
  1185. LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
  1186. refresh();
  1187. return false;
  1188. }
  1189. bool LLPanelLandObjects::callbackReturnOtherObjects(const LLSD& notification, const LLSD& response)
  1190. {
  1191. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1192. LLParcel *parcel = mParcel->getParcel();
  1193. if (0 == option)
  1194. {
  1195. if (parcel)
  1196. {
  1197. LLNotificationsUtil::add("UnOwnedObjectsReturned");
  1198. send_return_objects_message(parcel->getLocalID(), RT_OTHER);
  1199. }
  1200. }
  1201. LLSelectMgr::getInstance()->unhighlightAll();
  1202. LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
  1203. refresh();
  1204. return false;
  1205. }
  1206. bool LLPanelLandObjects::callbackReturnOwnerList(const LLSD& notification, const LLSD& response)
  1207. {
  1208. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1209. LLParcel *parcel = mParcel->getParcel();
  1210. if (0 == option)
  1211. {
  1212. if (parcel)
  1213. {
  1214. // Make sure we have something selected.
  1215. uuid_list_t::iterator selected = mSelectedOwners.begin();
  1216. if (selected != mSelectedOwners.end())
  1217. {
  1218. LLSD args;
  1219. if (mSelectedIsGroup)
  1220. {
  1221. args["GROUPNAME"] = mSelectedName;
  1222. LLNotificationsUtil::add("GroupObjectsReturned", args);
  1223. }
  1224. else
  1225. {
  1226. args["NAME"] = mSelectedName;
  1227. LLNotificationsUtil::add("OtherObjectsReturned2", args);
  1228. }
  1229. send_return_objects_message(parcel->getLocalID(), RT_LIST, &(mSelectedOwners));
  1230. }
  1231. }
  1232. }
  1233. LLSelectMgr::getInstance()->unhighlightAll();
  1234. LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
  1235. refresh();
  1236. return false;
  1237. }
  1238. // static
  1239. void LLPanelLandObjects::onClickReturnOwnerList(void* userdata)
  1240. {
  1241. LLPanelLandObjects *self = (LLPanelLandObjects *)userdata;
  1242. LLParcel* parcelp = self->mParcel->getParcel();
  1243. if (!parcelp) return;
  1244. // Make sure we have something selected.
  1245. if (self->mSelectedOwners.empty())
  1246. {
  1247. return;
  1248. }
  1249. //uuid_list_t::iterator selected_itr = self->mSelectedOwners.begin();
  1250. //if (selected_itr == self->mSelectedOwners.end()) return;
  1251. send_parcel_select_objects(parcelp->getLocalID(), RT_LIST, &(self->mSelectedOwners));
  1252. LLSD args;
  1253. args["NAME"] = self->mSelectedName;
  1254. args["N"] = llformat("%d",self->mSelectedCount);
  1255. if (self->mSelectedIsGroup)
  1256. {
  1257. LLNotificationsUtil::add("ReturnObjectsDeededToGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerList, self, _1, _2));
  1258. }
  1259. else
  1260. {
  1261. LLNotificationsUtil::add("ReturnObjectsOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerList, self, _1, _2));
  1262. }
  1263. }
  1264. // static
  1265. void LLPanelLandObjects::onClickRefresh(void* userdata)
  1266. {
  1267. LLPanelLandObjects *self = (LLPanelLandObjects*)userdata;
  1268. LLMessageSystem *msg = gMessageSystem;
  1269. LLParcel* parcel = self->mParcel->getParcel();
  1270. if (!parcel) return;
  1271. LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  1272. if (!region) return;
  1273. // ready the list for results
  1274. self->mOwnerList->deleteAllItems();
  1275. self->mOwnerList->setCommentText(LLTrans::getString("Searching"));
  1276. self->mOwnerList->setEnabled(FALSE);
  1277. self->mFirstReply = TRUE;
  1278. // send the message
  1279. msg->newMessageFast(_PREHASH_ParcelObjectOwnersRequest);
  1280. msg->nextBlockFast(_PREHASH_AgentData);
  1281. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  1282. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  1283. msg->nextBlockFast(_PREHASH_ParcelData);
  1284. msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID());
  1285. msg->sendReliable(region->getHost());
  1286. }
  1287. // static
  1288. void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, void **)
  1289. {
  1290. LLPanelLandObjects* self = LLFloaterLand::getCurrentPanelLandObjects();
  1291. if (!self)
  1292. {
  1293. llwarns << "Received message for nonexistent LLPanelLandObject"
  1294. << llendl;
  1295. return;
  1296. }
  1297. const LLFontGL* FONT = LLFontGL::getFontSansSerif();
  1298. // Extract all of the owners.
  1299. S32 rows = msg->getNumberOfBlocksFast(_PREHASH_Data);
  1300. //uuid_list_t return_ids;
  1301. LLUUID owner_id;
  1302. BOOL is_group_owned;
  1303. S32 object_count;
  1304. U32 most_recent_time = 0;
  1305. BOOL is_online;
  1306. std::string object_count_str;
  1307. //BOOL b_need_refresh = FALSE;
  1308. // If we were waiting for the first reply, clear the "Searching..." text.
  1309. if (self->mFirstReply)
  1310. {
  1311. self->mOwnerList->deleteAllItems();
  1312. self->mFirstReply = FALSE;
  1313. }
  1314. for(S32 i = 0; i < rows; ++i)
  1315. {
  1316. msg->getUUIDFast(_PREHASH_Data, _PREHASH_OwnerID, owner_id, i);
  1317. msg->getBOOLFast(_PREHASH_Data, _PREHASH_IsGroupOwned, is_group_owned, i);
  1318. msg->getS32Fast (_PREHASH_Data, _PREHASH_Count, object_count, i);
  1319. msg->getBOOLFast(_PREHASH_Data, _PREHASH_OnlineStatus, is_online, i);
  1320. if(msg->has("DataExtended"))
  1321. {
  1322. msg->getU32("DataExtended", "TimeStamp", most_recent_time, i);
  1323. }
  1324. if (owner_id.isNull())
  1325. {
  1326. continue;
  1327. }
  1328. LLNameListCtrl::NameItem item_params;
  1329. item_params.value = owner_id;
  1330. item_params.target = is_group_owned ? LLNameListCtrl::GROUP : LLNameListCtrl::INDIVIDUAL;
  1331. if (is_group_owned)
  1332. {
  1333. item_params.columns.add().type("icon").value(self->mIconGroup->getName()).column("type");
  1334. item_params.columns.add().value(OWNER_GROUP).font(FONT).column("online_status");
  1335. }
  1336. else if (is_online)
  1337. {
  1338. item_params.columns.add().type("icon").value(self->mIconAvatarOnline->getName()).column("type");
  1339. item_params.columns.add().value(OWNER_ONLINE).font(FONT).column("online_status");
  1340. }
  1341. else // offline
  1342. {
  1343. item_params.columns.add().type("icon").value(self->mIconAvatarOffline->getName()).column("type");
  1344. item_params.columns.add().value(OWNER_OFFLINE).font(FONT).column("online_status");
  1345. }
  1346. // Placeholder for name.
  1347. LLAvatarName av_name;
  1348. LLAvatarNameCache::get(owner_id, &av_name);
  1349. item_params.columns.add().value(av_name.getCompleteName()).font(FONT).column("name");
  1350. object_count_str = llformat("%d", object_count);
  1351. item_params.columns.add().value(object_count_str).font(FONT).column("count");
  1352. item_params.columns.add().value(LLDate((time_t)most_recent_time)).font(FONT).column("mostrecent").type("date");
  1353. self->mOwnerList->addNameItemRow(item_params);
  1354. lldebugs << "object owner " << owner_id << " (" << (is_group_owned ? "group" : "agent")
  1355. << ") owns " << object_count << " objects." << llendl;
  1356. }
  1357. // check for no results
  1358. if (0 == self->mOwnerList->getItemCount())
  1359. {
  1360. self->mOwnerList->setCommentText(LLTrans::getString("NoneFound"));
  1361. }
  1362. else
  1363. {
  1364. self->mOwnerList->setEnabled(TRUE);
  1365. }
  1366. }
  1367. // static
  1368. void LLPanelLandObjects::onCommitList(LLUICtrl* ctrl, void* data)
  1369. {
  1370. LLPanelLandObjects* self = (LLPanelLandObjects*)data;
  1371. if (FALSE == self->mOwnerList->getCanSelect())
  1372. {
  1373. return;
  1374. }
  1375. LLScrollListItem *item = self->mOwnerList->getFirstSelected();
  1376. if (item)
  1377. {
  1378. // Look up the selected name, for future dialog box use.
  1379. const LLScrollListCell* cell;
  1380. cell = item->getColumn(1);
  1381. if (!cell)
  1382. {
  1383. return;
  1384. }
  1385. // Is this a group?
  1386. self->mSelectedIsGroup = cell->getValue().asString() == OWNER_GROUP;
  1387. cell = item->getColumn(2);
  1388. self->mSelectedName = cell->getValue().asString();
  1389. cell = item->getColumn(3);
  1390. self->mSelectedCount = atoi(cell->getValue().asString().c_str());
  1391. // Set the selection, and enable the return button.
  1392. self->mSelectedOwners.clear();
  1393. self->mSelectedOwners.insert(item->getUUID());
  1394. self->mBtnReturnOwnerList->setEnabled(TRUE);
  1395. // Highlight this user's objects
  1396. clickShowCore(self, RT_LIST, &(self->mSelectedOwners));
  1397. }
  1398. }
  1399. // static
  1400. void LLPanelLandObjects::clickShowCore(LLPanelLandObjects* self, S32 return_type, uuid_list_t* list)
  1401. {
  1402. LLParcel* parcel = self->mParcel->getParcel();
  1403. if (!parcel) return;
  1404. send_parcel_select_objects(parcel->getLocalID(), return_type, list);
  1405. }
  1406. // static
  1407. void LLPanelLandObjects::onClickShowOwnerObjects(void* userdata)
  1408. {
  1409. clickShowCore((LLPanelLandObjects*)userdata, RT_OWNER);
  1410. }
  1411. // static
  1412. void LLPanelLandObjects::onClickShowGroupObjects(void* userdata)
  1413. {
  1414. clickShowCore((LLPanelLandObjects*)userdata, (RT_GROUP));
  1415. }
  1416. // static
  1417. void LLPanelLandObjects::onClickShowOtherObjects(void* userdata)
  1418. {
  1419. clickShowCore((LLPanelLandObjects*)userdata, RT_OTHER);
  1420. }
  1421. // static
  1422. void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata)
  1423. {
  1424. S32 owned = 0;
  1425. LLPanelLandObjects* panelp = (LLPanelLandObjects*)userdata;
  1426. LLParcel* parcel = panelp->mParcel->getParcel();
  1427. if (!parcel) return;
  1428. owned = parcel->getOwnerPrimCount();
  1429. send_parcel_select_objects(parcel->getLocalID(), RT_OWNER);
  1430. LLUUID owner_id = parcel->getOwnerID();
  1431. LLSD args;
  1432. args["N"] = llformat("%d",owned);
  1433. if (owner_id == gAgent.getID())
  1434. {
  1435. LLNotificationsUtil::add("ReturnObjectsOwnedBySelf", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerObjects, panelp, _1, _2));
  1436. }
  1437. else
  1438. {
  1439. args["NAME"] = LLSLURL("agent", owner_id, "completename").getSLURLString();
  1440. LLNotificationsUtil::add("ReturnObjectsOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerObjects, panelp, _1, _2));
  1441. }
  1442. }
  1443. // static
  1444. void LLPanelLandObjects::onClickReturnGroupObjects(void* userdata)
  1445. {
  1446. LLPanelLandObjects* panelp = (LLPanelLandObjects*)userdata;
  1447. LLParcel* parcel = panelp->mParcel->getParcel();
  1448. if (!parcel) return;
  1449. send_parcel_select_objects(parcel->getLocalID(), RT_GROUP);
  1450. std::string group_name;
  1451. gCacheName->getGroupName(parcel->getGroupID(), group_name);
  1452. LLSD args;
  1453. args["NAME"] = group_name;
  1454. args["N"] = llformat("%d", parcel->getGroupPrimCount());
  1455. // create and show confirmation textbox
  1456. LLNotificationsUtil::add("ReturnObjectsDeededToGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnGroupObjects, panelp, _1, _2));
  1457. }
  1458. // static
  1459. void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata)
  1460. {
  1461. S32 other = 0;
  1462. LLPanelLandObjects* panelp = (LLPanelLandObjects*)userdata;
  1463. LLParcel* parcel = panelp->mParcel->getParcel();
  1464. if (!parcel) return;
  1465. other = parcel->getOtherPrimCount();
  1466. send_parcel_select_objects(parcel->getLocalID(), RT_OTHER);
  1467. LLSD args;
  1468. args["N"] = llformat("%d", other);
  1469. if (parcel->getIsGroupOwned())
  1470. {
  1471. std::string group_name;
  1472. gCacheName->getGroupName(parcel->getGroupID(), group_name);
  1473. args["NAME"] = group_name;
  1474. LLNotificationsUtil::add("ReturnObjectsNotOwnedByGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2));
  1475. }
  1476. else
  1477. {
  1478. LLUUID owner_id = parcel->getOwnerID();
  1479. if (owner_id == gAgent.getID())
  1480. {
  1481. LLNotificationsUtil::add("ReturnObjectsNotOwnedBySelf", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2));
  1482. }
  1483. else
  1484. {
  1485. args["NAME"] = LLSLURL("agent", owner_id, "completename").getSLURLString();
  1486. LLNotificationsUtil::add("ReturnObjectsNotOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2));
  1487. }
  1488. }
  1489. }
  1490. // static
  1491. void LLPanelLandObjects::onLostFocus(LLFocusableElement* caller, void* user_data)
  1492. {
  1493. onCommitClean((LLUICtrl*)caller, user_data);
  1494. }
  1495. // static
  1496. void LLPanelLandObjects::onCommitClean(LLUICtrl *caller, void* user_data)
  1497. {
  1498. LLPanelLandObjects *lop = (LLPanelLandObjects *)user_data;
  1499. LLParcel* parcel = lop->mParcel->getParcel();
  1500. if (parcel)
  1501. {
  1502. lop->mOtherTime = atoi(lop->mCleanOtherObjectsTime->getText().c_str());
  1503. parcel->setCleanOtherTime(lop->mOtherTime);
  1504. send_other_clean_time_message(parcel->getLocalID(), lop->mOtherTime);
  1505. }
  1506. }
  1507. //---------------------------------------------------------------------------
  1508. // LLPanelLandOptions
  1509. //---------------------------------------------------------------------------
  1510. LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel)
  1511. : LLPanel(),
  1512. mCheckEditObjects(NULL),
  1513. mCheckEditGroupObjects(NULL),
  1514. mCheckAllObjectEntry(NULL),
  1515. mCheckGroupObjectEntry(NULL),
  1516. mCheckSafe(NULL),
  1517. mCheckFly(NULL),
  1518. mCheckGroupScripts(NULL),
  1519. mCheckOtherScripts(NULL),
  1520. mCheckShowDirectory(NULL),
  1521. mCategoryCombo(NULL),
  1522. mLandingTypeCombo(NULL),
  1523. mSnapshotCtrl(NULL),
  1524. mLocationText(NULL),
  1525. mSetBtn(NULL),
  1526. mClearBtn(NULL),
  1527. mMatureCtrl(NULL),
  1528. mPushRestrictionCtrl(NULL),
  1529. mSeeAvatarsCtrl(NULL),
  1530. mParcel(parcel)
  1531. {
  1532. }
  1533. BOOL LLPanelLandOptions::postBuild()
  1534. {
  1535. mCheckEditObjects = getChild<LLCheckBoxCtrl>( "edit objects check");
  1536. childSetCommitCallback("edit objects check", onCommitAny, this);
  1537. mCheckEditGroupObjects = getChild<LLCheckBoxCtrl>( "edit group objects check");
  1538. childSetCommitCallback("edit group objects check", onCommitAny, this);
  1539. mCheckAllObjectEntry = getChild<LLCheckBoxCtrl>( "all object entry check");
  1540. childSetCommitCallback("all object entry check", onCommitAny, this);
  1541. mCheckGroupObjectEntry = getChild<LLCheckBoxCtrl>( "group object entry check");
  1542. childSetCommitCallback("group object entry check", onCommitAny, this);
  1543. mCheckGroupScripts = getChild<LLCheckBoxCtrl>( "check group scripts");
  1544. childSetCommitCallback("check group scripts", onCommitAny, this);
  1545. mCheckFly = getChild<LLCheckBoxCtrl>( "check fly");
  1546. childSetCommitCallback("check fly", onCommitAny, this);
  1547. mCheckOtherScripts = getChild<LLCheckBoxCtrl>( "check other scripts");
  1548. childSetCommitCallback("check other scripts", onCommitAny, this);
  1549. mCheckSafe = getChild<LLCheckBoxCtrl>( "check safe");
  1550. childSetCommitCallback("check safe", onCommitAny, this);
  1551. mPushRestrictionCtrl = getChild<LLCheckBoxCtrl>( "PushRestrictCheck");
  1552. childSetCommitCallback("PushRestrictCheck", onCommitAny, this);
  1553. mSeeAvatarsCtrl = getChild<LLCheckBoxCtrl>( "SeeAvatarsCheck");
  1554. childSetCommitCallback("SeeAvatarsCheck", onCommitAny, this);
  1555. mCheckShowDirectory = getChild<LLCheckBoxCtrl>( "ShowDirectoryCheck");
  1556. childSetCommitCallback("ShowDirectoryCheck", onCommitAny, this);
  1557. if (gAgent.getAgentAccess().isInTransition())
  1558. {
  1559. // during the AO transition, this combo has an Adult item.
  1560. // Post-transition, it goes away. We can remove this conditional
  1561. // after the transition and just use the "else" clause.
  1562. mCategoryCombo = getChild<LLComboBox>( "land category with adult");
  1563. childSetCommitCallback("land category with adult", onCommitAny, this);
  1564. }
  1565. else
  1566. {
  1567. // this is the code that should be preserved post-transition
  1568. // you could also change the XML to set visibility and enabled true.
  1569. mCategoryCombo = getChild<LLComboBox>( "land category");
  1570. childSetCommitCallback("land category", onCommitAny, this);
  1571. }
  1572. mCategoryCombo->setVisible(true);
  1573. mCategoryCombo->setEnabled(true);
  1574. mMatureCtrl = getChild<LLCheckBoxCtrl>( "MatureCheck");
  1575. childSetCommitCallback("MatureCheck", onCommitAny, this);
  1576. if (gAgent.wantsPGOnly())
  1577. {
  1578. // Disable these buttons if they are PG (Teen) users
  1579. mMatureCtrl->setVisible(FALSE);
  1580. mMatureCtrl->setEnabled(FALSE);
  1581. }
  1582. mSnapshotCtrl = getChild<LLTextureCtrl>("snapshot_ctrl");
  1583. if (mSnapshotCtrl)
  1584. {
  1585. mSnapshotCtrl->setCommitCallback( onCommitAny, this );
  1586. mSnapshotCtrl->setAllowNoTexture ( TRUE );
  1587. mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
  1588. mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
  1589. }
  1590. else
  1591. {
  1592. llwarns << "LLUICtrlFactory::getTexturePickerByName() returned NULL for 'snapshot_ctrl'" << llendl;
  1593. }
  1594. mLocationText = getChild<LLTextBox>("landing_point");
  1595. mSetBtn = getChild<LLButton>("Set");
  1596. mSetBtn->setClickedCallback(onClickSet, this);
  1597. mClearBtn = getChild<LLButton>("Clear");
  1598. mClearBtn->setClickedCallback(onClickClear, this);
  1599. mLandingTypeCombo = getChild<LLComboBox>( "landing type");
  1600. childSetCommitCallback("landing type", onCommitAny, this);
  1601. return TRUE;
  1602. }
  1603. // virtual
  1604. LLPanelLandOptions::~LLPanelLandOptions()
  1605. { }
  1606. // virtual
  1607. void LLPanelLandOptions::refresh()
  1608. {
  1609. refreshSearch();
  1610. LLParcel *parcel = mParcel->getParcel();
  1611. if (!parcel)
  1612. {
  1613. mCheckEditObjects ->set(FALSE);
  1614. mCheckEditObjects ->setEnabled(FALSE);
  1615. mCheckEditGroupObjects ->set(FALSE);
  1616. mCheckEditGroupObjects ->setEnabled(FALSE);
  1617. mCheckAllObjectEntry ->set(FALSE);
  1618. mCheckAllObjectEntry ->setEnabled(FALSE);
  1619. mCheckGroupObjectEntry ->set(FALSE);
  1620. mCheckGroupObjectEntry ->setEnabled(FALSE);
  1621. mCheckSafe ->set(FALSE);
  1622. mCheckSafe ->setEnabled(FALSE);
  1623. mCheckFly ->set(FALSE);
  1624. mCheckFly ->setEnabled(FALSE);
  1625. mCheckGroupScripts ->set(FALSE);
  1626. mCheckGroupScripts ->setEnabled(FALSE);
  1627. mCheckOtherScripts ->set(FALSE);
  1628. mCheckOtherScripts ->setEnabled(FALSE);
  1629. mPushRestrictionCtrl->set(FALSE);
  1630. mPushRestrictionCtrl->setEnabled(FALSE);
  1631. mSeeAvatarsCtrl->set(TRUE);
  1632. mSeeAvatarsCtrl->setEnabled(FALSE);
  1633. mLandingTypeCombo->setCurrentByIndex(0);
  1634. mLandingTypeCombo->setEnabled(FALSE);
  1635. mSnapshotCtrl->setImageAssetID(LLUUID::null);
  1636. mSnapshotCtrl->setEnabled(FALSE);
  1637. mLocationText->setTextArg("[LANDING]", getString("landing_point_none"));
  1638. mSetBtn->setEnabled(FALSE);
  1639. mClearBtn->setEnabled(FALSE);
  1640. mMatureCtrl->setEnabled(FALSE);
  1641. }
  1642. else
  1643. {
  1644. // something selected, hooray!
  1645. // Display options
  1646. BOOL can_change_options = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_OPTIONS);
  1647. mCheckEditObjects ->set( parcel->getAllowModify() );
  1648. mCheckEditObjects ->setEnabled( can_change_options );
  1649. mCheckEditGroupObjects ->set( parcel->getAllowGroupModify() || parcel->getAllowModify());
  1650. mCheckEditGroupObjects ->setEnabled( can_change_options && !parcel->getAllowModify() ); // If others edit is enabled, then this is explicitly enabled.
  1651. mCheckAllObjectEntry ->set( parcel->getAllowAllObjectEntry() );
  1652. mCheckAllObjectEntry ->setEnabled( can_change_options );
  1653. mCheckGroupObjectEntry ->set( parcel->getAllowGroupObjectEntry() || parcel->getAllowAllObjectEntry());
  1654. mCheckGroupObjectEntry ->setEnabled( can_change_options && !parcel->getAllowAllObjectEntry() );
  1655. mCheckSafe ->set( !parcel->getAllowDamage() );
  1656. mCheckSafe ->setEnabled( can_change_options );
  1657. mCheckFly ->set( parcel->getAllowFly() );
  1658. mCheckFly ->setEnabled( can_change_options );
  1659. mCheckGroupScripts ->set( parcel->getAllowGroupScripts() || parcel->getAllowOtherScripts());
  1660. mCheckGroupScripts ->setEnabled( can_change_options && !parcel->getAllowOtherScripts());
  1661. mCheckOtherScripts ->set( parcel->getAllowOtherScripts() );
  1662. mCheckOtherScripts ->setEnabled( can_change_options );
  1663. mPushRestrictionCtrl->set( parcel->getRestrictPushObject() );
  1664. if(parcel->getRegionPushOverride())
  1665. {
  1666. mPushRestrictionCtrl->setLabel(getString("push_restrict_region_text"));
  1667. mPushRestrictionCtrl->setEnabled(false);
  1668. mPushRestrictionCtrl->set(TRUE);
  1669. }
  1670. else
  1671. {
  1672. mPushRestrictionCtrl->setLabel(getString("push_restrict_text"));
  1673. mPushRestrictionCtrl->setEnabled(can_change_options);
  1674. }
  1675. mSeeAvatarsCtrl->set(parcel->getSeeAVs());
  1676. mSeeAvatarsCtrl->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData());
  1677. BOOL can_change_landing_point = LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
  1678. GP_LAND_SET_LANDING_POINT);
  1679. mLandingTypeCombo->setCurrentByIndex((S32)parcel->getLandingType());
  1680. mLandingTypeCombo->setEnabled( can_change_landing_point );
  1681. bool can_change_identity =
  1682. LLViewerParcelMgr::isParcelModifiableByAgent(
  1683. parcel, GP_LAND_CHANGE_IDENTITY);
  1684. mSnapshotCtrl->setImageAssetID(parcel->getSnapshotID());
  1685. mSnapshotCtrl->setEnabled( can_change_identity );
  1686. LLVector3 pos = parcel->getUserLocation();
  1687. if (pos.isExactlyZero())
  1688. {
  1689. mLocationText->setTextArg("[LANDING]", getString("landing_point_none"));
  1690. }
  1691. else
  1692. {
  1693. mLocationText->setTextArg("[LANDING]",llformat("%d, %d, %d",
  1694. llround(pos.mV[VX]),
  1695. llround(pos.mV[VY]),
  1696. llround(pos.mV[VZ])));
  1697. }
  1698. mSetBtn->setEnabled( can_change_landing_point );
  1699. mClearBtn->setEnabled( can_change_landing_point );
  1700. if (gAgent.wantsPGOnly())
  1701. {
  1702. // Disable these buttons if they are PG (Teen) users
  1703. mMatureCtrl->setVisible(FALSE);
  1704. mMatureCtrl->setEnabled(FALSE);
  1705. }
  1706. else
  1707. {
  1708. // not teen so fill in the data for the maturity control
  1709. mMatureCtrl->setVisible(TRUE);
  1710. LLStyle::Params style;
  1711. style.image(LLUI::getUIImage(gFloaterView->getParentFloater(this)->getString("maturity_icon_moderate")));
  1712. LLCheckBoxWithTBAcess* fullaccess_mature_ctrl = (LLCheckBoxWithTBAcess*)mMatureCtrl;
  1713. fullaccess_mature_ctrl->getTextBox()->setText(LLStringExplicit(""));
  1714. fullaccess_mature_ctrl->getTextBox()->appendImageSegment(style);
  1715. fullaccess_mature_ctrl->getTextBox()->appendText(getString("mature_check_mature"), false);
  1716. fullaccess_mature_ctrl->setToolTip(getString("mature_check_mature_tooltip"));
  1717. fullaccess_mature_ctrl->reshape(fullaccess_mature_ctrl->getRect().getWidth(), fullaccess_mature_ctrl->getRect().getHeight(), FALSE);
  1718. // they can see the checkbox, but its disposition depends on the
  1719. // state of the region
  1720. LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  1721. if (regionp)
  1722. {
  1723. if (regionp->getSimAccess() == SIM_ACCESS_PG)
  1724. {
  1725. mMatureCtrl->setEnabled(FALSE);
  1726. mMatureCtrl->set(FALSE);
  1727. }
  1728. else if (regionp->getSimAccess() == SIM_ACCESS_MATURE)
  1729. {
  1730. mMatureCtrl->setEnabled(can_change_identity);
  1731. mMatureCtrl->set(parcel->getMaturePublish());
  1732. }
  1733. else if (regionp->getSimAccess() == SIM_ACCESS_ADULT)
  1734. {
  1735. mMatureCtrl->setEnabled(FALSE);
  1736. mMatureCtrl->set(TRUE);
  1737. mMatureCtrl->setLabel(getString("mature_check_adult"));
  1738. mMatureCtrl->setToolTip(getString("mature_check_adult_tooltip"));
  1739. }
  1740. }
  1741. }
  1742. }
  1743. }
  1744. // virtual
  1745. void LLPanelLandOptions::draw()
  1746. {
  1747. refreshSearch(); // Is this necessary? JC
  1748. LLPanel::draw();
  1749. }
  1750. // private
  1751. void LLPanelLandOptions::refreshSearch()
  1752. {
  1753. LLParcel *parcel = mParcel->getParcel();
  1754. if (!parcel)
  1755. {
  1756. mCheckShowDirectory->set(FALSE);
  1757. mCheckShowDirectory->setEnabled(FALSE);
  1758. // *TODO:Translate
  1759. const std::string& none_string = LLParcel::getCategoryUIString(LLParcel::C_NONE);
  1760. mCategoryCombo->setSimple(none_string);
  1761. mCategoryCombo->setEnabled(FALSE);
  1762. return;
  1763. }
  1764. LLViewerRegion* region =
  1765. LLViewerParcelMgr::getInstance()->getSelectionRegion();
  1766. bool can_change =
  1767. LLViewerParcelMgr::isParcelModifiableByAgent(
  1768. parcel, GP_LAND_CHANGE_IDENTITY)
  1769. && region
  1770. && !(region->getRegionFlags() & REGION_FLAGS_BLOCK_PARCEL_SEARCH);
  1771. // There is a bug with this panel whereby the Show Directory bit can be
  1772. // slammed off by the Region based on an override. Since this data is cached
  1773. // locally the change will not reflect in the panel, which could cause confusion
  1774. // A workaround for this is to flip the bit off in the locally cached version
  1775. // when we detect a mismatch case.
  1776. if(!can_change && parcel->getParcelFlag(PF_SHOW_DIRECTORY))
  1777. {
  1778. parcel->setParcelFlag(PF_SHOW_DIRECTORY, FALSE);
  1779. }
  1780. BOOL show_directory = parcel->getParcelFlag(PF_SHOW_DIRECTORY);
  1781. mCheckShowDirectory ->set(show_directory);
  1782. // Set by string in case the order in UI doesn't match the order by index.
  1783. // *TODO:Translate
  1784. LLParcel::ECategory cat = parcel->getCategory();
  1785. const std::string& category_string = LLParcel::getCategoryUIString(cat);
  1786. mCategoryCombo->setSimple(category_string);
  1787. std::string tooltip;
  1788. bool enable_show_directory = false;
  1789. // Parcels <= 128 square meters cannot be listed in search, in an
  1790. // effort to reduce search spam from small parcels. See also
  1791. // the search crawler "grid-crawl.py" in secondlife.com/doc/app/search/ JC
  1792. const S32 MIN_PARCEL_AREA_FOR_SEARCH = 128;
  1793. bool large_enough = parcel->getArea() > MIN_PARCEL_AREA_FOR_SEARCH;
  1794. if (large_enough)
  1795. {
  1796. if (can_change)
  1797. {
  1798. tooltip = getString("search_enabled_tooltip");
  1799. enable_show_directory = true;
  1800. }
  1801. else
  1802. {
  1803. tooltip = getString("search_disabled_permissions_tooltip");
  1804. enable_show_directory = false;
  1805. }
  1806. }
  1807. else
  1808. {
  1809. // not large enough to include in search
  1810. if (can_change)
  1811. {
  1812. if (show_directory)
  1813. {
  1814. // parcels that are too small, but are still in search for
  1815. // legacy reasons, need to have the check box enabled so
  1816. // the owner can delist the parcel. JC
  1817. tooltip = getString("search_enabled_tooltip");
  1818. enable_show_directory = true;
  1819. }
  1820. else
  1821. {
  1822. tooltip = getString("search_disabled_small_tooltip");
  1823. enable_show_d