PageRenderTime 152ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/newview/llfloaterproperties.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 905 lines | 691 code | 87 blank | 127 comment | 108 complexity | c176a35ffc8803f3224eec0556ca6d54 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llfloaterproperties.cpp
  3. * @brief A floater which shows an inventory item's 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 "llfloaterproperties.h"
  28. #include <algorithm>
  29. #include <functional>
  30. #include "llcachename.h"
  31. #include "lldbstrings.h"
  32. #include "llfloaterreg.h"
  33. #include "llagent.h"
  34. #include "llbutton.h"
  35. #include "llcheckboxctrl.h"
  36. #include "llavataractions.h"
  37. #include "llinventorydefines.h"
  38. #include "llinventoryobserver.h"
  39. #include "llinventorymodel.h"
  40. #include "lllineeditor.h"
  41. //#include "llspinctrl.h"
  42. #include "llradiogroup.h"
  43. #include "llresmgr.h"
  44. #include "roles_constants.h"
  45. #include "llselectmgr.h"
  46. #include "lltextbox.h"
  47. #include "lltrans.h"
  48. #include "lluiconstants.h"
  49. #include "llviewerinventory.h"
  50. #include "llviewerobjectlist.h"
  51. #include "llviewerregion.h"
  52. #include "llviewercontrol.h"
  53. #include "llviewerwindow.h"
  54. #include "llgroupactions.h"
  55. #include "lluictrlfactory.h"
  56. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  57. // Class LLPropertiesObserver
  58. //
  59. // helper class to watch the inventory.
  60. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  61. // Ugh. This can't be a singleton because it needs to remove itself
  62. // from the inventory observer list when destroyed, which could
  63. // happen after gInventory has already been destroyed if a singleton.
  64. // Instead, do our own ref counting and create / destroy it as needed
  65. class LLPropertiesObserver : public LLInventoryObserver
  66. {
  67. public:
  68. LLPropertiesObserver(LLFloaterProperties* floater)
  69. : mFloater(floater)
  70. {
  71. gInventory.addObserver(this);
  72. }
  73. virtual ~LLPropertiesObserver()
  74. {
  75. gInventory.removeObserver(this);
  76. }
  77. virtual void changed(U32 mask);
  78. private:
  79. LLFloaterProperties* mFloater;
  80. };
  81. void LLPropertiesObserver::changed(U32 mask)
  82. {
  83. // if there's a change we're interested in.
  84. if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0)
  85. {
  86. mFloater->dirty();
  87. }
  88. }
  89. ///----------------------------------------------------------------------------
  90. /// Class LLFloaterProperties
  91. ///----------------------------------------------------------------------------
  92. // Default constructor
  93. LLFloaterProperties::LLFloaterProperties(const LLUUID& item_id)
  94. : LLFloater(mItemID),
  95. mItemID(item_id),
  96. mDirty(TRUE)
  97. {
  98. mPropertiesObserver = new LLPropertiesObserver(this);
  99. }
  100. // Destroys the object
  101. LLFloaterProperties::~LLFloaterProperties()
  102. {
  103. delete mPropertiesObserver;
  104. mPropertiesObserver = NULL;
  105. }
  106. // virtual
  107. BOOL LLFloaterProperties::postBuild()
  108. {
  109. // build the UI
  110. // item name & description
  111. getChild<LLLineEditor>("LabelItemName")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
  112. getChild<LLUICtrl>("LabelItemName")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitName,this));
  113. getChild<LLLineEditor>("LabelItemDesc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
  114. getChild<LLUICtrl>("LabelItemDesc")->setCommitCallback(boost::bind(&LLFloaterProperties:: onCommitDescription, this));
  115. // Creator information
  116. getChild<LLUICtrl>("BtnCreator")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickCreator,this));
  117. // owner information
  118. getChild<LLUICtrl>("BtnOwner")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickOwner,this));
  119. // acquired date
  120. // owner permissions
  121. // Permissions debug text
  122. // group permissions
  123. getChild<LLUICtrl>("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this));
  124. // everyone permissions
  125. getChild<LLUICtrl>("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this));
  126. // next owner permissions
  127. getChild<LLUICtrl>("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this));
  128. getChild<LLUICtrl>("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this));
  129. getChild<LLUICtrl>("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this));
  130. // Mark for sale or not, and sale info
  131. getChild<LLUICtrl>("CheckPurchase")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this));
  132. getChild<LLUICtrl>("RadioSaleType")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleType, this));
  133. // "Price" label for edit
  134. getChild<LLUICtrl>("Edit Cost")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this));
  135. // The UI has been built, now fill in all the values
  136. refresh();
  137. return TRUE;
  138. }
  139. // virtual
  140. void LLFloaterProperties::onOpen(const LLSD& key)
  141. {
  142. refresh();
  143. }
  144. void LLFloaterProperties::refresh()
  145. {
  146. LLInventoryItem* item = findItem();
  147. if(item)
  148. {
  149. refreshFromItem(item);
  150. }
  151. else
  152. {
  153. //RN: it is possible that the container object is in the middle of an inventory refresh
  154. // causing findItem() to fail, so just temporarily disable everything
  155. mDirty = TRUE;
  156. const char* enableNames[]={
  157. "LabelItemName",
  158. "LabelItemDesc",
  159. "LabelCreatorName",
  160. "BtnCreator",
  161. "LabelOwnerName",
  162. "BtnOwner",
  163. "CheckOwnerModify",
  164. "CheckOwnerCopy",
  165. "CheckOwnerTransfer",
  166. "CheckShareWithGroup",
  167. "CheckEveryoneCopy",
  168. "CheckNextOwnerModify",
  169. "CheckNextOwnerCopy",
  170. "CheckNextOwnerTransfer",
  171. "CheckPurchase",
  172. "RadioSaleType",
  173. "Edit Cost"
  174. };
  175. for(size_t t=0; t<LL_ARRAY_SIZE(enableNames); ++t)
  176. {
  177. getChildView(enableNames[t])->setEnabled(false);
  178. }
  179. const char* hideNames[]={
  180. "BaseMaskDebug",
  181. "OwnerMaskDebug",
  182. "GroupMaskDebug",
  183. "EveryoneMaskDebug",
  184. "NextMaskDebug"
  185. };
  186. for(size_t t=0; t<LL_ARRAY_SIZE(hideNames); ++t)
  187. {
  188. getChildView(hideNames[t])->setVisible(false);
  189. }
  190. }
  191. }
  192. void LLFloaterProperties::draw()
  193. {
  194. if (mDirty)
  195. {
  196. // RN: clear dirty first because refresh can set dirty to TRUE
  197. mDirty = FALSE;
  198. refresh();
  199. }
  200. LLFloater::draw();
  201. }
  202. void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
  203. {
  204. ////////////////////////
  205. // PERMISSIONS LOOKUP //
  206. ////////////////////////
  207. // do not enable the UI for incomplete items.
  208. LLViewerInventoryItem* i = (LLViewerInventoryItem*)item;
  209. BOOL is_complete = i->isFinished();
  210. const BOOL cannot_restrict_permissions = LLInventoryType::cannotRestrictPermissions(i->getInventoryType());
  211. const BOOL is_calling_card = (i->getInventoryType() == LLInventoryType::IT_CALLINGCARD);
  212. const LLPermissions& perm = item->getPermissions();
  213. const BOOL can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm,
  214. GP_OBJECT_MANIPULATE);
  215. const BOOL can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm,
  216. GP_OBJECT_SET_SALE) &&
  217. !cannot_restrict_permissions;
  218. const BOOL is_link = i->getIsLinkType();
  219. // You need permission to modify the object to modify an inventory
  220. // item in it.
  221. LLViewerObject* object = NULL;
  222. if(!mObjectID.isNull()) object = gObjectList.findObject(mObjectID);
  223. BOOL is_obj_modify = TRUE;
  224. if(object)
  225. {
  226. is_obj_modify = object->permOwnerModify();
  227. }
  228. //////////////////////
  229. // ITEM NAME & DESC //
  230. //////////////////////
  231. BOOL is_modifiable = gAgent.allowOperation(PERM_MODIFY, perm,
  232. GP_OBJECT_MANIPULATE)
  233. && is_obj_modify && is_complete;
  234. getChildView("LabelItemNameTitle")->setEnabled(TRUE);
  235. getChildView("LabelItemName")->setEnabled(is_modifiable && !is_calling_card); // for now, don't allow rename of calling cards
  236. getChild<LLUICtrl>("LabelItemName")->setValue(item->getName());
  237. getChildView("LabelItemDescTitle")->setEnabled(TRUE);
  238. getChildView("LabelItemDesc")->setEnabled(is_modifiable);
  239. getChildView("IconLocked")->setVisible(!is_modifiable);
  240. getChild<LLUICtrl>("LabelItemDesc")->setValue(item->getDescription());
  241. //////////////////
  242. // CREATOR NAME //
  243. //////////////////
  244. if(!gCacheName) return;
  245. if(!gAgent.getRegion()) return;
  246. if (item->getCreatorUUID().notNull())
  247. {
  248. std::string name;
  249. gCacheName->getFullName(item->getCreatorUUID(), name);
  250. getChildView("BtnCreator")->setEnabled(TRUE);
  251. getChildView("LabelCreatorTitle")->setEnabled(TRUE);
  252. getChildView("LabelCreatorName")->setEnabled(TRUE);
  253. getChild<LLUICtrl>("LabelCreatorName")->setValue(name);
  254. }
  255. else
  256. {
  257. getChildView("BtnCreator")->setEnabled(FALSE);
  258. getChildView("LabelCreatorTitle")->setEnabled(FALSE);
  259. getChildView("LabelCreatorName")->setEnabled(FALSE);
  260. getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown"));
  261. }
  262. ////////////////
  263. // OWNER NAME //
  264. ////////////////
  265. if(perm.isOwned())
  266. {
  267. std::string name;
  268. if (perm.isGroupOwned())
  269. {
  270. gCacheName->getGroupName(perm.getGroup(), name);
  271. }
  272. else
  273. {
  274. gCacheName->getFullName(perm.getOwner(), name);
  275. }
  276. getChildView("BtnOwner")->setEnabled(TRUE);
  277. getChildView("LabelOwnerTitle")->setEnabled(TRUE);
  278. getChildView("LabelOwnerName")->setEnabled(TRUE);
  279. getChild<LLUICtrl>("LabelOwnerName")->setValue(name);
  280. }
  281. else
  282. {
  283. getChildView("BtnOwner")->setEnabled(FALSE);
  284. getChildView("LabelOwnerTitle")->setEnabled(FALSE);
  285. getChildView("LabelOwnerName")->setEnabled(FALSE);
  286. getChild<LLUICtrl>("LabelOwnerName")->setValue(getString("public"));
  287. }
  288. //////////////////
  289. // ACQUIRE DATE //
  290. //////////////////
  291. time_t time_utc = item->getCreationDate();
  292. if (0 == time_utc)
  293. {
  294. getChild<LLUICtrl>("LabelAcquiredDate")->setValue(getString("unknown"));
  295. }
  296. else
  297. {
  298. std::string timeStr = getString("acquiredDate");
  299. LLSD substitution;
  300. substitution["datetime"] = (S32) time_utc;
  301. LLStringUtil::format (timeStr, substitution);
  302. getChild<LLUICtrl>("LabelAcquiredDate")->setValue(timeStr);
  303. }
  304. ///////////////////////
  305. // OWNER PERMISSIONS //
  306. ///////////////////////
  307. if(can_agent_manipulate)
  308. {
  309. getChild<LLUICtrl>("OwnerLabel")->setValue(getString("you_can"));
  310. }
  311. else
  312. {
  313. getChild<LLUICtrl>("OwnerLabel")->setValue(getString("owner_can"));
  314. }
  315. U32 base_mask = perm.getMaskBase();
  316. U32 owner_mask = perm.getMaskOwner();
  317. U32 group_mask = perm.getMaskGroup();
  318. U32 everyone_mask = perm.getMaskEveryone();
  319. U32 next_owner_mask = perm.getMaskNextOwner();
  320. getChildView("OwnerLabel")->setEnabled(TRUE);
  321. getChildView("CheckOwnerModify")->setEnabled(FALSE);
  322. getChild<LLUICtrl>("CheckOwnerModify")->setValue(LLSD((BOOL)(owner_mask & PERM_MODIFY)));
  323. getChildView("CheckOwnerCopy")->setEnabled(FALSE);
  324. getChild<LLUICtrl>("CheckOwnerCopy")->setValue(LLSD((BOOL)(owner_mask & PERM_COPY)));
  325. getChildView("CheckOwnerTransfer")->setEnabled(FALSE);
  326. getChild<LLUICtrl>("CheckOwnerTransfer")->setValue(LLSD((BOOL)(owner_mask & PERM_TRANSFER)));
  327. ///////////////////////
  328. // DEBUG PERMISSIONS //
  329. ///////////////////////
  330. if( gSavedSettings.getBOOL("DebugPermissions") )
  331. {
  332. BOOL slam_perm = FALSE;
  333. BOOL overwrite_group = FALSE;
  334. BOOL overwrite_everyone = FALSE;
  335. if (item->getType() == LLAssetType::AT_OBJECT)
  336. {
  337. U32 flags = item->getFlags();
  338. slam_perm = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_PERM;
  339. overwrite_everyone = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE;
  340. overwrite_group = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP;
  341. }
  342. std::string perm_string;
  343. perm_string = "B: ";
  344. perm_string += mask_to_string(base_mask);
  345. getChild<LLUICtrl>("BaseMaskDebug")->setValue(perm_string);
  346. getChildView("BaseMaskDebug")->setVisible(TRUE);
  347. perm_string = "O: ";
  348. perm_string += mask_to_string(owner_mask);
  349. getChild<LLUICtrl>("OwnerMaskDebug")->setValue(perm_string);
  350. getChildView("OwnerMaskDebug")->setVisible(TRUE);
  351. perm_string = "G";
  352. perm_string += overwrite_group ? "*: " : ": ";
  353. perm_string += mask_to_string(group_mask);
  354. getChild<LLUICtrl>("GroupMaskDebug")->setValue(perm_string);
  355. getChildView("GroupMaskDebug")->setVisible(TRUE);
  356. perm_string = "E";
  357. perm_string += overwrite_everyone ? "*: " : ": ";
  358. perm_string += mask_to_string(everyone_mask);
  359. getChild<LLUICtrl>("EveryoneMaskDebug")->setValue(perm_string);
  360. getChildView("EveryoneMaskDebug")->setVisible(TRUE);
  361. perm_string = "N";
  362. perm_string += slam_perm ? "*: " : ": ";
  363. perm_string += mask_to_string(next_owner_mask);
  364. getChild<LLUICtrl>("NextMaskDebug")->setValue(perm_string);
  365. getChildView("NextMaskDebug")->setVisible(TRUE);
  366. }
  367. else
  368. {
  369. getChildView("BaseMaskDebug")->setVisible(FALSE);
  370. getChildView("OwnerMaskDebug")->setVisible(FALSE);
  371. getChildView("GroupMaskDebug")->setVisible(FALSE);
  372. getChildView("EveryoneMaskDebug")->setVisible(FALSE);
  373. getChildView("NextMaskDebug")->setVisible(FALSE);
  374. }
  375. /////////////
  376. // SHARING //
  377. /////////////
  378. // Check for ability to change values.
  379. if (is_link || cannot_restrict_permissions)
  380. {
  381. getChildView("CheckShareWithGroup")->setEnabled(FALSE);
  382. getChildView("CheckEveryoneCopy")->setEnabled(FALSE);
  383. }
  384. else if (is_obj_modify && can_agent_manipulate)
  385. {
  386. getChildView("CheckShareWithGroup")->setEnabled(TRUE);
  387. getChildView("CheckEveryoneCopy")->setEnabled((owner_mask & PERM_COPY) && (owner_mask & PERM_TRANSFER));
  388. }
  389. else
  390. {
  391. getChildView("CheckShareWithGroup")->setEnabled(FALSE);
  392. getChildView("CheckEveryoneCopy")->setEnabled(FALSE);
  393. }
  394. // Set values.
  395. BOOL is_group_copy = (group_mask & PERM_COPY) ? TRUE : FALSE;
  396. BOOL is_group_modify = (group_mask & PERM_MODIFY) ? TRUE : FALSE;
  397. BOOL is_group_move = (group_mask & PERM_MOVE) ? TRUE : FALSE;
  398. if (is_group_copy && is_group_modify && is_group_move)
  399. {
  400. getChild<LLUICtrl>("CheckShareWithGroup")->setValue(LLSD((BOOL)TRUE));
  401. LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
  402. if(ctl)
  403. {
  404. ctl->setTentative(FALSE);
  405. }
  406. }
  407. else if (!is_group_copy && !is_group_modify && !is_group_move)
  408. {
  409. getChild<LLUICtrl>("CheckShareWithGroup")->setValue(LLSD((BOOL)FALSE));
  410. LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
  411. if(ctl)
  412. {
  413. ctl->setTentative(FALSE);
  414. }
  415. }
  416. else
  417. {
  418. LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
  419. if(ctl)
  420. {
  421. ctl->setTentative(TRUE);
  422. ctl->set(TRUE);
  423. }
  424. }
  425. getChild<LLUICtrl>("CheckEveryoneCopy")->setValue(LLSD((BOOL)(everyone_mask & PERM_COPY)));
  426. ///////////////
  427. // SALE INFO //
  428. ///////////////
  429. const LLSaleInfo& sale_info = item->getSaleInfo();
  430. BOOL is_for_sale = sale_info.isForSale();
  431. // Check for ability to change values.
  432. if (is_obj_modify && can_agent_sell
  433. && gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE))
  434. {
  435. getChildView("SaleLabel")->setEnabled(is_complete);
  436. getChildView("CheckPurchase")->setEnabled(is_complete);
  437. getChildView("NextOwnerLabel")->setEnabled(TRUE);
  438. getChildView("CheckNextOwnerModify")->setEnabled((base_mask & PERM_MODIFY) && !cannot_restrict_permissions);
  439. getChildView("CheckNextOwnerCopy")->setEnabled((base_mask & PERM_COPY) && !cannot_restrict_permissions);
  440. getChildView("CheckNextOwnerTransfer")->setEnabled((next_owner_mask & PERM_COPY) && !cannot_restrict_permissions);
  441. getChildView("RadioSaleType")->setEnabled(is_complete && is_for_sale);
  442. getChildView("TextPrice")->setEnabled(is_complete && is_for_sale);
  443. getChildView("Edit Cost")->setEnabled(is_complete && is_for_sale);
  444. }
  445. else
  446. {
  447. getChildView("SaleLabel")->setEnabled(FALSE);
  448. getChildView("CheckPurchase")->setEnabled(FALSE);
  449. getChildView("NextOwnerLabel")->setEnabled(FALSE);
  450. getChildView("CheckNextOwnerModify")->setEnabled(FALSE);
  451. getChildView("CheckNextOwnerCopy")->setEnabled(FALSE);
  452. getChildView("CheckNextOwnerTransfer")->setEnabled(FALSE);
  453. getChildView("RadioSaleType")->setEnabled(FALSE);
  454. getChildView("TextPrice")->setEnabled(FALSE);
  455. getChildView("Edit Cost")->setEnabled(FALSE);
  456. }
  457. // Set values.
  458. getChild<LLUICtrl>("CheckPurchase")->setValue(is_for_sale);
  459. getChildView("combobox sale copy")->setEnabled(is_for_sale);
  460. getChildView("Edit Cost")->setEnabled(is_for_sale);
  461. getChild<LLUICtrl>("CheckNextOwnerModify")->setValue(LLSD(BOOL(next_owner_mask & PERM_MODIFY)));
  462. getChild<LLUICtrl>("CheckNextOwnerCopy")->setValue(LLSD(BOOL(next_owner_mask & PERM_COPY)));
  463. getChild<LLUICtrl>("CheckNextOwnerTransfer")->setValue(LLSD(BOOL(next_owner_mask & PERM_TRANSFER)));
  464. LLRadioGroup* radioSaleType = getChild<LLRadioGroup>("RadioSaleType");
  465. if (is_for_sale)
  466. {
  467. radioSaleType->setSelectedIndex((S32)sale_info.getSaleType() - 1);
  468. S32 numerical_price;
  469. numerical_price = sale_info.getSalePrice();
  470. getChild<LLUICtrl>("Edit Cost")->setValue(llformat("%d",numerical_price));
  471. }
  472. else
  473. {
  474. radioSaleType->setSelectedIndex(-1);
  475. getChild<LLUICtrl>("Edit Cost")->setValue(llformat("%d",0));
  476. }
  477. }
  478. void LLFloaterProperties::onClickCreator()
  479. {
  480. LLInventoryItem* item = findItem();
  481. if(!item) return;
  482. if(!item->getCreatorUUID().isNull())
  483. {
  484. LLAvatarActions::showProfile(item->getCreatorUUID());
  485. }
  486. }
  487. // static
  488. void LLFloaterProperties::onClickOwner()
  489. {
  490. LLInventoryItem* item = findItem();
  491. if(!item) return;
  492. if(item->getPermissions().isGroupOwned())
  493. {
  494. LLGroupActions::show(item->getPermissions().getGroup());
  495. }
  496. else
  497. {
  498. LLAvatarActions::showProfile(item->getPermissions().getOwner());
  499. }
  500. }
  501. // static
  502. void LLFloaterProperties::onCommitName()
  503. {
  504. //llinfos << "LLFloaterProperties::onCommitName()" << llendl;
  505. LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem();
  506. if(!item)
  507. {
  508. return;
  509. }
  510. LLLineEditor* labelItemName = getChild<LLLineEditor>("LabelItemName");
  511. if(labelItemName&&
  512. (item->getName() != labelItemName->getText()) &&
  513. (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)) )
  514. {
  515. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
  516. new_item->rename(labelItemName->getText());
  517. if(mObjectID.isNull())
  518. {
  519. new_item->updateServer(FALSE);
  520. gInventory.updateItem(new_item);
  521. gInventory.notifyObservers();
  522. }
  523. else
  524. {
  525. LLViewerObject* object = gObjectList.findObject(mObjectID);
  526. if(object)
  527. {
  528. object->updateInventory(
  529. new_item,
  530. TASK_INVENTORY_ITEM_KEY,
  531. false);
  532. }
  533. }
  534. }
  535. }
  536. void LLFloaterProperties::onCommitDescription()
  537. {
  538. //llinfos << "LLFloaterProperties::onCommitDescription()" << llendl;
  539. LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem();
  540. if(!item) return;
  541. LLLineEditor* labelItemDesc = getChild<LLLineEditor>("LabelItemDesc");
  542. if(!labelItemDesc)
  543. {
  544. return;
  545. }
  546. if((item->getDescription() != labelItemDesc->getText()) &&
  547. (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)))
  548. {
  549. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
  550. new_item->setDescription(labelItemDesc->getText());
  551. if(mObjectID.isNull())
  552. {
  553. new_item->updateServer(FALSE);
  554. gInventory.updateItem(new_item);
  555. gInventory.notifyObservers();
  556. }
  557. else
  558. {
  559. LLViewerObject* object = gObjectList.findObject(mObjectID);
  560. if(object)
  561. {
  562. object->updateInventory(
  563. new_item,
  564. TASK_INVENTORY_ITEM_KEY,
  565. false);
  566. }
  567. }
  568. }
  569. }
  570. // static
  571. void LLFloaterProperties::onCommitPermissions()
  572. {
  573. //llinfos << "LLFloaterProperties::onCommitPermissions()" << llendl;
  574. LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem();
  575. if(!item) return;
  576. LLPermissions perm(item->getPermissions());
  577. LLCheckBoxCtrl* CheckShareWithGroup = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
  578. if(CheckShareWithGroup)
  579. {
  580. perm.setGroupBits(gAgent.getID(), gAgent.getGroupID(),
  581. CheckShareWithGroup->get(),
  582. PERM_MODIFY | PERM_MOVE | PERM_COPY);
  583. }
  584. LLCheckBoxCtrl* CheckEveryoneCopy = getChild<LLCheckBoxCtrl>("CheckEveryoneCopy");
  585. if(CheckEveryoneCopy)
  586. {
  587. perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(),
  588. CheckEveryoneCopy->get(), PERM_COPY);
  589. }
  590. LLCheckBoxCtrl* CheckNextOwnerModify = getChild<LLCheckBoxCtrl>("CheckNextOwnerModify");
  591. if(CheckNextOwnerModify)
  592. {
  593. perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
  594. CheckNextOwnerModify->get(), PERM_MODIFY);
  595. }
  596. LLCheckBoxCtrl* CheckNextOwnerCopy = getChild<LLCheckBoxCtrl>("CheckNextOwnerCopy");
  597. if(CheckNextOwnerCopy)
  598. {
  599. perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
  600. CheckNextOwnerCopy->get(), PERM_COPY);
  601. }
  602. LLCheckBoxCtrl* CheckNextOwnerTransfer = getChild<LLCheckBoxCtrl>("CheckNextOwnerTransfer");
  603. if(CheckNextOwnerTransfer)
  604. {
  605. perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
  606. CheckNextOwnerTransfer->get(), PERM_TRANSFER);
  607. }
  608. if(perm != item->getPermissions()
  609. && item->isFinished())
  610. {
  611. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
  612. new_item->setPermissions(perm);
  613. U32 flags = new_item->getFlags();
  614. // If next owner permissions have changed (and this is an object)
  615. // then set the slam permissions flag so that they are applied on rez.
  616. if((perm.getMaskNextOwner()!=item->getPermissions().getMaskNextOwner())
  617. && (item->getType() == LLAssetType::AT_OBJECT))
  618. {
  619. flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_PERM;
  620. }
  621. // If everyone permissions have changed (and this is an object)
  622. // then set the overwrite everyone permissions flag so they
  623. // are applied on rez.
  624. if ((perm.getMaskEveryone()!=item->getPermissions().getMaskEveryone())
  625. && (item->getType() == LLAssetType::AT_OBJECT))
  626. {
  627. flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE;
  628. }
  629. // If group permissions have changed (and this is an object)
  630. // then set the overwrite group permissions flag so they
  631. // are applied on rez.
  632. if ((perm.getMaskGroup()!=item->getPermissions().getMaskGroup())
  633. && (item->getType() == LLAssetType::AT_OBJECT))
  634. {
  635. flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP;
  636. }
  637. new_item->setFlags(flags);
  638. if(mObjectID.isNull())
  639. {
  640. new_item->updateServer(FALSE);
  641. gInventory.updateItem(new_item);
  642. gInventory.notifyObservers();
  643. }
  644. else
  645. {
  646. LLViewerObject* object = gObjectList.findObject(mObjectID);
  647. if(object)
  648. {
  649. object->updateInventory(
  650. new_item,
  651. TASK_INVENTORY_ITEM_KEY,
  652. false);
  653. }
  654. }
  655. }
  656. else
  657. {
  658. // need to make sure we don't just follow the click
  659. refresh();
  660. }
  661. }
  662. // static
  663. void LLFloaterProperties::onCommitSaleInfo()
  664. {
  665. //llinfos << "LLFloaterProperties::onCommitSaleInfo()" << llendl;
  666. updateSaleInfo();
  667. }
  668. // static
  669. void LLFloaterProperties::onCommitSaleType()
  670. {
  671. //llinfos << "LLFloaterProperties::onCommitSaleType()" << llendl;
  672. updateSaleInfo();
  673. }
  674. void LLFloaterProperties::updateSaleInfo()
  675. {
  676. LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem();
  677. if(!item) return;
  678. LLSaleInfo sale_info(item->getSaleInfo());
  679. if(!gAgent.allowOperation(PERM_TRANSFER, item->getPermissions(), GP_OBJECT_SET_SALE))
  680. {
  681. getChild<LLUICtrl>("CheckPurchase")->setValue(LLSD((BOOL)FALSE));
  682. }
  683. if((BOOL)getChild<LLUICtrl>("CheckPurchase")->getValue())
  684. {
  685. // turn on sale info
  686. LLSaleInfo::EForSale sale_type = LLSaleInfo::FS_COPY;
  687. LLRadioGroup* RadioSaleType = getChild<LLRadioGroup>("RadioSaleType");
  688. if(RadioSaleType)
  689. {
  690. switch (RadioSaleType->getSelectedIndex())
  691. {
  692. case 0:
  693. sale_type = LLSaleInfo::FS_ORIGINAL;
  694. break;
  695. case 1:
  696. sale_type = LLSaleInfo::FS_COPY;
  697. break;
  698. case 2:
  699. sale_type = LLSaleInfo::FS_CONTENTS;
  700. break;
  701. default:
  702. sale_type = LLSaleInfo::FS_COPY;
  703. break;
  704. }
  705. }
  706. if (sale_type == LLSaleInfo::FS_COPY
  707. && !gAgent.allowOperation(PERM_COPY, item->getPermissions(),
  708. GP_OBJECT_SET_SALE))
  709. {
  710. sale_type = LLSaleInfo::FS_ORIGINAL;
  711. }
  712. S32 price = -1;
  713. price = getChild<LLUICtrl>("Edit Cost")->getValue().asInteger();;
  714. // Invalid data - turn off the sale
  715. if (price < 0)
  716. {
  717. sale_type = LLSaleInfo::FS_NOT;
  718. price = 0;
  719. }
  720. sale_info.setSaleType(sale_type);
  721. sale_info.setSalePrice(price);
  722. }
  723. else
  724. {
  725. sale_info.setSaleType(LLSaleInfo::FS_NOT);
  726. }
  727. if(sale_info != item->getSaleInfo()
  728. && item->isFinished())
  729. {
  730. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
  731. // Force an update on the sale price at rez
  732. if (item->getType() == LLAssetType::AT_OBJECT)
  733. {
  734. U32 flags = new_item->getFlags();
  735. flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_SALE;
  736. new_item->setFlags(flags);
  737. }
  738. new_item->setSaleInfo(sale_info);
  739. if(mObjectID.isNull())
  740. {
  741. // This is in the agent's inventory.
  742. new_item->updateServer(FALSE);
  743. gInventory.updateItem(new_item);
  744. gInventory.notifyObservers();
  745. }
  746. else
  747. {
  748. // This is in an object's contents.
  749. LLViewerObject* object = gObjectList.findObject(mObjectID);
  750. if(object)
  751. {
  752. object->updateInventory(
  753. new_item,
  754. TASK_INVENTORY_ITEM_KEY,
  755. false);
  756. }
  757. }
  758. }
  759. else
  760. {
  761. // need to make sure we don't just follow the click
  762. refresh();
  763. }
  764. }
  765. LLInventoryItem* LLFloaterProperties::findItem() const
  766. {
  767. LLInventoryItem* item = NULL;
  768. if(mObjectID.isNull())
  769. {
  770. // it is in agent inventory
  771. item = gInventory.getItem(mItemID);
  772. }
  773. else
  774. {
  775. LLViewerObject* object = gObjectList.findObject(mObjectID);
  776. if(object)
  777. {
  778. item = (LLInventoryItem*)object->getInventoryObject(mItemID);
  779. }
  780. }
  781. return item;
  782. }
  783. //static
  784. void LLFloaterProperties::dirtyAll()
  785. {
  786. LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("properties");
  787. for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
  788. iter != inst_list.end(); ++iter)
  789. {
  790. LLFloaterProperties* floater = dynamic_cast<LLFloaterProperties*>(*iter);
  791. llassert(floater); // else cast failed - wrong type D:
  792. if (floater)
  793. {
  794. floater->dirty();
  795. }
  796. }
  797. }
  798. ///----------------------------------------------------------------------------
  799. /// LLMultiProperties
  800. ///----------------------------------------------------------------------------
  801. LLMultiProperties::LLMultiProperties()
  802. : LLMultiFloater(LLSD())
  803. {
  804. // start with a small rect in the top-left corner ; will get resized
  805. LLRect rect;
  806. rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 20, 20);
  807. setRect(rect);
  808. LLFloater* last_floater = LLFloaterReg::getLastFloaterInGroup("properties");
  809. if (last_floater)
  810. {
  811. stackWith(*last_floater);
  812. }
  813. setTitle(LLTrans::getString("MultiPropertiesTitle"));
  814. buildTabContainer();
  815. }
  816. ///----------------------------------------------------------------------------
  817. /// Local function definitions
  818. ///----------------------------------------------------------------------------