diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2025-05-07 22:29:08 +0300 |
---|---|---|
committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2025-05-08 18:46:33 +0300 |
commit | 37134720bce619a754ff097aff764d9a44bb0893 (patch) | |
tree | fdde1922360f0d42ab1c660eaecfc04e56c1a66f | |
parent | 50108bf0b7953e1f44a13b0790fe8dd8e9f7d2ca (diff) |
#3757 Smarter subfolders dragndrop
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 38 | ||||
-rw-r--r-- | indra/newview/llinventoryfunctions.cpp | 41 | ||||
-rw-r--r-- | indra/newview/llinventoryfunctions.h | 3 | ||||
-rw-r--r-- | indra/newview/llinventorygallery.cpp | 19 |
4 files changed, 87 insertions, 14 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 4018a89c5a..bff7138282 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2664,6 +2664,7 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // bool is_movable = true; + bool create_outfit = false; if (is_movable && (marketplacelistings_id == cat_id)) { @@ -2708,7 +2709,12 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, tooltip_msg = LLTrans::getString("TooltipOutfitNotInInventory"); is_movable = false; } - else if (can_move_to_my_outfits(model, inv_cat, max_items_to_wear)) + else if (can_move_to_my_outfits_as_outfit(model, inv_cat, max_items_to_wear)) + { + is_movable = true; + create_outfit = true; + } + else if (can_move_to_my_outfits_as_subfolder(model, inv_cat)) { is_movable = true; } @@ -2742,7 +2748,12 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, is_movable = false; tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); } - else if (can_move_to_my_outfits(model, inv_cat, max_items_to_wear)) + else if (can_move_to_my_outfits_as_outfit(model, inv_cat, max_items_to_wear)) + { + is_movable = true; + create_outfit = true; + } + else if (can_move_to_my_outfits_as_subfolder(model, inv_cat)) { is_movable = true; } @@ -2943,7 +2954,7 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, if (mUUID == my_outifts_id) { EMyOutfitsSubfolderType inv_res = myoutfit_object_subfolder_type(model, cat_id, my_outifts_id); - if (inv_res == MY_OUTFITS_SUBFOLDER || inv_res == MY_OUTFITS_OUTFIT) + if (inv_res == MY_OUTFITS_SUBFOLDER || inv_res == MY_OUTFITS_OUTFIT || !create_outfit) { LLInvFVBridge::changeCategoryParent( model, @@ -2967,7 +2978,7 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, { case MY_OUTFITS_NO: // Moning from outside outfits into outfits - if (dest_res == MY_OUTFITS_SUBFOLDER) + if (dest_res == MY_OUTFITS_SUBFOLDER && create_outfit) { // turn it into outfit dropToMyOutfitsSubfolder(inv_cat, mUUID, LLFolderType::FT_OUTFIT, cb); @@ -4094,7 +4105,6 @@ void LLFolderBridge::perform_pasteFromClipboard() LLInventoryObject *obj = model->getObject(item_id); if (obj) { - if (move_is_into_lost_and_found) { if (LLAssetType::AT_CATEGORY == obj->getType()) @@ -4111,9 +4121,9 @@ void LLFolderBridge::perform_pasteFromClipboard() } else if (move_is_into_my_outfits && LLAssetType::AT_CATEGORY == obj->getType()) { - LLInventoryCategory* cat = model->getCategory(item_id); + LLViewerInventoryCategory* cat = model->getCategory(item_id); U32 max_items_to_wear = gSavedSettings.getU32("WearFolderLimit"); - if (cat && can_move_to_my_outfits(model, cat, max_items_to_wear)) + if (cat && can_move_to_my_outfits_as_outfit(model, cat, max_items_to_wear)) { if (mUUID == my_outifts_id) { @@ -4133,6 +4143,18 @@ void LLFolderBridge::perform_pasteFromClipboard() } } } + else if (cat && can_move_to_my_outfits_as_subfolder(model, cat)) + { + if (LLClipboard::instance().isCutMode()) + { + changeCategoryParent(model, cat, parent_id, false); + if (cb) cb->fire(item_id); + } + else + { + copy_inventory_category(model, cat, parent_id); + } + } else { LLNotificationsUtil::add("MyOutfitsPasteFailed"); @@ -4181,7 +4203,7 @@ void LLFolderBridge::perform_pasteFromClipboard() // move_inventory_item() is not enough, as we have to update inventory locally too if (LLAssetType::AT_CATEGORY == obj->getType()) { - LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id); + LLViewerInventoryCategory* vicat = model->getCategory(item_id); llassert(vicat); if (vicat) { diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 7fff88fba7..9967318e92 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2314,7 +2314,7 @@ bool can_move_to_landmarks(LLInventoryItem* inv_item) } // Returns true if folder's content can be moved to Current Outfit or any outfit folder. -bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit) +bool can_move_to_my_outfits_as_outfit(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit) { LLInventoryModel::cat_array_t *cats; LLInventoryModel::item_array_t *items; @@ -2353,6 +2353,45 @@ bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_ca return true; } +bool can_move_to_my_outfits_as_subfolder(LLInventoryModel* model, LLInventoryCategory* inv_cat, S32 depth) +{ + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + model->getDirectDescendentsOf(inv_cat->getUUID(), cats, items); + + if (items->size() > 0) + { + // subfolders don't allow items + return false; + } + + constexpr size_t MAX_CONTENT = 255; + if (cats->size() > MAX_CONTENT) + { + // don't allow massive folders + return false; + } + + for (LLPointer<LLViewerInventoryCategory>& cat : *cats) + { + // outfits are valid to move, check non-outfit folders + if (cat->getPreferredType() != LLFolderType::FT_OUTFIT) + { + if (depth == 3) + { + // don't allow massive folders + return false; + } + if (!can_move_to_my_outfits_as_subfolder(model, cat, depth + 1)) + { + return false; + } + } + } + + return true; +} + std::string get_localized_folder_name(LLUUID cat_uuid) { std::string localized_root_name; diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 0ab045f2a0..f56413bf5d 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -112,7 +112,8 @@ std::string get_category_path(LLUUID cat_id); bool can_move_to_outfit(LLInventoryItem* inv_item, bool move_is_into_current_outfit); bool can_move_to_landmarks(LLInventoryItem* inv_item); -bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit); +bool can_move_to_my_outfits_as_outfit(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit); +bool can_move_to_my_outfits_as_subfolder(LLInventoryModel* model, LLInventoryCategory* inv_cat, S32 depth = 0); std::string get_localized_folder_name(LLUUID cat_uuid); void new_folder_window(const LLUUID& folder_id); void ungroup_folder_items(const LLUUID& folder_id); diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp index eb47af85fd..3222dff1b2 100644 --- a/indra/newview/llinventorygallery.cpp +++ b/indra/newview/llinventorygallery.cpp @@ -3714,6 +3714,7 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, // bool is_movable = true; + bool create_outfit = false; if (is_movable && (marketplacelistings_id == cat_id)) { @@ -3759,7 +3760,12 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, tooltip_msg = LLTrans::getString("TooltipOutfitNotInInventory"); is_movable = false; } - else if (can_move_to_my_outfits(model, inv_cat, max_items_to_wear)) + else if (can_move_to_my_outfits_as_outfit(model, inv_cat, max_items_to_wear)) + { + is_movable = true; + create_outfit = true; + } + else if (can_move_to_my_outfits_as_subfolder(model, inv_cat)) { is_movable = true; } @@ -3793,7 +3799,12 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, is_movable = false; tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); } - else if (can_move_to_my_outfits(model, inv_cat, max_items_to_wear)) + else if (can_move_to_my_outfits_as_outfit(model, inv_cat, max_items_to_wear)) + { + is_movable = true; + create_outfit = true; + } + else if (can_move_to_my_outfits_as_subfolder(model, inv_cat)) { is_movable = true; } @@ -3928,7 +3939,7 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, if (dest_id == my_outifts_id) { EMyOutfitsSubfolderType inv_res = myoutfit_object_subfolder_type(model, cat_id, my_outifts_id); - if (inv_res == MY_OUTFITS_SUBFOLDER || inv_res == MY_OUTFITS_OUTFIT) + if (inv_res == MY_OUTFITS_SUBFOLDER || inv_res == MY_OUTFITS_OUTFIT || !create_outfit) { gInventory.changeCategoryParent( (LLViewerInventoryCategory*)inv_cat, @@ -3950,7 +3961,7 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, { case MY_OUTFITS_NO: // Moning from outside outfits into outfits - if (dest_res == MY_OUTFITS_SUBFOLDER) + if (dest_res == MY_OUTFITS_SUBFOLDER && create_outfit) { // turn it into outfit dropToMyOutfitsSubfolder(inv_cat, dest_id, LLFolderType::FT_OUTFIT); |