PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llfloaterbuy.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 306 lines | 198 code | 50 blank | 58 comment | 27 complexity | 8f1f2c8ce2929454219aa576be2caa5b MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llfloaterbuy.cpp
  3. * @author James Cook
  4. * @brief LLFloaterBuy class implementation
  5. *
  6. * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. /**
  28. * Floater that appears when buying an object, giving a preview
  29. * of its contents and their permissions.
  30. */
  31. #include "llviewerprecompiledheaders.h"
  32. #include "llfloaterbuy.h"
  33. #include "llagent.h" // for agent id
  34. #include "llinventorymodel.h" // for gInventory
  35. #include "llfloaterreg.h"
  36. #include "llinventoryicon.h"
  37. #include "llinventorydefines.h"
  38. #include "llinventoryfunctions.h"
  39. #include "llnotificationsutil.h"
  40. #include "llselectmgr.h"
  41. #include "llscrolllistctrl.h"
  42. #include "llviewerobject.h"
  43. #include "lluictrlfactory.h"
  44. #include "llviewerwindow.h"
  45. #include "lltrans.h"
  46. LLFloaterBuy::LLFloaterBuy(const LLSD& key)
  47. : LLFloater(key)
  48. {
  49. }
  50. BOOL LLFloaterBuy::postBuild()
  51. {
  52. getChildView("object_list")->setEnabled(FALSE);
  53. getChildView("item_list")->setEnabled(FALSE);
  54. getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuy::onClickCancel, this));
  55. getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuy::onClickBuy, this));
  56. setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130)
  57. // Always center the dialog. User can change the size,
  58. // but purchases are important and should be center screen.
  59. // This also avoids problems where the user resizes the application window
  60. // mid-session and the saved rect is off-center.
  61. center();
  62. return TRUE;
  63. }
  64. LLFloaterBuy::~LLFloaterBuy()
  65. {
  66. mObjectSelection = NULL;
  67. }
  68. void LLFloaterBuy::reset()
  69. {
  70. LLScrollListCtrl* object_list = getChild<LLScrollListCtrl>("object_list");
  71. if (object_list) object_list->deleteAllItems();
  72. LLScrollListCtrl* item_list = getChild<LLScrollListCtrl>("item_list");
  73. if (item_list) item_list->deleteAllItems();
  74. }
  75. // static
  76. void LLFloaterBuy::show(const LLSaleInfo& sale_info)
  77. {
  78. LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
  79. if (selection->getRootObjectCount() != 1)
  80. {
  81. LLNotificationsUtil::add("BuyOneObjectOnly");
  82. return;
  83. }
  84. LLFloaterBuy* floater = LLFloaterReg::showTypedInstance<LLFloaterBuy>("buy_object");
  85. if (!floater)
  86. return;
  87. // Clean up the lists...
  88. floater->reset();
  89. floater->mSaleInfo = sale_info;
  90. floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
  91. LLSelectNode* node = selection->getFirstRootNode();
  92. if (!node)
  93. return;
  94. // Set title based on sale type
  95. LLUIString title;
  96. switch (sale_info.getSaleType())
  97. {
  98. case LLSaleInfo::FS_ORIGINAL:
  99. title = floater->getString("title_buy_text");
  100. break;
  101. case LLSaleInfo::FS_COPY:
  102. default:
  103. title = floater->getString("title_buy_copy_text");
  104. break;
  105. }
  106. title.setArg("[NAME]", node->mName);
  107. floater->setTitle(title);
  108. LLUUID owner_id;
  109. std::string owner_name;
  110. BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
  111. if (!owners_identical)
  112. {
  113. LLNotificationsUtil::add("BuyObjectOneOwner");
  114. return;
  115. }
  116. LLCtrlListInterface *object_list = floater->childGetListInterface("object_list");
  117. if (!object_list)
  118. {
  119. return;
  120. }
  121. // Update the display
  122. // Display next owner permissions
  123. LLSD row;
  124. // Compute icon for this item
  125. std::string icon_name = LLInventoryIcon::getIconName(LLAssetType::AT_OBJECT,
  126. LLInventoryType::IT_OBJECT);
  127. row["columns"][0]["column"] = "icon";
  128. row["columns"][0]["type"] = "icon";
  129. row["columns"][0]["value"] = icon_name;
  130. // Append the permissions that you will acquire (not the current
  131. // permissions).
  132. U32 next_owner_mask = node->mPermissions->getMaskNextOwner();
  133. std::string text = node->mName;
  134. if (!(next_owner_mask & PERM_COPY))
  135. {
  136. text.append(floater->getString("no_copy_text"));
  137. }
  138. if (!(next_owner_mask & PERM_MODIFY))
  139. {
  140. text.append(floater->getString("no_modify_text"));
  141. }
  142. if (!(next_owner_mask & PERM_TRANSFER))
  143. {
  144. text.append(floater->getString("no_transfer_text"));
  145. }
  146. row["columns"][1]["column"] = "text";
  147. row["columns"][1]["value"] = text;
  148. row["columns"][1]["font"] = "SANSSERIF";
  149. // Add after columns added so appropriate heights are correct.
  150. object_list->addElement(row);
  151. floater->getChild<LLUICtrl>("buy_text")->setTextArg("[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
  152. floater->getChild<LLUICtrl>("buy_name_text")->setTextArg("[NAME]", owner_name);
  153. // Must do this after the floater is created, because
  154. // sometimes the inventory is already there and
  155. // the callback is called immediately.
  156. LLViewerObject* obj = selection->getFirstRootObject();
  157. floater->registerVOInventoryListener(obj,NULL);
  158. floater->requestVOInventory();
  159. }
  160. void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
  161. LLInventoryObject::object_list_t* inv,
  162. S32 serial_num,
  163. void* data)
  164. {
  165. if (!obj)
  166. {
  167. llwarns << "No object in LLFloaterBuy::inventoryChanged" << llendl;
  168. return;
  169. }
  170. if (!inv)
  171. {
  172. llwarns << "No inventory in LLFloaterBuy::inventoryChanged"
  173. << llendl;
  174. removeVOInventoryListener();
  175. return;
  176. }
  177. LLCtrlListInterface *item_list = childGetListInterface("item_list");
  178. if (!item_list)
  179. {
  180. removeVOInventoryListener();
  181. return;
  182. }
  183. LLInventoryObject::object_list_t::const_iterator it = inv->begin();
  184. LLInventoryObject::object_list_t::const_iterator end = inv->end();
  185. for ( ; it != end; ++it )
  186. {
  187. LLInventoryObject* obj = (LLInventoryObject*)(*it);
  188. // Skip folders, so we know we have inventory items only
  189. if (obj->getType() == LLAssetType::AT_CATEGORY)
  190. continue;
  191. // Skip the mysterious blank InventoryObject
  192. if (obj->getType() == LLAssetType::AT_NONE)
  193. continue;
  194. LLInventoryItem* inv_item = (LLInventoryItem*)(obj);
  195. // Skip items we can't transfer
  196. if (!inv_item->getPermissions().allowTransferTo(gAgent.getID()))
  197. continue;
  198. // Create the line in the list
  199. LLSD row;
  200. // Compute icon for this item
  201. BOOL item_is_multi = FALSE;
  202. if ( inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED
  203. || inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
  204. {
  205. item_is_multi = TRUE;
  206. }
  207. std::string icon_name = LLInventoryIcon::getIconName(inv_item->getType(),
  208. inv_item->getInventoryType(),
  209. inv_item->getFlags(),
  210. item_is_multi);
  211. row["columns"][0]["column"] = "icon";
  212. row["columns"][0]["type"] = "icon";
  213. row["columns"][0]["value"] = icon_name;
  214. // Append the permissions that you will acquire (not the current
  215. // permissions).
  216. U32 next_owner_mask = inv_item->getPermissions().getMaskNextOwner();
  217. std::string text = obj->getName();
  218. if (!(next_owner_mask & PERM_COPY))
  219. {
  220. text.append(LLTrans::getString("no_copy"));
  221. }
  222. if (!(next_owner_mask & PERM_MODIFY))
  223. {
  224. text.append(LLTrans::getString("no_modify"));
  225. }
  226. if (!(next_owner_mask & PERM_TRANSFER))
  227. {
  228. text.append(LLTrans::getString("no_transfer"));
  229. }
  230. row["columns"][1]["column"] = "text";
  231. row["columns"][1]["value"] = text;
  232. row["columns"][1]["font"] = "SANSSERIF";
  233. item_list->addElement(row);
  234. }
  235. removeVOInventoryListener();
  236. }
  237. void LLFloaterBuy::onClickBuy()
  238. {
  239. // Put the items where we put new folders.
  240. LLUUID category_id;
  241. category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
  242. // *NOTE: doesn't work for multiple object buy, which UI does not
  243. // currently support sale info is used for verification only, if
  244. // it doesn't match region info then sale is canceled.
  245. LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, mSaleInfo );
  246. closeFloater();
  247. }
  248. void LLFloaterBuy::onClickCancel()
  249. {
  250. closeFloater();
  251. }
  252. // virtual
  253. void LLFloaterBuy::onClose(bool app_quitting)
  254. {
  255. mObjectSelection.clear();
  256. }