#3757 Allow subfolders in "My Outfits"
parent
a7f3785cd6
commit
b95b20a1be
|
|
@ -122,7 +122,7 @@ void LLAppearanceListener::getOutfitsList(LLSD const &data)
|
|||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
|
||||
LLIsType is_category(LLAssetType::AT_CATEGORY);
|
||||
LLIsFolderType is_category(LLFolderType::FT_OUTFIT);
|
||||
gInventory.collectDescendentsIf(outfits_id, cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, is_category);
|
||||
|
||||
response["outfits"] = llsd::toMap(cat_array,
|
||||
|
|
|
|||
|
|
@ -2916,6 +2916,10 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
|
|||
// create a new folder and populate it with links to original objects
|
||||
dropToMyOutfits(inv_cat, cb);
|
||||
}
|
||||
else if (getCategory() && getCategory()->getParentUUID() == my_outifts_id)
|
||||
{
|
||||
dropToMyOutfitsSubfolder(inv_cat, mUUID, cb);
|
||||
}
|
||||
// if target is current outfit folder we use link
|
||||
else if (move_is_into_current_outfit &&
|
||||
(inv_cat->getPreferredType() == LLFolderType::FT_NONE ||
|
||||
|
|
@ -4016,7 +4020,14 @@ void LLFolderBridge::perform_pasteFromClipboard()
|
|||
U32 max_items_to_wear = gSavedSettings.getU32("WearFolderLimit");
|
||||
if (cat && can_move_to_my_outfits(model, cat, max_items_to_wear))
|
||||
{
|
||||
dropToMyOutfits(cat, cb);
|
||||
if (mUUID == my_outifts_id)
|
||||
{
|
||||
dropToMyOutfits(cat, cb);
|
||||
}
|
||||
else if (getCategory() && getCategory()->getParentUUID() == mUUID)
|
||||
{
|
||||
dropToMyOutfitsSubfolder(cat, mUUID, cb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -4256,6 +4267,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
|
||||
if (outfits_id == mUUID)
|
||||
{
|
||||
items.push_back(std::string("New Outfit Folder"));
|
||||
items.push_back(std::string("New Outfit"));
|
||||
}
|
||||
|
||||
|
|
@ -5331,13 +5343,36 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI
|
|||
// Note: creation will take time, so passing folder id to callback is slightly unreliable,
|
||||
// but so is collecting and passing descendants' ids
|
||||
inventory_func_type func = boost::bind(outfitFolderCreatedCallback, inv_cat->getUUID(), _1, cb, mInventoryPanel);
|
||||
gInventory.createNewCategory(dest_id,
|
||||
getInventoryModel()->createNewCategory(dest_id,
|
||||
LLFolderType::FT_OUTFIT,
|
||||
inv_cat->getName(),
|
||||
func,
|
||||
inv_cat->getThumbnailUUID());
|
||||
}
|
||||
|
||||
void LLFolderBridge::dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id, LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = getInventoryModel()->getCategory(dest_id);
|
||||
const LLUUID outfits_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
|
||||
inventory_func_type func = boost::bind(outfitFolderCreatedCallback, inv_cat->getUUID(), _1, cb, mInventoryPanel);
|
||||
if (cat && cat->getParentUUID() == outfits_id)
|
||||
{
|
||||
getInventoryModel()->createNewCategory(dest_id,
|
||||
LLFolderType::FT_OUTFIT,
|
||||
inv_cat->getName(),
|
||||
func,
|
||||
inv_cat->getThumbnailUUID());
|
||||
}
|
||||
else
|
||||
{
|
||||
getInventoryModel()->createNewCategory(outfits_id,
|
||||
LLFolderType::FT_OUTFIT,
|
||||
inv_cat->getName(),
|
||||
func,
|
||||
inv_cat->getThumbnailUUID());
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id,
|
||||
LLUUID cat_dest_id,
|
||||
LLPointer<LLInventoryCallback> cb,
|
||||
|
|
@ -5441,6 +5476,10 @@ bool LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
|
|||
const bool move_is_into_favorites = (mUUID == favorites_id);
|
||||
const bool move_is_into_my_outfits = (mUUID == my_outifts_id) || model->isObjectDescendentOf(mUUID, my_outifts_id);
|
||||
const bool move_is_into_outfit = move_is_into_my_outfits || (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
|
||||
const bool move_is_into_my_outfits_subfolder = move_is_into_my_outfits
|
||||
&& getCategory()
|
||||
&& getCategory()->getParentUUID() == my_outifts_id
|
||||
&& getCategory()->getPreferredType() != LLFolderType::FT_OUTFIT;
|
||||
const bool move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id);
|
||||
const bool move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
|
||||
const bool move_is_from_marketplacelistings = model->isObjectDescendentOf(inv_item->getUUID(), marketplacelistings_id);
|
||||
|
|
@ -5511,7 +5550,7 @@ bool LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
|
|||
}
|
||||
else if (user_confirm && (move_is_into_current_outfit || move_is_into_outfit))
|
||||
{
|
||||
accept = can_move_to_outfit(inv_item, move_is_into_current_outfit);
|
||||
accept = !move_is_into_my_outfits_subfolder && can_move_to_outfit(inv_item, move_is_into_current_outfit);
|
||||
}
|
||||
else if (user_confirm && (move_is_into_favorites || move_is_into_landmarks))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -369,6 +369,7 @@ protected:
|
|||
void dropToFavorites(LLInventoryItem* inv_item, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void dropToOutfit(LLInventoryItem* inv_item, bool move_is_into_current_outfit, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Messy hacks for handling folder options
|
||||
|
|
|
|||
|
|
@ -2621,6 +2621,11 @@ bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(const LLInventoryIte
|
|||
return false;
|
||||
}
|
||||
|
||||
bool LLIsFolderType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
return cat && cat->getPreferredType() == mType;
|
||||
}
|
||||
|
||||
bool LLIsType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if(mType == LLAssetType::AT_CATEGORY)
|
||||
|
|
|
|||
|
|
@ -234,6 +234,24 @@ protected:
|
|||
// the type is the type passed in during construction.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLIsFolderType : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLIsFolderType(LLFolderType::EType type) : mType(type) {}
|
||||
virtual ~LLIsFolderType() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item);
|
||||
protected:
|
||||
LLFolderType::EType mType;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLIsType
|
||||
//
|
||||
// Implementation of a LLInventoryCollectFunctor which returns true if
|
||||
// the type is the type passed in during construction.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLIsType : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ const S32 FAST_LOAD_THUMBNAIL_TRSHOLD = 50; // load folders below this value imm
|
|||
bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, bool drop, std::string& tooltip_msg, bool is_link);
|
||||
bool dragItemIntoFolder(LLUUID folder_id, LLInventoryItem* inv_item, bool drop, std::string& tooltip_msg, bool user_confirm);
|
||||
void dropToMyOutfits(LLInventoryCategory* inv_cat);
|
||||
void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id);
|
||||
|
||||
class LLGalleryPanel: public LLPanel
|
||||
{
|
||||
|
|
@ -3898,6 +3899,10 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat,
|
|||
// create a new folder and populate it with links to original objects
|
||||
dropToMyOutfits(inv_cat);
|
||||
}
|
||||
else if (dest_cat && dest_cat->getParentUUID() == my_outifts_id)
|
||||
{
|
||||
dropToMyOutfitsSubfolder(inv_cat, dest_id);
|
||||
}
|
||||
// if target is current outfit folder we use link
|
||||
else if (move_is_into_current_outfit &&
|
||||
(inv_cat->getPreferredType() == LLFolderType::FT_NONE ||
|
||||
|
|
@ -4041,3 +4046,11 @@ void dropToMyOutfits(LLInventoryCategory* inv_cat)
|
|||
inventory_func_type func = boost::bind(&outfitFolderCreatedCallback, inv_cat->getUUID(), _1);
|
||||
gInventory.createNewCategory(dest_id, LLFolderType::FT_OUTFIT, inv_cat->getName(), func, inv_cat->getThumbnailUUID());
|
||||
}
|
||||
|
||||
void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID &dest_id)
|
||||
{
|
||||
// Note: creation will take time, so passing folder id to callback is slightly unreliable,
|
||||
// but so is collecting and passing descendants' ids
|
||||
inventory_func_type func = boost::bind(&outfitFolderCreatedCallback, inv_cat->getUUID(), _1);
|
||||
gInventory.createNewCategory(dest_id, LLFolderType::FT_OUTFIT, inv_cat->getName(), func, inv_cat->getThumbnailUUID());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -771,6 +771,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
|
|||
|
||||
if(is_outfits && !isRootFolder())
|
||||
{
|
||||
items.push_back(std::string("New Outfit Folder"));
|
||||
items.push_back(std::string("New Outfit"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -819,6 +819,49 @@ void LLOutfitListBase::observerCallback(const LLUUID& category_id)
|
|||
refreshList(category_id);
|
||||
}
|
||||
|
||||
class LLIsOutfitListFolder : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLIsOutfitListFolder()
|
||||
{
|
||||
mOutfitsId = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
|
||||
}
|
||||
virtual ~LLIsOutfitListFolder() {}
|
||||
|
||||
bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) override
|
||||
{
|
||||
if (cat)
|
||||
{
|
||||
if (cat->getPreferredType() == LLFolderType::FT_OUTFIT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (cat->getPreferredType() == LLFolderType::FT_NONE
|
||||
&& cat->getParentUUID() == mOutfitsId)
|
||||
{
|
||||
LLViewerInventoryCategory* inv_cat = dynamic_cast<LLViewerInventoryCategory*>(cat);
|
||||
if (inv_cat && inv_cat->getDescendentCount() > 3)
|
||||
{
|
||||
LLInventoryModel::cat_array_t* cats;
|
||||
LLInventoryModel::item_array_t* items;
|
||||
gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cats, items);
|
||||
if (items->size() > 3) // eyes, skin, hair and shape are required
|
||||
{
|
||||
// For now assume this to be an old style outfit, not a subfolder
|
||||
// but ideally no such 'outfits' should be left in My Outfits
|
||||
// Todo: stop counting FT_NONE as outfits,
|
||||
// convert obvious outfits into FT_OUTFIT
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected:
|
||||
LLUUID mOutfitsId;
|
||||
};
|
||||
|
||||
void LLOutfitListBase::refreshList(const LLUUID& category_id)
|
||||
{
|
||||
bool wasNull = mRefreshListState.CategoryUUID.isNull();
|
||||
|
|
@ -828,13 +871,13 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id)
|
|||
LLInventoryModel::item_array_t item_array;
|
||||
|
||||
// Collect all sub-categories of a given category.
|
||||
LLIsType is_category(LLAssetType::AT_CATEGORY);
|
||||
LLIsOutfitListFolder is_outfit;
|
||||
gInventory.collectDescendentsIf(
|
||||
category_id,
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_category);
|
||||
is_outfit);
|
||||
|
||||
// Memorize item names for each UUID
|
||||
std::map<LLUUID, std::string> names;
|
||||
|
|
|
|||
|
|
@ -151,6 +151,14 @@
|
|||
function="Inventory.DoCreate"
|
||||
parameter="category" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Folder"
|
||||
layout="topleft"
|
||||
name="New Outfit Folder">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoCreate"
|
||||
parameter="category" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Outfit"
|
||||
layout="topleft"
|
||||
|
|
|
|||
Loading…
Reference in New Issue