Skip to content

Commit 5b11a77

Browse files
committed
#3757 Menu for subfodlers in outfits
1 parent d832abf commit 5b11a77

File tree

6 files changed

+202
-70
lines changed

6 files changed

+202
-70
lines changed

indra/newview/llinventorybridge.cpp

Lines changed: 140 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,44 @@ static bool check_item(const LLUUID& item_id,
105105

106106
// Helper functions
107107

108+
109+
namespace {
110+
enum EMyOutfitsSubfolderType
111+
{
112+
MY_OUTFITS_NO,
113+
MY_OUTFITS_SUBFOLDER,
114+
MY_OUTFITS_OUTFIT,
115+
};
116+
117+
EMyOutfitsSubfolderType myoutfit_object_subfolder_type(LLInventoryModel* model, const LLUUID& obj_id,
118+
const LLUUID& cat_id)
119+
{
120+
if (obj_id == cat_id) return MY_OUTFITS_NO;
121+
122+
const LLViewerInventoryCategory* test_cat = model->getCategory(obj_id);
123+
while (test_cat)
124+
{
125+
if (test_cat->getPreferredType() == LLFolderType::FT_OUTFIT)
126+
{
127+
return MY_OUTFITS_OUTFIT;
128+
}
129+
130+
const LLUUID& parent_id = test_cat->getParentUUID();
131+
if (parent_id.isNull())
132+
{
133+
return MY_OUTFITS_NO;
134+
}
135+
if (parent_id == cat_id)
136+
{
137+
return MY_OUTFITS_SUBFOLDER;
138+
}
139+
test_cat = model->getCategory(parent_id);
140+
}
141+
142+
return MY_OUTFITS_NO;
143+
}
144+
}
145+
108146
bool isAddAction(const std::string& action)
109147
{
110148
return ("wear" == action || "attach" == action || "activate" == action);
@@ -2912,13 +2950,22 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
29122950

29132951
if (mUUID == my_outifts_id)
29142952
{
2915-
// Category can contains objects,
2953+
// Category can't contains objects,
29162954
// create a new folder and populate it with links to original objects
29172955
dropToMyOutfits(inv_cat, cb);
29182956
}
2919-
else if (getCategory() && getCategory()->getParentUUID() == my_outifts_id)
2957+
else if (move_is_into_my_outfits)
29202958
{
2921-
dropToMyOutfitsSubfolder(inv_cat, mUUID, cb);
2959+
EMyOutfitsSubfolderType res = myoutfit_object_subfolder_type(model, mUUID, my_outifts_id);
2960+
if (res == MY_OUTFITS_SUBFOLDER)
2961+
{
2962+
// turn it into outfit
2963+
dropToMyOutfitsSubfolder(inv_cat, mUUID, LLFolderType::FT_OUTFIT, cb);
2964+
}
2965+
else
2966+
{
2967+
dropToMyOutfitsSubfolder(inv_cat, mUUID, LLFolderType::FT_NONE, cb);
2968+
}
29222969
}
29232970
// if target is current outfit folder we use link
29242971
else if (move_is_into_current_outfit &&
@@ -4012,6 +4059,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
40124059
{
40134060
if (!move_is_into_my_outfits && item && can_move_to_outfit(item, move_is_into_current_outfit))
40144061
{
4062+
// todo: this is going to create dupplicate folders?
40154063
dropToOutfit(item, move_is_into_current_outfit, cb);
40164064
}
40174065
else if (move_is_into_my_outfits && LLAssetType::AT_CATEGORY == obj->getType())
@@ -4024,9 +4072,18 @@ void LLFolderBridge::perform_pasteFromClipboard()
40244072
{
40254073
dropToMyOutfits(cat, cb);
40264074
}
4027-
else if (getCategory() && getCategory()->getParentUUID() == mUUID)
4075+
else if (move_is_into_my_outfits)
40284076
{
4029-
dropToMyOutfitsSubfolder(cat, mUUID, cb);
4077+
EMyOutfitsSubfolderType res = myoutfit_object_subfolder_type(model, mUUID, my_outifts_id);
4078+
if (res == MY_OUTFITS_SUBFOLDER)
4079+
{
4080+
// turn it into outfit
4081+
dropToMyOutfitsSubfolder(cat, mUUID, LLFolderType::FT_OUTFIT, cb);
4082+
}
4083+
else
4084+
{
4085+
dropToMyOutfitsSubfolder(cat, mUUID, LLFolderType::FT_NONE, cb);
4086+
}
40304087
}
40314088
}
40324089
else
@@ -4361,63 +4418,85 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
43614418
else if(isAgentInventory()) // do not allow creating in library
43624419
{
43634420
LLViewerInventoryCategory *cat = getCategory();
4364-
// BAP removed protected check to re-enable standard ops in untyped folders.
4365-
// Not sure what the right thing is to do here.
4366-
if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT))
4367-
{
4368-
if (!isInboxFolder() // don't allow creation in inbox
4369-
&& outfits_id != mUUID)
4370-
{
4371-
bool menu_items_added = false;
4372-
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
4373-
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
4374-
{
4375-
items.push_back(std::string("New Folder"));
4376-
menu_items_added = true;
4377-
}
4378-
if (!isMarketplaceListingsFolder())
4379-
{
4380-
items.push_back(std::string("upload_def"));
4381-
items.push_back(std::string("create_new"));
4382-
items.push_back(std::string("New Script"));
4383-
items.push_back(std::string("New Note"));
4384-
items.push_back(std::string("New Gesture"));
4385-
items.push_back(std::string("New Material"));
4386-
items.push_back(std::string("New Clothes"));
4387-
items.push_back(std::string("New Body Parts"));
4388-
items.push_back(std::string("New Settings"));
4389-
if (!LLEnvironment::instance().isInventoryEnabled())
4390-
{
4391-
disabled_items.push_back("New Settings");
4392-
}
4393-
}
4394-
else
4395-
{
4396-
items.push_back(std::string("New Listing Folder"));
4397-
}
4398-
if (menu_items_added)
4399-
{
4400-
items.push_back(std::string("Create Separator"));
4401-
}
4402-
}
4403-
getClipboardEntries(false, items, disabled_items, flags);
4404-
}
4405-
else
4421+
4422+
if (cat)
44064423
{
4407-
// Want some but not all of the items from getClipboardEntries for outfits.
4408-
if (cat && (cat->getPreferredType() == LLFolderType::FT_OUTFIT))
4424+
if (cat->getPreferredType() == LLFolderType::FT_OUTFIT)
44094425
{
4426+
// Want some but not all of the items from getClipboardEntries for outfits.
4427+
items.push_back(std::string("New Outfit Folder"));
44104428
items.push_back(std::string("Rename"));
44114429
items.push_back(std::string("thumbnail"));
44124430

44134431
addDeleteContextMenuOptions(items, disabled_items);
44144432
// EXT-4030: disallow deletion of currently worn outfit
4415-
const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
4433+
const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
44164434
if (base_outfit_link && (cat == base_outfit_link->getLinkedCategory()))
44174435
{
44184436
disabled_items.push_back(std::string("Delete"));
44194437
}
44204438
}
4439+
else if (outfits_id == mUUID)
4440+
{
4441+
getClipboardEntries(false, items, disabled_items, flags);
4442+
}
4443+
else if (!isCOFFolder())
4444+
{
4445+
EMyOutfitsSubfolderType in_my_outfits = myoutfit_object_subfolder_type(model, mUUID, outfits_id);
4446+
if (in_my_outfits != MY_OUTFITS_NO)
4447+
{
4448+
if (in_my_outfits == MY_OUTFITS_SUBFOLDER)
4449+
{
4450+
// Not inside an outfit, but inside 'my outfits'
4451+
items.push_back(std::string("New Outfit"));
4452+
}
4453+
4454+
items.push_back(std::string("New Outfit Folder"));
4455+
items.push_back(std::string("Rename"));
4456+
items.push_back(std::string("thumbnail"));
4457+
4458+
addDeleteContextMenuOptions(items, disabled_items);
4459+
}
4460+
else
4461+
{
4462+
if (!isInboxFolder() // don't allow creation in inbox
4463+
&& outfits_id != mUUID)
4464+
{
4465+
bool menu_items_added = false;
4466+
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
4467+
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
4468+
{
4469+
items.push_back(std::string("New Folder"));
4470+
menu_items_added = true;
4471+
}
4472+
if (!isMarketplaceListingsFolder())
4473+
{
4474+
items.push_back(std::string("upload_def"));
4475+
items.push_back(std::string("create_new"));
4476+
items.push_back(std::string("New Script"));
4477+
items.push_back(std::string("New Note"));
4478+
items.push_back(std::string("New Gesture"));
4479+
items.push_back(std::string("New Material"));
4480+
items.push_back(std::string("New Clothes"));
4481+
items.push_back(std::string("New Body Parts"));
4482+
items.push_back(std::string("New Settings"));
4483+
if (!LLEnvironment::instance().isInventoryEnabled())
4484+
{
4485+
disabled_items.push_back("New Settings");
4486+
}
4487+
}
4488+
else
4489+
{
4490+
items.push_back(std::string("New Listing Folder"));
4491+
}
4492+
if (menu_items_added)
4493+
{
4494+
items.push_back(std::string("Create Separator"));
4495+
}
4496+
}
4497+
getClipboardEntries(false, items, disabled_items, flags);
4498+
}
4499+
}
44214500
}
44224501

44234502
if (model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT) == mUUID)
@@ -4570,7 +4649,11 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
45704649

45714650
if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren() && (type != LLFolderType::FT_OUTFIT))
45724651
{
4573-
items.push_back(std::string("Ungroup folder items"));
4652+
const LLUUID my_outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
4653+
if (!gInventory.isObjectDescendentOf(mUUID, my_outfits))
4654+
{
4655+
items.push_back(std::string("Ungroup folder items"));
4656+
}
45744657
}
45754658
}
45764659
else
@@ -5350,23 +5433,23 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI
53505433
inv_cat->getThumbnailUUID());
53515434
}
53525435

