From ed02d0c1fccbfd25ed54f6be5b051736834d2e27 Mon Sep 17 00:00:00 2001 From: Leyla Farazha Date: Fri, 29 Jul 2011 17:01:24 -0700 Subject: EXP-843 Enable drag and drop to and from the outbox, with conditional warnings based on permissions EXP-1034 Add confirmation dialog for moving no-copy items to outbox --- indra/newview/llinventorybridge.cpp | 158 +++++++++++++++++++++++++++++++++++- 1 file changed, 155 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index ff328fd071..8eacb5a719 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -573,7 +573,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } // 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")); } @@ -794,6 +794,20 @@ BOOL LLInvFVBridge::isInboxFolder() const return gInventory.isObjectDescendentOf(mUUID, inbox_id); } + +BOOL LLInvFVBridge::isOutboxFolder() const +{ + const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); + + if (outbox_id.isNull()) + { + return FALSE; + } + + return gInventory.isObjectDescendentOf(mUUID, outbox_id); +} + + BOOL LLInvFVBridge::isItemPermissive() const { return FALSE; @@ -1648,6 +1662,55 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const } +static BOOL can_move_to_outbox(LLInventoryItem* inv_item) +{ + return inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); +} + + +void LLFolderBridge::dropFolderToOutbox(LLInventoryCategory* inv_cat) +{ + LLUUID dest_folder_id = gInventory.createNewCategory(mUUID, LLFolderType::FT_NONE, inv_cat->getName()); + + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(inv_cat->getUUID(),cat_array,item_array); + + for (LLInventoryModel::item_array_t::iterator iter = item_array->begin(); iter != item_array->end(); iter++) + { + LLInventoryItem* item = *iter; + if (item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + //LLPointer cb = new OutboxMoveCallback(); + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + dest_folder_id, + item->getName(), + LLPointer(NULL)); + + } + else + { + LLSD args; + args["ITEM_NAME"] = item->getName(); + LLSD payload; + payload["item_id"] = item->getUUID(); + payload["dest_folder_id"] = dest_folder_id; + LLNotificationsUtil::add("ConfirmNoCopyToOutbox", args, payload, boost::bind(&LLFolderBridge::moveToOutbox, this, _1, _2)); + } + + } + /* + // we need to also drill down recursively + for (LLInventoryModel::cat_array_t::iterator iter = cat_array->begin(); iter != cat_array->end(); iter++) + { + LLViewerInventoryCategory* category = gInventory.getCategory(dest_folder_id); + } + */ +} + BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, BOOL drop) { @@ -1674,10 +1737,12 @@ 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); //-------------------------------------------------------------------------------- // Determine if folder can be moved. @@ -1730,6 +1795,18 @@ 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)) + { + is_movable = FALSE; + break; + } + } + } // //-------------------------------------------------------------------------------- @@ -1797,6 +1874,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, #endif } } + if (move_is_into_outbox) + { + dropFolderToOutbox(inv_cat); + } else { if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) @@ -2635,7 +2716,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)) @@ -3003,6 +3084,67 @@ static BOOL can_move_to_landmarks(LLInventoryItem* inv_item) return LLAssetType::AT_LANDMARK == inv_item->getType(); } +void LLFolderBridge::dropToOutbox(LLInventoryItem* inv_item) +{ + if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + LLUUID dest_folder_id = mUUID; + + // when moving item directly into outbox create folder with that name + if (mUUID == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) + { + dest_folder_id = gInventory.createNewCategory(mUUID, LLFolderType::FT_NONE, inv_item->getName()); + } + + copy_inventory_item( + gAgent.getID(), + inv_item->getPermissions().getOwner(), + inv_item->getUUID(), + dest_folder_id, + inv_item->getName(), + LLPointer(NULL)); + + } + else + { + LLSD args; + args["ITEM_NAME"] = inv_item->getName(); + LLSD payload; + payload["item_id"] = inv_item->getUUID(); + payload["dest_folder_id"] = mUUID; + LLNotificationsUtil::add("ConfirmNoCopyToOutbox", args, payload, boost::bind(&LLFolderBridge::moveToOutbox, this, _1, _2)); + } +} + + +void LLFolderBridge::moveToOutbox(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return; // canceled + + + LLInventoryModel* model = getInventoryModel(); + LLViewerInventoryItem * viitem = gInventory.getItem(notification["payload"]["item_id"].asUUID()); + LLUUID dest_folder_id = notification["payload"]["dest_folder_id"].asUUID(); + + if (viitem) + { + + // when moving item directly into outbox create folder with that name + if (dest_folder_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) + { + dest_folder_id = gInventory.createNewCategory(mUUID, LLFolderType::FT_NONE, viitem->getName()); + } + + LLInvFVBridge::changeItemParent( + model, + viitem, + dest_folder_id, + false); + } + +} + void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item) { // use callback to rearrange favorite landmarks after adding @@ -3060,11 +3202,13 @@ 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); LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); BOOL accept = FALSE; @@ -3130,6 +3274,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); + } if(accept && drop) { @@ -3180,6 +3328,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { dropToOutfit(inv_item, move_is_into_current_outfit); } + else if (move_is_into_outbox) + { + dropToOutbox(inv_item); + } // NORMAL or TRASH folder // (move the item, restamp if into trash) else -- cgit v1.2.3 From e69efc8369a65008d41155717761fbaec0e309c5 Mon Sep 17 00:00:00 2001 From: Leyla Farazha Date: Fri, 12 Aug 2011 10:39:35 -0700 Subject: EXP-843 Enable drag and drop from the outbox EXP-1036 Disable most inventory functionality for the outbox view --- indra/newview/llinventorybridge.cpp | 186 ++++++++++++++---------------------- 1 file changed, 74 insertions(+), 112 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 8eacb5a719..a6a8bc662f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -610,6 +610,10 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -1664,51 +1668,17 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const static BOOL can_move_to_outbox(LLInventoryItem* inv_item) { - return inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + bool worn = get_is_item_worn(inv_item->getUUID()); + bool allow_transfer = inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + + return !worn && allow_transfer; } + void LLFolderBridge::dropFolderToOutbox(LLInventoryCategory* inv_cat) { - LLUUID dest_folder_id = gInventory.createNewCategory(mUUID, LLFolderType::FT_NONE, inv_cat->getName()); - - LLInventoryModel::cat_array_t* cat_array; - LLInventoryModel::item_array_t* item_array; - gInventory.getDirectDescendentsOf(inv_cat->getUUID(),cat_array,item_array); - - for (LLInventoryModel::item_array_t::iterator iter = item_array->begin(); iter != item_array->end(); iter++) - { - LLInventoryItem* item = *iter; - if (item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) - { - //LLPointer cb = new OutboxMoveCallback(); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - dest_folder_id, - item->getName(), - LLPointer(NULL)); - - } - else - { - LLSD args; - args["ITEM_NAME"] = item->getName(); - LLSD payload; - payload["item_id"] = item->getUUID(); - payload["dest_folder_id"] = dest_folder_id; - LLNotificationsUtil::add("ConfirmNoCopyToOutbox", args, payload, boost::bind(&LLFolderBridge::moveToOutbox, this, _1, _2)); - } - - } - /* - // we need to also drill down recursively - for (LLInventoryModel::cat_array_t::iterator iter = cat_array->begin(); iter != cat_array->end(); iter++) - { - LLViewerInventoryCategory* category = gInventory.getCategory(dest_folder_id); - } - */ + copy_folder_to_outbox(inv_cat, getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)); } BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, @@ -2574,6 +2544,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); @@ -2709,6 +2680,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(); @@ -2783,10 +2758,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); @@ -3084,67 +3062,6 @@ static BOOL can_move_to_landmarks(LLInventoryItem* inv_item) return LLAssetType::AT_LANDMARK == inv_item->getType(); } -void LLFolderBridge::dropToOutbox(LLInventoryItem* inv_item) -{ - if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) - { - LLUUID dest_folder_id = mUUID; - - // when moving item directly into outbox create folder with that name - if (mUUID == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) - { - dest_folder_id = gInventory.createNewCategory(mUUID, LLFolderType::FT_NONE, inv_item->getName()); - } - - copy_inventory_item( - gAgent.getID(), - inv_item->getPermissions().getOwner(), - inv_item->getUUID(), - dest_folder_id, - inv_item->getName(), - LLPointer(NULL)); - - } - else - { - LLSD args; - args["ITEM_NAME"] = inv_item->getName(); - LLSD payload; - payload["item_id"] = inv_item->getUUID(); - payload["dest_folder_id"] = mUUID; - LLNotificationsUtil::add("ConfirmNoCopyToOutbox", args, payload, boost::bind(&LLFolderBridge::moveToOutbox, this, _1, _2)); - } -} - - -void LLFolderBridge::moveToOutbox(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return; // canceled - - - LLInventoryModel* model = getInventoryModel(); - LLViewerInventoryItem * viitem = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - LLUUID dest_folder_id = notification["payload"]["dest_folder_id"].asUUID(); - - if (viitem) - { - - // when moving item directly into outbox create folder with that name - if (dest_folder_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) - { - dest_folder_id = gInventory.createNewCategory(mUUID, LLFolderType::FT_NONE, viitem->getName()); - } - - LLInvFVBridge::changeItemParent( - model, - viitem, - dest_folder_id, - false); - } - -} - void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item) { // use callback to rearrange favorite landmarks after adding @@ -3330,7 +3247,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } else if (move_is_into_outbox) { - dropToOutbox(inv_item); + copy_item_to_outbox(inv_item, outbox_id); } // NORMAL or TRASH folder // (move the item, restamp if into trash) @@ -3532,6 +3449,10 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -3608,6 +3529,10 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -3622,8 +3547,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); } @@ -3659,6 +3587,10 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -3673,8 +3605,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 @@ -3888,6 +3823,10 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -4145,6 +4084,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")); @@ -4198,6 +4141,10 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -4212,9 +4159,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); @@ -4471,6 +4421,10 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(isItemInTrash()) { addTrashContextMenuOptions(items, disabled_items); + } + else if(isOutboxFolder()) + { + items.push_back(std::string("Delete")); } else { @@ -4804,6 +4758,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); @@ -5201,6 +5159,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")); -- cgit v1.2.3 From 6f7132ca77d0507f2744bea5050a2ab1135cd88a Mon Sep 17 00:00:00 2001 From: Leyla Farazha Date: Mon, 15 Aug 2011 09:53:26 -0700 Subject: deleting folders after no-copy move to outbox --- indra/newview/llinventorybridge.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a6a8bc662f..ac53532e32 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1678,7 +1678,7 @@ static BOOL can_move_to_outbox(LLInventoryItem* inv_item) void LLFolderBridge::dropFolderToOutbox(LLInventoryCategory* inv_cat) { - copy_folder_to_outbox(inv_cat, getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)); + copy_folder_to_outbox(inv_cat, getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false), inv_cat->getUUID()); } BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, @@ -3247,7 +3247,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } else if (move_is_into_outbox) { - copy_item_to_outbox(inv_item, outbox_id); + copy_item_to_outbox(inv_item, outbox_id, LLUUID::null); } // NORMAL or TRASH folder // (move the item, restamp if into trash) -- cgit v1.2.3 From 8baafe6613e62a76c6a0b85842cc7d542d615e71 Mon Sep 17 00:00:00 2001 From: Leyla Farazha Date: Thu, 18 Aug 2011 14:33:54 -0700 Subject: EXP-1098 User can drag folders into Outbox with more than 3 levels of nested folders EXP-1100 Show tooltips when drag and drop operations are not allowed --- indra/newview/llinventorybridge.cpp | 88 ++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 11 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index ac53532e32..01d4153d3f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1666,10 +1666,19 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const } -static BOOL can_move_to_outbox(LLInventoryItem* inv_item) +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; } @@ -1681,8 +1690,53 @@ 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 = max(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(); @@ -1770,12 +1824,21 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, for (S32 i=0; i < descendent_items.count(); ++i) { LLInventoryItem* item = descendent_items[i]; - if (!can_move_to_outbox(item)) + 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; + } + } // @@ -2805,7 +2868,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; @@ -2825,7 +2889,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. @@ -2836,12 +2900,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: @@ -2851,7 +2915,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: @@ -3108,7 +3172,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(); @@ -3193,7 +3258,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } else if (move_is_into_outbox) { - accept = can_move_to_outbox(inv_item); + accept = can_move_to_outbox(inv_item, tooltip_msg); } if(accept && drop) @@ -3869,7 +3934,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; -- cgit v1.2.3 From 504fabba1d8d2ffd1d3c43368cbd1a8522ca2ebc Mon Sep 17 00:00:00 2001 From: Leyla Farazha Date: Thu, 18 Aug 2011 18:04:44 -0700 Subject: fixing inner inbox drag and drop --- indra/newview/llinventorybridge.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 01d4153d3f..5c13a46f56 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1767,6 +1767,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, 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. @@ -1907,7 +1908,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, #endif } } - if (move_is_into_outbox) + if (move_is_into_outbox && !move_is_from_outbox) { dropFolderToOutbox(inv_cat); } @@ -3191,6 +3192,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, 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; @@ -3310,7 +3312,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { dropToOutfit(inv_item, move_is_into_current_outfit); } - else if (move_is_into_outbox) + else if (move_is_into_outbox && !move_is_from_outbox) { copy_item_to_outbox(inv_item, outbox_id, LLUUID::null); } -- cgit v1.2.3 From 38aa19614e1242e02c23a5dd2fbf5fae49783ed9 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Fri, 19 Aug 2011 11:52:33 -0700 Subject: Mac build fix: changed "max" to "llmax" --- indra/newview/llinventorybridge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 5c13a46f56..0959a08359 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1703,7 +1703,7 @@ int get_folder_levels(LLInventoryCategory* inv_cat) for (S32 i=0; i < cats->count(); ++i) { LLInventoryCategory* category = cats->get(i); - max_child_levels = max(max_child_levels, get_folder_levels(category)); + max_child_levels = llmax(max_child_levels, get_folder_levels(category)); } return 1 + max_child_levels; -- cgit v1.2.3 From c2443b95d3cd9f0f26e5e8f5c2dbeb5f6c307447 Mon Sep 17 00:00:00 2001 From: "leslie@leslie-HPz600.lindenlab.com" Date: Fri, 26 Aug 2011 16:33:47 -0700 Subject: EXP-1126 FIX -- Cannot use arrow keys to scroll up and down in Inbox and Outbox EXP-1003 FIX -- Renaming a folder in Received Items panel resets the New flag for that folder EXP-1001 FIX -- Newness is removed on next login if you log out or crash before opening inventory panel EXP-857 FIX -- Add context menu entries as alternate path to populate outbox EXP-858 FIX -- Outbox sync failure error handling EXP-1158 FIX -- Viewer crash when deleting items from Outbox when some folders are open * Made inbox, outbox and inventory panels all legit tab stops for keyboard focus * Added mouse over indication on inventory panel primarily for increased clarity on outbox error messages * Disabled "Rename" option on inbox items * Added context menu option to copy/move an item to the merchant outbox * Context menu option to copy/move to outbox is visible and/or enabled/disabled when appropriate * "LastInventoryInboxCollapse" no longer written out as a setting when the panel is not visible * Fixed up collapse time check to not try to parse empty string on first load (deminishes text spam in log greatly) * Disabled double-click as a way to equip items in the inbox or outbox * Viewer code no longer removes items from the outbox after sync. We rely on the sim to do this now. * Basic outbox sync error handling now displays error messages as tooltips along with badge over item in outbox * Moved some scroll container default values out of code and into xml --- indra/newview/llinventorybridge.cpp | 144 +++++++++++++++++++++++++++++++----- 1 file changed, 127 insertions(+), 17 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0959a08359..f3429607e9 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -107,6 +107,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 +555,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,6 +590,26 @@ 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); + } + } } } @@ -798,10 +839,9 @@ BOOL LLInvFVBridge::isInboxFolder() const return gInventory.isObjectDescendentOf(mUUID, inbox_id); } - BOOL LLInvFVBridge::isOutboxFolder() const { - const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); + const LLUUID outbox_id = getOutboxFolder(); if (outbox_id.isNull()) { @@ -811,6 +851,12 @@ BOOL LLInvFVBridge::isOutboxFolder() const 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 { @@ -956,9 +1002,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; } @@ -1007,6 +1058,50 @@ BOOL LLInvFVBridge::canShare() const return FALSE; } +BOOL LLInvFVBridge::canListOnMarketplace() const +{ + 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; +} + +BOOL LLInvFVBridge::canListOnMarketplaceNow() const +{ + if (get_is_item_worn(mUUID)) + { + return FALSE; + } + + return TRUE; +} + + // +=================================================+ // | InventoryFVBridgeBuilder | // +=================================================+ @@ -1104,6 +1199,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() @@ -1244,7 +1349,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"); @@ -1312,6 +1417,11 @@ BOOL LLItemBridge::isItemRenameable() const return FALSE; } + if (isInboxFolder()) + { + return FALSE; + } + return (item->getPermissions().allowModifyBy(gAgent.getID())); } return FALSE; @@ -1475,16 +1585,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 | // +=================================================+ @@ -2324,6 +2424,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() -- cgit v1.2.3 From f1c01becf27ab92a39c90d725c5bc70c73286e65 Mon Sep 17 00:00:00 2001 From: "leslie@leslie-HPz600.lindenlab.com" Date: Tue, 30 Aug 2011 16:18:34 -0700 Subject: EXP-857 PROGRESS -- Add context menu entries as alternate path to populate outbox * Folders containing items being worn now have the "Copy to Marketplace" context menu item disabled. --- indra/newview/llinventorybridge.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index f3429607e9..fb5d145637 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1098,6 +1098,13 @@ BOOL LLInvFVBridge::canListOnMarketplaceNow() const 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; } -- cgit v1.2.3 From 4ad3676985fa6abbb764136f1ec658ddcf296058 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Thu, 8 Sep 2011 12:09:43 -0700 Subject: Disable merchant outbox context menu --- indra/newview/llinventorybridge.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b4dac28595..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 two_uuids_t; typedef std::list two_uuids_list_t; @@ -1060,6 +1063,7 @@ BOOL LLInvFVBridge::canShare() 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())) @@ -1089,10 +1093,14 @@ BOOL LLInvFVBridge::canListOnMarketplace() const } return TRUE; +#else + return FALSE; +#endif } BOOL LLInvFVBridge::canListOnMarketplaceNow() const { +#if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU if (get_is_item_worn(mUUID)) { return FALSE; @@ -1106,6 +1114,9 @@ BOOL LLInvFVBridge::canListOnMarketplaceNow() const } return TRUE; +#else + return FALSE; +#endif } -- cgit v1.2.3