llfloaterbuy.cpp

Go to the documentation of this file.
00001 
00038 #include "llviewerprecompiledheaders.h"
00039 
00040 #include "llfloaterbuy.h"
00041 
00042 #include "llagent.h"                    // for agent id
00043 #include "llalertdialog.h"
00044 #include "llinventorymodel.h"   // for gInventory
00045 #include "llinventoryview.h"    // for get_item_icon
00046 #include "llselectmgr.h"
00047 #include "llscrolllistctrl.h"
00048 #include "llviewerobject.h"
00049 #include "llvieweruictrlfactory.h"
00050 #include "llviewerwindow.h"
00051 
00052 LLFloaterBuy* LLFloaterBuy::sInstance = NULL;
00053 
00054 LLFloaterBuy::LLFloaterBuy()
00055 :       LLFloater("floater_buy_object", "FloaterBuyRect", "")
00056 {
00057         gUICtrlFactory->buildFloater(this, "floater_buy_object.xml");
00058 
00059         childDisable("object_list");
00060         childDisable("item_list");
00061 
00062         childSetAction("cancel_btn", onClickCancel, this);
00063         childSetAction("buy_btn", onClickBuy, this);
00064 
00065         setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130)
00066 }
00067 
00068 LLFloaterBuy::~LLFloaterBuy()
00069 {
00070         sInstance = NULL;
00071 }
00072 
00073 void LLFloaterBuy::reset()
00074 {
00075         LLScrollListCtrl* object_list = LLUICtrlFactory::getScrollListByName(this, "object_list");
00076         if (object_list) object_list->deleteAllItems();
00077 
00078         LLScrollListCtrl* item_list = LLUICtrlFactory::getScrollListByName(this, "item_list");
00079         if (item_list) item_list->deleteAllItems();
00080 }
00081 
00082 // static
00083 void LLFloaterBuy::show(const LLSaleInfo& sale_info)
00084 {
00085         LLObjectSelectionHandle selection = gSelectMgr->getSelection();
00086 
00087         if (selection->getRootObjectCount() != 1)
00088         {
00089                 gViewerWindow->alertXml("BuyOneObjectOnly");
00090                 return;
00091         }
00092 
00093         // Create a new instance only if one doesn't exist
00094         if (sInstance)
00095         {
00096                 // Clean up the lists...
00097                 sInstance->reset();
00098         }
00099         else
00100         {
00101                 sInstance = new LLFloaterBuy();
00102         }
00103         
00104         sInstance->open(); /*Flawfinder: ignore*/
00105         sInstance->setFocus(TRUE);
00106         sInstance->mSaleInfo = sale_info;
00107         sInstance->mObjectSelection = gSelectMgr->getEditSelection();
00108 
00109         // Always center the dialog.  User can change the size,
00110         // but purchases are important and should be center screen.
00111         // This also avoids problems where the user resizes the application window
00112         // mid-session and the saved rect is off-center.
00113         sInstance->center();
00114 
00115         LLSelectNode* node = selection->getFirstRootNode();
00116         if (!node)
00117                 return;
00118 
00119         // Set title based on sale type
00120         LLUIString title;
00121         switch (sale_info.getSaleType())
00122         {
00123           case LLSaleInfo::FS_ORIGINAL:
00124                 title = sInstance->childGetText("title_buy_text");
00125                 break;
00126           case LLSaleInfo::FS_COPY:
00127           default:
00128                 title = sInstance->childGetText("title_buy_copy_text");
00129                 break;
00130         }
00131         title.setArg("[NAME]", node->mName);
00132         sInstance->setTitle(title);
00133 
00134         LLUUID owner_id;
00135         LLString owner_name;
00136         BOOL owners_identical = gSelectMgr->selectGetOwner(owner_id, owner_name);
00137         if (!owners_identical)
00138         {
00139                 gViewerWindow->alertXml("BuyObjectOneOwner");
00140                 return;
00141         }
00142 
00143         LLCtrlListInterface *object_list = sInstance->childGetListInterface("object_list");
00144         if (!object_list)
00145         {
00146                 return;
00147         }
00148 
00149         // Update the display
00150         // Display next owner permissions
00151         LLSD row;
00152 
00153         // Compute icon for this item
00154         LLUUID icon_id = get_item_icon_uuid(LLAssetType::AT_OBJECT, 
00155                                                  LLInventoryType::IT_OBJECT,
00156                                                  0x0, FALSE);
00157 
00158         row["columns"][0]["column"] = "icon";
00159         row["columns"][0]["type"] = "icon";
00160         row["columns"][0]["value"] = icon_id;
00161         
00162         // Append the permissions that you will acquire (not the current
00163         // permissions).
00164         U32 next_owner_mask = node->mPermissions->getMaskNextOwner();
00165         LLString text = node->mName;
00166         if (!(next_owner_mask & PERM_COPY))
00167         {
00168                 text.append(sInstance->childGetText("no_copy_text"));
00169         }
00170         if (!(next_owner_mask & PERM_MODIFY))
00171         {
00172                 text.append(sInstance->childGetText("no_modify_text"));
00173         }
00174         if (!(next_owner_mask & PERM_TRANSFER))
00175         {
00176                 text.append(sInstance->childGetText("no_transfer_text"));
00177         }
00178 
00179         row["columns"][1]["column"] = "text";
00180         row["columns"][1]["value"] = text;
00181         row["columns"][1]["font"] = "SANSSERIF";
00182 
00183         // Add after columns added so appropriate heights are correct.
00184         object_list->addElement(row);
00185 
00186         sInstance->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
00187         sInstance->childSetTextArg("buy_text", "[NAME]", owner_name);
00188 
00189         // Must do this after the floater is created, because
00190         // sometimes the inventory is already there and 
00191         // the callback is called immediately.
00192         LLViewerObject* obj = selection->getFirstRootObject();
00193         sInstance->registerVOInventoryListener(obj,NULL);
00194         sInstance->requestVOInventory();
00195 }
00196 
00197 
00198 void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
00199                                                                  InventoryObjectList* inv,
00200                                                                  S32 serial_num,
00201                                                                  void* data)
00202 {
00203         if (!obj)
00204         {
00205                 llwarns << "No object in LLFloaterBuy::inventoryChanged" << llendl;
00206                 return;
00207         }
00208 
00209         if (!inv)
00210         {
00211                 llwarns << "No inventory in LLFloaterBuy::inventoryChanged"
00212                         << llendl;
00213                 removeVOInventoryListener();
00214                 return;
00215         }
00216 
00217         LLCtrlListInterface *item_list = childGetListInterface("item_list");
00218         if (!item_list)
00219         {
00220                 removeVOInventoryListener();
00221                 return;
00222         }
00223 
00224         InventoryObjectList::const_iterator it = inv->begin();
00225         InventoryObjectList::const_iterator end = inv->end();
00226         for ( ; it != end; ++it )
00227         {
00228                 LLInventoryObject* obj = (LLInventoryObject*)(*it);
00229                         
00230                 // Skip folders, so we know we have inventory items only
00231                 if (obj->getType() == LLAssetType::AT_CATEGORY)
00232                         continue;
00233 
00234                 // Skip root folders, so we know we have inventory items only
00235                 if (obj->getType() == LLAssetType::AT_ROOT_CATEGORY) 
00236                         continue;
00237 
00238                 // Skip the mysterious blank InventoryObject 
00239                 if (obj->getType() == LLAssetType::AT_NONE)
00240                         continue;
00241 
00242 
00243                 LLInventoryItem* inv_item = (LLInventoryItem*)(obj);
00244 
00245                 // Skip items we can't transfer
00246                 if (!inv_item->getPermissions().allowTransferTo(gAgent.getID())) 
00247                         continue;
00248 
00249                 // Create the line in the list
00250                 LLSD row;
00251 
00252                 // Compute icon for this item
00253                 BOOL item_is_multi = FALSE;
00254                 if ( inv_item->getFlags() & LLInventoryItem::II_FLAGS_LANDMARK_VISITED )
00255                 {
00256                         item_is_multi = TRUE;
00257                 }
00258 
00259                 LLUUID icon_id = get_item_icon_uuid(inv_item->getType(), 
00260                                                          inv_item->getInventoryType(),
00261                                                          inv_item->getFlags(),
00262                                                          item_is_multi);
00263                 row["columns"][0]["column"] = "icon";
00264                 row["columns"][0]["type"] = "icon";
00265                 row["columns"][0]["value"] = icon_id;
00266                                 
00267                 // Append the permissions that you will acquire (not the current
00268                 // permissions).
00269                 U32 next_owner_mask = inv_item->getPermissions().getMaskNextOwner();
00270                 LLString text = obj->getName();
00271                 if (!(next_owner_mask & PERM_COPY))
00272                 {
00273                         text.append(" (no copy)");
00274                 }
00275                 if (!(next_owner_mask & PERM_MODIFY))
00276                 {
00277                         text.append(" (no modify)");
00278                 }
00279                 if (!(next_owner_mask & PERM_TRANSFER))
00280                 {
00281                         text.append(" (no transfer)");
00282                 }
00283 
00284                 row["columns"][1]["column"] = "text";
00285                 row["columns"][1]["value"] = text;
00286                 row["columns"][1]["font"] = "SANSSERIF";
00287 
00288                 item_list->addElement(row);
00289         }
00290         removeVOInventoryListener();
00291 }
00292 
00293 
00294 // static
00295 void LLFloaterBuy::onClickBuy(void*)
00296 {
00297         if (!sInstance)
00298         {
00299                 llinfos << "LLFloaterBuy::onClickBuy no sInstance!" << llendl;
00300                 return;
00301         }
00302 
00303         // Put the items where we put new folders.
00304         LLUUID category_id;
00305         category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT);
00306 
00307         // *NOTE: doesn't work for multiple object buy, which UI does not
00308         // currently support sale info is used for verification only, if
00309         // it doesn't match region info then sale is canceled.
00310         gSelectMgr->sendBuy(gAgent.getID(), category_id, sInstance->mSaleInfo );
00311 
00312         sInstance->close();
00313 }
00314 
00315 
00316 // static
00317 void LLFloaterBuy::onClickCancel(void*)
00318 {
00319         if (sInstance)
00320         {
00321                 sInstance->close();
00322         }
00323 }

Generated on Thu Jul 1 06:08:31 2010 for Second Life Viewer by  doxygen 1.4.7