svn merge -r129617:130277 svn+ssh://svn.lindenlab.com/svn/linden/branches/avatar-pipeline/currently-worn-folder-5 into svn+ssh://svn.lindenlab.com/svn/linden/branches/viewer/viewer-2.0.0-3
For DEV-34223 : AVP Current Outfit Folder For DEV-37485 : AVP Appearance Side Panel For DEV-35335 : AVP Automatic Folder Classification This merges the Appearance Side Panel / Ensemble Typing / Current Outfit Folder work for the AVP team.master
parent
0bf4b5f222
commit
7bbc5cdea6
|
|
@ -282,6 +282,12 @@ bool LLAssetType::lookupIsProtectedCategoryType(EType asset_type)
|
|||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLAssetType::lookupIsEnsembleCategoryType(EType asset_type)
|
||||
{
|
||||
return (asset_type >= AT_FOLDER_ENSEMBLE_START &&
|
||||
asset_type <= AT_FOLDER_ENSEMBLE_END);
|
||||
}
|
||||
|
||||
// static. Generate a good default description
|
||||
void LLAssetType::generateDescriptionFor(LLAssetType::EType asset_type,
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ public:
|
|||
|
||||
static const char* lookupCategoryName(EType asset_type);
|
||||
static bool lookupIsProtectedCategoryType(EType asset_type);
|
||||
static bool lookupIsEnsembleCategoryType(EType asset_type);
|
||||
|
||||
/* TODO: Change return types from "const char *" to "const std::string &".
|
||||
This is fairly straightforward, but requires changing some calls to use .c_str().
|
||||
|
|
|
|||
|
|
@ -133,6 +133,11 @@ LLAssetType::EType LLInventoryObject::getActualType() const
|
|||
return mType;
|
||||
}
|
||||
|
||||
BOOL LLInventoryObject::getIsLinkType() const
|
||||
{
|
||||
return LLAssetType::lookupIsLinkType(mType);
|
||||
}
|
||||
|
||||
// See LLInventoryItem override.
|
||||
// virtual
|
||||
const LLUUID& LLInventoryObject::getLinkedUUID() const
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public:
|
|||
virtual const std::string& getName() const;
|
||||
virtual LLAssetType::EType getType() const;
|
||||
LLAssetType::EType getActualType() const; // bypasses indirection for linked items
|
||||
|
||||
BOOL getIsLinkType() const;
|
||||
// mutators - will not call updateServer();
|
||||
void setUUID(const LLUUID& new_uuid);
|
||||
void rename(const std::string& new_name);
|
||||
|
|
|
|||
|
|
@ -278,6 +278,8 @@ set(viewer_SOURCE_FILES
|
|||
llnotify.cpp
|
||||
lloutputmonitorctrl.cpp
|
||||
lloverlaybar.cpp
|
||||
llpanelappearance.cpp
|
||||
llpanelappearancetab.cpp
|
||||
llpanelavatar.cpp
|
||||
llpanelavatarrow.cpp
|
||||
llpanelavatartag.cpp
|
||||
|
|
@ -305,6 +307,8 @@ set(viewer_SOURCE_FILES
|
|||
llpanellandmarks.cpp
|
||||
llpanellandmedia.cpp
|
||||
llpanellogin.cpp
|
||||
llpanellookinfo.cpp
|
||||
llpanellooks.cpp
|
||||
llpanelmedia.cpp
|
||||
llpanelmeprofile.cpp
|
||||
llpanelmovetip.cpp
|
||||
|
|
@ -719,6 +723,8 @@ set(viewer_HEADER_FILES
|
|||
llnotify.h
|
||||
lloutputmonitorctrl.h
|
||||
lloverlaybar.h
|
||||
llpanelappearance.h
|
||||
llpanelappearancetab.h
|
||||
llpanelavatar.h
|
||||
llpanelavatarrow.h
|
||||
llpanelavatartag.h
|
||||
|
|
@ -746,6 +752,8 @@ set(viewer_HEADER_FILES
|
|||
llpanellandmarks.h
|
||||
llpanellandmedia.h
|
||||
llpanellogin.h
|
||||
llpanellookinfo.h
|
||||
llpanellooks.h
|
||||
llpanelmedia.h
|
||||
llpanelmeprofile.h
|
||||
llpanelmovetip.h
|
||||
|
|
|
|||
|
|
@ -9,50 +9,66 @@
|
|||
asset_num="27"
|
||||
xui_name="head"
|
||||
icon_name="inv_folder_outfit_head.tga"
|
||||
allowed="hair,eyes"
|
||||
/>
|
||||
<ensemble
|
||||
asset_num="28"
|
||||
xui_name="gloves"
|
||||
icon_name="inv_folder_outfit_gloves.tga"
|
||||
allowed="gloves"
|
||||
/>
|
||||
<ensemble
|
||||
asset_num="29"
|
||||
xui_name="jacket"
|
||||
icon_name="inv_folder_outfit_jacket.tga"
|
||||
allowed="jacket"
|
||||
/>
|
||||
<ensemble
|
||||
asset_num="30"
|
||||
xui_name="pants"
|
||||
icon_name="inv_folder_outfit_pants.tga"
|
||||
allowed="pants,underpants"
|
||||
/>
|
||||
<ensemble
|
||||
asset_num="31"
|
||||
xui_name="shape"
|
||||
icon_name="inv_folder_outfit_shape.tga"
|
||||
allowed="shape,skin,hair,eyes"
|
||||
/>
|
||||
<ensemble
|
||||
asset_num="32"
|
||||
xui_name="shoes"
|
||||
icon_name="inv_folder_outfit_shoes.tga"
|
||||
allowed="shoes,socks"
|
||||
/>
|
||||
<ensemble
|
||||
asset_num="33"
|
||||
xui_name="shirt"
|
||||
icon_name="inv_folder_outfit_shirt.tga"
|
||||
allowed="shirt,undershirt"
|
||||
/>
|
||||
<ensemble
|
||||
asset_num="34"
|
||||
xui_name="skirt"
|
||||
icon_name="inv_folder_outfit_skirt.tga"
|
||||
allowed=""
|
||||
/>
|
||||
<ensemble
|
||||
asset_num="35"
|
||||
xui_name="underpants"
|
||||
icon_name="inv_folder_outfit_underpants.tga"
|
||||
allowed="underpants"
|
||||
/>
|
||||
<ensemble
|
||||
asset_num="36"
|
||||
xui_name="undershirt"
|
||||
icon_name="inv_folder_outfit_undershirt.tga"
|
||||
allowed="undershirt"
|
||||
/>
|
||||
<ensemble
|
||||
asset_num="47"
|
||||
xui_name="outfit"
|
||||
icon_name="inv_folder_outfit.tga"
|
||||
allowed="outfit"
|
||||
/>
|
||||
</ensemble_defs>
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include "llfloatercustomize.h"
|
||||
#include "llfloaterinventory.h"
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llnotify.h"
|
||||
#include "llviewerregion.h"
|
||||
|
|
@ -46,6 +47,9 @@
|
|||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
// For viewer2.0 internal demo, don't use current outfit folder contents at all during initial startup. Will reenable
|
||||
// this once we're sure this works completely.
|
||||
// #define USE_CURRENT_OUTFIT_FOLDER
|
||||
|
||||
LLAgentWearables gAgentWearables;
|
||||
|
||||
|
|
@ -662,13 +666,6 @@ BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
struct InitialWearableData
|
||||
{
|
||||
S32 mType;
|
||||
U32 mIndex;
|
||||
LLUUID mItemID;
|
||||
};
|
||||
|
||||
// MULTI-WEARABLE: update for multiple
|
||||
// static
|
||||
void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data)
|
||||
|
|
@ -696,14 +693,18 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
|
|||
return;
|
||||
}
|
||||
|
||||
// Get the UUID of the current outfit folder (will be created if it doesn't exist)
|
||||
LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
|
||||
|
||||
LLOutfitFolderFetch* outfit = new LLOutfitFolderFetch();
|
||||
|
||||
//lldebugs << "processAgentInitialWearablesUpdate()" << llendl;
|
||||
// Add wearables
|
||||
LLUUID asset_id_array[WT_COUNT];
|
||||
LLUUID item_id_array[WT_COUNT];
|
||||
// MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element.
|
||||
gAgentWearables.mItemsAwaitingWearableUpdate.clear();
|
||||
for (S32 i=0; i < num_wearables; i++)
|
||||
{
|
||||
// Parse initial werables data from message system
|
||||
U8 type_u8 = 0;
|
||||
gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i);
|
||||
if (type_u8 >= WT_COUNT)
|
||||
|
|
@ -711,10 +712,10 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
|
|||
continue;
|
||||
}
|
||||
const EWearableType type = (EWearableType) type_u8;
|
||||
|
||||
|
||||
LLUUID item_id;
|
||||
gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i);
|
||||
|
||||
|
||||
LLUUID asset_id;
|
||||
gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i);
|
||||
if (asset_id.isNull())
|
||||
|
|
@ -728,33 +729,76 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// MULTI-WEARABLE: extend arrays to index by type + index.
|
||||
gAgentWearables.mItemsAwaitingWearableUpdate.insert(item_id);
|
||||
item_id_array[type] = item_id;
|
||||
asset_id_array[type] = asset_id;
|
||||
|
||||
// MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element.
|
||||
|
||||
// Store initial wearables data until we know whether we have the current outfit folder or need to use the data.
|
||||
InitialWearableData * temp_wearable_data = new InitialWearableData(type, 0, item_id, asset_id); // MULTI-WEARABLE: update
|
||||
outfit->mAgentInitialWearables.push_back(temp_wearable_data);
|
||||
|
||||
}
|
||||
|
||||
lldebugs << " " << LLWearableDictionary::getTypeLabel(type) << llendl;
|
||||
}
|
||||
|
||||
// now that we have the asset ids...request the wearable assets
|
||||
for (S32 i = 0; i < WT_COUNT; i++)
|
||||
|
||||
// What we do here is get the complete information on the items in
|
||||
// the inventory, and set up an observer that will wait for that to
|
||||
// happen.
|
||||
LLInventoryFetchDescendentsObserver::folder_ref_t folders;
|
||||
folders.push_back(current_outfit_id);
|
||||
outfit->fetchDescendents(folders);
|
||||
if(outfit->isEverythingComplete())
|
||||
{
|
||||
// MULTI-WEARABLE: TODO: update once messages change.
|
||||
// Currently use results to populate the zeroth element.
|
||||
if (!item_id_array[i].isNull())
|
||||
{
|
||||
InitialWearableData *wear_data = new InitialWearableData;
|
||||
wear_data->mType = i;
|
||||
wear_data->mIndex = 0; // MULTI-WEARABLE: update
|
||||
wear_data->mItemID = item_id_array[i];
|
||||
LLWearableList::instance().getAsset(asset_id_array[i],
|
||||
LLStringUtil::null,
|
||||
LLWearableDictionary::getAssetType((EWearableType) i),
|
||||
onInitialWearableAssetArrived, (void*)wear_data);
|
||||
}
|
||||
// everything is already here - call done.
|
||||
outfit->done();
|
||||
}
|
||||
else
|
||||
{
|
||||
// it's all on it's way - add an observer, and the inventory
|
||||
// will call done for us when everything is here.
|
||||
gInventory.addObserver(outfit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAgentWearables::fetchInitialWearables(initial_wearable_data_vec_t & current_outfit_links, initial_wearable_data_vec_t & message_wearables)
|
||||
{
|
||||
#ifdef USE_CURRENT_OUTFIT_FOLDER
|
||||
if (!current_outfit_links.empty())
|
||||
{
|
||||
for (U8 i = 0; i < current_outfit_links.size(); ++i)
|
||||
{
|
||||
// Fetch the wearables in the current outfit folder
|
||||
LLWearableList::instance().getAsset(current_outfit_links[i]->mAssetID,
|
||||
LLStringUtil::null,
|
||||
LLWearableDictionary::getAssetType(current_outfit_links[i]->mType),
|
||||
onInitialWearableAssetArrived, (void*)(current_outfit_links[i]));
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!message_wearables.empty()) // We have an empty current outfit folder, use the message data instead.
|
||||
{
|
||||
LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
|
||||
for (U8 i = 0; i < message_wearables.size(); ++i)
|
||||
{
|
||||
// Populate the current outfit folder with links to the wearables passed in the message
|
||||
#ifdef USE_CURRENT_OUTFIT_FOLDER
|
||||
std::string link_name = "WearableLink";
|
||||
link_inventory_item(gAgent.getID(), message_wearables[i]->mItemID, current_outfit_id, link_name,
|
||||
LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
|
||||
#endif
|
||||
// Fetch the wearables
|
||||
LLWearableList::instance().getAsset(message_wearables[i]->mAssetID,
|
||||
LLStringUtil::null,
|
||||
LLWearableDictionary::getAssetType(message_wearables[i]->mType),
|
||||
onInitialWearableAssetArrived, (void*)(message_wearables[i]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Wearables") << "No current outfit folder iterms found and no initial wearables fallback message received." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -763,7 +807,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
|
|||
void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* userdata)
|
||||
{
|
||||
boost::scoped_ptr<InitialWearableData> wear_data((InitialWearableData*)userdata);
|
||||
const EWearableType type = (EWearableType)wear_data->mType;
|
||||
const EWearableType type = wear_data->mType;
|
||||
const U32 index = wear_data->mIndex;
|
||||
|
||||
LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
|
||||
|
|
@ -775,10 +819,11 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void*
|
|||
if (wearable)
|
||||
{
|
||||
llassert(type == wearable->getType());
|
||||
// MULTI-WEARABLE: is this always zeroth element? Change sometime.
|
||||
wearable->setItemID(wear_data->mItemID);
|
||||
gAgentWearables.setWearable(type,index,wearable);
|
||||
gAgentWearables.setWearable(type, index, wearable);
|
||||
gAgentWearables.mItemsAwaitingWearableUpdate.erase(wear_data->mItemID);
|
||||
|
||||
|
||||
// disable composites if initial textures are baked
|
||||
avatar->setupComposites();
|
||||
|
||||
|
|
@ -954,6 +999,8 @@ void LLAgentWearables::createStandardWearablesAllDone()
|
|||
mAvatarObject->onFirstTEMessageReceived();
|
||||
}
|
||||
|
||||
// Note: wearables_to_include should be a list of EWearableType types
|
||||
// attachments_to_include should be a list of attachment points
|
||||
void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name,
|
||||
const LLDynamicArray<S32>& wearables_to_include,
|
||||
const LLDynamicArray<S32>& attachments_to_include,
|
||||
|
|
@ -1087,6 +1134,98 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name,
|
|||
}
|
||||
}
|
||||
|
||||
// Note: wearables_to_include should be a list of EWearableType types
|
||||
// attachments_to_include should be a list of attachment points
|
||||
void LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name,
|
||||
const LLDynamicArray<S32>& wearables_to_include,
|
||||
const LLDynamicArray<S32>& attachments_to_include,
|
||||
BOOL rename_clothing)
|
||||
{
|
||||
if (mAvatarObject.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// First, make a folder in the Clothes directory.
|
||||
LLUUID folder_id = gInventory.createNewCategory(
|
||||
gInventory.findCategoryUUIDForType(LLAssetType::AT_MY_OUTFITS),
|
||||
LLAssetType::AT_OUTFIT,
|
||||
new_folder_name);
|
||||
|
||||
// bool found_first_item = false;
|
||||
|
||||
///////////////////
|
||||
// Wearables
|
||||
|
||||
if (wearables_to_include.count())
|
||||
{
|
||||
// Then, iterate though each of the wearables and save links to them in the folder.
|
||||
S32 i;
|
||||
S32 count = wearables_to_include.count();
|
||||
LLDynamicArray<LLUUID> delete_items;
|
||||
LLPointer<LLRefCount> cbdone = NULL;
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
const S32 type = wearables_to_include[i];
|
||||
for (U32 j=0; j<getWearableCount((EWearableType)i); j++)
|
||||
{
|
||||
LLWearable* old_wearable = getWearable((EWearableType)type,j);
|
||||
if (old_wearable)
|
||||
{
|
||||
std::string new_name;
|
||||
if (rename_clothing)
|
||||
{
|
||||
new_name = new_folder_name;
|
||||
new_name.append(" ");
|
||||
new_name.append(old_wearable->getTypeLabel());
|
||||
LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN);
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* item = gInventory.getItem(getWearableItemID((EWearableType) type, j));
|
||||
// BAP TODO
|
||||
LLPointer<LLInventoryCallback> cb = NULL;
|
||||
link_inventory_item(gAgent.getID(),
|
||||
item->getUUID(),
|
||||
folder_id,
|
||||
new_name,
|
||||
LLAssetType::AT_LINK,
|
||||
cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Attachments
|
||||
|
||||
if (attachments_to_include.count())
|
||||
{
|
||||
for (S32 i = 0; i < attachments_to_include.count(); i++)
|
||||
{
|
||||
S32 attachment_pt = attachments_to_include[i];
|
||||
LLViewerJointAttachment* attachment = get_if_there(mAvatarObject->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL);
|
||||
if (!attachment) continue;
|
||||
LLViewerObject* attached_object = attachment->getObject();
|
||||
if (!attached_object) continue;
|
||||
const LLUUID& item_id = attachment->getItemID();
|
||||
if (item_id.isNull()) continue;
|
||||
LLInventoryItem* item = gInventory.getItem(item_id);
|
||||
if (!item) continue;
|
||||
|
||||
// BAP link here
|
||||
LLPointer<LLInventoryCallback> cb = NULL;
|
||||
link_inventory_item(gAgent.getID(),
|
||||
item->getUUID(),
|
||||
folder_id,
|
||||
item->getName(),
|
||||
LLAssetType::AT_LINK,
|
||||
cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
|
||||
{
|
||||
LLUUID first_item_id = getWearableItemID((EWearableType)type, index);
|
||||
|
|
@ -1635,3 +1774,56 @@ void LLAgentWearables::updateServer()
|
|||
sendAgentWearablesUpdate();
|
||||
gAgent.sendAgentSetAppearance();
|
||||
}
|
||||
|
||||
void LLAgentWearables::LLOutfitFolderFetch::done()
|
||||
{
|
||||
// What we do here is get the complete information on the items in
|
||||
// the library, and set up an observer that will wait for that to
|
||||
// happen.
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
gInventory.collectDescendents(mCompleteFolders.front(),
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
S32 count = item_array.count();
|
||||
LLAgentWearables::initial_wearable_data_vec_t current_outfit_links;
|
||||
current_outfit_links.reserve(count);
|
||||
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
{
|
||||
// A bit of a hack since wearables database doesn't contain asset types...
|
||||
// Perform indirection in case this assetID is in fact a link. This only works
|
||||
// because of the assumption that all assetIDs and itemIDs are unique (i.e.
|
||||
// no assetID is also used as an itemID elsewhere); therefore if the assetID
|
||||
// exists as an itemID in the user's inventory, then this must be a link.
|
||||
const LLInventoryItem *linked_item = gInventory.getItem(item_array.get(i)->getUUID());
|
||||
LLAssetType::EType asset_type = (LLAssetType::EType) 0;
|
||||
if (linked_item)
|
||||
{
|
||||
asset_type = linked_item->getType();
|
||||
LLInventoryItem * base_item = gInventory.getItem(linked_item->getLinkedUUID());
|
||||
if (base_item)
|
||||
{
|
||||
EWearableType type = (EWearableType) (base_item->getFlags() & LLInventoryItem::II_FLAGS_WEARABLES_MASK);
|
||||
// MULTI-WEARABLE: update
|
||||
InitialWearableData * temp_wearable_data = new InitialWearableData(type, 0, linked_item->getLinkedUUID(), base_item->getAssetUUID());
|
||||
current_outfit_links.push_back(temp_wearable_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Null base_item in LLOutfitFolderFetch::done, linkedUUID is " << linked_item->getLinkedUUID().asString() << llendl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Null linked_item in LLOutfitFolderFetch::done, UUID is " << item_array.get(i)->getUUID().asString() << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
gInventory.removeObserver(this);
|
||||
LLAgentWearables::fetchInitialWearables(current_outfit_links, mAgentInitialWearables);
|
||||
mAgentInitialWearables.clear();
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,14 +36,33 @@
|
|||
#include "llmemory.h"
|
||||
#include "lluuid.h"
|
||||
#include "llinventory.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llvoavatardefines.h"
|
||||
|
||||
class LLInventoryItem;
|
||||
class LLVOAvatarSelf;
|
||||
class LLWearable;
|
||||
|
||||
// Forward Declaration
|
||||
class LLInventoryFetchDescendentsObserver;
|
||||
|
||||
class LLAgentWearables
|
||||
{
|
||||
//--------------------------------------------------------------------
|
||||
// Data Types
|
||||
//--------------------------------------------------------------------
|
||||
typedef struct _InitialWearableData
|
||||
{
|
||||
EWearableType mType;
|
||||
U32 mIndex;
|
||||
LLUUID mItemID;
|
||||
LLUUID mAssetID;
|
||||
_InitialWearableData(EWearableType type, U32 index, LLUUID itemID, LLUUID assetID) :
|
||||
mType(type), mIndex(index), mItemID(itemID), mAssetID(assetID) { }
|
||||
} InitialWearableData;
|
||||
typedef std::vector<InitialWearableData *> initial_wearable_data_vec_t;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Constructors / destructors / Initializers
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -85,13 +104,14 @@ public:
|
|||
U32 getWearableCount(const EWearableType type) const;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Setters
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
// Low-level data structure setter - public access is via setWearableItem, etc.
|
||||
void setWearable(const EWearableType type, U32 index, LLWearable *wearable);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Setters
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false);
|
||||
void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove);
|
||||
|
|
@ -127,7 +147,9 @@ protected:
|
|||
// Server Communication
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
|
||||
static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
|
||||
static void fetchInitialWearables(initial_wearable_data_vec_t & current_outfit_links, initial_wearable_data_vec_t & message_wearables);
|
||||
protected:
|
||||
void sendAgentWearablesUpdate();
|
||||
void sendAgentWearablesRequest();
|
||||
|
|
@ -139,10 +161,19 @@ protected:
|
|||
// Outfits
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
// Note: wearables_to_include should be a list of EWearableType types
|
||||
// attachments_to_include should be a list of attachment points
|
||||
void makeNewOutfit(const std::string& new_folder_name,
|
||||
const LLDynamicArray<S32>& wearables_to_include,
|
||||
const LLDynamicArray<S32>& attachments_to_include,
|
||||
BOOL rename_clothing);protected:
|
||||
BOOL rename_clothing);
|
||||
|
||||
// Note: wearables_to_include should be a list of EWearableType types
|
||||
// attachments_to_include should be a list of attachment points
|
||||
void makeNewOutfitLinks(const std::string& new_folder_name,
|
||||
const LLDynamicArray<S32>& wearables_to_include,
|
||||
const LLDynamicArray<S32>& attachments_to_include,
|
||||
BOOL rename_clothing);
|
||||
private:
|
||||
void makeNewOutfitDone(S32 type, U32 index);
|
||||
|
||||
|
|
@ -223,6 +254,17 @@ private:
|
|||
U32 mTodo;
|
||||
LLPointer<LLRefCount> mCB;
|
||||
};
|
||||
|
||||
// Outfit folder fetching callback structure.
|
||||
class LLOutfitFolderFetch : public LLInventoryFetchDescendentsObserver
|
||||
{
|
||||
public:
|
||||
LLOutfitFolderFetch() {}
|
||||
~LLOutfitFolderFetch() {}
|
||||
virtual void done();
|
||||
|
||||
LLAgentWearables::initial_wearable_data_vec_t mAgentInitialWearables;
|
||||
};
|
||||
|
||||
}; // LLAgentWearables
|
||||
|
||||
|
|
|
|||
|
|
@ -1274,9 +1274,9 @@ void LLInventoryPanel::draw()
|
|||
LLPanel::draw();
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setFilterTypes(U32 filter_types)
|
||||
void LLInventoryPanel::setFilterTypes(U64 filter_types, BOOL filter_for_categories)
|
||||
{
|
||||
mFolders->getFilter()->setFilterTypes(filter_types);
|
||||
mFolders->getFilter()->setFilterTypes(filter_types, filter_for_categories);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ public:
|
|||
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); }
|
||||
void clearSelection();
|
||||
LLInventoryFilter* getFilter() { return mFolders->getFilter(); }
|
||||
void setFilterTypes(U32 filter);
|
||||
void setFilterTypes(U64 filter, BOOL filter_for_categories = FALSE); // if filter_for_categories is true, operate on folder preferred asset type
|
||||
U32 getFilterTypes() const { return mFolders->getFilterTypes(); }
|
||||
void setFilterPermMask(PermissionMask filter_perm_mask);
|
||||
U32 getFilterPermMask() const { return mFolders->getFilterPermissions(); }
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
|
|||
const BOOL can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm,
|
||||
GP_OBJECT_SET_SALE) &&
|
||||
!cannot_restrict_permissions;
|
||||
const BOOL is_link = LLAssetType::lookupIsLinkType(i->getActualType());
|
||||
const BOOL is_link = i->getIsLinkType();
|
||||
|
||||
// You need permission to modify the object to modify an inventory
|
||||
// item in it.
|
||||
|
|
|
|||
|
|
@ -1103,26 +1103,7 @@ void LLFolderView::changeType(LLInventoryModel *model, LLAssetType::EType new_fo
|
|||
if (!folder_bridge) return;
|
||||
LLViewerInventoryCategory *cat = folder_bridge->getCategory();
|
||||
if (!cat) return;
|
||||
|
||||
const LLUUID &folder_id = cat->getUUID();
|
||||
const LLUUID &parent_id = cat->getParentUUID();
|
||||
const std::string &name = cat->getName();
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_UpdateInventoryFolder);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_FolderData);
|
||||
msg->addUUIDFast(_PREHASH_FolderID, folder_id);
|
||||
msg->addUUIDFast(_PREHASH_ParentID, parent_id);
|
||||
msg->addS8Fast(_PREHASH_Type, new_folder_type);
|
||||
msg->addStringFast(_PREHASH_Name, name);
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
cat->setPreferredType(new_folder_type);
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, folder_id);
|
||||
gInventory.updateLinkedObjects(folder_id);
|
||||
cat->changeType(new_folder_type);
|
||||
}
|
||||
|
||||
void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ public:
|
|||
virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
|
||||
virtual std::string getLabelSuffix() const = 0;
|
||||
virtual void openItem( void ) = 0;
|
||||
virtual void closeItem( void ) = 0;
|
||||
virtual void previewItem( void ) = 0;
|
||||
virtual void selectItem(void) = 0;
|
||||
virtual void showProperties(void) = 0;
|
||||
|
|
|
|||
|
|
@ -1912,12 +1912,16 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r
|
|||
{
|
||||
BOOL was_open = mIsOpen;
|
||||
mIsOpen = openitem;
|
||||
if(!was_open && openitem)
|
||||
if (mListener)
|
||||
{
|
||||
if(mListener)
|
||||
if(!was_open && openitem)
|
||||
{
|
||||
mListener->openItem();
|
||||
}
|
||||
else if(was_open && !openitem)
|
||||
{
|
||||
mListener->closeItem();
|
||||
}
|
||||
}
|
||||
|
||||
if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ void dec_busy_count()
|
|||
struct LLWearableHoldingPattern;
|
||||
void wear_add_inventory_item_on_avatar(LLInventoryItem* item);
|
||||
void wear_inventory_category_on_avatar(LLInventoryCategory* category, BOOL append);
|
||||
void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOOL append);
|
||||
void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOOL append, BOOL follow_folder_links);
|
||||
void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*);
|
||||
void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, BOOL append);
|
||||
void remove_inventory_category_from_avatar(LLInventoryCategory* category);
|
||||
|
|
@ -219,7 +219,7 @@ void LLInvFVBridge::renameLinkedItems(const LLUUID &item_id, const std::string&
|
|||
LLInventoryItem* itemp = model->getItem(mUUID);
|
||||
if (!itemp) return;
|
||||
|
||||
if (LLAssetType::lookupIsLinkType(itemp->getActualType()))
|
||||
if (itemp->getIsLinkType())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -654,7 +654,7 @@ BOOL LLInvFVBridge::isLinkedObjectInTrash() const
|
|||
if (isInTrash()) return TRUE;
|
||||
|
||||
LLInventoryObject *obj = getInventoryObject();
|
||||
if (obj && LLAssetType::lookupIsLinkType(obj->getActualType()))
|
||||
if (obj && obj->getIsLinkType())
|
||||
{
|
||||
LLInventoryModel* model = getInventoryModel();
|
||||
if(!model) return FALSE;
|
||||
|
|
@ -1023,7 +1023,7 @@ void LLItemBridge::restoreToWorld()
|
|||
void LLItemBridge::gotoItem(LLFolderView *folder)
|
||||
{
|
||||
LLInventoryObject *obj = getInventoryObject();
|
||||
if (obj && LLAssetType::lookupIsLinkType(obj->getActualType()))
|
||||
if (obj && obj->getIsLinkType())
|
||||
{
|
||||
LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel();
|
||||
if (active_panel)
|
||||
|
|
@ -1089,7 +1089,7 @@ LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const
|
|||
}
|
||||
|
||||
const LLViewerInventoryItem* item = getItem();
|
||||
if (item && LLAssetType::lookupIsLinkType(item->getActualType()))
|
||||
if (item && item->getIsLinkType())
|
||||
{
|
||||
font |= LLFontGL::ITALIC;
|
||||
}
|
||||
|
|
@ -1116,7 +1116,7 @@ std::string LLItemBridge::getLabelSuffix() const
|
|||
BOOL broken_link = LLAssetType::lookupIsLinkType(item->getType());
|
||||
if (broken_link) return BROKEN_LINK;
|
||||
|
||||
BOOL link = LLAssetType::lookupIsLinkType(item->getActualType());
|
||||
BOOL link = item->getIsLinkType();
|
||||
if (link) return LINK;
|
||||
|
||||
BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
|
||||
|
|
@ -1241,7 +1241,7 @@ BOOL LLItemBridge::isItemCopyable() const
|
|||
// All items can be copied, not all can be pasted.
|
||||
// The only time an item can't be copied is if it's a link
|
||||
// return (item->getPermissions().allowCopyBy(gAgent.getID()));
|
||||
if (LLAssetType::lookupIsLinkType(item->getActualType()))
|
||||
if (item->getIsLinkType())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -1441,6 +1441,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
|
|||
BOOL move_is_into_trash = (mUUID == trash_id)
|
||||
|| model->isObjectDescendentOf(mUUID, trash_id);
|
||||
BOOL is_movable = (!LLAssetType::lookupIsProtectedCategoryType(inv_cat->getPreferredType()));
|
||||
LLUUID current_outfit_id = model->findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
|
||||
BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
|
||||
if (move_is_into_current_outfit)
|
||||
{
|
||||
// BAP - restrictions?
|
||||
is_movable = true;
|
||||
}
|
||||
if( is_movable )
|
||||
{
|
||||
gInventory.collectDescendents( cat_id, descendent_categories, descendent_items, FALSE );
|
||||
|
|
@ -1507,13 +1514,27 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
|
|||
}
|
||||
}
|
||||
|
||||
// Reparent the folder and restamp children if it's moving
|
||||
// into trash.
|
||||
LLInvFVBridge::changeCategoryParent(
|
||||
model,
|
||||
(LLViewerInventoryCategory*)inv_cat,
|
||||
mUUID,
|
||||
move_is_into_trash);
|
||||
if (current_outfit_id == mUUID) // if target is current outfit folder we use link
|
||||
{
|
||||
link_inventory_item(
|
||||
gAgent.getID(),
|
||||
inv_cat->getUUID(),
|
||||
mUUID,
|
||||
inv_cat->getName(),
|
||||
LLAssetType::AT_LINK_FOLDER,
|
||||
LLPointer<LLInventoryCallback>(NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Reparent the folder and restamp children if it's moving
|
||||
// into trash.
|
||||
LLInvFVBridge::changeCategoryParent(
|
||||
model,
|
||||
(LLViewerInventoryCategory*)inv_cat,
|
||||
mUUID,
|
||||
move_is_into_trash);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(LLToolDragAndDrop::SOURCE_WORLD == source)
|
||||
|
|
@ -1899,7 +1920,29 @@ void LLFolderBridge::openItem()
|
|||
lldebugs << "LLFolderBridge::openItem()" << llendl;
|
||||
LLInventoryModel* model = getInventoryModel();
|
||||
if(!model) return;
|
||||
model->fetchDescendentsOf(mUUID);
|
||||
bool fetching_inventory = model->fetchDescendentsOf(mUUID);
|
||||
// Only change folder type if we have the folder contents.
|
||||
if (!fetching_inventory)
|
||||
{
|
||||
// Disabling this for now, it's causing crash when new items are added to folders
|
||||
// since folder type may change before new item item has finished processing.
|
||||
// determineFolderType();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderBridge::closeItem()
|
||||
{
|
||||
determineFolderType();
|
||||
}
|
||||
|
||||
void LLFolderBridge::determineFolderType()
|
||||
{
|
||||
if (isUpToDate())
|
||||
{
|
||||
LLInventoryModel* model = getInventoryModel();
|
||||
LLViewerInventoryCategory* category = model->getCategory(mUUID);
|
||||
category->determineFolderType();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLFolderBridge::isItemRenameable() const
|
||||
|
|
@ -2013,6 +2056,15 @@ LLUIImagePtr LLFolderBridge::getIcon(LLAssetType::EType preferred_type)
|
|||
//TODO - need icon
|
||||
control = "inv_folder_plain_closed.tga";
|
||||
break;
|
||||
case LLAssetType::AT_OUTFIT:
|
||||
control = "inv_folder_outfit.tga";
|
||||
break;
|
||||
case LLAssetType::AT_CURRENT_OUTFIT:
|
||||
control = "inv_folder_current_outfit.tga";
|
||||
break;
|
||||
case LLAssetType::AT_MY_OUTFITS:
|
||||
control = "inv_folder_my_outfits.tga";
|
||||
break;
|
||||
default:
|
||||
control = "inv_folder_plain_closed.tga";
|
||||
break;
|
||||
|
|
@ -2199,6 +2251,10 @@ void LLFolderBridge::folderOptionsMenu()
|
|||
}
|
||||
mItems.push_back(std::string("Take Off Items"));
|
||||
}
|
||||
if (LLAssetType::AT_CURRENT_OUTFIT == category->getPreferredType())
|
||||
{
|
||||
mItems.push_back(std::string("Replace Outfit"));
|
||||
}
|
||||
hideContextEntries(*mMenu, mItems, disabled_items);
|
||||
}
|
||||
|
||||
|
|
@ -2253,6 +2309,8 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
|||
else if(isAgentInventory()) // do not allow creating in library
|
||||
{
|
||||
mItems.push_back(std::string("New Folder"));
|
||||
mItems.push_back(std::string("New Outfit"));
|
||||
mItems.push_back(std::string("New My Outfits"));
|
||||
mItems.push_back(std::string("New Script"));
|
||||
mItems.push_back(std::string("New Note"));
|
||||
mItems.push_back(std::string("New Gesture"));
|
||||
|
|
@ -2492,7 +2550,9 @@ void LLFolderBridge::modifyOutfit(BOOL append)
|
|||
LLViewerInventoryCategory* cat = getCategory();
|
||||
if(!cat) return;
|
||||
|
||||
wear_inventory_category_on_avatar( cat, append );
|
||||
// BAP - was:
|
||||
// wear_inventory_category_on_avatar( cat, append );
|
||||
wear_inventory_category( cat, FALSE, append );
|
||||
}
|
||||
|
||||
// helper stuff
|
||||
|
|
@ -3500,7 +3560,7 @@ LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const
|
|||
}
|
||||
|
||||
LLInventoryItem* item = getItem();
|
||||
if (LLAssetType::lookupIsLinkType(item->getActualType()))
|
||||
if (item && item->getIsLinkType())
|
||||
{
|
||||
font |= LLFontGL::ITALIC;
|
||||
}
|
||||
|
|
@ -3599,7 +3659,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
|||
else
|
||||
{
|
||||
LLInventoryItem* item = getItem();
|
||||
if (item && LLAssetType::lookupIsLinkType(item->getActualType()))
|
||||
if (item && item->getIsLinkType())
|
||||
{
|
||||
items.push_back(std::string("Goto Link"));
|
||||
}
|
||||
|
|
@ -4086,17 +4146,18 @@ void wear_inventory_category_on_avatar( LLInventoryCategory* category, BOOL appe
|
|||
lldebugs << "wear_inventory_category_on_avatar( " << category->getName()
|
||||
<< " )" << llendl;
|
||||
|
||||
BOOL follow_folder_links = (category->getPreferredType() == LLAssetType::AT_CURRENT_OUTFIT || category->getPreferredType() == LLAssetType::AT_OUTFIT );
|
||||
if( gFloaterCustomize )
|
||||
{
|
||||
gFloaterCustomize->askToSaveIfDirty(boost::bind(wear_inventory_category_on_avatar_step2, _1, category->getUUID(), append));
|
||||
gFloaterCustomize->askToSaveIfDirty(boost::bind(wear_inventory_category_on_avatar_step2, _1, category->getUUID(), append, follow_folder_links));
|
||||
}
|
||||
else
|
||||
{
|
||||
wear_inventory_category_on_avatar_step2(TRUE, category->getUUID(), append );
|
||||
wear_inventory_category_on_avatar_step2(TRUE, category->getUUID(), append, follow_folder_links );
|
||||
}
|
||||
}
|
||||
|
||||
void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOOL append )
|
||||
void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOOL append, BOOL follow_folder_links )
|
||||
{
|
||||
// Find all the wearables that are in the category's subtree.
|
||||
lldebugs << "wear_inventory_category_on_avatar_step2()" << llendl;
|
||||
|
|
@ -4109,7 +4170,8 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO
|
|||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_wearable);
|
||||
is_wearable,
|
||||
follow_folder_links);
|
||||
S32 i;
|
||||
S32 wearable_count = item_array.count();
|
||||
|
||||
|
|
@ -4120,7 +4182,8 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO
|
|||
obj_cat_array,
|
||||
obj_item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_object);
|
||||
is_object,
|
||||
follow_folder_links);
|
||||
S32 obj_count = obj_item_array.count();
|
||||
|
||||
// Find all gestures in this folder
|
||||
|
|
@ -4131,7 +4194,8 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO
|
|||
gest_cat_array,
|
||||
gest_item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_gesture);
|
||||
is_gesture,
|
||||
follow_folder_links);
|
||||
S32 gest_count = gest_item_array.count();
|
||||
|
||||
if( !wearable_count && !obj_count && !gest_count)
|
||||
|
|
@ -4139,11 +4203,26 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO
|
|||
LLNotifications::instance().add("CouldNotPutOnOutfit");
|
||||
return;
|
||||
}
|
||||
|
||||
const LLUUID ¤t_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
|
||||
|
||||
// Processes that take time should show the busy cursor
|
||||
if (wearable_count > 0 || obj_count > 0)
|
||||
{
|
||||
// Processes that take time should show the busy cursor
|
||||
inc_busy_count();
|
||||
|
||||
// Remove all current outfit folder links if we're now replacing the contents.
|
||||
if (!append)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
gInventory.collectDescendents(current_outfit_id, cat_array, item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
for (i = 0; i < item_array.count(); ++i)
|
||||
{
|
||||
gInventory.purgeObject(item_array.get(i)->getUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Activate all gestures in this folder
|
||||
|
|
@ -4184,8 +4263,14 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO
|
|||
for(i = 0; i < wearable_count; ++i)
|
||||
{
|
||||
gAddToOutfit = append;
|
||||
|
||||
found = found_container.get(i);
|
||||
|
||||
// Populate the current outfit folder with links to the newly added wearables
|
||||
std::string link_name = "WearableLink";
|
||||
link_inventory_item(gAgent.getID(), found->mItemID, current_outfit_id, link_name,
|
||||
LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
|
||||
|
||||
// Fetch the wearables about to be worn.
|
||||
LLWearableList::instance().getAsset(found->mAssetID,
|
||||
found->mName,
|
||||
found->mAssetType,
|
||||
|
|
@ -4240,9 +4325,9 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO
|
|||
msg->addBOOLFast(_PREHASH_FirstDetachAll, !append );
|
||||
}
|
||||
|
||||
LLInventoryItem* item = obj_item_array.get(i);
|
||||
const LLInventoryItem* item = obj_item_array.get(i).get();
|
||||
msg->nextBlockFast(_PREHASH_ObjectData );
|
||||
msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() );
|
||||
msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
|
||||
msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
|
||||
msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point
|
||||
pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
|
||||
|
|
@ -4254,9 +4339,26 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO
|
|||
// End of message chunk
|
||||
msg->sendReliable( gAgent.getRegion()->getHost() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(i = 0; i < obj_count; ++i)
|
||||
{
|
||||
const std::string link_name = "AttachmentLink";
|
||||
const LLInventoryItem* item = obj_item_array.get(i).get();
|
||||
link_inventory_item(gAgent.getID(), item->getLinkedUUID(), current_outfit_id, link_name,
|
||||
LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a link to the folder that we wore.
|
||||
LLViewerInventoryCategory* catp = gInventory.getCategory(category);
|
||||
if (catp)
|
||||
{
|
||||
link_inventory_item(gAgent.getID(), category, current_outfit_id, catp->getName(),
|
||||
LLAssetType::AT_LINK_FOLDER, LLPointer<LLInventoryCallback>(NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4583,7 +4685,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
|||
items.push_back(std::string("Open"));
|
||||
}
|
||||
|
||||
if (item && LLAssetType::lookupIsLinkType(item->getActualType()))
|
||||
if (item && item->getIsLinkType())
|
||||
{
|
||||
items.push_back(std::string("Goto Link"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ public:
|
|||
}
|
||||
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
|
||||
virtual void openItem() {}
|
||||
virtual void closeItem() {}
|
||||
virtual void gotoItem(LLFolderView *folder) {} // for links
|
||||
virtual void previewItem() {openItem();}
|
||||
virtual void showProperties();
|
||||
|
|
@ -271,6 +272,7 @@ public:
|
|||
BOOL drop);
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual void closeItem();
|
||||
virtual BOOL isItemRenameable() const;
|
||||
virtual void selectItem();
|
||||
virtual void restoreItem();
|
||||
|
|
@ -325,6 +327,8 @@ protected:
|
|||
BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck);
|
||||
|
||||
void modifyOutfit(BOOL append);
|
||||
void determineFolderType();
|
||||
|
||||
public:
|
||||
static LLFolderBridge* sSelf;
|
||||
static void staticFolderOptionsMenu();
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "llfolderviewitem.h"
|
||||
#include "llinventorymodel.h" // gInventory.backgroundFetchActive()
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
// linden library includes
|
||||
#include "lltrans.h"
|
||||
|
|
@ -51,12 +52,13 @@ LLInventoryFilter::LLInventoryFilter(const std::string& name)
|
|||
mModified(FALSE),
|
||||
mNeedTextRebuild(TRUE)
|
||||
{
|
||||
mFilterOps.mFilterTypes = 0xffffffff;
|
||||
mFilterOps.mFilterTypes = 0xffffffffffffffffULL;
|
||||
mFilterOps.mMinDate = time_min();
|
||||
mFilterOps.mMaxDate = time_max();
|
||||
mFilterOps.mHoursAgo = 0;
|
||||
mFilterOps.mShowFolderState = SHOW_NON_EMPTY_FOLDERS;
|
||||
mFilterOps.mPermissions = PERM_NONE;
|
||||
mFilterOps.mFilterForCategories = FALSE;
|
||||
|
||||
mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
|
||||
|
||||
|
|
@ -94,7 +96,25 @@ BOOL LLInventoryFilter::check(LLFolderViewItem* item)
|
|||
}
|
||||
LLFolderViewEventListener* listener = item->getListener();
|
||||
mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
|
||||
BOOL passed = (0x1 << listener->getInventoryType() & mFilterOps.mFilterTypes || listener->getInventoryType() == LLInventoryType::IT_NONE)
|
||||
|
||||
bool passed_type = false;
|
||||
if (mFilterOps.mFilterForCategories)
|
||||
{
|
||||
if (listener->getInventoryType() == LLInventoryType::IT_CATEGORY)
|
||||
{
|
||||
LLViewerInventoryCategory *cat = gInventory.getCategory(listener->getUUID());
|
||||
if (cat)
|
||||
{
|
||||
passed_type |= ((1LL << cat->getPreferredType() & mFilterOps.mFilterTypes) != U64(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
passed_type |= ((1LL << listener->getInventoryType() & mFilterOps.mFilterTypes) != U64(0)) || listener->getInventoryType() == LLInventoryType::IT_NONE;
|
||||
}
|
||||
|
||||
BOOL passed = passed_type
|
||||
&& (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos)
|
||||
&& ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions)
|
||||
&& (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate);
|
||||
|
|
@ -124,7 +144,7 @@ BOOL LLInventoryFilter::isNotDefault()
|
|||
|
||||
BOOL LLInventoryFilter::isActive()
|
||||
{
|
||||
return mFilterOps.mFilterTypes != 0xffffffff
|
||||
return mFilterOps.mFilterTypes != 0xffffffffffffffffULL
|
||||
|| mFilterSubString.size()
|
||||
|| mFilterOps.mPermissions != PERM_NONE
|
||||
|| mFilterOps.mMinDate != time_min()
|
||||
|
|
@ -144,7 +164,7 @@ BOOL LLInventoryFilter::isModifiedAndClear()
|
|||
return ret;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterTypes(U32 types)
|
||||
void LLInventoryFilter::setFilterTypes(U64 types, BOOL filter_for_categories)
|
||||
{
|
||||
if (mFilterOps.mFilterTypes != types)
|
||||
{
|
||||
|
|
@ -168,8 +188,8 @@ void LLInventoryFilter::setFilterTypes(U32 types)
|
|||
{
|
||||
setModified(FILTER_MORE_RESTRICTIVE);
|
||||
}
|
||||
|
||||
}
|
||||
mFilterOps.mFilterForCategories = filter_for_categories;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterSubString(const std::string& string)
|
||||
|
|
@ -374,7 +394,7 @@ void LLInventoryFilter::setModified(EFilterBehavior behavior)
|
|||
|
||||
BOOL LLInventoryFilter::isFilterWith(LLInventoryType::EType t)
|
||||
{
|
||||
return mFilterOps.mFilterTypes & (0x01 << t);
|
||||
return mFilterOps.mFilterTypes & (1LL << t);
|
||||
}
|
||||
|
||||
std::string LLInventoryFilter::getFilterText()
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public:
|
|||
LLInventoryFilter(const std::string& name);
|
||||
virtual ~LLInventoryFilter();
|
||||
|
||||
void setFilterTypes(U32 types);
|
||||
void setFilterTypes(U64 types, BOOL filter_for_categories = FALSE); // if filter_for_categories is true, operate on folder preferred asset type
|
||||
U32 getFilterTypes() const { return mFilterOps.mFilterTypes; }
|
||||
|
||||
void setFilterSubString(const std::string& string);
|
||||
|
|
@ -120,7 +120,8 @@ public:
|
|||
protected:
|
||||
struct filter_ops
|
||||
{
|
||||
U32 mFilterTypes;
|
||||
U64 mFilterTypes;
|
||||
BOOL mFilterForCategories;
|
||||
time_t mMinDate;
|
||||
time_t mMaxDate;
|
||||
U32 mHoursAgo;
|
||||
|
|
|
|||
|
|
@ -434,7 +434,8 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,
|
|||
cat_array_t& cats,
|
||||
item_array_t& items,
|
||||
BOOL include_trash,
|
||||
LLInventoryCollectFunctor& add)
|
||||
LLInventoryCollectFunctor& add,
|
||||
BOOL follow_folder_links)
|
||||
{
|
||||
// Start with categories
|
||||
if(!include_trash)
|
||||
|
|
@ -458,9 +459,38 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,
|
|||
}
|
||||
}
|
||||
|
||||
// Move onto items
|
||||
LLViewerInventoryItem* item = NULL;
|
||||
item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, id);
|
||||
|
||||
// Follow folder links recursively. Currently never goes more
|
||||
// than one level deep (for current outfit support)
|
||||
// Note: if making it fully recursive, need more checking against infinite loops.
|
||||
if (follow_folder_links && item_array)
|
||||
{
|
||||
S32 count = item_array->count();
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
{
|
||||
item = item_array->get(i);
|
||||
if (item->getActualType() == LLAssetType::AT_LINK_FOLDER)
|
||||
{
|
||||
// BAP either getLinkedCategory() should return non-const, or the functor should take const.
|
||||
LLViewerInventoryCategory *linked_cat = const_cast<LLViewerInventoryCategory*>(item->getLinkedCategory());
|
||||
if (linked_cat)
|
||||
{
|
||||
if(add(linked_cat,NULL))
|
||||
{
|
||||
// BAP should this be added here? May not
|
||||
// matter if it's only being used in current
|
||||
// outfit traversal.
|
||||
cats.put(LLPointer<LLViewerInventoryCategory>(linked_cat));
|
||||
}
|
||||
collectDescendentsIf(linked_cat->getUUID(), cats, items, include_trash, add, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move onto items
|
||||
if(item_array)
|
||||
{
|
||||
S32 count = item_array->count();
|
||||
|
|
@ -872,7 +902,7 @@ void LLInventoryModel::purgeLinkedObjects(const LLUUID &id)
|
|||
LLInventoryObject* objectp = getObject(id);
|
||||
if (!objectp) return;
|
||||
|
||||
if (LLAssetType::lookupIsLinkType(objectp->getActualType()))
|
||||
if (objectp->getIsLinkType())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -1196,14 +1226,14 @@ void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::str
|
|||
gInventory.notifyObservers("fetchinventory");
|
||||
}
|
||||
|
||||
void LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
|
||||
bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = getCategory(folder_id);
|
||||
if(!cat)
|
||||
{
|
||||
llwarns << "Asked to fetch descendents of non-existent folder: "
|
||||
<< folder_id << llendl;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
//S32 known_descendents = 0;
|
||||
///cat_array_t* categories = get_ptr_in_map(mParentChildCategoryTree, folder_id);
|
||||
|
|
@ -1216,10 +1246,7 @@ void LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
|
|||
//{
|
||||
// known_descendents += items->count();
|
||||
//}
|
||||
if(!cat->fetchDescendents())
|
||||
{
|
||||
//llinfos << "Not fetching descendents" << llendl;
|
||||
}
|
||||
return cat->fetchDescendents();
|
||||
}
|
||||
|
||||
//Initialize statics.
|
||||
|
|
@ -1337,6 +1364,7 @@ void fetchDescendentsResponder::result(const LLSD& content)
|
|||
{
|
||||
cat->setVersion(version);
|
||||
cat->setDescendentCount(descendents);
|
||||
cat->determineFolderType();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4059,7 +4087,7 @@ bool LLAssetIDMatches::operator()(LLInventoryCategory* cat, LLInventoryItem* ite
|
|||
bool LLLinkedItemIDMatches::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
return (item &&
|
||||
(LLAssetType::lookupIsLinkType(item->getActualType())) &&
|
||||
(item->getIsLinkType()) &&
|
||||
(item->getLinkedUUID() == mBaseItemID)); // A linked item's assetID will be the compared-to item's itemID.
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -185,7 +185,8 @@ public:
|
|||
cat_array_t& categories,
|
||||
item_array_t& items,
|
||||
BOOL include_trash,
|
||||
LLInventoryCollectFunctor& add);
|
||||
LLInventoryCollectFunctor& add,
|
||||
BOOL follow_folder_links = FALSE);
|
||||
|
||||
// Collect all items in inventory that are linked to item_id.
|
||||
// Assumes item_id is itself not a linked item.
|
||||
|
|
@ -296,8 +297,9 @@ public:
|
|||
// minimal functionality before the actual arrival of inventory.
|
||||
//void mock(const LLUUID& root_id);
|
||||
|
||||
// make sure we have the descendents in the structure.
|
||||
void fetchDescendentsOf(const LLUUID& folder_id);
|
||||
// Make sure we have the descendents in the structure. Returns true
|
||||
// if a fetch was performed.
|
||||
bool fetchDescendentsOf(const LLUUID& folder_id);
|
||||
|
||||
// Add categories to a list to be fetched in bulk.
|
||||
static void bulkFetch(std::string url);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* @file llpanelteleporthistory.h
|
||||
* @brief Teleport history represented by a scrolling list
|
||||
* class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPANELLOOKSHISTORY_H
|
||||
#define LL_LLPANELLOOKSHISTORY_H
|
||||
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
|
||||
#include "llpanelappearancetab.h"
|
||||
#include "lllookshistory.h"
|
||||
|
||||
class LLLooksHistoryPanel : public LLPanelAppearanceTab
|
||||
{
|
||||
public:
|
||||
LLLooksHistoryPanel();
|
||||
virtual ~LLLooksHistoryPanel();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onSearchEdit(const std::string& string);
|
||||
/*virtual*/ void onShowOnMap();
|
||||
/*virtual*/ void onLooks();
|
||||
///*virtual*/ void onCopySLURL();
|
||||
|
||||
void showLooksHistory();
|
||||
void handleItemSelect(const LLSD& data);
|
||||
|
||||
static void onDoubleClickItem(void* user_data);
|
||||
|
||||
private:
|
||||
enum LOOKS_HISTORY_COLUMN_ORDER
|
||||
{
|
||||
LIST_ICON,
|
||||
LIST_ITEM_TITLE,
|
||||
LIST_INDEX
|
||||
};
|
||||
|
||||
LLLooksHistory* mLooksHistory;
|
||||
LLScrollListCtrl* mHistoryItems;
|
||||
std::string mFilterSubString;
|
||||
};
|
||||
|
||||
#endif //LL_LLPANELLOOKSHISTORY_H
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* @file llpanelplacestab.h
|
||||
* @brief Tabs interface for Side Bar "Places" panel
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPANELAPPEARANCETAB_H
|
||||
#define LL_LLPANELAPPEARANCETAB_H
|
||||
|
||||
#include "llpanel.h"
|
||||
|
||||
#include "llpanelappearance.h"
|
||||
|
||||
class LLPanelAppearanceTab : public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelAppearanceTab(LLPanelAppearance *parent) :
|
||||
LLPanel(),
|
||||
mParent(parent)
|
||||
{}
|
||||
virtual ~LLPanelAppearanceTab() {}
|
||||
|
||||
virtual void onSearchEdit(const std::string& string) = 0;
|
||||
virtual void updateVerbs() = 0; // Updates buttons at the bottom of Appearance panel
|
||||
virtual void onWear() = 0;
|
||||
virtual void onEdit() = 0;
|
||||
virtual void onNew() = 0;
|
||||
|
||||
bool isTabVisible(); // Check if parent TabContainer is visible.
|
||||
|
||||
void setPanelAppearanceButtons(LLPanelAppearance* panel);
|
||||
|
||||
|
||||
protected:
|
||||
LLButton* mWearBtn;
|
||||
LLButton* mEditBtn;
|
||||
LLPanelAppearance* mParent;
|
||||
};
|
||||
|
||||
#endif //LL_LLPANELAPPEARANCETAB_H
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
#include "indra_constants.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llfoldertype.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llconsole.h"
|
||||
#include "llinventorymodel.h"
|
||||
|
|
@ -587,6 +588,79 @@ bool LLViewerInventoryCategory::exportFileLocal(LLFILE* fp) const
|
|||
return true;
|
||||
}
|
||||
|
||||
void LLViewerInventoryCategory::determineFolderType()
|
||||
{
|
||||
LLAssetType::EType original_type = getPreferredType();
|
||||
if (LLAssetType::lookupIsProtectedCategoryType(original_type))
|
||||
return;
|
||||
|
||||
U64 folder_valid = 0;
|
||||
U64 folder_invalid = 0;
|
||||
LLInventoryModel::cat_array_t category_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
gInventory.collectDescendents(getUUID(),category_array,item_array,FALSE);
|
||||
|
||||
// For ensembles
|
||||
if (category_array.empty())
|
||||
{
|
||||
for (LLInventoryModel::item_array_t::iterator item_iter = item_array.begin();
|
||||
item_iter != item_array.end();
|
||||
item_iter++)
|
||||
{
|
||||
const LLViewerInventoryItem *item = (*item_iter);
|
||||
if (item->getIsLinkType())
|
||||
return;
|
||||
if (item->getInventoryType() == LLInventoryType::IT_WEARABLE)
|
||||
{
|
||||
U32 flags = item->getFlags();
|
||||
if (flags > WT_COUNT)
|
||||
return;
|
||||
const EWearableType wearable_type = EWearableType(flags);
|
||||
const std::string& wearable_name = LLWearableDictionary::getTypeName(wearable_type);
|
||||
U64 valid_folder_types = LLFolderType::lookupValidFolderTypes(wearable_name);
|
||||
folder_valid |= valid_folder_types;
|
||||
folder_invalid |= ~valid_folder_types;
|
||||
}
|
||||
}
|
||||
for (U8 i = LLAssetType::AT_FOLDER_ENSEMBLE_START; i <= LLAssetType::AT_FOLDER_ENSEMBLE_END; i++)
|
||||
{
|
||||
if ((folder_valid & (1LL << i)) &&
|
||||
!(folder_invalid & (1LL << i)))
|
||||
{
|
||||
changeType((LLAssetType::EType)i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (LLAssetType::lookupIsEnsembleCategoryType(original_type))
|
||||
{
|
||||
changeType(LLAssetType::AT_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerInventoryCategory::changeType(LLAssetType::EType new_folder_type)
|
||||
{
|
||||
const LLUUID &folder_id = getUUID();
|
||||
const LLUUID &parent_id = getParentUUID();
|
||||
const std::string &name = getName();
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_UpdateInventoryFolder);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_FolderData);
|
||||
msg->addUUIDFast(_PREHASH_FolderID, folder_id);
|
||||
msg->addUUIDFast(_PREHASH_ParentID, parent_id);
|
||||
msg->addS8Fast(_PREHASH_Type, new_folder_type);
|
||||
msg->addStringFast(_PREHASH_Name, name);
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
setPreferredType(new_folder_type);
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, folder_id);
|
||||
gInventory.updateLinkedObjects(folder_id);
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function definitions
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
@ -880,16 +954,23 @@ void menu_create_inventory_item(LLFolderView* folder, LLFolderBridge *bridge, co
|
|||
{
|
||||
std::string type = userdata.asString();
|
||||
|
||||
if ("category" == type)
|
||||
if (("category" == type) || ("current" == type) || ("outfit" == type) || ("my_otfts" == type) )
|
||||
{
|
||||
LLAssetType::EType a_type = LLAssetType::AT_NONE;
|
||||
if ("current" == type)
|
||||
a_type = LLAssetType::AT_CURRENT_OUTFIT;
|
||||
if ("outfit" == type)
|
||||
a_type = LLAssetType::AT_OUTFIT;
|
||||
if ("my_otfts" == type)
|
||||
a_type = LLAssetType::AT_MY_OUTFITS;
|
||||
LLUUID category;
|
||||
if (bridge)
|
||||
{
|
||||
category = gInventory.createNewCategory(bridge->getUUID(), LLAssetType::AT_NONE, LLStringUtil::null);
|
||||
category = gInventory.createNewCategory(bridge->getUUID(), a_type, LLStringUtil::null);
|
||||
}
|
||||
else
|
||||
{
|
||||
category = gInventory.createNewCategory(gInventory.getRootFolderID(), LLAssetType::AT_NONE, LLStringUtil::null);
|
||||
category = gInventory.createNewCategory(gInventory.getRootFolderID(), a_type, LLStringUtil::null);
|
||||
}
|
||||
gInventory.notifyObservers();
|
||||
folder->setSelectionByID(category, TRUE);
|
||||
|
|
@ -1029,6 +1110,11 @@ const std::string& LLViewerInventoryItem::getName() const
|
|||
|
||||
const LLPermissions& LLViewerInventoryItem::getPermissions() const
|
||||
{
|
||||
if (const LLViewerInventoryItem *linked_item = getLinkedItem())
|
||||
{
|
||||
return linked_item->getPermissions();
|
||||
}
|
||||
|
||||
// Use the actual permissions of the symlink, not its parent.
|
||||
return LLInventoryItem::getPermissions();
|
||||
}
|
||||
|
|
@ -1070,6 +1156,13 @@ LLInventoryType::EType LLViewerInventoryItem::getInventoryType() const
|
|||
return linked_item->getInventoryType();
|
||||
}
|
||||
|
||||
// Categories don't have types. If this item is an AT_FOLDER_LINK,
|
||||
// treat it as a category.
|
||||
if (getLinkedCategory())
|
||||
{
|
||||
return LLInventoryType::IT_CATEGORY;
|
||||
}
|
||||
|
||||
return LLInventoryItem::getInventoryType();
|
||||
}
|
||||
|
||||
|
|
@ -1079,7 +1172,6 @@ U32 LLViewerInventoryItem::getFlags() const
|
|||
{
|
||||
return linked_item->getFlags();
|
||||
}
|
||||
|
||||
return LLInventoryItem::getFlags();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -206,7 +206,8 @@ public:
|
|||
// other than cacheing.
|
||||
bool exportFileLocal(LLFILE* fp) const;
|
||||
bool importFileLocal(LLFILE* fp);
|
||||
|
||||
void determineFolderType();
|
||||
void changeType(LLAssetType::EType new_folder_type);
|
||||
protected:
|
||||
LLUUID mOwnerID;
|
||||
S32 mVersion;
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 808 B |
Binary file not shown.
|
After Width: | Height: | Size: 835 B |
|
|
@ -174,6 +174,9 @@
|
|||
<texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="true"/>
|
||||
<texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="true"/>
|
||||
|
||||
<texture name="TabIcon_Appearance_Off" file_name="taskpanel/TabIcon_Appearance_Off.png" preload="false" />
|
||||
<texture name="TabIcon_Appearance_Over" file_name="taskpanel/TabIcon_Appearance_Over.png" preload="false"/>
|
||||
<texture name="TabIcon_Appearance_Selected" file_name="taskpanel/TabIcon_Appearance_Selected.png" preload="false" />
|
||||
<texture name="TabIcon_Close_Off" file_name="taskpanel/TabIcon_Close_Off.png" preload="false" />
|
||||
<texture name="TabIcon_Close_Over" file_name="taskpanel/TabIcon_Close_Over.png" preload="false"/>
|
||||
<texture name="TabIcon_Home_Off" file_name="taskpanel/TabIcon_Home_Off.png" preload="false" />
|
||||
|
|
|
|||
|
|
@ -206,6 +206,22 @@
|
|||
function="Inventory.DoCreate"
|
||||
parameter="category" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Outfit"
|
||||
layout="topleft"
|
||||
name="New Outfit">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoCreate"
|
||||
parameter="outfit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New My Outfits"
|
||||
layout="topleft"
|
||||
name="New My Outfits">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoCreate"
|
||||
parameter="my_otfts" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Script"
|
||||
layout="topleft"
|
||||
|
|
|
|||
|
|
@ -84,6 +84,22 @@
|
|||
function="Inventory.DoCreate"
|
||||
parameter="current" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Outfit"
|
||||
layout="topleft"
|
||||
name="New Outfit">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoCreate"
|
||||
parameter="outfit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New My Outfits"
|
||||
layout="topleft"
|
||||
name="New My Outfits">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoCreate"
|
||||
parameter="my_otfts" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Script"
|
||||
layout="topleft"
|
||||
|
|
@ -322,6 +338,14 @@
|
|||
function="Inventory.DoToSelected"
|
||||
parameter="change_folder_type_undershirt" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Outfit"
|
||||
layout="topleft"
|
||||
name="Outfit">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="change_folder_type_outfit" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
<menu_item_call
|
||||
label="Teleport"
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
class="panel_places"
|
||||
name="panel_places"
|
||||
filename="panel_places.xml"
|
||||
label="Places"
|
||||
label="Places"
|
||||
border="true"
|
||||
/>
|
||||
</sidetray_tab>
|
||||
|
|
@ -586,5 +586,25 @@
|
|||
|
||||
</sidetray_tab>
|
||||
-->
|
||||
|
||||
<sidetray_tab
|
||||
name="sidebar_appearance"
|
||||
tab_title="Appearance"
|
||||
description="Change your looks and appearance."
|
||||
image="TabIcon_Appearance_Off"
|
||||
mouse_opaque="false"
|
||||
background_opaque="false"
|
||||
background_visible="true"
|
||||
bg_opaque_color="0.5 0.5 0.5 1.0"
|
||||
>
|
||||
<panel
|
||||
class="panel_appearance"
|
||||
name="panel_appearance"
|
||||
filename="panel_appearance.xml"
|
||||
border="true"
|
||||
/>
|
||||
</sidetray_tab>
|
||||
|
||||
|
||||
</side_tray>
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,31 @@
|
|||
mouse_opaque="false" name="tab_description" >
|
||||
Change your profile, your look and quick links to your outfits.
|
||||
</text>
|
||||
</panel>
|
||||
<panel
|
||||
left="10" width="280" height="130"
|
||||
background_visible="true"
|
||||
background_opaque="false"
|
||||
bg_alpha_color="0.3 0.3 0.3 1.0"
|
||||
name="sidebar_appearance"
|
||||
follows="left|top|right"
|
||||
class="panel_sidetray_home_info">
|
||||
<text
|
||||
top="-10" width="200" left="5" height="30" follows="left|right|top"
|
||||
font="SansSerifHugeBold" text_color="white" word_wrap="true"
|
||||
mouse_opaque="false" name="tab_name" >
|
||||
Appearance
|
||||
</text>
|
||||
<icon
|
||||
top="-10" right="-10" width="20" height="20" follows="top|right"
|
||||
color="1 1 1 1" enabled="true" image_name="inv_item_shirt.tga"
|
||||
mouse_opaque="false" name="tab_icon"/>
|
||||
<text
|
||||
top="-40" left="10" right="-10" height="120" follows="left|right|bottom"
|
||||
font="SansSerifBig" text_color="white" word_wrap="true"
|
||||
mouse_opaque="false" name="tab_description" >
|
||||
Change your appearance.
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
|
||||
|
|
@ -409,6 +409,8 @@ this texture in your inventory
|
|||
<string name="InvFolder Animations">Animations</string>
|
||||
<string name="InvFolder Gestures">Gestures</string>
|
||||
<string name="InvFolder favorite">Favorites</string>
|
||||
<string name="InvFolder Current Outfit">Current Outfit</string>
|
||||
<string name="InvFolder My Outfits">My Outfits</string>
|
||||
|
||||
<!-- inventory FVBridge -->
|
||||
<string name="Buy">Buy</string>
|
||||
|
|
|
|||
Loading…
Reference in New Issue