summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2014-05-23 17:19:03 -0700
committerMerov Linden <merov@lindenlab.com>2014-05-23 17:19:03 -0700
commitd06d4a36e702604368c70244114c58c5df730fb9 (patch)
tree6eeb5fa768d1c2a18320642c04aa7c93ebd27293
parentaa518ce8f112a7717d025cf7bdf710635999c6a2 (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-xindra/newview/llinventorybridge.cpp267
-rwxr-xr-xindra/newview/llinventoryfunctions.cpp222
-rwxr-xr-xindra/newview/llinventoryfunctions.h3
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);