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.2.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/newview/llinventoryfunctions.cpp | 149 +++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') 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 ///---------------------------------------------------------------------------- -- cgit v1.2.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.2.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/llinventoryfunctions.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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.2.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 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 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); } } -- cgit v1.2.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/llinventoryfunctions.cpp | 47 ++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 8 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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); -- cgit v1.2.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/llinventoryfunctions.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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 { -- cgit v1.2.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.2.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/llinventoryfunctions.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') 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 -- cgit v1.2.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/llinventoryfunctions.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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 -- cgit v1.2.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/llinventoryfunctions.cpp | 87 ++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 20 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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); } } -- cgit v1.2.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.2.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/llinventoryfunctions.cpp | 55 ++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 15 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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; } -- cgit v1.2.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/llinventoryfunctions.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') 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.2.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/llinventoryfunctions.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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.2.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.2.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.2.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.2.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.2.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/llinventoryfunctions.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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(); -- cgit v1.2.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/llinventoryfunctions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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); -- cgit v1.2.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/llinventoryfunctions.cpp | 38 ++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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; -- cgit v1.2.3 From 007a058c5fee29b70bc4ac1a4b9ff40deabdbd82 Mon Sep 17 00:00:00 2001 From: Merov Linden 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.2.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/llinventoryfunctions.cpp | 74 ++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 13 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') 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); } } -- cgit v1.2.3 From 40a51eb94dae1bc8ba287706b514b3e54b1dade8 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 21 Apr 2014 17:10:45 -0700 Subject: DD-72 : Fix display of stock number on listing with no associated version folder --- indra/newview/llinventoryfunctions.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 237a1baac0..10a5ac4bc7 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -845,6 +845,11 @@ S32 compute_stock_count(LLUUID cat_uuid) // 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 there's no version folder associated, the notion of stock count has no meaning + return -1; + } } else if (depth == 2) { -- cgit v1.2.3 From 4deb9f54c64d114bfd2aba76e51eaa01908b6610 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 29 Apr 2014 12:03:03 -0700 Subject: DD-76 : Do not allow Calling Cards in Marketplace Listings --- 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 10a5ac4bc7..e63aca67f8 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1129,6 +1129,16 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } continue; } + if (viewer_inv_item->getType() == LLAssetType::AT_CALLINGCARD) + { + std::string message = " Error : calling cards are not allowed in listings : " + viewer_inv_item->getName(); + llinfos << "Merov : Validation error : " << message << llendl; + if (cb) + { + cb(message); + } + continue; + } // 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())) -- cgit v1.2.3 From 7df858622bf379781246f23445f86ead4ad3288a Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 29 Apr 2014 20:37:37 -0700 Subject: DD-73 : Rewrote the move single item to marketplace code so to support the required folder structure better --- indra/newview/llinventoryfunctions.cpp | 58 ++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 21 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index e63aca67f8..62b626d0c8 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -885,9 +885,9 @@ S32 compute_stock_count(LLUUID cat_uuid) 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); - if (marketplace_listings_uuid.isNull()) + // Get the marketplace listings depth of the destination folder, exit with error if not under marketplace + S32 depth = depth_nesting_in_marketplace(dest_folder); + if (depth < 0) { llinfos << "Merov : Marketplace error : There is no marketplace listings folder -> move aborted!" << llendl; return; @@ -912,26 +912,36 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol // 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) + // When moving an isolated item, we might need to create the folder structure to support it + if (depth == 0) { - dest_folder = create_folder_for_item(inv_item, dest_folder); + // We need a listing folder + dest_folder = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, viewer_inv_item->getName()); + depth++; + } + if (depth == 1) + { + // We need a version folder + dest_folder = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, viewer_inv_item->getName()); + depth++; } LLViewerInventoryCategory* dest_cat = gInventory.getCategory(dest_folder); + if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && + (dest_cat->getPreferredType() != LLFolderType::FT_MARKETPLACE_STOCK)) + { + // We need a stock folder + dest_folder = gInventory.createNewCategory(dest_folder, LLFolderType::FT_MARKETPLACE_STOCK, viewer_inv_item->getName()); + dest_cat = gInventory.getCategory(dest_folder); + depth++; + } // 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; + llinfos << "Merov : Marketplace error : Cannot move item in that 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)) - { - 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(); @@ -950,12 +960,9 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol else { // Reparent the item - gInventory.changeItemParent(viewer_inv_item, dest_folder, false); + gInventory.changeItemParent(viewer_inv_item, dest_folder, true); } - // 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); @@ -1188,14 +1195,23 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (!items_vector[i].empty()) { // Create a new folder - std::string message = " Warning : creating stock folder : " + viewer_cat->getName(); + 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); + std::string message = ""; + if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) + { + message = " Warning : creating stock folder : "; + } + else + { + message = " Warning : creating intermediate folder : "; + } + message += 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()); // Move each item to the new folder while (!items_vector[i].empty()) @@ -1207,7 +1223,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { cb(message); } - gInventory.changeItemParent(viewer_inv_item, folder_uuid, false); + gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); items_vector[i].pop_back(); } update_marketplace_category(folder_uuid); -- cgit v1.2.3 From 87192990592f9abda8314393bdcac3627c15d5ac Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 1 May 2014 17:36:17 -0700 Subject: DD-81 : Fixed the stock folder count update using an inventory observer. This observe other changes as well of interest to marketplace and should improve consistency in general --- indra/newview/llinventoryfunctions.cpp | 97 +++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 31 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 62b626d0c8..413c0d4b4b 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -126,7 +126,6 @@ void update_marketplace_folder_hierarchy(const LLUUID cat_id) // for all observers of the folder to, possibly, change the display label of the folder // 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; @@ -142,55 +141,87 @@ void update_marketplace_folder_hierarchy(const LLUUID cat_id) return; } -void update_marketplace_category(const LLUUID& cat_id) +void update_marketplace_category(const LLUUID& cur_uuid) { - // When changing the marketplace status of a folder, we usually have to change the status of all + // When changing the marketplace status of an item, 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 + // Consequently, the only way to correctly update an item 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 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)) + // Grab marketplace listing data for this item + S32 depth = depth_nesting_in_marketplace(cur_uuid); + if (depth > 0) { - // In those cases, just do the regular category update - LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); - gInventory.updateCategory(cat); - gInventory.notifyObservers(); - return; - } + // Retrieve the listing uuid this object is in + LLUUID listing_uuid = nested_parent_id(cur_uuid, depth); - // Grab marketplace listing data for this folder - 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 (version_folder_uuid.notNull() && !gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid)) + // Verify marketplace data consistency for this listing + if (LLMarketplaceData::instance().isListed(listing_uuid)) { - // *TODO : Confirm with Producer that this is what we want to happen in that case! - 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); + LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolderID(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 : 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)) + + // Update all descendents starting from the listing root + update_marketplace_folder_hierarchy(listing_uuid); + } + else if (depth < 0) + { + if (LLMarketplaceData::instance().isListed(cur_uuid)) { // *TODO : Confirm with Producer that this is what we want to happen in that case! llinfos << "Merov : Disassociate as the listing folder is not under the marketplace folder anymore!!" << llendl; - LLMarketplaceData::instance().deleteListing(listing_uuid); + LLMarketplaceData::instance().deleteListing(cur_uuid); } } + + return; +} + +// Iterate through the marketplace and flag for label change all categories that countain a stock folder (i.e. stock folders and embedding folders up the hierarchy) +void update_all_marketplace_count(const LLUUID& cat_id) +{ + // Get all descendent folders down + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat_id,cat_array,item_array); - // Update all descendents starting from the listing root - update_marketplace_folder_hierarchy(listing_uuid); + 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 (category->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + // Listing containing stock folders needs to be updated but not others + // Note: we take advantage of the fact that stock folder *do not* contain sub folders to avoid a recursive call here + update_marketplace_category(category->getUUID()); + } + else + { + // Explore the contained folders recursively + update_all_marketplace_count(category->getUUID()); + } + } +} +void update_all_marketplace_count() +{ + // Get the marketplace root and launch the recursive exploration + const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + if (!marketplace_listings_uuid.isNull()) + { + update_all_marketplace_count(marketplace_listings_uuid); + } return; } @@ -966,6 +997,7 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol // Update the modified folders update_marketplace_category(src_folder); update_marketplace_category(dest_folder); + gInventory.notifyObservers(); } else { @@ -1011,6 +1043,7 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU // Update the modified folders update_marketplace_category(src_folder); update_marketplace_category(dest_folder); + gInventory.notifyObservers(); } } @@ -1227,6 +1260,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ items_vector[i].pop_back(); } update_marketplace_category(folder_uuid); + gInventory.notifyObservers(); } } // Clean up @@ -1248,6 +1282,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { // Update the current folder update_marketplace_category(cat->getUUID()); + gInventory.notifyObservers(); } } -- cgit v1.2.3 From 4d14e1ca9600d7ca7023edbd3827fbff994c8110 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 8 May 2014 15:56:38 -0700 Subject: DD-22 : WIP : Cleanep up the class definition, seting methods private and better isolate calls leading to HTTP requests --- indra/newview/llinventoryfunctions.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 413c0d4b4b..f92831ccc5 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -167,8 +167,8 @@ void update_marketplace_category(const LLUUID& cur_uuid) { // *TODO : Confirm with Producer that this is what we want to happen in that case! 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); + LLMarketplaceData::instance().setVersionFolder(listing_uuid, LLUUID::null); + LLMarketplaceData::instance().activateListing(listing_uuid, false); } } @@ -181,7 +181,7 @@ void update_marketplace_category(const LLUUID& cur_uuid) { // *TODO : Confirm with Producer that this is what we want to happen in that case! llinfos << "Merov : Disassociate as the listing folder is not under the marketplace folder anymore!!" << llendl; - LLMarketplaceData::instance().deleteListing(cur_uuid); + LLMarketplaceData::instance().clearListing(cur_uuid); } } -- cgit v1.2.3 From b4ddacaa5a3a6a46c38e13a52254c16956e9ed5a Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 8 May 2014 21:26:07 -0700 Subject: DD-22 : WIP : More clean up of marketplace classes, rationalize methods naming --- indra/newview/llinventoryfunctions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index f92831ccc5..283736f607 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -162,7 +162,7 @@ void update_marketplace_category(const LLUUID& cur_uuid) // Verify marketplace data consistency for this listing if (LLMarketplaceData::instance().isListed(listing_uuid)) { - LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolderID(listing_uuid); + LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolder(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! @@ -867,7 +867,7 @@ S32 compute_stock_count(LLUUID cat_uuid) return -1; } - LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolderID(listing_uuid); + LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolder(listing_uuid); // Handle the case of the first 2 levels : listing and version folders if (depth == 1) { -- cgit v1.2.3 From 989250ab0a91087a5709b3e377660059096c9e6f Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 14 May 2014 10:40:22 -0700 Subject: DD-95 : Prevent validation to run on folders that are not under the marketplace root --- indra/newview/llinventoryfunctions.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 283736f607..a31edfe183 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1100,6 +1100,12 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); const LLFolderType::EType folder_type = cat->getPreferredType(); S32 depth = depth_nesting_in_marketplace(cat->getUUID()); + if (depth < 0) + { + // If the folder is not under the marketplace listings root, validation should not be applied + // *TODO: Should we call update_marketplace_category(cat->getUUID()) ? + return; + } if (depth == 1) { std::string message = "Validating listing : " + cat->getName(); -- cgit v1.2.3 From 2a6ce118882b7ac4ce533dcd3c74f582e01bdb29 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 21 May 2014 16:40:23 -0700 Subject: DD-91, DD-84 : WIP : Verify restrictions when moving things to marketplace, provide clear alert for errors, parametrize alerts and tooltips correctly --- indra/newview/llinventoryfunctions.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index a31edfe183..8652c94407 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -914,14 +914,17 @@ S32 compute_stock_count(LLUUID cat_uuid) return curr_count; } -void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) +bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) { // Get the marketplace listings depth of the destination folder, exit with error if not under marketplace S32 depth = depth_nesting_in_marketplace(dest_folder); if (depth < 0) { llinfos << "Merov : Marketplace error : There is no marketplace listings folder -> move aborted!" << llendl; - return; + LLSD subs; + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Not Merchant"); + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return false; } // We will collapse links into items/folders @@ -931,7 +934,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, copy); + return move_folder_to_marketplacelistings(linked_category, dest_folder, copy); } else { @@ -970,7 +973,10 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol if (!dest_cat->acceptItem(viewer_inv_item)) { llinfos << "Merov : Marketplace error : Cannot move item in that folder -> move aborted!" << llendl; - return; + LLSD subs; + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Not Accepted"); + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return false; } // Get the parent folder of the moved item : we may have to update it @@ -1001,13 +1007,17 @@ void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol } else { - // *TODO : signal an error to the user (UI for this TBD) llinfos << "Merov : Marketplace error : User doesn't have the correct permission to put this item on sale -> move aborted!" << llendl; + LLSD subs; + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Unsellable Item"); + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return false; } } + return true; } -void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy) +bool 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)) @@ -1019,7 +1029,10 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU if (dest_cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) { llinfos << "Merov : Marketplace error : Cannot move folder in stock folder -> move aborted!" << llendl; - return; + LLSD subs; + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Not Accepted"); + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return false; } // Get the parent folder of the moved item : we may have to update it @@ -1045,6 +1058,7 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU update_marketplace_category(dest_folder); gInventory.notifyObservers(); } + return true; } // Returns true if all items within the argument folder are fit for sale, false otherwise -- cgit v1.2.3 From d06d4a36e702604368c70244114c58c5df730fb9 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 23 May 2014 17:19:03 -0700 Subject: DD-91 : WIP : Refactor code testing the validity of a drag, drop or paste of a folder or item in the marketplace --- indra/newview/llinventoryfunctions.cpp | 222 +++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 8652c94407..25592be99e 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -914,6 +914,228 @@ S32 compute_stock_count(LLUUID cat_uuid) return curr_count; } +bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg) +{ + // Collapse links directly to items/folders + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item; + LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); + if (linked_item != NULL) + { + inv_item = linked_item; + } + + bool allow_transfer = inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + if (!allow_transfer) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNoTransfer"); + return false; + } + + bool worn = get_is_item_worn(inv_item->getUUID()); + if (worn) + { + tooltip_msg = LLTrans::getString("TooltipOutboxWorn"); + return false; + } + + bool calling_card = (LLAssetType::AT_CALLINGCARD == inv_item->getType()); + if (calling_card) + { + tooltip_msg = LLTrans::getString("TooltipOutboxCallingCard"); + return false; + } + + return true; +} + +// local helper +// Returns the max tree length (in folder nodes) down from the argument folder +int get_folder_levels(LLInventoryCategory* inv_cat) +{ + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cats, items); + + int max_child_levels = 0; + + for (S32 i=0; i < cats->count(); ++i) + { + LLInventoryCategory* category = cats->get(i); + max_child_levels = llmax(max_child_levels, get_folder_levels(category)); + } + + return 1 + max_child_levels; +} + +// local helper +// Returns the distance (in folder nodes) between the ancestor and its descendant. Returns -1 if not related. +int get_folder_path_length(const LLUUID& ancestor_id, const LLUUID& descendant_id) +{ + int depth = 0; + + if (ancestor_id == descendant_id) return depth; + + const LLInventoryCategory* category = gInventory.getCategory(descendant_id); + + while (category) + { + LLUUID parent_id = category->getParentUUID(); + + if (parent_id.isNull()) break; + + depth++; + + if (parent_id == ancestor_id) return depth; + + category = gInventory.getCategory(parent_id); + } + + llwarns << "get_folder_path_length() couldn't trace a path from the descendant to the ancestor" << llendl; + return -1; +} + +// Returns true if inv_item can be dropped in dest_folder, a folder nested in marketplace listings (or merchant inventory) under the root_folder root +// If returns is false, tooltip_msg contains an error message to display to the user (localized and all). +// bundle_size is the amount of sibling items that are getting moved to the marketplace at the same time. +bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryItem* inv_item, std::string& tooltip_msg, S32 bundle_size) +{ + // Check stock folder type matches item type in marketplace listings or merchant outbox (even if of no use there for the moment) + LLViewerInventoryCategory* view_folder = dynamic_cast(dest_folder); + bool accept = (view_folder && view_folder->acceptItem(inv_item)); + + // Check that the item has the right type and persimssions to be sold on the marketplace + if (accept) + { + accept = can_move_to_marketplace(inv_item, tooltip_msg); + } + + // Check that the total amount of items won't violate the max limit on the marketplace + if (accept) + { + int existing_item_count = bundle_size; + + if (root_folder) + { + LLInventoryModel::cat_array_t existing_categories; + LLInventoryModel::item_array_t existing_items; + + gInventory.collectDescendents(root_folder->getUUID(), existing_categories, existing_items, FALSE); + + existing_item_count += existing_items.count(); + } + + if (existing_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxItemCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects", args); + accept = false; + } + } + + return accept; +} + +// Returns true if inve_cat can be dropped in dest_folder, a folder nested in marketplace listings (or merchant inventory) under the root_folder root +// If returns is false, tooltip_msg contains an error message to display to the user (localized and all). +// bundle_size is the amount of sibling items that are getting moved to the marketplace at the same time. +bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size) +{ + bool accept = true; + + // Compute the nested folder levels we'll get into with that folder + int nested_folder_levels = get_folder_levels(inv_cat); + if (root_folder) + { + nested_folder_levels += get_folder_path_length(root_folder->getUUID(), inv_cat->getUUID()); + } + if (nested_folder_levels > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels", args); + accept = false; + } + + if (accept) + { + LLInventoryModel::cat_array_t descendent_categories; + LLInventoryModel::item_array_t descendent_items; + gInventory.collectDescendents(inv_cat->getUUID(), descendent_categories, descendent_items, FALSE); + + int dragged_folder_count = descendent_categories.count(); + int existing_item_count = 0; + int existing_folder_count = 0; + + if (root_folder) + { + if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), root_folder->getUUID())) + { + // Don't use count because we're already inside the same category anyway + dragged_folder_count = 0; + } + else + { + existing_folder_count = 1; // Include the root folder in the count! + dragged_folder_count += bundle_size; + } + + // Tally the total number of categories and items inside the root folder + + LLInventoryModel::cat_array_t existing_categories; + LLInventoryModel::item_array_t existing_items; + + gInventory.collectDescendents(root_folder->getUUID(), existing_categories, existing_items, FALSE); + + existing_folder_count += existing_categories.count(); + existing_item_count += existing_items.count(); + } + else + { + // Assume a single folder is being moved in + dragged_folder_count += 1; + } + + const int nested_folder_count = existing_folder_count + dragged_folder_count; + const int nested_item_count = existing_item_count + descendent_items.count(); + + if (nested_folder_count > gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyFolders", args); + accept = false; + } + else if (nested_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxItemCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects", args); + accept = false; + } + + // Now check that each item in the folder can be moved in the marketplace + if (accept) + { + for (S32 i=0; i < descendent_items.count(); ++i) + { + LLInventoryItem* item = descendent_items[i]; + if (!can_move_to_marketplace(item, tooltip_msg)) + { + accept = false; + break; + } + } + } + } + + return accept; +} + bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) { // Get the marketplace listings depth of the destination folder, exit with error if not under marketplace -- cgit v1.2.3 From 4e0050ae9db61ef5b13c346ff659ae64c3756249 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 28 May 2014 10:16:17 -0700 Subject: DD-91 : WIP : Continue refactor of item checking in marketplace and simplify error messages --- indra/newview/llinventoryfunctions.cpp | 73 +++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 33 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 25592be99e..12a89c0ad8 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -914,16 +914,33 @@ S32 compute_stock_count(LLUUID cat_uuid) return curr_count; } -bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg) +bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg, bool resolve_links) { // Collapse links directly to items/folders LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item; LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); - if (linked_item != NULL) + LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory(); + + // Linked items and folders cannot be put for sale if caller can't resolve them + if (!resolve_links && (linked_category || linked_item)) + { + tooltip_msg = LLTrans::getString("TooltipOutboxLinked"); + return false; + } + + // A category is always considered as passing... + if (linked_category != NULL) + { + return true; + } + + // Take the linked item if necessary + if (linked_item != NULL) { inv_item = linked_item; } + // Check permissions bool allow_transfer = inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); if (!allow_transfer) { @@ -931,6 +948,7 @@ bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg return false; } + // Check for worn/not worn status bool worn = get_is_item_worn(inv_item->getUUID()); if (worn) { @@ -938,6 +956,7 @@ bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg return false; } + // Check for type bool calling_card = (LLAssetType::AT_CALLINGCARD == inv_item->getType()); if (calling_card) { @@ -1037,7 +1056,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve return accept; } -// Returns true if inve_cat can be dropped in dest_folder, a folder nested in marketplace listings (or merchant inventory) under the root_folder root +// Returns true if inv_cat can be dropped in dest_folder, a folder nested in marketplace listings (or merchant inventory) under the root_folder root // If returns is false, tooltip_msg contains an error message to display to the user (localized and all). // bundle_size is the amount of sibling items that are getting moved to the marketplace at the same time. bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size) @@ -1144,7 +1163,7 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol { llinfos << "Merov : Marketplace error : There is no marketplace listings folder -> move aborted!" << llendl; LLSD subs; - subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Not Merchant"); + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + LLTrans::getString("Marketplace Error Not Merchant"); LLNotificationsUtil::add("MerchantPasteFailed", subs); return false; } @@ -1166,7 +1185,8 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol // 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())) + std::string error_msg; + if (can_move_to_marketplace(inv_item, error_msg)) { // When moving an isolated item, we might need to create the folder structure to support it if (depth == 0) @@ -1196,7 +1216,7 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol { llinfos << "Merov : Marketplace error : Cannot move item in that folder -> move aborted!" << llendl; LLSD subs; - subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Not Accepted"); + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + LLTrans::getString("Marketplace Error Not Accepted"); LLNotificationsUtil::add("MerchantPasteFailed", subs); return false; } @@ -1229,9 +1249,9 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol } else { - llinfos << "Merov : Marketplace error : User doesn't have the correct permission to put this item on sale -> move aborted!" << llendl; + llinfos << "Merov : Marketplace error : " << error_msg << llendl; LLSD subs; - subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Unsellable Item"); + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + error_msg; LLNotificationsUtil::add("MerchantPasteFailed", subs); return false; } @@ -1350,6 +1370,12 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { cb(message); } + message.clear(); + bool is_ok = can_move_folder_to_marketplace(cat, cat, cat, message); + if (cb && !is_ok) + { + cb(message); + } } if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth <= 2)) { @@ -1388,33 +1414,14 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { 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) + std::string error_msg; + if (!can_move_to_marketplace(item, error_msg, false)) { - 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())) - { - 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; - } - if (viewer_inv_item->getType() == LLAssetType::AT_CALLINGCARD) - { - std::string message = " Error : calling cards are not allowed in listings : " + viewer_inv_item->getName(); - llinfos << "Merov : Validation error : " << message << llendl; + + std::string message = LLTrans::getString("Marketplace Error Prefix") + error_msg + " : " + viewer_inv_item->getName(); + llinfos << "Merov : Validation : " << message << llendl; if (cb) { cb(message); -- cgit v1.2.3 From e19a45a16cf21d422ba08fc1ca186fbba23e15b2 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 28 May 2014 16:07:39 -0700 Subject: DD-91 : Fixed! Get each listing to pass through the folder/size check on validation. Make all messages localizable. General clean up --- indra/newview/llinventoryfunctions.cpp | 185 +++++++++++++++------------------ 1 file changed, 86 insertions(+), 99 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 12a89c0ad8..b56383e48f 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -914,6 +914,7 @@ S32 compute_stock_count(LLUUID cat_uuid) return curr_count; } +// local helper bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg, bool resolve_links) { // Collapse links directly to items/folders @@ -940,7 +941,8 @@ bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg inv_item = linked_item; } - // Check permissions + // 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. bool allow_transfer = inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); if (!allow_transfer) { @@ -948,7 +950,7 @@ bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg return false; } - // Check for worn/not worn status + // Check worn/not worn status: worn items cannot be put on the marketplace bool worn = get_is_item_worn(inv_item->getUUID()); if (worn) { @@ -956,7 +958,7 @@ bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg return false; } - // Check for type + // Check type: for the moment, calling cards cannot be put on the marketplace bool calling_card = (LLAssetType::AT_CALLINGCARD == inv_item->getType()); if (calling_card) { @@ -1013,6 +1015,38 @@ int get_folder_path_length(const LLUUID& ancestor_id, const LLUUID& descendant_i return -1; } +// local helper +// Returns true if all items within the argument folder are fit for sale, false otherwise +bool has_correct_permissions_for_sale(LLInventoryCategory* cat, std::string& error_msg) +{ + 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; + if (!can_move_to_marketplace(item, error_msg, false)) + { + 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, error_msg)) + { + return false; + } + } + return true; +} + // Returns true if inv_item can be dropped in dest_folder, a folder nested in marketplace listings (or merchant inventory) under the root_folder root // If returns is false, tooltip_msg contains an error message to display to the user (localized and all). // bundle_size is the amount of sibling items that are getting moved to the marketplace at the same time. @@ -1025,7 +1059,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve // Check that the item has the right type and persimssions to be sold on the marketplace if (accept) { - accept = can_move_to_marketplace(inv_item, tooltip_msg); + accept = can_move_to_marketplace(inv_item, tooltip_msg, true); } // Check that the total amount of items won't violate the max limit on the marketplace @@ -1067,7 +1101,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn int nested_folder_levels = get_folder_levels(inv_cat); if (root_folder) { - nested_folder_levels += get_folder_path_length(root_folder->getUUID(), inv_cat->getUUID()); + nested_folder_levels += get_folder_path_length(root_folder->getUUID(), dest_folder->getUUID()); } if (nested_folder_levels > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) { @@ -1084,7 +1118,8 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn LLInventoryModel::item_array_t descendent_items; gInventory.collectDescendents(inv_cat->getUUID(), descendent_categories, descendent_items, FALSE); - int dragged_folder_count = descendent_categories.count(); + int dragged_folder_count = descendent_categories.count() + 1; + int dragged_item_count = descendent_items.count() + bundle_size; int existing_item_count = 0; int existing_folder_count = 0; @@ -1092,13 +1127,13 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn { if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), root_folder->getUUID())) { - // Don't use count because we're already inside the same category anyway + // Clear those counts or they will be counted twice because we're already inside the root category dragged_folder_count = 0; + dragged_item_count = bundle_size; } else { - existing_folder_count = 1; // Include the root folder in the count! - dragged_folder_count += bundle_size; + existing_folder_count += 1; // Include the root folder in the count! } // Tally the total number of categories and items inside the root folder @@ -1111,16 +1146,11 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn existing_folder_count += existing_categories.count(); existing_item_count += existing_items.count(); } - else - { - // Assume a single folder is being moved in - dragged_folder_count += 1; - } - const int nested_folder_count = existing_folder_count + dragged_folder_count; - const int nested_item_count = existing_item_count + descendent_items.count(); + const int total_folder_count = existing_folder_count + dragged_folder_count; + const int total_item_count = existing_item_count + dragged_item_count; - if (nested_folder_count > gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) + if (total_folder_count > gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) { LLStringUtil::format_map_t args; U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderCount"); @@ -1128,7 +1158,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn tooltip_msg = LLTrans::getString("TooltipOutboxTooManyFolders", args); accept = false; } - else if (nested_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) + else if (total_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) { LLStringUtil::format_map_t args; U32 amount = gSavedSettings.getU32("InventoryOutboxMaxItemCount"); @@ -1143,7 +1173,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn for (S32 i=0; i < descendent_items.count(); ++i) { LLInventoryItem* item = descendent_items[i]; - if (!can_move_to_marketplace(item, tooltip_msg)) + if (!can_move_to_marketplace(item, tooltip_msg, false)) { accept = false; break; @@ -1161,7 +1191,6 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol S32 depth = depth_nesting_in_marketplace(dest_folder); if (depth < 0) { - llinfos << "Merov : Marketplace error : There is no marketplace listings folder -> move aborted!" << llendl; LLSD subs; subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + LLTrans::getString("Marketplace Error Not Merchant"); LLNotificationsUtil::add("MerchantPasteFailed", subs); @@ -1186,7 +1215,7 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol // 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. std::string error_msg; - if (can_move_to_marketplace(inv_item, error_msg)) + if (can_move_to_marketplace(inv_item, error_msg, true)) { // When moving an isolated item, we might need to create the folder structure to support it if (depth == 0) @@ -1214,7 +1243,6 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol // 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 folder -> move aborted!" << llendl; LLSD subs; subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + LLTrans::getString("Marketplace Error Not Accepted"); LLNotificationsUtil::add("MerchantPasteFailed", subs); @@ -1249,7 +1277,6 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol } else { - llinfos << "Merov : Marketplace error : " << error_msg << llendl; LLSD subs; subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + error_msg; LLNotificationsUtil::add("MerchantPasteFailed", subs); @@ -1262,7 +1289,8 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol bool 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)) + std::string error_msg; + if (has_correct_permissions_for_sale(inv_cat, error_msg)) { // Get the destination folder LLViewerInventoryCategory* dest_cat = gInventory.getCategory(dest_folder); @@ -1270,9 +1298,8 @@ bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU // 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; LLSD subs; - subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Not Accepted"); + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + LLTrans::getString("Marketplace Error Not Accepted"); LLNotificationsUtil::add("MerchantPasteFailed", subs); return false; } @@ -1300,49 +1327,13 @@ bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU update_marketplace_category(dest_folder); gInventory.notifyObservers(); } - return true; -} - -// 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; - } - // 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; - } - } - - 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; - } - } + else + { + LLSD subs; + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + error_msg; + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return false; + } return true; } @@ -1364,29 +1355,33 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } if (depth == 1) { - std::string message = "Validating listing : " + cat->getName(); - llinfos << "Merov : Validation log : " << message << llendl; if (cb) { + std::string message = LLTrans::getString("Marketplace Validation Intro") + cat->getName(); cb(message); } - message.clear(); - bool is_ok = can_move_folder_to_marketplace(cat, cat, cat, message); + std::string message; + bool is_ok = can_move_folder_to_marketplace(cat, cat, cat, message, 0); if (cb && !is_ok) { + message = LLTrans::getString("Marketplace Validation Error") + message; cb(message); } } + std::string indent; + for (int i = 1; i < depth; i++) + { + indent += " "; + } 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()); - std::string message = " Warning : creating wrapping folder for stock folder : " + cat->getName(); - llinfos << "Merov : Validation warning : " << message << llendl; if (cb) { + std::string message = indent + LLTrans::getString("Marketplace Validation Warning Stock") + cat->getName(); cb(message); } LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); @@ -1419,11 +1414,9 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ std::string error_msg; if (!can_move_to_marketplace(item, error_msg, false)) { - - std::string message = LLTrans::getString("Marketplace Error Prefix") + error_msg + " : " + viewer_inv_item->getName(); - llinfos << "Merov : Validation : " << message << llendl; if (cb) { + std::string message = indent + LLTrans::getString("Marketplace Validation Error") + error_msg + " : " + viewer_inv_item->getName(); cb(message); } continue; @@ -1451,10 +1444,10 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // If we have no items in there (only folders) -> all OK if (count == 0) { - std::string message = " Log : folder validates: doesn't contain any item"; - llinfos << "Merov : Validation log : " << message << llendl; - if (cb) + // We warn if there's really nothing in the folder (may be it's a mistake or an under construction listing) + if ((cat_array->count() == 0) && cb) { + std::string message = indent + LLTrans::getString("Marketplace Validation Warning Empty") + cat->getName(); cb(message); } } @@ -1462,10 +1455,9 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ else if ((count == 1) && (((type == LLInventoryType::IT_COUNT) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)))) { // Done with that folder! - std::string message = " Log : folder validates: all items of compatible types"; - llinfos << "Merov : Validation log : " << message << llendl; if (cb) { + std::string message = indent + LLTrans::getString("Marketplace Validation Log") + cat->getName(); cb(message); } } @@ -1479,19 +1471,17 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Create a new folder 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); - std::string message = ""; - if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) - { - message = " Warning : creating stock folder : "; - } - else - { - message = " Warning : creating intermediate folder : "; - } - message += viewer_cat->getName(); - llinfos << "Merov : Validation warning : " << message << llendl; if (cb) { + std::string message = ""; + if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) + { + message = indent + LLTrans::getString("Marketplace Validation Warning Create Stock") + viewer_cat->getName(); + } + else + { + message = indent + LLTrans::getString("Marketplace Validation Warning Create Version") + viewer_cat->getName(); + } cb(message); } LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, viewer_cat->getName()); @@ -1499,10 +1489,9 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ while (!items_vector[i].empty()) { LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); - std::string message = " Warning : moving item : " + viewer_inv_item->getName(); - llinfos << "Merov : Validation warning : " << message << llendl; if (cb) { + std::string message = indent + LLTrans::getString("Marketplace Validation Warning Move") + viewer_inv_item->getName(); cb(message); } gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); @@ -1516,11 +1505,9 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (viewer_cat->getDescendentCount() == 0) { // Remove the current folder if it ends up empty - 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) { + std::string message = indent + LLTrans::getString("Marketplace Validation Warning Delete") + viewer_cat->getName(); cb(message); } gInventory.removeCategory(cat->getUUID()); -- cgit v1.2.3 From 22ee6abe0b4cd354ccbcb9055678356e91d009ff Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 28 May 2014 19:26:40 -0700 Subject: DD-84 : WIP : Add confirmation DAMA dialog when moving items in active listing --- indra/newview/llinventoryfunctions.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index b56383e48f..baf2a40590 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1185,7 +1185,8 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn return accept; } -bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) +// Local : perform the move at last... +bool perform_move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) { // Get the marketplace listings depth of the destination folder, exit with error if not under marketplace S32 depth = depth_nesting_in_marketplace(dest_folder); @@ -1286,6 +1287,33 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol return true; } +// Local : Callback for the move item if DAMA required... +bool callback_move_item_to_marketplacelistings(const LLSD& notification, const LLSD& response, LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) // YES + { + return perform_move_item_to_marketplacelistings(inv_item, dest_folder, copy); + } + return false; + } + +// Public interface: Check if confirmation dialog is required (DAMA) and call it or call the move item function directly +bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) +{ + // Merov : Use the following weak test for testing... + //if (LLMarketplaceData::instance().isVersionFolder(dest_folder)) + if (LLMarketplaceData::instance().getActivationState(dest_folder)) + { + LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(callback_move_item_to_marketplacelistings, _1, _2, inv_item, dest_folder, copy)); + return true; + } + else + { + return perform_move_item_to_marketplacelistings(inv_item, dest_folder, copy); + } +} + bool 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. -- cgit v1.2.3 From b9407199462c0b56a7d49c2e19657e87ec149d8c Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 29 May 2014 16:56:15 -0700 Subject: DD-84 : WIP : Get DAMA to display for drag and drop. Note that, because of current SLM issues, it works on version folders, active or not. --- indra/newview/llinventoryfunctions.cpp | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index baf2a40590..b56383e48f 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1185,8 +1185,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn return accept; } -// Local : perform the move at last... -bool perform_move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) +bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) { // Get the marketplace listings depth of the destination folder, exit with error if not under marketplace S32 depth = depth_nesting_in_marketplace(dest_folder); @@ -1287,33 +1286,6 @@ bool perform_move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID return true; } -// Local : Callback for the move item if DAMA required... -bool callback_move_item_to_marketplacelistings(const LLSD& notification, const LLSD& response, LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) // YES - { - return perform_move_item_to_marketplacelistings(inv_item, dest_folder, copy); - } - return false; - } - -// Public interface: Check if confirmation dialog is required (DAMA) and call it or call the move item function directly -bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) -{ - // Merov : Use the following weak test for testing... - //if (LLMarketplaceData::instance().isVersionFolder(dest_folder)) - if (LLMarketplaceData::instance().getActivationState(dest_folder)) - { - LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(callback_move_item_to_marketplacelistings, _1, _2, inv_item, dest_folder, copy)); - return true; - } - else - { - return perform_move_item_to_marketplacelistings(inv_item, dest_folder, copy); - } -} - bool 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. -- cgit v1.2.3 From a1afe50feb1c42cc21c7f89b4187a8f7abe0c9fc Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 30 May 2014 12:20:07 -0700 Subject: DD-84 : Prompt the user for active listing edits (Cut, Paste and Delete). --- indra/newview/llinventoryfunctions.cpp | 36 +++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index b56383e48f..7a7d910a23 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1912,13 +1912,45 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder) } } -void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action) +// Callback for doToSelected if DAMA required... +void LLInventoryAction::callback_doToSelected(const LLSD& notification, const LLSD& response, class LLInventoryModel* model, class LLFolderView* root, const std::string& action) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) // YES + { + doToSelected(model, root, action, FALSE); + } +} + +void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action, BOOL user_confirm) { if ("rename" == action) { root->startRenamingSelectedItem(); return; } + + std::set selected_items = root->getSelectionList(); + + // Prompt the user for some marketplace active listing edits + if (user_confirm && (("paste" == action) || ("cut" == action) || ("delete" == action))) + { + std::set::iterator set_iter = selected_items.begin(); + for (; set_iter != selected_items.end(); ++set_iter) + { + LLFolderViewModelItemInventory * viewModel = dynamic_cast((*set_iter)->getViewModelItem()); + if (viewModel && LLMarketplaceData::instance().isInActiveFolder(viewModel->getUUID())) + { + break; + } + } + if (set_iter != selected_items.end()) + { + LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); + return; + } + } + if ("delete" == action) { LLSD args; @@ -1945,8 +1977,6 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } - std::set selected_items = root->getSelectionList(); - LLMultiPreview* multi_previewp = NULL; LLMultiProperties* multi_propertiesp = NULL; -- cgit v1.2.3 From fd426bafb6616491b8929ee357a5b2d40e123607 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sat, 31 May 2014 19:19:20 -0700 Subject: DD-92 : Clear llinfos compilation warning and similar --- indra/newview/llinventoryfunctions.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index baa2a08933..5dc2385f04 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -166,7 +166,7 @@ void update_marketplace_category(const LLUUID& cur_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 : Unlist as the version folder is not under the listing folder anymore!!" << llendl; + LL_INFOS("SLM") << "Unlist as the version folder is not under the listing folder anymore!!" << LL_ENDL; LLMarketplaceData::instance().setVersionFolder(listing_uuid, LLUUID::null); LLMarketplaceData::instance().activateListing(listing_uuid, false); } @@ -180,7 +180,7 @@ void update_marketplace_category(const LLUUID& cur_uuid) if (LLMarketplaceData::instance().isListed(cur_uuid)) { // *TODO : Confirm with Producer that this is what we want to happen in that case! - llinfos << "Merov : Disassociate as the listing folder is not under the marketplace folder anymore!!" << llendl; + LL_INFOS("SLM") << "Disassociate as the listing folder is not under the marketplace folder anymore!!" << LL_ENDL; LLMarketplaceData::instance().clearListing(cur_uuid); } } @@ -1008,7 +1008,7 @@ int get_folder_path_length(const LLUUID& ancestor_id, const LLUUID& descendant_i category = gInventory.getCategory(parent_id); } - llwarns << "get_folder_path_length() couldn't trace a path from the descendant to the ancestor" << llendl; + LL_WARNS("SLM") << "get_folder_path_length() couldn't trace a path from the descendant to the ancestor" << LL_ENDL; return -1; } -- cgit v1.2.3 From 86d75052f65149da6bbe1ade5ea28b6f01aaba17 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 3 Jun 2014 19:46:33 -0700 Subject: DD-84 : Fix all active listing modification actions. Add specific message when listing will unlist. Make update skip consistency check when called from internal level (not public API). --- indra/newview/llinventoryfunctions.cpp | 36 +++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 5dc2385f04..f832237b8d 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -141,7 +141,7 @@ void update_marketplace_folder_hierarchy(const LLUUID cat_id) return; } -void update_marketplace_category(const LLUUID& cur_uuid) +void update_marketplace_category(const LLUUID& cur_uuid, bool skip_consistency_enforcement) { // When changing the marketplace status of an item, 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 @@ -160,12 +160,11 @@ void update_marketplace_category(const LLUUID& cur_uuid) LLUUID listing_uuid = nested_parent_id(cur_uuid, depth); // Verify marketplace data consistency for this listing - if (LLMarketplaceData::instance().isListed(listing_uuid)) + if (!skip_consistency_enforcement && LLMarketplaceData::instance().isListed(listing_uuid)) { LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolder(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! LL_INFOS("SLM") << "Unlist as the version folder is not under the listing folder anymore!!" << LL_ENDL; LLMarketplaceData::instance().setVersionFolder(listing_uuid, LLUUID::null); LLMarketplaceData::instance().activateListing(listing_uuid, false); @@ -177,9 +176,8 @@ void update_marketplace_category(const LLUUID& cur_uuid) } else if (depth < 0) { - if (LLMarketplaceData::instance().isListed(cur_uuid)) + if (!skip_consistency_enforcement && LLMarketplaceData::instance().isListed(cur_uuid)) { - // *TODO : Confirm with Producer that this is what we want to happen in that case! LL_INFOS("SLM") << "Disassociate as the listing folder is not under the marketplace folder anymore!!" << LL_ENDL; LLMarketplaceData::instance().clearListing(cur_uuid); } @@ -1928,21 +1926,16 @@ void LLInventoryAction::callback_doToSelected(const LLSD& notification, const LL void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action, BOOL user_confirm) { - if ("rename" == action) - { - root->startRenamingSelectedItem(); - return; - } - std::set selected_items = root->getSelectionList(); // Prompt the user for some marketplace active listing edits - if (user_confirm && (("paste" == action) || ("cut" == action) || ("delete" == action))) + if (user_confirm && (("cut" == action) || ("delete" == action) || ("rename" == action) || ("properties" == action) || ("task_properties" == action))) { std::set::iterator set_iter = selected_items.begin(); + LLFolderViewModelItemInventory * viewModel = NULL; for (; set_iter != selected_items.end(); ++set_iter) { - LLFolderViewModelItemInventory * viewModel = dynamic_cast((*set_iter)->getViewModelItem()); + viewModel = dynamic_cast((*set_iter)->getViewModelItem()); if (viewModel && LLMarketplaceData::instance().isInActiveFolder(viewModel->getUUID())) { break; @@ -1950,11 +1943,26 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } if (set_iter != selected_items.end()) { - LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); + if ((("cut" == action) || ("delete" == action)) && (LLMarketplaceData::instance().isListed(viewModel->getUUID()) || LLMarketplaceData::instance().isVersionFolder(viewModel->getUUID()))) + { + // Cut or delete of the active version folder or listing folder itself will unlist the listing so ask that question specifically + LLNotificationsUtil::add("ConfirmMerchantUnlist", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); + } + else + { + // Any other case will simply modify but not unlist a listing + LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); + } return; } } + if ("rename" == action) + { + root->startRenamingSelectedItem(); + return; + } + if ("delete" == action) { LLSD args; -- cgit v1.2.3 From 252ad06b7bcc33a48b6c23917f6156a436df4b00 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 4 Jun 2014 09:58:11 -0700 Subject: DD-84 : Final clean up for this fix --- indra/newview/llinventoryfunctions.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index f832237b8d..da8c03eb7c 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -141,7 +141,7 @@ void update_marketplace_folder_hierarchy(const LLUUID cat_id) return; } -void update_marketplace_category(const LLUUID& cur_uuid, bool skip_consistency_enforcement) +void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistency_enforcement) { // When changing the marketplace status of an item, 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 @@ -160,7 +160,7 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool skip_consistency_e LLUUID listing_uuid = nested_parent_id(cur_uuid, depth); // Verify marketplace data consistency for this listing - if (!skip_consistency_enforcement && LLMarketplaceData::instance().isListed(listing_uuid)) + if (perform_consistency_enforcement && LLMarketplaceData::instance().isListed(listing_uuid)) { LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolder(listing_uuid); if (version_folder_uuid.notNull() && !gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid)) @@ -176,7 +176,7 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool skip_consistency_e } else if (depth < 0) { - if (!skip_consistency_enforcement && LLMarketplaceData::instance().isListed(cur_uuid)) + if (perform_consistency_enforcement && LLMarketplaceData::instance().isListed(cur_uuid)) { LL_INFOS("SLM") << "Disassociate as the listing folder is not under the marketplace folder anymore!!" << LL_ENDL; LLMarketplaceData::instance().clearListing(cur_uuid); @@ -1929,7 +1929,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root std::set selected_items = root->getSelectionList(); // Prompt the user for some marketplace active listing edits - if (user_confirm && (("cut" == action) || ("delete" == action) || ("rename" == action) || ("properties" == action) || ("task_properties" == action))) + if (user_confirm && (("delete" == action) || ("rename" == action) || ("properties" == action) || ("task_properties" == action))) { std::set::iterator set_iter = selected_items.begin(); LLFolderViewModelItemInventory * viewModel = NULL; -- cgit v1.2.3 From 7911e32d4bd9f86bdde5771dcaa14203befa5f7d Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 5 Jun 2014 18:02:28 -0700 Subject: DD-114, DD-115, DD-116: Fixed counts on folder, folder depth and items on operations on marketplace listings --- indra/newview/llinventoryfunctions.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index da8c03eb7c..b17e9551e5 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1092,13 +1092,14 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn { bool accept = true; - // Compute the nested folder levels we'll get into with that folder - int nested_folder_levels = get_folder_levels(inv_cat); - if (root_folder) - { - nested_folder_levels += get_folder_path_length(root_folder->getUUID(), dest_folder->getUUID()); - } - if (nested_folder_levels > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) + // Compute the nested folders level we'll add into with that incoming folder + int incoming_folder_depth = get_folder_levels(inv_cat); + // Compute the nested folders level we're inserting ourselves in + // Note: add one when inserting under a listing folder as we need to take the root listing folder in the count + int insertion_point_folder_depth = (root_folder ? get_folder_path_length(root_folder->getUUID(), dest_folder->getUUID()) + 1 : 0); + + // Compare the whole with the nested folders depth limit + if ((incoming_folder_depth + insertion_point_folder_depth) > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) { LLStringUtil::format_map_t args; U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"); @@ -1113,8 +1114,8 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn LLInventoryModel::item_array_t descendent_items; gInventory.collectDescendents(inv_cat->getUUID(), descendent_categories, descendent_items, FALSE); - int dragged_folder_count = descendent_categories.size() + 1; - int dragged_item_count = descendent_items.size() + bundle_size; + int dragged_folder_count = descendent_categories.size() + bundle_size; // Note: We assume that we're moving a bunch of folders in. That might be wrong... + int dragged_item_count = descendent_items.size(); int existing_item_count = 0; int existing_folder_count = 0; @@ -1124,7 +1125,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn { // Clear those counts or they will be counted twice because we're already inside the root category dragged_folder_count = 0; - dragged_item_count = bundle_size; + dragged_item_count = 0; } else { -- cgit v1.2.3 From 4083e972ccf238cd02d60da2af88855f25ed7b1f Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 9 Jun 2014 15:20:07 -0700 Subject: DD-97 : When clearing the version folder of a record, force activation (listed) status to false at the same time, avoiding confusing (and eventually wrong) double call to updateSLMListing --- indra/newview/llinventoryfunctions.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index b17e9551e5..606f95560b 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -167,7 +167,6 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc { LL_INFOS("SLM") << "Unlist as the version folder is not under the listing folder anymore!!" << LL_ENDL; LLMarketplaceData::instance().setVersionFolder(listing_uuid, LLUUID::null); - LLMarketplaceData::instance().activateListing(listing_uuid, false); } } -- cgit v1.2.3 From 73055758b9a170f7f1b868caab477b3b0d1b5b18 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 9 Jun 2014 16:23:18 -0700 Subject: DD-126 : Fixed. Check that the version folder depth is 2 when enforcing consistency rules --- indra/newview/llinventoryfunctions.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 606f95560b..de1173bf2b 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -163,9 +163,10 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc if (perform_consistency_enforcement && LLMarketplaceData::instance().isListed(listing_uuid)) { LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolder(listing_uuid); - if (version_folder_uuid.notNull() && !gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid)) + S32 version_depth = depth_nesting_in_marketplace(version_folder_uuid); + if (version_folder_uuid.notNull() && (!gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid) || (version_depth != 2))) { - LL_INFOS("SLM") << "Unlist as the version folder is not under the listing folder anymore!!" << LL_ENDL; + LL_INFOS("SLM") << "Unlist and clear version folder as the version folder is not at the right place anymore!!" << LL_ENDL; LLMarketplaceData::instance().setVersionFolder(listing_uuid, LLUUID::null); } } -- cgit v1.2.3 From d37ef40e98059e0ceb40385e3c40e891e6eec4ec Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 9 Jun 2014 17:31:43 -0700 Subject: DD-115, DD-130 : Fixed. Count items and folders from the version folder, not the listing root --- indra/newview/llinventoryfunctions.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index de1173bf2b..71f80e8bd5 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1062,12 +1062,15 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve { int existing_item_count = bundle_size; - if (root_folder) + // Get the version folder: that's where the counts start from + const LLViewerInventoryCategory * version_folder = ((root_folder && (root_folder != dest_folder)) ? gInventory.getFirstDescendantOf(root_folder->getUUID(), dest_folder->getUUID()) : NULL); + + if (version_folder) { LLInventoryModel::cat_array_t existing_categories; LLInventoryModel::item_array_t existing_items; - gInventory.collectDescendents(root_folder->getUUID(), existing_categories, existing_items, FALSE); + gInventory.collectDescendents(version_folder->getUUID(), existing_categories, existing_items, FALSE); existing_item_count += existing_items.size(); } @@ -1097,6 +1100,9 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn // Compute the nested folders level we're inserting ourselves in // Note: add one when inserting under a listing folder as we need to take the root listing folder in the count int insertion_point_folder_depth = (root_folder ? get_folder_path_length(root_folder->getUUID(), dest_folder->getUUID()) + 1 : 0); + + // Get the version folder: that's where the counts start from + const LLViewerInventoryCategory * version_folder = (insertion_point_folder_depth >= 2 ? gInventory.getFirstDescendantOf(root_folder->getUUID(), dest_folder->getUUID()) : NULL); // Compare the whole with the nested folders depth limit if ((incoming_folder_depth + insertion_point_folder_depth) > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) @@ -1119,17 +1125,17 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn int existing_item_count = 0; int existing_folder_count = 0; - if (root_folder) + if (version_folder) { - if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), root_folder->getUUID())) + if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), version_folder->getUUID())) { - // Clear those counts or they will be counted twice because we're already inside the root category + // Clear those counts or they will be counted twice because we're already inside the version category dragged_folder_count = 0; dragged_item_count = 0; } else { - existing_folder_count += 1; // Include the root folder in the count! + existing_folder_count += 2; // Include the version and root folders in the count! } // Tally the total number of categories and items inside the root folder @@ -1137,11 +1143,16 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn LLInventoryModel::cat_array_t existing_categories; LLInventoryModel::item_array_t existing_items; - gInventory.collectDescendents(root_folder->getUUID(), existing_categories, existing_items, FALSE); + gInventory.collectDescendents(version_folder->getUUID(), existing_categories, existing_items, FALSE); existing_folder_count += existing_categories.size(); existing_item_count += existing_items.size(); } + else if (root_folder) + { + // Not in a version folder but inside a listing folder: we're being inserted as a version folder then + existing_folder_count += 1; // Include the root folder in the count! + } const int total_folder_count = existing_folder_count + dragged_folder_count; const int total_item_count = existing_item_count + dragged_item_count; -- cgit v1.2.3 From 10dc6854a8f677c206aa9d3595f63223d542260e Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 11 Jun 2014 19:19:44 -0700 Subject: DD-130 : Count all folders and subfolders from the version folder excluding the version folder itself --- indra/newview/llinventoryfunctions.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 71f80e8bd5..78b3d71872 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1098,14 +1098,15 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn // Compute the nested folders level we'll add into with that incoming folder int incoming_folder_depth = get_folder_levels(inv_cat); // Compute the nested folders level we're inserting ourselves in - // Note: add one when inserting under a listing folder as we need to take the root listing folder in the count + // Note: add 1 when inserting under a listing folder as we need to take the root listing folder in the count int insertion_point_folder_depth = (root_folder ? get_folder_path_length(root_folder->getUUID(), dest_folder->getUUID()) + 1 : 0); - // Get the version folder: that's where the counts start from + // Get the version folder: that's where the folders and items counts start from const LLViewerInventoryCategory * version_folder = (insertion_point_folder_depth >= 2 ? gInventory.getFirstDescendantOf(root_folder->getUUID(), dest_folder->getUUID()) : NULL); // Compare the whole with the nested folders depth limit - if ((incoming_folder_depth + insertion_point_folder_depth) > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) + // Note: substract 2 as we leave root and version folder out of the count threshold + if ((incoming_folder_depth + insertion_point_folder_depth - 2) > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) { LLStringUtil::format_map_t args; U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"); @@ -1133,26 +1134,15 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn dragged_folder_count = 0; dragged_item_count = 0; } - else - { - existing_folder_count += 2; // Include the version and root folders in the count! - } // Tally the total number of categories and items inside the root folder - LLInventoryModel::cat_array_t existing_categories; LLInventoryModel::item_array_t existing_items; - gInventory.collectDescendents(version_folder->getUUID(), existing_categories, existing_items, FALSE); existing_folder_count += existing_categories.size(); existing_item_count += existing_items.size(); } - else if (root_folder) - { - // Not in a version folder but inside a listing folder: we're being inserted as a version folder then - existing_folder_count += 1; // Include the root folder in the count! - } const int total_folder_count = existing_folder_count + dragged_folder_count; const int total_item_count = existing_item_count + dragged_item_count; -- cgit v1.2.3 From f79b1139fd28b29c51a0c001960ef3f0bb999ec0 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 13 Jun 2014 10:20:53 -0700 Subject: DD-82 : Update marketplace listings after delete, cut and other operations on selected items --- indra/newview/llinventoryfunctions.cpp | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 78b3d71872..08c6d7e577 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -90,6 +90,7 @@ BOOL LLInventoryState::sWearNewClothing = FALSE; LLUUID LLInventoryState::sWearNewClothingTransactionID; +std::list LLInventoryAction::sMarketplaceFolders; // Helper function : callback to update a folder after inventory action happened in the background void update_folder_cb(const LLUUID& dest_folder) @@ -1959,9 +1960,14 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } } + // Keep track of the marketplace folders that will need update of their status/name after the operation is performed + buildMarketplaceFolders(root); + if ("rename" == action) { root->startRenamingSelectedItem(); + // Update the marketplace listings that have been affected by the operation + updateMarketplaceFolders(); return; } @@ -1970,6 +1976,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root LLSD args; args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" : "DeleteItem"); LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root)); + // Note: marketplace listings will be updated in the callback if delete confirmed return; } if (("copy" == action) || ("cut" == action)) @@ -1987,6 +1994,8 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root LLViewerInventoryCategory *cat = model->getCategory(inventory_item->getUUID()); if (!cat) return; cat->changeType(new_folder_type); + // Update the marketplace listings that have been affected by the operation + updateMarketplaceFolders(); return; } @@ -2021,6 +2030,9 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root bridge->performAction(model, action); } + // Update the marketplace listings that have been affected by the operation + updateMarketplaceFolders(); + LLFloater::setFloaterHost(NULL); if (multi_previewp) { @@ -2064,5 +2076,43 @@ void LLInventoryAction::onItemsRemovalConfirmation( const LLSD& notification, co //because once removed from root folder view the item is no longer a selected item removeItemFromDND(root); root->removeSelectedItems(); + + // Update the marketplace listings that have been affected by the operation + updateMarketplaceFolders(); } } + +void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root) +{ + // Make a list of all marketplace folders containing the elements in the selected list + // Once those elements are updated (cut, delete in particular but potentially any action), their originally + // containing marketplace listing might need to be udpated to reflect their new content accurately + sMarketplaceFolders.clear(); + const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + std::set selected_items = root->getSelectionList(); + std::set::iterator set_iter = selected_items.begin(); + LLFolderViewModelItemInventory * viewModel = NULL; + for (; set_iter != selected_items.end(); ++set_iter) + { + viewModel = dynamic_cast((*set_iter)->getViewModelItem()); + if (viewModel && gInventory.isObjectDescendentOf(viewModel->getInventoryObject()->getParentUUID(), marketplacelistings_id)) + { + sMarketplaceFolders.push_back(viewModel->getInventoryObject()->getParentUUID()); + } + } + // Suppress dupes in the list so we won't update listings twice + sMarketplaceFolders.sort(); + sMarketplaceFolders.unique(); +} + +void LLInventoryAction::updateMarketplaceFolders() +{ + while (!sMarketplaceFolders.empty()) + { + update_marketplace_category(sMarketplaceFolders.back()); + sMarketplaceFolders.pop_back(); + } +} + + + -- cgit v1.2.3 From c890d32101f559ef4422b3af3a9aa4c14b429743 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 20 Jun 2014 22:06:31 -0700 Subject: DD-150 : Fix U32 to S32 conversion that failed a condition in folder count --- 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 08c6d7e577..88967a4d39 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1107,7 +1107,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn // Compare the whole with the nested folders depth limit // Note: substract 2 as we leave root and version folder out of the count threshold - if ((incoming_folder_depth + insertion_point_folder_depth - 2) > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) + if ((incoming_folder_depth + insertion_point_folder_depth - 2) > (S32)(gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"))) { LLStringUtil::format_map_t args; U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"); -- cgit v1.2.3 From 18579f8eedb4d31ded2658dd5d8d1f82477a5d56 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 4 Jul 2014 11:45:54 -0700 Subject: DD-133 : Fixed. Add the original items to the list of things to update after action is performed. --- indra/newview/llinventoryfunctions.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 88967a4d39..84b8177e0d 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2085,8 +2085,11 @@ void LLInventoryAction::onItemsRemovalConfirmation( const LLSD& notification, co void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root) { // Make a list of all marketplace folders containing the elements in the selected list - // Once those elements are updated (cut, delete in particular but potentially any action), their originally - // containing marketplace listing might need to be udpated to reflect their new content accurately + // as well as the elements themselves. + // Once those elements are updated (cut, delete in particular but potentially any action), their + // containing folder will need to be updated as well as their initially containing folder. For + // instance, moving a stock folder from a listed folder to another will require an update of the + // target listing *and* the original listing. So we need to keep track of both. sMarketplaceFolders.clear(); const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); std::set selected_items = root->getSelectionList(); @@ -2098,6 +2101,7 @@ void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root) if (viewModel && gInventory.isObjectDescendentOf(viewModel->getInventoryObject()->getParentUUID(), marketplacelistings_id)) { sMarketplaceFolders.push_back(viewModel->getInventoryObject()->getParentUUID()); + sMarketplaceFolders.push_back(viewModel->getInventoryObject()->getUUID()); } } // Suppress dupes in the list so we won't update listings twice -- cgit v1.2.3 From 9a5ebdb1af723eed134d9e4e7ef4c7219a45f27b Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 4 Jul 2014 15:05:28 -0700 Subject: DD-128 : Fixed. Do not allow clothes or body parts on active listings to be worn or rendered IW --- 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 84b8177e0d..63b1fa78fc 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1930,9 +1930,9 @@ void LLInventoryAction::callback_doToSelected(const LLSD& notification, const LL void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action, BOOL user_confirm) { std::set selected_items = root->getSelectionList(); - - // Prompt the user for some marketplace active listing edits - if (user_confirm && (("delete" == action) || ("rename" == action) || ("properties" == action) || ("task_properties" == action))) + + // Prompt the user and check for authorization for some marketplace active listing edits + if (user_confirm && (("delete" == action) || ("cut" == action) || ("rename" == action) || ("properties" == action) || ("task_properties" == action) || ("open" == action))) { std::set::iterator set_iter = selected_items.begin(); LLFolderViewModelItemInventory * viewModel = NULL; @@ -1950,13 +1950,24 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root { // Cut or delete of the active version folder or listing folder itself will unlist the listing so ask that question specifically LLNotificationsUtil::add("ConfirmMerchantUnlist", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); + return; + } + else if ("open" == action) + { + if (get_can_item_be_worn(viewModel->getUUID())) + { + // Wearing an object from an active listing is verbotten + LLNotificationsUtil::add("AlertMerchantListingCannotWear"); + return; + } + // Note: we do not prompt for active change when opening items (e.g. textures or note cards) on the marketplace... } else { // Any other case will simply modify but not unlist a listing LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); + return; } - return; } } -- cgit v1.2.3 From cec79bdb29ac5438c9b9bb0312b4981116f17f61 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 4 Jul 2014 16:24:52 -0700 Subject: DD-152 : Fixed. Update all the descendent of a marketplace folder when moving it out of the marketplace --- indra/newview/llinventoryfunctions.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 63b1fa78fc..e31a6c8976 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -182,6 +182,11 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc LL_INFOS("SLM") << "Disassociate as the listing folder is not under the marketplace folder anymore!!" << LL_ENDL; LLMarketplaceData::instance().clearListing(cur_uuid); } + // Update all descendents if this is a category + if (gInventory.getCategory(cur_uuid)) + { + update_marketplace_folder_hierarchy(cur_uuid); + } } return; -- cgit v1.2.3 From 9c04a5bfbb56f2deb755da11ef261aad6491a46b Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 25 Jul 2014 17:14:17 -0700 Subject: DD-128 : Fixed. Do not allow items under the marketplace, even in inactive listings, to be worn. --- 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 e31a6c8976..f009a6f7dd 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1944,7 +1944,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root for (; set_iter != selected_items.end(); ++set_iter) { viewModel = dynamic_cast((*set_iter)->getViewModelItem()); - if (viewModel && LLMarketplaceData::instance().isInActiveFolder(viewModel->getUUID())) + if (viewModel && (depth_nesting_in_marketplace(viewModel->getUUID()) >= 0)) { break; } -- cgit v1.2.3 From bd5da258ea4cd5557bc79f29b0034cf666d0f652 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 25 Jul 2014 17:58:54 -0700 Subject: DD-128 : Fixed. Some confirmations are for active listings only. --- indra/newview/llinventoryfunctions.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index f009a6f7dd..0fd7eb067c 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1951,24 +1951,25 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } if (set_iter != selected_items.end()) { - if ((("cut" == action) || ("delete" == action)) && (LLMarketplaceData::instance().isListed(viewModel->getUUID()) || LLMarketplaceData::instance().isVersionFolder(viewModel->getUUID()))) - { - // Cut or delete of the active version folder or listing folder itself will unlist the listing so ask that question specifically - LLNotificationsUtil::add("ConfirmMerchantUnlist", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); - return; - } - else if ("open" == action) + if ("open" == action) { if (get_can_item_be_worn(viewModel->getUUID())) { - // Wearing an object from an active listing is verbotten + // Wearing an object from any listing, active or not, is verbotten LLNotificationsUtil::add("AlertMerchantListingCannotWear"); return; } - // Note: we do not prompt for active change when opening items (e.g. textures or note cards) on the marketplace... + // Note: we do not prompt for change when opening items (e.g. textures or note cards) on the marketplace... } - else + else if (LLMarketplaceData::instance().isInActiveFolder(viewModel->getUUID())) { + // If item is in active listing, further confirmation is required + if ((("cut" == action) || ("delete" == action)) && (LLMarketplaceData::instance().isListed(viewModel->getUUID()) || LLMarketplaceData::instance().isVersionFolder(viewModel->getUUID()))) + { + // Cut or delete of the active version folder or listing folder itself will unlist the listing so ask that question specifically + LLNotificationsUtil::add("ConfirmMerchantUnlist", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); + return; + } // Any other case will simply modify but not unlist a listing LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); return; -- cgit v1.2.3 From 51e4ad0ed0ba07328ec8415742a3f5c60afc7244 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sat, 26 Jul 2014 14:44:04 -0700 Subject: DD-101 : Do not list or associate listings that do not validate. Present user with relevant error when that happens. --- indra/newview/llinventoryfunctions.cpp | 60 ++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 24 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 0fd7eb067c..bdd129d54c 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1340,13 +1340,16 @@ bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU return true; } -// 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 : 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, validation_callback_t cb) -{ - // Special case a stock folder depth issue +// 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 (through the +// optional callback cb). It also returns a boolean, true if things validate, false if issues are raised. +// The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders. +bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb) +{ + // Folder is valid unless issue is raised + bool result = true; + + // 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()); @@ -1354,28 +1357,34 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { // If the folder is not under the marketplace listings root, validation should not be applied // *TODO: Should we call update_marketplace_category(cat->getUUID()) ? - return; + return result; } + if (depth == 1) { if (cb) { std::string message = LLTrans::getString("Marketplace Validation Intro") + cat->getName(); - cb(message); + cb(message,LLError::LEVEL_INFO); } std::string message; - bool is_ok = can_move_folder_to_marketplace(cat, cat, cat, message, 0); - if (cb && !is_ok) + if (!can_move_folder_to_marketplace(cat, cat, cat, message, 0)) { - message = LLTrans::getString("Marketplace Validation Error") + message; - cb(message); + result = false; + if (cb) + { + message = LLTrans::getString("Marketplace Validation Error") + message; + cb(message,LLError::LEVEL_ERROR); + } } } + std::string indent; for (int i = 1; i < depth; i++) { indent += " "; } + if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth <= 2)) { // Nest the stock folder one level deeper in a normal folder and restart from there @@ -1385,12 +1394,12 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { std::string message = indent + LLTrans::getString("Marketplace Validation Warning Stock") + cat->getName(); - cb(message); + cb(message,LLError::LEVEL_WARN); } LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); gInventory.changeCategoryParent(viewer_cat, folder_uuid, false); - validate_marketplacelistings(new_cat, cb); - return; + result &= validate_marketplacelistings(new_cat, cb); + return result; } LLInventoryModel::cat_array_t* cat_array; @@ -1417,10 +1426,11 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ std::string error_msg; if (!can_move_to_marketplace(item, error_msg, false)) { + result = false; if (cb) { std::string message = indent + LLTrans::getString("Marketplace Validation Error") + error_msg + " : " + viewer_inv_item->getName(); - cb(message); + cb(message,LLError::LEVEL_ERROR); } continue; } @@ -1451,7 +1461,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if ((cat_array->size() == 0) && cb) { std::string message = indent + LLTrans::getString("Marketplace Validation Warning Empty") + cat->getName(); - cb(message); + cb(message,LLError::LEVEL_WARN); } } // If we have one kind only, in the correct folder type at the right depth -> all OK @@ -1461,7 +1471,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { std::string message = indent + LLTrans::getString("Marketplace Validation Log") + cat->getName(); - cb(message); + cb(message,LLError::LEVEL_INFO); } } else @@ -1485,7 +1495,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { message = indent + LLTrans::getString("Marketplace Validation Warning Create Version") + viewer_cat->getName(); } - cb(message); + cb(message,LLError::LEVEL_WARN); } LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, viewer_cat->getName()); // Move each item to the new folder @@ -1495,7 +1505,7 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { std::string message = indent + LLTrans::getString("Marketplace Validation Warning Move") + viewer_inv_item->getName(); - cb(message); + cb(message,LLError::LEVEL_WARN); } gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); items_vector[i].pop_back(); @@ -1511,11 +1521,11 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { std::string message = indent + LLTrans::getString("Marketplace Validation Warning Delete") + viewer_cat->getName(); - cb(message); + cb(message,LLError::LEVEL_WARN); } gInventory.removeCategory(cat->getUUID()); gInventory.notifyObservers(); - return; + return result; } else { @@ -1531,8 +1541,10 @@ void validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) { LLInventoryCategory* category = *iter; - validate_marketplacelistings(category, cb); + result &= validate_marketplacelistings(category, cb); } + + return result; } ///---------------------------------------------------------------------------- -- cgit v1.2.3 From 9bedc2ab3dc88e2958a31d8501c3291cb2d5d20e Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 14 Aug 2014 21:02:43 -0700 Subject: DD-117 : Prevent drag and drop of linked items into the marketplace --- indra/newview/llinventoryfunctions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index bdd129d54c..98f74bb1a6 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -923,8 +923,8 @@ bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory(); - // Linked items and folders cannot be put for sale if caller can't resolve them - if (!resolve_links && (linked_category || linked_item)) + // Linked items and folders cannot be put for sale + if (linked_category || linked_item) { tooltip_msg = LLTrans::getString("TooltipOutboxLinked"); return false; -- cgit v1.2.3 From 51e8b7fae6ff14c58bf32ef740a60386bc15baee Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 19 Aug 2014 22:34:06 -0700 Subject: DD-129 : Prevent DAMA when dropping under the root of a listing, even active. Finer granularity of DAMA for all drop and cut and paste cases. --- indra/newview/llinventoryfunctions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 98f74bb1a6..8ea8e5998e 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1973,7 +1973,8 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } // Note: we do not prompt for change when opening items (e.g. textures or note cards) on the marketplace... } - else if (LLMarketplaceData::instance().isInActiveFolder(viewModel->getUUID())) + else if (LLMarketplaceData::instance().isInActiveFolder(viewModel->getUUID()) || + LLMarketplaceData::instance().isListedAndActive(viewModel->getUUID())) { // If item is in active listing, further confirmation is required if ((("cut" == action) || ("delete" == action)) && (LLMarketplaceData::instance().isListed(viewModel->getUUID()) || LLMarketplaceData::instance().isVersionFolder(viewModel->getUUID()))) -- cgit v1.2.3 From 6ab1e773d55b9dbe4a0af161ac194536a5892904 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 22 Aug 2014 00:18:00 -0700 Subject: DD-122 : WIP : Raise error when trying to list something that is empty or has empty stock folders. --- indra/newview/llinventoryfunctions.cpp | 35 ++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 8ea8e5998e..59fdb19d90 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1454,17 +1454,40 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ type = (LLInventoryType::EType)(i); } } - // If we have no items in there (only folders) -> all OK + // If we have no items in there (only folders or empty), analyze a bit further if (count == 0) { - // We warn if there's really nothing in the folder (may be it's a mistake or an under construction listing) - if ((cat_array->size() == 0) && cb) + if (cat_array->size() == 0) { - std::string message = indent + LLTrans::getString("Marketplace Validation Warning Empty") + cat->getName(); - cb(message,LLError::LEVEL_WARN); + // If this is an empty version folder (not even folders), raise an error + if (depth == 2) + { + result = false; + if (cb) + { + std::string message = indent + LLTrans::getString("Marketplace Validation Error Empty Version") + cat->getName(); + cb(message,LLError::LEVEL_ERROR); + } + } + // If this is a legit but empty stock folder, raise an error + else if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)) + { + result = false; + if (cb) + { + std::string message = indent + LLTrans::getString("Marketplace Validation Error Empty Stock") + cat->getName(); + cb(message,LLError::LEVEL_ERROR); + } + } + else if (cb) + { + // We warn if there's nothing in a regular folder (may be it's an under construction listing) + std::string message = indent + LLTrans::getString("Marketplace Validation Warning Empty") + cat->getName(); + cb(message,LLError::LEVEL_WARN); + } } } - // If we have one kind only, in the correct folder type at the right depth -> all OK + // If we have a single type of items of the right type in the right place, we're done else if ((count == 1) && (((type == LLInventoryType::IT_COUNT) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)))) { // Done with that folder! -- cgit v1.2.3 From c4ad85ecb9c85cdbedec6c297ae3ab2bc5eb554b Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sat, 23 Aug 2014 14:46:59 -0700 Subject: DD-19 : WIP : Cleaned up marketplace validation UI as requested per Producer --- indra/newview/llinventoryfunctions.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 59fdb19d90..8833d72dfa 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1364,7 +1364,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { if (cb) { - std::string message = LLTrans::getString("Marketplace Validation Intro") + cat->getName(); + std::string message = cat->getName() + LLTrans::getString("Marketplace Validation Intro"); cb(message,LLError::LEVEL_INFO); } std::string message; @@ -1373,7 +1373,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ result = false; if (cb) { - message = LLTrans::getString("Marketplace Validation Error") + message; + message = cat->getName() + LLTrans::getString("Marketplace Validation Error") + message; cb(message,LLError::LEVEL_ERROR); } } @@ -1393,7 +1393,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName()); if (cb) { - std::string message = indent + LLTrans::getString("Marketplace Validation Warning Stock") + cat->getName(); + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning Stock"); cb(message,LLError::LEVEL_WARN); } LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); @@ -1429,7 +1429,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ result = false; if (cb) { - std::string message = indent + LLTrans::getString("Marketplace Validation Error") + error_msg + " : " + viewer_inv_item->getName(); + std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + error_msg; cb(message,LLError::LEVEL_ERROR); } continue; @@ -1465,7 +1465,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ result = false; if (cb) { - std::string message = indent + LLTrans::getString("Marketplace Validation Error Empty Version") + cat->getName(); + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Empty Version"); cb(message,LLError::LEVEL_ERROR); } } @@ -1475,14 +1475,14 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ result = false; if (cb) { - std::string message = indent + LLTrans::getString("Marketplace Validation Error Empty Stock") + cat->getName(); + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Empty Stock"); cb(message,LLError::LEVEL_ERROR); } } else if (cb) { // We warn if there's nothing in a regular folder (may be it's an under construction listing) - std::string message = indent + LLTrans::getString("Marketplace Validation Warning Empty") + cat->getName(); + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning Empty"); cb(message,LLError::LEVEL_WARN); } } @@ -1493,7 +1493,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Done with that folder! if (cb) { - std::string message = indent + LLTrans::getString("Marketplace Validation Log") + cat->getName(); + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); cb(message,LLError::LEVEL_INFO); } } @@ -1512,11 +1512,11 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ std::string message = ""; if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) { - message = indent + LLTrans::getString("Marketplace Validation Warning Create Stock") + viewer_cat->getName(); + message = indent + viewer_cat->getName() + LLTrans::getString("Marketplace Validation Warning Create Stock"); } else { - message = indent + LLTrans::getString("Marketplace Validation Warning Create Version") + viewer_cat->getName(); + message = indent + viewer_cat->getName() + LLTrans::getString("Marketplace Validation Warning Create Version"); } cb(message,LLError::LEVEL_WARN); } @@ -1527,7 +1527,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); if (cb) { - std::string message = indent + LLTrans::getString("Marketplace Validation Warning Move") + viewer_inv_item->getName(); + std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Move"); cb(message,LLError::LEVEL_WARN); } gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); @@ -1543,7 +1543,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Remove the current folder if it ends up empty if (cb) { - std::string message = indent + LLTrans::getString("Marketplace Validation Warning Delete") + viewer_cat->getName(); + std::string message = indent + viewer_cat->getName() + LLTrans::getString("Marketplace Validation Warning Delete"); cb(message,LLError::LEVEL_WARN); } gInventory.removeCategory(cat->getUUID()); -- cgit v1.2.3 From 2631d6f81717a0f6be0e5adba58ddddcd826b721 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 25 Aug 2014 11:30:46 -0700 Subject: DD-105 : WIP : Use one single mechanism for marking folders being updated by SLM --- indra/newview/llinventoryfunctions.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 8833d72dfa..55333923f9 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -175,8 +175,17 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc // Update all descendents starting from the listing root update_marketplace_folder_hierarchy(listing_uuid); } - else if (depth < 0) + else if (depth == 0) { + // If this is the marketplace listings root itself, update all descendents + if (gInventory.getCategory(cur_uuid)) + { + update_marketplace_folder_hierarchy(cur_uuid); + } + } + else + { + // If the folder is outside the marletplace listings root, clear its SLM data if needs be if (perform_consistency_enforcement && LLMarketplaceData::instance().isListed(cur_uuid)) { LL_INFOS("SLM") << "Disassociate as the listing folder is not under the marketplace folder anymore!!" << LL_ENDL; -- cgit v1.2.3 From d6defce1a1cad39c3a65e4ea1674f34c276d0aeb Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 25 Aug 2014 23:56:34 -0700 Subject: DD-19 : Print errors in bold, sort folders alphabetically, simplify log text when no errors --- indra/newview/llinventoryfunctions.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 55333923f9..58a10fe180 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1353,6 +1353,11 @@ bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU // This function does no deletion of listings but a mere audit and raises issues to the user (through the // optional callback cb). It also returns a boolean, true if things validate, false if issues are raised. // The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders. +bool sort_alpha(const LLViewerInventoryCategory* cat1, const LLViewerInventoryCategory* cat2) +{ + return cat1->getName().compare(cat2->getName()) < 0; +} + bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb) { // Folder is valid unless issue is raised @@ -1569,7 +1574,9 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Recursion : Perform the same validation on each nested folder LLInventoryModel::cat_array_t cat_array_copy = *cat_array; - + // Sort the folders in alphabetical order first + std::sort(cat_array_copy.begin(), cat_array_copy.end(), sort_alpha); + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) { LLInventoryCategory* category = *iter; -- cgit v1.2.3 From a5afdf0b9715d677ce49e24aea96c002e85e3769 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 31 Aug 2014 21:16:34 -0700 Subject: DD-179 : Return no listing for a lone object lost under the marketplace listing root --- indra/newview/llinventoryfunctions.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 58a10fe180..6986ac664f 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -841,8 +841,20 @@ S32 depth_nesting_in_marketplace(LLUUID cur_uuid) // Returns the UUID of the marketplace listing this object is in LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth) { + if (depth < 1) + { + // For objects outside the marketplace listings root (or root itself), we return a NULL UUID + return LLUUID::null; + } + else if (depth == 1) + { + // Just under the root, we return the passed UUID itself if it's a folder, NULL otherwise (not a listing) + LLViewerInventoryCategory* cat = gInventory.getCategory(cur_uuid); + return (cat ? cur_uuid : LLUUID::null); + } + + // depth > 1 LLInventoryObject* cur_object = gInventory.getObject(cur_uuid); - cur_uuid = (depth < 1 ? LLUUID::null : cur_uuid); while (depth > 1) { depth--; -- cgit v1.2.3 From 5b1f6d23be13d5a0879b06d5c11f333c68bc132b Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 2 Sep 2014 21:52:31 -0700 Subject: DD-106 : WIP : Use a single atomic SLM call for association and unlisting. Updating status on source and destination working. --- indra/newview/llinventoryfunctions.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 6986ac664f..3925bcda02 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -153,6 +153,11 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc // is limited to 4. // We also take care of degenerated cases so we don't update all folders in the inventory by mistake. + if (cur_uuid.isNull()) + { + return; + } + // Grab marketplace listing data for this item S32 depth = depth_nesting_in_marketplace(cur_uuid); if (depth > 0) -- cgit v1.2.3 From 8f119c04d484546d73fa906e8f6bd4018e2e6162 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 3 Sep 2014 22:06:04 -0700 Subject: DD-179 : Avoid creating folders named Marketplace Listings when doing audit --- indra/newview/llinventoryfunctions.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 3925bcda02..ab370d6a63 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1537,21 +1537,23 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { // Create a new folder LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); + LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); + std::string folder_name = (depth > 1 ? viewer_cat->getName() : viewer_inv_item->getName()); LLFolderType::EType new_folder_type = (i == LLInventoryType::IT_COUNT ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); if (cb) { std::string message = ""; if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) { - message = indent + viewer_cat->getName() + LLTrans::getString("Marketplace Validation Warning Create Stock"); + message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Stock"); } else { - message = indent + viewer_cat->getName() + LLTrans::getString("Marketplace Validation Warning Create Version"); + message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Version"); } cb(message,LLError::LEVEL_WARN); } - LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, viewer_cat->getName()); + LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, folder_name); // Move each item to the new folder while (!items_vector[i].empty()) { -- cgit v1.2.3 From e9a0b933957d9a620011c43aa37f4c5ee5a74c2e Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 22 Sep 2014 09:27:15 -0700 Subject: DD-19 : WIP : Tweak Validation messages as required by producer --- indra/newview/llinventoryfunctions.cpp | 108 ++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 41 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ab370d6a63..dca8cabc73 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1375,7 +1375,7 @@ bool sort_alpha(const LLViewerInventoryCategory* cat1, const LLViewerInventoryCa return cat1->getName().compare(cat2->getName()) < 0; } -bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb) +bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy) { // Folder is valid unless issue is raised bool result = true; @@ -1391,46 +1391,51 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ return result; } + std::string indent; + for (int i = 1; i < depth; i++) + { + indent += " "; + } + if (depth == 1) { if (cb) { - std::string message = cat->getName() + LLTrans::getString("Marketplace Validation Intro"); + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Intro"); cb(message,LLError::LEVEL_INFO); } + } + else if (depth == 2) + { std::string message; if (!can_move_folder_to_marketplace(cat, cat, cat, message, 0)) { result = false; if (cb) { - message = cat->getName() + LLTrans::getString("Marketplace Validation Error") + message; + message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error") + message; cb(message,LLError::LEVEL_ERROR); } } } - std::string indent; - for (int i = 1; i < depth; i++) - { - indent += " "; - } - 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()); if (cb) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning Stock"); cb(message,LLError::LEVEL_WARN); } - LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); - gInventory.changeCategoryParent(viewer_cat, folder_uuid, false); - result &= validate_marketplacelistings(new_cat, cb); - return result; + if (fix_hierarchy) + { + // Nest the stock folder one level deeper in a normal folder and restart from there + LLUUID parent_uuid = cat->getParentUUID(); + 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); + result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy); + return result; + } } LLInventoryModel::cat_array_t* cat_array; @@ -1535,39 +1540,60 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { if (!items_vector[i].empty()) { - // Create a new folder - LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); - LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); - std::string folder_name = (depth > 1 ? viewer_cat->getName() : viewer_inv_item->getName()); - LLFolderType::EType new_folder_type = (i == LLInventoryType::IT_COUNT ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); - if (cb) + if (fix_hierarchy) { - std::string message = ""; - if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) + // Create a new folder + LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); + LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); + std::string folder_name = (depth > 1 ? viewer_cat->getName() : viewer_inv_item->getName()); + LLFolderType::EType new_folder_type = (i == LLInventoryType::IT_COUNT ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); + if (cb) { - message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Stock"); + std::string message = ""; + if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) + { + message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Stock"); + } + else + { + message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Version"); + } + cb(message,LLError::LEVEL_WARN); } - else + LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, folder_name); + // Move each item to the new folder + while (!items_vector[i].empty()) { - message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Version"); + LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); + if (cb) + { + std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Move"); + cb(message,LLError::LEVEL_WARN); + } + gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); + items_vector[i].pop_back(); } - cb(message,LLError::LEVEL_WARN); + update_marketplace_category(folder_uuid); + gInventory.notifyObservers(); } - LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, folder_name); - // Move each item to the new folder - while (!items_vector[i].empty()) + else if (i != LLInventoryType::IT_COUNT) { - LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); - if (cb) + // Report about misplaced no-copy items + while (!items_vector[i].empty()) { - std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Move"); - cb(message,LLError::LEVEL_WARN); + LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); + if (cb) + { + std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Stock Item"); + cb(message,LLError::LEVEL_WARN); + } + items_vector[i].pop_back(); } - gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); - items_vector[i].pop_back(); +// LLStringUtil::format_map_t args; +// U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"); +// args["[AMOUNT]"] = llformat("%d",amount); +// tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels", args); } - update_marketplace_category(folder_uuid); - gInventory.notifyObservers(); } } // Clean up @@ -1599,7 +1625,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) { LLInventoryCategory* category = *iter; - result &= validate_marketplacelistings(category, cb); + result &= validate_marketplacelistings(category, cb, fix_hierarchy); } return result; -- cgit v1.2.3 From c94191b2d2d5a11cb6d8f4d90526bf280aa77926 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 22 Sep 2014 17:54:05 -0700 Subject: DD-19 : Fix all the subcases signaled by QA and producers, though not with the same messages. Needs validation by producer. --- indra/newview/llinventoryfunctions.cpp | 115 +++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 42 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index dca8cabc73..9bb900de1f 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1123,7 +1123,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve // Returns true if inv_cat can be dropped in dest_folder, a folder nested in marketplace listings (or merchant inventory) under the root_folder root // If returns is false, tooltip_msg contains an error message to display to the user (localized and all). // bundle_size is the amount of sibling items that are getting moved to the marketplace at the same time. -bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size) +bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size, bool check_items) { bool accept = true; @@ -1197,7 +1197,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn } // Now check that each item in the folder can be moved in the marketplace - if (accept) + if (accept && check_items) { for (S32 i=0; i < descendent_items.size(); ++i) { @@ -1396,19 +1396,12 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { indent += " "; } - - if (depth == 1) - { - if (cb) - { - std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Intro"); - cb(message,LLError::LEVEL_INFO); - } - } - else if (depth == 2) + + if (depth == 2) { + // Check out that version folders are marketplace ready std::string message; - if (!can_move_folder_to_marketplace(cat, cat, cat, message, 0)) + if (!can_move_folder_to_marketplace(cat, cat, cat, message, 0, false)) { result = false; if (cb) @@ -1452,6 +1445,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ 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 + bool has_bad_items = false; 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++) { @@ -1462,8 +1456,8 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ std::string error_msg; if (!can_move_to_marketplace(item, error_msg, false)) { - result = false; - if (cb) + has_bad_items = true; + if (cb && fix_hierarchy) { std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + error_msg; cb(message,LLError::LEVEL_ERROR); @@ -1491,11 +1485,11 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } } // If we have no items in there (only folders or empty), analyze a bit further - if (count == 0) + if ((count == 0) && !has_bad_items) { if (cat_array->size() == 0) { - // If this is an empty version folder (not even folders), raise an error + // If this is an empty version folder, raise an error if (depth == 2) { result = false; @@ -1522,12 +1516,21 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ cb(message,LLError::LEVEL_WARN); } } + else + { + // Done with that folder : Print out the folder name unless we already found an error here + if (cb && result && (depth >= 1)) + { + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); + cb(message,LLError::LEVEL_INFO); + } + } } // If we have a single type of items of the right type in the right place, we're done - else if ((count == 1) && (((type == LLInventoryType::IT_COUNT) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)))) + else if ((count == 1) && !has_bad_items && (((type == LLInventoryType::IT_COUNT) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)))) { - // Done with that folder! - if (cb) + // Done with that folder : Print out the folder name unless we already found an error here + if (cb && result && (depth >= 1)) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); cb(message,LLError::LEVEL_INFO); @@ -1535,12 +1538,12 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } else { - // Create one folder per vector at the right depth and of the right type - for (S32 i = 0; i <= LLInventoryType::IT_COUNT; i++) + if (fix_hierarchy && !has_bad_items) { - if (!items_vector[i].empty()) + // Create one folder per vector at the right depth and of the right type + for (S32 i = 0; i <= LLInventoryType::IT_COUNT; i++) { - if (fix_hierarchy) + if (!items_vector[i].empty()) { // Create a new folder LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); @@ -1576,23 +1579,51 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ update_marketplace_category(folder_uuid); gInventory.notifyObservers(); } - else if (i != LLInventoryType::IT_COUNT) + } + } + else if (cb) + { + // We are not fixing the hierarchy but reporting problems, report everything we can find + // Print the folder name + if (result && (depth >= 1)) + { + if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (count >= 2)) { - // Report about misplaced no-copy items - while (!items_vector[i].empty()) - { - LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); - if (cb) - { - std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Stock Item"); - cb(message,LLError::LEVEL_WARN); - } - items_vector[i].pop_back(); - } -// LLStringUtil::format_map_t args; -// U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"); -// args["[AMOUNT]"] = llformat("%d",amount); -// tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels", args); + // Report if a stock folder contains a mix of items + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning Mixed Stock"); + cb(message,LLError::LEVEL_WARN); + } + else + { + // Simply print the folder name + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); + cb(message,LLError::LEVEL_INFO); + } + } + // Scan each item and report if there's a problem + 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; + std::string error_msg; + if (!can_move_to_marketplace(item, error_msg, false)) + { + // Report items that shouldn't be there to start with + std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + error_msg; + cb(message,LLError::LEVEL_ERROR); + } + else if ((!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) && (folder_type != LLFolderType::FT_MARKETPLACE_STOCK)) + { + // Report stock items that are misplaced + std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Stock Item"); + cb(message,LLError::LEVEL_WARN); + } + else if (depth == 1) + { + // Report items not wrapped in version folder + std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Unwrapped Item"); + cb(message,LLError::LEVEL_WARN); } } } @@ -1607,7 +1638,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } gInventory.removeCategory(cat->getUUID()); gInventory.notifyObservers(); - return result; + return result && !has_bad_items; } else { @@ -1628,7 +1659,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ result &= validate_marketplacelistings(category, cb, fix_hierarchy); } - return result; + return result && !has_bad_items; } ///---------------------------------------------------------------------------- -- cgit v1.2.3 From 3b6bb86a1eafeb2bab77b28829f796229fcbae77 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 22 Sep 2014 18:20:53 -0700 Subject: DD-19 : WIP : Cleanup comments --- indra/newview/llinventoryfunctions.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 9bb900de1f..eb218b6a51 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1380,28 +1380,29 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Folder is valid unless issue is raised bool result = true; - // Special case a stock folder depth issue + // Get the type and the depth of the folder LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); const LLFolderType::EType folder_type = cat->getPreferredType(); S32 depth = depth_nesting_in_marketplace(cat->getUUID()); if (depth < 0) { // If the folder is not under the marketplace listings root, validation should not be applied - // *TODO: Should we call update_marketplace_category(cat->getUUID()) ? return result; } + // Set the indentation for print output (typically, audit button in marketplace folder floater) std::string indent; for (int i = 1; i < depth; i++) { indent += " "; } + // Check out that version folders are marketplace ready if (depth == 2) { - // Check out that version folders are marketplace ready std::string message; - if (!can_move_folder_to_marketplace(cat, cat, cat, message, 0, false)) + // Note: if we fix the hierarchy, we want to check the items individually, hence the last argument here + if (!can_move_folder_to_marketplace(cat, cat, cat, message, 0, fix_hierarchy)) { result = false; if (cb) @@ -1412,6 +1413,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } } + // Check out that stock folders are at the right level if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth <= 2)) { if (cb) @@ -1452,7 +1454,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ LLInventoryItem* item = *iter; LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) item; - // Skip items that shouldn't be there to start with, raise an error message for those + // Test but skip items that shouldn't be there to start with, raise an error message for those std::string error_msg; if (!can_move_to_marketplace(item, error_msg, false)) { @@ -1473,6 +1475,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } items_vector[type].push_back(viewer_inv_item); } + // How many types of folders? Which type is it if only one? S32 count = 0; LLInventoryType::EType type = LLInventoryType::IT_COUNT; @@ -1484,6 +1487,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ type = (LLInventoryType::EType)(i); } } + // If we have no items in there (only folders or empty), analyze a bit further if ((count == 0) && !has_bad_items) { @@ -1627,6 +1631,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } } } + // Clean up if (viewer_cat->getDescendentCount() == 0) { -- cgit v1.2.3 From 10b8f8952321eee959f1b4cf2255782c61683900 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 23 Sep 2014 13:57:43 -0700 Subject: DD-19 : Fixed messages in Validation as requested by producers --- indra/newview/llinventoryfunctions.cpp | 36 ++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index eb218b6a51..b4a07e20f2 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1407,7 +1407,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ result = false; if (cb) { - message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error") + message; + message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error") + " " + message; cb(message,LLError::LEVEL_ERROR); } } @@ -1416,13 +1416,13 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Check out that stock folders are at the right level if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth <= 2)) { - if (cb) - { - std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning Stock"); - cb(message,LLError::LEVEL_WARN); - } if (fix_hierarchy) { + if (cb) + { + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning") + " " + LLTrans::getString("Marketplace Validation Warning Stock"); + cb(message,LLError::LEVEL_WARN); + } // Nest the stock folder one level deeper in a normal folder and restart from there LLUUID parent_uuid = cat->getParentUUID(); LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName()); @@ -1431,6 +1431,15 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy); return result; } + else + { + result = false; + if (cb) + { + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error") + " " + LLTrans::getString("Marketplace Validation Warning Stock"); + cb(message,LLError::LEVEL_ERROR); + } + } } LLInventoryModel::cat_array_t* cat_array; @@ -1461,7 +1470,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ has_bad_items = true; if (cb && fix_hierarchy) { - std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + error_msg; + std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + " " + error_msg; cb(message,LLError::LEVEL_ERROR); } continue; @@ -1594,8 +1603,9 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (count >= 2)) { // Report if a stock folder contains a mix of items - std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning Mixed Stock"); - cb(message,LLError::LEVEL_WARN); + result = false; + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Mixed Stock"); + cb(message,LLError::LEVEL_ERROR); } else { @@ -1614,14 +1624,16 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (!can_move_to_marketplace(item, error_msg, false)) { // Report items that shouldn't be there to start with - std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + error_msg; + result = false; + std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + " " + error_msg; cb(message,LLError::LEVEL_ERROR); } else if ((!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) && (folder_type != LLFolderType::FT_MARKETPLACE_STOCK)) { // Report stock items that are misplaced - std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Stock Item"); - cb(message,LLError::LEVEL_WARN); + result = false; + std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error Stock Item"); + cb(message,LLError::LEVEL_ERROR); } else if (depth == 1) { -- cgit v1.2.3 From 78f1938fafad94e94427c51e97c751a4c1244862 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 23 Sep 2014 22:50:01 -0700 Subject: DD-110 : Prevent paste of Library items into the marketplace --- indra/newview/llinventoryfunctions.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index b4a07e20f2..31c88b39fc 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -984,7 +984,14 @@ bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg tooltip_msg = LLTrans::getString("TooltipOutboxWorn"); return false; } - + + // Check library status: library items cannot be put on the marketplace + if (!gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.getRootFolderID())) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + return false; + } + // Check type: for the moment, calling cards cannot be put on the marketplace bool calling_card = (LLAssetType::AT_CALLINGCARD == inv_item->getType()); if (calling_card) @@ -1083,7 +1090,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve LLViewerInventoryCategory* view_folder = dynamic_cast(dest_folder); bool accept = (view_folder && view_folder->acceptItem(inv_item)); - // Check that the item has the right type and persimssions to be sold on the marketplace + // Check that the item has the right type and permissions to be sold on the marketplace if (accept) { accept = can_move_to_marketplace(inv_item, tooltip_msg, true); -- cgit v1.2.3 From 896f48229e577b1bcf94f2cb80d73a6bf1a9330c Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 28 Sep 2014 17:30:48 -0700 Subject: DD-211 : Verify that the items have the right permissions when dropping in a stock folder, add an adequate message when failing to drop in a stock folder. --- indra/newview/llinventoryfunctions.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 31c88b39fc..85a2e7b37b 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1089,6 +1089,10 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve // Check stock folder type matches item type in marketplace listings or merchant outbox (even if of no use there for the moment) LLViewerInventoryCategory* view_folder = dynamic_cast(dest_folder); bool accept = (view_folder && view_folder->acceptItem(inv_item)); + if (!accept) + { + tooltip_msg = LLTrans::getString("TooltipOutboxMixedStock"); + } // Check that the item has the right type and permissions to be sold on the marketplace if (accept) -- cgit v1.2.3 From 31d5383417000738a29c8f664124e140b1afce5d Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sat, 4 Oct 2014 22:15:53 -0700 Subject: DD-213 : Differentiate pasting from moving when verifying if action is legit. Also takes into account moving within the same version folder when moving items --- indra/newview/llinventoryfunctions.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 110806f41b..1ca658ebd2 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1084,7 +1084,7 @@ bool has_correct_permissions_for_sale(LLInventoryCategory* cat, std::string& err // Returns true if inv_item can be dropped in dest_folder, a folder nested in marketplace listings (or merchant inventory) under the root_folder root // If returns is false, tooltip_msg contains an error message to display to the user (localized and all). // bundle_size is the amount of sibling items that are getting moved to the marketplace at the same time. -bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryItem* inv_item, std::string& tooltip_msg, S32 bundle_size) +bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryItem* inv_item, std::string& tooltip_msg, S32 bundle_size, bool from_paste) { // Check stock folder type matches item type in marketplace listings or merchant outbox (even if of no use there for the moment) LLViewerInventoryCategory* view_folder = dynamic_cast(dest_folder); @@ -1110,6 +1110,12 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve if (version_folder) { + if (!from_paste && gInventory.isObjectDescendentOf(inv_item->getUUID(), version_folder->getUUID())) + { + // Clear those counts or they will be counted twice because we're already inside the version category + existing_item_count = 0; + } + LLInventoryModel::cat_array_t existing_categories; LLInventoryModel::item_array_t existing_items; @@ -1134,7 +1140,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve // Returns true if inv_cat can be dropped in dest_folder, a folder nested in marketplace listings (or merchant inventory) under the root_folder root // If returns is false, tooltip_msg contains an error message to display to the user (localized and all). // bundle_size is the amount of sibling items that are getting moved to the marketplace at the same time. -bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size, bool check_items) +bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size, bool check_items, bool from_paste) { bool accept = true; @@ -1171,7 +1177,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn if (version_folder) { - if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), version_folder->getUUID())) + if (!from_paste && gInventory.isObjectDescendentOf(inv_cat->getUUID(), version_folder->getUUID())) { // Clear those counts or they will be counted twice because we're already inside the version category dragged_folder_count = 0; -- cgit v1.2.3 From 828f47892151737bd5afe39b19c83d2b04fe9192 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 3 Nov 2014 13:18:06 -0800 Subject: DD-263 : Update the count on hand on SLM in various situation where stock count changes (activate, drag/drop, associate, etc...) --- indra/newview/llinventoryfunctions.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 1ca658ebd2..ac1efa5471 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -177,6 +177,11 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc } } + // Check if the count on hand needs to be updated on SLM + if (compute_stock_count(listing_uuid) != LLMarketplaceData::instance().getCountOnHand(listing_uuid)) + { + LLMarketplaceData::instance().updateCountOnHand(listing_uuid); + } // Update all descendents starting from the listing root update_marketplace_folder_hierarchy(listing_uuid); } -- cgit v1.2.3 From 70a2956f584f554d1f0fd3b12890671ac47ea1f2 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 10 Nov 2014 22:14:50 -0800 Subject: DD-276, DD-280 : Serialize update count on SLM by preventing sending update while previous transaction not completed --- indra/newview/llinventoryfunctions.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ac1efa5471..461631288c 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -178,7 +178,8 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc } // Check if the count on hand needs to be updated on SLM - if (compute_stock_count(listing_uuid) != LLMarketplaceData::instance().getCountOnHand(listing_uuid)) + if (!LLMarketplaceData::instance().isUpdating(listing_uuid) && + (compute_stock_count(listing_uuid) != LLMarketplaceData::instance().getCountOnHand(listing_uuid))) { LLMarketplaceData::instance().updateCountOnHand(listing_uuid); } @@ -195,7 +196,7 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc } else { - // If the folder is outside the marletplace listings root, clear its SLM data if needs be + // If the folder is outside the marketplace listings root, clear its SLM data if needs be if (perform_consistency_enforcement && LLMarketplaceData::instance().isListed(cur_uuid)) { LL_INFOS("SLM") << "Disassociate as the listing folder is not under the marketplace folder anymore!!" << LL_ENDL; -- cgit v1.2.3 From d0afd691526a51a99223d056398c1ede5bb93494 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 16 Nov 2014 13:30:01 -0800 Subject: DD-284 : Separate no copy from copy items when counting items in marketplace listings folders --- indra/newview/llinventoryfunctions.cpp | 36 +++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 461631288c..e5a515383e 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -100,6 +100,36 @@ void update_folder_cb(const LLUUID& dest_folder) gInventory.notifyObservers(); } +// Helper function : Count only the copyable items, i.e. skip the stock items (which are no copy) +S32 count_copyable_items(LLInventoryModel::item_array_t& items) +{ + S32 count = 0; + for (LLInventoryModel::item_array_t::const_iterator it = items.begin(); it != items.end(); ++it) + { + LLViewerInventoryItem* item = *it; + if (item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + count++; + } + } + return count; +} + +// Helper function : Count the number of stock folders +S32 count_stock_folders(LLInventoryModel::cat_array_t& categories) +{ + S32 count = 0; + for (LLInventoryModel::cat_array_t::const_iterator it = categories.begin(); it != categories.end(); ++it) + { + LLInventoryCategory* cat = *it; + if (cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + count++; + } + } + return count; +} + // Generates a string containing the path to the item specified by // item_id. void append_path(const LLUUID& id, std::string& path) @@ -1127,7 +1157,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve gInventory.collectDescendents(version_folder->getUUID(), existing_categories, existing_items, FALSE); - existing_item_count += existing_items.size(); + existing_item_count += count_copyable_items(existing_items) + count_stock_folders(existing_categories); } if (existing_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) @@ -1177,7 +1207,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn gInventory.collectDescendents(inv_cat->getUUID(), descendent_categories, descendent_items, FALSE); int dragged_folder_count = descendent_categories.size() + bundle_size; // Note: We assume that we're moving a bunch of folders in. That might be wrong... - int dragged_item_count = descendent_items.size(); + int dragged_item_count = count_copyable_items(descendent_items) + count_stock_folders(descendent_categories); int existing_item_count = 0; int existing_folder_count = 0; @@ -1196,7 +1226,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn gInventory.collectDescendents(version_folder->getUUID(), existing_categories, existing_items, FALSE); existing_folder_count += existing_categories.size(); - existing_item_count += existing_items.size(); + existing_item_count += count_copyable_items(existing_items) + count_stock_folders(existing_categories); } const int total_folder_count = existing_folder_count + dragged_folder_count; -- cgit v1.2.3 From 43745ce2714eca8dce95e08a89eeb3c278b0be3f Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 16 Nov 2014 14:26:33 -0800 Subject: DD-281 : Do not unlist listings that go out of stock --- indra/newview/llinventoryfunctions.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index e5a515383e..a11339358a 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1565,14 +1565,13 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ cb(message,LLError::LEVEL_ERROR); } } - // If this is a legit but empty stock folder, raise an error else if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)) { - result = false; + // If this is a legit but empty stock folder, warn only (listing must stay searchable when empty) if (cb) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Empty Stock"); - cb(message,LLError::LEVEL_ERROR); + cb(message,LLError::LEVEL_WARN); } } else if (cb) -- cgit v1.2.3 From 3513633d86b89127e8d19cc5906ab614bb051560 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 18 Nov 2014 14:54:36 -0800 Subject: DD-264 : Do not unlist listings when version folder is emptied --- indra/newview/llinventoryfunctions.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index a11339358a..d1acbee533 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1555,19 +1555,18 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { if (cat_array->size() == 0) { - // If this is an empty version folder, raise an error if (depth == 2) { - result = false; + // If this is an empty version folder, warn only (listing won't be delivered by AIS, but only AIS should unlist) if (cb) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Empty Version"); - cb(message,LLError::LEVEL_ERROR); + cb(message,LLError::LEVEL_WARN); } } else if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)) { - // If this is a legit but empty stock folder, warn only (listing must stay searchable when empty) + // If this is a legit but empty stock folder, warn only (listing must stay searchable when out of stock) if (cb) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Empty Stock"); -- cgit v1.2.3 From 02c535276404faca30d626b311967e2888052843 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 23 Nov 2014 14:39:01 -0800 Subject: DD-284 : Do not count incoming stock items if dropped in a stock folder --- indra/newview/llinventoryfunctions.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index d1acbee533..71a5ad412e 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1124,6 +1124,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve { // Check stock folder type matches item type in marketplace listings or merchant outbox (even if of no use there for the moment) LLViewerInventoryCategory* view_folder = dynamic_cast(dest_folder); + bool move_in_stock = (view_folder && (view_folder->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK)); bool accept = (view_folder && view_folder->acceptItem(inv_item)); if (!accept) { @@ -1139,7 +1140,8 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve // Check that the total amount of items won't violate the max limit on the marketplace if (accept) { - int existing_item_count = bundle_size; + // If the dest folder is a stock folder, we do not count the incoming items toward the total (stock items are seen as one) + int existing_item_count = (move_in_stock ? 0 : bundle_size); // Get the version folder: that's where the counts start from const LLViewerInventoryCategory * version_folder = ((root_folder && (root_folder != dest_folder)) ? gInventory.getFirstDescendantOf(root_folder->getUUID(), dest_folder->getUUID()) : NULL); -- cgit v1.2.3 From 072ac0e5a66b43d345d1767055518e8ce1b66a43 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 23 Nov 2014 17:04:02 -0800 Subject: DD-286 : We report if a stock folder contains subfolders, we do not count subfolders in stock count and we move subfolders out on drop --- indra/newview/llinventoryfunctions.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 71a5ad412e..ddcaf9d2bd 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -916,9 +916,12 @@ S32 compute_stock_count(LLUUID 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: stock folders are *not* supposed to have nested subfolders so we stop recursion here but we count only items (subfolders will be ignored) // Note: we *always* give a stock count for stock folders, it's useful even if the listing is unassociated - return cat->getDescendentCount(); + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat_uuid,cat_array,item_array); + return item_array->size(); } // Grab marketplace data for this folder @@ -1593,7 +1596,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } } // If we have a single type of items of the right type in the right place, we're done - else if ((count == 1) && !has_bad_items && (((type == LLInventoryType::IT_COUNT) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)))) + else if ((count == 1) && !has_bad_items && (((type == LLInventoryType::IT_COUNT) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2) && (cat_array->size() == 0)))) { // Done with that folder : Print out the folder name unless we already found an error here if (cb && result && (depth >= 1)) @@ -1646,6 +1649,18 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ gInventory.notifyObservers(); } } + // Stock folder should have no sub folder so reparent those up + if (folder_type == LLFolderType::FT_MARKETPLACE_STOCK) + { + LLUUID parent_uuid = cat->getParentUUID(); + 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++) + { + LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (*iter); + gInventory.changeCategoryParent(viewer_cat, parent_uuid, false); + // Note : those reparented folders will be recursively visited and validated at the end of this function + } + } } else if (cb) { @@ -1660,6 +1675,13 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Mixed Stock"); cb(message,LLError::LEVEL_ERROR); } + else if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (cat_array->size() != 0)) + { + // Report if a stock folder contains subfolders + result = false; + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Subfolder In Stock"); + cb(message,LLError::LEVEL_ERROR); + } else { // Simply print the folder name -- cgit v1.2.3 From e8ea398e123be29227275e8ca5b1d2d0ce7f1e4f Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 22 Dec 2014 16:33:47 -0800 Subject: DD-282 : Suppress Unassociate menu item. Confirm when cutting, deleting or moving a listing --- indra/newview/llinventoryfunctions.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ddcaf9d2bd..1a75ebbbac 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2194,6 +2194,12 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); return; } + // Cutting or deleting a whole listing needs confirmation as SLM will be archived and inaccessible to the user + else if (LLMarketplaceData::instance().isListed(viewModel->getUUID()) && (("cut" == action) || ("delete" == action))) + { + LLNotificationsUtil::add("ConfirmListingCutOrDelete", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); + return; + } } } -- cgit v1.2.3 From edbd73b8364f66bfce24701db5cb160ecc89e37d Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 26 Dec 2014 17:37:48 -0800 Subject: DD-296 : Prompt the user when trying to copy a selection containing nocopy items to the marketplace --- indra/newview/llinventoryfunctions.cpp | 60 +++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 1a75ebbbac..eab9e027b4 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -130,6 +130,53 @@ S32 count_stock_folders(LLInventoryModel::cat_array_t& categories) return count; } +// Helper function : Returns true if the hierarchy contains nocopy items +bool contains_nocopy_items(const LLUUID& id) +{ + LLInventoryCategory* cat = gInventory.getCategory(id); + + if (cat) + { + // Get the content + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(id,cat_array,item_array); + + // Check all the items: returns true upon encountering a nocopy item + for (LLInventoryModel::item_array_t::iterator iter = item_array->begin(); iter != item_array->end(); iter++) + { + LLInventoryItem* item = *iter; + LLViewerInventoryItem * inv_item = (LLViewerInventoryItem *) item; + if (!inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + return true; + } + } + + // Check all the sub folders recursively + for (LLInventoryModel::cat_array_t::iterator iter = cat_array->begin(); iter != cat_array->end(); iter++) + { + LLViewerInventoryCategory* cat = *iter; + if (contains_nocopy_items(cat->getUUID())) + { + return true; + } + } + } + else + { + LLInventoryItem* item = gInventory.getItem(id); + LLViewerInventoryItem * inv_item = (LLViewerInventoryItem *) item; + if (!inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + return true; + } + } + + // Exit without meeting a nocopy item + return false; +} + // Generates a string containing the path to the item specified by // item_id. void append_path(const LLUUID& id, std::string& path) @@ -2199,7 +2246,18 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root { LLNotificationsUtil::add("ConfirmListingCutOrDelete", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); return; - } + } + } + } + // Copying to the marketplace needs confirmation if nocopy items are involved + if (user_confirm && ("copy_to_marketplace_listings" == action)) + { + std::set::iterator set_iter = selected_items.begin(); + LLFolderViewModelItemInventory * viewModel = dynamic_cast((*set_iter)->getViewModelItem()); + if (contains_nocopy_items(viewModel->getUUID())) + { + LLNotificationsUtil::add("ConfirmCopyToMarketplace", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); + return; } } -- cgit v1.2.3 From 6cf5912fd0339d09d9ac441d02c2dade824802ac Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sat, 24 Jan 2015 16:50:56 -0800 Subject: DD-306 : Suppress no issue listings from audit listing dump, add no error message when no error, disable some right click menu items in multiselection cases --- indra/newview/llinventoryfunctions.cpp | 36 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index eab9e027b4..cb41111b6f 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1513,7 +1513,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error") + " " + message; - cb(message,LLError::LEVEL_ERROR); + cb(message,depth,LLError::LEVEL_ERROR); } } } @@ -1526,7 +1526,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning") + " " + LLTrans::getString("Marketplace Validation Warning Stock"); - cb(message,LLError::LEVEL_WARN); + cb(message,depth,LLError::LEVEL_WARN); } // Nest the stock folder one level deeper in a normal folder and restart from there LLUUID parent_uuid = cat->getParentUUID(); @@ -1542,7 +1542,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error") + " " + LLTrans::getString("Marketplace Validation Warning Stock"); - cb(message,LLError::LEVEL_ERROR); + cb(message,depth,LLError::LEVEL_ERROR); } } } @@ -1576,7 +1576,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb && fix_hierarchy) { std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + " " + error_msg; - cb(message,LLError::LEVEL_ERROR); + cb(message,depth,LLError::LEVEL_ERROR); } continue; } @@ -1613,7 +1613,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Empty Version"); - cb(message,LLError::LEVEL_WARN); + cb(message,depth,LLError::LEVEL_WARN); } } else if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)) @@ -1622,14 +1622,14 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Empty Stock"); - cb(message,LLError::LEVEL_WARN); + cb(message,depth,LLError::LEVEL_WARN); } } else if (cb) { // We warn if there's nothing in a regular folder (may be it's an under construction listing) std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning Empty"); - cb(message,LLError::LEVEL_WARN); + cb(message,depth,LLError::LEVEL_WARN); } } else @@ -1638,7 +1638,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb && result && (depth >= 1)) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); - cb(message,LLError::LEVEL_INFO); + cb(message,depth,LLError::LEVEL_INFO); } } } @@ -1649,7 +1649,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb && result && (depth >= 1)) { std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); - cb(message,LLError::LEVEL_INFO); + cb(message,depth,LLError::LEVEL_INFO); } } else @@ -1677,7 +1677,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Version"); } - cb(message,LLError::LEVEL_WARN); + cb(message,depth,LLError::LEVEL_WARN); } LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, folder_name); // Move each item to the new folder @@ -1687,7 +1687,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Move"); - cb(message,LLError::LEVEL_WARN); + cb(message,depth,LLError::LEVEL_WARN); } gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); items_vector[i].pop_back(); @@ -1720,20 +1720,20 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Report if a stock folder contains a mix of items result = false; std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Mixed Stock"); - cb(message,LLError::LEVEL_ERROR); + cb(message,depth,LLError::LEVEL_ERROR); } else if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (cat_array->size() != 0)) { // Report if a stock folder contains subfolders result = false; std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Subfolder In Stock"); - cb(message,LLError::LEVEL_ERROR); + cb(message,depth,LLError::LEVEL_ERROR); } else { // Simply print the folder name std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); - cb(message,LLError::LEVEL_INFO); + cb(message,depth,LLError::LEVEL_INFO); } } // Scan each item and report if there's a problem @@ -1748,20 +1748,20 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Report items that shouldn't be there to start with result = false; std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + " " + error_msg; - cb(message,LLError::LEVEL_ERROR); + cb(message,depth,LLError::LEVEL_ERROR); } else if ((!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) && (folder_type != LLFolderType::FT_MARKETPLACE_STOCK)) { // Report stock items that are misplaced result = false; std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error Stock Item"); - cb(message,LLError::LEVEL_ERROR); + cb(message,depth,LLError::LEVEL_ERROR); } else if (depth == 1) { // Report items not wrapped in version folder std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Unwrapped Item"); - cb(message,LLError::LEVEL_WARN); + cb(message,depth,LLError::LEVEL_WARN); } } } @@ -1773,7 +1773,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (cb) { std::string message = indent + viewer_cat->getName() + LLTrans::getString("Marketplace Validation Warning Delete"); - cb(message,LLError::LEVEL_WARN); + cb(message,depth,LLError::LEVEL_WARN); } gInventory.removeCategory(cat->getUUID()); gInventory.notifyObservers(); -- cgit v1.2.3 From 4fdaa7fc561e9e05751373160434a61151c2b75e Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sun, 25 Jan 2015 17:10:05 -0800 Subject: DD-296 : Disable move and copy to marketplace if limit passed. Improve perf of validate_marketplaceting(). Open marketplace floater on copy or move. String fix. --- indra/newview/llinventoryfunctions.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index cb41111b6f..40eeb01d54 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -724,6 +724,11 @@ void open_outbox() LLFloaterReg::showInstance("outbox"); } +void open_marketplace_listings() +{ + LLFloaterReg::showInstance("marketplace_listings"); +} + // 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) @@ -1468,6 +1473,8 @@ bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU LLNotificationsUtil::add("MerchantPasteFailed", subs); return false; } + + open_marketplace_listings(); return true; } @@ -1480,7 +1487,7 @@ bool sort_alpha(const LLViewerInventoryCategory* cat1, const LLViewerInventoryCa return cat1->getName().compare(cat2->getName()) < 0; } -bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy) +bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy, S32 depth) { // Folder is valid unless issue is raised bool result = true; @@ -1488,11 +1495,17 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Get the type and the depth of the folder LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); const LLFolderType::EType folder_type = cat->getPreferredType(); - S32 depth = depth_nesting_in_marketplace(cat->getUUID()); if (depth < 0) { - // If the folder is not under the marketplace listings root, validation should not be applied - return result; + // If the depth argument was not provided, evaluate the depth directly + depth = depth_nesting_in_marketplace(cat->getUUID()); + } + if (depth < 0) + { + // If the folder is not under the marketplace listings root, we run validation as if it was a listing folder and prevent any hierarchy fix + // This allows the function to be used to pre-validate a folder + depth = 1; + fix_hierarchy = false; } // Set the indentation for print output (typically, audit button in marketplace folder floater) @@ -1533,7 +1546,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ 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); - result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy); + result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1); return result; } else @@ -1795,7 +1808,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) { LLInventoryCategory* category = *iter; - result &= validate_marketplacelistings(category, cb, fix_hierarchy); + result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1); } return result && !has_bad_items; -- cgit v1.2.3 From f1c9536401016052bbee84c6ff178fa0d466bc78 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 27 Jan 2015 23:19:51 -0800 Subject: DD-296 : Add options to move or leave behind no copy items when copying a folder to the marketplace --- indra/newview/llinventoryfunctions.cpp | 60 ++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 13 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 40eeb01d54..97d6bf004b 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -346,7 +346,8 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, - const LLUUID& root_copy_id) + const LLUUID& root_copy_id, + bool move_no_copy_items ) { // Create the initial folder LLUUID new_cat_uuid = gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName()); @@ -366,13 +367,27 @@ void copy_inventory_category(LLInventoryModel* model, { 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(), - cb); + + if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + // If the item is nocopy, we do nothing or, optionally, move it + if (move_no_copy_items) + { + // Reparent the item + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) item; + gInventory.changeItemParent(viewer_inv_item, new_cat_uuid, true); + } + } + else + { + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + new_cat_uuid, + std::string(), + cb); + } } // Copy all the folders @@ -382,7 +397,7 @@ void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* category = *iter; if (category->getUUID() != root_id) { - copy_inventory_category(model, category, new_cat_uuid, root_id); + copy_inventory_category(model, category, new_cat_uuid, root_id, move_no_copy_items); } } } @@ -1351,6 +1366,12 @@ bool 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); + // If we want to copy but the item is no copy, fail silently (this is a common case that doesn't warrant notification) + if (copy && !viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + return false; + } + // 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. std::string error_msg; @@ -1373,7 +1394,7 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && (dest_cat->getPreferredType() != LLFolderType::FT_MARKETPLACE_STOCK)) { - // We need a stock folder + // We need to create a stock folder to move a no copy item dest_folder = gInventory.createNewCategory(dest_folder, LLFolderType::FT_MARKETPLACE_STOCK, viewer_inv_item->getName()); dest_cat = gInventory.getCategory(dest_folder); depth++; @@ -1425,7 +1446,7 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol return true; } -bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy) +bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy, bool move_no_copy_items) { // Check that we have adequate permission on all items being moved. Proceed if we do. std::string error_msg; @@ -1450,7 +1471,7 @@ bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU if (copy) { // Copy the folder - copy_inventory_category(&gInventory, viewer_inv_cat, dest_folder); + copy_inventory_category(&gInventory, viewer_inv_cat, dest_folder, LLUUID::null, move_no_copy_items); } else { @@ -2211,6 +2232,19 @@ void LLInventoryAction::callback_doToSelected(const LLSD& notification, const LL } } +void LLInventoryAction::callback_copySelected(const LLSD& notification, const LLSD& response, class LLInventoryModel* model, class LLFolderView* root, const std::string& action) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) // YES, Move no copy item(s) + { + doToSelected(model, root, "copy_or_move_to_marketplace_listings", FALSE); + } + else if (option == 1) // NO, Don't move no copy item(s) (leave them behind) + { + doToSelected(model, root, "copy_to_marketplace_listings", FALSE); + } +} + void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action, BOOL user_confirm) { std::set selected_items = root->getSelectionList(); @@ -2269,7 +2303,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root LLFolderViewModelItemInventory * viewModel = dynamic_cast((*set_iter)->getViewModelItem()); if (contains_nocopy_items(viewModel->getUUID())) { - LLNotificationsUtil::add("ConfirmCopyToMarketplace", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_doToSelected, _1, _2, model, root, action)); + LLNotificationsUtil::add("ConfirmCopyToMarketplace", LLSD(), LLSD(), boost::bind(&LLInventoryAction::callback_copySelected, _1, _2, model, root, action)); return; } } -- cgit v1.2.3 From ab91c83881ae182de2ebf8e99d31db2c5bd39f08 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 3 Feb 2015 22:04:58 -0800 Subject: DD-296 : Implement listing validation after we get all copied items confirmation from the server --- indra/newview/llinventoryfunctions.cpp | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 97d6bf004b..6721a9e4f4 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -130,6 +130,25 @@ S32 count_stock_folders(LLInventoryModel::cat_array_t& categories) return count; } +// Helper funtion : Count the number of items (not folders) in the descending hierarchy +S32 count_descendants_items(const LLUUID& cat_id) +{ + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat_id,cat_array,item_array); + + S32 count = item_array->size(); + + 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++) + { + LLViewerInventoryCategory* category = *iter; + count += count_descendants_items(category->getUUID()); + } + + return count; +} + // Helper function : Returns true if the hierarchy contains nocopy items bool contains_nocopy_items(const LLUUID& id) { @@ -360,6 +379,12 @@ void copy_inventory_category(LLInventoryModel* model, LLInventoryModel::cat_array_t* cat_array; LLInventoryModel::item_array_t* item_array; gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); + + // If root_copy_id is null, tell the marketplace model we'll be waiting for new items to be copied over for this folder + if (root_copy_id.isNull()) + { + LLMarketplaceData::instance().setValidationWaiting(root_id,count_descendants_items(cat->getUUID())); + } // Copy all the items LLInventoryModel::item_array_t item_array_copy = *item_array; @@ -377,6 +402,8 @@ void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) item; gInventory.changeItemParent(viewer_inv_item, new_cat_uuid, true); } + // Decrement the count in root_id since that one item won't be copied over + LLMarketplaceData::instance().decrementValidationWaiting(root_id); } else { @@ -1443,6 +1470,8 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol return false; } } + + open_marketplace_listings(); return true; } @@ -1477,11 +1506,10 @@ bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU { // Reparent the folder 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(dest_cat); } - // 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); -- cgit v1.2.3 From e07bc619b5d4b3c24b3850de1a9d6655e1e13596 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 5 Feb 2015 22:49:56 -0800 Subject: DD-322 : Use vector of UUIDs instead of pointers to items when reparenting those items --- indra/newview/llinventoryfunctions.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 6721a9e4f4..37cd592534 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1619,7 +1619,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // * have stock items nested at depth 2 at least // * never ever move the non-stock items - std::vector > items_vector; + 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 @@ -1649,7 +1649,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Get the item type for stock items type = viewer_inv_item->getInventoryType(); } - items_vector[type].push_back(viewer_inv_item); + items_vector[type].push_back(viewer_inv_item->getUUID()); } // How many types of folders? Which type is it if only one? @@ -1725,7 +1725,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { // Create a new folder LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); - LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); + LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector[i].back()); std::string folder_name = (depth > 1 ? viewer_cat->getName() : viewer_inv_item->getName()); LLFolderType::EType new_folder_type = (i == LLInventoryType::IT_COUNT ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); if (cb) @@ -1742,10 +1742,11 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ cb(message,depth,LLError::LEVEL_WARN); } LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, folder_name); + // Move each item to the new folder while (!items_vector[i].empty()) { - LLViewerInventoryItem* viewer_inv_item = items_vector[i].back(); + LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector[i].back()); if (cb) { std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Move"); -- cgit v1.2.3 From 4e1054a71fa158d3e5c2eaaaaf374829c33f52cb Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 9 Feb 2015 22:14:42 -0800 Subject: DD-296 : Make validation with fix of listing a bit more resilient when moving items and folders around --- indra/newview/llinventoryfunctions.cpp | 85 ++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 39 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 37cd592534..2140f3b352 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1552,7 +1552,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ if (depth < 0) { // If the folder is not under the marketplace listings root, we run validation as if it was a listing folder and prevent any hierarchy fix - // This allows the function to be used to pre-validate a folder + // This allows the function to be used to pre-validate a folder anywhere in the inventory depth = 1; fix_hierarchy = false; } @@ -1609,20 +1609,20 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } } - LLInventoryModel::cat_array_t* cat_array; - LLInventoryModel::item_array_t* item_array; - gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,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: + // Item sorting and validation : sorting and moving the various stock items is complicated as the set of constraints is high + // 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 + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); + 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 + // Parse the items and create vectors of item UUIDs sorting copyable items and stock items of various types bool has_bad_items = false; 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++) @@ -1652,7 +1652,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ items_vector[type].push_back(viewer_inv_item->getUUID()); } - // How many types of folders? Which type is it if only one? + // How many types of items? 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++) @@ -1669,6 +1669,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { if (cat_array->size() == 0) { + // So we have no item and no folder. That's at least a warning. if (depth == 2) { // If this is an empty version folder, warn only (listing won't be delivered by AIS, but only AIS should unlist) @@ -1718,51 +1719,56 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { if (fix_hierarchy && !has_bad_items) { - // Create one folder per vector at the right depth and of the right type - for (S32 i = 0; i <= LLInventoryType::IT_COUNT; i++) + // If we have more than 1 type of items or we are at the listing level, wrap the items in subfolders + if ((count > 1) || (depth == 1)) { - if (!items_vector[i].empty()) + // Create one folder per vector at the right depth and of the right type + for (S32 i = 0; i <= LLInventoryType::IT_COUNT; i++) { - // Create a new folder - LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); - LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector[i].back()); - std::string folder_name = (depth > 1 ? viewer_cat->getName() : viewer_inv_item->getName()); - LLFolderType::EType new_folder_type = (i == LLInventoryType::IT_COUNT ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); - if (cb) - { - std::string message = ""; - if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) - { - message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Stock"); - } - else - { - message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Version"); - } - cb(message,depth,LLError::LEVEL_WARN); - } - LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, folder_name); - - // Move each item to the new folder - while (!items_vector[i].empty()) + if (!items_vector[i].empty()) { + // Create a new folder + LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector[i].back()); + std::string folder_name = (depth > 1 ? viewer_cat->getName() : viewer_inv_item->getName()); + LLFolderType::EType new_folder_type = (i == LLInventoryType::IT_COUNT ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); if (cb) { - std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Move"); + std::string message = ""; + if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) + { + message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Stock"); + } + else + { + message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Version"); + } cb(message,depth,LLError::LEVEL_WARN); } - gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); - items_vector[i].pop_back(); + LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, folder_name); + + // Move each item to the new folder + while (!items_vector[i].empty()) + { + LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector[i].back()); + if (cb) + { + std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Move"); + cb(message,depth,LLError::LEVEL_WARN); + } + gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); + items_vector[i].pop_back(); + } + update_marketplace_category(folder_uuid); + gInventory.notifyObservers(); } - update_marketplace_category(folder_uuid); - gInventory.notifyObservers(); } } // Stock folder should have no sub folder so reparent those up if (folder_type == LLFolderType::FT_MARKETPLACE_STOCK) { LLUUID parent_uuid = cat->getParentUUID(); + gInventory.getDirectDescendentsOf(cat->getUUID(),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++) { @@ -1851,6 +1857,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } // Recursion : Perform the same validation on each nested folder + gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); LLInventoryModel::cat_array_t cat_array_copy = *cat_array; // Sort the folders in alphabetical order first std::sort(cat_array_copy.begin(), cat_array_copy.end(), sort_alpha); -- cgit v1.2.3 From 9ce64ec527f7b49b1641753ce6e67b8ed7f603c7 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 10 Feb 2015 22:40:28 -0800 Subject: DD-324 : Alert the user when we split a stock folder --- indra/newview/llinventoryfunctions.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 2140f3b352..02c4d76a13 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1719,6 +1719,11 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { if (fix_hierarchy && !has_bad_items) { + // Alert the user when an existing stock folder has to be split + if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && ((count >= 2) || (cat_array->size() > 0))) + { + LLNotificationsUtil::add("AlertMerchantStockFolderSplit"); + } // If we have more than 1 type of items or we are at the listing level, wrap the items in subfolders if ((count > 1) || (depth == 1)) { -- cgit v1.2.3 From 0177f56fc92536b7fe0c8139ae1e081fd09eacfe Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sat, 21 Feb 2015 18:41:54 -0800 Subject: DD-335 : Improve the performance of Get listings by 400%, fix a bug when error occured on SLM --- 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 02c4d76a13..3939281d0a 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -274,7 +274,7 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc } // Check if the count on hand needs to be updated on SLM - if (!LLMarketplaceData::instance().isUpdating(listing_uuid) && + if (perform_consistency_enforcement && !LLMarketplaceData::instance().isUpdating(listing_uuid) && (compute_stock_count(listing_uuid) != LLMarketplaceData::instance().getCountOnHand(listing_uuid))) { LLMarketplaceData::instance().updateCountOnHand(listing_uuid); -- cgit v1.2.3 From c7f24a69cfa0e87160d98325431c3098dcd8295b Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 17 Mar 2015 12:59:37 -0700 Subject: DD-362 : WIP : Check stock folder count limit --- indra/newview/llinventoryfunctions.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 3939281d0a..229644bdf9 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1267,6 +1267,19 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects", args); accept = false; } + + if (move_in_stock) + { + int stock_size = bundle_size + count_descendants_items(dest_folder->getUUID()); + if (stock_size > gSavedSettings.getU32("InventoryOutboxMaxStockItemCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxStockItemCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyStockItems", args); + accept = false; + } + } } return accept; @@ -1803,6 +1816,15 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Subfolder In Stock"); cb(message,depth,LLError::LEVEL_ERROR); } + else if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (item_array->size() > gSavedSettings.getU32("InventoryOutboxMaxStockItemCount"))) + { + // Report if a stock folder has too many items + result = false; + LLStringUtil::format_map_t args; + args["[AMOUNT]"] = llformat("%d",gSavedSettings.getU32("InventoryOutboxMaxStockItemCount")); + std::string message = indent + cat->getName() + LLTrans::getString("TooltipOutboxTooManyStockItems", args); + cb(message,depth,LLError::LEVEL_ERROR); + } else { // Simply print the folder name -- cgit v1.2.3 From 7e2a449b4e5bd2beeff1c6543e4f893fc38f0fe8 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 17 Mar 2015 15:31:32 -0700 Subject: DD-362 : Limit the admissible total of stock items, fail validation if above the threshold --- indra/newview/llinventoryfunctions.cpp | 60 ++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 21 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 229644bdf9..6e142d8998 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -115,6 +115,21 @@ S32 count_copyable_items(LLInventoryModel::item_array_t& items) return count; } +// Helper function : Count only the non-copyable items, i.e. the stock items, skip the others +S32 count_stock_items(LLInventoryModel::item_array_t& items) +{ + S32 count = 0; + for (LLInventoryModel::item_array_t::const_iterator it = items.begin(); it != items.end(); ++it) + { + LLViewerInventoryItem* item = *it; + if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + count++; + } + } + return count; +} + // Helper function : Count the number of stock folders S32 count_stock_folders(LLInventoryModel::cat_array_t& categories) { @@ -1240,6 +1255,9 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve // If the dest folder is a stock folder, we do not count the incoming items toward the total (stock items are seen as one) int existing_item_count = (move_in_stock ? 0 : bundle_size); + // If the dest folder is a stock folder, we do assume that the incoming items are also stock items (they should anyway) + int existing_stock_count = (move_in_stock ? bundle_size : 0); + // Get the version folder: that's where the counts start from const LLViewerInventoryCategory * version_folder = ((root_folder && (root_folder != dest_folder)) ? gInventory.getFirstDescendantOf(root_folder->getUUID(), dest_folder->getUUID()) : NULL); @@ -1257,6 +1275,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve gInventory.collectDescendents(version_folder->getUUID(), existing_categories, existing_items, FALSE); existing_item_count += count_copyable_items(existing_items) + count_stock_folders(existing_categories); + existing_stock_count += count_stock_items(existing_items); } if (existing_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) @@ -1267,18 +1286,13 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects", args); accept = false; } - - if (move_in_stock) + else if (existing_stock_count > gSavedSettings.getU32("InventoryOutboxMaxStockItemCount")) { - int stock_size = bundle_size + count_descendants_items(dest_folder->getUUID()); - if (stock_size > gSavedSettings.getU32("InventoryOutboxMaxStockItemCount")) - { - LLStringUtil::format_map_t args; - U32 amount = gSavedSettings.getU32("InventoryOutboxMaxStockItemCount"); - args["[AMOUNT]"] = llformat("%d",amount); - tooltip_msg = LLTrans::getString("TooltipOutboxTooManyStockItems", args); - accept = false; - } + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxStockItemCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyStockItems", args); + accept = false; } } @@ -1320,7 +1334,9 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn int dragged_folder_count = descendent_categories.size() + bundle_size; // Note: We assume that we're moving a bunch of folders in. That might be wrong... int dragged_item_count = count_copyable_items(descendent_items) + count_stock_folders(descendent_categories); + int dragged_stock_count = count_stock_items(descendent_items); int existing_item_count = 0; + int existing_stock_count = 0; int existing_folder_count = 0; if (version_folder) @@ -1330,6 +1346,7 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn // Clear those counts or they will be counted twice because we're already inside the version category dragged_folder_count = 0; dragged_item_count = 0; + dragged_stock_count = 0; } // Tally the total number of categories and items inside the root folder @@ -1339,10 +1356,12 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn existing_folder_count += existing_categories.size(); existing_item_count += count_copyable_items(existing_items) + count_stock_folders(existing_categories); + existing_stock_count += count_stock_items(existing_items); } const int total_folder_count = existing_folder_count + dragged_folder_count; const int total_item_count = existing_item_count + dragged_item_count; + const int total_stock_count = existing_stock_count + dragged_stock_count; if (total_folder_count > gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) { @@ -1360,6 +1379,14 @@ bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLIn tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects", args); accept = false; } + else if (total_stock_count > gSavedSettings.getU32("InventoryOutboxMaxStockItemCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxStockItemCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyStockItems", args); + accept = false; + } // Now check that each item in the folder can be moved in the marketplace if (accept && check_items) @@ -1677,7 +1704,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } } - // If we have no items in there (only folders or empty), analyze a bit further + // If we have no items in there (only folders or empty), analyze a bit further if ((count == 0) && !has_bad_items) { if (cat_array->size() == 0) @@ -1816,15 +1843,6 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Subfolder In Stock"); cb(message,depth,LLError::LEVEL_ERROR); } - else if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (item_array->size() > gSavedSettings.getU32("InventoryOutboxMaxStockItemCount"))) - { - // Report if a stock folder has too many items - result = false; - LLStringUtil::format_map_t args; - args["[AMOUNT]"] = llformat("%d",gSavedSettings.getU32("InventoryOutboxMaxStockItemCount")); - std::string message = indent + cat->getName() + LLTrans::getString("TooltipOutboxTooManyStockItems", args); - cb(message,depth,LLError::LEVEL_ERROR); - } else { // Simply print the folder name -- cgit v1.2.3 From b9397343939df8f0ecd065d11624de74f344577f Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 20 Mar 2015 13:42:03 -0700 Subject: DD-324 : Fix crash when recursively wrapping no copy items in stock folders --- indra/newview/llinventoryfunctions.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 6e142d8998..1a7b804d44 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1764,8 +1764,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { LLNotificationsUtil::add("AlertMerchantStockFolderSplit"); } - // If we have more than 1 type of items or we are at the listing level, wrap the items in subfolders - if ((count > 1) || (depth == 1)) + // If we have more than 1 type of items or we are at the listing level or we have stok/no stock type mismatch, wrap the items in subfolders + if ((count > 1) || (depth == 1) || + ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (type == LLInventoryType::IT_COUNT)) || + ((folder_type != LLFolderType::FT_MARKETPLACE_STOCK) && (type != LLInventoryType::IT_COUNT))) { // Create one folder per vector at the right depth and of the right type for (S32 i = 0; i <= LLInventoryType::IT_COUNT; i++) @@ -1819,7 +1821,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (*iter); gInventory.changeCategoryParent(viewer_cat, parent_uuid, false); - // Note : those reparented folders will be recursively visited and validated at the end of this function + result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth); } } } -- cgit v1.2.3 From 79b891a688c0ebd329118a7ebc1a527c72d8f83f Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 7 Apr 2015 15:22:32 -0700 Subject: DD-382 : Set count_on_hand correctly when creating or assigning a listing --- indra/newview/llinventoryfunctions.cpp | 55 ++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 25 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 1a7b804d44..aeee3738f9 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1014,7 +1014,7 @@ LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth) return cur_uuid; } -S32 compute_stock_count(LLUUID cat_uuid) +S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) { // Handle the case of the folder being a stock folder immediately LLViewerInventoryCategory* cat = gInventory.getCategory(cat_uuid); @@ -1033,36 +1033,41 @@ S32 compute_stock_count(LLUUID cat_uuid) return item_array->size(); } - // 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)) + // When force_count is true, we do not do any verification of the marketplace status and simply compute + // the stock amount based on the descendent hierarchy. This is used specifically when creating a listing. + if (!force_count) { - // 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().getVersionFolder(listing_uuid); - // Handle the case of the first 2 levels : listing and version folders - if (depth == 1) - { - if (version_folder_uuid.notNull()) + // 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 there is a version folder, the stock value for the listing is the version folder stock - return compute_stock_count(version_folder_uuid); + // If not listed, the notion of stock is meaningless so it won't be computed for any level + return -1; } - else + + LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolder(listing_uuid); + // Handle the case of the first 2 levels : listing and version folders + if (depth == 1) { - // If there's no version folder associated, the notion of stock count has no meaning - return -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 there's no version folder associated, the notion of stock count has no meaning + return -1; + } } - } - else if (depth == 2) - { - if (version_folder_uuid.notNull() && (version_folder_uuid != cat_uuid)) + else if (depth == 2) { - // If there is a version folder but we're not it, our stock count is meaningless - return -1; + 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; + } } } -- cgit v1.2.3 From 19b0fd1fd0bd9d3cd55d4835c14f35c02c163942 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 7 Apr 2015 15:43:27 -0700 Subject: DD-382 : Fix typo resulting in double negative in test and serious 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 aeee3738f9..8344868f6f 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1040,7 +1040,7 @@ S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) // 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 (!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; -- cgit v1.2.3 From c5c027eb14e92b89a3888a7c17ee1fd44e2f65b2 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 7 Apr 2015 22:49:40 -0700 Subject: DD-381 : Fix update of count on hand on drop. Will spam SLM a bit but only solution --- indra/newview/llinventoryfunctions.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 8344868f6f..386819b25a 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -289,8 +289,7 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc } // Check if the count on hand needs to be updated on SLM - if (perform_consistency_enforcement && !LLMarketplaceData::instance().isUpdating(listing_uuid) && - (compute_stock_count(listing_uuid) != LLMarketplaceData::instance().getCountOnHand(listing_uuid))) + if (perform_consistency_enforcement && (compute_stock_count(listing_uuid) != LLMarketplaceData::instance().getCountOnHand(listing_uuid))) { LLMarketplaceData::instance().updateCountOnHand(listing_uuid); } @@ -1053,7 +1052,7 @@ S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) 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); + return compute_stock_count(version_folder_uuid, true); } else { @@ -1084,7 +1083,7 @@ S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) 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()); + S32 count = compute_stock_count(category->getUUID(), true); if ((curr_count == -1) || ((count != -1) && (count < curr_count))) { curr_count = count; -- cgit v1.2.3 From 68771449157d27309ea77119d50dd8da31db1b23 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Thu, 9 Apr 2015 16:47:46 -0700 Subject: DD-384, DD-388 : Do not trust cached values for stock folders, do not consider a non fetched stock folder empty --- indra/newview/llinventoryfunctions.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 386819b25a..123e55a8ee 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1024,6 +1024,11 @@ S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) } if (cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) { + if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) + { + // If the folder is not completely fetched, we do not want to return any confusing value that could lead to unlisting + return -1; + } // Note: stock folders are *not* supposed to have nested subfolders so we stop recursion here but we count only items (subfolders will be ignored) // Note: we *always* give a stock count for stock folders, it's useful even if the listing is unassociated LLInventoryModel::cat_array_t* cat_array; -- cgit v1.2.3 From a9c3681cb5eecc043dab3f5c9dc9d97bc1af1075 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 10 Apr 2015 17:37:11 -0700 Subject: DD-381 : Avoid unecessary SLM updates, suppress some update_marketplace_category() that are picked by dirty bit setup --- indra/newview/llinventoryfunctions.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 123e55a8ee..135b6f2f17 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1505,11 +1505,6 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol // Reparent the item gInventory.changeItemParent(viewer_inv_item, dest_folder, true); } - - // Update the modified folders - update_marketplace_category(src_folder); - update_marketplace_category(dest_folder); - gInventory.notifyObservers(); } else { -- cgit v1.2.3 From 637e096d5718d0a174b5383aa29e3480edd734ea Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 13 Apr 2015 15:29:56 -0700 Subject: DD-388 : More resilient way of reacting to not evaluated stock count throughout marketplace handling --- indra/newview/llinventoryfunctions.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 135b6f2f17..9e88acdbd7 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1020,14 +1020,15 @@ S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) if (!cat) { // Not a category so no stock count to speak of - return -1; + return COMPUTE_STOCK_INFINITE; } if (cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) { if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) { // If the folder is not completely fetched, we do not want to return any confusing value that could lead to unlisting - return -1; + // "COMPUTE_STOCK_NOT_EVALUATED" denotes that a stock folder has a count that cannot be evaluated at this time (folder not up to date) + return COMPUTE_STOCK_NOT_EVALUATED; } // Note: stock folders are *not* supposed to have nested subfolders so we stop recursion here but we count only items (subfolders will be ignored) // Note: we *always* give a stock count for stock folders, it's useful even if the listing is unassociated @@ -1047,7 +1048,7 @@ S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) 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; + return COMPUTE_STOCK_INFINITE; } LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolder(listing_uuid); @@ -1062,7 +1063,7 @@ S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) else { // If there's no version folder associated, the notion of stock count has no meaning - return -1; + return COMPUTE_STOCK_INFINITE; } } else if (depth == 2) @@ -1070,18 +1071,19 @@ S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) 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; + return COMPUTE_STOCK_INFINITE; } } } // In all other cases, the stock count is the min of stock folders count found in the descendents + // "COMPUTE_STOCK_NOT_EVALUATED" denotes that a stock folder in the hierarchy has a count that cannot be evaluated at this time (folder not up to date) 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; + // "COMPUTE_STOCK_INFINITE" denotes a folder that doesn't countain any stock folders in its descendents + S32 curr_count = COMPUTE_STOCK_INFINITE; // Note: marketplace listings have a maximum depth nesting of 4 LLInventoryModel::cat_array_t cat_array_copy = *cat_array; @@ -1089,7 +1091,7 @@ S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) { LLInventoryCategory* category = *iter; S32 count = compute_stock_count(category->getUUID(), true); - if ((curr_count == -1) || ((count != -1) && (count < curr_count))) + if ((curr_count == COMPUTE_STOCK_INFINITE) || ((count != COMPUTE_STOCK_INFINITE) && (count < curr_count))) { curr_count = count; } -- cgit v1.2.3 From 3748d2f6dcde6f26c591c544c674aa76a81544c1 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 1 May 2015 23:17:05 -0700 Subject: DD-378 : Separate stock items of different permissions in different stock folders --- indra/newview/llinventoryfunctions.cpp | 95 ++++++++++++++++------------------ 1 file changed, 46 insertions(+), 49 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 9e88acdbd7..cc620bc0e2 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1665,8 +1665,8 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ LLInventoryModel::item_array_t* item_array; gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); - std::vector > items_vector; - items_vector.resize(LLInventoryType::IT_COUNT+1); + // We use a composite (type,permission) key on that map to store UUIDs of items of same (type,permissions) + std::map > items_vector; // Parse the items and create vectors of item UUIDs sorting copyable items and stock items of various types bool has_bad_items = false; @@ -1690,25 +1690,21 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } // Update the appropriate vector item for that type LLInventoryType::EType type = LLInventoryType::IT_COUNT; // Default value for non stock items + U32 perms = 0; if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) { // Get the item type for stock items type = viewer_inv_item->getInventoryType(); + perms = viewer_inv_item->getPermissions().getMaskNextOwner(); } - items_vector[type].push_back(viewer_inv_item->getUUID()); + U32 key = ((U32)(type) & 0xFF) << 24 | (perms & 0xFFFFFF); + items_vector[key].push_back(viewer_inv_item->getUUID()); } // How many types of items? 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++) - { - if (!items_vector[i].empty()) - { - count++; - type = (LLInventoryType::EType)(i); - } - } + S32 count = items_vector.size(); + U32 default_key = (U32)(LLInventoryType::IT_COUNT) << 24; // This is the key for any normal copyable item + U32 unique_key = (count == 1 ? items_vector.begin()->first : default_key); // The key in the case of one item type only // If we have no items in there (only folders or empty), analyze a bit further if ((count == 0) && !has_bad_items) @@ -1752,7 +1748,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } } // If we have a single type of items of the right type in the right place, we're done - else if ((count == 1) && !has_bad_items && (((type == LLInventoryType::IT_COUNT) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2) && (cat_array->size() == 0)))) + else if ((count == 1) && !has_bad_items && (((unique_key == default_key) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2) && (cat_array->size() == 0)))) { // Done with that folder : Print out the folder name unless we already found an error here if (cb && result && (depth >= 1)) @@ -1770,51 +1766,52 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { LLNotificationsUtil::add("AlertMerchantStockFolderSplit"); } - // If we have more than 1 type of items or we are at the listing level or we have stok/no stock type mismatch, wrap the items in subfolders + // If we have more than 1 type of items or we are at the listing level or we have stock/no stock type mismatch, wrap the items in subfolders if ((count > 1) || (depth == 1) || - ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (type == LLInventoryType::IT_COUNT)) || - ((folder_type != LLFolderType::FT_MARKETPLACE_STOCK) && (type != LLInventoryType::IT_COUNT))) + ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (unique_key == default_key)) || + ((folder_type != LLFolderType::FT_MARKETPLACE_STOCK) && (unique_key != default_key))) { // Create one folder per vector at the right depth and of the right type - for (S32 i = 0; i <= LLInventoryType::IT_COUNT; i++) + std::map >::iterator items_vector_it = items_vector.begin(); + while (items_vector_it != items_vector.end()) { - if (!items_vector[i].empty()) + // Create a new folder + LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); + LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector_it->second.back()); + std::string folder_name = (depth > 1 ? viewer_cat->getName() : viewer_inv_item->getName()); + LLFolderType::EType new_folder_type = (items_vector_it->first == default_key ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); + if (cb) { - // Create a new folder - LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); - LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector[i].back()); - std::string folder_name = (depth > 1 ? viewer_cat->getName() : viewer_inv_item->getName()); - LLFolderType::EType new_folder_type = (i == LLInventoryType::IT_COUNT ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); - if (cb) + std::string message = ""; + if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) { - std::string message = ""; - if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) - { - message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Stock"); - } - else - { - message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Version"); - } - cb(message,depth,LLError::LEVEL_WARN); + message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Stock"); } - LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, folder_name); - - // Move each item to the new folder - while (!items_vector[i].empty()) + else { - LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector[i].back()); - if (cb) - { - std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Move"); - cb(message,depth,LLError::LEVEL_WARN); - } - gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); - items_vector[i].pop_back(); + message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Version"); + } + cb(message,depth,LLError::LEVEL_WARN); + } + LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, folder_name); + + // Move each item to the new folder + while (!items_vector_it->second.empty()) + { + LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector_it->second.back()); + if (cb) + { + std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Move"); + cb(message,depth,LLError::LEVEL_WARN); } - update_marketplace_category(folder_uuid); - gInventory.notifyObservers(); + gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); + items_vector_it->second.pop_back(); } + + // Next type + update_marketplace_category(folder_uuid); + gInventory.notifyObservers(); + items_vector_it++; } } // Stock folder should have no sub folder so reparent those up -- cgit v1.2.3 From 676640278402b01473c81cdb945dc7696a549240 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 8 May 2015 20:41:43 -0700 Subject: DD-399 : Use folder name to create new folders when under listing level --- 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 cc620bc0e2..48748ff823 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1778,7 +1778,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Create a new folder LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector_it->second.back()); - std::string folder_name = (depth > 1 ? viewer_cat->getName() : viewer_inv_item->getName()); + std::string folder_name = (depth >= 1 ? viewer_cat->getName() : viewer_inv_item->getName()); LLFolderType::EType new_folder_type = (items_vector_it->first == default_key ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); if (cb) { -- cgit v1.2.3 From fdad3f54bd12adcaffd54edd86fbd8ce51507017 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 13 May 2015 23:45:25 -0700 Subject: DD-366 : Update validated listing folders more consistently --- indra/newview/llinventoryfunctions.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 48748ff823..68fb44ea50 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1573,17 +1573,29 @@ bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU return true; } -// 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 (through the -// optional callback cb). It also returns a boolean, true if things validate, false if issues are raised. -// The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders. bool sort_alpha(const LLViewerInventoryCategory* cat1, const LLViewerInventoryCategory* cat2) { return cat1->getName().compare(cat2->getName()) < 0; } +void dump_trace(std::string& message, S32 depth, LLError::ELevel log_level) +{ + llinfos << "validate_marketplacelistings : error = "<< log_level << ", depth = " << depth << ", message = " << message << llendl; +} + +// 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 (through the +// optional callback cb). It also returns a boolean, true if things validate, false if issues are raised. +// The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders. bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy, S32 depth) { +#if 0 + // Used only for debug + if (!cb) + { + cb = boost::bind(&dump_trace, _1, _2, _3); + } +#endif // Folder is valid unless issue is raised bool result = true; @@ -1697,7 +1709,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ type = viewer_inv_item->getInventoryType(); perms = viewer_inv_item->getPermissions().getMaskNextOwner(); } - U32 key = ((U32)(type) & 0xFF) << 24 | (perms & 0xFFFFFF); + U32 key = (((U32)(type) & 0xFF) << 24) | (perms & 0xFFFFFF); items_vector[key].push_back(viewer_inv_item->getUUID()); } @@ -1809,6 +1821,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ } // Next type + update_marketplace_category(parent_uuid); update_marketplace_category(folder_uuid); gInventory.notifyObservers(); items_vector_it++; @@ -1898,12 +1911,6 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ gInventory.notifyObservers(); return result && !has_bad_items; } - else - { - // Update the current folder - update_marketplace_category(cat->getUUID()); - gInventory.notifyObservers(); - } } // Recursion : Perform the same validation on each nested folder @@ -1918,6 +1925,8 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1); } + update_marketplace_category(cat->getUUID()); + gInventory.notifyObservers(); return result && !has_bad_items; } -- cgit v1.2.3 From e8dce624e4633b3861567aa68d23a5a40b52c94d Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sat, 6 Jun 2015 17:49:19 -0700 Subject: DD-333 : Prevent dropping no copy items if it'll create folders above the folder limit --- indra/newview/llinventoryfunctions.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 6f6777bd8f..d402590e51 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1270,6 +1270,8 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve // If the dest folder is a stock folder, we do assume that the incoming items are also stock items (they should anyway) int existing_stock_count = (move_in_stock ? bundle_size : 0); + int existing_folder_count = 0; + // Get the version folder: that's where the counts start from const LLViewerInventoryCategory * version_folder = ((root_folder && (root_folder != dest_folder)) ? gInventory.getFirstDescendantOf(root_folder->getUUID(), dest_folder->getUUID()) : NULL); @@ -1288,6 +1290,14 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve existing_item_count += count_copyable_items(existing_items) + count_stock_folders(existing_categories); existing_stock_count += count_stock_items(existing_items); + existing_folder_count += existing_categories.size(); + + // If the incoming item is a nocopy (stock) item, we need to consider that it will create a stock folder + if (!inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && !move_in_stock) + { + // Note : we do not assume that all incoming items are nocopy of different kinds... + existing_folder_count += 1; + } } if (existing_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) @@ -1306,6 +1316,14 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve tooltip_msg = LLTrans::getString("TooltipOutboxTooManyStockItems", args); accept = false; } + else if (existing_folder_count > gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyFolders", args); + accept = false; + } } return accept; -- cgit v1.2.3 From b0e75cc153d6ec18d8987a5322767b548f29926f Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Sat, 6 Jun 2015 20:23:01 -0700 Subject: DD-416 : Unlist a listed listing that becomes devoid of any item --- indra/newview/llinventoryfunctions.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index d402590e51..4feb697af9 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -287,6 +287,11 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc LL_INFOS("SLM") << "Unlist and clear version folder as the version folder is not at the right place anymore!!" << LL_ENDL; LLMarketplaceData::instance().setVersionFolder(listing_uuid, LLUUID::null); } + else if (version_folder_uuid.notNull() && (count_descendants_items(version_folder_uuid) == 0)) + { + LL_INFOS("SLM") << "Unlist as the version folder is empty of any item!!" << LL_ENDL; + LLMarketplaceData::instance().activateListing(listing_uuid, false); + } } // Check if the count on hand needs to be updated on SLM -- cgit v1.2.3 From 2cc3ce72b3f7abf037e554b04850e627a9d8eb5f Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 9 Jun 2015 15:41:11 -0700 Subject: DD-359 : Improve performance by caching display data while updating and preventing refreshing the whole marketplace (never useful) --- indra/newview/llinventoryfunctions.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 4feb697af9..e245fd2d59 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2576,6 +2576,7 @@ void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root) // containing folder will need to be updated as well as their initially containing folder. For // instance, moving a stock folder from a listed folder to another will require an update of the // target listing *and* the original listing. So we need to keep track of both. + // Note: do not however put the marketplace listings root itself in this list or the whole marketplace data will be rebuilt. sMarketplaceFolders.clear(); const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); std::set selected_items = root->getSelectionList(); @@ -2586,8 +2587,16 @@ void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root) viewModel = dynamic_cast((*set_iter)->getViewModelItem()); if (viewModel && gInventory.isObjectDescendentOf(viewModel->getInventoryObject()->getParentUUID(), marketplacelistings_id)) { - sMarketplaceFolders.push_back(viewModel->getInventoryObject()->getParentUUID()); - sMarketplaceFolders.push_back(viewModel->getInventoryObject()->getUUID()); + const LLUUID &parent_id = viewModel->getInventoryObject()->getParentUUID(); + if (parent_id != marketplacelistings_id) + { + sMarketplaceFolders.push_back(parent_id); + } + const LLUUID &curr_id = viewModel->getInventoryObject()->getUUID(); + if (curr_id != marketplacelistings_id) + { + sMarketplaceFolders.push_back(curr_id); + } } } // Suppress dupes in the list so we won't update listings twice -- cgit v1.2.3 From 84a7394ae03608556b5974ca1bdfc280cf5874b7 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 9 Jun 2015 19:44:03 -0700 Subject: DD-412 : WIP : Validate a listing before creating a listing on SLM --- indra/newview/llinventoryfunctions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index e245fd2d59..d9002a631d 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1916,8 +1916,9 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ else if (depth == 1) { // Report items not wrapped in version folder + result = false; std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Unwrapped Item"); - cb(message,depth,LLError::LEVEL_WARN); + cb(message,depth,LLError::LEVEL_ERROR); } } } -- cgit v1.2.3 From ab73b1af8fad5f012f782632a08740b4a0a1c8fa Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 10 Jun 2015 14:53:12 -0700 Subject: DD-416 : Added DAMA when version folder is empty and unlisted, accelerated some functions avoiding depth computation when we could, fixed cut case --- indra/newview/llinventoryfunctions.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index d9002a631d..b241bfa466 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -285,19 +285,20 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc if (version_folder_uuid.notNull() && (!gInventory.isObjectDescendentOf(version_folder_uuid, listing_uuid) || (version_depth != 2))) { LL_INFOS("SLM") << "Unlist and clear version folder as the version folder is not at the right place anymore!!" << LL_ENDL; - LLMarketplaceData::instance().setVersionFolder(listing_uuid, LLUUID::null); + LLMarketplaceData::instance().setVersionFolder(listing_uuid, LLUUID::null,1); } - else if (version_folder_uuid.notNull() && (count_descendants_items(version_folder_uuid) == 0)) + else if (version_folder_uuid.notNull() && LLMarketplaceData::instance().getActivationState(version_folder_uuid) && (count_descendants_items(version_folder_uuid) == 0) && !LLMarketplaceData::instance().isUpdating(version_folder_uuid,version_depth)) { LL_INFOS("SLM") << "Unlist as the version folder is empty of any item!!" << LL_ENDL; - LLMarketplaceData::instance().activateListing(listing_uuid, false); + LLNotificationsUtil::add("AlertMerchantVersionFolderEmpty"); + LLMarketplaceData::instance().activateListing(listing_uuid, false,1); } } // Check if the count on hand needs to be updated on SLM if (perform_consistency_enforcement && (compute_stock_count(listing_uuid) != LLMarketplaceData::instance().getCountOnHand(listing_uuid))) { - LLMarketplaceData::instance().updateCountOnHand(listing_uuid); + LLMarketplaceData::instance().updateCountOnHand(listing_uuid,1); } // Update all descendents starting from the listing root update_marketplace_folder_hierarchy(listing_uuid); -- cgit v1.2.3 From c828382db3e5d689194295d6e4351715bca02aca Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Fri, 24 Jul 2015 15:48:27 +0300 Subject: MAINT-5432 FIXED Null check to avoid crash --- indra/newview/llinventoryfunctions.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 0dbb5a6d61..0195b5efc1 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2609,6 +2609,11 @@ void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root) // Note: do not however put the marketplace listings root itself in this list or the whole marketplace data will be rebuilt. sMarketplaceFolders.clear(); const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + if (marketplacelistings_id.isNull()) + { + return; + } + std::set selected_items = root->getSelectionList(); std::set::iterator set_iter = selected_items.begin(); LLFolderViewModelItemInventory * viewModel = NULL; -- cgit v1.2.3 From f5d22358d29905c2adbe0af1c8c453dd0a80b4e2 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Tue, 28 Jul 2015 09:01:20 +0300 Subject: MAINT-5432 MAINT-5440 FIXED Crash in LLUUID::operator==(LLUUID const &) and LLFolderView::removeSelectedItems() --- indra/newview/llinventoryfunctions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventoryfunctions.cpp') diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 0195b5efc1..218590e5c3 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2620,7 +2620,8 @@ void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root) for (; set_iter != selected_items.end(); ++set_iter) { viewModel = dynamic_cast((*set_iter)->getViewModelItem()); - if (viewModel && gInventory.isObjectDescendentOf(viewModel->getInventoryObject()->getParentUUID(), marketplacelistings_id)) + if (!viewModel || !viewModel->getInventoryObject()) continue; + if (gInventory.isObjectDescendentOf(viewModel->getInventoryObject()->getParentUUID(), marketplacelistings_id)) { const LLUUID &parent_id = viewModel->getInventoryObject()->getParentUUID(); if (parent_id != marketplacelistings_id) -- cgit v1.2.3