5353-
void LLFolderBridge::dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id, LLPointer<LLInventoryCallback> cb)
5436+
void LLFolderBridge::dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id, LLFolderType::EType preferred_type, LLPointer<LLInventoryCallback> cb)
53545437
{
53555438
LLViewerInventoryCategory* cat = getInventoryModel()->getCategory(dest_id);
53565439
const LLUUID outfits_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
53575440
inventory_func_type func = boost::bind(outfitFolderCreatedCallback, inv_cat->getUUID(), _1, cb, mInventoryPanel);
53585441
if (cat && cat->getParentUUID() == outfits_id)
53595442
{
53605443
getInventoryModel()->createNewCategory(dest_id,
5361-
LLFolderType::FT_OUTFIT,
5444+
preferred_type,
53625445
inv_cat->getName(),
53635446
func,
53645447
inv_cat->getThumbnailUUID());
53655448
}
53665449
else
53675450
{
53685451
getInventoryModel()->createNewCategory(outfits_id,
5369-
LLFolderType::FT_OUTFIT,
5452+
preferred_type,
53705453
inv_cat->getName(),
53715454
func,
53725455
inv_cat->getThumbnailUUID());
@@ -5476,10 +5559,6 @@ bool LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
54765559
const bool move_is_into_favorites = (mUUID == favorites_id);
54775560
const bool move_is_into_my_outfits = (mUUID == my_outifts_id) || model->isObjectDescendentOf(mUUID, my_outifts_id);
54785561
const bool move_is_into_outfit = move_is_into_my_outfits || (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
5479-
const bool move_is_into_my_outfits_subfolder = move_is_into_my_outfits
5480-
&& getCategory()
5481-
&& getCategory()->getParentUUID() == my_outifts_id
5482-
&& getCategory()->getPreferredType() != LLFolderType::FT_OUTFIT;
54835562
const bool move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id);
54845563
const bool move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
54855564
const bool move_is_from_marketplacelistings = model->isObjectDescendentOf(inv_item->getUUID(), marketplacelistings_id);
@@ -5550,7 +5629,9 @@ bool LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
55505629
}
55515630
else if (user_confirm && (move_is_into_current_outfit || move_is_into_outfit))
55525631
{
5553-
accept = !move_is_into_my_outfits_subfolder && can_move_to_outfit(inv_item, move_is_into_current_outfit);
5632+
EMyOutfitsSubfolderType res = myoutfit_object_subfolder_type(model, mUUID, my_outifts_id);
5633+
// don't allow items in my outfits' subfodlers, only in outfits and outfit's subfolders
5634+
accept = res != MY_OUTFITS_SUBFOLDER && can_move_to_outfit(inv_item, move_is_into_current_outfit);
55545635
}
55555636
else if (user_confirm && (move_is_into_favorites || move_is_into_landmarks))
55565637
{

indra/newview/llinventorybridge.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ class LLFolderBridge : public LLInvFVBridge
369369
void dropToFavorites(LLInventoryItem* inv_item, LLPointer<LLInventoryCallback> cb = NULL);
370370
void dropToOutfit(LLInventoryItem* inv_item, bool move_is_into_current_outfit, LLPointer<LLInventoryCallback> cb = NULL);
371371
void dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLInventoryCallback> cb = NULL);
372-
void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest, LLPointer<LLInventoryCallback> cb = NULL);
372+
void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest, LLFolderType::EType preferred_type, LLPointer<LLInventoryCallback> cb = NULL);
373373

