diff options
Diffstat (limited to 'indra/newview/llinventorybridge.cpp')
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 630 |
1 files changed, 448 insertions, 182 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 5916ed60a4..4040701f42 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -53,6 +53,7 @@ #include "llinventorymodel.h" #include "llinventorymodelbackgroundfetch.h" #include "llinventorypanel.h" +#include "llmarketplacefunctions.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llpreviewanim.h" @@ -60,6 +61,7 @@ #include "llpreviewtexture.h" #include "llselectmgr.h" #include "llsidepanelappearance.h" +#include "lltooldraganddrop.h" #include "lltrans.h" #include "llviewerassettype.h" #include "llviewerfoldertype.h" @@ -71,7 +73,9 @@ #include "llwearablelist.h" // Marketplace outbox current disabled -#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 0 // keep in sync with ENABLE_INVENTORY_DISPLAY_OUTBOX, ENABLE_MERCHANT_OUTBOX_PANEL +#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 1 +#define ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU 0 +#define BLOCK_WORN_ITEMS_IN_OUTBOX 1 typedef std::pair<LLUUID, LLUUID> two_uuids_t; typedef std::list<two_uuids_t> two_uuids_list_t; @@ -127,6 +131,11 @@ bool isMarketplaceCopyAction(const std::string& action) return (("copy_to_outbox" == action) || ("move_to_outbox" == action)); } +bool isMarketplaceSendAction(const std::string& action) +{ + return ("send_to_marketplace" == action); +} + // +=================================================+ // | LLInvFVBridge | // +=================================================+ @@ -462,14 +471,13 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const void hide_context_entries(LLMenuGL& menu, const menuentry_vec_t &entries_to_show, - const menuentry_vec_t &disabled_entries, - BOOL append) // If append is TRUE, then new enabled entries + const menuentry_vec_t &disabled_entries) // If append is TRUE, then new enabled entries { const LLView::child_list_t *list = menu.getChildList(); // For removing double separators or leading separator. Start at true so that // if the first element is a separator, it will not be shown. - BOOL is_previous_entry_separator = TRUE; + bool is_previous_entry_separator = true; for (LLView::child_list_t::const_iterator itor = list->begin(); itor != list->end(); @@ -493,6 +501,7 @@ void hide_context_entries(LLMenuGL& menu, if (*itor2 == name) { found = true; + break; } } @@ -500,9 +509,8 @@ void hide_context_entries(LLMenuGL& menu, // between two separators). if (found) { - const BOOL is_entry_separator = (dynamic_cast<LLMenuItemSeparatorGL *>(menu_item) != NULL); - if (is_entry_separator && is_previous_entry_separator) - found = false; + const bool is_entry_separator = (dynamic_cast<LLMenuItemSeparatorGL *>(menu_item) != NULL); + found = !(is_entry_separator && is_previous_entry_separator); is_previous_entry_separator = is_entry_separator; } @@ -520,15 +528,13 @@ void hide_context_entries(LLMenuGL& menu, // A bit of a hack so we can remember that some UI element explicitly set this to be visible // so that some other UI element from multi-select doesn't later set this invisible. menu_item->pushVisible(TRUE); - if (append) - { - menu_item->setEnabled(TRUE); - } + for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2) { if (*itor2 == name) { menu_item->setEnabled(FALSE); + break; } } } @@ -616,7 +622,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } } - // Don't allow items to be pasted directly into the COF or the inbox + // Don't allow items to be pasted directly into the COF or the inbox/outbox if (!isCOFFolder() && !isInboxFolder() && !isOutboxFolder()) { items.push_back(std::string("Paste")); @@ -657,7 +663,7 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else if(isOutboxFolder()) { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { @@ -734,6 +740,32 @@ void LLInvFVBridge::addOpenRightClickMenuOption(menuentry_vec_t &items) items.push_back(std::string("Open")); } +void LLInvFVBridge::addOutboxContextMenuOptions(U32 flags, + menuentry_vec_t &items, + menuentry_vec_t &disabled_items) +{ + items.push_back(std::string("Rename")); + items.push_back(std::string("Delete")); + + if ((flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Rename")); + } + +#if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU + if (isOutboxFolderDirectParent()) + { + items.push_back(std::string("Marketplace Separator")); + items.push_back(std::string("Marketplace Send")); + + if ((flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Marketplace Send")); + } + } +#endif // ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU +} + // *TODO: remove this BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const { @@ -854,6 +886,22 @@ BOOL LLInvFVBridge::isOutboxFolder() const return gInventory.isObjectDescendentOf(mUUID, outbox_id); } +BOOL LLInvFVBridge::isOutboxFolderDirectParent() const +{ + BOOL outbox_is_parent = FALSE; + + const LLInventoryCategory *cat = gInventory.getCategory(mUUID); + + if (cat) + { + const LLUUID outbox_id = getOutboxFolder(); + + outbox_is_parent = (outbox_id.notNull() && (outbox_id == cat->getParentUUID())); + } + + return outbox_is_parent; +} + const LLUUID LLInvFVBridge::getOutboxFolder() const { const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); @@ -1040,82 +1088,132 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid) } } -BOOL LLInvFVBridge::canShare() const +bool LLInvFVBridge::canShare() const { - if (!isAgentInventory()) return FALSE; - - const LLInventoryModel* model = getInventoryModel(); - if (!model) return FALSE; + bool can_share = false; - const LLViewerInventoryItem *item = model->getItem(mUUID); - if (item) + if (isAgentInventory()) { - if (!LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item)) - return FALSE; - return (BOOL)LLGiveInventory::isInventoryGiveAcceptable(item); + const LLInventoryModel* model = getInventoryModel(); + if (model) + { + const LLViewerInventoryItem *item = model->getItem(mUUID); + if (item) + { + if (LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item)) + { + can_share = LLGiveInventory::isInventoryGiveAcceptable(item); + } + } + else + { + // Categories can be given. + can_share = (model->getCategory(mUUID) != NULL); + } + } } - // Categories can be given. - if (model->getCategory(mUUID)) return TRUE; - - return FALSE; + return can_share; } -BOOL LLInvFVBridge::canListOnMarketplace() const +bool LLInvFVBridge::canListOnMarketplace() const { #if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU + LLInventoryModel * model = getInventoryModel(); + const LLViewerInventoryCategory * cat = model->getCategory(mUUID); if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) { - return FALSE; + return false; } if (!isAgentInventory()) { - return FALSE; + return false; } if (getOutboxFolder().isNull()) { - return FALSE; + return false; } if (isInboxFolder() || isOutboxFolder()) { - return FALSE; + return false; + } + + const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + if (outbox_id.isNull()) + { + return false; } LLViewerInventoryItem * item = model->getItem(mUUID); if (item && !item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) { - return FALSE; + return false; } - return TRUE; + return true; + #else - return FALSE; + return false; #endif } -BOOL LLInvFVBridge::canListOnMarketplaceNow() const +bool LLInvFVBridge::canListOnMarketplaceNow() const { #if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU - if (get_is_item_worn(mUUID)) + + bool can_list = true; + + // Do not allow listing while import is in progress + if (LLMarketplaceInventoryImporter::instanceExists()) { - return FALSE; + can_list = !LLMarketplaceInventoryImporter::instance().isImportInProgress(); } + + const LLInventoryObject* obj = getInventoryObject(); + can_list &= (obj != NULL); - // Loop through all items worn by avatar and check to see if they are descendants - // of the item we are trying to list on the marketplace - if (get_is_parent_to_worn_item(mUUID)) + if (can_list) { - return FALSE; + const LLUUID& object_id = obj->getLinkedUUID(); + can_list = object_id.notNull(); + + if (can_list) + { + LLFolderViewFolder * object_folderp = mRoot->getFolderByID(object_id); + if (object_folderp) + { + can_list = !object_folderp->isLoading(); + } + } + + if (can_list) + { + // Get outbox id + const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + LLFolderViewItem * outbox_itemp = mRoot->getItemByID(outbox_id); + + if (outbox_itemp) + { + MASK mask = 0x0; + BOOL drop = FALSE; + EDragAndDropType cargo_type = LLViewerAssetType::lookupDragAndDropType(obj->getActualType()); + void * cargo_data = (void *) obj; + std::string tooltip_msg; + + can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg); + } + } } + + return can_list; - return TRUE; #else - return FALSE; + return false; #endif } @@ -1225,7 +1323,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) if (!itemp) return; const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); - copy_item_to_outbox(itemp, outbox_id, LLUUID::null); + copy_item_to_outbox(itemp, outbox_id, LLUUID::null, LLToolDragAndDrop::getOperationId()); } } @@ -1787,30 +1885,35 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const static BOOL can_move_to_outbox(LLInventoryItem* inv_item, std::string& tooltip_msg) { - bool worn = get_is_item_worn(inv_item->getUUID()); + // 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; } - else if(worn) + +#if BLOCK_WORN_ITEMS_IN_OUTBOX + bool worn = get_is_item_worn(inv_item->getUUID()); + if (worn) { tooltip_msg = LLTrans::getString("TooltipOutboxWorn"); + return false; } +#endif - return !worn && allow_transfer; -} - - - -void LLFolderBridge::dropFolderToOutbox(LLInventoryCategory* inv_cat) -{ - copy_folder_to_outbox(inv_cat, getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false), inv_cat->getUUID()); + return true; } - int get_folder_levels(LLInventoryCategory* inv_cat) { LLInventoryModel::cat_array_t* cats; @@ -1865,54 +1968,78 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, if (!isAgentAvatarValid()) return FALSE; if (!isAgentInventory()) return FALSE; // cannot drag categories into library + const LLUUID &cat_id = inv_cat->getUUID(); + const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); + const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + + const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); + const BOOL move_is_from_outbox = model->isObjectDescendentOf(cat_id, outbox_id); // check to make sure source is agent inventory, and is represented there. LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); - const BOOL is_agent_inventory = (model->getCategory(inv_cat->getUUID()) != NULL) + const BOOL is_agent_inventory = (model->getCategory(cat_id) != NULL) && (LLToolDragAndDrop::SOURCE_AGENT == source); - const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); - const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); - BOOL accept = FALSE; if (is_agent_inventory) { - const LLUUID &cat_id = inv_cat->getUUID(); const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false); const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); - const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); const BOOL move_is_into_outfit = getCategory() && (getCategory()->getPreferredType() == LLFolderType::FT_OUTFIT); const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id); - const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); - const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_cat->getUUID(), outbox_id); //-------------------------------------------------------------------------------- // Determine if folder can be moved. // BOOL is_movable = TRUE; - if (LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())) + + if (is_movable && (mUUID == cat_id)) + { is_movable = FALSE; - if (move_is_into_outfit) + tooltip_msg = LLTrans::getString("TooltipDragOntoSelf"); + } + if (is_movable && (model->isObjectDescendentOf(mUUID, cat_id))) + { is_movable = FALSE; - if (mUUID == gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)) + tooltip_msg = LLTrans::getString("TooltipDragOntoOwnChild"); + } + if (is_movable && LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())) + { + is_movable = FALSE; + // tooltip? + } + if (is_movable && move_is_into_outfit) + { is_movable = FALSE; + // tooltip? + } + if (is_movable && (mUUID == model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE))) + { + is_movable = FALSE; + // tooltip? + } + LLInventoryModel::cat_array_t descendent_categories; LLInventoryModel::item_array_t descendent_items; - gInventory.collectDescendents(cat_id, descendent_categories, descendent_items, FALSE); - for (S32 i=0; i < descendent_categories.count(); ++i) + if (is_movable) { - LLInventoryCategory* category = descendent_categories[i]; - if(LLFolderType::lookupIsProtectedType(category->getPreferredType())) + model->collectDescendents(cat_id, descendent_categories, descendent_items, FALSE); + for (S32 i=0; i < descendent_categories.count(); ++i) { - // Can't move "special folders" (e.g. Textures Folder). - is_movable = FALSE; - break; + LLInventoryCategory* category = descendent_categories[i]; + if(LLFolderType::lookupIsProtectedType(category->getPreferredType())) + { + // Can't move "special folders" (e.g. Textures Folder). + is_movable = FALSE; + break; + } } } - if (move_is_into_trash) + if (is_movable && move_is_into_trash) { for (S32 i=0; i < descendent_items.count(); ++i) { @@ -1924,7 +2051,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } } } - if (move_is_into_landmarks) + if (is_movable && move_is_into_landmarks) { for (S32 i=0; i < descendent_items.count(); ++i) { @@ -1939,35 +2066,100 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } } } - if (move_is_into_outbox) + if (is_movable && move_is_into_outbox) { - for (S32 i=0; i < descendent_items.count(); ++i) + const int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat); + + if (nested_folder_levels > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) { - LLInventoryItem* item = descendent_items[i]; - if (!can_move_to_outbox(item, tooltip_msg)) - { - is_movable = FALSE; - break; - } + tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels"); + 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 = model->getFirstDescendantOf(outbox_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().getCargoIDsCount(); + } + } + + // Tally the total number of categories and items inside the master folder - int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat); + LLInventoryModel::cat_array_t existing_categories; + LLInventoryModel::item_array_t existing_items; - if (nested_folder_levels > 4) - { - tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels"); - is_movable = FALSE; + 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")) + { + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyFolders"); + is_movable = FALSE; + } + else if (nested_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) + { + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects"); + 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_outbox(item, tooltip_msg)) + { + is_movable = FALSE; + break; + } + } + } } - } // //-------------------------------------------------------------------------------- - accept = is_movable - && (mUUID != cat_id) // Can't move a folder into itself - && (mUUID != inv_cat->getParentUUID()) // Avoid moves that would change nothing - && !(model->isObjectDescendentOf(mUUID, cat_id)); // Avoid circularity + accept = is_movable; + if (accept && drop) { // Look for any gestures and deactivate them @@ -1999,7 +2191,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // Recursively create links in target outfit. LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - gInventory.collectDescendents(inv_cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH); + model->collectDescendents(cat_id, cats, items, LLInventoryModel::EXCLUDE_TRASH); LLAppearanceMgr::instance().linkAll(mUUID,items,NULL); } } @@ -2017,7 +2209,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, const std::string empty_description = ""; link_inventory_item( gAgent.getID(), - inv_cat->getUUID(), + cat_id, mUUID, inv_cat->getName(), empty_description, @@ -2029,13 +2221,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } else if (move_is_into_outbox && !move_is_from_outbox) { - dropFolderToOutbox(inv_cat); + copy_folder_to_outbox(inv_cat, mUUID, cat_id, LLToolDragAndDrop::getOperationId()); } else { - if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) + if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) { - set_dad_inbox_object(inv_cat->getUUID()); + set_dad_inbox_object(cat_id); } // Reparent the folder and restamp children if it's moving @@ -2050,15 +2242,28 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } else if (LLToolDragAndDrop::SOURCE_WORLD == source) { - // content category has same ID as object itself - LLUUID object_id = inv_cat->getUUID(); - LLUUID category_id = mUUID; - accept = move_inv_category_world_to_agent(object_id, category_id, drop); + if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else + { + accept = move_inv_category_world_to_agent(cat_id, mUUID, drop); + } } else if (LLToolDragAndDrop::SOURCE_LIBRARY == source) { - // Accept folders that contain complete outfits. - accept = move_is_into_current_outfit && LLAppearanceMgr::instance().getCanMakeFolderIntoOutfit(inv_cat->getUUID()); + if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else + { + // Accept folders that contain complete outfits. + accept = move_is_into_current_outfit && LLAppearanceMgr::instance().getCanMakeFolderIntoOutfit(cat_id); + } if (accept && drop) { @@ -2450,8 +2655,19 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) if (!cat) return; const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); - copy_folder_to_outbox(cat, outbox_id, cat->getUUID()); + copy_folder_to_outbox(cat, outbox_id, cat->getUUID(), LLToolDragAndDrop::getOperationId()); } +#if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU + else if (isMarketplaceSendAction(action)) + { + llinfos << "Send to marketplace action!" << llendl; + + LLInventoryCategory * cat = gInventory.getCategory(mUUID); + if (!cat) return; + + send_to_marketplace(cat); + } +#endif // ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU } void LLFolderBridge::openItem() @@ -2810,7 +3026,7 @@ void LLFolderBridge::folderOptionsMenu() LLMenuGL* menup = dynamic_cast<LLMenuGL*>(mMenu.get()); if (menup) { - hide_context_entries(*menup, mItems, mDisabledItems, TRUE); + hide_context_entries(*menup, mItems, mDisabledItems); // Reposition the menu, in case we're adding items to an existing menu. menup->needsArrange(); @@ -2874,20 +3090,23 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else if(isOutboxFolder()) { - mItems.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, mItems, mDisabledItems); } else if(isAgentInventory()) // do not allow creating in library { - LLViewerInventoryCategory *cat = getCategory(); + LLViewerInventoryCategory *cat = getCategory(); // BAP removed protected check to re-enable standard ops in untyped folders. // Not sure what the right thing is to do here. if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT)) { - if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox + if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox or outbox { // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) + { mItems.push_back(std::string("New Folder")); + } + mItems.push_back(std::string("New Script")); mItems.push_back(std::string("New Note")); mItems.push_back(std::string("New Gesture")); @@ -3306,8 +3525,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { LLInventoryModel* model = getInventoryModel(); - if(!model || !inv_item) return FALSE; - if(!isAgentInventory()) return FALSE; // cannot drag into library + if (!model || !inv_item) return FALSE; + if (!isAgentInventory()) return FALSE; // cannot drag into library if (!isAgentAvatarValid()) return FALSE; const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); @@ -3375,10 +3594,14 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, accept = TRUE; if (!is_movable) + { accept = FALSE; - if ((mUUID == inv_item->getParentUUID()) && !move_is_into_favorites) + } + else if ((mUUID == inv_item->getParentUUID()) && !move_is_into_favorites) + { accept = FALSE; - if (move_is_into_current_outfit || move_is_into_outfit) + } + else if (move_is_into_current_outfit || move_is_into_outfit) { accept = can_move_to_outfit(inv_item, move_is_into_current_outfit); } @@ -3389,9 +3612,32 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, else if (move_is_into_outbox) { accept = can_move_to_outbox(inv_item, tooltip_msg); + + if (accept) + { + const LLViewerInventoryCategory * master_folder = model->getFirstDescendantOf(outbox_id, mUUID); + + int existing_item_count = LLToolDragAndDrop::instance().getCargoIDsCount(); + + 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")) + { + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects"); + accept = FALSE; + } + } } - if(accept && drop) + if (accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE && LLGestureMgr::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash) @@ -3440,9 +3686,16 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { dropToOutfit(inv_item, move_is_into_current_outfit); } - else if (move_is_into_outbox && !move_is_from_outbox) + else if (move_is_into_outbox) { - copy_item_to_outbox(inv_item, outbox_id, LLUUID::null); + if (move_is_from_outbox) + { + move_item_within_outbox(inv_item, mUUID, LLToolDragAndDrop::getOperationId()); + } + else + { + copy_item_to_outbox(inv_item, mUUID, LLUUID::null, LLToolDragAndDrop::getOperationId()); + } } // NORMAL or TRASH folder // (move the item, restamp if into trash) @@ -3463,7 +3716,6 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // //-------------------------------------------------------------------------------- - } } else if (LLToolDragAndDrop::SOURCE_WORLD == source) @@ -3472,7 +3724,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // anonymous objects, it would be possible to bypass // permissions. object = gObjectList.findObject(inv_item->getParentUUID()); - if(!object) + if (!object) { llinfos << "Object not found for drop." << llendl; return FALSE; @@ -3482,10 +3734,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // move/copy this item. LLPermissions perm(inv_item->getPermissions()); BOOL is_move = FALSE; - if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) + if ((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) && perm.allowTransferTo(gAgent.getID()))) // || gAgent.isGodlike()) - { accept = TRUE; } @@ -3501,7 +3752,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // Don't allow placing an original item into Current Outfit or an outfit folder // because they must contain only links to wearable items. // *TODO: Probably we should create a link to an item if it was dragged to outfit or COF. - if(move_is_into_current_outfit || move_is_into_outfit) + if (move_is_into_current_outfit || move_is_into_outfit) { accept = FALSE; } @@ -3512,8 +3763,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { accept = FALSE; } - - if(drop && accept) + else if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + + if (accept && drop) { LLMoveInv* move_inv = new LLMoveInv; move_inv->mObjectID = inv_item->getParentUUID(); @@ -3535,15 +3791,22 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, LLNotifications::instance().forceResponse(params, 0); } } - } else if(LLToolDragAndDrop::SOURCE_NOTECARD == source) { - // Don't allow placing an original item from a notecard to Current Outfit or an outfit folder - // because they must contain only links to wearable items. - accept = !(move_is_into_current_outfit || move_is_into_outfit); - - if(accept && drop) + if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else + { + // Don't allow placing an original item from a notecard to Current Outfit or an outfit folder + // because they must contain only links to wearable items. + accept = !(move_is_into_current_outfit || move_is_into_outfit); + } + + if (accept && drop) { copy_inventory_from_notecard(mUUID, // Drop to the chosen destination folder LLToolDragAndDrop::getInstance()->getObjectID(), @@ -3558,7 +3821,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { accept = TRUE; - if (move_is_into_current_outfit || move_is_into_outfit) + if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else if (move_is_into_current_outfit || move_is_into_outfit) { accept = can_move_to_outfit(inv_item, move_is_into_current_outfit); } @@ -3649,7 +3917,7 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else if(isOutboxFolder()) { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { @@ -3723,29 +3991,29 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) menuentry_vec_t items; menuentry_vec_t disabled_items; - if(isItemInTrash()) + if (isOutboxFolder()) { - addTrashContextMenuOptions(items, disabled_items); - } - else if(isOutboxFolder()) - { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { - items.push_back(std::string("Share")); - if (!canShare()) + if (isItemInTrash()) { - disabled_items.push_back(std::string("Share")); - } - items.push_back(std::string("Sound Open")); - items.push_back(std::string("Properties")); + addTrashContextMenuOptions(items, disabled_items); + } + else + { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } + items.push_back(std::string("Sound Open")); + items.push_back(std::string("Properties")); - getClipboardEntries(true, items, disabled_items, flags); - } + getClipboardEntries(true, items, disabled_items, flags); + } - if (!isOutboxFolder()) - { items.push_back(std::string("Sound Separator")); items.push_back(std::string("Sound Play")); } @@ -3781,29 +4049,29 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) menuentry_vec_t disabled_items; lldebugs << "LLLandmarkBridge::buildContextMenu()" << llendl; - if(isItemInTrash()) + if(isOutboxFolder()) { - addTrashContextMenuOptions(items, disabled_items); - } - else if(isOutboxFolder()) - { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { - items.push_back(std::string("Share")); - if (!canShare()) + if(isItemInTrash()) { - disabled_items.push_back(std::string("Share")); - } - items.push_back(std::string("Landmark Open")); - items.push_back(std::string("Properties")); + addTrashContextMenuOptions(items, disabled_items); + } + else + { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } + items.push_back(std::string("Landmark Open")); + items.push_back(std::string("Properties")); - getClipboardEntries(true, items, disabled_items, flags); - } + getClipboardEntries(true, items, disabled_items, flags); + } - if (!isOutboxFolder()) - { items.push_back(std::string("Landmark Separator")); items.push_back(std::string("About Landmark")); } @@ -4336,36 +4604,35 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags) menuentry_vec_t disabled_items; lldebugs << "LLAnimationBridge::buildContextMenu()" << llendl; - if(isItemInTrash()) - { - addTrashContextMenuOptions(items, disabled_items); - } - else if(isOutboxFolder()) + if(isOutboxFolder()) { items.push_back(std::string("Delete")); } else { - items.push_back(std::string("Share")); - if (!canShare()) + if(isItemInTrash()) { - disabled_items.push_back(std::string("Share")); - } - items.push_back(std::string("Animation Open")); - items.push_back(std::string("Properties")); + addTrashContextMenuOptions(items, disabled_items); + } + else + { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } + items.push_back(std::string("Animation Open")); + items.push_back(std::string("Properties")); - getClipboardEntries(true, items, disabled_items, flags); - } + getClipboardEntries(true, items, disabled_items, flags); + } - if (!isOutboxFolder()) - { items.push_back(std::string("Animation Separator")); items.push_back(std::string("Animation Play")); items.push_back(std::string("Animation Audition")); } hide_context_entries(menu, items, disabled_items); - } // virtual @@ -5350,7 +5617,7 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else if(isOutboxFolder()) { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { @@ -5359,7 +5626,6 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) getClipboardEntries(true, items, disabled_items, flags); } - hide_context_entries(menu, items, disabled_items); } |