PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llsidepaneliteminfo.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1035 lines | 799 code | 109 blank | 127 comment | 124 complexity | 87fdca359d1e77257a1c4ac31654f1c8 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsidepaneliteminfo.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 "llsidepaneliteminfo.h"
  28. #include "roles_constants.h"
  29. #include "llagent.h"
  30. #include "llavataractions.h"
  31. #include "llbutton.h"
  32. #include "llfloaterreg.h"
  33. #include "llgroupactions.h"
  34. #include "llinventorydefines.h"
  35. #include "llinventorymodel.h"
  36. #include "llinventoryobserver.h"
  37. #include "lllineeditor.h"
  38. #include "llradiogroup.h"
  39. #include "llslurl.h"
  40. #include "llviewercontrol.h"
  41. #include "llviewerinventory.h"
  42. #include "llviewerobjectlist.h"
  43. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  44. // Class LLItemPropertiesObserver
  45. //
  46. // Helper class to watch for changes to the item.
  47. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  48. class LLItemPropertiesObserver : public LLInventoryObserver
  49. {
  50. public:
  51. LLItemPropertiesObserver(LLSidepanelItemInfo* floater)
  52. : mFloater(floater)
  53. {
  54. gInventory.addObserver(this);
  55. }
  56. virtual ~LLItemPropertiesObserver()
  57. {
  58. gInventory.removeObserver(this);
  59. }
  60. virtual void changed(U32 mask);
  61. private:
  62. LLSidepanelItemInfo* mFloater;
  63. };
  64. void LLItemPropertiesObserver::changed(U32 mask)
  65. {
  66. const std::set<LLUUID>& mChangedItemIDs = gInventory.getChangedIDs();
  67. std::set<LLUUID>::const_iterator it;
  68. const LLUUID& item_id = mFloater->getItemID();
  69. for (it = mChangedItemIDs.begin(); it != mChangedItemIDs.end(); it++)
  70. {
  71. // set dirty for 'item profile panel' only if changed item is the item for which 'item profile panel' is shown (STORM-288)
  72. if (*it == item_id)
  73. {
  74. // if there's a change we're interested in.
  75. if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0)
  76. {
  77. mFloater->dirty();
  78. }
  79. }
  80. }
  81. }
  82. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  83. // Class LLObjectInventoryObserver
  84. //
  85. // Helper class to watch for changes in an object inventory.
  86. // Used to update item properties in LLSidepanelItemInfo.
  87. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  88. class LLObjectInventoryObserver : public LLVOInventoryListener
  89. {
  90. public:
  91. LLObjectInventoryObserver(LLSidepanelItemInfo* floater, LLViewerObject* object)
  92. : mFloater(floater)
  93. {
  94. registerVOInventoryListener(object, NULL);
  95. }
  96. virtual ~LLObjectInventoryObserver()
  97. {
  98. removeVOInventoryListener();
  99. }
  100. /*virtual*/ void inventoryChanged(LLViewerObject* object,
  101. LLInventoryObject::object_list_t* inventory,
  102. S32 serial_num,
  103. void* user_data);
  104. private:
  105. LLSidepanelItemInfo* mFloater;
  106. };
  107. /*virtual*/
  108. void LLObjectInventoryObserver::inventoryChanged(LLViewerObject* object,
  109. LLInventoryObject::object_list_t* inventory,
  110. S32 serial_num,
  111. void* user_data)
  112. {
  113. mFloater->dirty();
  114. }
  115. ///----------------------------------------------------------------------------
  116. /// Class LLSidepanelItemInfo
  117. ///----------------------------------------------------------------------------
  118. static LLRegisterPanelClassWrapper<LLSidepanelItemInfo> t_item_info("sidepanel_item_info");
  119. // Default constructor
  120. LLSidepanelItemInfo::LLSidepanelItemInfo(const LLPanel::Params& p)
  121. : LLSidepanelInventorySubpanel(p)
  122. , mItemID(LLUUID::null)
  123. , mObjectInventoryObserver(NULL)
  124. {
  125. mPropertiesObserver = new LLItemPropertiesObserver(this);
  126. }
  127. // Destroys the object
  128. LLSidepanelItemInfo::~LLSidepanelItemInfo()
  129. {
  130. delete mPropertiesObserver;
  131. mPropertiesObserver = NULL;
  132. stopObjectInventoryObserver();
  133. }
  134. // virtual
  135. BOOL LLSidepanelItemInfo::postBuild()
  136. {
  137. LLSidepanelInventorySubpanel::postBuild();
  138. getChild<LLLineEditor>("LabelItemName")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
  139. getChild<LLUICtrl>("LabelItemName")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitName,this));
  140. getChild<LLLineEditor>("LabelItemDesc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
  141. getChild<LLUICtrl>("LabelItemDesc")->setCommitCallback(boost::bind(&LLSidepanelItemInfo:: onCommitDescription, this));
  142. // Creator information
  143. getChild<LLUICtrl>("BtnCreator")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onClickCreator,this));
  144. // owner information
  145. getChild<LLUICtrl>("BtnOwner")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onClickOwner,this));
  146. // acquired date
  147. // owner permissions
  148. // Permissions debug text
  149. // group permissions
  150. getChild<LLUICtrl>("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
  151. // everyone permissions
  152. getChild<LLUICtrl>("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
  153. // next owner permissions
  154. getChild<LLUICtrl>("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
  155. getChild<LLUICtrl>("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
  156. getChild<LLUICtrl>("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
  157. // Mark for sale or not, and sale info
  158. getChild<LLUICtrl>("CheckPurchase")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this));
  159. // "Price" label for edit
  160. getChild<LLUICtrl>("Edit Cost")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this));
  161. refresh();
  162. return TRUE;
  163. }
  164. void LLSidepanelItemInfo::setObjectID(const LLUUID& object_id)
  165. {
  166. mObjectID = object_id;
  167. // Start monitoring changes in the object inventory to update
  168. // selected inventory item properties in Item Profile panel. See STORM-148.
  169. startObjectInventoryObserver();
  170. }
  171. void LLSidepanelItemInfo::setItemID(const LLUUID& item_id)
  172. {
  173. mItemID = item_id;
  174. }
  175. const LLUUID& LLSidepanelItemInfo::getObjectID() const
  176. {
  177. return mObjectID;
  178. }
  179. const LLUUID& LLSidepanelItemInfo::getItemID() const
  180. {
  181. return mItemID;
  182. }
  183. void LLSidepanelItemInfo::reset()
  184. {
  185. LLSidepanelInventorySubpanel::reset();
  186. mObjectID = LLUUID::null;
  187. mItemID = LLUUID::null;
  188. stopObjectInventoryObserver();
  189. }
  190. void LLSidepanelItemInfo::refresh()
  191. {
  192. LLViewerInventoryItem* item = findItem();
  193. if(item)
  194. {
  195. refreshFromItem(item);
  196. updateVerbs();
  197. return;
  198. }
  199. else
  200. {
  201. if (getIsEditing())
  202. {
  203. setIsEditing(FALSE);
  204. }
  205. }
  206. if (!getIsEditing())
  207. {
  208. const std::string no_item_names[]={
  209. "LabelItemName",
  210. "LabelItemDesc",
  211. "LabelCreatorName",
  212. "LabelOwnerName",
  213. "CheckOwnerModify",
  214. "CheckOwnerCopy",
  215. "CheckOwnerTransfer",
  216. "CheckShareWithGroup",
  217. "CheckEveryoneCopy",
  218. "CheckNextOwnerModify",
  219. "CheckNextOwnerCopy",
  220. "CheckNextOwnerTransfer",
  221. "CheckPurchase",
  222. "Edit Cost"
  223. };
  224. for(size_t t=0; t<LL_ARRAY_SIZE(no_item_names); ++t)
  225. {
  226. getChildView(no_item_names[t])->setEnabled(false);
  227. }
  228. const std::string hide_names[]={
  229. "BaseMaskDebug",
  230. "OwnerMaskDebug",
  231. "GroupMaskDebug",
  232. "EveryoneMaskDebug",
  233. "NextMaskDebug"
  234. };
  235. for(size_t t=0; t<LL_ARRAY_SIZE(hide_names); ++t)
  236. {
  237. getChildView(hide_names[t])->setVisible(false);
  238. }
  239. }
  240. if (!item)
  241. {
  242. const std::string no_edit_mode_names[]={
  243. "BtnCreator",
  244. "BtnOwner",
  245. };
  246. for(size_t t=0; t<LL_ARRAY_SIZE(no_edit_mode_names); ++t)
  247. {
  248. getChildView(no_edit_mode_names[t])->setEnabled(false);
  249. }
  250. }
  251. updateVerbs();
  252. }
  253. void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
  254. {
  255. ////////////////////////
  256. // PERMISSIONS LOOKUP //
  257. ////////////////////////
  258. llassert(item);
  259. if (!item) return;
  260. // do not enable the UI for incomplete items.
  261. BOOL is_complete = item->isFinished();
  262. const BOOL cannot_restrict_permissions = LLInventoryType::cannotRestrictPermissions(item->getInventoryType());
  263. const BOOL is_calling_card = (item->getInventoryType() == LLInventoryType::IT_CALLINGCARD);
  264. const LLPermissions& perm = item->getPermissions();
  265. const BOOL can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm,
  266. GP_OBJECT_MANIPULATE);
  267. const BOOL can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm,
  268. GP_OBJECT_SET_SALE) &&
  269. !cannot_restrict_permissions;
  270. const BOOL is_link = item->getIsLinkType();
  271. const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
  272. bool not_in_trash = (item->getUUID() != trash_id) && !gInventory.isObjectDescendentOf(item->getUUID(), trash_id);
  273. // You need permission to modify the object to modify an inventory
  274. // item in it.
  275. LLViewerObject* object = NULL;
  276. if(!mObjectID.isNull()) object = gObjectList.findObject(mObjectID);
  277. BOOL is_obj_modify = TRUE;
  278. if(object)
  279. {
  280. is_obj_modify = object->permOwnerModify();
  281. }
  282. //////////////////////
  283. // ITEM NAME & DESC //
  284. //////////////////////
  285. BOOL is_modifiable = gAgent.allowOperation(PERM_MODIFY, perm,
  286. GP_OBJECT_MANIPULATE)
  287. && is_obj_modify && is_complete && not_in_trash;
  288. getChildView("LabelItemNameTitle")->setEnabled(TRUE);
  289. getChildView("LabelItemName")->setEnabled(is_modifiable && !is_calling_card); // for now, don't allow rename of calling cards
  290. getChild<LLUICtrl>("LabelItemName")->setValue(item->getName());
  291. getChildView("LabelItemDescTitle")->setEnabled(TRUE);
  292. getChildView("LabelItemDesc")->setEnabled(is_modifiable);
  293. getChildView("IconLocked")->setVisible(!is_modifiable);
  294. getChild<LLUICtrl>("LabelItemDesc")->setValue(item->getDescription());
  295. //////////////////
  296. // CREATOR NAME //
  297. //////////////////
  298. if(!gCacheName) return;
  299. if(!gAgent.getRegion()) return;
  300. if (item->getCreatorUUID().notNull())
  301. {
  302. LLUUID creator_id = item->getCreatorUUID();
  303. std::string name =
  304. LLSLURL("agent", creator_id, "completename").getSLURLString();
  305. getChildView("BtnCreator")->setEnabled(TRUE);
  306. getChildView("LabelCreatorTitle")->setEnabled(TRUE);
  307. getChildView("LabelCreatorName")->setEnabled(FALSE);
  308. getChild<LLUICtrl>("LabelCreatorName")->setValue(name);
  309. }
  310. else
  311. {
  312. getChildView("BtnCreator")->setEnabled(FALSE);
  313. getChildView("LabelCreatorTitle")->setEnabled(FALSE);
  314. getChildView("LabelCreatorName")->setEnabled(FALSE);
  315. getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown"));
  316. }
  317. ////////////////
  318. // OWNER NAME //
  319. ////////////////
  320. if(perm.isOwned())
  321. {
  322. std::string name;
  323. if (perm.isGroupOwned())
  324. {
  325. gCacheName->getGroupName(perm.getGroup(), name);
  326. }
  327. else
  328. {
  329. LLUUID owner_id = perm.getOwner();
  330. name = LLSLURL("agent", owner_id, "completename").getSLURLString();
  331. }
  332. getChildView("BtnOwner")->setEnabled(TRUE);
  333. getChildView("LabelOwnerTitle")->setEnabled(TRUE);
  334. getChildView("LabelOwnerName")->setEnabled(FALSE);
  335. getChild<LLUICtrl>("LabelOwnerName")->setValue(name);
  336. }
  337. else
  338. {
  339. getChildView("BtnOwner")->setEnabled(FALSE);
  340. getChildView("LabelOwnerTitle")->setEnabled(FALSE);
  341. getChildView("LabelOwnerName")->setEnabled(FALSE);
  342. getChild<LLUICtrl>("LabelOwnerName")->setValue(getString("public"));
  343. }
  344. ////////////
  345. // ORIGIN //
  346. ////////////
  347. if (object)
  348. {
  349. getChild<LLUICtrl>("origin")->setValue(getString("origin_inworld"));
  350. }
  351. else
  352. {
  353. getChild<LLUICtrl>("origin")->setValue(getString("origin_inventory"));
  354. }
  355. //////////////////
  356. // ACQUIRE DATE //
  357. //////////////////
  358. time_t time_utc = item->getCreationDate();
  359. if (0 == time_utc)
  360. {
  361. getChild<LLUICtrl>("LabelAcquiredDate")->setValue(getString("unknown"));
  362. }
  363. else
  364. {
  365. std::string timeStr = getString("acquiredDate");
  366. LLSD substitution;
  367. substitution["datetime"] = (S32) time_utc;
  368. LLStringUtil::format (timeStr, substitution);
  369. getChild<LLUICtrl>("LabelAcquiredDate")->setValue(timeStr);
  370. }
  371. //////////////////////////////////////
  372. // PERMISSIONS AND SALE ITEM HIDING //
  373. //////////////////////////////////////
  374. const std::string perm_and_sale_items[]={
  375. "perms_inv",
  376. "OwnerLabel",
  377. "perm_modify",
  378. "CheckOwnerModify",
  379. "CheckOwnerCopy",
  380. "CheckOwnerTransfer",
  381. "GroupLabel",
  382. "CheckShareWithGroup",
  383. "AnyoneLabel",
  384. "CheckEveryoneCopy",
  385. "NextOwnerLabel",
  386. "CheckNextOwnerModify",
  387. "CheckNextOwnerCopy",
  388. "CheckNextOwnerTransfer",
  389. "CheckPurchase",
  390. "SaleLabel",
  391. "combobox sale copy",
  392. "Edit Cost",
  393. "TextPrice"
  394. };
  395. const std::string debug_items[]={
  396. "BaseMaskDebug",
  397. "OwnerMaskDebug",
  398. "GroupMaskDebug",
  399. "EveryoneMaskDebug",
  400. "NextMaskDebug"
  401. };
  402. // Hide permissions checkboxes and labels and for sale info if in the trash
  403. // or ui elements don't apply to these objects and return from function
  404. if (!not_in_trash || cannot_restrict_permissions)
  405. {
  406. for(size_t t=0; t<LL_ARRAY_SIZE(perm_and_sale_items); ++t)
  407. {
  408. getChildView(perm_and_sale_items[t])->setVisible(false);
  409. }
  410. for(size_t t=0; t<LL_ARRAY_SIZE(debug_items); ++t)
  411. {
  412. getChildView(debug_items[t])->setVisible(false);
  413. }
  414. return;
  415. }
  416. else // Make sure perms and sale ui elements are visible
  417. {
  418. for(size_t t=0; t<LL_ARRAY_SIZE(perm_and_sale_items); ++t)
  419. {
  420. getChildView(perm_and_sale_items[t])->setVisible(true);
  421. }
  422. }
  423. ///////////////////////
  424. // OWNER PERMISSIONS //
  425. ///////////////////////
  426. if(can_agent_manipulate)
  427. {
  428. getChild<LLUICtrl>("OwnerLabel")->setValue(getString("you_can"));
  429. }
  430. else
  431. {
  432. getChild<LLUICtrl>("OwnerLabel")->setValue(getString("owner_can"));
  433. }
  434. U32 base_mask = perm.getMaskBase();
  435. U32 owner_mask = perm.getMaskOwner();
  436. U32 group_mask = perm.getMaskGroup();
  437. U32 everyone_mask = perm.getMaskEveryone();
  438. U32 next_owner_mask = perm.getMaskNextOwner();
  439. getChildView("OwnerLabel")->setEnabled(TRUE);
  440. getChildView("CheckOwnerModify")->setEnabled(FALSE);
  441. getChild<LLUICtrl>("CheckOwnerModify")->setValue(LLSD((BOOL)(owner_mask & PERM_MODIFY)));
  442. getChildView("CheckOwnerCopy")->setEnabled(FALSE);
  443. getChild<LLUICtrl>("CheckOwnerCopy")->setValue(LLSD((BOOL)(owner_mask & PERM_COPY)));
  444. getChildView("CheckOwnerTransfer")->setEnabled(FALSE);
  445. getChild<LLUICtrl>("CheckOwnerTransfer")->setValue(LLSD((BOOL)(owner_mask & PERM_TRANSFER)));
  446. ///////////////////////
  447. // DEBUG PERMISSIONS //
  448. ///////////////////////
  449. if( gSavedSettings.getBOOL("DebugPermissions") )
  450. {
  451. BOOL slam_perm = FALSE;
  452. BOOL overwrite_group = FALSE;
  453. BOOL overwrite_everyone = FALSE;
  454. if (item->getType() == LLAssetType::AT_OBJECT)
  455. {
  456. U32 flags = item->getFlags();
  457. slam_perm = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_PERM;
  458. overwrite_everyone = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE;
  459. overwrite_group = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP;
  460. }
  461. std::string perm_string;
  462. perm_string = "B: ";
  463. perm_string += mask_to_string(base_mask);
  464. getChild<LLUICtrl>("BaseMaskDebug")->setValue(perm_string);
  465. getChildView("BaseMaskDebug")->setVisible(TRUE);
  466. perm_string = "O: ";
  467. perm_string += mask_to_string(owner_mask);
  468. getChild<LLUICtrl>("OwnerMaskDebug")->setValue(perm_string);
  469. getChildView("OwnerMaskDebug")->setVisible(TRUE);
  470. perm_string = "G";
  471. perm_string += overwrite_group ? "*: " : ": ";
  472. perm_string += mask_to_string(group_mask);
  473. getChild<LLUICtrl>("GroupMaskDebug")->setValue(perm_string);
  474. getChildView("GroupMaskDebug")->setVisible(TRUE);
  475. perm_string = "E";
  476. perm_string += overwrite_everyone ? "*: " : ": ";
  477. perm_string += mask_to_string(everyone_mask);
  478. getChild<LLUICtrl>("EveryoneMaskDebug")->setValue(perm_string);
  479. getChildView("EveryoneMaskDebug")->setVisible(TRUE);
  480. perm_string = "N";
  481. perm_string += slam_perm ? "*: " : ": ";
  482. perm_string += mask_to_string(next_owner_mask);
  483. getChild<LLUICtrl>("NextMaskDebug")->setValue(perm_string);
  484. getChildView("NextMaskDebug")->setVisible(TRUE);
  485. }
  486. else
  487. {
  488. getChildView("BaseMaskDebug")->setVisible(FALSE);
  489. getChildView("OwnerMaskDebug")->setVisible(FALSE);
  490. getChildView("GroupMaskDebug")->setVisible(FALSE);
  491. getChildView("EveryoneMaskDebug")->setVisible(FALSE);
  492. getChildView("NextMaskDebug")->setVisible(FALSE);
  493. }
  494. /////////////
  495. // SHARING //
  496. /////////////
  497. // Check for ability to change values.
  498. if (is_link || cannot_restrict_permissions)
  499. {
  500. getChildView("CheckShareWithGroup")->setEnabled(FALSE);
  501. getChildView("CheckEveryoneCopy")->setEnabled(FALSE);
  502. }
  503. else if (is_obj_modify && can_agent_manipulate)
  504. {
  505. getChildView("CheckShareWithGroup")->setEnabled(TRUE);
  506. getChildView("CheckEveryoneCopy")->setEnabled((owner_mask & PERM_COPY) && (owner_mask & PERM_TRANSFER));
  507. }
  508. else
  509. {
  510. getChildView("CheckShareWithGroup")->setEnabled(FALSE);
  511. getChildView("CheckEveryoneCopy")->setEnabled(FALSE);
  512. }
  513. // Set values.
  514. BOOL is_group_copy = (group_mask & PERM_COPY) ? TRUE : FALSE;
  515. BOOL is_group_modify = (group_mask & PERM_MODIFY) ? TRUE : FALSE;
  516. BOOL is_group_move = (group_mask & PERM_MOVE) ? TRUE : FALSE;
  517. if (is_group_copy && is_group_modify && is_group_move)
  518. {
  519. getChild<LLUICtrl>("CheckShareWithGroup")->setValue(LLSD((BOOL)TRUE));
  520. LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
  521. if(ctl)
  522. {
  523. ctl->setTentative(FALSE);
  524. }
  525. }
  526. else if (!is_group_copy && !is_group_modify && !is_group_move)
  527. {
  528. getChild<LLUICtrl>("CheckShareWithGroup")->setValue(LLSD((BOOL)FALSE));
  529. LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
  530. if(ctl)
  531. {
  532. ctl->setTentative(FALSE);
  533. }
  534. }
  535. else
  536. {
  537. LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
  538. if(ctl)
  539. {
  540. ctl->setTentative(TRUE);
  541. ctl->set(TRUE);
  542. }
  543. }
  544. getChild<LLUICtrl>("CheckEveryoneCopy")->setValue(LLSD((BOOL)(everyone_mask & PERM_COPY)));
  545. ///////////////
  546. // SALE INFO //
  547. ///////////////
  548. const LLSaleInfo& sale_info = item->getSaleInfo();
  549. BOOL is_for_sale = sale_info.isForSale();
  550. // Check for ability to change values.
  551. if (is_obj_modify && can_agent_sell
  552. && gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE))
  553. {
  554. getChildView("SaleLabel")->setEnabled(is_complete);
  555. getChildView("CheckPurchase")->setEnabled(is_complete);
  556. getChildView("NextOwnerLabel")->setEnabled(TRUE);
  557. getChildView("CheckNextOwnerModify")->setEnabled((base_mask & PERM_MODIFY) && !cannot_restrict_permissions);
  558. getChildView("CheckNextOwnerCopy")->setEnabled((base_mask & PERM_COPY) && !cannot_restrict_permissions);
  559. getChildView("CheckNextOwnerTransfer")->setEnabled((next_owner_mask & PERM_COPY) && !cannot_restrict_permissions);
  560. getChildView("TextPrice")->setEnabled(is_complete && is_for_sale);
  561. getChildView("Edit Cost")->setEnabled(is_complete && is_for_sale);
  562. }
  563. else
  564. {
  565. getChildView("SaleLabel")->setEnabled(FALSE);
  566. getChildView("CheckPurchase")->setEnabled(FALSE);
  567. getChildView("NextOwnerLabel")->setEnabled(FALSE);
  568. getChildView("CheckNextOwnerModify")->setEnabled(FALSE);
  569. getChildView("CheckNextOwnerCopy")->setEnabled(FALSE);
  570. getChildView("CheckNextOwnerTransfer")->setEnabled(FALSE);
  571. getChildView("TextPrice")->setEnabled(FALSE);
  572. getChildView("Edit Cost")->setEnabled(FALSE);
  573. }
  574. // Set values.
  575. getChild<LLUICtrl>("CheckPurchase")->setValue(is_for_sale);
  576. getChildView("combobox sale copy")->setEnabled(is_for_sale);
  577. getChildView("Edit Cost")->setEnabled(is_for_sale);
  578. getChild<LLUICtrl>("CheckNextOwnerModify")->setValue(LLSD(BOOL(next_owner_mask & PERM_MODIFY)));
  579. getChild<LLUICtrl>("CheckNextOwnerCopy")->setValue(LLSD(BOOL(next_owner_mask & PERM_COPY)));
  580. getChild<LLUICtrl>("CheckNextOwnerTransfer")->setValue(LLSD(BOOL(next_owner_mask & PERM_TRANSFER)));
  581. if (is_for_sale)
  582. {
  583. S32 numerical_price;
  584. numerical_price = sale_info.getSalePrice();
  585. getChild<LLUICtrl>("Edit Cost")->setValue(llformat("%d",numerical_price));
  586. }
  587. else
  588. {
  589. getChild<LLUICtrl>("Edit Cost")->setValue(llformat("%d",0));
  590. }
  591. }
  592. void LLSidepanelItemInfo::startObjectInventoryObserver()
  593. {
  594. if (!mObjectInventoryObserver)
  595. {
  596. stopObjectInventoryObserver();
  597. // Previous object observer should be removed before starting to observe a new object.
  598. llassert(mObjectInventoryObserver == NULL);
  599. }
  600. if (mObjectID.isNull())
  601. {
  602. llwarns << "Empty object id passed to inventory observer" << llendl;
  603. return;
  604. }
  605. LLViewerObject* object = gObjectList.findObject(mObjectID);
  606. mObjectInventoryObserver = new LLObjectInventoryObserver(this, object);
  607. }
  608. void LLSidepanelItemInfo::stopObjectInventoryObserver()
  609. {
  610. delete mObjectInventoryObserver;
  611. mObjectInventoryObserver = NULL;
  612. }
  613. void LLSidepanelItemInfo::onClickCreator()
  614. {
  615. LLViewerInventoryItem* item = findItem();
  616. if(!item) return;
  617. if(!item->getCreatorUUID().isNull())
  618. {
  619. LLAvatarActions::showProfile(item->getCreatorUUID());
  620. }
  621. }
  622. // static
  623. void LLSidepanelItemInfo::onClickOwner()
  624. {
  625. LLViewerInventoryItem* item = findItem();
  626. if(!item) return;
  627. if(item->getPermissions().isGroupOwned())
  628. {
  629. LLGroupActions::show(item->getPermissions().getGroup());
  630. }
  631. else
  632. {
  633. LLAvatarActions::showProfile(item->getPermissions().getOwner());
  634. }
  635. }
  636. // static
  637. void LLSidepanelItemInfo::onCommitName()
  638. {
  639. //llinfos << "LLSidepanelItemInfo::onCommitName()" << llendl;
  640. LLViewerInventoryItem* item = findItem();
  641. if(!item)
  642. {
  643. return;
  644. }
  645. LLLineEditor* labelItemName = getChild<LLLineEditor>("LabelItemName");
  646. if(labelItemName&&
  647. (item->getName() != labelItemName->getText()) &&
  648. (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)) )
  649. {
  650. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
  651. new_item->rename(labelItemName->getText());
  652. if(mObjectID.isNull())
  653. {
  654. new_item->updateServer(FALSE);
  655. gInventory.updateItem(new_item);
  656. gInventory.notifyObservers();
  657. }
  658. else
  659. {
  660. LLViewerObject* object = gObjectList.findObject(mObjectID);
  661. if(object)
  662. {
  663. object->updateInventory(
  664. new_item,
  665. TASK_INVENTORY_ITEM_KEY,
  666. false);
  667. }
  668. }
  669. }
  670. }
  671. void LLSidepanelItemInfo::onCommitDescription()
  672. {
  673. //llinfos << "LLSidepanelItemInfo::onCommitDescription()" << llendl;
  674. LLViewerInventoryItem* item = findItem();
  675. if(!item) return;
  676. LLLineEditor* labelItemDesc = getChild<LLLineEditor>("LabelItemDesc");
  677. if(!labelItemDesc)
  678. {
  679. return;
  680. }
  681. if((item->getDescription() != labelItemDesc->getText()) &&
  682. (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)))
  683. {
  684. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
  685. new_item->setDescription(labelItemDesc->getText());
  686. if(mObjectID.isNull())
  687. {
  688. new_item->updateServer(FALSE);
  689. gInventory.updateItem(new_item);
  690. gInventory.notifyObservers();
  691. }
  692. else
  693. {
  694. LLViewerObject* object = gObjectList.findObject(mObjectID);
  695. if(object)
  696. {
  697. object->updateInventory(
  698. new_item,
  699. TASK_INVENTORY_ITEM_KEY,
  700. false);
  701. }
  702. }
  703. }
  704. }
  705. // static
  706. void LLSidepanelItemInfo::onCommitPermissions()
  707. {
  708. //llinfos << "LLSidepanelItemInfo::onCommitPermissions()" << llendl;
  709. LLViewerInventoryItem* item = findItem();
  710. if(!item) return;
  711. LLPermissions perm(item->getPermissions());
  712. LLCheckBoxCtrl* CheckShareWithGroup = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
  713. if(CheckShareWithGroup)
  714. {
  715. perm.setGroupBits(gAgent.getID(), gAgent.getGroupID(),
  716. CheckShareWithGroup->get(),
  717. PERM_MODIFY | PERM_MOVE | PERM_COPY);
  718. }
  719. LLCheckBoxCtrl* CheckEveryoneCopy = getChild<LLCheckBoxCtrl>("CheckEveryoneCopy");
  720. if(CheckEveryoneCopy)
  721. {
  722. perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(),
  723. CheckEveryoneCopy->get(), PERM_COPY);
  724. }
  725. LLCheckBoxCtrl* CheckNextOwnerModify = getChild<LLCheckBoxCtrl>("CheckNextOwnerModify");
  726. if(CheckNextOwnerModify)
  727. {
  728. perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
  729. CheckNextOwnerModify->get(), PERM_MODIFY);
  730. }
  731. LLCheckBoxCtrl* CheckNextOwnerCopy = getChild<LLCheckBoxCtrl>("CheckNextOwnerCopy");
  732. if(CheckNextOwnerCopy)
  733. {
  734. perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
  735. CheckNextOwnerCopy->get(), PERM_COPY);
  736. }
  737. LLCheckBoxCtrl* CheckNextOwnerTransfer = getChild<LLCheckBoxCtrl>("CheckNextOwnerTransfer");
  738. if(CheckNextOwnerTransfer)
  739. {
  740. perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
  741. CheckNextOwnerTransfer->get(), PERM_TRANSFER);
  742. }
  743. if(perm != item->getPermissions()
  744. && item->isFinished())
  745. {
  746. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
  747. new_item->setPermissions(perm);
  748. U32 flags = new_item->getFlags();
  749. // If next owner permissions have changed (and this is an object)
  750. // then set the slam permissions flag so that they are applied on rez.
  751. if((perm.getMaskNextOwner()!=item->getPermissions().getMaskNextOwner())
  752. && (item->getType() == LLAssetType::AT_OBJECT))
  753. {
  754. flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_PERM;
  755. }
  756. // If everyone permissions have changed (and this is an object)
  757. // then set the overwrite everyone permissions flag so they
  758. // are applied on rez.
  759. if ((perm.getMaskEveryone()!=item->getPermissions().getMaskEveryone())
  760. && (item->getType() == LLAssetType::AT_OBJECT))
  761. {
  762. flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE;
  763. }
  764. // If group permissions have changed (and this is an object)
  765. // then set the overwrite group permissions flag so they
  766. // are applied on rez.
  767. if ((perm.getMaskGroup()!=item->getPermissions().getMaskGroup())
  768. && (item->getType() == LLAssetType::AT_OBJECT))
  769. {
  770. flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP;
  771. }
  772. new_item->setFlags(flags);
  773. if(mObjectID.isNull())
  774. {
  775. new_item->updateServer(FALSE);
  776. gInventory.updateItem(new_item);
  777. gInventory.notifyObservers();
  778. }
  779. else
  780. {
  781. LLViewerObject* object = gObjectList.findObject(mObjectID);
  782. if(object)
  783. {
  784. object->updateInventory(
  785. new_item,
  786. TASK_INVENTORY_ITEM_KEY,
  787. false);
  788. }
  789. }
  790. }
  791. else
  792. {
  793. // need to make sure we don't just follow the click
  794. refresh();
  795. }
  796. }
  797. // static
  798. void LLSidepanelItemInfo::onCommitSaleInfo()
  799. {
  800. //llinfos << "LLSidepanelItemInfo::onCommitSaleInfo()" << llendl;
  801. updateSaleInfo();
  802. }
  803. // static
  804. void LLSidepanelItemInfo::onCommitSaleType()
  805. {
  806. //llinfos << "LLSidepanelItemInfo::onCommitSaleType()" << llendl;
  807. updateSaleInfo();
  808. }
  809. void LLSidepanelItemInfo::updateSaleInfo()
  810. {
  811. LLViewerInventoryItem* item = findItem();
  812. if(!item) return;
  813. LLSaleInfo sale_info(item->getSaleInfo());
  814. if(!gAgent.allowOperation(PERM_TRANSFER, item->getPermissions(), GP_OBJECT_SET_SALE))
  815. {
  816. getChild<LLUICtrl>("CheckPurchase")->setValue(LLSD((BOOL)FALSE));
  817. }
  818. if((BOOL)getChild<LLUICtrl>("CheckPurchase")->getValue())
  819. {
  820. // turn on sale info
  821. LLSaleInfo::EForSale sale_type = LLSaleInfo::FS_COPY;
  822. LLRadioGroup* RadioSaleType = getChild<LLRadioGroup>("RadioSaleType");
  823. if(RadioSaleType)
  824. {
  825. switch (RadioSaleType->getSelectedIndex())
  826. {
  827. case 0:
  828. sale_type = LLSaleInfo::FS_ORIGINAL;
  829. break;
  830. case 1:
  831. sale_type = LLSaleInfo::FS_COPY;
  832. break;
  833. case 2:
  834. sale_type = LLSaleInfo::FS_CONTENTS;
  835. break;
  836. default:
  837. sale_type = LLSaleInfo::FS_COPY;
  838. break;
  839. }
  840. }
  841. if (sale_type == LLSaleInfo::FS_COPY
  842. && !gAgent.allowOperation(PERM_COPY, item->getPermissions(),
  843. GP_OBJECT_SET_SALE))
  844. {
  845. sale_type = LLSaleInfo::FS_ORIGINAL;
  846. }
  847. S32 price = -1;
  848. price = getChild<LLUICtrl>("Edit Cost")->getValue().asInteger();;
  849. // Invalid data - turn off the sale
  850. if (price < 0)
  851. {
  852. sale_type = LLSaleInfo::FS_NOT;
  853. price = 0;
  854. }
  855. sale_info.setSaleType(sale_type);
  856. sale_info.setSalePrice(price);
  857. }
  858. else
  859. {
  860. sale_info.setSaleType(LLSaleInfo::FS_NOT);
  861. }
  862. if(sale_info != item->getSaleInfo()
  863. && item->isFinished())
  864. {
  865. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
  866. // Force an update on the sale price at rez
  867. if (item->getType() == LLAssetType::AT_OBJECT)
  868. {
  869. U32 flags = new_item->getFlags();
  870. flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_SALE;
  871. new_item->setFlags(flags);
  872. }
  873. new_item->setSaleInfo(sale_info);
  874. if(mObjectID.isNull())
  875. {
  876. // This is in the agent's inventory.
  877. new_item->updateServer(FALSE);
  878. gInventory.updateItem(new_item);
  879. gInventory.notifyObservers();
  880. }
  881. else
  882. {
  883. // This is in an object's contents.
  884. LLViewerObject* object = gObjectList.findObject(mObjectID);
  885. if(object)
  886. {
  887. object->updateInventory(
  888. new_item,
  889. TASK_INVENTORY_ITEM_KEY,
  890. false);
  891. }
  892. }
  893. }
  894. else
  895. {
  896. // need to make sure we don't just follow the click
  897. refresh();
  898. }
  899. }
  900. LLViewerInventoryItem* LLSidepanelItemInfo::findItem() const
  901. {
  902. LLViewerInventoryItem* item = NULL;
  903. if(mObjectID.isNull())
  904. {
  905. // it is in agent inventory
  906. item = gInventory.getItem(mItemID);
  907. }
  908. else
  909. {
  910. LLViewerObject* object = gObjectList.findObject(mObjectID);
  911. if(object)
  912. {
  913. item = static_cast<LLViewerInventoryItem*>(object->getInventoryObject(mItemID));
  914. }
  915. }
  916. return item;
  917. }
  918. // virtual
  919. void LLSidepanelItemInfo::save()
  920. {
  921. onCommitName();
  922. onCommitDescription();
  923. onCommitPermissions();
  924. onCommitSaleInfo();
  925. onCommitSaleType();
  926. }