diff options
Diffstat (limited to 'indra/newview/llinventorybridge.cpp')
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 382 |
1 files changed, 346 insertions, 36 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index f0fc710f3d..a36aa3dedf 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -70,6 +70,9 @@ #include "llvoavatarself.h" #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 + typedef std::pair<LLUUID, LLUUID> two_uuids_t; typedef std::list<two_uuids_t> two_uuids_list_t; @@ -107,6 +110,23 @@ bool confirm_attachment_rez(const LLSD& notification, const LLSD& response); void teleport_via_landmark(const LLUUID& asset_id); static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit); +// Helper functions + +bool isAddAction(const std::string& action) +{ + return ("wear" == action || "attach" == action || "activate" == action); +} + +bool isRemoveAction(const std::string& action) +{ + return ("take_off" == action || "detach" == action || "deactivate" == action); +} + +bool isMarketplaceCopyAction(const std::string& action) +{ + return (("copy_to_outbox" == action) || ("move_to_outbox" == action)); +} + // +=================================================+ // | LLInvFVBridge | // +=================================================+ @@ -538,10 +558,14 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, { items.push_back(std::string("Find Links")); } - items.push_back(std::string("Rename")); - if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0) + + if (!isInboxFolder()) { - disabled_items.push_back(std::string("Rename")); + items.push_back(std::string("Rename")); + if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Rename")); + } } if (show_asset_id) @@ -569,11 +593,31 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, { disabled_items.push_back(std::string("Copy")); } + + if (canListOnMarketplace()) + { + items.push_back(std::string("Marketplace Separator")); + + bool copyable = true; + LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID); + if (inv_item) + { + copyable = inv_item->getPermissions().allowCopyBy(gAgent.getID()); + } + + const std::string merchant_action = ((copyable == true) ? "Merchant Copy" : "Merchant Move"); + items.push_back(merchant_action); + + if (!canListOnMarketplaceNow()) + { + disabled_items.push_back(merchant_action); + } + } } } // Don't allow items to be pasted directly into the COF or the inbox - if (!isCOFFolder() && !isInboxFolder()) + if (!isCOFFolder() && !isInboxFolder() && !isOutboxFolder()) { items.push_back(std::string("Paste")); } @@ -610,6 +654,10 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -794,6 +842,25 @@ BOOL LLInvFVBridge::isInboxFolder() const return gInventory.isObjectDescendentOf(mUUID, inbox_id); } +BOOL LLInvFVBridge::isOutboxFolder() const +{ + const LLUUID outbox_id = getOutboxFolder(); + + if (outbox_id.isNull()) + { + return FALSE; + } + + return gInventory.isObjectDescendentOf(mUUID, outbox_id); +} + +const LLUUID LLInvFVBridge::getOutboxFolder() const +{ + const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); + + return outbox_id; +} + BOOL LLInvFVBridge::isItemPermissive() const { return FALSE; @@ -938,9 +1005,14 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, new_listener = new LLMeshBridge(inventory, root, uuid); break; + case LLAssetType::AT_IMAGE_TGA: + case LLAssetType::AT_IMAGE_JPEG: + //llwarns << LLAssetType::lookup(asset_type) << " asset type is unhandled for uuid " << uuid << llendl; + break; + default: llinfos << "Unhandled asset type (llassetstorage.h): " - << (S32)asset_type << llendl; + << (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << llendl; break; } @@ -989,6 +1061,65 @@ BOOL LLInvFVBridge::canShare() const return FALSE; } +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; + } + + if (!isAgentInventory()) + { + return FALSE; + } + + if (getOutboxFolder().isNull()) + { + return FALSE; + } + + if (isInboxFolder() || isOutboxFolder()) + { + return FALSE; + } + + LLViewerInventoryItem * item = model->getItem(mUUID); + if (item && !item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) + { + return FALSE; + } + + return TRUE; +#else + return FALSE; +#endif +} + +BOOL LLInvFVBridge::canListOnMarketplaceNow() const +{ +#if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU + if (get_is_item_worn(mUUID)) + { + return FALSE; + } + + // 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)) + { + return FALSE; + } + + return TRUE; +#else + return FALSE; +#endif +} + + // +=================================================+ // | InventoryFVBridgeBuilder | // +=================================================+ @@ -1086,6 +1217,16 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) folder_view_itemp->getListener()->pasteLinkFromClipboard(); return; } + else if (isMarketplaceCopyAction(action)) + { + llinfos << "Copy item to marketplace action!" << llendl; + + LLInventoryItem* itemp = model->getItem(mUUID); + if (!itemp) return; + + const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); + copy_item_to_outbox(itemp, outbox_id, LLUUID::null); + } } void LLItemBridge::selectItem() @@ -1226,7 +1367,7 @@ std::string LLItemBridge::getLabelSuffix() const { // String table is loaded before login screen and inventory items are // loaded after login, so LLTrans should be ready. - static std::string NO_COPY =LLTrans::getString("no_copy"); + static std::string NO_COPY = LLTrans::getString("no_copy"); static std::string NO_MOD = LLTrans::getString("no_modify"); static std::string NO_XFER = LLTrans::getString("no_transfer"); static std::string LINK = LLTrans::getString("link"); @@ -1294,6 +1435,11 @@ BOOL LLItemBridge::isItemRenameable() const return FALSE; } + if (isInboxFolder()) + { + return FALSE; + } + return (item->getPermissions().allowModifyBy(gAgent.getID())); } return FALSE; @@ -1457,16 +1603,6 @@ BOOL LLItemBridge::isItemPermissive() const return FALSE; } -bool LLItemBridge::isAddAction(std::string action) const -{ - return ("wear" == action || "attach" == action || "activate" == action); -} - -bool LLItemBridge::isRemoveAction(std::string action) const -{ - return ("take_off" == action || "detach" == action || "deactivate" == action); -} - // +=================================================+ // | LLFolderBridge | // +=================================================+ @@ -1648,8 +1784,77 @@ 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()); + bool allow_transfer = inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + + if (!allow_transfer) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNoTransfer"); + } + else if(worn) + { + tooltip_msg = LLTrans::getString("TooltipOutboxWorn"); + } + + 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()); +} + + + +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) + BOOL drop, + std::string& tooltip_msg) { LLInventoryModel* model = getInventoryModel(); @@ -1674,10 +1879,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, 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. @@ -1730,6 +1938,27 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } } } + if (move_is_into_outbox) + { + 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; + } + } + + int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat); + + if (nested_folder_levels > 4) + { + tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels"); + is_movable = FALSE; + } + + } // //-------------------------------------------------------------------------------- @@ -1797,6 +2026,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, #endif } } + if (move_is_into_outbox && !move_is_from_outbox) + { + dropFolderToOutbox(inv_cat); + } else { if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) @@ -2209,6 +2442,16 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) removeSystemFolder(); } #endif + else if (isMarketplaceCopyAction(action)) + { + llinfos << "Copy folder to marketplace action!" << llendl; + + LLInventoryCategory * cat = gInventory.getCategory(mUUID); + if (!cat) return; + + const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); + copy_folder_to_outbox(cat, outbox_id, cat->getUUID()); + } } void LLFolderBridge::openItem() @@ -2493,6 +2736,7 @@ void LLFolderBridge::folderOptionsMenu() if (trash_id == mUUID) return; if (isItemInTrash()) return; if (!isAgentInventory()) return; + if (isOutboxFolder()) return; LLFolderType::EType type = category->getPreferredType(); const bool is_system_folder = LLFolderType::lookupIsProtectedType(type); @@ -2628,6 +2872,10 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) mItems.clear(); // clear any items that used to exist addTrashContextMenuOptions(mItems, mDisabledItems); } + else if(isOutboxFolder()) + { + mItems.push_back(std::string("Delete")); + } else if(isAgentInventory()) // do not allow creating in library { LLViewerInventoryCategory *cat = getCategory(); @@ -2635,7 +2883,7 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // Not sure what the right thing is to do here. if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT)) { - if (!isInboxFolder()) // don't allow creation in inbox + if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox { // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) @@ -2702,10 +2950,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) mDisabledItems.push_back(std::string("Delete System Folder")); } - mItems.push_back(std::string("Share")); - if (!canShare()) + if (!isOutboxFolder()) { - mDisabledItems.push_back(std::string("Share")); + mItems.push_back(std::string("Share")); + if (!canShare()) + { + mDisabledItems.push_back(std::string("Share")); + } } hide_context_entries(menu, mItems, mDisabledItems); @@ -2746,7 +2997,8 @@ BOOL LLFolderBridge::hasChildren() const BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, - void* cargo_data) + void* cargo_data, + std::string& tooltip_msg) { LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data; @@ -2766,7 +3018,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_ANIMATION: case DAD_GESTURE: case DAD_MESH: - accept = dragItemIntoFolder(inv_item, drop); + accept = dragItemIntoFolder(inv_item, drop, tooltip_msg); break; case DAD_LINK: // DAD_LINK type might mean one of two asset types: AT_LINK or AT_LINK_FOLDER. @@ -2777,12 +3029,12 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, LLInventoryCategory* linked_category = gInventory.getCategory(inv_item->getLinkedUUID()); if (linked_category) { - accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop); + accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop, tooltip_msg); } } else { - accept = dragItemIntoFolder(inv_item, drop); + accept = dragItemIntoFolder(inv_item, drop, tooltip_msg); } break; case DAD_CATEGORY: @@ -2792,7 +3044,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, } else { - accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop); + accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop, tooltip_msg); } break; case DAD_ROOT_CATEGORY: @@ -3049,7 +3301,8 @@ void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_c // into the folder, as well as performing the actual drop, depending // if drop == TRUE. BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, - BOOL drop) + BOOL drop, + std::string& tooltip_msg) { LLInventoryModel* model = getInventoryModel(); @@ -3060,11 +3313,14 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false); const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); + const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_favorites = (mUUID == favorites_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); //(mUUID == outbox_id); + const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_item->getUUID(), outbox_id); LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); BOOL accept = FALSE; @@ -3130,6 +3386,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { accept = can_move_to_landmarks(inv_item); } + else if (move_is_into_outbox) + { + accept = can_move_to_outbox(inv_item, tooltip_msg); + } if(accept && drop) { @@ -3180,6 +3440,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { dropToOutfit(inv_item, move_is_into_current_outfit); } + else if (move_is_into_outbox && !move_is_from_outbox) + { + copy_item_to_outbox(inv_item, outbox_id, LLUUID::null); + } // NORMAL or TRASH folder // (move the item, restamp if into trash) else @@ -3380,6 +3644,10 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -3456,6 +3724,10 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -3470,8 +3742,11 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) getClipboardEntries(true, items, disabled_items, flags); } - items.push_back(std::string("Sound Separator")); - items.push_back(std::string("Sound Play")); + if (!isOutboxFolder()) + { + items.push_back(std::string("Sound Separator")); + items.push_back(std::string("Sound Play")); + } hide_context_entries(menu, items, disabled_items); } @@ -3507,6 +3782,10 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -3521,8 +3800,11 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) getClipboardEntries(true, items, disabled_items, flags); } - items.push_back(std::string("Landmark Separator")); - items.push_back(std::string("About Landmark")); + if (!isOutboxFolder()) + { + items.push_back(std::string("Landmark Separator")); + items.push_back(std::string("About Landmark")); + } // Disable "About Landmark" menu item for // multiple landmarks selected. Only one landmark @@ -3736,6 +4018,10 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -3778,7 +4064,8 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, - void* cargo_data) + void* cargo_data, + std::string& tooltip_msg) { LLViewerInventoryItem* item = getItem(); BOOL rv = FALSE; @@ -3993,6 +4280,10 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { addTrashContextMenuOptions(items, disabled_items); } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); + } else { items.push_back(std::string("Share")); @@ -4046,6 +4337,10 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -4060,9 +4355,12 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags) getClipboardEntries(true, items, disabled_items, flags); } - items.push_back(std::string("Animation Separator")); - items.push_back(std::string("Animation Play")); - items.push_back(std::string("Animation Audition")); + 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); @@ -4319,6 +4617,10 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -4652,6 +4954,10 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { addTrashContextMenuOptions(items, disabled_items); } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); + } else { // FWIW, it looks like SUPPRESS_OPEN_ITEM is not set anywhere BOOL can_open = ((flags & SUPPRESS_OPEN_ITEM) != SUPPRESS_OPEN_ITEM); @@ -5040,6 +5346,10 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Restore Item")); } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); + } else { items.push_back(std::string("Properties")); |