diff options
author | Merov Linden <merov@lindenlab.com> | 2014-05-23 17:19:03 -0700 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2014-05-23 17:19:03 -0700 |
commit | d06d4a36e702604368c70244114c58c5df730fb9 (patch) | |
tree | 6eeb5fa768d1c2a18320642c04aa7c93ebd27293 | |
parent | aa518ce8f112a7717d025cf7bdf710635999c6a2 (diff) |
DD-91 : WIP : Refactor code testing the validity of a drag, drop or paste of a folder or item in the marketplace
-rwxr-xr-x | indra/newview/llinventorybridge.cpp | 267 | ||||
-rwxr-xr-x | indra/newview/llinventoryfunctions.cpp | 222 | ||||
-rwxr-xr-x | indra/newview/llinventoryfunctions.h | 3 |
3 files changed, 256 insertions, 236 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 07b4eee90d..4da8fd4b86 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2314,82 +2314,6 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const } -static 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; -} - - -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; -} - -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; -} BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, BOOL drop, @@ -2518,101 +2442,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } if (is_movable && (move_is_into_outbox || move_is_into_marketplacelistings)) { - int nested_folder_levels = get_folder_levels(inv_cat); - nested_folder_levels += (move_is_into_outbox ? get_folder_path_length(outbox_id, mUUID) : get_folder_path_length(marketplacelistings_id, mUUID)); - - 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); - is_movable = FALSE; - } - else - { - int dragged_folder_count = descendent_categories.count(); - int existing_item_count = 0; - int existing_folder_count = 0; - - const LLViewerInventoryCategory * master_folder = (move_is_into_outbox ? model->getFirstDescendantOf(outbox_id, mUUID) : model->getFirstDescendantOf(marketplacelistings_id, mUUID)); - - if (master_folder != NULL) - { - if (model->isObjectDescendentOf(cat_id, master_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 master folder in the count! - - // If we're in the drop operation as opposed to the drag without drop, we are doing a - // single category at a time so don't block based on the total amount of cargo data items - if (drop) - { - dragged_folder_count += 1; - } - else - { - // NOTE: The cargo id's count is a total of categories AND items but we err on the side of - // prevention rather than letting too many folders into the hierarchy of the outbox, - // when we're dragging the item to a new parent - dragged_folder_count += LLToolDragAndDrop::instance().getCargoCount(); - } - } - - // Tally the total number of categories and items inside the master folder - - LLInventoryModel::cat_array_t existing_categories; - LLInventoryModel::item_array_t existing_items; - - model->collectDescendents(master_folder->getUUID(), existing_categories, existing_items, FALSE); - - existing_folder_count += existing_categories.count(); - existing_item_count += existing_items.count(); - } - else - { - // Assume a single category is being dragged to the outbox since we evaluate one at a time - // when not putting them under a parent item. - 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); - is_movable = 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); - is_movable = FALSE; - } - - if (is_movable == TRUE) - { - for (S32 i=0; i < descendent_items.count(); ++i) - { - LLInventoryItem* item = descendent_items[i]; - if (!can_move_to_marketplace(item, tooltip_msg)) - { - is_movable = FALSE; - break; - } - } - } - } + const LLViewerInventoryCategory * master_folder = (move_is_into_outbox ? model->getFirstDescendantOf(outbox_id, mUUID) : model->getFirstDescendantOf(marketplacelistings_id, mUUID)); + LLViewerInventoryCategory * dest_folder = getCategory(); + S32 bundle_size = (drop ? 1 : LLToolDragAndDrop::instance().getCargoCount()); + is_movable = can_move_folder_to_marketplace(master_folder, dest_folder, inv_cat, tooltip_msg, bundle_size); } if (is_movable) @@ -3443,44 +3276,33 @@ void LLFolderBridge::pasteFromClipboard() LLDynamicArray<LLUUID> objects; LLClipboard::instance().pasteFromClipboard(objects); - // Use "dragOrDrop" to go through the same accept logic if (move_is_into_outbox || move_is_into_marketplacelistings) { - LLFolderViewFolder* outbox_itemp = (move_is_into_outbox ? mInventoryPanel.get()->getFolderByID(outbox_id) : mInventoryPanel.get()->getFolderByID(marketplacelistings_id)); - - if (outbox_itemp) - { - LLToolDragAndDrop::instance().setCargoCount(objects.size()); - - std::string error_msg; - for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) - { - const LLUUID& item_id = (*iter); - LLInventoryObject *item = model->getObject(item_id); - - if (item) - { - MASK mask = 0x0; - BOOL drop = FALSE; - EDragAndDropType cargo_type = LLViewerAssetType::lookupDragAndDropType(item->getActualType()); - void * cargo_data = (void *) item; - if (!outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, error_msg)) - { - break; - } - } - } - - LLToolDragAndDrop::instance().resetCargoCount(); - - if (!error_msg.empty()) - { - LLSD subs; - subs["[ERROR_CODE]"] = error_msg; - LLNotificationsUtil::add("MerchantPasteFailed", subs); - return; - } + std::string error_msg; + const LLViewerInventoryCategory * master_folder = (move_is_into_outbox ? model->getFirstDescendantOf(outbox_id, mUUID) : model->getFirstDescendantOf(marketplacelistings_id, mUUID)); + LLViewerInventoryCategory * dest_folder = getCategory(); + for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) + { + const LLUUID& item_id = (*iter); + LLInventoryItem *item = model->getItem(item_id); + LLInventoryCategory *cat = model->getCategory(item_id); + + if (item && !can_move_item_to_marketplace(master_folder, dest_folder, item, error_msg)) + { + break; + } + if (cat && !can_move_folder_to_marketplace(master_folder, dest_folder, cat, error_msg)) + { + break; + } } + if (!error_msg.empty()) + { + LLSD subs; + subs["[ERROR_CODE]"] = error_msg; + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return; + } } const LLUUID parent_id(mUUID); @@ -4373,36 +4195,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } else if (move_is_into_outbox || move_is_into_marketplacelistings) { - // Check stock folder type matches item type in marketplace listings - accept = (!move_is_into_marketplacelistings || (getCategory() && getCategory()->acceptItem(inv_item))); - - accept &= can_move_to_marketplace(inv_item, tooltip_msg); - - if (accept) - { - const LLViewerInventoryCategory * master_folder = (move_is_into_outbox ? model->getFirstDescendantOf(outbox_id, mUUID) : model->getFirstDescendantOf(marketplacelistings_id, mUUID)); - - int existing_item_count = LLToolDragAndDrop::instance().getCargoCount(); - - if (master_folder != NULL) - { - LLInventoryModel::cat_array_t existing_categories; - LLInventoryModel::item_array_t existing_items; - - gInventory.collectDescendents(master_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; - } - } + const LLViewerInventoryCategory * master_folder = (move_is_into_outbox ? model->getFirstDescendantOf(outbox_id, mUUID) : model->getFirstDescendantOf(marketplacelistings_id, mUUID)); + LLViewerInventoryCategory * dest_folder = getCategory(); + accept = can_move_item_to_marketplace(master_folder, dest_folder, inv_item, tooltip_msg, LLToolDragAndDrop::instance().getCargoCount()); } LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); 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<LLViewerInventoryCategory*>(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 diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index c3ace9d914..e87a263427 100755 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -76,6 +76,9 @@ void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_fold typedef boost::function<void(std::string& validation_message)> validation_callback_t; +bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryItem* inv_item, std::string& tooltip_msg, S32 bundle_size = 1); +bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size = 1); +bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg); bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy = false); bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy = false); bool has_correct_permissions_for_sale(LLInventoryCategory* cat); |