From f93f860e9b565213089f945ee0d88dedf3dcd9c0 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 14 Mar 2014 13:52:42 -0700 Subject: DD-43, DD-44 : implement update_marketplace_category() and get it called swhen appropriate --- indra/newview/llinventoryfunctions.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index f1a4889f5a..203eb4ec4e 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -111,6 +111,16 @@ void append_path(const LLUUID& id, std::string& path) path.append(temp); } +void update_marketplace_category(const LLUUID& cat_id) +{ + // When changing the marketplace status of a folder, the only thing that needs to happen is + // for all observers of the folder to, possibly, change the display label of said folder. + // At least that's the status for the moment so, even if that function seems small, we + // prefer to encapsulate that behavior here. + gInventory.addChangedMask(LLInventoryObserver::LABEL, cat_id); + gInventory.notifyObservers(); +} + void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name) { LLViewerInventoryCategory* cat; -- cgit v1.3 From 0ec8fbec6deaa24506391ef239c50009eebe1eef Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 28 Mar 2014 15:54:36 -0700 Subject: DD-24 : Add FT_MARKETPLACE_STOCK as a new type for folders, implement the promotion code for Drag and Drop, display of stock folders and embryonic marketplace validation --- indra/llcommon/llfoldertype.cpp | 1 + indra/llcommon/llfoldertype.h | 1 + indra/newview/llinventorybridge.cpp | 56 ++++++++-- indra/newview/llinventoryfunctions.cpp | 149 +++++++++++++++++++++++++ indra/newview/llinventoryfunctions.h | 6 +- indra/newview/llinventorymodel.cpp | 4 +- indra/newview/llinventorypanel.cpp | 1 + indra/newview/llviewerfoldertype.cpp | 3 +- indra/newview/skins/default/xui/en/strings.xml | 1 + 9 files changed, 210 insertions(+), 12 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/llcommon/llfoldertype.cpp b/indra/llcommon/llfoldertype.cpp index 5b80189d2a..afa9e59832 100755 --- a/indra/llcommon/llfoldertype.cpp +++ b/indra/llcommon/llfoldertype.cpp @@ -98,6 +98,7 @@ LLFolderDictionary::LLFolderDictionary() addEntry(LLFolderType::FT_BASIC_ROOT, new FolderEntry("basic_rt", TRUE)); addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new FolderEntry("merchant", FALSE)); + addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new FolderEntry("stock", FALSE)); addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE)); }; diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h index 91dc1da543..20925eede0 100644 --- a/indra/llcommon/llfoldertype.h +++ b/indra/llcommon/llfoldertype.h @@ -88,6 +88,7 @@ public: FT_BASIC_ROOT = 52, FT_MARKETPLACE_LISTINGS = 53, + FT_MARKETPLACE_STOCK = 54, FT_COUNT, diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 3d418105e3..d0abe6db29 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1958,7 +1958,7 @@ std::string LLFolderBridge::getLabelSuffix() const { if (LLMarketplaceData::instance().isListed(getUUID())) { - llinfos << "Merov : in merchant folder and listed : id = " << getUUID() << llendl; + //llinfos << "Merov : in merchant folder and listed : id = " << getUUID() << llendl; std::string suffix = LLMarketplaceData::instance().getListingID(getUUID()); if (suffix.empty()) { @@ -1971,9 +1971,15 @@ std::string LLFolderBridge::getLabelSuffix() const } return LLInvFVBridge::getLabelSuffix() + suffix; } + else if (getCategory()->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + //llinfos << "Merov : in merchant folder and is a stock folder : id = " << getUUID() << llendl; + std::string suffix = " (" + LLTrans::getString("MarketplaceStock") + ")"; + return LLInvFVBridge::getLabelSuffix() + suffix; + } else { - llinfos << "Merov : in merchant folder but not listed : id = " << getUUID() << llendl; + //llinfos << "Merov : in merchant folder but not listed : id = " << getUUID() << llendl; return LLInvFVBridge::getLabelSuffix(); } } @@ -2316,10 +2322,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, const LLUUID &cat_id = inv_cat->getUUID(); const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); const BOOL move_is_from_outbox = model->isObjectDescendentOf(cat_id, outbox_id); + const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id); + const BOOL move_is_from_marketplacelistings = model->isObjectDescendentOf(cat_id, marketplacelistings_id); // check to make sure source is agent inventory, and is represented there. LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); @@ -2499,6 +2508,12 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } } } + if (is_movable && move_is_into_marketplacelistings) + { + // *TODO : Merov : Add here the logic to prevent huge nesting in marketplace listings + // For the moment, we just take in anything + is_movable = TRUE; + } if (is_movable) { @@ -2601,6 +2616,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, { copy_folder_to_outbox(inv_cat, mUUID, cat_id, LLToolDragAndDrop::getOperationId()); } + else if (move_is_into_marketplacelistings && !move_is_from_marketplacelistings) + { + move_folder_to_marketplacelistings(inv_cat, mUUID); + } else { if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false))) @@ -2620,7 +2639,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } else if (LLToolDragAndDrop::SOURCE_WORLD == source) { - if (move_is_into_outbox) + if (move_is_into_outbox || move_is_into_marketplacelistings) { tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); accept = FALSE; @@ -2632,7 +2651,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } else if (LLToolDragAndDrop::SOURCE_LIBRARY == source) { - if (move_is_into_outbox) + if (move_is_into_outbox || move_is_into_marketplacelistings) { tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); accept = FALSE; @@ -3248,6 +3267,9 @@ void LLFolderBridge::pasteFromClipboard() const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); + // *TODO : Add marketplace listings case + //const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + //const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id); LLDynamicArray objects; LLClipboard::instance().pasteFromClipboard(objects); @@ -3372,12 +3394,14 @@ void LLFolderBridge::pasteLinkFromClipboard() { const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); + const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id); - if (move_is_into_outbox) + if (move_is_into_outbox || move_is_into_marketplacelistings) { // Notify user of failure somehow -- play error sound? modal dialog? return; @@ -4047,6 +4071,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false); const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_favorites = (mUUID == favorites_id); @@ -4054,6 +4079,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id); const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_item->getUUID(), outbox_id); + const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id); LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); BOOL accept = FALSE; @@ -4150,6 +4176,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } } } + else if (move_is_into_marketplacelistings) + { + // *TODO : Add here any logic that may prevent an item to be copied into the marketplace listings + // For the moment, we let anything go + accept = TRUE; + } LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); @@ -4208,6 +4240,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { dropToOutfit(inv_item, move_is_into_current_outfit); } + // MERCHANT OUTBOX folder + // Move the item else if (move_is_into_outbox) { if (move_is_from_outbox) @@ -4219,6 +4253,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, copy_item_to_outbox(inv_item, mUUID, LLUUID::null, LLToolDragAndDrop::getOperationId()); } } + // MARKETPLACE LISTINGS folder + // Move the item + else if (move_is_into_marketplacelistings) + { + move_item_to_marketplacelistings(inv_item, mUUID); + } // NORMAL or TRASH folder // (move the item, restamp if into trash) else @@ -4285,7 +4325,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { accept = FALSE; } - else if (move_is_into_outbox) + else if (move_is_into_outbox || move_is_into_marketplacelistings) { tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); accept = FALSE; @@ -4323,7 +4363,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } else if(LLToolDragAndDrop::SOURCE_NOTECARD == source) { - if (move_is_into_outbox) + if (move_is_into_outbox || move_is_into_marketplacelistings) { tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); accept = FALSE; @@ -4357,7 +4397,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { accept = TRUE; - if (move_is_into_outbox) + if (move_is_into_outbox || move_is_into_marketplacelistings) { tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); accept = FALSE; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 203eb4ec4e..fe55f8955f 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -686,6 +686,155 @@ void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_fold open_outbox(); } +void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder) +{ + // Collapse links into items/folders + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item; + LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory(); + + if (linked_category != NULL) + { + // Move the linked folder directly + move_folder_to_marketplacelistings(linked_category, dest_folder); + } + else + { + // Grab the linked item if any + LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); + viewer_inv_item = (linked_item != NULL ? linked_item : viewer_inv_item); + + // Check that the agent has copy permission on the item: this is required as a resident cannot + // put on sale items she has no right about. Proceed with move if we have permission. + // *TODO : Check that this is adequate (copied from the Merchant Outbox permission check so should be OK...) + if (viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + // When moving an isolated item directly under the marketplace listings root, we create a new folder with that name + if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false)) + { + // *TODO : This method is not specific to the outbox folder so make it more generic + dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, 0); + } + + // Reparent the item + gInventory.changeItemParent(viewer_inv_item, dest_folder, false); + + // Check the item for no copy permission and promote the destination folder if necessary + if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY)) + { + llinfos << "Merov : item is no copy -> change the destination folder type!" << llendl; + LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (gInventory.getCategory(dest_folder)); + viewer_cat->changeType(LLFolderType::FT_MARKETPLACE_STOCK); + } + } + else + { + // *TODO : signal an error to the user (UI for this TBD) + llinfos << "Merov : user doesn't have the correct permission to put this item on sale -> move aborted!" << llendl; + } + } +} + +void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder) +{ + // Check that we have adequate permission on all items being moved. Proceed if we do. + if (has_correct_permissions_for_sale(inv_cat)) + { + + // Reparent the folder + LLViewerInventoryCategory * viewer_inv_cat = (LLViewerInventoryCategory *) inv_cat; + gInventory.changeCategoryParent(viewer_inv_cat, dest_folder, false); + + // Check the destination folder recursively for no copy items and promote the including folders if any + validate_marketplacelistings(inv_cat); + } +} + +// Returns true if all items within the argument folder are fit for sale, false otherwise +bool has_correct_permissions_for_sale(LLInventoryCategory* cat) +{ + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); + + LLInventoryModel::item_array_t item_array_copy = *item_array; + + for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) + { + LLInventoryItem* item = *iter; + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) item; + LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory(); + LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); + // Linked items and folders cannot be put for sale + if (linked_category || linked_item) + { + llinfos << "Merov : linked items in this folder -> not allowed to sell!" << llendl; + return false; + } + // *TODO : Check that this is adequate (copied from the Merchant Outbox permission check so should be OK...) + if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + llinfos << "Merov : wrong permissions on items in this folder -> not allowed to sell!" << llendl; + return false; + } + } + + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + { + LLInventoryCategory* category = *iter; + if (!has_correct_permissions_for_sale(category)) + { + return false; + } + } + return true; +} + +// Make all relevant business logic checks on the marketplace listings starting with the folder as argument +// This function does no deletion or move but a mere audit and raises issues to the user +// The only thing that's done is to modify the type of folders containing no-copy items to stock folders +// *TODO : Signal the errors to the user somewhat (UI still TBD) +// *TODO : Add the rest of the SLM/AIS business logic (limit of nesting depth, stock folder consistency, overall limit on listings, etc...) +void validate_marketplacelistings(LLInventoryCategory* cat) +{ + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); + + LLInventoryModel::item_array_t item_array_copy = *item_array; + + for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) + { + LLInventoryItem* item = *iter; + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) item; + LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory(); + LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); + if (linked_category || linked_item) + { + llinfos << "Merov : Validation error: there are linked items in this listing!" << llendl; + } + if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + llinfos << "Merov : Validation error: there are items with incorrect permissions in this listing!" << llendl; + } + if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY)) + { + llinfos << "Merov : Validation warning : item is no copy -> change the folder type to stock!" << llendl; + LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); + viewer_cat->changeType(LLFolderType::FT_MARKETPLACE_STOCK); + } + } + + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + { + LLInventoryCategory* category = *iter; + validate_marketplacelistings(category); + } +} + ///---------------------------------------------------------------------------- /// LLInventoryCollectFunctor implementations ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 1443c186cf..006cc3de68 100755 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -70,9 +70,13 @@ void append_path(const LLUUID& id, std::string& path); void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder, S32 operation_id); void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id); - void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id); +void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder); +void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder); +bool has_correct_permissions_for_sale(LLInventoryCategory* cat); +void validate_marketplacelistings(LLInventoryCategory* inv_cat); + /** Miscellaneous global functions ** ** *******************************************************************************/ diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index ed7fd3cd34..37e11123c6 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2160,12 +2160,12 @@ void LLInventoryModel::buildParentChildMap() // implement it, we would need a set or map of uuid pairs // which would be (folder_id, new_parent_id) to be sent up // to the server. - llinfos << "Lost categroy: " << cat->getUUID() << " - " + llinfos << "Lost category: " << cat->getUUID() << " - " << cat->getName() << llendl; ++lost; // plop it into the lost & found. LLFolderType::EType pref = cat->getPreferredType(); - if(LLFolderType::FT_NONE == pref) + if ((LLFolderType::FT_NONE == pref) || (LLFolderType::FT_MARKETPLACE_STOCK == pref)) { cat->setParent(findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND)); } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index bf8f7819ef..6305275a08 100755 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1491,5 +1491,6 @@ namespace LLInitParam declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX) , LLFolderType::FT_OUTBOX); declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT) , LLFolderType::FT_BASIC_ROOT); declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_LISTINGS) , LLFolderType::FT_MARKETPLACE_LISTINGS); + declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_STOCK), LLFolderType::FT_MARKETPLACE_STOCK); } } diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index ee8f85782f..b82f954e91 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -142,7 +142,8 @@ LLViewerFolderDictionary::LLViewerFolderDictionary() addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new ViewerFolderEntry("Marketplace listings", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible)); - + addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new ViewerFolderEntry("New Stock", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, false, "default")); + addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, false, "default")); #if SUPPORT_ENSEMBLES diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 80b520622a..ce9bbbc8d2 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2273,6 +2273,7 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors. no Mkt ID live + stock Open landmarks -- cgit v1.3 From e624e6ab9ea8c27c2649f6f0391b0f7d1362fda3 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 31 Mar 2014 15:00:14 -0700 Subject: DD-24 : Make stock folder really work and stick. Improve validation. Handle edge cases when moving under root --- indra/newview/llinventoryfunctions.cpp | 70 +++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 22 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index fe55f8955f..de7a79502d 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -521,14 +521,17 @@ void open_outbox() LLFloaterReg::showInstance("outbox"); } -LLUUID create_folder_in_outbox_for_item(LLInventoryItem* item, const LLUUID& destFolderId, S32 operation_id) +// Create a new folder in destFolderId with the same name as the item name and return the uuid of the new folder +// Note: this is used locally in various situation where we need to wrap an item into a special folder +LLUUID create_folder_for_item(LLInventoryItem* item, const LLUUID& destFolderId) { llassert(item); llassert(destFolderId.notNull()); LLUUID created_folder_id = gInventory.createNewCategory(destFolderId, LLFolderType::FT_NONE, item->getName()); gInventory.notifyObservers(); - + + // *TODO : Create different notifications for the various cases LLNotificationsUtil::add("OutboxFolderCreated"); return created_folder_id; @@ -544,8 +547,7 @@ void move_to_outbox_cb_action(const LLSD& payload) // when moving item directly into outbox create folder with that name if (dest_folder_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) { - S32 operation_id = payload["operation_id"].asInteger(); - dest_folder_id = create_folder_in_outbox_for_item(viitem, dest_folder_id, operation_id); + dest_folder_id = create_folder_for_item(viitem, dest_folder_id); } LLUUID parent = viitem->getParentUUID(); @@ -616,7 +618,7 @@ void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LL // when moving item directly into outbox create folder with that name if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) { - dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, operation_id); + dest_folder = create_folder_for_item(inv_item, dest_folder); } copy_inventory_item(gAgent.getID(), @@ -646,7 +648,7 @@ void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 // when moving item directly into outbox create folder with that name if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) { - dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, operation_id); + dest_folder = create_folder_for_item(inv_item, dest_folder); } LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item; @@ -688,7 +690,15 @@ void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_fold void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder) { - // Collapse links into items/folders + // Get the marketplace listings, exit with error if none + const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + if (marketplace_listings_uuid.isNull()) + { + llinfos << "Merov : Marketplace error : There is no marketplace listings folder -> move aborted!" << llendl; + return; + } + + // We will collapse links into items/folders LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item; LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory(); @@ -709,27 +719,28 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol if (viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) { // When moving an isolated item directly under the marketplace listings root, we create a new folder with that name - if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false)) + if (dest_folder == marketplace_listings_uuid) + { + dest_folder = create_folder_for_item(inv_item, dest_folder); + } + LLViewerInventoryCategory* category = gInventory.getCategory(dest_folder); + + // When moving a no copy item into a first level listing folder, we create a stock folder for it + if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY) && (category->getParentUUID() == marketplace_listings_uuid)) { - // *TODO : This method is not specific to the outbox folder so make it more generic - dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, 0); + dest_folder = create_folder_for_item(inv_item, dest_folder); } // Reparent the item gInventory.changeItemParent(viewer_inv_item, dest_folder, false); - // Check the item for no copy permission and promote the destination folder if necessary - if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY)) - { - llinfos << "Merov : item is no copy -> change the destination folder type!" << llendl; - LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (gInventory.getCategory(dest_folder)); - viewer_cat->changeType(LLFolderType::FT_MARKETPLACE_STOCK); - } + // Validate the destination : note that this will run the validation code only on one listing folder at most... + validate_marketplacelistings(category); } else { // *TODO : signal an error to the user (UI for this TBD) - llinfos << "Merov : user doesn't have the correct permission to put this item on sale -> move aborted!" << llendl; + llinfos << "Merov : Marketplace error : User doesn't have the correct permission to put this item on sale -> move aborted!" << llendl; } } } @@ -802,6 +813,10 @@ void validate_marketplacelistings(LLInventoryCategory* cat) LLInventoryModel::item_array_t* item_array; gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); + LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); + const LLFolderType::EType folder_type = cat->getPreferredType(); + LLUUID stock_folder; + LLInventoryModel::item_array_t item_array_copy = *item_array; for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) @@ -818,14 +833,25 @@ void validate_marketplacelistings(LLInventoryCategory* cat) { llinfos << "Merov : Validation error: there are items with incorrect permissions in this listing!" << llendl; } - if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY)) + if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY) && (folder_type != LLFolderType::FT_MARKETPLACE_STOCK)) { - llinfos << "Merov : Validation warning : item is no copy -> change the folder type to stock!" << llendl; - LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); - viewer_cat->changeType(LLFolderType::FT_MARKETPLACE_STOCK); + llinfos << "Merov : Validation warning : no copy item found in non stock folder -> reparent to relevant stock folder!" << llendl; + if (stock_folder.isNull()) + { + llinfos << "Merov : Validation warning : no appropriate existing stock folder -> create a new stock folder!" << llendl; + stock_folder = gInventory.createNewCategory(viewer_cat->getParentUUID(), LLFolderType::FT_MARKETPLACE_STOCK, viewer_cat->getName()); + } + gInventory.changeItemParent(viewer_inv_item, stock_folder, false); } } + if (stock_folder.notNull() && (viewer_cat->getDescendentCount() == 0)) + { + llinfos << "Merov : Validation warning : folder content completely moved to stock folder -> remove empty folder!" << llendl; + gInventory.removeCategory(cat->getUUID()); + return; + } + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) -- cgit v1.3 From ec290cd059d80519ff6891149306586819ac008d Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 31 Mar 2014 16:17:10 -0700 Subject: DD-18 : WIP : Implement stock folder counting but no propagation so far, also update is not working --- indra/newview/llinventorybridge.cpp | 5 +++-- indra/newview/llinventoryfunctions.cpp | 20 +++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d0abe6db29..bf56be320f 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1973,8 +1973,9 @@ std::string LLFolderBridge::getLabelSuffix() const } else if (getCategory()->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) { - //llinfos << "Merov : in merchant folder and is a stock folder : id = " << getUUID() << llendl; - std::string suffix = " (" + LLTrans::getString("MarketplaceStock") + ")"; + llinfos << "Merov : in merchant folder and is a stock folder : name = " << getCategory()->getName() << ", stock = " << getCategory()->getDescendentCount() << llendl; + std::string stock = llformat("%d", getCategory()->getDescendentCount()); + std::string suffix = " (" + LLTrans::getString("MarketplaceStock") + ") (" + stock + ")"; return LLInvFVBridge::getLabelSuffix() + suffix; } else diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index de7a79502d..5e4fb557d5 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -733,6 +733,8 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol // Reparent the item gInventory.changeItemParent(viewer_inv_item, dest_folder, false); + gInventory.updateCategory(category); + gInventory.notifyObservers(); // Validate the destination : note that this will run the validation code only on one listing folder at most... validate_marketplacelistings(category); @@ -754,6 +756,8 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU // Reparent the folder LLViewerInventoryCategory * viewer_inv_cat = (LLViewerInventoryCategory *) inv_cat; gInventory.changeCategoryParent(viewer_inv_cat, dest_folder, false); + gInventory.updateCategory(viewer_inv_cat); + gInventory.notifyObservers(); // Check the destination folder recursively for no copy items and promote the including folders if any validate_marketplacelistings(inv_cat); @@ -815,7 +819,8 @@ void validate_marketplacelistings(LLInventoryCategory* cat) LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); const LLFolderType::EType folder_type = cat->getPreferredType(); - LLUUID stock_folder; + LLUUID stock_folder_uuid; + LLViewerInventoryCategory* stock_folder_cat = NULL; LLInventoryModel::item_array_t item_array_copy = *item_array; @@ -836,19 +841,24 @@ void validate_marketplacelistings(LLInventoryCategory* cat) if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY) && (folder_type != LLFolderType::FT_MARKETPLACE_STOCK)) { llinfos << "Merov : Validation warning : no copy item found in non stock folder -> reparent to relevant stock folder!" << llendl; - if (stock_folder.isNull()) + if (stock_folder_uuid.isNull()) { llinfos << "Merov : Validation warning : no appropriate existing stock folder -> create a new stock folder!" << llendl; - stock_folder = gInventory.createNewCategory(viewer_cat->getParentUUID(), LLFolderType::FT_MARKETPLACE_STOCK, viewer_cat->getName()); + stock_folder_uuid = gInventory.createNewCategory(viewer_cat->getParentUUID(), LLFolderType::FT_MARKETPLACE_STOCK, viewer_cat->getName()); + stock_folder_cat = gInventory.getCategory(stock_folder_uuid); } - gInventory.changeItemParent(viewer_inv_item, stock_folder, false); + gInventory.changeItemParent(viewer_inv_item, stock_folder_uuid, false); + gInventory.updateCategory(viewer_cat); + gInventory.updateCategory(stock_folder_cat); + gInventory.notifyObservers(); } } - if (stock_folder.notNull() && (viewer_cat->getDescendentCount() == 0)) + if (stock_folder_uuid.notNull() && (viewer_cat->getDescendentCount() == 0)) { llinfos << "Merov : Validation warning : folder content completely moved to stock folder -> remove empty folder!" << llendl; gInventory.removeCategory(cat->getUUID()); + gInventory.notifyObservers(); return; } -- cgit v1.3 From 69fb50322eb0de9071ed22d4e62cef11ae811c4d Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 31 Mar 2014 20:24:41 -0700 Subject: DD-18 : WIP : Making stock folders update work better --- indra/newview/llinventoryfunctions.cpp | 31 ++++++++++++++++++++++++------- indra/newview/llinventorymodel.cpp | 10 ++++++++-- 2 files changed, 32 insertions(+), 9 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 5e4fb557d5..17bcd333f8 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -723,21 +723,28 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol { dest_folder = create_folder_for_item(inv_item, dest_folder); } - LLViewerInventoryCategory* category = gInventory.getCategory(dest_folder); + LLViewerInventoryCategory* dest_cat = gInventory.getCategory(dest_folder); // When moving a no copy item into a first level listing folder, we create a stock folder for it - if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY) && (category->getParentUUID() == marketplace_listings_uuid)) + if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY) && (dest_cat->getParentUUID() == marketplace_listings_uuid)) { dest_folder = create_folder_for_item(inv_item, dest_folder); } + // Get the parent folder of the moved item : we may have to update it + LLUUID src_folder = viewer_inv_item->getParentUUID(); + LLViewerInventoryCategory* src_cat = gInventory.getCategory(src_folder); + // Reparent the item gInventory.changeItemParent(viewer_inv_item, dest_folder, false); - gInventory.updateCategory(category); + + // Update the modified folders + gInventory.updateCategory(src_cat); + gInventory.updateCategory(dest_cat); gInventory.notifyObservers(); // Validate the destination : note that this will run the validation code only on one listing folder at most... - validate_marketplacelistings(category); + validate_marketplacelistings(dest_cat); } else { @@ -752,15 +759,25 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU // Check that we have adequate permission on all items being moved. Proceed if we do. if (has_correct_permissions_for_sale(inv_cat)) { - + // Get the destination folder + // *TODO : check that this folder is not full of no-copy items under its root... + LLViewerInventoryCategory* dest_cat = gInventory.getCategory(dest_folder); + + // Get the parent folder of the moved item : we may have to update it + LLUUID src_folder = inv_cat->getParentUUID(); + LLViewerInventoryCategory* src_cat = gInventory.getCategory(src_folder); + // Reparent the folder LLViewerInventoryCategory * viewer_inv_cat = (LLViewerInventoryCategory *) inv_cat; gInventory.changeCategoryParent(viewer_inv_cat, dest_folder, false); - gInventory.updateCategory(viewer_inv_cat); + + // Update the modified folders + gInventory.updateCategory(src_cat); + gInventory.updateCategory(dest_cat); gInventory.notifyObservers(); // Check the destination folder recursively for no copy items and promote the including folders if any - validate_marketplacelistings(inv_cat); + validate_marketplacelistings(dest_cat); } } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 37e11123c6..96a2db5afb 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1027,7 +1027,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat) LLViewerInventoryCategory* old_cat = getCategory(cat->getUUID()); if(old_cat) { - // We already have an old category, modify it's values + // We already have an old category, modify its values U32 mask = LLInventoryObserver::NONE; LLUUID old_parent_id = old_cat->getParentUUID(); LLUUID new_parent_id = cat->getParentUUID(); @@ -1052,7 +1052,13 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat) { mask |= LLInventoryObserver::LABEL; } - old_cat->copyViewerCategory(cat); + // Under marketplace, category labels are quite complex and need extra upate + const LLUUID marketplace_id = findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + if (marketplace_id.notNull() && isObjectDescendentOf(cat->getUUID(), marketplace_id)) + { + mask |= LLInventoryObserver::LABEL; + } + old_cat->copyViewerCategory(cat); addChangedMask(mask, cat->getUUID()); } else -- cgit v1.3 From f66de28a7cf735df15d167df270943547bdbde81 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 1 Apr 2014 21:41:18 -0700 Subject: DD-20 : WIP : Implemented the cut and paste code for marketplace. Stock update still not working as expected. --- indra/newview/llinventorybridge.cpp | 90 +++++++++++++++++++++++----------- indra/newview/llinventoryfunctions.cpp | 47 +++++++++++++++--- indra/newview/llinventoryfunctions.h | 4 +- indra/newview/llinventorymodel.cpp | 3 ++ 4 files changed, 105 insertions(+), 39 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index bf56be320f..5462b2bef4 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3264,13 +3264,12 @@ void LLFolderBridge::pasteFromClipboard() { const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); - // *TODO : Add marketplace listings case - //const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); - //const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id); + const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id); LLDynamicArray objects; LLClipboard::instance().pasteFromClipboard(objects); @@ -3342,21 +3341,35 @@ void LLFolderBridge::pasteFromClipboard() LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id); llassert(vicat); if (vicat) - { - //changeCategoryParent() implicity calls dirtyFilter - changeCategoryParent(model, vicat, parent_id, FALSE); + { + if (move_is_into_marketplacelistings) + { + move_folder_to_marketplacelistings(vicat, parent_id); + } + else + { + //changeCategoryParent() implicity calls dirtyFilter + changeCategoryParent(model, vicat, parent_id, FALSE); + } } } else - { - LLViewerInventoryItem* viitem = dynamic_cast(item); - llassert(viitem); - if (viitem) - { - //changeItemParent() implicity calls dirtyFilter - changeItemParent(model, viitem, parent_id, FALSE); - } - } + { + LLViewerInventoryItem* viitem = dynamic_cast(item); + llassert(viitem); + if (viitem) + { + if (move_is_into_marketplacelistings) + { + move_item_to_marketplacelistings(viitem, parent_id); + } + else + { + //changeItemParent() implicity calls dirtyFilter + changeItemParent(model, viitem, parent_id, FALSE); + } + } + } } else { @@ -3367,22 +3380,41 @@ void LLFolderBridge::pasteFromClipboard() llassert(vicat); if (vicat) { - copy_inventory_category(model, vicat, parent_id); + if (move_is_into_marketplacelistings) + { + move_folder_to_marketplacelistings(vicat, parent_id, true); + } + else + { + copy_inventory_category(model, vicat, parent_id); + } } } - else - { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - parent_id, - std::string(), - LLPointer(NULL)); - } - } - } - } + else + { + LLViewerInventoryItem* viitem = dynamic_cast(item); + llassert(viitem); + if (viitem) + { + if (move_is_into_marketplacelistings) + { + move_item_to_marketplacelistings(viitem, parent_id, true); + } + else + { + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + parent_id, + std::string(), + LLPointer(NULL)); + } + } + } + } + } + } // Change mode to paste for next paste LLClipboard::instance().setCutMode(false); } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 17bcd333f8..8216830336 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -688,7 +688,15 @@ void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_fold open_outbox(); } -void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder) +///---------------------------------------------------------------------------- +// Marketplace functions +// +// Handles Copy and Move to or within the Marketplace listings folder. +// Handles creation of stock folders, nesting of listings and version folders, +// permission checking and listings validation. +///---------------------------------------------------------------------------- + +void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) { // Get the marketplace listings, exit with error if none const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); @@ -705,7 +713,7 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol if (linked_category != NULL) { // Move the linked folder directly - move_folder_to_marketplacelistings(linked_category, dest_folder); + move_folder_to_marketplacelistings(linked_category, dest_folder, copy); } else { @@ -733,10 +741,25 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol // Get the parent folder of the moved item : we may have to update it LLUUID src_folder = viewer_inv_item->getParentUUID(); - LLViewerInventoryCategory* src_cat = gInventory.getCategory(src_folder); + LLViewerInventoryCategory* src_cat = gInventory.getCategory(src_folder); - // Reparent the item - gInventory.changeItemParent(viewer_inv_item, dest_folder, false); + if (copy) + { + // Copy the item + copy_inventory_item( + gAgent.getID(), + viewer_inv_item->getPermissions().getOwner(), + viewer_inv_item->getUUID(), + dest_folder, + std::string(), + LLPointer(NULL)); + + } + else + { + // Reparent the item + gInventory.changeItemParent(viewer_inv_item, dest_folder, false); + } // Update the modified folders gInventory.updateCategory(src_cat); @@ -754,7 +777,7 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol } } -void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder) +void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy) { // Check that we have adequate permission on all items being moved. Proceed if we do. if (has_correct_permissions_for_sale(inv_cat)) @@ -767,9 +790,17 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU LLUUID src_folder = inv_cat->getParentUUID(); LLViewerInventoryCategory* src_cat = gInventory.getCategory(src_folder); - // Reparent the folder LLViewerInventoryCategory * viewer_inv_cat = (LLViewerInventoryCategory *) inv_cat; - gInventory.changeCategoryParent(viewer_inv_cat, dest_folder, false); + if (copy) + { + // Copy the folder + copy_inventory_category(&gInventory, viewer_inv_cat, dest_folder); + } + else + { + // Reparent the folder + gInventory.changeCategoryParent(viewer_inv_cat, dest_folder, false); + } // Update the modified folders gInventory.updateCategory(src_cat); diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 006cc3de68..e6f9ef6d89 100755 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -72,8 +72,8 @@ void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LL void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id); void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id); -void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder); -void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder); +void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy = false); +void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy = false); bool has_correct_permissions_for_sale(LLInventoryCategory* cat); void validate_marketplacelistings(LLInventoryCategory* inv_cat); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 96a2db5afb..afddde02a4 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1056,7 +1056,10 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat) const LLUUID marketplace_id = findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); if (marketplace_id.notNull() && isObjectDescendentOf(cat->getUUID(), marketplace_id)) { + // *TODO : Need some internal analysis to be less brutal with updates mask |= LLInventoryObserver::LABEL; + mask |= LLInventoryObserver::STRUCTURE; + mask |= LLInventoryObserver::INTERNAL; } old_cat->copyViewerCategory(cat); addChangedMask(mask, cat->getUUID()); -- cgit v1.3 From a98346b0c3b90e75858f6ef98985c1246ad30418 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 2 Apr 2014 18:06:22 -0700 Subject: DD-20 : WIP : Improve Cut and Paste for marketplace. Still some use cases that are not working well --- indra/newview/llinventorybridge.cpp | 22 +++++++++++++++++++--- indra/newview/llinventorybridge.h | 1 + indra/newview/llinventoryfunctions.cpp | 15 ++++++++++++--- indra/newview/llinventorymodel.cpp | 4 +--- 4 files changed, 33 insertions(+), 9 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 5462b2bef4..68418063e7 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1186,6 +1186,22 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid) } } +void LLInvFVBridge::removeObject(LLInventoryModel *model, const LLUUID &uuid) +{ + // Keep track of the parent + LLInventoryItem* itemp = model->getItem(uuid); + LLUUID parent_id = (itemp ? itemp->getParentUUID() : LLUUID::null); + // Remove the object + model->removeObject(uuid); + // Get the parent updated + if (parent_id.notNull()) + { + LLViewerInventoryCategory* parent_cat = model->getCategory(parent_id); + model->updateCategory(parent_cat); + model->notifyObservers(); + } +} + bool LLInvFVBridge::canShare() const { bool can_share = false; @@ -1406,7 +1422,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) else if ("cut" == action) { cutToClipboard(); - gInventory.removeObject(mUUID); + removeObject(model, mUUID); return; } else if ("copy" == action) @@ -1973,7 +1989,7 @@ std::string LLFolderBridge::getLabelSuffix() const } else if (getCategory()->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) { - llinfos << "Merov : in merchant folder and is a stock folder : name = " << getCategory()->getName() << ", stock = " << getCategory()->getDescendentCount() << llendl; + //llinfos << "Merov : getLabelSuffix : stock folder : name = " << getCategory()->getName() << ", stock = " << getCategory()->getDescendentCount() << llendl; std::string stock = llformat("%d", getCategory()->getDescendentCount()); std::string suffix = " (" + LLTrans::getString("MarketplaceStock") + ") (" + stock + ")"; return LLInvFVBridge::getLabelSuffix() + suffix; @@ -3026,7 +3042,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) else if ("cut" == action) { cutToClipboard(); - gInventory.removeObject(mUUID); + removeObject(model, mUUID); return; } else if ("copy" == action) diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 26c48fdc57..2c0b620395 100755 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -184,6 +184,7 @@ protected: mutable std::string mSearchableName; void purgeItem(LLInventoryModel *model, const LLUUID &uuid); + void removeObject(LLInventoryModel *model, const LLUUID &uuid); virtual void buildDisplayName() const {} }; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 8216830336..aef05fead5 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -90,6 +90,14 @@ BOOL LLInventoryState::sWearNewClothing = FALSE; LLUUID LLInventoryState::sWearNewClothingTransactionID; +// Helper function : callback to update a folder after inventory action happened in the background +void update_folder_cb(const LLUUID& dest_folder) +{ + LLViewerInventoryCategory* dest_cat = gInventory.getCategory(dest_folder); + gInventory.updateCategory(dest_cat); + gInventory.notifyObservers(); +} + // Generates a string containing the path to the item specified by // item_id. void append_path(const LLUUID& id, std::string& path) @@ -163,13 +171,14 @@ void copy_inventory_category(LLInventoryModel* model, for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) { LLInventoryItem* item = *iter; + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, new_cat_uuid)); copy_inventory_item( gAgent.getID(), item->getPermissions().getOwner(), item->getUUID(), new_cat_uuid, std::string(), - LLPointer(NULL)); + cb); } // Copy all the folders @@ -746,14 +755,14 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol if (copy) { // Copy the item + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, dest_folder)); copy_inventory_item( gAgent.getID(), viewer_inv_item->getPermissions().getOwner(), viewer_inv_item->getUUID(), dest_folder, std::string(), - LLPointer(NULL)); - + cb); } else { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index afddde02a4..269542d383 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1056,11 +1056,9 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat) const LLUUID marketplace_id = findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); if (marketplace_id.notNull() && isObjectDescendentOf(cat->getUUID(), marketplace_id)) { - // *TODO : Need some internal analysis to be less brutal with updates mask |= LLInventoryObserver::LABEL; - mask |= LLInventoryObserver::STRUCTURE; - mask |= LLInventoryObserver::INTERNAL; } + llinfos << "Merov : updateCategory : " << cat->getName() << llendl; old_cat->copyViewerCategory(cat); addChangedMask(mask, cat->getUUID()); } -- cgit v1.3 From 0f944702298cc4e7c62b117d5bba1b8cd788a73d Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 3 Apr 2014 16:23:01 -0700 Subject: DD-24 : Fix the tests that decide what is resalable and what is a stock item --- indra/newview/llinventoryfunctions.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index aef05fead5..d99193067d 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -730,10 +730,9 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); viewer_inv_item = (linked_item != NULL ? linked_item : viewer_inv_item); - // Check that the agent has copy permission on the item: this is required as a resident cannot - // put on sale items she has no right about. Proceed with move if we have permission. - // *TODO : Check that this is adequate (copied from the Merchant Outbox permission check so should be OK...) - if (viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + // Check that the agent has transfer permission on the item: this is required as a resident cannot + // put on sale items she cannot transfer. Proceed with move if we have permission. + if (viewer_inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID())) { // When moving an isolated item directly under the marketplace listings root, we create a new folder with that name if (dest_folder == marketplace_listings_uuid) @@ -743,7 +742,7 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol LLViewerInventoryCategory* dest_cat = gInventory.getCategory(dest_folder); // When moving a no copy item into a first level listing folder, we create a stock folder for it - if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY) && (dest_cat->getParentUUID() == marketplace_listings_uuid)) + if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && (dest_cat->getParentUUID() == marketplace_listings_uuid)) { dest_folder = create_folder_for_item(inv_item, dest_folder); } @@ -842,8 +841,9 @@ bool has_correct_permissions_for_sale(LLInventoryCategory* cat) llinfos << "Merov : linked items in this folder -> not allowed to sell!" << llendl; return false; } - // *TODO : Check that this is adequate (copied from the Merchant Outbox permission check so should be OK...) - if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + // Check that the agent has transfer permission on the item: this is required as a resident cannot + // put on sale items she cannot transfer. Proceed with move if we have permission. + if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID())) { llinfos << "Merov : wrong permissions on items in this folder -> not allowed to sell!" << llendl; return false; @@ -891,11 +891,11 @@ void validate_marketplacelistings(LLInventoryCategory* cat) { llinfos << "Merov : Validation error: there are linked items in this listing!" << llendl; } - if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID())) { llinfos << "Merov : Validation error: there are items with incorrect permissions in this listing!" << llendl; } - if (!(viewer_inv_item->getPermissions().getMaskEveryone() & PERM_COPY) && (folder_type != LLFolderType::FT_MARKETPLACE_STOCK)) + if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && (folder_type != LLFolderType::FT_MARKETPLACE_STOCK)) { llinfos << "Merov : Validation warning : no copy item found in non stock folder -> reparent to relevant stock folder!" << llendl; if (stock_folder_uuid.isNull()) -- cgit v1.3 From e1d2f71d348bafe0be783dcb3dfbeb56bc877c12 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 4 Apr 2014 16:56:17 -0700 Subject: DD-14 : Add all right click menu items for marketplace. Make Add, Activate and Deactivate work. Right click fails on non folder items though in marketplace --- indra/newview/llfloatermarketplacelistings.cpp | 23 ----- indra/newview/llinventorybridge.cpp | 113 +++++++++++++++++++-- indra/newview/llinventoryfunctions.cpp | 27 +++++ indra/newview/llinventoryfunctions.h | 1 + .../skins/default/xui/en/menu_inventory.xml | 51 ++++++++-- 5 files changed, 174 insertions(+), 41 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index 42e49f5d7d..10c6045f87 100755 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -246,29 +246,6 @@ void LLFloaterMarketplaceListings::onOpen(const LLSD& key) setup(); } - // Merov : Debug : Create fake Marketplace data if none is present - if (LLMarketplaceData::instance().isEmpty() && (getFolderCount() > 0)) - { - LLInventoryModel::cat_array_t* cats; - LLInventoryModel::item_array_t* items; - gInventory.getDirectDescendentsOf(mRootFolderId, cats, items); - - int index = 0; - for (LLInventoryModel::cat_array_t::iterator iter = cats->begin(); iter != cats->end(); iter++, index++) - { - LLViewerInventoryCategory* category = *iter; - if (index%3) - { - LLMarketplaceData::instance().addTestItem(category->getUUID()); - if (index%3 == 1) - { - LLMarketplaceData::instance().setListingID(category->getUUID(),"TestingID1234"); - } - LLMarketplaceData::instance().setActivation(category->getUUID(),(index%2)); - } - } - } - // // Update the floater view // diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index ceb54b3dcd..cd3e51a0ea 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -744,10 +744,6 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { addOutboxContextMenuOptions(flags, items, disabled_items); } - else if (isMarketplaceListingsFolder()) - { - addMarketplaceContextMenuOptions(flags, items, disabled_items); - } else { items.push_back(std::string("Share")); @@ -853,8 +849,49 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags, menuentry_vec_t &items, menuentry_vec_t &disabled_items) { - items.push_back(std::string("Marketplace Separator")); - items.push_back(std::string("Marketplace Activate")); + S32 depth = depth_nesting_in_marketplace(mUUID); + llinfos << "Merov : adding marketplace menu at depth = " << depth << llendl; + if (depth <= 1) + { + // Options available at the Listing Folder level only + items.push_back(std::string("Marketplace Add Listing")); + items.push_back(std::string("Marketplace Attach Listing")); + if (LLMarketplaceData::instance().isListed(mUUID)) + { + disabled_items.push_back(std::string("Marketplace Add Listing")); + disabled_items.push_back(std::string("Marketplace Attach Listing")); + } + } + if (depth <= 2) + { + // Options available at the Listing Folder and Version Folder levels + items.push_back(std::string("Marketplace Activate")); + items.push_back(std::string("Marketplace Deactivate")); + if (LLMarketplaceData::instance().isListed(mUUID)) + { + if (LLMarketplaceData::instance().getActivationState(mUUID)) + { + disabled_items.push_back(std::string("Marketplace Activate")); + } + else + { + disabled_items.push_back(std::string("Marketplace Deactivate")); + } + } + else + { + disabled_items.push_back(std::string("Marketplace Activate")); + disabled_items.push_back(std::string("Marketplace Deactivate")); + } + } + // Options available at all levels on all items + items.push_back(std::string("Marketplace Show Listing")); + if (!LLMarketplaceData::instance().isListed(mUUID)) + { + disabled_items.push_back(std::string("Marketplace Show Listing")); + } + // Separator + items.push_back(std::string("Marketplace Listings Separator")); } @@ -3084,13 +3121,33 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) } else if ("marketplace_activate" == action) { - if (!LLMarketplaceData::instance().isListed(mUUID)) - { - LLMarketplaceData::instance().addTestItem(mUUID); - } LLMarketplaceData::instance().setActivation(mUUID,true); return; } + else if ("marketplace_deactivate" == action) + { + LLMarketplaceData::instance().setActivation(mUUID,false); + return; + } + else if ("marketplace_add_listing" == action) + { + // *TODO : Do something a bit smarter... + LLMarketplaceData::instance().addTestItem(mUUID); + return; + } + else if ("marketplace_attach_listing" == action) + { + // *TODO : Get a list of listing IDs and let the user choose one, delist the old one and relist the new one + LLMarketplaceData::instance().addTestItem(mUUID); + return; + } + else if ("marketplace_show_listing" == action) + { + // *TODO : Need to show a browser window with the info for the listing + // Get the listing id (i.e. go up the hierarchy to find the listing folder + // Show the listing folder in a browser window + return; + } #ifndef LL_RELEASE_FOR_DOWNLOAD else if ("delete_system_folder" == action) { @@ -4644,6 +4701,10 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { addOutboxContextMenuOptions(flags, items, disabled_items); } + else if (isMarketplaceListingsFolder()) + { + addMarketplaceContextMenuOptions(flags, items, disabled_items); + } else { items.push_back(std::string("Share")); @@ -4711,6 +4772,10 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { addOutboxContextMenuOptions(flags, items, disabled_items); } + else if (isMarketplaceListingsFolder()) + { + addMarketplaceContextMenuOptions(flags, items, disabled_items); + } else { if (isItemInTrash()) @@ -4769,6 +4834,10 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { addOutboxContextMenuOptions(flags, items, disabled_items); } + else if (isMarketplaceListingsFolder()) + { + addMarketplaceContextMenuOptions(flags, items, disabled_items); + } else { if(isItemInTrash()) @@ -5019,6 +5088,10 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { items.push_back(std::string("Delete")); } + else if (isMarketplaceListingsFolder()) + { + addMarketplaceContextMenuOptions(flags, items, disabled_items); + } else { items.push_back(std::string("Share")); @@ -5286,6 +5359,10 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { items.push_back(std::string("Delete")); } + else if (isMarketplaceListingsFolder()) + { + addMarketplaceContextMenuOptions(flags, items, disabled_items); + } else { items.push_back(std::string("Share")); @@ -5340,6 +5417,10 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { items.push_back(std::string("Delete")); } + else if (isMarketplaceListingsFolder()) + { + addMarketplaceContextMenuOptions(flags, items, disabled_items); + } else { if(isItemInTrash()) @@ -5619,6 +5700,10 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { items.push_back(std::string("Delete")); } + else if (isMarketplaceListingsFolder()) + { + addMarketplaceContextMenuOptions(flags, items, disabled_items); + } else { items.push_back(std::string("Share")); @@ -5841,6 +5926,10 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { items.push_back(std::string("Delete")); } + else if (isMarketplaceListingsFolder()) + { + addMarketplaceContextMenuOptions(flags, items, disabled_items); + } else { // FWIW, it looks like SUPPRESS_OPEN_ITEM is not set anywhere BOOL can_open = ((flags & SUPPRESS_OPEN_ITEM) != SUPPRESS_OPEN_ITEM); @@ -6141,6 +6230,10 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { addOutboxContextMenuOptions(flags, items, disabled_items); } + else if (isMarketplaceListingsFolder()) + { + addMarketplaceContextMenuOptions(flags, items, disabled_items); + } else { items.push_back(std::string("Properties")); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index d99193067d..e57519d67a 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -705,6 +705,33 @@ void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_fold // permission checking and listings validation. ///---------------------------------------------------------------------------- +S32 depth_nesting_in_marketplace(LLUUID cur_uuid) +{ + // Get the marketplace listings root, exit with -1 (i.e. not under the marketplace listings root) if none + const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + if (marketplace_listings_uuid.isNull()) + { + return -1; + } + // If not a descendent of the marketplace listings root, then the nesting depth is -1 by definition + if (!gInventory.isObjectDescendentOf(cur_uuid, marketplace_listings_uuid)) + { + return -1; + } + + // Iterate through the parents till we hit the marketplace listings root + // Note that the marketplace listings root itself will return 0 + S32 depth = 0; + LLInventoryObject* cur_object = gInventory.getObject(cur_uuid); + while (cur_uuid != marketplace_listings_uuid) + { + depth++; + cur_uuid = cur_object->getParentUUID(); + cur_object = gInventory.getCategory(cur_uuid); + } + return depth; +} + void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) { // Get the marketplace listings, exit with error if none diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index e6f9ef6d89..aab4db8adf 100755 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -76,6 +76,7 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy = false); bool has_correct_permissions_for_sale(LLInventoryCategory* cat); void validate_marketplacelistings(LLInventoryCategory* inv_cat); +S32 depth_nesting_in_marketplace(LLUUID cur_uuid); /** Miscellaneous global functions ** ** diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index aa115c1ad1..cde14e72f0 100755 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -4,6 +4,49 @@ layout="topleft" name="Popup" visible="false"> + + + + + + + + + + + + + + + + - - - -- cgit v1.3 From a38bc63da24994b51cfd3487d4011c8e608cd41d Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 6 Apr 2014 22:03:58 -0700 Subject: DD-15 : Allow version folder to be made active/inactive, add new methods to marketplace to make all that a bit more clear and clean --- indra/newview/llinventorybridge.cpp | 74 +++++++++++++------- indra/newview/llinventoryfunctions.cpp | 20 +++++- indra/newview/llinventoryfunctions.h | 1 + indra/newview/llmarketplacefunctions.cpp | 112 ++++++++++++++++++++++++++----- indra/newview/llmarketplacefunctions.h | 26 ++++--- 5 files changed, 179 insertions(+), 54 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index cd3e51a0ea..9c9f195875 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -851,24 +851,17 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags, { S32 depth = depth_nesting_in_marketplace(mUUID); llinfos << "Merov : adding marketplace menu at depth = " << depth << llendl; - if (depth <= 1) + if (depth == 1) { - // Options available at the Listing Folder level only + // Options available at the Listing Folder level items.push_back(std::string("Marketplace Add Listing")); items.push_back(std::string("Marketplace Attach Listing")); - if (LLMarketplaceData::instance().isListed(mUUID)) - { - disabled_items.push_back(std::string("Marketplace Add Listing")); - disabled_items.push_back(std::string("Marketplace Attach Listing")); - } - } - if (depth <= 2) - { - // Options available at the Listing Folder and Version Folder levels items.push_back(std::string("Marketplace Activate")); items.push_back(std::string("Marketplace Deactivate")); if (LLMarketplaceData::instance().isListed(mUUID)) { + disabled_items.push_back(std::string("Marketplace Add Listing")); + disabled_items.push_back(std::string("Marketplace Attach Listing")); if (LLMarketplaceData::instance().getActivationState(mUUID)) { disabled_items.push_back(std::string("Marketplace Activate")); @@ -884,9 +877,28 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags, disabled_items.push_back(std::string("Marketplace Deactivate")); } } + if (depth == 2) + { + // Options available at the Version Folder levels + LLInventoryObject* object = gInventory.getObject(mUUID); + if (LLMarketplaceData::instance().isListed(object->getParentUUID())) + { + items.push_back(std::string("Marketplace Activate")); + items.push_back(std::string("Marketplace Deactivate")); + if (LLMarketplaceData::instance().getActivationState(mUUID)) + { + disabled_items.push_back(std::string("Marketplace Activate")); + } + else + { + disabled_items.push_back(std::string("Marketplace Deactivate")); + } + } + } // Options available at all levels on all items items.push_back(std::string("Marketplace Show Listing")); - if (!LLMarketplaceData::instance().isListed(mUUID)) + LLUUID listing_folder_id = nested_parent_id(mUUID,depth); + if (!LLMarketplaceData::instance().isListed(listing_folder_id)) { disabled_items.push_back(std::string("Marketplace Show Listing")); } @@ -2011,17 +2023,9 @@ void LLFolderBridge::buildDisplayName() const std::string LLFolderBridge::getLabelSuffix() const { - // *TODO : We need to display some suffix also for the version folder! - /* - LLInventoryCategory* cat = gInventory.getCategory(getUUID()); - if(cat) - { - const LLUUID& parent_folder_id = cat->getParentUUID(); - accessories = (parent_folder_id == gInventory.getLibraryRootFolderID()); - } - */ if (isMarketplaceListingsFolder()) { + // Listing folder case if (LLMarketplaceData::instance().isListed(getUUID())) { //llinfos << "Merov : in merchant folder and listed : id = " << getUUID() << llendl; @@ -2037,6 +2041,17 @@ std::string LLFolderBridge::getLabelSuffix() const } return LLInvFVBridge::getLabelSuffix() + suffix; } + // Version folder case + else if (LLMarketplaceData::instance().isVersionFolder(getUUID())) + { + std::string suffix; + if (LLMarketplaceData::instance().getActivationState(getUUID())) + { + suffix += " (" + LLTrans::getString("MarketplaceActive") + ")"; + } + return LLInvFVBridge::getLabelSuffix() + suffix; + } + // Stock folder case else if (getCategory()->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) { //llinfos << "Merov : getLabelSuffix : stock folder : name = " << getCategory()->getName() << ", stock = " << getCategory()->getDescendentCount() << llendl; @@ -3121,7 +3136,17 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) } else if ("marketplace_activate" == action) { - LLMarketplaceData::instance().setActivation(mUUID,true); + S32 depth = depth_nesting_in_marketplace(mUUID); + if (depth == 2) + { + LLInventoryCategory* category = gInventory.getCategory(mUUID); + LLMarketplaceData::instance().setVersionFolderID(category->getParentUUID(), mUUID); + LLMarketplaceData::instance().setActivation(mUUID,true); + } + else if (depth == 1) + { + LLMarketplaceData::instance().setActivation(mUUID,true); + } return; } else if ("marketplace_deactivate" == action) @@ -3131,14 +3156,13 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) } else if ("marketplace_add_listing" == action) { - // *TODO : Do something a bit smarter... - LLMarketplaceData::instance().addTestItem(mUUID); + LLMarketplaceData::instance().addListing(mUUID); return; } else if ("marketplace_attach_listing" == action) { // *TODO : Get a list of listing IDs and let the user choose one, delist the old one and relist the new one - LLMarketplaceData::instance().addTestItem(mUUID); + LLMarketplaceData::instance().addListing(mUUID); return; } else if ("marketplace_show_listing" == action) diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index e57519d67a..aef3bc9cca 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -125,8 +125,11 @@ void update_marketplace_category(const LLUUID& cat_id) // for all observers of the folder to, possibly, change the display label of said folder. // At least that's the status for the moment so, even if that function seems small, we // prefer to encapsulate that behavior here. - gInventory.addChangedMask(LLInventoryObserver::LABEL, cat_id); - gInventory.notifyObservers(); + if (cat_id.notNull()) + { + gInventory.addChangedMask(LLInventoryObserver::LABEL, cat_id); + gInventory.notifyObservers(); + } } void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name) @@ -732,6 +735,19 @@ S32 depth_nesting_in_marketplace(LLUUID cur_uuid) return depth; } +LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth) +{ + LLInventoryObject* cur_object = gInventory.getObject(cur_uuid); + cur_uuid = (depth < 1 ? LLUUID::null : cur_uuid); + while (depth > 1) + { + depth--; + cur_uuid = cur_object->getParentUUID(); + cur_object = gInventory.getCategory(cur_uuid); + } + return cur_uuid; +} + void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) { // Get the marketplace listings, exit with error if none diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index aab4db8adf..69219c7c42 100755 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -77,6 +77,7 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU bool has_correct_permissions_for_sale(LLInventoryCategory* cat); void validate_marketplacelistings(LLInventoryCategory* inv_cat); S32 depth_nesting_in_marketplace(LLUUID cur_uuid); +LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth); /** Miscellaneous global functions ** ** diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 6f35cc217d..29ce5361f0 100755 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -535,25 +535,25 @@ void LLMarketplaceInventoryImporter::updateImport() // Tuple == Item LLMarketplaceTuple::LLMarketplaceTuple() : - mFolderListingId(), + mListingFolderId(), mListingId(""), - mActiveVersionFolderId(), + mVersionFolderId(), mIsActive(false) { } LLMarketplaceTuple::LLMarketplaceTuple(const LLUUID& folder_id) : - mFolderListingId(folder_id), + mListingFolderId(folder_id), mListingId(""), - mActiveVersionFolderId(), + mVersionFolderId(), mIsActive(false) { } LLMarketplaceTuple::LLMarketplaceTuple(const LLUUID& folder_id, std::string listing_id, const LLUUID& version_id, bool is_listed) : - mFolderListingId(folder_id), + mListingFolderId(folder_id), mListingId(listing_id), - mActiveVersionFolderId(version_id), + mVersionFolderId(version_id), mIsActive(is_listed) { } @@ -564,28 +564,85 @@ LLMarketplaceData::LLMarketplaceData() { } +// Creation / Deletion +bool LLMarketplaceData::addListing(const LLUUID& folder_id) +{ + if (isListed(folder_id)) + { + // Listing already exists -> exit with error + return false; + } + mMarketplaceItems[folder_id] = LLMarketplaceTuple(folder_id); + update_marketplace_category(folder_id); + return true; +} + +bool LLMarketplaceData::deleteListing(const LLUUID& folder_id) +{ + if (!isListed(folder_id)) + { + // Listing doesn't exist -> exit with error + return false; + } + mMarketplaceItems.erase(folder_id); + update_marketplace_category(folder_id); + return true; +} + // Accessors bool LLMarketplaceData::getActivationState(const LLUUID& folder_id) { - marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id); - return (it == mMarketplaceItems.end() ? false : (it->second).mIsActive); + // Listing folder case + if (isListed(folder_id)) + { + marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id); + return (it->second).mIsActive; + } + // We need to iterate through the list to check it's not a version folder + marketplace_items_list_t::iterator it = mMarketplaceItems.begin(); + while (it != mMarketplaceItems.end()) + { + if ((it->second).mVersionFolderId == folder_id) + { + return (it->second).mIsActive; + } + it++; + } + return false; } + std::string LLMarketplaceData::getListingID(const LLUUID& folder_id) { marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id); return (it == mMarketplaceItems.end() ? "" : (it->second).mListingId); } + LLUUID LLMarketplaceData::getVersionFolderID(const LLUUID& folder_id) { marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id); - return (it == mMarketplaceItems.end() ? LLUUID::null : (it->second).mActiveVersionFolderId); + return (it == mMarketplaceItems.end() ? LLUUID::null : (it->second).mVersionFolderId); } + bool LLMarketplaceData::isListed(const LLUUID& folder_id) { marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id); return (it != mMarketplaceItems.end()); } +bool LLMarketplaceData::isVersionFolder(const LLUUID& folder_id) +{ + marketplace_items_list_t::iterator it = mMarketplaceItems.begin(); + while (it != mMarketplaceItems.end()) + { + if ((it->second).mVersionFolderId == folder_id) + { + return true; + } + it++; + } + return false; +} + // Modifiers bool LLMarketplaceData::setListingID(const LLUUID& folder_id, std::string listing_id) { @@ -601,6 +658,7 @@ bool LLMarketplaceData::setListingID(const LLUUID& folder_id, std::string listin return true; } } + bool LLMarketplaceData::setVersionFolderID(const LLUUID& folder_id, const LLUUID& version_id) { marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id); @@ -610,24 +668,42 @@ bool LLMarketplaceData::setVersionFolderID(const LLUUID& folder_id, const LLUUID } else { - (it->second).mActiveVersionFolderId = version_id; - update_marketplace_category(folder_id); + LLUUID old_version_id = (it->second).mVersionFolderId; + if (old_version_id != version_id) + { + (it->second).mVersionFolderId = version_id; + update_marketplace_category(old_version_id); + update_marketplace_category(version_id); + } return true; } } + bool LLMarketplaceData::setActivation(const LLUUID& folder_id, bool activate) { - marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id); - if (it == mMarketplaceItems.end()) - { - return false; - } - else + // Listing folder case + if (isListed(folder_id)) { + marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id); (it->second).mIsActive = activate; - update_marketplace_category(folder_id); + update_marketplace_category((it->second).mListingFolderId); + update_marketplace_category((it->second).mVersionFolderId); return true; } + // We need to iterate through the list to check it's not a version folder + marketplace_items_list_t::iterator it = mMarketplaceItems.begin(); + while (it != mMarketplaceItems.end()) + { + if ((it->second).mVersionFolderId == folder_id) + { + (it->second).mIsActive = activate; + update_marketplace_category((it->second).mListingFolderId); + update_marketplace_category((it->second).mVersionFolderId); + return true; + } + it++; + } + return false; } // Test methods diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index 00840c6e23..d76072da1f 100755 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -113,7 +113,8 @@ private: // * implement the Marketplace API (TBD) // * cache the current Marketplace data (tuples) // * provide methods to get Marketplace data on any inventory item -// * signal marketplace updates to inventory +// * set Marketplace data +// * signal Marketplace updates to inventory class LLMarketplaceData; // A Marketplace item is known by its tuple @@ -128,15 +129,16 @@ public: private: // Representation of a marketplace item in the Marketplace DB (well, what we know of it...) - LLUUID mFolderListingId; + LLUUID mListingFolderId; std::string mListingId; - LLUUID mActiveVersionFolderId; + LLUUID mVersionFolderId; bool mIsActive; }; -// Note: the folder UUID is used as a key to this map. It could therefore be taken off the object themselves +// Note: The listing folder UUID is used as a key to this map. It could therefore be taken off the LLMarketplaceTuple objects themselves typedef std::map marketplace_items_list_t; -// There's one and only one possible set of Marketplace data per agent and per session +// Session cache of Marketplace tuples +// Note: There's one and only one possible set of Marketplace dataset per agent and per session class LLMarketplaceData : public LLSingleton { @@ -145,14 +147,20 @@ public: bool isEmpty() { return (mMarketplaceItems.size() == 0); } - // Access Marketplace Data : each method returns a default value if the folder_id can't be found + // Probe the Marketplace data set to identify folders + bool isListed(const LLUUID& folder_id); // returns true if folder_id is a Listing folder + bool isVersionFolder(const LLUUID& folder_id); // returns true if folder_id is a Version folder + + // Create/Delete Marketplace data set : each method returns true if the function succeeds, false if error + bool addListing(const LLUUID& folder_id); + bool deleteListing(const LLUUID& folder_id); + + // Access Marketplace data set : each method returns a default value if the folder_id can't be found bool getActivationState(const LLUUID& folder_id); std::string getListingID(const LLUUID& folder_id); LLUUID getVersionFolderID(const LLUUID& folder_id); - bool isListed(const LLUUID& folder_id); // returns true if folder_id is in the items map - - // Modify Marketplace Data : each method returns true if the function succeeds, false if error + // Modify Marketplace data set : each method returns true if the function succeeds, false if error bool setListingID(const LLUUID& folder_id, std::string listing_id); bool setVersionFolderID(const LLUUID& folder_id, const LLUUID& version_id); bool setActivation(const LLUUID& folder_id, bool activate); -- cgit v1.3 From fc4e9d2572635903449ade6ebf2a45aa9e971023 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 8 Apr 2014 18:12:48 -0700 Subject: DD-18 : Compute stock for all levels, get folders to update more consistently on all actions in the marketplace --- indra/newview/llinventorybridge.cpp | 24 +++---- indra/newview/llinventoryfunctions.cpp | 87 ++++++++++++++++++++------ indra/newview/llinventoryfunctions.h | 1 + indra/newview/llinventorymodel.cpp | 2 +- indra/newview/skins/default/xui/en/strings.xml | 1 + 5 files changed, 78 insertions(+), 37 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 8d87b40e4e..7ff0a445e8 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -652,7 +652,6 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, items.push_back(std::string("Rename")); if (!isItemRenameable() || ((flags & FIRST_SELECTED_ITEM) == 0)) { - llinfos << "Merov : rename disable, renameable = " << isItemRenameable() << ", flags = " << flags << llendl; disabled_items.push_back(std::string("Rename")); } } @@ -851,7 +850,6 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags, menuentry_vec_t &disabled_items) { S32 depth = depth_nesting_in_marketplace(mUUID); - llinfos << "Merov : adding marketplace menu at depth = " << depth << llendl; if (depth == 1) { // Options available at the Listing Folder level @@ -2026,11 +2024,11 @@ std::string LLFolderBridge::getLabelSuffix() const { if (isMarketplaceListingsFolder()) { + std::string suffix = ""; // Listing folder case if (LLMarketplaceData::instance().isListed(getUUID())) { - //llinfos << "Merov : in merchant folder and listed : id = " << getUUID() << llendl; - std::string suffix = LLMarketplaceData::instance().getListingID(getUUID()); + suffix = LLMarketplaceData::instance().getListingID(getUUID()); if (suffix.empty()) { suffix = LLTrans::getString("MarketplaceNoID"); @@ -2040,31 +2038,25 @@ std::string LLFolderBridge::getLabelSuffix() const { suffix += " (" + LLTrans::getString("MarketplaceActive") + ")"; } - return LLInvFVBridge::getLabelSuffix() + suffix; } // Version folder case else if (LLMarketplaceData::instance().isVersionFolder(getUUID())) { - std::string suffix; if (LLMarketplaceData::instance().getActivationState(getUUID())) { suffix += " (" + LLTrans::getString("MarketplaceActive") + ")"; } - return LLInvFVBridge::getLabelSuffix() + suffix; } - // Stock folder case - else if (getCategory()->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + S32 stock_count = compute_stock_count(getUUID()); + if (stock_count == 0) { - //llinfos << "Merov : getLabelSuffix : stock folder : name = " << getCategory()->getName() << ", stock = " << getCategory()->getDescendentCount() << llendl; - std::string stock = llformat("%d", getCategory()->getDescendentCount()); - std::string suffix = " (" + LLTrans::getString("MarketplaceStock") + ") (" + stock + ")"; - return LLInvFVBridge::getLabelSuffix() + suffix; + suffix += " (" + LLTrans::getString("MarketplaceNoStock") + ")"; } - else + else if (stock_count != -1) { - //llinfos << "Merov : in merchant folder but not listed : id = " << getUUID() << llendl; - return LLInvFVBridge::getLabelSuffix(); + suffix += " (" + LLTrans::getString("MarketplaceStock") + "=" + llformat("%d", stock_count) + ")"; } + return LLInvFVBridge::getLabelSuffix() + suffix; } else { diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index aef3bc9cca..20cbb06f07 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -122,14 +122,31 @@ void append_path(const LLUUID& id, std::string& path) void update_marketplace_category(const LLUUID& cat_id) { // When changing the marketplace status of a folder, the only thing that needs to happen is - // for all observers of the folder to, possibly, change the display label of said folder. - // At least that's the status for the moment so, even if that function seems small, we - // prefer to encapsulate that behavior here. - if (cat_id.notNull()) + // for all observers of the folder to, possibly, change the display label of the folder + // as well as, potentially, change the display label of all parent folders up to the marketplace root. + + const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + // No marketplace, likely called in error then... + // Or not a descendent of the marketplace listings root, then just do the regular category update + if (marketplace_listings_uuid.isNull() || !gInventory.isObjectDescendentOf(cat_id, marketplace_listings_uuid)) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + gInventory.updateCategory(cat); + gInventory.notifyObservers(); + return; + } + // Explore all the hierarchy of folders up to the root to get them to update + // Note: this is not supposed to be deeper than 4 + LLUUID cur_id = cat_id; + LLInventoryCategory* cur_cat = gInventory.getCategory(cur_id); + while (cur_id != marketplace_listings_uuid) { - gInventory.addChangedMask(LLInventoryObserver::LABEL, cat_id); + gInventory.addChangedMask(LLInventoryObserver::LABEL, cur_id); gInventory.notifyObservers(); + cur_id = cur_cat->getParentUUID(); + cur_cat = gInventory.getCategory(cur_id); } + return; } void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name) @@ -748,6 +765,41 @@ LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth) return cur_uuid; } +S32 compute_stock_count(LLUUID cat_uuid) +{ + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat_uuid,cat_array,item_array); + + // "-1" denotes a folder that doesn't countain any stock folders in its descendents + S32 curr_count = -1; + + LLInventoryCategory* cat = gInventory.getCategory(cat_uuid); + + if (cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + // Note: stock folders are *not* supposed to have nested subfolders so we stop recursion here + LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); + curr_count = viewer_cat->getDescendentCount(); + } + else + { + // Note: marketplace listings have a maximum depth nesting of 4 + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + { + LLInventoryCategory* category = *iter; + S32 count = compute_stock_count(category->getUUID()); + if ((curr_count == -1) || ((count != -1) && (count < curr_count))) + { + curr_count = count; + } + } + } + + return curr_count; +} + void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) { // Get the marketplace listings, exit with error if none @@ -792,7 +844,6 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol // Get the parent folder of the moved item : we may have to update it LLUUID src_folder = viewer_inv_item->getParentUUID(); - LLViewerInventoryCategory* src_cat = gInventory.getCategory(src_folder); if (copy) { @@ -812,13 +863,12 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol gInventory.changeItemParent(viewer_inv_item, dest_folder, false); } - // Update the modified folders - gInventory.updateCategory(src_cat); - gInventory.updateCategory(dest_cat); - gInventory.notifyObservers(); - // Validate the destination : note that this will run the validation code only on one listing folder at most... validate_marketplacelistings(dest_cat); + + // Update the modified folders + update_marketplace_category(src_folder); + update_marketplace_category(dest_folder); } else { @@ -839,7 +889,6 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU // Get the parent folder of the moved item : we may have to update it LLUUID src_folder = inv_cat->getParentUUID(); - LLViewerInventoryCategory* src_cat = gInventory.getCategory(src_folder); LLViewerInventoryCategory * viewer_inv_cat = (LLViewerInventoryCategory *) inv_cat; if (copy) @@ -853,13 +902,12 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU gInventory.changeCategoryParent(viewer_inv_cat, dest_folder, false); } - // Update the modified folders - gInventory.updateCategory(src_cat); - gInventory.updateCategory(dest_cat); - gInventory.notifyObservers(); - // Check the destination folder recursively for no copy items and promote the including folders if any validate_marketplacelistings(dest_cat); + + // Update the modified folders + update_marketplace_category(src_folder); + update_marketplace_category(dest_folder); } } @@ -948,9 +996,8 @@ void validate_marketplacelistings(LLInventoryCategory* cat) stock_folder_cat = gInventory.getCategory(stock_folder_uuid); } gInventory.changeItemParent(viewer_inv_item, stock_folder_uuid, false); - gInventory.updateCategory(viewer_cat); - gInventory.updateCategory(stock_folder_cat); - gInventory.notifyObservers(); + update_marketplace_category(viewer_cat->getUUID()); + update_marketplace_category(stock_folder_uuid); } } diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 69219c7c42..66f1c99630 100755 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -78,6 +78,7 @@ bool has_correct_permissions_for_sale(LLInventoryCategory* cat); void validate_marketplacelistings(LLInventoryCategory* inv_cat); S32 depth_nesting_in_marketplace(LLUUID cur_uuid); LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth); +S32 compute_stock_count(LLUUID cat_uuid); /** Miscellaneous global functions ** ** diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 96a2db5afb..c0aedd3881 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1013,7 +1013,7 @@ LLInventoryModel::item_array_t* LLInventoryModel::getUnlockedItemArray(const LLU // an existing item with the matching id, or it will add the category. void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat) { - if(cat->getUUID().isNull()) + if(!cat || cat->getUUID().isNull()) { return; } diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index ce9bbbc8d2..55272750e7 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2274,6 +2274,7 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors. no Mkt ID live stock + out of stock Open landmarks -- cgit v1.3 From 9b52f19a68eb9ff3e88c9d45c2d799be6eccf44e Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 8 Apr 2014 21:26:40 -0700 Subject: DD-18 : Make the stock count take the listing status and version status into account so to be accurate and more resilient --- indra/newview/llinventoryfunctions.cpp | 66 ++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 18 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 20cbb06f07..ad9326965b 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -59,6 +59,7 @@ #include "llinventorypanel.h" #include "lllineeditor.h" #include "llmarketplacenotifications.h" +#include "llmarketplacefunctions.h" #include "llmenugl.h" #include "llnotificationsutil.h" #include "llpanelmaininventory.h" @@ -752,6 +753,7 @@ S32 depth_nesting_in_marketplace(LLUUID cur_uuid) return depth; } +// Returns the UUID of the marketplace listing this object is in LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth) { LLInventoryObject* cur_object = gInventory.getObject(cur_uuid); @@ -767,6 +769,45 @@ LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth) S32 compute_stock_count(LLUUID cat_uuid) { + // Handle the case of the folder being a stock folder immediately + LLViewerInventoryCategory* cat = gInventory.getCategory(cat_uuid); + if (cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + // Note: stock folders are *not* supposed to have nested subfolders so we stop recursion here + // Note: we *always* give a stock count for stock folders, it's useful even if the listing is unassociated + //LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); + return cat->getDescendentCount(); + } + + // Grab marketplace data for this folder + S32 depth = depth_nesting_in_marketplace(cat_uuid); + LLUUID listing_uuid = nested_parent_id(cat_uuid, depth); + if (!LLMarketplaceData::instance().isListed(listing_uuid)) + { + // If not listed, the notion of stock is meaningless so it won't be computed for any level + return -1; + } + + LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolderID(listing_uuid); + // Handle the case of the first 2 levels : listing and version folders + if (depth == 1) + { + if (version_folder_uuid.notNull()) + { + // If there is a version folder, the stock value for the listing is the version folder stock + return compute_stock_count(version_folder_uuid); + } + } + else if (depth == 2) + { + if (version_folder_uuid.notNull() && (version_folder_uuid != cat_uuid)) + { + // If there is a version folder but we're not it, our stock count is meaningless + return -1; + } + } + + // In all other cases, the stock count is the min of stock folders count found in the descendents LLInventoryModel::cat_array_t* cat_array; LLInventoryModel::item_array_t* item_array; gInventory.getDirectDescendentsOf(cat_uuid,cat_array,item_array); @@ -774,26 +815,15 @@ S32 compute_stock_count(LLUUID cat_uuid) // "-1" denotes a folder that doesn't countain any stock folders in its descendents S32 curr_count = -1; - LLInventoryCategory* cat = gInventory.getCategory(cat_uuid); - - if (cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) - { - // Note: stock folders are *not* supposed to have nested subfolders so we stop recursion here - LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); - curr_count = viewer_cat->getDescendentCount(); - } - else + // Note: marketplace listings have a maximum depth nesting of 4 + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) { - // Note: marketplace listings have a maximum depth nesting of 4 - LLInventoryModel::cat_array_t cat_array_copy = *cat_array; - for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + LLInventoryCategory* category = *iter; + S32 count = compute_stock_count(category->getUUID()); + if ((curr_count == -1) || ((count != -1) && (count < curr_count))) { - LLInventoryCategory* category = *iter; - S32 count = compute_stock_count(category->getUUID()); - if ((curr_count == -1) || ((count != -1) && (count < curr_count))) - { - curr_count = count; - } + curr_count = count; } } -- cgit v1.3 From 748bbeaf982c456b120d4b3f4d33aa6dce576908 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 9 Apr 2014 14:19:38 -0700 Subject: DD-13 : Clean up Associate/Disassociate listing. Also clarify the update folder code in marketplace --- indra/newview/llinventorybridge.cpp | 19 ++++++-- indra/newview/llinventoryfunctions.cpp | 55 ++++++++++++++++------ indra/newview/llmarketplacefunctions.cpp | 18 ------- indra/newview/llmarketplacefunctions.h | 5 -- .../skins/default/xui/en/menu_inventory.xml | 14 ++++-- 5 files changed, 67 insertions(+), 44 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 7ff0a445e8..3af734ba27 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -65,6 +65,7 @@ #include "llsidepanelappearance.h" #include "lltooldraganddrop.h" #include "lltrans.h" +#include "llurlaction.h" #include "llviewerassettype.h" #include "llviewerfoldertype.h" #include "llviewermenu.h" @@ -853,13 +854,14 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags, if (depth == 1) { // Options available at the Listing Folder level - items.push_back(std::string("Marketplace Add Listing")); + items.push_back(std::string("Marketplace Associate Listing")); items.push_back(std::string("Marketplace Attach Listing")); + items.push_back(std::string("Marketplace Disassociate Listing")); items.push_back(std::string("Marketplace Activate")); items.push_back(std::string("Marketplace Deactivate")); if (LLMarketplaceData::instance().isListed(mUUID)) { - disabled_items.push_back(std::string("Marketplace Add Listing")); + disabled_items.push_back(std::string("Marketplace Associate Listing")); disabled_items.push_back(std::string("Marketplace Attach Listing")); if (LLMarketplaceData::instance().getActivationState(mUUID)) { @@ -872,6 +874,7 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags, } else { + disabled_items.push_back(std::string("Marketplace Disassociate Listing")); disabled_items.push_back(std::string("Marketplace Activate")); disabled_items.push_back(std::string("Marketplace Deactivate")); } @@ -3147,11 +3150,16 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) LLMarketplaceData::instance().setActivation(mUUID,false); return; } - else if ("marketplace_add_listing" == action) + else if ("marketplace_associate_listing" == action) { LLMarketplaceData::instance().addListing(mUUID); return; } + else if ("marketplace_disassociate_listing" == action) + { + LLMarketplaceData::instance().deleteListing(mUUID); + return; + } else if ("marketplace_attach_listing" == action) { // *TODO : Get a list of listing IDs and let the user choose one, delist the old one and relist the new one @@ -3163,6 +3171,11 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) // *TODO : Need to show a browser window with the info for the listing // Get the listing id (i.e. go up the hierarchy to find the listing folder // Show the listing folder in a browser window + // https://marketplace.secondlife.com/p/Nounours/4438852 + // https://marketplace.secondlife.com/p/Un-autre-nounours/4447997?preview=true + // https://marketplace.secondlife.com/p//?preview=true + std::string url("https://marketplace.secondlife.com/p/Un-autre-nounours/4447997?preview=true"); + LLUrlAction::openURL(url); return; } #ifndef LL_RELEASE_FOR_DOWNLOAD diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ad9326965b..ff38017d6f 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -120,33 +120,58 @@ void append_path(const LLUUID& id, std::string& path) path.append(temp); } -void update_marketplace_category(const LLUUID& cat_id) +void update_marketplace_folder_hierarchy(const LLUUID cat_id) { // When changing the marketplace status of a folder, the only thing that needs to happen is // for all observers of the folder to, possibly, change the display label of the folder - // as well as, potentially, change the display label of all parent folders up to the marketplace root. + // so that's the only thing we change on the update mask. + gInventory.addChangedMask(LLInventoryObserver::LABEL, cat_id); + gInventory.notifyObservers(); + + // Update all descendent folders down + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat_id,cat_array,item_array); + + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + { + LLInventoryCategory* category = *iter; + update_marketplace_folder_hierarchy(category->getUUID()); + } + return; +} + +void update_marketplace_category(const LLUUID& cat_id) +{ + // When changing the marketplace status of a folder, we usually have to change the status of all + // folders in the same listing. This is because the display of each folder is affected by the + // overall status of the whole listing. + // Consequently, the only way to correctly update a folder anywhere in the marketplace is to + // update the whole listing from its listing root. + // This is not as bad as it seems as we only update folders, not items, and the folder nesting depth + // is limited to 4. + // We also take care of degenerated cases so we don't update all folders in the inventory by mistake. const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); - // No marketplace, likely called in error then... - // Or not a descendent of the marketplace listings root, then just do the regular category update + // No marketplace -> likely called too early... or + // Not a descendent of the marketplace listings root -> likely called in error then... if (marketplace_listings_uuid.isNull() || !gInventory.isObjectDescendentOf(cat_id, marketplace_listings_uuid)) { + // In those cases, just do the regular category update LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); gInventory.updateCategory(cat); gInventory.notifyObservers(); return; } - // Explore all the hierarchy of folders up to the root to get them to update - // Note: this is not supposed to be deeper than 4 - LLUUID cur_id = cat_id; - LLInventoryCategory* cur_cat = gInventory.getCategory(cur_id); - while (cur_id != marketplace_listings_uuid) - { - gInventory.addChangedMask(LLInventoryObserver::LABEL, cur_id); - gInventory.notifyObservers(); - cur_id = cur_cat->getParentUUID(); - cur_cat = gInventory.getCategory(cur_id); - } + + // Grab marketplace listing data for this folder + S32 depth = depth_nesting_in_marketplace(cat_id); + LLUUID listing_uuid = nested_parent_id(cat_id, depth); + + // Update all descendents starting from the listing root + update_marketplace_folder_hierarchy(listing_uuid); + return; } diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 29ce5361f0..b7c84dc714 100755 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -687,7 +687,6 @@ bool LLMarketplaceData::setActivation(const LLUUID& folder_id, bool activate) marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id); (it->second).mIsActive = activate; update_marketplace_category((it->second).mListingFolderId); - update_marketplace_category((it->second).mVersionFolderId); return true; } // We need to iterate through the list to check it's not a version folder @@ -698,7 +697,6 @@ bool LLMarketplaceData::setActivation(const LLUUID& folder_id, bool activate) { (it->second).mIsActive = activate; update_marketplace_category((it->second).mListingFolderId); - update_marketplace_category((it->second).mVersionFolderId); return true; } it++; @@ -706,20 +704,4 @@ bool LLMarketplaceData::setActivation(const LLUUID& folder_id, bool activate) return false; } -// Test methods -void LLMarketplaceData::addTestItem(const LLUUID& folder_id) -{ - llinfos << "Merov : addTestItem, id = " << folder_id << llendl; - mMarketplaceItems[folder_id] = LLMarketplaceTuple(folder_id); - update_marketplace_category(folder_id); -} -void LLMarketplaceData::addTestItem(const LLUUID& folder_id, const LLUUID& version_id) -{ - llinfos << "Merov : addTestItem, id = " << folder_id << ", version = " << version_id << llendl; - mMarketplaceItems[folder_id] = LLMarketplaceTuple(folder_id); - setVersionFolderID(folder_id, version_id); - update_marketplace_category(folder_id); - update_marketplace_category(version_id); -} - diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index d76072da1f..0b1066a558 100755 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -165,11 +165,6 @@ public: bool setVersionFolderID(const LLUUID& folder_id, const LLUUID& version_id); bool setActivation(const LLUUID& folder_id, bool activate); - // Merov : DD Development : methods to populate the items list with something usefull using - // inventory IDs and some pseudo random code so we can play with the UI... - void addTestItem(const LLUUID& folder_id); - void addTestItem(const LLUUID& folder_id, const LLUUID& version_id); - private: marketplace_items_list_t mMarketplaceItems; }; diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index cde14e72f0..0be5509333 100755 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -5,12 +5,12 @@ name="Popup" visible="false"> + name="Marketplace Associate Listing"> + parameter="marketplace_associate_listing" /> + + + -- cgit v1.3 From 253781f87c1653ee203ba3e7bf340747b894140d Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 10 Apr 2014 18:55:07 -0700 Subject: DD-16 : Implement sort by stock count in merketplace --- indra/newview/llfloatermarketplacelistings.cpp | 2 +- indra/newview/llfolderviewmodelinventory.cpp | 32 +++++++++++++++++++++++++- indra/newview/llfolderviewmodelinventory.h | 2 ++ indra/newview/llinventoryfunctions.cpp | 5 ++++ 4 files changed, 39 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index 10c6045f87..9bbe63de72 100755 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -95,7 +95,7 @@ void LLPanelMarketplaceListings::onViewSortMenuItemClicked(const LLSD& userdata) if (chosen_item == "sort_by_stock_amount") { mSortOrder = (mSortOrder == LLInventoryFilter::SO_FOLDERS_BY_NAME ? LLInventoryFilter::SO_FOLDERS_BY_WEIGHT : LLInventoryFilter::SO_FOLDERS_BY_NAME); - mAllPanel->getFolderViewModel()->setSorter(mSortOrder); + mAllPanel->setSortOrder(mSortOrder); } // View/filter options else if (chosen_item == "show_all") diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp index aac3a41b9e..c31b40b179 100755 --- a/indra/newview/llfolderviewmodelinventory.cpp +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llfolderviewmodelinventory.h" #include "llinventorymodelbackgroundfetch.h" +#include "llinventoryfunctions.h" #include "llinventorypanel.h" #include "lltooldraganddrop.h" #include "llfavoritesbar.h" @@ -269,7 +270,7 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, // We sort by name if we aren't sorting by date // OR if these are folders and we are sorting folders by name. - bool by_name = (!mByDate || (mFoldersByName && (a->getSortGroup() != SG_ITEM))); + bool by_name = ((!mByDate || (mFoldersByName && (a->getSortGroup() != SG_ITEM))) && !mFoldersByWeight); if (a->getSortGroup() != b->getSortGroup()) { @@ -301,6 +302,35 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, return (compare < 0); } } + else if (mFoldersByWeight) + { + S32 weight_a = compute_stock_count(a->getUUID()); + S32 weight_b = compute_stock_count(b->getUUID()); + if ((weight_a != -1) || (weight_b != -1)) + { + llinfos << "Merov : sort by weight, a = " << a->getName() << ", " << weight_a << ", b = " << b->getName() << ", " << weight_b << llendl; + } + if (weight_a == weight_b) + { + // Equal weight -> use alphabetical order + return (LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()) < 0); + } + else if (weight_a == -1) + { + // No weight -> move a at the end of the list + return false; + } + else if (weight_b == -1) + { + // No weight -> move b at the end of the list + return true; + } + else + { + // Lighter is first (sorted in increasing order of weight) + return (weight_a < weight_b); + } + } else { time_t first_create = a->getCreationDate(); diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h index 9dcfdfa185..b6d2c8502b 100755 --- a/indra/newview/llfolderviewmodelinventory.h +++ b/indra/newview/llfolderviewmodelinventory.h @@ -89,6 +89,7 @@ public: mByDate = (mSortOrder & LLInventoryFilter::SO_DATE); mSystemToTop = (mSortOrder & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); mFoldersByName = (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_NAME); + mFoldersByWeight = (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_WEIGHT); } bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const; @@ -97,6 +98,7 @@ private: bool mByDate; bool mSystemToTop; bool mFoldersByName; + bool mFoldersByWeight; }; class LLFolderViewModelInventory diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ff38017d6f..57e1b6d9bc 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -796,6 +796,11 @@ S32 compute_stock_count(LLUUID cat_uuid) { // Handle the case of the folder being a stock folder immediately LLViewerInventoryCategory* cat = gInventory.getCategory(cat_uuid); + if (!cat) + { + // Not a category so no stock count to speak of + return -1; + } if (cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) { // Note: stock folders are *not* supposed to have nested subfolders so we stop recursion here -- cgit v1.3 From 45ec0833c2f11b7c59b6e250fd63f55fb2317cb5 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 11 Apr 2014 14:13:33 -0700 Subject: DD-57 : Update stock folder count when item moved back to inventory --- indra/newview/llinventorybridge.cpp | 17 +++++++++++++++-- indra/newview/llinventoryfunctions.cpp | 1 - 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 3af734ba27..d38f6cffca 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2401,11 +2401,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + const LLUUID from_folder_uuid = inv_cat->getParentUUID(); const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); const BOOL move_is_from_outbox = model->isObjectDescendentOf(cat_id, outbox_id); const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id); + const BOOL move_is_from_marketplacelistings = model->isObjectDescendentOf(cat_id, marketplacelistings_id); // check to make sure source is agent inventory, and is represented there. LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); @@ -2712,6 +2714,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, mUUID, move_is_into_trash); } + if (move_is_from_marketplacelistings) + { + update_marketplace_category(from_folder_uuid); + } } } else if (LLToolDragAndDrop::SOURCE_WORLD == source) @@ -4234,6 +4240,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + const LLUUID from_folder_uuid = inv_item->getParentUUID(); const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_favorites = (mUUID == favorites_id); @@ -4242,6 +4249,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_item->getUUID(), outbox_id); const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id); + const BOOL move_is_from_marketplacelistings = model->isObjectDescendentOf(inv_item->getUUID(), marketplacelistings_id); LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); BOOL accept = FALSE; @@ -4384,7 +4392,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, LLFolderViewItem* itemp = destination_panel->getRootFolder()->getDraggingOverItem(); if (itemp) { - LLUUID srcItemId = inv_item->getUUID(); + LLUUID srcItemId = inv_item->getUUID(); LLUUID destItemId = static_cast(itemp->getViewModelItem())->getUUID(); LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(srcItemId, destItemId); } @@ -4437,8 +4445,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, mUUID, move_is_into_trash); } + + if (move_is_from_marketplacelistings) + { + update_marketplace_category(from_folder_uuid); + } - // + // //-------------------------------------------------------------------------------- } } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 57e1b6d9bc..757dcb4992 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -805,7 +805,6 @@ S32 compute_stock_count(LLUUID cat_uuid) { // Note: stock folders are *not* supposed to have nested subfolders so we stop recursion here // Note: we *always* give a stock count for stock folders, it's useful even if the listing is unassociated - //LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); return cat->getDescendentCount(); } -- cgit v1.3 From 1b4408e59d6798e2916ce9bcbedbd729fde0d959 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 11 Apr 2014 14:58:12 -0700 Subject: DD-59 : WIP : Added marketplace consitency check and cleaning when updating a marketplace folder --- indra/newview/llinventoryfunctions.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 757dcb4992..0aba4f57a0 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -155,8 +155,8 @@ void update_marketplace_category(const LLUUID& cat_id) const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); // No marketplace -> likely called too early... or - // Not a descendent of the marketplace listings root -> likely called in error then... - if (marketplace_listings_uuid.isNull() || !gInventory.isObjectDescendentOf(cat_id, marketplace_listings_uuid)) + // Not a descendent of the marketplace listings root and not part of marketplace -> likely called in error then... + if (marketplace_listings_uuid.isNull() || (!gInventory.isObjectDescendentOf(cat_id, marketplace_listings_uuid) && !LLMarketplaceData::instance().isListed(cat_id) && !LLMarketplaceData::instance().isVersionFolder(cat_id))) { // In those cases, just do the regular category update LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); @@ -169,6 +169,24 @@ void update_marketplace_category(const LLUUID& cat_id) S32 depth = depth_nesting_in_marketplace(cat_id); LLUUID listing_uuid = nested_parent_id(cat_id, depth); + // Verify marketplace data consistency for this listing + if (LLMarketplaceData::instance().isListed(listing_uuid)) + { + LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolderID(listing_uuid); + if (!gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid)) + { + // *TODO : Confirm with Producer that this is what we want to happen in that case! + llinfos << "Merov : Delisting as the version folder is not under the listing folder anymore!!" << llendl; + LLMarketplaceData::instance().deleteListing(listing_uuid); + } + if (!gInventory.isObjectDescendentOf(listing_uuid, marketplace_listings_uuid)) + { + // *TODO : Confirm with Producer that this is what we want to happen in that case! + llinfos << "Merov : Delisting as the listing folder is not under the marketplace folder anymore!!" << llendl; + LLMarketplaceData::instance().deleteListing(listing_uuid); + } + } + // Update all descendents starting from the listing root update_marketplace_folder_hierarchy(listing_uuid); -- cgit v1.3 From dd070683e8aedac36919144ca13a7c9a405d653a Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 11 Apr 2014 20:25:15 -0700 Subject: DD-59 : WIP : Fixed consistency check bug --- indra/newview/llinventoryfunctions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 0aba4f57a0..ae9480326c 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -173,7 +173,7 @@ void update_marketplace_category(const LLUUID& cat_id) if (LLMarketplaceData::instance().isListed(listing_uuid)) { LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolderID(listing_uuid); - if (!gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid)) + if (version_folder_uuid.notNull() && !gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid)) { // *TODO : Confirm with Producer that this is what we want to happen in that case! llinfos << "Merov : Delisting as the version folder is not under the listing folder anymore!!" << llendl; -- cgit v1.3 From ae94a0d06962bc9615bcae2e75dd6cd23fa1067e Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 13 Apr 2014 18:00:24 -0700 Subject: DD-59 : Modify the validation function to create stock folders for each types and create them at the right nesting depth --- indra/newview/llinventoryfunctions.cpp | 104 +++++++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 25 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ae9480326c..a0aa06ddf2 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1032,8 +1032,8 @@ bool has_correct_permissions_for_sale(LLInventoryCategory* cat) } // Make all relevant business logic checks on the marketplace listings starting with the folder as argument -// This function does no deletion or move but a mere audit and raises issues to the user -// The only thing that's done is to modify the type of folders containing no-copy items to stock folders +// This function does no deletion of listings but a mere audit and raises issues to the user +// The only thing that's done is to move and sort folders containing no-copy items to stock folders // *TODO : Signal the errors to the user somewhat (UI still TBD) // *TODO : Add the rest of the SLM/AIS business logic (limit of nesting depth, stock folder consistency, overall limit on listings, etc...) void validate_marketplacelistings(LLInventoryCategory* cat) @@ -1044,48 +1044,102 @@ void validate_marketplacelistings(LLInventoryCategory* cat) LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); const LLFolderType::EType folder_type = cat->getPreferredType(); - LLUUID stock_folder_uuid; - LLViewerInventoryCategory* stock_folder_cat = NULL; + S32 depth = depth_nesting_in_marketplace(cat->getUUID()); - LLInventoryModel::item_array_t item_array_copy = *item_array; + // Stock items : sorting and moving the various stock items is complicated as the set of constraints is high + // For each folder, we need to: + // * separate non stock items, stock items per types in different folders + // * have stock items nested at depth 2 at least + // * never ever move the non-stock items + std::vector > items_vector; + items_vector.resize(LLInventoryType::IT_COUNT+1); + + // Parse the items and create vectors of items to sort copyable items and stock items of various types + LLInventoryModel::item_array_t item_array_copy = *item_array; for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) { LLInventoryItem* item = *iter; LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) item; LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory(); LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); + // Skip items that shouldn't be there to start with, raise an error message for those if (linked_category || linked_item) { - llinfos << "Merov : Validation error: there are linked items in this listing!" << llendl; + llinfos << "Merov : Validation error: skipping linked item : " << viewer_inv_item->getName() << llendl; + continue; } if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID())) { - llinfos << "Merov : Validation error: there are items with incorrect permissions in this listing!" << llendl; + llinfos << "Merov : Validation error: skipping item with incorrect permissions : " << viewer_inv_item->getName() << llendl; + continue; } - if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && (folder_type != LLFolderType::FT_MARKETPLACE_STOCK)) + // Update the appropriate vector item for that type + LLInventoryType::EType type = LLInventoryType::IT_COUNT; // Default value for non stock items + if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) { - llinfos << "Merov : Validation warning : no copy item found in non stock folder -> reparent to relevant stock folder!" << llendl; - if (stock_folder_uuid.isNull()) - { - llinfos << "Merov : Validation warning : no appropriate existing stock folder -> create a new stock folder!" << llendl; - stock_folder_uuid = gInventory.createNewCategory(viewer_cat->getParentUUID(), LLFolderType::FT_MARKETPLACE_STOCK, viewer_cat->getName()); - stock_folder_cat = gInventory.getCategory(stock_folder_uuid); - } - gInventory.changeItemParent(viewer_inv_item, stock_folder_uuid, false); - update_marketplace_category(viewer_cat->getUUID()); - update_marketplace_category(stock_folder_uuid); + // Get the item type for stock items + type = viewer_inv_item->getInventoryType(); } + items_vector[type].push_back(viewer_inv_item); } - - if (stock_folder_uuid.notNull() && (viewer_cat->getDescendentCount() == 0)) + // How many types of folders? Which type is it if only one? + S32 count = 0; + LLInventoryType::EType type = LLInventoryType::IT_COUNT; + for (S32 i = 0; i <= LLInventoryType::IT_COUNT; i++) { - llinfos << "Merov : Validation warning : folder content completely moved to stock folder -> remove empty folder!" << llendl; - gInventory.removeCategory(cat->getUUID()); - gInventory.notifyObservers(); - return; + if (!items_vector[i].empty()) + { + count++; + type = (LLInventoryType::EType)(i); + } } - + // If we have one kind only, in the correct folder type at the right depth -> all OK + if ((count <= 1) && ((type == LLInventoryType::IT_COUNT) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth >= 2)))) + { + // Done with that folder! + llinfos << "Merov : Validation log: folder validates : " << viewer_cat->getName() << llendl; + } + else + { + // Create one folder per vector of the stock kind at the right depth + // Note: we *intentionally* skip the non stock items at the end, those should not be moved around + for (S32 i = 0; i < LLInventoryType::IT_COUNT; i++) + { + if (!items_vector[i].empty()) + { + // Create a new folder + llinfos << "Merov : Validation log: creating stock folder : " << viewer_cat->getName() << ", type = " << i << llendl; + LLUUID parent_uuid = (depth >=2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); + LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_MARKETPLACE_STOCK, viewer_cat->getName()); + // Move each item to the new folder + while (!items_vector[i].empty()) + { + LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); + llinfos << "Merov : Validation log: moving item : " << viewer_inv_item->getName() << llendl; + gInventory.changeItemParent(viewer_inv_item, folder_uuid, false); + items_vector[i].pop_back(); + } + update_marketplace_category(folder_uuid); + } + } + // Clean up + if (viewer_cat->getDescendentCount() == 0) + { + // Remove the current folder if it ends up empty + llinfos << "Merov : Validation warning : folder content completely moved to stock folder -> remove empty folder!" << llendl; + gInventory.removeCategory(cat->getUUID()); + gInventory.notifyObservers(); + return; + } + else + { + // Update the current folder + update_marketplace_category(cat->getUUID()); + } + } + + // Recursion : Perform the same validation on each nested folder LLInventoryModel::cat_array_t cat_array_copy = *cat_array; for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) -- cgit v1.3 From eb8c0bf086f66ce1ee7d373ceaaba64a113bf1fd Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 13 Apr 2014 22:24:58 -0700 Subject: DD-59 : Takes care of the case of a stock folder at the level of a listing folder --- indra/newview/llinventoryfunctions.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index a0aa06ddf2..c7cd38b20e 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1038,14 +1038,25 @@ bool has_correct_permissions_for_sale(LLInventoryCategory* cat) // *TODO : Add the rest of the SLM/AIS business logic (limit of nesting depth, stock folder consistency, overall limit on listings, etc...) void validate_marketplacelistings(LLInventoryCategory* cat) { + // Special case a stock folder depth issue + LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); + const LLFolderType::EType folder_type = cat->getPreferredType(); + S32 depth = depth_nesting_in_marketplace(cat->getUUID()); + if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth == 1)) + { + // Nest the stock folder one level deeper in a normal folder and restart from there + LLUUID parent_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName()); + LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); + gInventory.changeCategoryParent(viewer_cat, folder_uuid, false); + validate_marketplacelistings(new_cat); + return; + } + LLInventoryModel::cat_array_t* cat_array; LLInventoryModel::item_array_t* item_array; gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); - LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); - const LLFolderType::EType folder_type = cat->getPreferredType(); - S32 depth = depth_nesting_in_marketplace(cat->getUUID()); - // Stock items : sorting and moving the various stock items is complicated as the set of constraints is high // For each folder, we need to: // * separate non stock items, stock items per types in different folders -- cgit v1.3 From 545b408618388c0484b16d7dff22b9aeb6421530 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 14 Apr 2014 22:58:14 -0700 Subject: DD-20 : Prevent pasting incompatible items in stock folders --- indra/newview/llinventorybridge.cpp | 18 +----------------- indra/newview/llinventoryfunctions.cpp | 15 ++++++++++++++- indra/newview/llviewerinventory.cpp | 23 +++++++++++++++++++++++ indra/newview/llviewerinventory.h | 3 +++ 4 files changed, 41 insertions(+), 18 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index e740a16d49..520a840f74 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4350,23 +4350,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } else if (move_is_into_marketplacelistings) { - // If destination folder type is stock, check perm and type of item, if not compatible -> FALSE - if (getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) - { - // If the item is copyable (i.e. non stock) do not accept the drop in a stock folder - if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) - { - accept = FALSE; - } - else - { - LLInventoryModel::cat_array_t* cat_array; - LLInventoryModel::item_array_t* item_array; - gInventory.getDirectDescendentsOf(mUUID,cat_array,item_array); - // Destination stock folder must be empty OR types must be identical - accept = (!item_array->count() || (item_array->get(0)->getInventoryType() == inv_item->getInventoryType())); - } - } + accept = (getCategory() && getCategory()->acceptItem(inv_item)); } LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index c7cd38b20e..7a16cf5e74 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -913,6 +913,13 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol } LLViewerInventoryCategory* dest_cat = gInventory.getCategory(dest_folder); + // Verify we can have this item in that destination category + if (!dest_cat->acceptItem(viewer_inv_item)) + { + llinfos << "Merov : Marketplace error : Cannot move item in that stock folder -> move aborted!" << llendl; + return; + } + // When moving a no copy item into a first level listing folder, we create a stock folder for it if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && (dest_cat->getParentUUID() == marketplace_listings_uuid)) { @@ -961,9 +968,15 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU if (has_correct_permissions_for_sale(inv_cat)) { // Get the destination folder - // *TODO : check that this folder is not full of no-copy items under its root... LLViewerInventoryCategory* dest_cat = gInventory.getCategory(dest_folder); + // Check it's not a stock folder + if (dest_cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + llinfos << "Merov : Marketplace error : Cannot move folder in stock folder -> move aborted!" << llendl; + return; + } + // Get the parent folder of the moved item : we may have to update it LLUUID src_folder = inv_cat->getParentUUID(); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index fff9821e86..4ca569e78c 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -816,6 +816,29 @@ bool LLViewerInventoryCategory::exportFileLocal(LLFILE* fp) const return true; } +bool LLViewerInventoryCategory::acceptItem(LLInventoryItem* inv_item) +{ + bool accept = true; + // Only stock folders have limitation on which item they will accept + if (getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + // If the item is copyable (i.e. non stock) do not accept the drop in a stock folder + if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + accept = false; + } + else + { + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(getUUID(),cat_array,item_array); + // Destination stock folder must be empty OR types of incoming and existing items must be identical + accept = (!item_array->count() || (item_array->get(0)->getInventoryType() == inv_item->getInventoryType())); + } + } + return accept; +} + void LLViewerInventoryCategory::determineFolderType() { /* Do NOT uncomment this code. This is for future 2.1 support of ensembles. diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index ab19a12014..6b33ef0672 100755 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -225,6 +225,9 @@ public: bool importFileLocal(LLFILE* fp); void determineFolderType(); void changeType(LLFolderType::EType new_folder_type); + + // returns true if the category object will accept the incoming item + bool acceptItem(LLInventoryItem* inv_item); private: friend class LLInventoryModel; -- cgit v1.3 From 851912b9f8a5fc9f604adf8c43941b7fe27aae09 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 15 Apr 2014 12:12:10 -0700 Subject: DD-65, DD-55: Treat activation/deactivation separately for listing and version folders. Also use max instead of stock for suffix for non stock folders. --- indra/newview/llinventorybridge.cpp | 35 +++++++++++++++++++------- indra/newview/llinventoryfunctions.cpp | 4 +-- indra/newview/skins/default/xui/en/strings.xml | 4 ++- 3 files changed, 31 insertions(+), 12 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 520a840f74..374d09ce98 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -887,7 +887,7 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags, { items.push_back(std::string("Marketplace Activate")); items.push_back(std::string("Marketplace Deactivate")); - if (LLMarketplaceData::instance().getActivationState(mUUID)) + if (LLMarketplaceData::instance().isVersionFolder(mUUID)) { disabled_items.push_back(std::string("Marketplace Activate")); } @@ -2039,17 +2039,15 @@ std::string LLFolderBridge::getLabelSuffix() const suffix = " (" + suffix + ")"; if (LLMarketplaceData::instance().getActivationState(getUUID())) { - suffix += " (" + LLTrans::getString("MarketplaceActive") + ")"; + suffix += " (" + LLTrans::getString("MarketplaceLive") + ")"; } } // Version folder case else if (LLMarketplaceData::instance().isVersionFolder(getUUID())) { - if (LLMarketplaceData::instance().getActivationState(getUUID())) - { - suffix += " (" + LLTrans::getString("MarketplaceActive") + ")"; - } + suffix += " (" + LLTrans::getString("MarketplaceActive") + ")"; } + // Add stock amount S32 stock_count = compute_stock_count(getUUID()); if (stock_count == 0) { @@ -2057,7 +2055,14 @@ std::string LLFolderBridge::getLabelSuffix() const } else if (stock_count != -1) { - suffix += " (" + LLTrans::getString("MarketplaceStock") + "=" + llformat("%d", stock_count) + ")"; + if (getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + suffix += " (" + LLTrans::getString("MarketplaceStock") + "=" + llformat("%d", stock_count) + ")"; + } + else + { + suffix += " (" + LLTrans::getString("MarketplaceMax") + "=" + llformat("%d", stock_count) + ")"; + } } return LLInvFVBridge::getLabelSuffix() + suffix; } @@ -3141,19 +3146,31 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) S32 depth = depth_nesting_in_marketplace(mUUID); if (depth == 2) { + // At the version folder level, "activate" means "set this as the version folder" LLInventoryCategory* category = gInventory.getCategory(mUUID); LLMarketplaceData::instance().setVersionFolderID(category->getParentUUID(), mUUID); - LLMarketplaceData::instance().setActivation(mUUID,true); } else if (depth == 1) { + // At the listing folder level, "activate" means "put it for sale on the marketplace" LLMarketplaceData::instance().setActivation(mUUID,true); } return; } else if ("marketplace_deactivate" == action) { - LLMarketplaceData::instance().setActivation(mUUID,false); + S32 depth = depth_nesting_in_marketplace(mUUID); + if (depth == 2) + { + // At the version folder level, "deactivate" means "zap the version folder" + LLInventoryCategory* category = gInventory.getCategory(mUUID); + LLMarketplaceData::instance().setVersionFolderID(category->getParentUUID(), LLUUID::null); + } + else if (depth == 1) + { + // At the listing folder level, "deactivate" means "take this out of the marketplace" + LLMarketplaceData::instance().setActivation(mUUID,false); + } return; } else if ("marketplace_associate_listing" == action) diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 7a16cf5e74..e6f863d46e 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -155,8 +155,8 @@ void update_marketplace_category(const LLUUID& cat_id) const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); // No marketplace -> likely called too early... or - // Not a descendent of the marketplace listings root and not part of marketplace -> likely called in error then... - if (marketplace_listings_uuid.isNull() || (!gInventory.isObjectDescendentOf(cat_id, marketplace_listings_uuid) && !LLMarketplaceData::instance().isListed(cat_id) && !LLMarketplaceData::instance().isVersionFolder(cat_id))) + // Not a descendent of the marketplace listings root -> likely called in error then... + if (marketplace_listings_uuid.isNull() || !gInventory.isObjectDescendentOf(cat_id, marketplace_listings_uuid)) { // In those cases, just do the regular category update LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 55272750e7..74c85bcd6b 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2272,7 +2272,9 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors. Error: There was a problem with this item. Try again later. no Mkt ID - live + live + active + max stock out of stock -- cgit v1.3 From 18da8170a7fc635281fae370e7fb43a361a5cc91 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 17 Apr 2014 16:49:28 -0700 Subject: DD-54 : WIP : Improved validation to wrap items and stock items within version folders if necessary. Also hooked up the audit button with the validation code though all printout happens in the log --- indra/newview/llfloatermarketplacelistings.cpp | 12 ++++++- indra/newview/llfloatermarketplacelistings.h | 1 + indra/newview/llinventoryfunctions.cpp | 38 +++++++++++++--------- .../default/xui/en/panel_marketplace_listings.xml | 1 - 4 files changed, 35 insertions(+), 17 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index 869b911310..7db78ff290 100755 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -34,6 +34,7 @@ #include "llinventorybridge.h" #include "llinventorymodelbackgroundfetch.h" #include "llinventoryobserver.h" +#include "llinventoryfunctions.h" #include "llmarketplacefunctions.h" #include "llnotificationhandler.h" #include "llnotificationmanager.h" @@ -60,6 +61,7 @@ BOOL LLPanelMarketplaceListings::postBuild() { mAllPanel = getChild("All Items"); childSetAction("add_btn", boost::bind(&LLPanelMarketplaceListings::onAddButtonClicked, this)); + childSetAction("audit_btn", boost::bind(&LLPanelMarketplaceListings::onAuditButtonClicked, this)); // Set the sort order newest to oldest LLInventoryPanel* panel = getChild("All Items"); @@ -99,7 +101,7 @@ void LLPanelMarketplaceListings::onSelectionChange(LLInventoryPanel *panel, cons void LLPanelMarketplaceListings::onAddButtonClicked() { - LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, true); + LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); llassert(marketplacelistings_id.notNull()); LLFolderType::EType preferred_type = LLFolderType::lookup("category"); LLUUID category = gInventory.createNewCategory(marketplacelistings_id, preferred_type, LLStringUtil::null); @@ -107,6 +109,14 @@ void LLPanelMarketplaceListings::onAddButtonClicked() mAllPanel->setSelectionByID(category, TRUE); } +void LLPanelMarketplaceListings::onAuditButtonClicked() +{ + LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, true); + llassert(marketplacelistings_id.notNull()); + LLViewerInventoryCategory* cat = gInventory.getCategory(marketplacelistings_id); + validate_marketplacelistings(cat); +} + void LLPanelMarketplaceListings::onViewSortMenuItemClicked(const LLSD& userdata) { std::string chosen_item = userdata.asString(); diff --git a/indra/newview/llfloatermarketplacelistings.h b/indra/newview/llfloatermarketplacelistings.h index c9fe68a70c..960b6c55e0 100755 --- a/indra/newview/llfloatermarketplacelistings.h +++ b/indra/newview/llfloatermarketplacelistings.h @@ -55,6 +55,7 @@ private: void onViewSortMenuItemClicked(const LLSD& userdata); bool onViewSortMenuItemCheck(const LLSD& userdata); void onAddButtonClicked(); + void onAuditButtonClicked(); void onSelectionChange(LLInventoryPanel *panel, const std::deque& items, BOOL user_action); LLInventoryPanel* mAllPanel; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index e6f863d46e..f4b66d82a4 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1051,15 +1051,18 @@ bool has_correct_permissions_for_sale(LLInventoryCategory* cat) // *TODO : Add the rest of the SLM/AIS business logic (limit of nesting depth, stock folder consistency, overall limit on listings, etc...) void validate_marketplacelistings(LLInventoryCategory* cat) { - // Special case a stock folder depth issue + llinfos << "Merov : Validation log: validating folder : " << cat->getName() << llendl; + // Special case a stock folder depth issue LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); const LLFolderType::EType folder_type = cat->getPreferredType(); S32 depth = depth_nesting_in_marketplace(cat->getUUID()); - if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth == 1)) + if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth <= 2)) { // Nest the stock folder one level deeper in a normal folder and restart from there - LLUUID parent_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + //LLUUID parent_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + LLUUID parent_uuid = cat->getParentUUID(); LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName()); + llinfos << "Merov : Validation warning: creating wrapping folder for stock folder : " << cat->getName() << llendl; LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); gInventory.changeCategoryParent(viewer_cat, folder_uuid, false); validate_marketplacelistings(new_cat); @@ -1090,12 +1093,12 @@ void validate_marketplacelistings(LLInventoryCategory* cat) // Skip items that shouldn't be there to start with, raise an error message for those if (linked_category || linked_item) { - llinfos << "Merov : Validation error: skipping linked item : " << viewer_inv_item->getName() << llendl; + llinfos << "Merov : Validation error: linked item are not allowed in listings : " << viewer_inv_item->getName() << llendl; continue; } if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID())) { - llinfos << "Merov : Validation error: skipping item with incorrect permissions : " << viewer_inv_item->getName() << llendl; + llinfos << "Merov : Validation error: item with incorrect permissions in listing : " << viewer_inv_item->getName() << llendl; continue; } // Update the appropriate vector item for that type @@ -1118,29 +1121,34 @@ void validate_marketplacelistings(LLInventoryCategory* cat) type = (LLInventoryType::EType)(i); } } + // If we have no items in there (only folders) -> all OK + if (count == 0) + { + llinfos << "Merov : Validation log: folder validates: doesn't contain any item" << llendl; + } // If we have one kind only, in the correct folder type at the right depth -> all OK - if ((count <= 1) && ((type == LLInventoryType::IT_COUNT) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth >= 2)))) + else if ((count == 1) && (((type == LLInventoryType::IT_COUNT) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)))) { // Done with that folder! - llinfos << "Merov : Validation log: folder validates : " << viewer_cat->getName() << llendl; + llinfos << "Merov : Validation log: folder validates: all items of type : " << type << llendl; } else { - // Create one folder per vector of the stock kind at the right depth - // Note: we *intentionally* skip the non stock items at the end, those should not be moved around - for (S32 i = 0; i < LLInventoryType::IT_COUNT; i++) + // Create one folder per vector at the right depth and of the right type + for (S32 i = 0; i <= LLInventoryType::IT_COUNT; i++) { if (!items_vector[i].empty()) { // Create a new folder - llinfos << "Merov : Validation log: creating stock folder : " << viewer_cat->getName() << ", type = " << i << llendl; - LLUUID parent_uuid = (depth >=2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); - LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_MARKETPLACE_STOCK, viewer_cat->getName()); + llinfos << "Merov : Validation warning: creating stock folder : " << viewer_cat->getName() << ", type = " << i << llendl; + LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); + LLFolderType::EType new_folder_type = (i == LLInventoryType::IT_COUNT ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); + LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, viewer_cat->getName()); // Move each item to the new folder while (!items_vector[i].empty()) { LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); - llinfos << "Merov : Validation log: moving item : " << viewer_inv_item->getName() << llendl; + llinfos << "Merov : Validation warning: moving item : " << viewer_inv_item->getName() << llendl; gInventory.changeItemParent(viewer_inv_item, folder_uuid, false); items_vector[i].pop_back(); } @@ -1151,7 +1159,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat) if (viewer_cat->getDescendentCount() == 0) { // Remove the current folder if it ends up empty - llinfos << "Merov : Validation warning : folder content completely moved to stock folder -> remove empty folder!" << llendl; + llinfos << "Merov : Validation warning : folder content completely moved to stock folder -> removing empty folder" << llendl; gInventory.removeCategory(cat->getUUID()); gInventory.notifyObservers(); return; diff --git a/indra/newview/skins/default/xui/en/panel_marketplace_listings.xml b/indra/newview/skins/default/xui/en/panel_marketplace_listings.xml index acbb428422..0ebb7a5f48 100755 --- a/indra/newview/skins/default/xui/en/panel_marketplace_listings.xml +++ b/indra/newview/skins/default/xui/en/panel_marketplace_listings.xml @@ -94,7 +94,6 @@ background_visible="true" border="false" bevel_style="none" - sort_order_setting="InventorySortOrder" show_item_link_overlays="true"> Date: Fri, 18 Apr 2014 15:47:59 -0700 Subject: DD-68 : Simply unlist if active version folder moved out of listing --- indra/newview/llinventoryfunctions.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index f4b66d82a4..c9d9781848 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -176,13 +176,14 @@ void update_marketplace_category(const LLUUID& cat_id) if (version_folder_uuid.notNull() && !gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid)) { // *TODO : Confirm with Producer that this is what we want to happen in that case! - llinfos << "Merov : Delisting as the version folder is not under the listing folder anymore!!" << llendl; - LLMarketplaceData::instance().deleteListing(listing_uuid); + llinfos << "Merov : Unlist as the version folder is not under the listing folder anymore!!" << llendl; + LLMarketplaceData::instance().setVersionFolderID(listing_uuid, LLUUID::null); + LLMarketplaceData::instance().setActivation(listing_uuid, false); } if (!gInventory.isObjectDescendentOf(listing_uuid, marketplace_listings_uuid)) { // *TODO : Confirm with Producer that this is what we want to happen in that case! - llinfos << "Merov : Delisting as the listing folder is not under the marketplace folder anymore!!" << llendl; + llinfos << "Merov : Disassociate as the listing folder is not under the marketplace folder anymore!!" << llendl; LLMarketplaceData::instance().deleteListing(listing_uuid); } } -- cgit v1.3 From e4863cf7f6f3799be2f85ba0ec808f2b5f509f95 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 20 Apr 2014 20:32:17 -0700 Subject: DD-19 : Implement preliminary audit / validation display --- indra/newview/llfloatermarketplacelistings.cpp | 36 +++++++---- indra/newview/llfloatermarketplacelistings.h | 6 +- indra/newview/llinventoryfunctions.cpp | 74 ++++++++++++++++++---- indra/newview/llinventoryfunctions.h | 4 +- .../xui/en/floater_marketplace_validation.xml | 10 +-- 5 files changed, 94 insertions(+), 36 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index 2f730d9d14..2cfbd97ef1 100755 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -111,10 +111,6 @@ void LLPanelMarketplaceListings::onAddButtonClicked() void LLPanelMarketplaceListings::onAuditButtonClicked() { - LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, true); - llassert(marketplacelistings_id.notNull()); - LLViewerInventoryCategory* cat = gInventory.getCategory(marketplacelistings_id); - validate_marketplacelistings(cat); LLSD data(LLSD::emptyMap()); LLFloaterReg::showInstance("marketplace_validation", data); } @@ -583,21 +579,26 @@ void LLFloaterAssociateListing::cancel() LLFloaterMarketplaceValidation::LLFloaterMarketplaceValidation(const LLSD& data) : LLModalDialog( data["message"].asString() ), -mMessage(data["message"].asString()), mEditor(NULL) { } BOOL LLFloaterMarketplaceValidation::postBuild() { - childSetAction("Continue", onContinue, this); + childSetAction("OK", onOK, this); - // this displays the message - mEditor = getChild("tos_text"); - mEditor->setEnabled( FALSE ); + // This widget displays the validation messages + mEditor = getChild("validation_text"); + mEditor->setEnabled(FALSE); mEditor->setFocus(TRUE); - mEditor->setValue(LLSD(mMessage)); - + mEditor->setValue(LLSD()); + + // Validates the marketplace + LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, true); + llassert(marketplacelistings_id.notNull()); + LLViewerInventoryCategory* cat = gInventory.getCategory(marketplacelistings_id); + validate_marketplacelistings(cat,boost::bind(&LLFloaterMarketplaceValidation::appendMessage, this, _1)); + return TRUE; } @@ -613,14 +614,21 @@ void LLFloaterMarketplaceValidation::draw() } // static -void LLFloaterMarketplaceValidation::onContinue( void* userdata ) +void LLFloaterMarketplaceValidation::onOK( void* userdata ) { - LLFloaterMarketplaceValidation* self = (LLFloaterMarketplaceValidation*) userdata; - // destroys this object + LLFloaterMarketplaceValidation* self = (LLFloaterMarketplaceValidation*) userdata; self->closeFloater(); } +void LLFloaterMarketplaceValidation::appendMessage(std::string& message) +{ + if (mEditor) + { + mEditor->appendText(message, true); + } +} + diff --git a/indra/newview/llfloatermarketplacelistings.h b/indra/newview/llfloatermarketplacelistings.h index 0906ce30a7..1d3378791d 100755 --- a/indra/newview/llfloatermarketplacelistings.h +++ b/indra/newview/llfloatermarketplacelistings.h @@ -164,10 +164,10 @@ public: virtual void draw(); - static void onContinue( void* userdata ); - + void appendMessage(std::string& message); + static void onOK( void* userdata ); + private: - std::string mMessage; LLTextEditor* mEditor; }; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index c9d9781848..237a1baac0 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1048,25 +1048,37 @@ bool has_correct_permissions_for_sale(LLInventoryCategory* cat) // Make all relevant business logic checks on the marketplace listings starting with the folder as argument // This function does no deletion of listings but a mere audit and raises issues to the user // The only thing that's done is to move and sort folders containing no-copy items to stock folders -// *TODO : Signal the errors to the user somewhat (UI still TBD) // *TODO : Add the rest of the SLM/AIS business logic (limit of nesting depth, stock folder consistency, overall limit on listings, etc...) -void validate_marketplacelistings(LLInventoryCategory* cat) +void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb) { - llinfos << "Merov : Validation log: validating folder : " << cat->getName() << llendl; // Special case a stock folder depth issue LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); const LLFolderType::EType folder_type = cat->getPreferredType(); S32 depth = depth_nesting_in_marketplace(cat->getUUID()); + if (depth == 1) + { + std::string message = "Validating listing : " + cat->getName(); + llinfos << "Merov : Validation log : " << message << llendl; + if (cb) + { + cb(message); + } + } if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth <= 2)) { // Nest the stock folder one level deeper in a normal folder and restart from there //LLUUID parent_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); LLUUID parent_uuid = cat->getParentUUID(); LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName()); - llinfos << "Merov : Validation warning: creating wrapping folder for stock folder : " << cat->getName() << llendl; + std::string message = " Warning : creating wrapping folder for stock folder : " + cat->getName(); + llinfos << "Merov : Validation warning : " << message << llendl; + if (cb) + { + cb(message); + } LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); gInventory.changeCategoryParent(viewer_cat, folder_uuid, false); - validate_marketplacelistings(new_cat); + validate_marketplacelistings(new_cat, cb); return; } @@ -1094,12 +1106,22 @@ void validate_marketplacelistings(LLInventoryCategory* cat) // Skip items that shouldn't be there to start with, raise an error message for those if (linked_category || linked_item) { - llinfos << "Merov : Validation error: linked item are not allowed in listings : " << viewer_inv_item->getName() << llendl; + std::string message = " Error : linked item are not allowed in listings : " + viewer_inv_item->getName(); + llinfos << "Merov : Validation error : " << message << llendl; + if (cb) + { + cb(message); + } continue; } if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID())) { - llinfos << "Merov : Validation error: item with incorrect permissions in listing : " << viewer_inv_item->getName() << llendl; + std::string message = " Error : item with incorrect permissions in listing : " + viewer_inv_item->getName(); + llinfos << "Merov : Validation error : " << message << llendl; + if (cb) + { + cb(message); + } continue; } // Update the appropriate vector item for that type @@ -1125,13 +1147,23 @@ void validate_marketplacelistings(LLInventoryCategory* cat) // If we have no items in there (only folders) -> all OK if (count == 0) { - llinfos << "Merov : Validation log: folder validates: doesn't contain any item" << llendl; + std::string message = " Log : folder validates: doesn't contain any item"; + llinfos << "Merov : Validation log : " << message << llendl; + if (cb) + { + cb(message); + } } // If we have one kind only, in the correct folder type at the right depth -> all OK else if ((count == 1) && (((type == LLInventoryType::IT_COUNT) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)))) { // Done with that folder! - llinfos << "Merov : Validation log: folder validates: all items of type : " << type << llendl; + std::string message = " Log : folder validates: all items of compatible types"; + llinfos << "Merov : Validation log : " << message << llendl; + if (cb) + { + cb(message); + } } else { @@ -1141,7 +1173,12 @@ void validate_marketplacelistings(LLInventoryCategory* cat) if (!items_vector[i].empty()) { // Create a new folder - llinfos << "Merov : Validation warning: creating stock folder : " << viewer_cat->getName() << ", type = " << i << llendl; + std::string message = " Warning : creating stock folder : " + viewer_cat->getName(); + llinfos << "Merov : Validation warning : " << message << llendl; + if (cb) + { + cb(message); + } LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); LLFolderType::EType new_folder_type = (i == LLInventoryType::IT_COUNT ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, viewer_cat->getName()); @@ -1149,7 +1186,12 @@ void validate_marketplacelistings(LLInventoryCategory* cat) while (!items_vector[i].empty()) { LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); - llinfos << "Merov : Validation warning: moving item : " << viewer_inv_item->getName() << llendl; + std::string message = " Warning : moving item : " + viewer_inv_item->getName(); + llinfos << "Merov : Validation warning : " << message << llendl; + if (cb) + { + cb(message); + } gInventory.changeItemParent(viewer_inv_item, folder_uuid, false); items_vector[i].pop_back(); } @@ -1160,7 +1202,13 @@ void validate_marketplacelistings(LLInventoryCategory* cat) if (viewer_cat->getDescendentCount() == 0) { // Remove the current folder if it ends up empty - llinfos << "Merov : Validation warning : folder content completely moved to stock folder -> removing empty folder" << llendl; + llinfos << "Merov : Validation warning : " << llendl; + std::string message = " Warning : folder content completely moved to stock folder -> removing empty folder"; + llinfos << "Merov : Validation warning : " << message << llendl; + if (cb) + { + cb(message); + } gInventory.removeCategory(cat->getUUID()); gInventory.notifyObservers(); return; @@ -1178,7 +1226,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat) for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) { LLInventoryCategory* category = *iter; - validate_marketplacelistings(category); + validate_marketplacelistings(category, cb); } } diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 66f1c99630..a31bc9dbdd 100755 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -72,10 +72,12 @@ void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LL void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id); void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id); +typedef boost::function validation_callback_t; + void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy = false); void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy = false); bool has_correct_permissions_for_sale(LLInventoryCategory* cat); -void validate_marketplacelistings(LLInventoryCategory* inv_cat); +void validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL); S32 depth_nesting_in_marketplace(LLUUID cur_uuid); LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth); S32 compute_stock_count(LLUUID cat_uuid); diff --git a/indra/newview/skins/default/xui/en/floater_marketplace_validation.xml b/indra/newview/skins/default/xui/en/floater_marketplace_validation.xml index eaaae60175..01d467a307 100755 --- a/indra/newview/skins/default/xui/en/floater_marketplace_validation.xml +++ b/indra/newview/skins/default/xui/en/floater_marketplace_validation.xml @@ -10,11 +10,11 @@ width="600">