374374
//--------------------------------------------------------------------
375375
// Messy hacks for handling folder options

indra/newview/llinventorygallery.cpp

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,49 @@ static LLPanelInjector<LLInventoryGallery> t_inventory_gallery("inventory_galler
6060
const S32 GALLERY_ITEMS_PER_ROW_MIN = 2;
6161
const S32 FAST_LOAD_THUMBNAIL_TRSHOLD = 50; // load folders below this value immediately
6262

63+
64+
namespace {
65+
enum EMyOutfitsSubfolderType
66+
{
67+
MY_OUTFITS_NO,
68+
MY_OUTFITS_SUBFOLDER,
69+
MY_OUTFITS_OUTFIT,
70+
};
71+
72+
EMyOutfitsSubfolderType myoutfit_object_subfolder_type(LLInventoryModel* model, const LLUUID& obj_id,
73+
const LLUUID& cat_id)
74+
{
75+
if (obj_id == cat_id) return MY_OUTFITS_NO;
76+
77+
const LLViewerInventoryCategory* test_cat = model->getCategory(obj_id);
78+
while (test_cat)
79+
{
80+
if (test_cat->getPreferredType() == LLFolderType::FT_OUTFIT)
81+
{
82+
return MY_OUTFITS_OUTFIT;
83+
}
84+
85+
const LLUUID& parent_id = test_cat->getParentUUID();
86+
if (parent_id.isNull())
87+
{
88+
return MY_OUTFITS_NO;
89+
}
90+
if (parent_id == cat_id)
91+
{
92+
return MY_OUTFITS_SUBFOLDER;
93+
}
94+
test_cat = model->getCategory(parent_id);
95+
}
96+
97+
return MY_OUTFITS_NO;
98+
}
99+
}
100+
63101
// Helper dnd functions
64102
bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, bool drop, std::string& tooltip_msg, bool is_link);
65103
bool dragItemIntoFolder(LLUUID folder_id, LLInventoryItem* inv_item, bool drop, std::string& tooltip_msg, bool user_confirm);
66104
void dropToMyOutfits(LLInventoryCategory* inv_cat);
67-
void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id);
105+
void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id, LLFolderType::EType preferred_type);
68106

