llfloaterbuycontents.cpp

Go to the documentation of this file.
00001 
00038 #include "llviewerprecompiledheaders.h"
00039 
00040 #include "llfloaterbuycontents.h"
00041 
00042 #include "llcachename.h"
00043 
00044 #include "llagent.h"                    // for agent id
00045 #include "llalertdialog.h"
00046 #include "llcheckboxctrl.h"
00047 #include "llinventorymodel.h"   // for gInventory
00048 #include "llinventoryview.h"    // for get_item_icon
00049 #include "llselectmgr.h"
00050 #include "llscrolllistctrl.h"
00051 #include "llviewerobject.h"
00052 #include "llviewerregion.h"
00053 #include "lluictrlfactory.h"
00054 #include "llviewerwindow.h"
00055 
00056 LLFloaterBuyContents* LLFloaterBuyContents::sInstance = NULL;
00057 
00058 LLFloaterBuyContents::LLFloaterBuyContents()
00059 :       LLFloater("floater_buy_contents", "FloaterBuyContentsRect", "")
00060 {
00061         LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_contents.xml");
00062 
00063         childSetAction("cancel_btn", onClickCancel, this);
00064         childSetAction("buy_btn", onClickBuy, this);
00065 
00066         childDisable("item_list");
00067         childDisable("buy_btn");
00068         childDisable("wear_check");
00069 
00070         setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130)
00071 }
00072 
00073 LLFloaterBuyContents::~LLFloaterBuyContents()
00074 {
00075         sInstance = NULL;
00076 }
00077 
00078 
00079 // static
00080 void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
00081 {
00082         LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
00083 
00084         if (selection->getRootObjectCount() != 1)
00085         {
00086                 gViewerWindow->alertXml("BuyContentsOneOnly");
00087                 return;
00088         }
00089 
00090         // Create a new instance only if needed
00091         if (sInstance)
00092         {
00093                 LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("item_list");
00094                 if (list) list->deleteAllItems();
00095         }
00096         else
00097         {
00098                 sInstance = new LLFloaterBuyContents();
00099         }
00100 
00101         sInstance->open(); /*Flawfinder: ignore*/
00102         sInstance->setFocus(TRUE);
00103         sInstance->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
00104 
00105         // Always center the dialog.  User can change the size,
00106         // but purchases are important and should be center screen.
00107         // This also avoids problems where the user resizes the application window
00108         // mid-session and the saved rect is off-center.
00109         sInstance->center();
00110 
00111         LLUUID owner_id;
00112         LLString owner_name;
00113         BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
00114         if (!owners_identical)
00115         {
00116                 gViewerWindow->alertXml("BuyContentsOneOwner");
00117                 return;
00118         }
00119 
00120         sInstance->mSaleInfo = sale_info;
00121 
00122         // Update the display
00123         LLSelectNode* node = selection->getFirstRootNode();
00124         if (!node) return;
00125         if(node->mPermissions->isGroupOwned())
00126         {
00127                 gCacheName->getGroupName(owner_id, owner_name);
00128         }
00129 
00130         sInstance->childSetTextArg("contains_text", "[NAME]", node->mName);
00131         sInstance->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
00132         sInstance->childSetTextArg("buy_text", "[NAME]", owner_name);
00133 
00134         // Must do this after the floater is created, because
00135         // sometimes the inventory is already there and 
00136         // the callback is called immediately.
00137         LLViewerObject* obj = selection->getFirstRootObject();
00138         sInstance->registerVOInventoryListener(obj,NULL);
00139         sInstance->requestVOInventory();
00140 }
00141 
00142 
00143 void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
00144                                                                                         InventoryObjectList* inv,
00145                                                                  S32 serial_num,
00146                                                                  void* data)
00147 {
00148         if (!obj)
00149         {
00150                 llwarns << "No object in LLFloaterBuyContents::inventoryChanged" << llendl;
00151                 return;
00152         }
00153 
00154         if (!inv)
00155         {
00156                 llwarns << "No inventory in LLFloaterBuyContents::inventoryChanged"
00157                         << llendl;
00158                 removeVOInventoryListener();
00159                 return;
00160         }
00161 
00162         LLCtrlListInterface *item_list = childGetListInterface("item_list");
00163         if (!item_list)
00164         {
00165                 removeVOInventoryListener();
00166                 return;
00167         }
00168 
00169         // default to turning off the buy button.
00170         childDisable("buy_btn");
00171 
00172         LLUUID owner_id;
00173         BOOL is_group_owned;
00174         LLAssetType::EType asset_type;
00175         LLInventoryType::EType inv_type;
00176         S32 wearable_count = 0;
00177         
00178         InventoryObjectList::const_iterator it = inv->begin();
00179         InventoryObjectList::const_iterator end = inv->end();
00180 
00181         for ( ; it != end; ++it )
00182         {
00183                 asset_type = (*it)->getType();
00184 
00185                 // Skip folders, so we know we have inventory items only
00186                 if (asset_type == LLAssetType::AT_CATEGORY)
00187                         continue;
00188 
00189                 // Skip root folders, so we know we have inventory items only
00190                 if (asset_type == LLAssetType::AT_ROOT_CATEGORY) 
00191                         continue;
00192 
00193                 LLInventoryItem* inv_item = (LLInventoryItem*)((LLInventoryObject*)(*it));
00194                 inv_type = inv_item->getInventoryType();
00195 
00196                 // Count clothing items for later
00197                 if (LLInventoryType::IT_WEARABLE == inv_type)
00198                 {
00199                         wearable_count++;
00200                 }
00201 
00202                 // Skip items the object's owner can't copy (and hence can't sell)
00203                 if (!inv_item->getPermissions().getOwnership(owner_id, is_group_owned))
00204                         continue;
00205 
00206                 if (!inv_item->getPermissions().allowCopyBy(owner_id, owner_id))
00207                         continue;
00208 
00209                 // Skip items we can't transfer
00210                 if (!inv_item->getPermissions().allowTransferTo(gAgent.getID())) 
00211                         continue;
00212 
00213                 // There will be at least one item shown in the display, so go
00214                 // ahead and enable the buy button.
00215                 childEnable("buy_btn");
00216 
00217                 // Create the line in the list
00218                 LLSD row;
00219 
00220                 BOOL item_is_multi = FALSE;
00221                 if ( inv_item->getFlags() & LLInventoryItem::II_FLAGS_LANDMARK_VISITED )
00222                 {
00223                         item_is_multi = TRUE;
00224                 }
00225 
00226                 LLString icon_name = get_item_icon_name(inv_item->getType(), 
00227                                                                  inv_item->getInventoryType(),
00228                                                                  inv_item->getFlags(),
00229                                                                  item_is_multi);
00230                 row["columns"][0]["column"] = "icon";
00231                 row["columns"][0]["type"] = "icon";
00232                 row["columns"][0]["value"] = icon_name;
00233                 
00234                 // Append the permissions that you will acquire (not the current
00235                 // permissions).
00236                 U32 next_owner_mask = inv_item->getPermissions().getMaskNextOwner();
00237                 LLString text = (*it)->getName();
00238 
00239                 if (!(next_owner_mask & PERM_COPY))
00240                 {
00241                         text.append(getString("no_copy_text"));
00242                 }
00243                 if (!(next_owner_mask & PERM_MODIFY))
00244                 {
00245                         text.append(getString("no_modify_text"));
00246                 }
00247                 if (!(next_owner_mask & PERM_TRANSFER))
00248                 {
00249                         text.append(getString("no_transfer_text"));
00250                 }
00251                 
00252                 row["columns"][1]["column"] = "text";
00253                 row["columns"][1]["value"] = text;
00254                 row["columns"][1]["font"] = "SANSSERIF";
00255 
00256                 item_list->addElement(row);
00257         }
00258 
00259         if (wearable_count > 0)
00260         {
00261                 childEnable("wear_check");
00262                 childSetValue("wear_check", LLSD(false) );
00263         }
00264         
00265         removeVOInventoryListener();
00266 }
00267 
00268 
00269 // static
00270 void LLFloaterBuyContents::onClickBuy(void*)
00271 {
00272         // Make sure this wasn't selected through other mechanisms 
00273         // (ie, being the default button and pressing enter.
00274         if(!sInstance->childIsEnabled("buy_btn"))
00275         {
00276                 // We shouldn't be enabled.  Just close.
00277                 sInstance->close();
00278                 return;
00279         }
00280 
00281         // We may want to wear this item
00282         if (sInstance->childGetValue("wear_check"))
00283         {
00284                 LLInventoryView::sWearNewClothing = TRUE;
00285         }
00286 
00287         // Put the items where we put new folders.
00288         LLUUID category_id;
00289         category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CATEGORY);
00290 
00291         // *NOTE: doesn't work for multiple object buy, which UI does not
00292         // currently support sale info is used for verification only, if
00293         // it doesn't match region info then sale is canceled.
00294         LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, sInstance->mSaleInfo);
00295 
00296         sInstance->close();
00297 }
00298 
00299 
00300 // static
00301 void LLFloaterBuyContents::onClickCancel(void*)
00302 {
00303         sInstance->close();
00304 }

Generated on Fri May 16 08:33:23 2008 for SecondLife by  doxygen 1.5.5