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 "llvieweruictrlfactory.h"
00054 #include "llviewerwindow.h"
00055 
00056 LLFloaterBuyContents* LLFloaterBuyContents::sInstance = NULL;
00057 
00058 LLFloaterBuyContents::LLFloaterBuyContents()
00059 :       LLFloater("floater_buy_contents", "FloaterBuyContentsRect", "")
00060 {
00061         gUICtrlFactory->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 = gSelectMgr->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 = LLUICtrlFactory::getScrollListByName(sInstance, "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 = gSelectMgr->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 = gSelectMgr->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                 char group_name[MAX_STRING];    /*Flawfinder: ignore*/
00128                 gCacheName->getGroupName(owner_id, group_name);
00129                 owner_name.assign(group_name);
00130         }
00131 
00132         sInstance->childSetTextArg("contains_text", "[NAME]", node->mName);
00133         sInstance->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
00134         sInstance->childSetTextArg("buy_text", "[NAME]", owner_name);
00135 
00136         // Must do this after the floater is created, because
00137         // sometimes the inventory is already there and 
00138         // the callback is called immediately.
00139         LLViewerObject* obj = selection->getFirstRootObject();
00140         sInstance->registerVOInventoryListener(obj,NULL);
00141         sInstance->requestVOInventory();
00142 }
00143 
00144 
00145 void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
00146                                                                                         InventoryObjectList* inv,
00147                                                                  S32 serial_num,
00148                                                                  void* data)
00149 {
00150         if (!obj)
00151         {
00152                 llwarns << "No object in LLFloaterBuyContents::inventoryChanged" << llendl;
00153                 return;
00154         }
00155 
00156         if (!inv)
00157         {
00158                 llwarns << "No inventory in LLFloaterBuyContents::inventoryChanged"
00159                         << llendl;
00160                 removeVOInventoryListener();
00161                 return;
00162         }
00163 
00164         LLCtrlListInterface *item_list = childGetListInterface("item_list");
00165         if (!item_list)
00166         {
00167                 removeVOInventoryListener();
00168                 return;
00169         }
00170 
00171         // default to turning off the buy button.
00172         childDisable("buy_btn");
00173 
00174         LLUUID owner_id;
00175         BOOL is_group_owned;
00176         LLAssetType::EType asset_type;
00177         LLInventoryType::EType inv_type;
00178         S32 wearable_count = 0;
00179         
00180         InventoryObjectList::const_iterator it = inv->begin();
00181         InventoryObjectList::const_iterator end = inv->end();
00182 
00183         for ( ; it != end; ++it )
00184         {
00185                 asset_type = (*it)->getType();
00186 
00187                 // Skip folders, so we know we have inventory items only
00188                 if (asset_type == LLAssetType::AT_CATEGORY)
00189                         continue;
00190 
00191                 // Skip root folders, so we know we have inventory items only
00192                 if (asset_type == LLAssetType::AT_ROOT_CATEGORY) 
00193                         continue;
00194 
00195                 LLInventoryItem* inv_item = (LLInventoryItem*)((LLInventoryObject*)(*it));
00196                 inv_type = inv_item->getInventoryType();
00197 
00198                 // Count clothing items for later
00199                 if (LLInventoryType::IT_WEARABLE == inv_type)
00200                 {
00201                         wearable_count++;
00202                 }
00203 
00204                 // Skip items the object's owner can't copy (and hence can't sell)
00205                 if (!inv_item->getPermissions().getOwnership(owner_id, is_group_owned))
00206                         continue;
00207 
00208                 if (!inv_item->getPermissions().allowCopyBy(owner_id, owner_id))
00209                         continue;
00210 
00211                 // Skip items we can't transfer
00212                 if (!inv_item->getPermissions().allowTransferTo(gAgent.getID())) 
00213                         continue;
00214 
00215                 // There will be at least one item shown in the display, so go
00216                 // ahead and enable the buy button.
00217                 childEnable("buy_btn");
00218 
00219                 // Create the line in the list
00220                 LLSD row;
00221 
00222                 BOOL item_is_multi = FALSE;
00223                 if ( inv_item->getFlags() & LLInventoryItem::II_FLAGS_LANDMARK_VISITED )
00224                 {
00225                         item_is_multi = TRUE;
00226                 }
00227 
00228                 LLUUID icon_id = get_item_icon_uuid(inv_item->getType(), 
00229                                                          inv_item->getInventoryType(),
00230                                                          inv_item->getFlags(),
00231                                                          item_is_multi);
00232                 row["columns"][0]["column"] = "icon";
00233                 row["columns"][0]["type"] = "icon";
00234                 row["columns"][0]["value"] = icon_id;
00235                 
00236                 // Append the permissions that you will acquire (not the current
00237                 // permissions).
00238                 U32 next_owner_mask = inv_item->getPermissions().getMaskNextOwner();
00239                 LLString text = (*it)->getName();
00240 
00241                 if (!(next_owner_mask & PERM_COPY))
00242                 {
00243                         text.append(childGetText("no_copy_text"));
00244                 }
00245                 if (!(next_owner_mask & PERM_MODIFY))
00246                 {
00247                         text.append(childGetText("no_modify_text"));
00248                 }
00249                 if (!(next_owner_mask & PERM_TRANSFER))
00250                 {
00251                         text.append(childGetText("no_transfer_text"));
00252                 }
00253                 
00254                 row["columns"][1]["column"] = "text";
00255                 row["columns"][1]["value"] = text;
00256                 row["columns"][1]["font"] = "SANSSERIF";
00257 
00258                 item_list->addElement(row);
00259         }
00260 
00261         if (wearable_count > 0)
00262         {
00263                 childEnable("wear_check");
00264                 childSetValue("wear_check", LLSD(false) );
00265         }
00266         
00267         removeVOInventoryListener();
00268 }
00269 
00270 
00271 // static
00272 void LLFloaterBuyContents::onClickBuy(void*)
00273 {
00274         // Make sure this wasn't selected through other mechanisms 
00275         // (ie, being the default button and pressing enter.
00276         if(!sInstance->childIsEnabled("buy_btn"))
00277         {
00278                 // We shouldn't be enabled.  Just close.
00279                 sInstance->close();
00280                 return;
00281         }
00282 
00283         // We may want to wear this item
00284         if (sInstance->childGetValue("wear_check"))
00285         {
00286                 LLInventoryView::sWearNewClothing = TRUE;
00287         }
00288 
00289         // Put the items where we put new folders.
00290         LLUUID category_id;
00291         category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CATEGORY);
00292 
00293         // *NOTE: doesn't work for multiple object buy, which UI does not
00294         // currently support sale info is used for verification only, if
00295         // it doesn't match region info then sale is canceled.
00296         gSelectMgr->sendBuy(gAgent.getID(), category_id, sInstance->mSaleInfo);
00297 
00298         sInstance->close();
00299 }
00300 
00301 
00302 // static
00303 void LLFloaterBuyContents::onClickCancel(void*)
00304 {
00305         sInstance->close();
00306 }

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