69107
class LLGalleryPanel: public LLPanel
70108
{
@@ -3899,9 +3937,18 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat,
38993937
// create a new folder and populate it with links to original objects
39003938
dropToMyOutfits(inv_cat);
39013939
}
3902-
else if (dest_cat && dest_cat->getParentUUID() == my_outifts_id)
3940+
else if (move_is_into_my_outfits)
39033941
{
3904-
dropToMyOutfitsSubfolder(inv_cat, dest_id);
3942+
EMyOutfitsSubfolderType res = myoutfit_object_subfolder_type(model, dest_id, my_outifts_id);
3943+
if (res == MY_OUTFITS_SUBFOLDER)
3944+
{
3945+
// turn it into outfit
3946+
dropToMyOutfitsSubfolder(inv_cat, dest_id, LLFolderType::FT_OUTFIT);
3947+
}
3948+
else
3949+
{
3950+
dropToMyOutfitsSubfolder(inv_cat, dest_id, LLFolderType::FT_NONE);
3951+
}
39053952
}
39063953
// if target is current outfit folder we use link
39073954
else if (move_is_into_current_outfit &&
@@ -4047,10 +4094,10 @@ void dropToMyOutfits(LLInventoryCategory* inv_cat)
40474094
gInventory.createNewCategory(dest_id, LLFolderType::FT_OUTFIT, inv_cat->getName(), func, inv_cat->getThumbnailUUID());
40484095
}
40494096

4050-
void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID &dest_id)
4097+
void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID &dest_id, LLFolderType::EType preferred_type)
40514098
{
40524099
// Note: creation will take time, so passing folder id to callback is slightly unreliable,
40534100
// but so is collecting and passing descendants' ids
40544101
inventory_func_type func = boost::bind(&outfitFolderCreatedCallback, inv_cat->getUUID(), _1);
4055-
gInventory.createNewCategory(dest_id, LLFolderType::FT_OUTFIT, inv_cat->getName(), func, inv_cat->getThumbnailUUID());
4102+
gInventory.createNewCategory(dest_id, preferred_type, inv_cat->getName(), func, inv_cat->getThumbnailUUID());
40564103
}

0 commit comments

Comments
 (0)