diff options
Diffstat (limited to 'indra/newview/llinventorygallerymenu.cpp')
-rw-r--r-- | indra/newview/llinventorygallerymenu.cpp | 295 |
1 files changed, 292 insertions, 3 deletions
diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp index 7c664b5dab..8e56ccc01d 100644 --- a/indra/newview/llinventorygallerymenu.cpp +++ b/indra/newview/llinventorygallerymenu.cpp @@ -32,9 +32,11 @@ #include "llappearancemgr.h" #include "llavataractions.h" #include "llclipboard.h" +#include "llenvironment.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llfloaterworldmap.h" +#include "llfriendcard.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" @@ -48,6 +50,41 @@ #include "llviewerwindow.h" #include "llvoavatarself.h" + +void modify_outfit(bool append, const LLUUID& cat_id, LLInventoryModel* model) +{ + LLViewerInventoryCategory* cat = model->getCategory(cat_id); + if (!cat) return; + + // checking amount of items to wear + static LLCachedControl<U32> max_items(gSavedSettings, "WearFolderLimit", 125); + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false); + model->collectDescendentsIf(cat_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + not_worn); + + if (items.size() > max_items()) + { + LLSD args; + args["AMOUNT"] = llformat("%u", max_items()); + LLNotificationsUtil::add("TooManyWearables", args); + return; + } + if (model->isObjectDescendentOf(cat_id, gInventory.getRootFolderID())) + { + LLAppearanceMgr::instance().wearInventoryCategory(cat, false, append); + } + else + { + // Library, we need to copy content first + LLAppearanceMgr::instance().wearInventoryCategory(cat, true, append); + } +} + LLContextMenu* LLInventoryGalleryContextMenu::createMenu() { LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -57,12 +94,35 @@ LLContextMenu* LLInventoryGalleryContextMenu::createMenu() registrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryGalleryContextMenu::fileUploadLocation, this, _2)); registrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH)); registrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND)); + registrar.add("Inventory.DoCreate", [this](LLUICtrl*, const LLSD& data) + { + if (mRootFolder) + { + mGallery->doCreate(mGallery->getRootFolder(), data); + } + else + { + mGallery->doCreate(mUUIDs.front(), data); + } + }); std::set<LLUUID> uuids(mUUIDs.begin(), mUUIDs.end()); registrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, uuids, gFloaterView->getParentFloater(mGallery))); enable_registrar.add("Inventory.CanSetUploadLocation", boost::bind(&LLInventoryGalleryContextMenu::canSetUploadLocation, this, _2)); + enable_registrar.add("Inventory.EnvironmentEnabled", [](LLUICtrl*, const LLSD&) + { + return LLEnvironment::instance().isInventoryEnabled(); + }); + enable_registrar.add("Inventory.MaterialsEnabled", [](LLUICtrl*, const LLSD&) + { + std::string agent_url = gAgent.getRegionCapability("UpdateMaterialAgentInventory"); + std::string task_url = gAgent.getRegionCapability("UpdateMaterialTaskInventory"); + + return (!agent_url.empty() && !task_url.empty()); + }); + LLContextMenu* menu = createFromFile("menu_gallery_inventory.xml"); updateMenuItemsVisibility(menu); @@ -138,7 +198,11 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata) } else if ("thumbnail" == action) { - LLSD data(mUUIDs.front()); + LLSD data; + for (const LLUUID& id : mUUIDs) + { + data.append(id); + } LLFloaterReg::showInstance("change_item_thumbnail", data); } else if ("cut" == action) @@ -186,6 +250,22 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata) { ungroup_folder_items(mUUIDs.front()); } + else if ("replaceoutfit" == action) + { + modify_outfit(false, mUUIDs.front(), &gInventory); + } + else if ("addtooutfit" == action) + { + modify_outfit(true, mUUIDs.front(), &gInventory); + } + else if ("removefromoutfit" == action) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(mUUIDs.front()); + if (cat) + { + LLAppearanceMgr::instance().takeOffOutfit(cat->getLinkedUUID()); + } + } else if ("take_off" == action || "detach" == action) { for (LLUUID& selected_id : mUUIDs) @@ -295,6 +375,54 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata) preview_texture->saveAs(); } } + else if (("copy_to_marketplace_listings" == action) + || ("move_to_marketplace_listings" == action)) + { + LLViewerInventoryItem* itemp = gInventory.getItem(mUUIDs.front()); + bool copy_operation = "copy_to_marketplace_listings" == action; + bool can_copy = itemp ? itemp->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) : false; + + + if (can_copy) + { + const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); + if (itemp) + { + move_item_to_marketplacelistings(itemp, marketplacelistings_id, copy_operation); + } + } + else + { + uuid_vec_t lamdba_list = mUUIDs; + LLNotificationsUtil::add( + "ConfirmCopyToMarketplace", + LLSD(), + LLSD(), + [lamdba_list](const LLSD& notification, const LLSD& response) + { + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + // option == 0 Move no copy item(s) + // option == 1 Don't move no copy item(s) (leave them behind) + bool copy_and_move = option == 0; + const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); + + // main inventory only allows one item? + LLViewerInventoryItem* itemp = gInventory.getItem(lamdba_list.front()); + if (itemp) + { + if (itemp->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + move_item_to_marketplacelistings(itemp, marketplacelistings_id, true); + } + else if (copy_and_move) + { + move_item_to_marketplacelistings(itemp, marketplacelistings_id, false); + } + } + } + ); + } + } } void LLInventoryGalleryContextMenu::rename(const LLUUID& item_id) @@ -388,6 +516,56 @@ bool is_inbox_folder(LLUUID item_id) return gInventory.isObjectDescendentOf(item_id, inbox_id); } +bool can_list_on_marketplace(const LLUUID &id) +{ + const LLInventoryObject* obj = gInventory.getObject(id); + bool can_list = (obj != NULL); + + if (can_list) + { + const LLUUID& object_id = obj->getLinkedUUID(); + can_list = object_id.notNull(); + + if (can_list) + { + std::string error_msg; + const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); + if (marketplacelistings_id.notNull()) + { + LLViewerInventoryCategory* master_folder = gInventory.getCategory(marketplacelistings_id); + LLInventoryCategory* cat = gInventory.getCategory(id); + if (cat) + { + can_list = can_move_folder_to_marketplace(master_folder, master_folder, cat, error_msg); + } + else + { + LLInventoryItem* item = gInventory.getItem(id); + can_list = (item ? can_move_item_to_marketplace(master_folder, master_folder, item, error_msg) : false); + } + } + else + { + can_list = false; + } + } + } + + return can_list; +} + +bool check_folder_for_contents_of_type(const LLUUID &id, LLInventoryModel* model, LLInventoryCollectFunctor& is_type) +{ + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + model->collectDescendentsIf(id, + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_type); + return item_array.size() > 0; +} + void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* menu) { LLUUID selected_id = mUUIDs.front(); @@ -409,6 +587,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men bool is_in_trash = gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH)); bool is_lost_and_found = (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND)); bool is_outfits= (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS)); + bool is_in_favorites = gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)); //bool is_favorites= (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)); bool is_system_folder = false; @@ -456,6 +635,49 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men items.push_back(std::string("open_in_new_window")); items.push_back(std::string("Open Folder Separator")); } + + // wearables related functionality for folders. + LLFindWearables is_wearable; + LLIsType is_object(LLAssetType::AT_OBJECT); + LLIsType is_gesture(LLAssetType::AT_GESTURE); + + if (check_folder_for_contents_of_type(selected_id, &gInventory, is_wearable) + || check_folder_for_contents_of_type(selected_id, &gInventory, is_object) + || check_folder_for_contents_of_type(selected_id, &gInventory, is_gesture)) + { + // Only enable add/replace outfit for non-system folders. + if (!is_system_folder) + { + // Adding an outfit onto another (versus replacing) doesn't make sense. + if (folder_type != LLFolderType::FT_OUTFIT) + { + items.push_back(std::string("Add To Outfit")); + if (!LLAppearanceMgr::instance().getCanAddToCOF(selected_id)) + { + disabled_items.push_back(std::string("Add To Outfit")); + } + } + + items.push_back(std::string("Replace Outfit")); + if (!LLAppearanceMgr::instance().getCanReplaceCOF(selected_id)) + { + disabled_items.push_back(std::string("Replace Outfit")); + } + } + if (is_agent_inventory) + { + items.push_back(std::string("Folder Wearables Separator")); + // Note: If user tries to unwear "My Inventory", it's going to deactivate everything including gestures + // Might be safer to disable this for "My Inventory" + items.push_back(std::string("Remove From Outfit")); + if (folder_type != LLFolderType::FT_ROOT_INVENTORY // Unless COF is empty, whih shouldn't be, warrantied to have worn items + && !LLAppearanceMgr::getCanRemoveFromCOF(selected_id)) // expensive from root! + { + disabled_items.push_back(std::string("Remove From Outfit")); + } + } + items.push_back(std::string("Outfit Separator")); + } } else { @@ -503,11 +725,30 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men } else { + if (is_agent_inventory && !is_inbox && !is_cof && !is_in_favorites && !is_outfits) + { + LLViewerInventoryCategory* category = gInventory.getCategory(selected_id); + if (!category || !LLFriendCardsManager::instance().isCategoryInFriendFolder(category)) + { + items.push_back(std::string("New Folder")); + } + + items.push_back(std::string("create_new")); + items.push_back(std::string("New Script")); + items.push_back(std::string("New Note")); + items.push_back(std::string("New Gesture")); + items.push_back(std::string("New Material")); + items.push_back(std::string("New Clothes")); + items.push_back(std::string("New Body Parts")); + items.push_back(std::string("New Settings")); + } + if(can_share_item(selected_id)) { items.push_back(std::string("Share")); } - if (LLClipboard::instance().hasContents() && is_agent_inventory && !is_cof && !is_inbox_folder(selected_id)) + + if (LLClipboard::instance().hasContents() && is_agent_inventory && !is_cof && !is_inbox) { items.push_back(std::string("Paste")); @@ -519,7 +760,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men } if (is_folder && is_agent_inventory) { - if (!is_cof && (folder_type != LLFolderType::FT_OUTFIT) && !is_outfits && !is_inbox_folder(selected_id)) + if (!is_cof && (folder_type != LLFolderType::FT_OUTFIT) && !is_outfits && !is_inbox) { if (!gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD)) && !isRootFolder()) { @@ -715,6 +956,54 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men disabled_items.push_back(std::string("New Folder")); disabled_items.push_back(std::string("upload_def")); + disabled_items.push_back(std::string("create_new")); + } + + if (is_agent_inventory && !mRootFolder) + { + items.push_back(std::string("New folder from selected")); + items.push_back(std::string("Subfolder Separator")); + if (!is_only_items_selected(mUUIDs) && !is_only_cats_selected(mUUIDs)) + { + disabled_items.push_back(std::string("New folder from selected")); + } + } + + // Marketplace + bool can_list = false; + const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); + if (marketplacelistings_id.notNull() && !is_inbox && !obj->getIsLinkType()) + { + if (is_folder) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(selected_id); + if (cat + && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) + && gInventory.isObjectDescendentOf(selected_id, gInventory.getRootFolderID())) + { + can_list = true; + } + } + else if (selected_item + && selected_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()) + && selected_item->getPermissions().getOwner() != ALEXANDRIA_LINDEN_ID + && LLAssetType::AT_CALLINGCARD != selected_item->getType()) + { + can_list = true; + } + } + + if (can_list) + { + items.push_back(std::string("Marketplace Separator")); + items.push_back(std::string("Marketplace Copy")); + items.push_back(std::string("Marketplace Move")); + + if (!can_list_on_marketplace(selected_id)) + { + disabled_items.push_back(std::string("Marketplace Copy")); + disabled_items.push_back(std::string("Marketplace Move")); + } } } |