Interim commit before diving into reworking the inventory panel.
This commit is contained in:
@@ -84,7 +84,6 @@ set(viewer_SOURCE_FILES
|
||||
lggdicdownload.cpp
|
||||
floaterao.cpp
|
||||
floatervoicelicense.cpp
|
||||
cofmgr.cpp
|
||||
lldaycyclemanager.cpp
|
||||
llenvmanager.cpp
|
||||
llwlhandlers.cpp
|
||||
@@ -121,7 +120,9 @@ set(viewer_SOURCE_FILES
|
||||
llagentpilot.cpp
|
||||
llagentui.cpp
|
||||
llagentwearables.cpp
|
||||
llagentwearablesfetch.cpp
|
||||
llanimstatelabels.cpp
|
||||
llappearancemgr.cpp
|
||||
llappviewer.cpp
|
||||
llassetconverter.cpp
|
||||
llassetuploadresponders.cpp
|
||||
@@ -307,6 +308,7 @@ set(viewer_SOURCE_FILES
|
||||
llinventorypanel.cpp
|
||||
lljoystickbutton.cpp
|
||||
lllandmarklist.cpp
|
||||
lllocaltextureobject.cpp
|
||||
lllocalinventory.cpp
|
||||
lllogchat.cpp
|
||||
llloginhandler.cpp
|
||||
@@ -328,6 +330,7 @@ set(viewer_SOURCE_FILES
|
||||
llnamelistctrl.cpp
|
||||
llnetmap.cpp
|
||||
llnotify.cpp
|
||||
lloutfitobserver.cpp
|
||||
lloverlaybar.cpp
|
||||
llpanelaudioprefs.cpp
|
||||
llpanelaudiovolume.cpp
|
||||
@@ -410,7 +413,9 @@ set(viewer_SOURCE_FILES
|
||||
llstylemap.cpp
|
||||
llsurface.cpp
|
||||
llsurfacepatch.cpp
|
||||
lltexglobalcolor.cpp
|
||||
lltexlayer.cpp
|
||||
lltexlayerparams.cpp
|
||||
lltexturecache.cpp
|
||||
lltexturectrl.cpp
|
||||
lltexturefetch.cpp
|
||||
@@ -568,7 +573,6 @@ set(viewer_HEADER_FILES
|
||||
aoremotectrl.h
|
||||
floaterao.h
|
||||
floatervoicelicense.h
|
||||
cofmgr.h
|
||||
lldaycyclemanager.h
|
||||
llenvmanager.h
|
||||
llwlhandlers.h
|
||||
@@ -605,8 +609,10 @@ set(viewer_HEADER_FILES
|
||||
llagentpilot.h
|
||||
llagentui.h
|
||||
llagentwearables.h
|
||||
llagentwearablesfetch.h
|
||||
llanimstatelabels.h
|
||||
llappearance.h
|
||||
llappearancemgr.h
|
||||
llappviewer.h
|
||||
llassetconverter.h
|
||||
llassetuploadresponders.h
|
||||
@@ -793,6 +799,7 @@ set(viewer_HEADER_FILES
|
||||
lljoystickbutton.h
|
||||
lllandmarklist.h
|
||||
lllightconstants.h
|
||||
lllocaltextureobject.h
|
||||
lllocalinventory.h
|
||||
lllogchat.h
|
||||
llloginhandler.h
|
||||
@@ -814,6 +821,7 @@ set(viewer_HEADER_FILES
|
||||
llnamelistctrl.h
|
||||
llnetmap.h
|
||||
llnotify.h
|
||||
lloutfitobserver.h
|
||||
lloverlaybar.h
|
||||
llpanelaudioprefs.h
|
||||
llpanelaudiovolume.h
|
||||
@@ -899,7 +907,9 @@ set(viewer_HEADER_FILES
|
||||
llsurface.h
|
||||
llsurfacepatch.h
|
||||
lltable.h
|
||||
lltexglobalcolor.h
|
||||
lltexlayer.h
|
||||
lltexlayerparams.h
|
||||
lltexturecache.h
|
||||
lltexturectrl.h
|
||||
lltexturefetch.h
|
||||
|
||||
@@ -2052,6 +2052,28 @@
|
||||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
</map>
|
||||
<key>AvatarBakedTextureUploadTimeout</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Specifes the maximum time in seconds to wait before sending your baked textures for avatar appearance. Set to 0 to disable and wait until all baked textures are at highest resolution.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>60</integer>
|
||||
</map>
|
||||
<key>AvatarBakedLocalTextureUpdateTimeout</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Specifes the maximum time in seconds to wait before updating your appearance during appearance mode.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>10</integer>
|
||||
</map>
|
||||
<key>AvatarPhysics</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -3948,8 +3970,30 @@
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
<string />
|
||||
</map>
|
||||
<key>DebugAvatarRezTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Display times for avatars to resolve.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DebugAvatarLocalTexLoadedTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Display time for loading avatar local textures.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DebugBeaconLineWidth</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -6773,6 +6817,17 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ForceAssetFail</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Force wearable fetches to fail for this asset type.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>255</integer>
|
||||
</map>
|
||||
<key>ForceShowGrid</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -8013,6 +8068,17 @@
|
||||
<key>Value</key>
|
||||
<real>128.0</real>
|
||||
</map>
|
||||
<key>MaxWearableWaitTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Max seconds to wait for wearable assets to fetch.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>60.0</real>
|
||||
</map>
|
||||
<key>MeanCollisionBump</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -8473,8 +8539,19 @@
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>MyOutfitsAutofill</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Always autofill My Outfits from library when empty (else happens just once).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>NearMeRange</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -14747,6 +14824,17 @@
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OutfitOperationsTimeout</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Timeout for outfit related operations.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>180</integer>
|
||||
</map>
|
||||
<key>UseHTTPInventory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -6387,8 +6387,6 @@
|
||||
<layer
|
||||
name="facialhair"
|
||||
global_color="hair_color">
|
||||
<morph_mask
|
||||
morph_name="Displace_Hair_Facial" />
|
||||
|
||||
<texture
|
||||
tga_file="head_hair.tga"
|
||||
@@ -7294,12 +7292,6 @@
|
||||
<texture
|
||||
local_texture="upper_shirt" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Displace_Loose_Upperbody" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Shirtsleeve_flair" />
|
||||
|
||||
<param
|
||||
id="803"
|
||||
group="0"
|
||||
@@ -8360,18 +8352,6 @@
|
||||
<texture
|
||||
local_texture="lower_pants" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Displace_Loose_Lowerbody" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Leg_Pantflair" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Low_Crotch" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Leg_Longcuffs" />
|
||||
|
||||
<param
|
||||
id="806"
|
||||
group="0"
|
||||
@@ -11863,6 +11843,37 @@
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
</driver_parameters>
|
||||
</driver_parameters>
|
||||
|
||||
<morph_masks>
|
||||
<mask
|
||||
morph_name="Displace_Hair_Facial"
|
||||
body_region="head"
|
||||
layer="facialhair" />
|
||||
<mask
|
||||
morph_name="Displace_Loose_Upperbody"
|
||||
body_region="upper_body"
|
||||
layer="upper_clothes" />
|
||||
<mask
|
||||
morph_name="Shirtsleeve_flair"
|
||||
body_region="upper_body"
|
||||
layer="upper_clothes" />
|
||||
<mask
|
||||
morph_name="Displace_Loose_Lowerbody"
|
||||
body_region="lower_body"
|
||||
layer="lower_pants" />
|
||||
<mask
|
||||
morph_name="Leg_Pantflair"
|
||||
body_region="lower_body"
|
||||
layer="lower_pants" />
|
||||
<mask
|
||||
morph_name="Low_Crotch"
|
||||
body_region="lower_body"
|
||||
layer="lower_pants" />
|
||||
<mask
|
||||
morph_name="Leg_Longcuffs"
|
||||
body_region="lower_body"
|
||||
layer="lower_pants" />
|
||||
</morph_masks>
|
||||
</linden_avatar>
|
||||
|
||||
|
||||
@@ -1,536 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (c) 2010, Kitty Barnett
|
||||
*
|
||||
* The source code in this file is provided to you under the terms of the
|
||||
* GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
|
||||
* in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "cofmgr.h"
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llcommonutils.h"
|
||||
#include "llerror.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "rlvviewer2.h"
|
||||
|
||||
// ============================================================================
|
||||
// Inventory helper classes
|
||||
//
|
||||
|
||||
class LLCOFLinkTargetFetcher : public LLInventoryFetchItemsObserver
|
||||
{
|
||||
public:
|
||||
LLCOFLinkTargetFetcher(const uuid_vec_t& idItems) : LLInventoryFetchItemsObserver(idItems) {}
|
||||
/*virtual*/ ~LLCOFLinkTargetFetcher() {}
|
||||
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
// We shouldn't be messing with inventory items during LLInventoryModel::notifyObservers()
|
||||
doOnIdleOneTime(boost::bind(&LLCOFLinkTargetFetcher::doneIdle, this));
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
|
||||
void doneIdle()
|
||||
{
|
||||
LLCOFMgr::instance().checkCOF();
|
||||
LLCOFMgr::instance().setLinkAttachments(true);
|
||||
LLCOFMgr::instance().updateAttachments();
|
||||
LLCOFMgr::instance().synchWearables();
|
||||
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
class LLCOFFetcher : public LLInventoryFetchDescendentsObserver
|
||||
{
|
||||
public:
|
||||
LLCOFFetcher(const LLUUID& cat_id) : LLInventoryFetchDescendentsObserver(cat_id) {}
|
||||
/*virtual*/ ~LLCOFFetcher() {}
|
||||
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
// We shouldn't be messing with inventory items during LLInventoryModel::notifyObservers()
|
||||
doOnIdleOneTime(boost::bind(&LLCOFFetcher::doneIdle, this));
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
|
||||
void doneIdle()
|
||||
{
|
||||
uuid_vec_t idItems;
|
||||
|
||||
// Add the link targets for COF
|
||||
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
|
||||
gInventory.collectDescendents(LLCOFMgr::getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH);
|
||||
for (S32 idxItem = 0; idxItem < items.count(); idxItem++)
|
||||
{
|
||||
const LLViewerInventoryItem* pItem = items.get(idxItem);
|
||||
if (!pItem)
|
||||
continue;
|
||||
idItems.push_back(pItem->getLinkedUUID());
|
||||
}
|
||||
|
||||
// Add all currently worn wearables
|
||||
for (S32 idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++)
|
||||
{
|
||||
const LLUUID& idItem = gAgentWearables.getWearableItemID((LLWearableType::EType)idxType,0); // TODO: MULTI-WEARABLE
|
||||
if (idItem.isNull())
|
||||
continue;
|
||||
idItems.push_back(idItem);
|
||||
}
|
||||
|
||||
// Add all currently worn attachments
|
||||
const LLVOAvatar* pAvatar = gAgentAvatarp;
|
||||
if (pAvatar)
|
||||
{
|
||||
for (LLVOAvatar::attachment_map_t::const_iterator itAttachPt = pAvatar->mAttachmentPoints.begin();
|
||||
itAttachPt != pAvatar->mAttachmentPoints.end(); ++itAttachPt)
|
||||
{
|
||||
const LLViewerJointAttachment* pAttachPt = itAttachPt->second;
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachment = pAttachPt->mAttachedObjects.begin();
|
||||
itAttachment != pAttachPt->mAttachedObjects.end(); ++itAttachment)
|
||||
{
|
||||
const LLUUID& idItem = (*itAttachment)->getAttachmentItemID();
|
||||
if (idItem.isNull())
|
||||
continue;
|
||||
idItems.push_back(idItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch it all
|
||||
LLCOFLinkTargetFetcher* pFetcher = new LLCOFLinkTargetFetcher(idItems);
|
||||
pFetcher->startFetch();
|
||||
if (pFetcher->isFinished())
|
||||
{
|
||||
pFetcher->done();
|
||||
}
|
||||
else
|
||||
{
|
||||
gInventory.addObserver(pFetcher);
|
||||
|
||||
// It doesn't look like we *really* need the link targets so we can do a preliminary initialization now already
|
||||
LLCOFMgr::instance().setLinkAttachments(true);
|
||||
LLCOFMgr::instance().updateAttachments();
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
class LLDeferredAddLinkTargetFetcher : public LLInventoryFetchItemsObserver
|
||||
{
|
||||
public:
|
||||
LLDeferredAddLinkTargetFetcher(const LLUUID& idItem, LLPointer<LLInventoryCallback> cb)
|
||||
: LLInventoryFetchItemsObserver(idItem), m_Callback(cb)
|
||||
{}
|
||||
LLDeferredAddLinkTargetFetcher(const uuid_vec_t& idItems, LLPointer<LLInventoryCallback> cb)
|
||||
: LLInventoryFetchItemsObserver(idItems), m_Callback(cb)
|
||||
{}
|
||||
/*virtual*/ ~LLDeferredAddLinkTargetFetcher() {}
|
||||
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
// We shouldn't be messing with inventory items during LLInventoryModel::notifyObservers()
|
||||
doOnIdleOneTime(boost::bind(&LLDeferredAddLinkTargetFetcher::doneIdle, this));
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
|
||||
void doneIdle()
|
||||
{
|
||||
for (uuid_vec_t::const_iterator itItemId = mComplete.begin(); itItemId != mComplete.end(); ++itItemId)
|
||||
{
|
||||
const LLViewerInventoryItem* pItem = gInventory.getItem(*itItemId);
|
||||
if (!pItem)
|
||||
continue;
|
||||
LLCOFMgr::instance().addCOFItemLink(pItem, m_Callback);
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
protected:
|
||||
LLPointer<LLInventoryCallback> m_Callback;
|
||||
};
|
||||
|
||||
class LLLinkAttachmentCallback : public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
LLLinkAttachmentCallback() {}
|
||||
/*virtual*/ ~LLLinkAttachmentCallback() {}
|
||||
/*virtual*/ void fire(const LLUUID& idItem) { LLCOFMgr::instance().onLinkAttachmentComplete(idItem); }
|
||||
};
|
||||
|
||||
class LLLinkWearableCallback : public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
LLLinkWearableCallback() {}
|
||||
/*virtual*/ ~LLLinkWearableCallback() {}
|
||||
/*virtual*/ void fire(const LLUUID& idItem) { LLCOFMgr::instance().onLinkWearableComplete(idItem); }
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Helper functions
|
||||
//
|
||||
|
||||
void LLCOFMgr::checkCOF()
|
||||
{
|
||||
const LLUUID idCOF = getCOF();
|
||||
const LLUUID idLAF = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
|
||||
|
||||
// Check COF for non-links and move them to Lost&Found
|
||||
LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems;
|
||||
gInventory.getDirectDescendentsOf(idCOF, pFolders, pItems);
|
||||
for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++)
|
||||
{
|
||||
LLViewerInventoryCategory* pFolder = pFolders->get(idxFolder).get();
|
||||
if ( (pFolder) && (idLAF.notNull()) )
|
||||
change_category_parent(&gInventory, pFolder, idLAF, false);
|
||||
}
|
||||
for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++)
|
||||
{
|
||||
LLViewerInventoryItem* pItem = pItems->get(idxItem).get();
|
||||
if ( (pItem) && (!pItem->getIsLinkType()) && (idLAF.notNull()) )
|
||||
change_item_parent(&gInventory, pItem, idLAF, false);
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFMgr::fetchCOF()
|
||||
{
|
||||
static bool sFetched = false;
|
||||
if (!sFetched)
|
||||
{
|
||||
const LLUUID idCOF = getCOF();
|
||||
if (idCOF.isNull())
|
||||
{
|
||||
LL_ERRS("COFMgr") << "Unable to find (or create) COF" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLCOFFetcher* pFetcher = new LLCOFFetcher(idCOF);
|
||||
pFetcher->startFetch();
|
||||
if (pFetcher->isFinished())
|
||||
pFetcher->done();
|
||||
else
|
||||
gInventory.addObserver(pFetcher);
|
||||
|
||||
sFetched = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFMgr::getDescendentsOfAssetType(const LLUUID& idCat, LLInventoryModel::item_array_t& items,
|
||||
LLAssetType::EType typeAsset, bool fFollowFolderLinks)
|
||||
{
|
||||
LLInventoryModel::cat_array_t folders;
|
||||
LLIsType f(typeAsset);
|
||||
gInventory.collectDescendentsIf(idCat, folders, items, LLInventoryModel::EXCLUDE_TRASH, f, fFollowFolderLinks);
|
||||
}
|
||||
|
||||
void LLCOFMgr::addCOFItemLink(const LLUUID& idItem, LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
const LLViewerInventoryItem *pItem = gInventory.getItem(idItem);
|
||||
if (!pItem)
|
||||
{
|
||||
LLDeferredAddLinkTargetFetcher* pFetcher = new LLDeferredAddLinkTargetFetcher(idItem, cb);
|
||||
pFetcher->startFetch();
|
||||
gInventory.addObserver(pFetcher);
|
||||
return;
|
||||
}
|
||||
addCOFItemLink(pItem, cb);
|
||||
}
|
||||
|
||||
void LLCOFMgr::addCOFItemLink(const LLInventoryItem* pItem, LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
if ( (!pItem) || (isLinkInCOF(pItem->getLinkedUUID())) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, pItem->getLinkedUUID());
|
||||
|
||||
const std::string strDescr = (pItem->getIsLinkType()) ? pItem->getDescription() : "";
|
||||
link_inventory_item(gAgent.getID(), pItem->getLinkedUUID(), getCOF(), pItem->getName(), strDescr, LLAssetType::AT_LINK, cb);
|
||||
}
|
||||
|
||||
bool LLCOFMgr::isLinkInCOF(const LLUUID& idItem) const
|
||||
{
|
||||
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
|
||||
LLLinkedItemIDMatches f(gInventory.getLinkedItemID(idItem));
|
||||
gInventory.collectDescendentsIf(getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH, f);
|
||||
return (!items.empty());
|
||||
}
|
||||
|
||||
void LLCOFMgr::removeCOFItemLinks(const LLUUID& idItem)
|
||||
{
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
|
||||
|
||||
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
|
||||
gInventory.collectDescendents(getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
for (S32 idxItem = 0; idxItem < items.count(); idxItem++)
|
||||
{
|
||||
const LLInventoryItem* pItem = items.get(idxItem).get();
|
||||
if ( (pItem->getIsLinkType()) && (idItem == pItem->getLinkedUUID()) )
|
||||
gInventory.purgeObject(pItem->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLCOFMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
|
||||
{
|
||||
if (!isLinkInCOF(obj_id)) return FALSE;
|
||||
|
||||
// If a non-link somehow ended up in COF, allow deletion.
|
||||
const LLInventoryObject *obj = gInventory.getObject(obj_id);
|
||||
if (obj && !obj->getIsLinkType())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// For now, don't allow direct deletion from the COF. Instead, force users
|
||||
// to choose "Detach" or "Take Off".
|
||||
return TRUE;
|
||||
/*
|
||||
const LLInventoryObject *obj = gInventory.getObject(obj_id);
|
||||
if (!obj) return FALSE;
|
||||
|
||||
// Can't delete bodyparts, since this would be equivalent to removing the item.
|
||||
if (obj->getType() == LLAssetType::AT_BODYPART) return TRUE;
|
||||
|
||||
// Can't delete the folder link, since this is saved for bookkeeping.
|
||||
if (obj->getActualType() == LLAssetType::AT_LINK_FOLDER) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
*/
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Attachment functions
|
||||
//
|
||||
|
||||
void LLCOFMgr::addAttachment(const LLUUID& idItem)
|
||||
{
|
||||
if ( (isLinkInCOF(idItem)) || (std::find(m_PendingAttachLinks.begin(), m_PendingAttachLinks.end(), idItem) != m_PendingAttachLinks.end()) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
|
||||
m_PendingAttachLinks.push_back(idItem);
|
||||
|
||||
if (m_fLinkAttachments)
|
||||
{
|
||||
LLPointer<LLInventoryCallback> cb = new LLLinkAttachmentCallback();
|
||||
addCOFItemLink(idItem, cb);
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFMgr::removeAttachment(const LLUUID& idItem)
|
||||
{
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
|
||||
|
||||
// Remove the attachment from the pending list
|
||||
uuid_vec_t::iterator itPending = std::find(m_PendingAttachLinks.begin(), m_PendingAttachLinks.end(), idItem);
|
||||
if (itPending != m_PendingAttachLinks.end())
|
||||
m_PendingAttachLinks.erase(itPending);
|
||||
|
||||
if (m_fLinkAttachments)
|
||||
{
|
||||
removeCOFItemLinks(idItem);
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFMgr::setLinkAttachments(bool fEnable)
|
||||
{
|
||||
m_fLinkAttachments = fEnable;
|
||||
|
||||
if (m_fLinkAttachments)
|
||||
linkPendingAttachments();
|
||||
}
|
||||
|
||||
void LLCOFMgr::linkPendingAttachments()
|
||||
{
|
||||
LLPointer<LLInventoryCallback> cb = NULL;
|
||||
for (uuid_vec_t::const_iterator itPending = m_PendingAttachLinks.begin(); itPending != m_PendingAttachLinks.end(); ++itPending)
|
||||
{
|
||||
const LLUUID& idAttachItem = *itPending;
|
||||
if ( (gAgentAvatarp->isWearingAttachment(idAttachItem)) && (!isLinkInCOF(idAttachItem)) )
|
||||
{
|
||||
if (!cb)
|
||||
cb = new LLLinkAttachmentCallback();
|
||||
addCOFItemLink(idAttachItem, cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFMgr::onLinkAttachmentComplete(const LLUUID& idItem)
|
||||
{
|
||||
const LLUUID& idItemBase = gInventory.getLinkedItemID(idItem);
|
||||
|
||||
// Remove the attachment from the pending list
|
||||
uuid_vec_t::iterator itPending = std::find(m_PendingAttachLinks.begin(), m_PendingAttachLinks.end(), idItemBase);
|
||||
if (itPending != m_PendingAttachLinks.end())
|
||||
m_PendingAttachLinks.erase(itPending);
|
||||
|
||||
// It may have been detached already in which case we should remove the COF link
|
||||
if ( (gAgentAvatarp) && (!gAgentAvatarp->isWearingAttachment(idItemBase)) )
|
||||
removeCOFItemLinks(idItemBase);
|
||||
}
|
||||
|
||||
void LLCOFMgr::updateAttachments()
|
||||
{
|
||||
/*const*/ LLVOAvatar* pAvatar = gAgentAvatarp;
|
||||
if (!pAvatar)
|
||||
return;
|
||||
|
||||
const LLUUID idCOF = getCOF();
|
||||
|
||||
// Grab all attachment links currently in COF
|
||||
LLInventoryModel::item_array_t items;
|
||||
getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_OBJECT, true);
|
||||
|
||||
// Include attachments which should be in COF but don't have their link created yet
|
||||
uuid_vec_t::iterator itPendingAttachLink = m_PendingAttachLinks.begin();
|
||||
while (itPendingAttachLink != m_PendingAttachLinks.end())
|
||||
{
|
||||
const LLUUID& idItem = *itPendingAttachLink;
|
||||
if ( (!pAvatar->isWearingAttachment(idItem)) || (isLinkInCOF(idItem)) )
|
||||
{
|
||||
itPendingAttachLink = m_PendingAttachLinks.erase(itPendingAttachLink);
|
||||
continue;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* pItem = gInventory.getItem(idItem);
|
||||
if (pItem)
|
||||
items.push_back(pItem);
|
||||
|
||||
++itPendingAttachLink;
|
||||
}
|
||||
|
||||
// Don't remove attachments until avatar is fully loaded (should reduce random attaching/detaching/reattaching at log-on)
|
||||
LLAgentWearables::userUpdateAttachments(items, !pAvatar->isFullyLoaded());
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Wearable functions
|
||||
//
|
||||
|
||||
void LLCOFMgr::addWearable(const LLUUID& idItem)
|
||||
{
|
||||
if ( (isLinkInCOF(idItem)) || (std::find(m_PendingWearableLinks.begin(), m_PendingWearableLinks.end(), idItem) != m_PendingWearableLinks.end()) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
|
||||
m_PendingWearableLinks.push_back(idItem);
|
||||
|
||||
LLPointer<LLInventoryCallback> cb = new LLLinkWearableCallback();
|
||||
addCOFItemLink(idItem, cb);
|
||||
}
|
||||
|
||||
void LLCOFMgr::removeWearable(const LLUUID& idItem)
|
||||
{
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
|
||||
|
||||
// Remove the attachment from the pending list
|
||||
uuid_vec_t::iterator itPending = std::find(m_PendingWearableLinks.begin(), m_PendingWearableLinks.end(), idItem);
|
||||
if (itPending != m_PendingWearableLinks.end())
|
||||
m_PendingWearableLinks.erase(itPending);
|
||||
|
||||
removeCOFItemLinks(idItem);
|
||||
}
|
||||
|
||||
void LLCOFMgr::onLinkWearableComplete(const LLUUID& idItem)
|
||||
{
|
||||
const LLUUID& idItemBase = gInventory.getLinkedItemID(idItem);
|
||||
|
||||
// Remove the attachment from the pending list
|
||||
uuid_vec_t::iterator itPending = std::find(m_PendingWearableLinks.begin(), m_PendingWearableLinks.end(), idItemBase);
|
||||
if (itPending != m_PendingWearableLinks.end())
|
||||
m_PendingWearableLinks.erase(itPending);
|
||||
|
||||
// It may have been removed already in which case we should remove the COF link
|
||||
if (!gAgentWearables.isWearingItem(idItemBase))
|
||||
removeCOFItemLinks(idItemBase);
|
||||
}
|
||||
|
||||
void LLCOFMgr::synchWearables()
|
||||
{
|
||||
const LLUUID idCOF = getCOF();
|
||||
|
||||
// Grab all wearable links currently in COF
|
||||
LLInventoryModel::item_array_t items;
|
||||
getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_BODYPART, true);
|
||||
getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_CLOTHING, true);
|
||||
|
||||
// Transform collection of link LLViewerInventory pointers into collection of target LLUUIDs
|
||||
uuid_vec_t curItems;
|
||||
for (S32 idxItem = 0; idxItem < items.count(); idxItem++)
|
||||
{
|
||||
const LLViewerInventoryItem* pItem = items.get(idxItem);
|
||||
if (!pItem)
|
||||
continue;
|
||||
curItems.push_back(pItem->getLinkedUUID());
|
||||
}
|
||||
|
||||
// Grab the item UUIDs of all currently worn wearables
|
||||
uuid_vec_t newItems;
|
||||
for (S32 idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++)
|
||||
{
|
||||
const LLUUID& idItem = gAgentWearables.getWearableItemID((LLWearableType::EType)idxType, 0); // TODO: MULTI-WEARABLE
|
||||
if (idItem.isNull())
|
||||
continue;
|
||||
newItems.push_back(idItem);
|
||||
}
|
||||
|
||||
uuid_vec_t addItems, remItems;
|
||||
LLCommonUtils::computeDifference(newItems, curItems, addItems, remItems);
|
||||
|
||||
// Add links for worn wearables that aren't linked yet
|
||||
for (uuid_vec_t::const_iterator itItem = addItems.begin(); itItem != addItems.end(); ++itItem)
|
||||
addWearable(*itItem);
|
||||
|
||||
// Remove links of wearables that aren't worn anymore
|
||||
for (uuid_vec_t::const_iterator itItem = remItems.begin(); itItem != remItems.end(); ++itItem)
|
||||
removeWearable(*itItem);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Base outfit folder functions
|
||||
//
|
||||
|
||||
void LLCOFMgr::addBOFLink(const LLUUID &idFolder, LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
purgeBOFLink();
|
||||
|
||||
const LLViewerInventoryCategory* pFolder = gInventory.getCategory(idFolder);
|
||||
if ( (pFolder) && (LLFolderType::FT_OUTFIT == pFolder->getPreferredType()) )
|
||||
link_inventory_item(gAgent.getID(), idFolder, getCOF(), pFolder->getName(), "", LLAssetType::AT_LINK_FOLDER, cb);
|
||||
}
|
||||
|
||||
void LLCOFMgr::purgeBOFLink()
|
||||
{
|
||||
LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems;
|
||||
gInventory.getDirectDescendentsOf(getCOF(), pFolders, pItems);
|
||||
for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++)
|
||||
{
|
||||
const LLViewerInventoryItem* pItem = pItems->get(idxItem).get();
|
||||
if ( (!pItem) || (LLAssetType::AT_LINK_FOLDER != pItem->getActualType()) )
|
||||
continue;
|
||||
|
||||
const LLViewerInventoryCategory* pLinkFolder = pItem->getLinkedCategory();
|
||||
if ( (pLinkFolder) && (LLFolderType::FT_OUTFIT == pLinkFolder->getPreferredType()) )
|
||||
gInventory.purgeObject(pItem->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -1,90 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (c) 2010, Kitty Barnett
|
||||
*
|
||||
* The source code in this file is provided to you under the terms of the
|
||||
* GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
|
||||
* in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "llinventorymodel.h"
|
||||
#include "llmemory.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
// ============================================================================
|
||||
|
||||
class LLCOFMgr : public LLSingleton<LLCOFMgr>
|
||||
{
|
||||
/*
|
||||
* Helper functions
|
||||
*/
|
||||
public:
|
||||
void checkCOF();
|
||||
void fetchCOF();
|
||||
static const LLUUID getCOF() { return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); }
|
||||
static void getDescendentsOfAssetType(const LLUUID& idCat, LLInventoryModel::item_array_t& items,
|
||||
LLAssetType::EType typeAsset, bool fFollowFolderLinks);
|
||||
bool isLinkInCOF(const LLUUID& idItem) const;
|
||||
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
|
||||
protected:
|
||||
void addCOFItemLink(const LLUUID& idItem, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void addCOFItemLink(const LLInventoryItem* pItem, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void removeCOFItemLinks(const LLUUID& idItem);
|
||||
|
||||
/*
|
||||
* Attachment functions
|
||||
*/
|
||||
public:
|
||||
void addAttachment(const LLUUID& idItem);
|
||||
void removeAttachment(const LLUUID& idItem);
|
||||
void synchAttachments();
|
||||
protected:
|
||||
void onLinkAttachmentComplete(const LLUUID& idItem);
|
||||
void linkPendingAttachments();
|
||||
void setLinkAttachments(bool fEnable);
|
||||
void updateAttachments();
|
||||
|
||||
/*
|
||||
* Wearable functions
|
||||
*/
|
||||
public:
|
||||
void addWearable(const LLUUID& idItem);
|
||||
void removeWearable(const LLUUID& idItem);
|
||||
void synchWearables();
|
||||
protected:
|
||||
void onLinkWearableComplete(const LLUUID& idItem);
|
||||
|
||||
/*
|
||||
* Base outfit folder functions
|
||||
*/
|
||||
public:
|
||||
void addBOFLink(const LLUUID& idFolder, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void purgeBOFLink();
|
||||
|
||||
/*
|
||||
* Member variables
|
||||
*/
|
||||
protected:
|
||||
bool m_fLinkAttachments;
|
||||
uuid_vec_t m_PendingAttachLinks;
|
||||
uuid_vec_t m_PendingWearableLinks;
|
||||
|
||||
protected:
|
||||
LLCOFMgr() : m_fLinkAttachments(false) {}
|
||||
private:
|
||||
friend class LLCOFFetcher;
|
||||
friend class LLCOFLinkTargetFetcher;
|
||||
friend class LLDeferredAddLinkTargetFetcher;
|
||||
friend class LLLinkAttachmentCallback;
|
||||
friend class LLLinkWearableCallback;
|
||||
friend class LLSingleton<LLCOFMgr>;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
@@ -3831,12 +3831,11 @@ void LLAgent::sendAgentSetAppearance()
|
||||
{
|
||||
if (!isAgentAvatarValid()) return;
|
||||
|
||||
if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && !gAgentCamera.cameraCustomizeAvatar()))
|
||||
if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl;
|
||||
//dumpAvatarTEs( "sendAgentSetAppearance()" );
|
||||
|
||||
@@ -3866,7 +3865,7 @@ void LLAgent::sendAgentSetAppearance()
|
||||
|
||||
// is texture data current relative to wearables?
|
||||
// KLW - TAT this will probably need to check the local queue.
|
||||
BOOL textures_current = !gAgentAvatarp->hasPendingBakedUploads() && gAgentWearables.areWearablesLoaded();
|
||||
BOOL textures_current = gAgentAvatarp->areTexturesCurrent();
|
||||
|
||||
for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
|
||||
{
|
||||
@@ -3878,8 +3877,8 @@ void LLAgent::sendAgentSetAppearance()
|
||||
continue;
|
||||
}
|
||||
|
||||
// IMG_DEFAULT_AVATAR means not baked
|
||||
if (!gAgentAvatarp->isTextureDefined(texture_index))
|
||||
// IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures
|
||||
if (!gAgentAvatarp->isTextureDefined(texture_index, 0))
|
||||
{
|
||||
textures_current = FALSE;
|
||||
break;
|
||||
@@ -3892,12 +3891,17 @@ void LLAgent::sendAgentSetAppearance()
|
||||
llinfos << "TAT: Sending cached texture data" << llendl;
|
||||
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
|
||||
{
|
||||
BOOL generate_valid_hash = TRUE;
|
||||
if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))
|
||||
{
|
||||
generate_valid_hash = FALSE;
|
||||
llinfos << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << llendl;
|
||||
}
|
||||
|
||||
const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, true);
|
||||
const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash);
|
||||
if (hash.notNull())
|
||||
{
|
||||
const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
|
||||
|
||||
ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
|
||||
msg->nextBlockFast(_PREHASH_WearableData);
|
||||
msg->addUUIDFast(_PREHASH_CacheID, hash);
|
||||
msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,33 +2,26 @@
|
||||
* @file llagentwearables.h
|
||||
* @brief LLAgentWearables class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2010, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* 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://secondlife.com/developers/opensource/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* 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://secondlife.com/developers/opensource/flossexception
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LL_LLAGENTWEARABLES_H
|
||||
@@ -63,16 +56,16 @@ public:
|
||||
LLAgentWearables();
|
||||
virtual ~LLAgentWearables();
|
||||
void setAvatarObject(LLVOAvatarSelf *avatar);
|
||||
void createStandardWearables(BOOL female);
|
||||
void createStandardWearables();
|
||||
void cleanup();
|
||||
//void dump();
|
||||
void dump();
|
||||
|
||||
// LLInitClass interface
|
||||
static void initClass();
|
||||
protected:
|
||||
void createStandardWearablesDone(S32 type, U32 index/* = 0*/);
|
||||
void createStandardWearablesAllDone();
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Queries
|
||||
//--------------------------------------------------------------------
|
||||
@@ -83,18 +76,16 @@ public:
|
||||
|
||||
BOOL isWearableCopyable(LLWearableType::EType type, U32 index /*= 0*/) const;
|
||||
BOOL areWearablesLoaded() const;
|
||||
bool isCOFChangeInProgress() const { return mCOFChangeInProgress; }
|
||||
void updateWearablesLoaded();
|
||||
//void checkWearablesLoaded() const;
|
||||
//bool canMoveWearable(const LLUUID& item_id, bool closer_to_body);
|
||||
void checkWearablesLoaded() const;
|
||||
bool canMoveWearable(const LLUUID& item_id, bool closer_to_body);
|
||||
|
||||
// Note: False for shape, skin, eyes, and hair, unless you have MORE than 1.
|
||||
//bool canWearableBeRemoved(const LLWearable* wearable) const;
|
||||
bool canWearableBeRemoved(const LLWearable* wearable) const;
|
||||
|
||||
//void animateAllWearableParams(F32 delta, BOOL upload_bake);
|
||||
void animateAllWearableParams(F32 delta, BOOL upload_bake);
|
||||
|
||||
BOOL needsReplacement(LLWearableType::EType wearableType, S32 remove);
|
||||
//U32 getWearablePermMask(LLWearableType::EType type) const;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Accessors
|
||||
//--------------------------------------------------------------------
|
||||
@@ -109,11 +100,11 @@ public:
|
||||
LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/);
|
||||
const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
|
||||
LLWearable* getTopWearable(const LLWearableType::EType type);
|
||||
LLWearable* getBottomWearable(const LLWearableType::EType type);
|
||||
LLWearable* getBottomWearable(const LLWearableType::EType type);
|
||||
U32 getWearableCount(const LLWearableType::EType type) const;
|
||||
U32 getWearableCount(const U32 tex_index) const;
|
||||
|
||||
static const U32 MAX_CLOTHING_PER_TYPE = 1;
|
||||
static const U32 MAX_CLOTHING_PER_TYPE = 5;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@@ -129,31 +120,20 @@ private:
|
||||
void popWearable(const LLWearableType::EType type, U32 index);
|
||||
|
||||
public:
|
||||
void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable);
|
||||
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);
|
||||
void setWearableName(const LLUUID& item_id, const std::string& new_name);
|
||||
//void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index);
|
||||
void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index);
|
||||
U32 getWearableIndex(const LLWearable *wearable) const;
|
||||
|
||||
protected:
|
||||
void setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable );
|
||||
void setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false);
|
||||
static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable);
|
||||
|
||||
void addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
|
||||
LLWearable* wearable,
|
||||
const LLUUID& category_id = LLUUID::null,
|
||||
BOOL notify = TRUE);
|
||||
|
||||
/**
|
||||
* @brief Only public because of addWearableToAgentInventoryCallback.
|
||||
*
|
||||
* NOTE: Do not call this method unless you are the inventory callback.
|
||||
* NOTE: This can suffer from race conditions when working on the
|
||||
* same values for index.
|
||||
* @param index The index in mWearableEntry.
|
||||
* @param item_id The inventory item id of the new wearable to wear.
|
||||
* @param wearable The actual wearable data.
|
||||
*/
|
||||
void addWearabletoAgentInventoryDone(const LLWearableType::EType type,
|
||||
const U32 index,
|
||||
const LLUUID& item_id,
|
||||
@@ -166,15 +146,15 @@ protected:
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
//static void createWearable(LLWearableType::EType type, bool wear = false, const LLUUID& parent_id = LLUUID::null);
|
||||
//static void editWearable(const LLUUID& item_id);
|
||||
//bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body);
|
||||
static void createWearable(LLWearableType::EType type, bool wear = false, const LLUUID& parent_id = LLUUID::null);
|
||||
static void editWearable(const LLUUID& item_id);
|
||||
bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body);
|
||||
|
||||
//void requestEditingWearable(const LLUUID& item_id);
|
||||
//void editWearableIfRequested(const LLUUID& item_id);
|
||||
void requestEditingWearable(const LLUUID& item_id);
|
||||
void editWearableIfRequested(const LLUUID& item_id);
|
||||
|
||||
private:
|
||||
//LLUUID mItemToEdit;
|
||||
LLUUID mItemToEdit;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Removing wearables
|
||||
@@ -185,7 +165,6 @@ private:
|
||||
void removeWearableFinal(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/);
|
||||
protected:
|
||||
static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response);
|
||||
static void userRemoveAllClothesStep2(BOOL proceed); // userdata is NULL
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Server Communication
|
||||
@@ -201,7 +180,7 @@ protected:
|
||||
void sendAgentWearablesRequest();
|
||||
void queryWearableCache();
|
||||
void updateServer();
|
||||
static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata );
|
||||
static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Outfits
|
||||
@@ -210,27 +189,20 @@ public:
|
||||
|
||||
// Should only be called if we *know* we've never done so before, since users may
|
||||
// not want the Library outfits to stay in their quick outfit selector and can delete them.
|
||||
//void populateMyOutfitsFolder();
|
||||
void makeNewOutfit(
|
||||
const std::string& new_folder_name,
|
||||
const LLDynamicArray<S32>& wearables_to_include,
|
||||
const LLDynamicArray<S32>& attachments_to_include,
|
||||
BOOL rename_clothing);
|
||||
private:
|
||||
void populateMyOutfitsFolder();
|
||||
|
||||
private:
|
||||
void makeNewOutfitDone(S32 type, U32 index);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Save Wearables
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found );
|
||||
void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
|
||||
void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE,
|
||||
const std::string new_name = "");
|
||||
|
||||
void saveAllWearables();
|
||||
void revertWearable( LLWearableType::EType type, const U32 index);
|
||||
void revertAllWearables();
|
||||
void revertWearable(const LLWearableType::EType type, const U32 index, bool set_by_user=false);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Static UI hooks
|
||||
@@ -238,15 +210,10 @@ public:
|
||||
public:
|
||||
static void userRemoveWearable(const LLWearableType::EType &type, const U32 &index);
|
||||
static void userRemoveWearablesOfType(const LLWearableType::EType &type);
|
||||
static void userRemoveAllClothes();
|
||||
|
||||
typedef std::vector<LLViewerObject*> llvo_vec_t;
|
||||
|
||||
// static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
|
||||
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a
|
||||
// Not the best way to go about this but other attempts changed far too much LL code to be a viable solution
|
||||
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly = false);
|
||||
// [/SL:KB]
|
||||
typedef std::vector<LLViewerObject*> llvo_vec_t;
|
||||
|
||||
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
|
||||
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
|
||||
static void userRemoveAllAttachments();
|
||||
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
|
||||
@@ -258,7 +225,7 @@ public:
|
||||
// Signals
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
/*typedef boost::function<void()> loading_started_callback_t;
|
||||
typedef boost::function<void()> loading_started_callback_t;
|
||||
typedef boost::signals2::signal<void()> loading_started_signal_t;
|
||||
boost::signals2::connection addLoadingStartedCallback(loading_started_callback_t cb);
|
||||
|
||||
@@ -267,9 +234,11 @@ public:
|
||||
boost::signals2::connection addLoadedCallback(loaded_callback_t cb);
|
||||
|
||||
void notifyLoadingStarted();
|
||||
void notifyLoadingFinished();*/
|
||||
void notifyLoadingFinished();
|
||||
|
||||
private:
|
||||
loading_started_signal_t mLoadingStartedSignal; // should be called before wearables are changed
|
||||
loaded_signal_t mLoadedSignal; // emitted when all agent wearables get loaded
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Member variables
|
||||
@@ -281,6 +250,12 @@ private:
|
||||
|
||||
static BOOL mInitialWearablesUpdateReceived;
|
||||
BOOL mWearablesLoaded;
|
||||
std::set<LLUUID> mItemsAwaitingWearableUpdate;
|
||||
|
||||
/**
|
||||
* True if agent's outfit is being changed now.
|
||||
*/
|
||||
BOOL mCOFChangeInProgress;
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// Support classes
|
||||
@@ -300,31 +275,22 @@ private:
|
||||
class addWearableToAgentInventoryCallback : public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
enum ETodo
|
||||
{
|
||||
CALL_NONE = 0,
|
||||
CALL_UPDATE = 1,
|
||||
CALL_RECOVERDONE = 2,
|
||||
CALL_CREATESTANDARDDONE = 4,
|
||||
CALL_MAKENEWOUTFITDONE = 8
|
||||
} EType;
|
||||
CALL_MAKENEWOUTFITDONE = 8,
|
||||
CALL_WEARITEM = 16
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Construct a callback for dealing with the wearables.
|
||||
*
|
||||
* Would like to pass the agent in here, but we can't safely
|
||||
* count on it being around later. Just use gAgent directly.
|
||||
* @param cb callback to execute on completion (??? unused ???)
|
||||
* @param index Index for the wearable in the agent
|
||||
* @param wearable The wearable data.
|
||||
* @param todo Bitmask of actions to take on completion.
|
||||
*/
|
||||
addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,
|
||||
LLWearableType::EType type,
|
||||
U32 index,
|
||||
LLWearable* wearable,
|
||||
U32 todo = CALL_NONE);
|
||||
virtual void fire(const LLUUID& inv_item);
|
||||
|
||||
private:
|
||||
LLWearableType::EType mType;
|
||||
U32 mIndex;
|
||||
|
||||
607
indra/newview/llagentwearablesfetch.cpp
Normal file
607
indra/newview/llagentwearablesfetch.cpp
Normal file
@@ -0,0 +1,607 @@
|
||||
/**
|
||||
* @file llagentwearablesfetch.cpp
|
||||
* @brief LLAgentWearblesFetch class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llagentwearablesfetch.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llstartup.h"
|
||||
#include "llvoavatarself.h"
|
||||
|
||||
|
||||
class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
LLOrderMyOutfitsOnDestroy() {};
|
||||
|
||||
virtual ~LLOrderMyOutfitsOnDestroy()
|
||||
{
|
||||
if (!LLApp::isRunning())
|
||||
{
|
||||
llwarns << "called during shutdown, skipping" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
|
||||
if (my_outfits_id.isNull()) return;
|
||||
|
||||
LLInventoryModel::cat_array_t* cats;
|
||||
LLInventoryModel::item_array_t* items;
|
||||
gInventory.getDirectDescendentsOf(my_outfits_id, cats, items);
|
||||
if (!cats) return;
|
||||
|
||||
//My Outfits should at least contain saved initial outfit and one another outfit
|
||||
if (cats->size() < 2)
|
||||
{
|
||||
llwarning("My Outfits category was not populated properly", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
llinfos << "Starting updating My Outfits with wearables ordering information" << llendl;
|
||||
|
||||
for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin();
|
||||
outfit_iter != cats->end(); ++outfit_iter)
|
||||
{
|
||||
const LLUUID& cat_id = (*outfit_iter)->getUUID();
|
||||
if (cat_id.isNull()) continue;
|
||||
|
||||
// saved initial outfit already contains wearables ordering information
|
||||
if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue;
|
||||
|
||||
LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id);
|
||||
}
|
||||
|
||||
llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
|
||||
}
|
||||
|
||||
/* virtual */ void fire(const LLUUID& inv_item) {};
|
||||
};
|
||||
|
||||
|
||||
LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :
|
||||
LLInventoryFetchDescendentsObserver(cof_id)
|
||||
{
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->outputRezTiming("Initial wearables fetch started");
|
||||
}
|
||||
}
|
||||
|
||||
LLInitialWearablesFetch::~LLInitialWearablesFetch()
|
||||
{
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLInitialWearablesFetch::done()
|
||||
{
|
||||
// Delay processing the actual results of this so it's not handled within
|
||||
// gInventory.notifyObservers. The results will be handled in the next
|
||||
// idle tick instead.
|
||||
gInventory.removeObserver(this);
|
||||
doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this));
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->outputRezTiming("Initial wearables fetch done");
|
||||
}
|
||||
}
|
||||
|
||||
void LLInitialWearablesFetch::add(InitialWearableData &data)
|
||||
|
||||
{
|
||||
mAgentInitialWearables.push_back(data);
|
||||
}
|
||||
|
||||
void LLInitialWearablesFetch::processContents()
|
||||
{
|
||||
if(!gAgentAvatarp) //no need to process wearables if the agent avatar is deleted.
|
||||
{
|
||||
delete this;
|
||||
return ;
|
||||
}
|
||||
|
||||
// Fetch the wearable items from the Current Outfit Folder
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
LLFindWearables is_wearable;
|
||||
llassert_always(mComplete.size() != 0);
|
||||
gInventory.collectDescendentsIf(mComplete.front(), cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH, is_wearable);
|
||||
|
||||
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true);
|
||||
if (wearable_array.count() > 0)
|
||||
{
|
||||
gAgentWearables.notifyLoadingStarted();
|
||||
LLAppearanceMgr::instance().updateAppearanceFromCOF();
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we're constructing the COF from the wearables message, we don't have a proper outfit link
|
||||
LLAppearanceMgr::instance().setOutfitDirty(true);
|
||||
processWearablesMessage();
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
class LLFetchAndLinkObserver: public LLInventoryFetchItemsObserver
|
||||
{
|
||||
public:
|
||||
LLFetchAndLinkObserver(uuid_vec_t& ids):
|
||||
LLInventoryFetchItemsObserver(ids)
|
||||
{
|
||||
}
|
||||
~LLFetchAndLinkObserver()
|
||||
{
|
||||
}
|
||||
virtual void done()
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
|
||||
// Link to all fetched items in COF.
|
||||
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
|
||||
for (uuid_vec_t::iterator it = mIDs.begin();
|
||||
it != mIDs.end();
|
||||
++it)
|
||||
{
|
||||
LLUUID id = *it;
|
||||
LLViewerInventoryItem *item = gInventory.getItem(*it);
|
||||
if (!item)
|
||||
{
|
||||
llwarns << "fetch failed!" << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
link_inventory_item(gAgent.getID(),
|
||||
item->getLinkedUUID(),
|
||||
LLAppearanceMgr::instance().getCOF(),
|
||||
item->getName(),
|
||||
item->getDescription(),
|
||||
LLAssetType::AT_LINK,
|
||||
link_waiter);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void LLInitialWearablesFetch::processWearablesMessage()
|
||||
{
|
||||
if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.
|
||||
{
|
||||
const LLUUID current_outfit_id = LLAppearanceMgr::instance().getCOF();
|
||||
uuid_vec_t ids;
|
||||
for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)
|
||||
{
|
||||
// Populate the current outfit folder with links to the wearables passed in the message
|
||||
InitialWearableData *wearable_data = new InitialWearableData(mAgentInitialWearables[i]); // This will be deleted in the callback.
|
||||
|
||||
if (wearable_data->mAssetID.notNull())
|
||||
{
|
||||
ids.push_back(wearable_data->mItemID);
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID "
|
||||
<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
|
||||
delete wearable_data;
|
||||
}
|
||||
}
|
||||
|
||||
// Add all current attachments to the requested items as well.
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
|
||||
iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter)
|
||||
{
|
||||
LLViewerJointAttachment* attachment = iter->second;
|
||||
if (!attachment) continue;
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
||||
attachment_iter != attachment->mAttachedObjects.end();
|
||||
++attachment_iter)
|
||||
{
|
||||
LLViewerObject* attached_object = (*attachment_iter);
|
||||
if (!attached_object) continue;
|
||||
const LLUUID& item_id = attached_object->getAttachmentItemID();
|
||||
if (item_id.isNull()) continue;
|
||||
ids.push_back(item_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need to fetch the inventory items for ids, then create links to them after they arrive.
|
||||
LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids);
|
||||
fetcher->startFetch();
|
||||
// If no items to be fetched, done will never be triggered.
|
||||
// TODO: Change LLInventoryFetchItemsObserver::fetchItems to trigger done() on this condition.
|
||||
if (fetcher->isFinished())
|
||||
{
|
||||
fetcher->done();
|
||||
}
|
||||
else
|
||||
{
|
||||
gInventory.addObserver(fetcher);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Wearables") << "No current outfit folder items found and no initial wearables fallback message received." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
LLLibraryOutfitsFetch::LLLibraryOutfitsFetch(const LLUUID& my_outfits_id) :
|
||||
LLInventoryFetchDescendentsObserver(my_outfits_id),
|
||||
mCurrFetchStep(LOFS_FOLDER),
|
||||
mOutfitsPopulated(false)
|
||||
{
|
||||
llinfos << "created" << llendl;
|
||||
|
||||
mMyOutfitsID = LLUUID::null;
|
||||
mClothingID = LLUUID::null;
|
||||
mLibraryClothingID = LLUUID::null;
|
||||
mImportedClothingID = LLUUID::null;
|
||||
mImportedClothingName = "Imported Library Clothing";
|
||||
}
|
||||
|
||||
LLLibraryOutfitsFetch::~LLLibraryOutfitsFetch()
|
||||
{
|
||||
llinfos << "destroyed" << llendl;
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::done()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
// Delay this until idle() routine, since it's a heavy operation and
|
||||
// we also can't have it run within notifyObservers.
|
||||
doOnIdleOneTime(boost::bind(&LLLibraryOutfitsFetch::doneIdle,this));
|
||||
gInventory.removeObserver(this); // Prevent doOnIdleOneTime from being added twice.
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::doneIdle()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
gInventory.addObserver(this); // Add this back in since it was taken out during ::done()
|
||||
|
||||
switch (mCurrFetchStep)
|
||||
{
|
||||
case LOFS_FOLDER:
|
||||
folderDone();
|
||||
mCurrFetchStep = LOFS_OUTFITS;
|
||||
break;
|
||||
case LOFS_OUTFITS:
|
||||
outfitsDone();
|
||||
mCurrFetchStep = LOFS_LIBRARY;
|
||||
break;
|
||||
case LOFS_LIBRARY:
|
||||
libraryDone();
|
||||
mCurrFetchStep = LOFS_IMPORTED;
|
||||
break;
|
||||
case LOFS_IMPORTED:
|
||||
importedFolderDone();
|
||||
mCurrFetchStep = LOFS_CONTENTS;
|
||||
break;
|
||||
case LOFS_CONTENTS:
|
||||
contentsDone();
|
||||
break;
|
||||
default:
|
||||
llwarns << "Got invalid state for outfit fetch: " << mCurrFetchStep << llendl;
|
||||
mOutfitsPopulated = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// We're completely done. Cleanup.
|
||||
if (mOutfitsPopulated)
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::folderDone()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
gInventory.collectDescendents(mMyOutfitsID, cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
// Early out if we already have items in My Outfits
|
||||
// except the case when My Outfits contains just initial outfit
|
||||
if (cat_array.count() > 1)
|
||||
{
|
||||
mOutfitsPopulated = true;
|
||||
return;
|
||||
}
|
||||
|
||||
mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
|
||||
mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true);
|
||||
|
||||
// If Library->Clothing->Initial Outfits exists, use that.
|
||||
LLNameCategoryCollector matchFolderFunctor("Initial Outfits");
|
||||
cat_array.clear();
|
||||
gInventory.collectDescendentsIf(mLibraryClothingID,
|
||||
cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
matchFolderFunctor);
|
||||
if (cat_array.count() > 0)
|
||||
{
|
||||
const LLViewerInventoryCategory *cat = cat_array.get(0);
|
||||
mLibraryClothingID = cat->getUUID();
|
||||
}
|
||||
|
||||
mComplete.clear();
|
||||
|
||||
// Get the complete information on the items in the inventory.
|
||||
uuid_vec_t folders;
|
||||
folders.push_back(mClothingID);
|
||||
folders.push_back(mLibraryClothingID);
|
||||
setFetchIDs(folders);
|
||||
startFetch();
|
||||
if (isFinished())
|
||||
{
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::outfitsDone()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
uuid_vec_t folders;
|
||||
|
||||
// Collect the contents of the Library's Clothing folder
|
||||
gInventory.collectDescendents(mLibraryClothingID, cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
llassert(cat_array.count() > 0);
|
||||
for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin();
|
||||
iter != cat_array.end();
|
||||
++iter)
|
||||
{
|
||||
const LLViewerInventoryCategory *cat = iter->get();
|
||||
|
||||
// Get the names and id's of every outfit in the library, skip "Ruth"
|
||||
// because it's a low quality legacy outfit
|
||||
if (cat->getName() != "Ruth")
|
||||
{
|
||||
// Get the name of every outfit in the library
|
||||
folders.push_back(cat->getUUID());
|
||||
mLibraryClothingFolders.push_back(cat->getUUID());
|
||||
}
|
||||
}
|
||||
cat_array.clear();
|
||||
wearable_array.clear();
|
||||
|
||||
// Check if you already have an "Imported Library Clothing" folder
|
||||
LLNameCategoryCollector matchFolderFunctor(mImportedClothingName);
|
||||
gInventory.collectDescendentsIf(mClothingID,
|
||||
cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
matchFolderFunctor);
|
||||
if (cat_array.size() > 0)
|
||||
{
|
||||
const LLViewerInventoryCategory *cat = cat_array.get(0);
|
||||
mImportedClothingID = cat->getUUID();
|
||||
}
|
||||
|
||||
mComplete.clear();
|
||||
setFetchIDs(folders);
|
||||
startFetch();
|
||||
if (isFinished())
|
||||
{
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
class LLLibraryOutfitsCopyDone: public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
LLLibraryOutfitsCopyDone(LLLibraryOutfitsFetch * fetcher):
|
||||
mFireCount(0), mLibraryOutfitsFetcher(fetcher)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~LLLibraryOutfitsCopyDone()
|
||||
{
|
||||
if (!LLApp::isExiting() && mLibraryOutfitsFetcher)
|
||||
{
|
||||
gInventory.addObserver(mLibraryOutfitsFetcher);
|
||||
mLibraryOutfitsFetcher->done();
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void fire(const LLUUID& inv_item)
|
||||
{
|
||||
mFireCount++;
|
||||
}
|
||||
private:
|
||||
U32 mFireCount;
|
||||
LLLibraryOutfitsFetch * mLibraryOutfitsFetcher;
|
||||
};
|
||||
|
||||
// Copy the clothing folders from the library into the imported clothing folder
|
||||
void LLLibraryOutfitsFetch::libraryDone()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
if (mImportedClothingID != LLUUID::null)
|
||||
{
|
||||
// Skip straight to fetching the contents of the imported folder
|
||||
importedFolderFetch();
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove observer; next autopopulation step will be triggered externally by LLLibraryOutfitsCopyDone.
|
||||
gInventory.removeObserver(this);
|
||||
|
||||
LLPointer<LLInventoryCallback> copy_waiter = new LLLibraryOutfitsCopyDone(this);
|
||||
mImportedClothingID = gInventory.createNewCategory(mClothingID,
|
||||
LLFolderType::FT_NONE,
|
||||
mImportedClothingName);
|
||||
// Copy each folder from library into clothing unless it already exists.
|
||||
for (uuid_vec_t::const_iterator iter = mLibraryClothingFolders.begin();
|
||||
iter != mLibraryClothingFolders.end();
|
||||
++iter)
|
||||
{
|
||||
const LLUUID& src_folder_id = (*iter); // Library clothing folder ID
|
||||
const LLViewerInventoryCategory *cat = gInventory.getCategory(src_folder_id);
|
||||
if (!cat)
|
||||
{
|
||||
llwarns << "Library folder import for uuid:" << src_folder_id << " failed to find folder." << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!LLAppearanceMgr::getInstance()->getCanMakeFolderIntoOutfit(src_folder_id))
|
||||
{
|
||||
llinfos << "Skipping non-outfit folder name:" << cat->getName() << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't copy the category if it already exists.
|
||||
LLNameCategoryCollector matchFolderFunctor(cat->getName());
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
gInventory.collectDescendentsIf(mImportedClothingID,
|
||||
cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
matchFolderFunctor);
|
||||
if (cat_array.size() > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LLUUID dst_folder_id = gInventory.createNewCategory(mImportedClothingID,
|
||||
LLFolderType::FT_NONE,
|
||||
cat->getName());
|
||||
LLAppearanceMgr::getInstance()->shallowCopyCategoryContents(src_folder_id, dst_folder_id, copy_waiter);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::importedFolderFetch()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
// Fetch the contents of the Imported Clothing Folder
|
||||
uuid_vec_t folders;
|
||||
folders.push_back(mImportedClothingID);
|
||||
|
||||
mComplete.clear();
|
||||
setFetchIDs(folders);
|
||||
startFetch();
|
||||
if (isFinished())
|
||||
{
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::importedFolderDone()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
uuid_vec_t folders;
|
||||
|
||||
// Collect the contents of the Imported Clothing folder
|
||||
gInventory.collectDescendents(mImportedClothingID, cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin();
|
||||
iter != cat_array.end();
|
||||
++iter)
|
||||
{
|
||||
const LLViewerInventoryCategory *cat = iter->get();
|
||||
|
||||
// Get the name of every imported outfit
|
||||
folders.push_back(cat->getUUID());
|
||||
mImportedClothingFolders.push_back(cat->getUUID());
|
||||
}
|
||||
|
||||
mComplete.clear();
|
||||
setFetchIDs(folders);
|
||||
startFetch();
|
||||
if (isFinished())
|
||||
{
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::contentsDone()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
|
||||
LLPointer<LLOrderMyOutfitsOnDestroy> order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy;
|
||||
|
||||
for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin();
|
||||
folder_iter != mImportedClothingFolders.end();
|
||||
++folder_iter)
|
||||
{
|
||||
const LLUUID &folder_id = (*folder_iter);
|
||||
const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
|
||||
if (!cat)
|
||||
{
|
||||
llwarns << "Library folder import for uuid:" << folder_id << " failed to find folder." << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
//initial outfit should be already in My Outfits
|
||||
if (cat->getName() == LLStartUp::getInitialOutfitName()) continue;
|
||||
|
||||
// First, make a folder in the My Outfits directory.
|
||||
LLUUID new_outfit_folder_id = gInventory.createNewCategory(mMyOutfitsID, LLFolderType::FT_OUTFIT, cat->getName());
|
||||
|
||||
cat_array.clear();
|
||||
wearable_array.clear();
|
||||
// Collect the contents of each imported clothing folder, so we can create new outfit links for it
|
||||
gInventory.collectDescendents(folder_id, cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
for (LLInventoryModel::item_array_t::const_iterator wearable_iter = wearable_array.begin();
|
||||
wearable_iter != wearable_array.end();
|
||||
++wearable_iter)
|
||||
{
|
||||
const LLViewerInventoryItem *item = wearable_iter->get();
|
||||
link_inventory_item(gAgent.getID(),
|
||||
item->getLinkedUUID(),
|
||||
new_outfit_folder_id,
|
||||
item->getName(),
|
||||
item->getDescription(),
|
||||
LLAssetType::AT_LINK,
|
||||
order_myoutfits_on_destroy);
|
||||
}
|
||||
}
|
||||
|
||||
mOutfitsPopulated = true;
|
||||
}
|
||||
|
||||
114
indra/newview/llagentwearablesfetch.h
Normal file
114
indra/newview/llagentwearablesfetch.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @file llagentwearablesinitialfetch.h
|
||||
* @brief LLAgentWearablesInitialFetch class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLAGENTWEARABLESINITIALFETCH_H
|
||||
#define LL_LLAGENTWEARABLESINITIALFETCH_H
|
||||
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llwearabletype.h"
|
||||
#include "lluuid.h"
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// InitialWearablesFetch
|
||||
//
|
||||
// This grabs contents from the COF and processes them.
|
||||
// The processing is handled in idle(), i.e. outside of done(),
|
||||
// to avoid gInventory.notifyObservers recursion.
|
||||
//--------------------------------------------------------------------
|
||||
class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver
|
||||
{
|
||||
LOG_CLASS(LLInitialWearablesFetch);
|
||||
|
||||
public:
|
||||
LLInitialWearablesFetch(const LLUUID& cof_id);
|
||||
~LLInitialWearablesFetch();
|
||||
virtual void done();
|
||||
|
||||
struct InitialWearableData
|
||||
{
|
||||
LLWearableType::EType mType;
|
||||
LLUUID mItemID;
|
||||
LLUUID mAssetID;
|
||||
InitialWearableData(LLWearableType::EType type, LLUUID& itemID, LLUUID& assetID) :
|
||||
mType(type),
|
||||
mItemID(itemID),
|
||||
mAssetID(assetID)
|
||||
{}
|
||||
};
|
||||
|
||||
void add(InitialWearableData &data);
|
||||
|
||||
protected:
|
||||
void processWearablesMessage();
|
||||
void processContents();
|
||||
|
||||
private:
|
||||
typedef std::vector<InitialWearableData> initial_wearable_data_vec_t;
|
||||
initial_wearable_data_vec_t mAgentInitialWearables; // Wearables from the old agent wearables msg
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// InitialWearablesFetch
|
||||
//
|
||||
// This grabs outfits from the Library and copies those over to the user's
|
||||
// outfits folder, typically during first-ever login.
|
||||
//--------------------------------------------------------------------
|
||||
class LLLibraryOutfitsFetch : public LLInventoryFetchDescendentsObserver
|
||||
{
|
||||
public:
|
||||
enum ELibraryOutfitFetchStep
|
||||
{
|
||||
LOFS_FOLDER = 0,
|
||||
LOFS_OUTFITS,
|
||||
LOFS_LIBRARY,
|
||||
LOFS_IMPORTED,
|
||||
LOFS_CONTENTS
|
||||
};
|
||||
|
||||
LLLibraryOutfitsFetch(const LLUUID& my_outfits_id);
|
||||
~LLLibraryOutfitsFetch();
|
||||
|
||||
virtual void done();
|
||||
void doneIdle();
|
||||
LLUUID mMyOutfitsID;
|
||||
void importedFolderFetch();
|
||||
protected:
|
||||
void folderDone();
|
||||
void outfitsDone();
|
||||
void libraryDone();
|
||||
void importedFolderDone();
|
||||
void contentsDone();
|
||||
enum ELibraryOutfitFetchStep mCurrFetchStep;
|
||||
uuid_vec_t mLibraryClothingFolders;
|
||||
uuid_vec_t mImportedClothingFolders;
|
||||
bool mOutfitsPopulated;
|
||||
LLUUID mClothingID;
|
||||
LLUUID mLibraryClothingID;
|
||||
LLUUID mImportedClothingID;
|
||||
std::string mImportedClothingName;
|
||||
};
|
||||
|
||||
#endif // LL_AGENTWEARABLESINITIALFETCH_H
|
||||
3138
indra/newview/llappearancemgr.cpp
Normal file
3138
indra/newview/llappearancemgr.cpp
Normal file
File diff suppressed because it is too large
Load Diff
265
indra/newview/llappearancemgr.h
Normal file
265
indra/newview/llappearancemgr.h
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @file llappearancemgr.h
|
||||
* @brief Manager for initiating appearance changes on the viewer
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLAPPEARANCEMGR_H
|
||||
#define LL_LLAPPEARANCEMGR_H
|
||||
|
||||
#include "llsingleton.h"
|
||||
|
||||
#include "llagentwearables.h"
|
||||
#include "llcallbacklist.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
class LLWearable;
|
||||
class LLWearableHoldingPattern;
|
||||
class LLInventoryCallback;
|
||||
class LLOutfitUnLockTimer;
|
||||
|
||||
class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
|
||||
{
|
||||
LOG_CLASS(LLAppearanceMgr);
|
||||
|
||||
friend class LLSingleton<LLAppearanceMgr>;
|
||||
friend class LLOutfitUnLockTimer;
|
||||
|
||||
public:
|
||||
typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t;
|
||||
|
||||
void updateAppearanceFromCOF(bool update_base_outfit_ordering = false);
|
||||
bool needToSaveCOF();
|
||||
void updateCOF(const LLUUID& category, bool append = false);
|
||||
// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
|
||||
void updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t& wear_items_new,
|
||||
LLInventoryModel::item_array_t& obj_items_new, LLInventoryModel::item_array_t& gest_items_new,
|
||||
bool append = false, const LLUUID& idOutfit = LLUUID::null);
|
||||
// [/RLVa:KB]
|
||||
void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append);
|
||||
void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append);
|
||||
void wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append);
|
||||
void wearOutfitByName(const std::string& name);
|
||||
void changeOutfit(bool proceed, const LLUUID& category, bool append);
|
||||
void replaceCurrentOutfit(const LLUUID& new_outfit);
|
||||
void renameOutfit(const LLUUID& outfit_id);
|
||||
void takeOffOutfit(const LLUUID& cat_id);
|
||||
void addCategoryToCurrentOutfit(const LLUUID& cat_id);
|
||||
S32 findExcessOrDuplicateItems(const LLUUID& cat_id,
|
||||
LLAssetType::EType type,
|
||||
S32 max_items,
|
||||
LLInventoryModel::item_array_t& items_to_kill);
|
||||
void enforceItemRestrictions();
|
||||
|
||||
// Copy all items and the src category itself.
|
||||
void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
|
||||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
// Return whether this folder contains minimal contents suitable for making a full outfit.
|
||||
BOOL getCanMakeFolderIntoOutfit(const LLUUID& folder_id);
|
||||
|
||||
// Determine whether a given outfit can be removed.
|
||||
bool getCanRemoveOutfit(const LLUUID& outfit_cat_id);
|
||||
|
||||
// Determine whether we're wearing any of the outfit contents (excluding body parts).
|
||||
static bool getCanRemoveFromCOF(const LLUUID& outfit_cat_id);
|
||||
|
||||
// Determine whether we can add anything (but body parts) from the outfit contents to COF.
|
||||
static bool getCanAddToCOF(const LLUUID& outfit_cat_id);
|
||||
|
||||
// Determine whether we can replace current outfit with the given one.
|
||||
bool getCanReplaceCOF(const LLUUID& outfit_cat_id);
|
||||
|
||||
// Copy all items in a category.
|
||||
void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
|
||||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
// Find the Current Outfit folder.
|
||||
const LLUUID getCOF() const;
|
||||
|
||||
// Finds the folder link to the currently worn outfit
|
||||
const LLViewerInventoryItem *getBaseOutfitLink();
|
||||
bool getBaseOutfitName(std::string &name);
|
||||
|
||||
// find the UUID of the currently worn outfit (Base Outfit)
|
||||
const LLUUID getBaseOutfitUUID();
|
||||
|
||||
// Wear/attach an item (from a user's inventory) on the agent
|
||||
bool wearItemOnAvatar(const LLUUID& item_to_wear, bool do_update = true, bool replace = false, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
|
||||
// Update the displayed outfit name in UI.
|
||||
void updatePanelOutfitName(const std::string& name);
|
||||
|
||||
void createBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> link_waiter);
|
||||
|
||||
void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
|
||||
|
||||
// For debugging - could be moved elsewhere.
|
||||
void dumpCat(const LLUUID& cat_id, const std::string& msg);
|
||||
void dumpItemArray(const LLInventoryModel::item_array_t& items, const std::string& msg);
|
||||
|
||||
// Attachment link management
|
||||
void unregisterAttachment(const LLUUID& item_id);
|
||||
void registerAttachment(const LLUUID& item_id);
|
||||
void setAttachmentInvLinkEnable(bool val);
|
||||
|
||||
// utility function for bulk linking.
|
||||
void linkAll(const LLUUID& category,
|
||||
LLInventoryModel::item_array_t& items,
|
||||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
// Add COF link to individual item.
|
||||
void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
|
||||
// Remove COF entries
|
||||
void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true);
|
||||
void removeCOFLinksOfType(LLWearableType::EType type, bool do_update = true);
|
||||
|
||||
// Add COF link to ensemble folder.
|
||||
void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
|
||||
|
||||
//has the current outfit changed since it was loaded?
|
||||
bool isOutfitDirty() { return mOutfitIsDirty; }
|
||||
|
||||
// set false if you just loaded the outfit, true otherwise
|
||||
void setOutfitDirty(bool isDirty) { mOutfitIsDirty = isDirty; }
|
||||
|
||||
// manually compare ouftit folder link to COF to see if outfit has changed.
|
||||
// should only be necessary to do on initial login.
|
||||
void updateIsDirty();
|
||||
|
||||
// Called when self avatar is first fully visible.
|
||||
void onFirstFullyVisible();
|
||||
|
||||
// Create initial outfits from library.
|
||||
void autopopulateOutfits();
|
||||
|
||||
// Copy initial gestures from library.
|
||||
void copyLibraryGestures();
|
||||
|
||||
void wearBaseOutfit();
|
||||
|
||||
// Overrides the base outfit with the content from COF
|
||||
// @return false if there is no base outfit
|
||||
bool updateBaseOutfit();
|
||||
|
||||
//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
|
||||
void removeItemFromAvatar(const LLUUID& item_id);
|
||||
|
||||
|
||||
LLUUID makeNewOutfitLinks(const std::string& new_folder_name,bool show_panel = true);
|
||||
|
||||
bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body);
|
||||
|
||||
static void sortItemsByActualDescription(LLInventoryModel::item_array_t& items);
|
||||
|
||||
//Divvy items into arrays by wearable type
|
||||
static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type);
|
||||
|
||||
//Check ordering information on wearables stored in links' descriptions and update if it is invalid
|
||||
// COF is processed if cat_id is not specified
|
||||
void updateClothingOrderingInfo(LLUUID cat_id = LLUUID::null, bool update_base_outfit_ordering = false);
|
||||
|
||||
bool isOutfitLocked() { return mOutfitLocked; }
|
||||
|
||||
bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; }
|
||||
|
||||
protected:
|
||||
LLAppearanceMgr();
|
||||
~LLAppearanceMgr();
|
||||
|
||||
private:
|
||||
|
||||
void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
|
||||
|
||||
void getDescendentsOfAssetType(const LLUUID& category,
|
||||
LLInventoryModel::item_array_t& items,
|
||||
LLAssetType::EType type,
|
||||
bool follow_folder_links);
|
||||
|
||||
void getUserDescendents(const LLUUID& category,
|
||||
LLInventoryModel::item_array_t& wear_items,
|
||||
LLInventoryModel::item_array_t& obj_items,
|
||||
LLInventoryModel::item_array_t& gest_items,
|
||||
bool follow_folder_links);
|
||||
|
||||
void purgeCategory(const LLUUID& category, bool keep_outfit_links);
|
||||
void purgeBaseOutfitLink(const LLUUID& category);
|
||||
|
||||
static void onOutfitRename(const LLSD& notification, const LLSD& response);
|
||||
|
||||
void setOutfitLocked(bool locked);
|
||||
|
||||
bool mAttachmentInvLinkEnabled;
|
||||
bool mOutfitIsDirty;
|
||||
bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
|
||||
|
||||
/**
|
||||
* Lock for blocking operations on outfit until server reply or timeout exceed
|
||||
* to avoid unsynchronized outfit state or performing duplicate operations.
|
||||
*/
|
||||
bool mOutfitLocked;
|
||||
|
||||
std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Item-specific convenience functions
|
||||
public:
|
||||
// Is this in the COF?
|
||||
BOOL getIsInCOF(const LLUUID& obj_id) const;
|
||||
// Is this in the COF and can the user delete it from the COF?
|
||||
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
|
||||
|
||||
/**
|
||||
* Checks if COF contains link to specified object.
|
||||
*/
|
||||
static bool isLinkInCOF(const LLUUID& obj_id);
|
||||
};
|
||||
|
||||
class LLUpdateAppearanceOnDestroy: public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering = false);
|
||||
virtual ~LLUpdateAppearanceOnDestroy();
|
||||
/* virtual */ void fire(const LLUUID& inv_item);
|
||||
|
||||
private:
|
||||
U32 mFireCount;
|
||||
bool mUpdateBaseOrder;
|
||||
};
|
||||
|
||||
|
||||
#define SUPPORT_ENSEMBLES 0
|
||||
|
||||
LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name);
|
||||
|
||||
// Invoke a given callable after category contents are fully fetched.
|
||||
void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb);
|
||||
|
||||
// Wear all items in a uuid vector.
|
||||
void wear_multiple(const uuid_vec_t& ids, bool replace);
|
||||
|
||||
#endif
|
||||
@@ -123,7 +123,7 @@ private:
|
||||
Impl* mImpl;
|
||||
};
|
||||
|
||||
class LLBakedUploadData;
|
||||
struct LLBakedUploadData;
|
||||
class LLSendTexLayerResponder : public LLAssetUploadResponder
|
||||
{
|
||||
LOG_CLASS(LLSendTexLayerResponder);
|
||||
|
||||
@@ -65,6 +65,7 @@ void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInvento
|
||||
objectp->getType(),
|
||||
LLInventoryType::IT_CATEGORY,
|
||||
panelp,
|
||||
panelp->getRootFolder(),
|
||||
objectp->getUUID());
|
||||
|
||||
if (new_listener)
|
||||
@@ -86,6 +87,7 @@ void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInvento
|
||||
item->getActualType(),
|
||||
item->getInventoryType(),
|
||||
panelp,
|
||||
panelp->getRootFolder(),
|
||||
item->getUUID(),
|
||||
item->getFlags());
|
||||
if (new_listener)
|
||||
|
||||
@@ -98,12 +98,69 @@ BOOL LLDriverParamInfo::parseXml(LLXmlTreeNode* node)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLDriverParamInfo::toStream(std::ostream &out)
|
||||
{
|
||||
LLViewerVisualParamInfo::toStream(out);
|
||||
out << "driver" << "\t";
|
||||
out << mDrivenInfoList.size() << "\t";
|
||||
for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
|
||||
{
|
||||
LLDrivenEntryInfo driven = *iter;
|
||||
out << driven.mDrivenID << "\t";
|
||||
}
|
||||
|
||||
out << std::endl;
|
||||
|
||||
if(isAgentAvatarValid())
|
||||
{
|
||||
for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
|
||||
{
|
||||
LLDrivenEntryInfo driven = *iter;
|
||||
LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID);
|
||||
if (param)
|
||||
{
|
||||
param->getInfo()->toStream(out);
|
||||
if (param->getWearableType() != mWearableType)
|
||||
{
|
||||
if(param->getCrossWearable())
|
||||
{
|
||||
out << "cross-wearable" << "\t";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "ERROR!" << "\t";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "valid" << "\t";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp << " for driver parameter " << getID() << llendl;
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLDriverParam
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LLDriverParam::LLDriverParam(LLVOAvatar *avatarp)
|
||||
: mCurrentDistortionParam( NULL ), mAvatarp(avatarp)
|
||||
LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
|
||||
mCurrentDistortionParam( NULL ),
|
||||
mAvatarp(avatarp),
|
||||
mWearablep(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLDriverParam::LLDriverParam(LLWearable *wearablep) :
|
||||
mCurrentDistortionParam( NULL ),
|
||||
mAvatarp(NULL),
|
||||
mWearablep(wearablep)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -120,27 +177,48 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
|
||||
mID = info->mID;
|
||||
|
||||
setWeight(getDefaultWeight(), FALSE );
|
||||
|
||||
LLDriverParamInfo::entry_info_list_t::iterator iter;
|
||||
mDriven.reserve(getInfo()->mDrivenInfoList.size());
|
||||
for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); iter++)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLDriverParam::setWearable(LLWearable *wearablep)
|
||||
{
|
||||
if (wearablep)
|
||||
{
|
||||
LLDrivenEntryInfo *driven_info = &(*iter);
|
||||
S32 driven_id = driven_info->mDrivenID;
|
||||
LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarp->getVisualParam( driven_id );
|
||||
if (param)
|
||||
mWearablep = wearablep;
|
||||
mAvatarp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLDriverParam::setAvatar(LLVOAvatar *avatarp)
|
||||
{
|
||||
if (avatarp)
|
||||
{
|
||||
mWearablep = NULL;
|
||||
mAvatarp = avatarp;
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
|
||||
{
|
||||
LLDriverParam *new_param;
|
||||
if (wearable)
|
||||
{
|
||||
new_param = new LLDriverParam(wearable);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mWearablep)
|
||||
{
|
||||
mDriven.push_back(LLDrivenEntry( param, driven_info ));
|
||||
new_param = new LLDriverParam(mWearablep);
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "<driven> Unable to resolve driven parameter: " << driven_id << llendl;
|
||||
mInfo = NULL;
|
||||
return FALSE;
|
||||
new_param = new LLDriverParam(mAvatarp);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
*new_param = *this;
|
||||
return new_param;
|
||||
}
|
||||
|
||||
#if 0 // obsolete
|
||||
@@ -406,6 +484,82 @@ void LLDriverParam::stopAnimating(BOOL upload_bake)
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
LLDriverParamInfo::entry_info_list_t::iterator iter;
|
||||
for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); ++iter)
|
||||
{
|
||||
LLDrivenEntryInfo *driven_info = &(*iter);
|
||||
S32 driven_id = driven_info->mDrivenID;
|
||||
|
||||
// check for already existing links. Do not overwrite.
|
||||
BOOL found = FALSE;
|
||||
for (entry_list_t::iterator driven_iter = mDriven.begin(); driven_iter != mDriven.end() && !found; ++driven_iter)
|
||||
{
|
||||
if (driven_iter->mInfo->mDrivenID == driven_id)
|
||||
{
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id);
|
||||
bool push = param && (!only_cross_params || param->getCrossWearable());
|
||||
if (push)
|
||||
{
|
||||
mDriven.push_back(LLDrivenEntry( param, driven_info ));
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void LLDriverParam::resetDrivenParams()
|
||||
{
|
||||
mDriven.clear();
|
||||
mDriven.reserve(getInfo()->mDrivenInfoList.size());
|
||||
}
|
||||
|
||||
void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
|
||||
{
|
||||
bool needs_update = (getWearableType()==driven_type);
|
||||
|
||||
// if the driver has a driven entry for the passed-in wearable type, we need to refresh the value
|
||||
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
|
||||
{
|
||||
LLDrivenEntry* driven = &(*iter);
|
||||
if (driven && driven->mParam && driven->mParam->getCrossWearable() && driven->mParam->getWearableType() == driven_type)
|
||||
{
|
||||
needs_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (needs_update)
|
||||
{
|
||||
LLWearableType::EType driver_type = (LLWearableType::EType)getWearableType();
|
||||
|
||||
// If we've gotten here, we've added a new wearable of type "type"
|
||||
// Thus this wearable needs to get updates from the driver wearable.
|
||||
// The call to setVisualParamWeight seems redundant, but is necessary
|
||||
// as the number of driven wearables has changed since the last update. -Nyx
|
||||
LLWearable *wearable = gAgentWearables.getTopWearable(driver_type);
|
||||
if (wearable)
|
||||
{
|
||||
wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// getDrivenWeight()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -465,7 +619,7 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight
|
||||
|
||||
void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
|
||||
{
|
||||
/*if(isAgentAvatarValid() &&
|
||||
if(isAgentAvatarValid() &&
|
||||
mWearablep &&
|
||||
driven->mParam->getCrossWearable() &&
|
||||
mWearablep->isOnTop())
|
||||
@@ -473,7 +627,7 @@ void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bo
|
||||
// call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
|
||||
gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
|
||||
}
|
||||
else*/
|
||||
else
|
||||
{
|
||||
driven->mParam->setWeight( driven_weight, upload_bake );
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ public:
|
||||
|
||||
/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
|
||||
|
||||
/*virtual*/ void toStream(std::ostream &out);
|
||||
|
||||
protected:
|
||||
typedef std::deque<LLDrivenEntryInfo> entry_info_list_t;
|
||||
entry_info_list_t mDrivenInfoList;
|
||||
@@ -78,6 +80,7 @@ class LLDriverParam : public LLViewerVisualParam
|
||||
friend class LLPhysicsMotion; // physics motion needs to access driven params directly.
|
||||
public:
|
||||
LLDriverParam(LLVOAvatar *avatarp);
|
||||
LLDriverParam(LLWearable *wearablep);
|
||||
~LLDriverParam();
|
||||
|
||||
// Special: These functions are overridden by child classes
|
||||
@@ -85,12 +88,20 @@ public:
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLDriverParamInfo *info);
|
||||
|
||||
void setWearable(LLWearable *wearablep);
|
||||
void setAvatar(LLVOAvatar *avatarp);
|
||||
void updateCrossDrivenParams(LLWearableType::EType driven_type);
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||
/*virtual*/ void apply( ESex sex ) {} // apply is called separately for each driven param.
|
||||
/*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
|
||||
/*virtual*/ void setAnimationTarget( F32 target_value, BOOL upload_bake );
|
||||
/*virtual*/ void stopAnimating(BOOL upload_bake);
|
||||
/*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
|
||||
/*virtual*/ void resetDrivenParams();
|
||||
|
||||
// LLViewerVisualParam Virtual functions
|
||||
/*virtual*/ F32 getTotalDistortion();
|
||||
@@ -111,6 +122,7 @@ protected:
|
||||
LLViewerVisualParam* mCurrentDistortionParam;
|
||||
// Backlink only; don't make this an LLPointer.
|
||||
LLVOAvatar* mAvatarp;
|
||||
LLWearable* mWearablep;
|
||||
};
|
||||
|
||||
#endif // LL_LLDRIVERPARAM_H
|
||||
|
||||
@@ -140,7 +140,7 @@ BOOL LLFloaterAvatarPicker::postBuild()
|
||||
inventory_panel->setFollowsAll();
|
||||
inventory_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
inventory_panel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD);
|
||||
inventory_panel->setSelectCallback(LLFloaterAvatarPicker::onCallingCardSelectionChange, this);
|
||||
inventory_panel->setSelectCallback(boost::bind(&LLFloaterAvatarPicker::onCallingCardSelectionChange, _1, _2, (void*)this));
|
||||
|
||||
childSetTabChangeCallback("ResidentChooserTabs", "SearchPanel", onTabChanged, this);
|
||||
childSetTabChangeCallback("ResidentChooserTabs", "CallingCardsPanel", onTabChanged, this);
|
||||
|
||||
@@ -765,8 +765,7 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata)
|
||||
{
|
||||
LLPanelEditWearable* self = (LLPanelEditWearable*) userdata;
|
||||
LLCheckBoxCtrl* checkbox_ctrl = (LLCheckBoxCtrl*) ctrl;
|
||||
LLVOAvatar *avatar = gAgentAvatarp;
|
||||
if (!avatar)
|
||||
if (!gAgentAvatarp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -777,13 +776,13 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata)
|
||||
if (new_invis_state)
|
||||
{
|
||||
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(IMG_INVISIBLE);
|
||||
const LLTextureEntry* current_te = avatar->getTE(te);
|
||||
const LLTextureEntry* current_te = gAgentAvatarp->getTE(te);
|
||||
if (current_te)
|
||||
{
|
||||
self->mPreviousTextureList[(S32)te] = current_te->getID();
|
||||
}
|
||||
avatar->setLocTexTE(te, image, TRUE);
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
gAgentAvatarp->setLocalTextureTE(te,image, 0);
|
||||
gAgentAvatarp->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -796,8 +795,8 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata)
|
||||
if (prev_id.notNull())
|
||||
{
|
||||
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(prev_id);
|
||||
avatar->setLocTexTE(te, image, TRUE);
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
gAgentAvatarp->setLocalTextureTE(te, image, 0);
|
||||
gAgentAvatarp->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -894,8 +893,7 @@ void LLPanelEditWearable::onTextureCommit( LLUICtrl* ctrl, void* userdata )
|
||||
LLPanelEditWearable* self = (LLPanelEditWearable*) userdata;
|
||||
LLTextureCtrl* texture_ctrl = (LLTextureCtrl*) ctrl;
|
||||
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
if( avatar )
|
||||
if( gAgentAvatarp )
|
||||
{
|
||||
ETextureIndex te = (ETextureIndex)(self->mTextureList[ctrl->getName()]);
|
||||
|
||||
@@ -908,8 +906,8 @@ void LLPanelEditWearable::onTextureCommit( LLUICtrl* ctrl, void* userdata )
|
||||
self->mTextureList[ctrl->getName()] = te;
|
||||
if (gAgentWearables.getWearable(self->mType, 0)) // TODO: MULTI-WEARABLE
|
||||
{
|
||||
avatar->setLocTexTE(te, image, TRUE);
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
gAgentAvatarp->setLocalTextureTE(te, image, 0);
|
||||
gAgentAvatarp->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
if (self->mType == LLWearableType::WT_ALPHA && image->getID() != IMG_INVISIBLE)
|
||||
{
|
||||
@@ -2039,7 +2037,8 @@ void LLFloaterCustomize::onMakeOutfitCommit( LLMakeOutfitDialog* dialog, void* u
|
||||
|
||||
dialog->getIncludedItems( wearables_to_include, attachments_to_include );
|
||||
|
||||
gAgentWearables.makeNewOutfit( dialog->getFolderName(), wearables_to_include, attachments_to_include, dialog->getRenameClothing() );
|
||||
// MULTI-WEARABLES TODO
|
||||
//LLAppearanceMgr::getInstance()->makeNewOutfit( dialog->getFolderName(), wearables_to_include, attachments_to_include, dialog->getRenameClothing() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ LLFloaterLandmark::LLFloaterLandmark(const LLSD& data)
|
||||
|
||||
mInventoryPanel->setFilterTypes(filter_types);
|
||||
//mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
|
||||
mInventoryPanel->setSelectCallback(onSelectionChange, this);
|
||||
mInventoryPanel->setSelectCallback(boost::bind(onSelectionChange, _1, _2, (void*)this));
|
||||
mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mInventoryPanel->setAllowMultiSelect(FALSE);
|
||||
|
||||
|
||||
@@ -196,12 +196,12 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
|
||||
|
||||
// Default constructor
|
||||
LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon,
|
||||
const LLRect& rect, const LLUUID& source_id, LLView *parent_view ) :
|
||||
const LLRect& rect, const LLUUID& source_id, LLView *parent_view, LLFolderViewEventListener* listener ) :
|
||||
#if LL_WINDOWS
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list
|
||||
#endif
|
||||
LLFolderViewFolder( name, root_folder_icon, this, NULL ),
|
||||
LLFolderViewFolder( name, root_folder_icon, this, listener ),
|
||||
#if LL_WINDOWS
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
@@ -223,8 +223,6 @@ LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_ic
|
||||
mShowSelectionContext(FALSE),
|
||||
mShowSingleSelection(FALSE),
|
||||
mArrangeGeneration(0),
|
||||
mUserData(NULL),
|
||||
mSelectCallback(NULL),
|
||||
mSignalSelectCallback(0),
|
||||
mMinWidth(0),
|
||||
mDragAndDropThisFrame(FALSE)
|
||||
@@ -274,6 +272,8 @@ LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_ic
|
||||
// Destroys the object
|
||||
LLFolderView::~LLFolderView( void )
|
||||
{
|
||||
closeRenamer();
|
||||
|
||||
// The release focus call can potentially call the
|
||||
// scrollcontainer, which can potentially be called with a partly
|
||||
// destroyed scollcontainer. Just null it out here, and no worries
|
||||
@@ -292,7 +292,7 @@ LLFolderView::~LLFolderView( void )
|
||||
mAutoOpenItems.removeAllNodes();
|
||||
gIdleCallbacks.deleteFunction(idle, this);
|
||||
|
||||
LLView::deleteViewByHandle(mPopupMenuHandle);
|
||||
if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
|
||||
|
||||
if(mRenamer == gFocusMgr.getTopCtrl())
|
||||
{
|
||||
@@ -434,6 +434,7 @@ void LLFolderView::closeAllFolders()
|
||||
{
|
||||
// Close all the folders
|
||||
setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
|
||||
arrangeAll();
|
||||
}
|
||||
|
||||
void LLFolderView::openFolder(const std::string& foldername)
|
||||
@@ -541,6 +542,9 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
|
||||
reshape( llmax(min_width, total_width), running_height );
|
||||
}
|
||||
|
||||
// move item renamer text field to item's new position
|
||||
updateRenamerPosition();
|
||||
|
||||
mTargetHeight = (F32)target_height;
|
||||
return llround(mTargetHeight);
|
||||
}
|
||||
@@ -580,6 +584,8 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
}
|
||||
width = llmax(mMinWidth, min_width);
|
||||
LLView::reshape(width, height, called_from_parent);
|
||||
|
||||
mReshapeSignal(mSelectedItems, FALSE);
|
||||
}
|
||||
|
||||
void LLFolderView::addToSelectionList(LLFolderViewItem* item)
|
||||
@@ -835,8 +841,7 @@ void LLFolderView::sanitizeSelection()
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing selected to start with, so pick "My Inventory" as best guess
|
||||
new_selection = getItemByID(gInventory.getRootFolderID());
|
||||
new_selection = NULL;
|
||||
}
|
||||
|
||||
if (new_selection)
|
||||
@@ -952,6 +957,7 @@ void LLFolderView::draw()
|
||||
}
|
||||
else
|
||||
{
|
||||
static LLCachedControl<LLColor4> sSearchStatusColor(gColors, "InventorySearchStatusColor", LLColor4::white );
|
||||
if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
|
||||
{
|
||||
mStatusText = std::string("Searching..."); // *TODO:translate
|
||||
@@ -980,17 +986,7 @@ void LLFolderView::finishRenamingItem( void )
|
||||
mRenameItem->rename( mRenamer->getText() );
|
||||
}
|
||||
|
||||
mRenamer->setCommitOnFocusLost( FALSE );
|
||||
mRenamer->setFocus( FALSE );
|
||||
mRenamer->setVisible( FALSE );
|
||||
mRenamer->setCommitOnFocusLost( TRUE );
|
||||
gFocusMgr.setTopCtrl( NULL );
|
||||
|
||||
if( mRenameItem )
|
||||
{
|
||||
setSelectionFromRoot( mRenameItem, TRUE );
|
||||
mRenameItem = NULL;
|
||||
}
|
||||
closeRenamer();
|
||||
|
||||
// List is re-sorted alphabeticly, so scroll to make sure the selected item is visible.
|
||||
scrollToShowSelection();
|
||||
@@ -998,15 +994,10 @@ void LLFolderView::finishRenamingItem( void )
|
||||
|
||||
void LLFolderView::closeRenamer( void )
|
||||
{
|
||||
// will commit current name (which could be same as original name)
|
||||
mRenamer->setFocus( FALSE );
|
||||
mRenamer->setVisible( FALSE );
|
||||
gFocusMgr.setTopCtrl( NULL );
|
||||
|
||||
if( mRenameItem )
|
||||
if (mRenamer && mRenamer->getVisible())
|
||||
{
|
||||
setSelectionFromRoot( mRenameItem, TRUE );
|
||||
mRenameItem = NULL;
|
||||
// Triggers onRenamerLost() that actually closes the renamer.
|
||||
gFocusMgr.setTopCtrl( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1081,7 +1072,7 @@ void LLFolderView::removeSelectedItems( void )
|
||||
if (!new_selection)
|
||||
{
|
||||
new_selection = last_item->getPreviousOpenNode(FALSE);
|
||||
while (new_selection && new_selection->isSelected())
|
||||
while (new_selection && (new_selection->isSelected()/* || isDescendantOfASelectedItem(new_selection, items)*/))
|
||||
{
|
||||
new_selection = new_selection->getPreviousOpenNode(FALSE);
|
||||
}
|
||||
@@ -1186,9 +1177,20 @@ void LLFolderView::propertiesSelectedItems( void )
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type)
|
||||
{
|
||||
LLFolderBridge *folder_bridge = LLFolderBridge::sSelf.get();
|
||||
|
||||
if (!folder_bridge) return;
|
||||
LLViewerInventoryCategory *cat = folder_bridge->getCategory();
|
||||
if (!cat) return;
|
||||
cat->changeType(new_folder_type);
|
||||
}
|
||||
void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
|
||||
{
|
||||
if (mAutoOpenItems.check() == item || mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH)
|
||||
if ((mAutoOpenItems.check() == item) ||
|
||||
(mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) ||
|
||||
item->isOpen())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1298,12 +1300,43 @@ void LLFolderView::copy()
|
||||
|
||||
BOOL LLFolderView::canCut() const
|
||||
{
|
||||
return FALSE;
|
||||
if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
|
||||
{
|
||||
const LLFolderViewItem* item = *selected_it;
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
|
||||
if (!listener || !listener->isItemRemovable())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFolderView::cut()
|
||||
{
|
||||
// implement Windows-style cut-and-leave
|
||||
// clear the inventory clipboard
|
||||
LLInventoryClipboard::instance().reset();
|
||||
S32 count = mSelectedItems.size();
|
||||
if(getVisible() && getEnabled() && (count > 0))
|
||||
{
|
||||
LLFolderViewEventListener* listener = NULL;
|
||||
selected_items_t::iterator item_it;
|
||||
for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
|
||||
{
|
||||
listener = (*item_it)->getListener();
|
||||
if(listener)
|
||||
{
|
||||
listener->cutToClipboard();
|
||||
}
|
||||
}
|
||||
}
|
||||
mSearchString.clear();
|
||||
}
|
||||
|
||||
BOOL LLFolderView::canPaste() const
|
||||
@@ -1386,23 +1419,8 @@ void LLFolderView::startRenamingSelectedItem( void )
|
||||
{
|
||||
mRenameItem = item;
|
||||
|
||||
S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD - 1 + item->getIndentation();
|
||||
S32 y = llfloor(item->getRect().getHeight()-sFont->getLineHeight()-2);
|
||||
item->localPointToScreen( x, y, &x, &y );
|
||||
screenPointToLocal( x, y, &x, &y );
|
||||
mRenamer->setOrigin( x, y );
|
||||
updateRenamerPosition();
|
||||
|
||||
S32 scroller_height = 0;
|
||||
S32 scroller_width = gViewerWindow->getWindowWidth();
|
||||
BOOL dummy_bool;
|
||||
if (mScrollContainer)
|
||||
{
|
||||
mScrollContainer->calcVisibleSize( &scroller_width, &scroller_height, &dummy_bool, &dummy_bool);
|
||||
}
|
||||
|
||||
S32 width = llmax(llmin(item->getRect().getWidth() - x, scroller_width - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
|
||||
S32 height = llfloor(sFont->getLineHeight() + RENAME_HEIGHT_PAD);
|
||||
mRenamer->reshape( width, height, TRUE );
|
||||
|
||||
mRenamer->setText(item->getName());
|
||||
mRenamer->selectAll();
|
||||
@@ -2091,11 +2109,11 @@ void LLFolderView::doIdle()
|
||||
}
|
||||
}
|
||||
|
||||
if (mSignalSelectCallback && mSelectCallback)
|
||||
if (mSignalSelectCallback)
|
||||
{
|
||||
//RN: we use keyboard focus as a proxy for user-explicit actions
|
||||
BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS);
|
||||
mSelectCallback(mSelectedItems, take_keyboard_focus, mUserData);
|
||||
mSelectSignal(mSelectedItems, take_keyboard_focus);
|
||||
}
|
||||
mSignalSelectCallback = FALSE;
|
||||
}
|
||||
@@ -2111,7 +2129,6 @@ void LLFolderView::idle(void* user_data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLFolderView::dumpSelectionInformation()
|
||||
{
|
||||
llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
|
||||
@@ -2124,6 +2141,29 @@ void LLFolderView::dumpSelectionInformation()
|
||||
llinfos << "****************************************" << llendl;
|
||||
}
|
||||
|
||||
void LLFolderView::updateRenamerPosition()
|
||||
{
|
||||
if(mRenameItem)
|
||||
{
|
||||
// See also LLFolderViewItem::draw()
|
||||
S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mRenameItem->getIndentation();
|
||||
S32 y = mRenameItem->getRect().getHeight() - mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
|
||||
mRenameItem->localPointToScreen( x, y, &x, &y );
|
||||
screenPointToLocal( x, y, &x, &y );
|
||||
mRenamer->setOrigin( x, y );
|
||||
|
||||
LLRect scroller_rect(0, 0, gViewerWindow->getWindowWidthScaled(), 0);
|
||||
if (mScrollContainer)
|
||||
{
|
||||
BOOL dummy_bool;
|
||||
mScrollContainer->calcVisibleSize( &scroller_rect.mRight, &scroller_rect.mTop, &dummy_bool, &dummy_bool);
|
||||
}
|
||||
|
||||
S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
|
||||
S32 height = mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
|
||||
mRenamer->reshape( width, height, TRUE );
|
||||
}
|
||||
}
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function definitions
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
@@ -74,15 +74,14 @@ class LLTextBox;
|
||||
class LLUICtrl;
|
||||
class LLLineEditor;
|
||||
|
||||
class LLFolderView : public LLFolderViewFolder, LLEditMenuHandler
|
||||
class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
|
||||
{
|
||||
public:
|
||||
typedef void (*SelectCallback)(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data);
|
||||
|
||||
static F32 sAutoOpenTime;
|
||||
|
||||
LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon, const LLRect& rect,
|
||||
const LLUUID& source_id, LLView *parent_view );
|
||||
const LLUUID& source_id, LLView *parent_view, LLFolderViewEventListener* listener );
|
||||
virtual ~LLFolderView( void );
|
||||
|
||||
virtual BOOL canFocusChildren() const;
|
||||
@@ -94,7 +93,10 @@ public:
|
||||
void setSortOrder(U32 order);
|
||||
void checkTreeResortForModelChanged();
|
||||
void setFilterPermMask(PermissionMask filter_perm_mask);
|
||||
void setSelectCallback(SelectCallback callback, void* user_data) { mSelectCallback = callback, mUserData = user_data; }
|
||||
|
||||
typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
|
||||
void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
|
||||
void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
|
||||
void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; }
|
||||
|
||||
LLInventoryFilter* getFilter();
|
||||
@@ -106,6 +108,7 @@ public:
|
||||
//LLInventoryFilter::EFolderShow getShowFolderState();
|
||||
U32 getSortOrder() const;
|
||||
BOOL isFilterModified();
|
||||
|
||||
BOOL getAllowMultiSelect() { return mAllowMultiSelect; }
|
||||
|
||||
U32 toggleSearchType(std::string toggle);
|
||||
@@ -152,6 +155,8 @@ public:
|
||||
|
||||
BOOL startDrag(LLToolDragAndDrop::ESource source);
|
||||
void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; }
|
||||
void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
|
||||
LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
|
||||
|
||||
// deletion functionality
|
||||
void removeSelectedItems();
|
||||
@@ -160,6 +165,9 @@ public:
|
||||
void openSelectedItems( void );
|
||||
void propertiesSelectedItems( void );
|
||||
|
||||
// change the folder type
|
||||
void changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type);
|
||||
|
||||
void autoOpenItem(LLFolderViewFolder* item);
|
||||
void closeAutoOpenedFolders();
|
||||
BOOL autoOpenTest(LLFolderViewFolder* item);
|
||||
@@ -238,6 +246,7 @@ public:
|
||||
// DEBUG only
|
||||
void dumpSelectionInformation();
|
||||
|
||||
void updateRenamerPosition();
|
||||
protected:
|
||||
LLScrollableContainerView* mScrollContainer; // NULL if this is not a child of a scroll container.
|
||||
|
||||
@@ -282,13 +291,20 @@ protected:
|
||||
LLFrameTimer mMultiSelectionFadeTimer;
|
||||
S32 mArrangeGeneration;
|
||||
|
||||
void* mUserData;
|
||||
SelectCallback mSelectCallback;
|
||||
signal_t mSelectSignal;
|
||||
signal_t mReshapeSignal;
|
||||
S32 mSignalSelectCallback;
|
||||
S32 mMinWidth;
|
||||
std::map<LLUUID, LLFolderViewItem*> mItemMap;
|
||||
BOOL mDragAndDropThisFrame;
|
||||
|
||||
/**
|
||||
* Contains item under mouse pointer while dragging
|
||||
*/
|
||||
LLFolderViewItem* mDraggingOverItem; // See EXT-719
|
||||
|
||||
public:
|
||||
static F32 sAutoOpenTime;
|
||||
};
|
||||
|
||||
bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b);
|
||||
|
||||
@@ -55,23 +55,26 @@ public:
|
||||
virtual const LLUUID& getUUID() const = 0;
|
||||
virtual time_t getCreationDate() const = 0; // UTC seconds
|
||||
virtual PermissionMask getPermissionMask() const = 0;
|
||||
virtual LLFolderType::EType getPreferredType() const = 0;
|
||||
virtual LLPointer<LLUIImage> getIcon() const = 0;
|
||||
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;
|
||||
virtual BOOL isItemRenameable() const = 0;
|
||||
virtual BOOL renameItem(const std::string& new_name) = 0;
|
||||
virtual BOOL isItemMovable( void ) = 0; // Can be moved to another folder
|
||||
virtual BOOL isItemRemovable( void ) = 0; // Can be destroyed
|
||||
virtual BOOL isItemMovable( void ) const = 0; // Can be moved to another folder
|
||||
virtual BOOL isItemRemovable( void ) const = 0; // Can be destroyed
|
||||
virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
|
||||
virtual BOOL removeItem() = 0;
|
||||
virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0;
|
||||
virtual void move( LLFolderViewEventListener* parent_listener ) = 0;
|
||||
virtual BOOL isItemCopyable() const = 0;
|
||||
virtual BOOL copyToClipboard() const = 0;
|
||||
virtual BOOL cutToClipboard() const = 0;
|
||||
virtual void cutToClipboard() = 0;
|
||||
virtual BOOL isClipboardPasteable() const = 0;
|
||||
virtual void pasteFromClipboard() = 0;
|
||||
virtual void pasteLinkFromClipboard() = 0;
|
||||
@@ -79,7 +82,8 @@ public:
|
||||
virtual BOOL isUpToDate() const = 0;
|
||||
virtual BOOL hasChildren() const = 0;
|
||||
virtual LLInventoryType::EType getInventoryType() const = 0;
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) {}
|
||||
virtual void performAction(LLInventoryModel* model, std::string action) = 0;
|
||||
virtual LLWearableType::EType getWearableType() const = 0;
|
||||
|
||||
// This method should be called when a drag begins. returns TRUE
|
||||
// if the drag can begin, otherwise FALSE.
|
||||
|
||||
@@ -50,13 +50,6 @@ const LLFontGL* LLFolderViewItem::sSmallFont = NULL;
|
||||
const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
|
||||
const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
|
||||
|
||||
LLColor4 LLFolderViewItem::sFgColor;
|
||||
LLColor4 LLFolderViewItem::sHighlightBgColor;
|
||||
LLColor4 LLFolderViewItem::sHighlightFgColor;
|
||||
LLColor4 LLFolderViewItem::sFilterBGColor;
|
||||
LLColor4 LLFolderViewItem::sFilterTextColor;
|
||||
LLColor4 LLFolderViewItem::sSuffixColor;
|
||||
LLColor4 LLFolderViewItem::sSearchStatusColor;
|
||||
LLUIImagePtr LLFolderViewItem::sArrowImage;
|
||||
LLUIImagePtr LLFolderViewItem::sBoxImage;
|
||||
|
||||
@@ -69,13 +62,6 @@ void LLFolderViewItem::initClass()
|
||||
{
|
||||
sFont = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
|
||||
sSmallFont = LLResMgr::getInstance()->getRes( LLFONT_SMALL );
|
||||
sFgColor = gColors.getColor( "MenuItemEnabledColor" );
|
||||
sHighlightBgColor = gColors.getColor( "MenuItemHighlightBgColor" );
|
||||
sHighlightFgColor = gColors.getColor( "MenuItemHighlightFgColor" );
|
||||
sFilterBGColor = gColors.getColor( "FilterBackgroundColor" );
|
||||
sFilterTextColor = gColors.getColor( "FilterTextColor" );
|
||||
sSuffixColor = gColors.getColor( "InventoryItemSuffixColor" );
|
||||
sSearchStatusColor = gColors.getColor( "InventorySearchStatusColor" );
|
||||
sArrowImage = LLUI::getUIImage("folder_arrow.tga");
|
||||
sBoxImage = LLUI::getUIImage("rounded_square.tga");
|
||||
}
|
||||
@@ -117,9 +103,15 @@ LLFolderViewItem::LLFolderViewItem( const std::string& name, LLUIImagePtr icon,
|
||||
mListener(listener)
|
||||
{
|
||||
sFolderViewItems.insert(this);
|
||||
refresh(); // possible opt: only call refreshFromListener()
|
||||
setTabStop(FALSE);
|
||||
}
|
||||
|
||||
BOOL LLFolderViewItem::postBuild()
|
||||
{
|
||||
refresh();
|
||||
setTabStop(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Destroys the object
|
||||
LLFolderViewItem::~LLFolderViewItem( void )
|
||||
{
|
||||
@@ -225,8 +217,6 @@ void LLFolderViewItem::setIcon(LLUIImagePtr icon)
|
||||
mIcon = icon;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// refresh information from the listener
|
||||
void LLFolderViewItem::refreshFromListener()
|
||||
{
|
||||
@@ -378,7 +368,7 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
|
||||
|
||||
S32 LLFolderViewItem::getItemHeight()
|
||||
{
|
||||
S32 icon_height = mIcon->getHeight();
|
||||
S32 icon_height = mIcon.notNull() ? mIcon->getHeight() : 0;
|
||||
S32 label_height = llround(sFont->getLineHeight());
|
||||
return llmax( icon_height, label_height ) + ICON_PAD;
|
||||
}
|
||||
@@ -807,7 +797,10 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
}
|
||||
if(mParentFolder && !handled)
|
||||
{
|
||||
// store this item to get it in LLFolderBridge::dragItemIntoFolder on drop event.
|
||||
mRoot->setDraggingOverItem(this);
|
||||
handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
|
||||
mRoot->setDraggingOverItem(NULL);
|
||||
}
|
||||
if (handled)
|
||||
{
|
||||
@@ -820,35 +813,46 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
|
||||
void LLFolderViewItem::draw()
|
||||
{
|
||||
bool possibly_has_children = false;
|
||||
bool up_to_date = mListener && mListener->isUpToDate();
|
||||
if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter...
|
||||
(!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter)
|
||||
static LLCachedControl<LLColor4> sFgColor(gColors, "MenuItemEnabledColor", LLColor4::white );
|
||||
static LLCachedControl<LLColor4> sHighlightBgColor(gColors, "MenuItemHighlightBgColor", LLColor4::white );
|
||||
static LLCachedControl<LLColor4> sHighlightFgColor(gColors, "MenuItemHighlightFgColor", LLColor4::white );
|
||||
static LLCachedControl<LLColor4> sFilterBGColor(gColors, "FilterBackgroundColor", LLColor4::white );
|
||||
static LLCachedControl<LLColor4> sFilterTextColor(gColors, "FilterTextColor", LLColor4::white );
|
||||
static LLCachedControl<LLColor4> sSuffixColor(gColors, "InventoryItemSuffixColor", LLColor4::white );
|
||||
static LLCachedControl<LLColor4> sSearchStatusColor(gColors, "InventorySearchStatusColor", LLColor4::white );
|
||||
|
||||
const S32 TOP_PAD = 0;
|
||||
const S32 FOCUS_LEFT = 0;
|
||||
const LLFontGL* font = sFont;
|
||||
|
||||
const BOOL in_inventory = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getRootFolderID());
|
||||
const BOOL in_library = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getLibraryRootFolderID());
|
||||
|
||||
//--------------------------------------------------------------------------------//
|
||||
// Draw open folder arrow
|
||||
//
|
||||
const bool up_to_date = mListener && mListener->isUpToDate();
|
||||
const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter...
|
||||
|| (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
|
||||
if (possibly_has_children && sArrowImage)
|
||||
{
|
||||
possibly_has_children = true;
|
||||
}
|
||||
if(/*mControlLabel[0] != '\0' && */possibly_has_children)
|
||||
{
|
||||
if (sArrowImage)
|
||||
{
|
||||
gl_draw_scaled_rotated_image(mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD,
|
||||
ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, sArrowImage->getImage(), sFgColor);
|
||||
}
|
||||
gl_draw_scaled_rotated_image(
|
||||
mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD,
|
||||
ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, sArrowImage->getImage(), sFgColor);
|
||||
}
|
||||
|
||||
F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
|
||||
|
||||
// If we have keyboard focus, draw selection filled
|
||||
BOOL show_context = getRoot()->getShowSelectionContext();
|
||||
BOOL filled = show_context || (gFocusMgr.getKeyboardFocus() == getRoot());
|
||||
|
||||
// always render "current" item, only render other selected items if
|
||||
// mShowSingleSelection is FALSE
|
||||
if( mIsSelected )
|
||||
//--------------------------------------------------------------------------------//
|
||||
// Draw highlight for selected items
|
||||
//
|
||||
const BOOL show_context = getRoot()->getShowSelectionContext();
|
||||
const BOOL filled = show_context || (getRoot()->getParent()->hasFocus()); // If we have keyboard focus, draw selection filled
|
||||
const S32 focus_top = getRect().getHeight();
|
||||
const S32 focus_bottom = getRect().getHeight() - getItemHeight();
|
||||
const bool folder_open = (getRect().getHeight() > getItemHeight() + 4);
|
||||
if (mIsSelected) // always render "current" item. Only render other selected items if mShowSingleSelection is FALSE
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLColor4 bg_color = sHighlightBgColor;
|
||||
//const S32 TRAILING_PAD = 5; // It just looks better with this.
|
||||
if (!mIsCurSelection)
|
||||
{
|
||||
// do time-based fade of extra objects
|
||||
@@ -864,37 +868,32 @@ void LLFolderViewItem::draw()
|
||||
bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
|
||||
}
|
||||
}
|
||||
|
||||
gl_rect_2d(
|
||||
0,
|
||||
getRect().getHeight(),
|
||||
getRect().getWidth() - 2,
|
||||
llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD),
|
||||
bg_color, filled);
|
||||
gl_rect_2d(FOCUS_LEFT,
|
||||
focus_top,
|
||||
getRect().getWidth() - 2,
|
||||
focus_bottom,
|
||||
bg_color, filled);
|
||||
if (mIsCurSelection)
|
||||
{
|
||||
gl_rect_2d(
|
||||
0,
|
||||
getRect().getHeight(),
|
||||
getRect().getWidth() - 2,
|
||||
llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD),
|
||||
gl_rect_2d(FOCUS_LEFT,
|
||||
focus_top,
|
||||
getRect().getWidth() - 2,
|
||||
focus_bottom,
|
||||
sHighlightFgColor, FALSE);
|
||||
}
|
||||
if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2)
|
||||
if (folder_open)
|
||||
{
|
||||
gl_rect_2d(
|
||||
0,
|
||||
llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
|
||||
getRect().getWidth() - 2,
|
||||
2,
|
||||
gl_rect_2d(FOCUS_LEFT,
|
||||
focus_bottom + 1, // overlap with bottom edge of above rect
|
||||
getRect().getWidth() - 2,
|
||||
0,
|
||||
sHighlightFgColor, FALSE);
|
||||
if (show_context)
|
||||
{
|
||||
gl_rect_2d(
|
||||
0,
|
||||
llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
|
||||
getRect().getWidth() - 2,
|
||||
2,
|
||||
gl_rect_2d(FOCUS_LEFT,
|
||||
focus_bottom + 1,
|
||||
getRect().getWidth() - 2,
|
||||
0,
|
||||
sHighlightBgColor, TRUE);
|
||||
}
|
||||
}
|
||||
@@ -902,46 +901,49 @@ void LLFolderViewItem::draw()
|
||||
if (mDragAndDropTarget)
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gl_rect_2d(
|
||||
0,
|
||||
getRect().getHeight(),
|
||||
getRect().getWidth() - 2,
|
||||
llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD),
|
||||
sHighlightBgColor, FALSE);
|
||||
|
||||
if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2)
|
||||
gl_rect_2d(FOCUS_LEFT,
|
||||
focus_top,
|
||||
getRect().getWidth() - 2,
|
||||
focus_bottom,
|
||||
sHighlightBgColor, FALSE);
|
||||
if (folder_open)
|
||||
{
|
||||
gl_rect_2d(
|
||||
0,
|
||||
llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
|
||||
getRect().getWidth() - 2,
|
||||
2,
|
||||
sHighlightBgColor, FALSE);
|
||||
gl_rect_2d(FOCUS_LEFT,
|
||||
focus_bottom + 1, // overlap with bottom edge of above rect
|
||||
getRect().getWidth() - 2,
|
||||
0,
|
||||
sHighlightBgColor, FALSE);
|
||||
}
|
||||
mDragAndDropTarget = FALSE;
|
||||
}
|
||||
|
||||
|
||||
if(mIcon)
|
||||
const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
|
||||
if (mIcon)
|
||||
{
|
||||
mIcon->draw(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight());
|
||||
mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------//
|
||||
// Exit if no label to draw
|
||||
//
|
||||
if (mLabel.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
|
||||
F32 right_x = 0;
|
||||
F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
|
||||
F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
|
||||
|
||||
if (!mLabel.empty())
|
||||
//--------------------------------------------------------------------------------//
|
||||
// Highlight filtered text
|
||||
//
|
||||
if (getRoot()->getDebugFilters())
|
||||
{
|
||||
// highlight filtered text
|
||||
BOOL debug_filters = getRoot()->getDebugFilters();
|
||||
LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor );
|
||||
F32 right_x;
|
||||
F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
|
||||
|
||||
if (debug_filters)
|
||||
{
|
||||
if (!getFiltered() && !possibly_has_children)
|
||||
{
|
||||
color.mV[VALPHA] *= 0.5f;
|
||||
}
|
||||
|
||||
LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ?
|
||||
LLColor4(0.5f, 0.8f, 0.5f, 1.f) :
|
||||
LLColor4(0.8f, 0.5f, 0.5f, 1.f);
|
||||
@@ -950,49 +952,70 @@ void LLFolderViewItem::draw()
|
||||
S32_MAX, S32_MAX, &right_x, FALSE );
|
||||
text_left = right_x;
|
||||
}
|
||||
//--------------------------------------------------------------------------------//
|
||||
// Draw the actual label text
|
||||
//
|
||||
font->renderUTF8(mLabel, 0, text_left, y, color,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE);
|
||||
|
||||
//--------------------------------------------------------------------------------//
|
||||
// Draw "Loading..." text
|
||||
//
|
||||
bool root_is_loading = false;
|
||||
if (in_inventory)
|
||||
{
|
||||
root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress();
|
||||
}
|
||||
if (in_library)
|
||||
{
|
||||
root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
|
||||
}
|
||||
if ((mIsLoading
|
||||
&& mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
|
||||
|| (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive()
|
||||
&& root_is_loading))
|
||||
{
|
||||
std::string load_string = " ( Loading... ) ";
|
||||
font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, S32_MAX, &right_x, FALSE);
|
||||
}
|
||||
|
||||
if ( mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime") )
|
||||
{
|
||||
// *TODO: Translate
|
||||
sFont->renderUTF8( std::string("Loading... "), 0, text_left, y, sSearchStatusColor,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x, FALSE);
|
||||
text_left = right_x;
|
||||
}
|
||||
//--------------------------------------------------------------------------------//
|
||||
// Draw label suffix
|
||||
//
|
||||
if (!mLabelSuffix.empty())
|
||||
{
|
||||
font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, S32_MAX, &right_x, FALSE );
|
||||
}
|
||||
|
||||
sFont->renderUTF8( mLabel, 0, text_left, y, color,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, S32_MAX, &right_x, FALSE );
|
||||
if (!mLabelSuffix.empty())
|
||||
{
|
||||
sFont->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, S32_MAX, &right_x, FALSE );
|
||||
}
|
||||
|
||||
if (sBoxImage.notNull() && mStringMatchOffset != std::string::npos)
|
||||
{
|
||||
// don't draw backgrounds for zero-length strings
|
||||
std::string combined_string = mLabel + mLabelSuffix;
|
||||
S32 filter_string_length = getRoot()->getFilterSubString().size();
|
||||
std::string combined_string_upper = combined_string;
|
||||
LLStringUtil::toUpper(combined_string_upper);
|
||||
if (filter_string_length > 0 && (mRoot->getSearchType() & 1) &&
|
||||
if (sBoxImage.notNull() && mStringMatchOffset != std::string::npos)
|
||||
{
|
||||
// don't draw backgrounds for zero-length strings
|
||||
std::string combined_string = mLabel + mLabelSuffix;
|
||||
S32 filter_string_length = getRoot()->getFilterSubString().size();
|
||||
std::string combined_string_upper = combined_string;
|
||||
LLStringUtil::toUpper(combined_string_upper);
|
||||
if (filter_string_length > 0 && (mRoot->getSearchType() & 1) &&
|
||||
combined_string_upper.find(mRoot->getFilterSubString()) == mStringMatchOffset)
|
||||
{
|
||||
S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1;
|
||||
S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
|
||||
S32 bottom = llfloor(getRect().getHeight() - sFont->getLineHeight() - 3);
|
||||
S32 top = getRect().getHeight();
|
||||
{
|
||||
S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1;
|
||||
S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
|
||||
S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
|
||||
S32 top = getRect().getHeight() - TOP_PAD;
|
||||
|
||||
LLRect box_rect(left, top, right, bottom);
|
||||
sBoxImage->draw(box_rect, sFilterBGColor);
|
||||
F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset);
|
||||
F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
|
||||
sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y,
|
||||
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW,
|
||||
filter_string_length, S32_MAX, &right_x, FALSE );
|
||||
}
|
||||
LLUIImage* box_image = sBoxImage;
|
||||
LLRect box_rect(left, top, right, bottom);
|
||||
box_image->draw(box_rect, sFilterBGColor);
|
||||
F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset);
|
||||
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
|
||||
font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy,
|
||||
|
||||
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW,
|
||||
filter_string_length, S32_MAX, &right_x, FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1025,7 +1048,6 @@ LLFolderViewFolder::LLFolderViewFolder( const std::string& name, LLUIImagePtr ic
|
||||
mCompletedFilterGeneration(-1),
|
||||
mMostFilteredDescendantGeneration(-1)
|
||||
{
|
||||
mType = std::string("(folder)");
|
||||
}
|
||||
|
||||
|
||||
@@ -1505,6 +1527,183 @@ BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selec
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
LLFolderViewFolder* LLFolderViewFolder::getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse)
|
||||
{
|
||||
if (!item_a->getParentFolder() || !item_b->getParentFolder()) return NULL;
|
||||
|
||||
std::deque<LLFolderViewFolder*> item_a_ancestors;
|
||||
|
||||
LLFolderViewFolder* parent = item_a->getParentFolder();
|
||||
while(parent)
|
||||
{
|
||||
item_a_ancestors.push_back(parent);
|
||||
parent = parent->getParentFolder();
|
||||
}
|
||||
|
||||
std::deque<LLFolderViewFolder*> item_b_ancestors;
|
||||
|
||||
parent = item_b->getParentFolder();
|
||||
while(parent)
|
||||
{
|
||||
item_b_ancestors.push_back(parent);
|
||||
parent = parent->getParentFolder();
|
||||
}
|
||||
|
||||
LLFolderViewFolder* common_ancestor = item_a->getRoot();
|
||||
|
||||
while(item_a_ancestors.size() > item_b_ancestors.size())
|
||||
{
|
||||
item_a = item_a_ancestors.front();
|
||||
item_a_ancestors.pop_front();
|
||||
}
|
||||
|
||||
while(item_b_ancestors.size() > item_a_ancestors.size())
|
||||
{
|
||||
item_b = item_b_ancestors.front();
|
||||
item_b_ancestors.pop_front();
|
||||
}
|
||||
|
||||
while(item_a_ancestors.size())
|
||||
{
|
||||
common_ancestor = item_a_ancestors.front();
|
||||
|
||||
if (item_a_ancestors.front() == item_b_ancestors.front())
|
||||
{
|
||||
// which came first, sibling a or sibling b?
|
||||
for (folders_t::iterator it = common_ancestor->mFolders.begin(), end_it = common_ancestor->mFolders.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
LLFolderViewItem* item = *it;
|
||||
|
||||
if (item == item_a)
|
||||
{
|
||||
reverse = false;
|
||||
return common_ancestor;
|
||||
}
|
||||
if (item == item_b)
|
||||
{
|
||||
reverse = true;
|
||||
return common_ancestor;
|
||||
}
|
||||
}
|
||||
|
||||
for (items_t::iterator it = common_ancestor->mItems.begin(), end_it = common_ancestor->mItems.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
LLFolderViewItem* item = *it;
|
||||
|
||||
if (item == item_a)
|
||||
{
|
||||
reverse = false;
|
||||
return common_ancestor;
|
||||
}
|
||||
if (item == item_b)
|
||||
{
|
||||
reverse = true;
|
||||
return common_ancestor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
item_a = item_a_ancestors.front();
|
||||
item_a_ancestors.pop_front();
|
||||
item_b = item_b_ancestors.front();
|
||||
item_b_ancestors.pop_front();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items)
|
||||
{
|
||||
bool selecting = start == NULL;
|
||||
if (reverse)
|
||||
{
|
||||
for (items_t::reverse_iterator it = mItems.rbegin(), end_it = mItems.rend();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
if (*it == end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (selecting)
|
||||
{
|
||||
items.push_back(*it);
|
||||
}
|
||||
|
||||
if (*it == start)
|
||||
{
|
||||
selecting = true;
|
||||
}
|
||||
}
|
||||
for (folders_t::reverse_iterator it = mFolders.rbegin(), end_it = mFolders.rend();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
if (*it == end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (selecting)
|
||||
{
|
||||
items.push_back(*it);
|
||||
}
|
||||
|
||||
if (*it == start)
|
||||
{
|
||||
selecting = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (folders_t::iterator it = mFolders.begin(), end_it = mFolders.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
if (*it == end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (selecting)
|
||||
{
|
||||
items.push_back(*it);
|
||||
}
|
||||
|
||||
if (*it == start)
|
||||
{
|
||||
selecting = true;
|
||||
}
|
||||
}
|
||||
for (items_t::iterator it = mItems.begin(), end_it = mItems.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
if (*it == end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (selecting)
|
||||
{
|
||||
items.push_back(*it);
|
||||
}
|
||||
|
||||
if (*it == start)
|
||||
{
|
||||
selecting = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items)
|
||||
{
|
||||
// pass on to child folders first
|
||||
@@ -2050,6 +2249,22 @@ void LLFolderViewFolder::openItem( void )
|
||||
toggleOpen();
|
||||
}
|
||||
|
||||
void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor)
|
||||
{
|
||||
for (folders_t::iterator iter = mFolders.begin();
|
||||
iter != mFolders.end();)
|
||||
{
|
||||
folders_t::iterator fit = iter++;
|
||||
functor.doItem((*fit));
|
||||
}
|
||||
for (items_t::iterator iter = mItems.begin();
|
||||
iter != mItems.end();)
|
||||
{
|
||||
items_t::iterator iit = iter++;
|
||||
functor.doItem((*iit));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
|
||||
{
|
||||
functor.doFolder(this);
|
||||
@@ -2157,12 +2372,6 @@ BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
|
||||
handled = LLFolderViewItem::handleHover(x, y, mask);
|
||||
}
|
||||
|
||||
//if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD && y > getRect().getHeight() - )
|
||||
//{
|
||||
// gViewerWindow->setCursor(UI_CURSOR_ARROW);
|
||||
// mExpanderHighlighted = TRUE;
|
||||
// handled = TRUE;
|
||||
//}
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,13 +107,6 @@ private:
|
||||
protected:
|
||||
static const LLFontGL* sFont;
|
||||
static const LLFontGL* sSmallFont;
|
||||
static LLColor4 sFgColor;
|
||||
static LLColor4 sHighlightBgColor;
|
||||
static LLColor4 sHighlightFgColor;
|
||||
static LLColor4 sFilterBGColor;
|
||||
static LLColor4 sFilterTextColor;
|
||||
static LLColor4 sSuffixColor;
|
||||
static LLColor4 sSearchStatusColor;
|
||||
static LLUIImagePtr sArrowImage;
|
||||
static LLUIImagePtr sBoxImage;
|
||||
|
||||
@@ -122,7 +115,6 @@ protected:
|
||||
std::string mSearchableLabelDesc;
|
||||
std::string mSearchableLabelCreator;
|
||||
std::string mSearchable;
|
||||
std::string mType;
|
||||
S32 mLabelWidth;
|
||||
U32 mCreationDate;
|
||||
LLFolderViewFolder* mParentFolder;
|
||||
@@ -156,6 +148,8 @@ protected:
|
||||
virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
|
||||
|
||||
public:
|
||||
BOOL postBuild();
|
||||
|
||||
// This function clears the currently selected item, and records
|
||||
// the specified selected item appropriately for display and use
|
||||
// in the UI. If open is TRUE, then folders are opened up along
|
||||
@@ -495,6 +489,8 @@ public:
|
||||
void applyFunctorRecursively(LLFolderViewFunctor& functor);
|
||||
virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
|
||||
|
||||
// Just apply this functor to the folder's immediate children.
|
||||
void applyFunctorToChildren(LLFolderViewFunctor& functor);
|
||||
|
||||
virtual void openItem( void );
|
||||
virtual BOOL addItem(LLFolderViewItem* item);
|
||||
@@ -510,6 +506,11 @@ public:
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
virtual void draw();
|
||||
|
||||
time_t getCreationDate() const;
|
||||
@@ -523,6 +524,8 @@ public:
|
||||
items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
|
||||
items_t::const_iterator getItemsEnd() const { return mItems.end(); }
|
||||
items_t::size_type getItemsCount() const { return mItems.size(); }
|
||||
LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
|
||||
void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llgesturemgr.cpp
|
||||
* @brief Manager for playing gestures on the viewer
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* 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
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* 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
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -37,11 +31,12 @@
|
||||
// system
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
// library
|
||||
#include "llaudioengine.h"
|
||||
#include "lldatapacker.h"
|
||||
#include "llinventory.h"
|
||||
#include "llkeyframemotion.h"
|
||||
#include "llmultigesture.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llstl.h"
|
||||
@@ -53,10 +48,11 @@
|
||||
#include "llagent.h"
|
||||
#include "llchatbar.h"
|
||||
#include "lldelayedgestureerror.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llappearancemgr.h"
|
||||
|
||||
#include "chatbar_as_cmdline.h"
|
||||
|
||||
@@ -78,7 +74,9 @@ LLGestureMgr::LLGestureMgr()
|
||||
mPlaying(),
|
||||
mActive(),
|
||||
mLoadingCount(0)
|
||||
{ }
|
||||
{
|
||||
gInventory.addObserver(this);
|
||||
}
|
||||
|
||||
|
||||
// We own the data for gestures, so clean them up.
|
||||
@@ -92,6 +90,7 @@ LLGestureMgr::~LLGestureMgr()
|
||||
delete gesture;
|
||||
gesture = NULL;
|
||||
}
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +99,41 @@ void LLGestureMgr::init()
|
||||
// TODO
|
||||
}
|
||||
|
||||
void LLGestureMgr::changed(U32 mask)
|
||||
{
|
||||
LLInventoryFetchItemsObserver::changed(mask);
|
||||
|
||||
if (mask & LLInventoryObserver::GESTURE)
|
||||
{
|
||||
// If there was a gesture label changed, update all the names in the
|
||||
// active gestures and then notify observers
|
||||
if (mask & LLInventoryObserver::LABEL)
|
||||
{
|
||||
for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it)
|
||||
{
|
||||
if(it->second)
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(it->first);
|
||||
if(item)
|
||||
{
|
||||
it->second->mName = item->getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
notifyObservers();
|
||||
}
|
||||
// If there was a gesture added or removed notify observers
|
||||
// STRUCTURE denotes that the inventory item has been moved
|
||||
// In the case of deleting gesture, it is moved to the trash
|
||||
else if(mask & LLInventoryObserver::ADD ||
|
||||
mask & LLInventoryObserver::REMOVE ||
|
||||
mask & LLInventoryObserver::STRUCTURE)
|
||||
{
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use this version when you have the item_id but not the asset_id,
|
||||
// and you KNOW the inventory is loaded.
|
||||
@@ -307,6 +341,8 @@ void LLGestureMgr::deactivateGesture(const LLUUID& item_id)
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id, false);
|
||||
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
@@ -496,6 +532,66 @@ void LLGestureMgr::playGesture(LLMultiGesture* gesture)
|
||||
gesture->mPlaying = TRUE;
|
||||
mPlaying.push_back(gesture);
|
||||
|
||||
// Load all needed assets to minimize the delays
|
||||
// when gesture is playing.
|
||||
for (std::vector<LLGestureStep*>::iterator steps_it = gesture->mSteps.begin();
|
||||
steps_it != gesture->mSteps.end();
|
||||
++steps_it)
|
||||
{
|
||||
LLGestureStep* step = *steps_it;
|
||||
switch(step->getType())
|
||||
{
|
||||
case STEP_ANIMATION:
|
||||
{
|
||||
LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
|
||||
const LLUUID& anim_id = anim_step->mAnimAssetID;
|
||||
|
||||
// Don't request the animation if this step stops it or if it is already in Static VFS
|
||||
if (!(anim_id.isNull()
|
||||
|| anim_step->mFlags & ANIM_FLAG_STOP
|
||||
|| gAssetStorage->hasLocalAsset(anim_id, LLAssetType::AT_ANIMATION)))
|
||||
{
|
||||
mLoadingAssets.insert(anim_id);
|
||||
|
||||
LLUUID* id = new LLUUID(gAgentID);
|
||||
gAssetStorage->getAssetData(anim_id,
|
||||
LLAssetType::AT_ANIMATION,
|
||||
onAssetLoadComplete,
|
||||
(void *)id,
|
||||
TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STEP_SOUND:
|
||||
{
|
||||
LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
|
||||
const LLUUID& sound_id = sound_step->mSoundAssetID;
|
||||
if (!(sound_id.isNull()
|
||||
|| gAssetStorage->hasLocalAsset(sound_id, LLAssetType::AT_SOUND)))
|
||||
{
|
||||
mLoadingAssets.insert(sound_id);
|
||||
|
||||
gAssetStorage->getAssetData(sound_id,
|
||||
LLAssetType::AT_SOUND,
|
||||
onAssetLoadComplete,
|
||||
NULL,
|
||||
TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STEP_CHAT:
|
||||
case STEP_WAIT:
|
||||
case STEP_EOF:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
llwarns << "Unknown gesture step type: " << step->getType() << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// And get it going
|
||||
stepGesture(gesture);
|
||||
|
||||
@@ -711,8 +807,7 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
if (!avatar) return;
|
||||
if (!isAgentAvatarValid() || hasLoadingAssets(gesture)) return;
|
||||
|
||||
// Of the ones that started playing, have any stopped?
|
||||
|
||||
@@ -723,8 +818,8 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
|
||||
{
|
||||
// look in signaled animations (simulator's view of what is
|
||||
// currently playing.
|
||||
LLVOAvatar::AnimIterator play_it = avatar->mSignaledAnimations.find(*gest_it);
|
||||
if (play_it != avatar->mSignaledAnimations.end())
|
||||
LLVOAvatar::AnimIterator play_it = gAgentAvatarp->mSignaledAnimations.find(*gest_it);
|
||||
if (play_it != gAgentAvatarp->mSignaledAnimations.end())
|
||||
{
|
||||
++gest_it;
|
||||
}
|
||||
@@ -742,8 +837,8 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
|
||||
gest_it != gesture->mRequestedAnimIDs.end();
|
||||
)
|
||||
{
|
||||
LLVOAvatar::AnimIterator play_it = avatar->mSignaledAnimations.find(*gest_it);
|
||||
if (play_it != avatar->mSignaledAnimations.end())
|
||||
LLVOAvatar::AnimIterator play_it = gAgentAvatarp->mSignaledAnimations.find(*gest_it);
|
||||
if (play_it != gAgentAvatarp->mSignaledAnimations.end())
|
||||
{
|
||||
// Hooray, this animation has started playing!
|
||||
// Copy into playing.
|
||||
@@ -998,10 +1093,22 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs,
|
||||
}
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* item = gInventory.getItem(item_id);
|
||||
if(item)
|
||||
{
|
||||
gesture->mName = item->getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Watch this item and set gesture name when item exists in inventory
|
||||
self.setFetchID(item_id);
|
||||
self.startFetch();
|
||||
}
|
||||
self.mActive[item_id] = gesture;
|
||||
|
||||
// Everything has been successful. Add to the active list.
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
|
||||
|
||||
if (inform_server)
|
||||
{
|
||||
// Inform the database of this change
|
||||
@@ -1019,6 +1126,13 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs,
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
callback_map_t::iterator i_cb = self.mCallbackMap.find(item_id);
|
||||
|
||||
if(i_cb != self.mCallbackMap.end())
|
||||
{
|
||||
i_cb->second(gesture);
|
||||
self.mCallbackMap.erase(i_cb);
|
||||
}
|
||||
|
||||
self.notifyObservers();
|
||||
}
|
||||
@@ -1055,7 +1169,98 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs,
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLGestureMgr::onAssetLoadComplete(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLGestureMgr& self = LLGestureMgr::instance();
|
||||
|
||||
// Complete the asset loading process depending on the type and
|
||||
// remove the asset id from pending downloads list.
|
||||
switch(type)
|
||||
{
|
||||
case LLAssetType::AT_ANIMATION:
|
||||
{
|
||||
LLKeyframeMotion::onLoadComplete(vfs, asset_uuid, type, user_data, status, ext_status);
|
||||
|
||||
self.mLoadingAssets.erase(asset_uuid);
|
||||
|
||||
break;
|
||||
}
|
||||
case LLAssetType::AT_SOUND:
|
||||
{
|
||||
LLAudioEngine::assetCallback(vfs, asset_uuid, type, user_data, status, ext_status);
|
||||
|
||||
self.mLoadingAssets.erase(asset_uuid);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
llwarns << "Unexpected asset type: " << type << llendl;
|
||||
|
||||
// We don't want to return from this callback without
|
||||
// an animation or sound callback being fired
|
||||
// and *user_data handled to avoid memory leaks.
|
||||
llassert(type == LLAssetType::AT_ANIMATION || type == LLAssetType::AT_SOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLGestureMgr::hasLoadingAssets(LLMultiGesture* gesture)
|
||||
{
|
||||
LLGestureMgr& self = LLGestureMgr::instance();
|
||||
|
||||
for (std::vector<LLGestureStep*>::iterator steps_it = gesture->mSteps.begin();
|
||||
steps_it != gesture->mSteps.end();
|
||||
++steps_it)
|
||||
{
|
||||
LLGestureStep* step = *steps_it;
|
||||
switch(step->getType())
|
||||
{
|
||||
case STEP_ANIMATION:
|
||||
{
|
||||
LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
|
||||
const LLUUID& anim_id = anim_step->mAnimAssetID;
|
||||
|
||||
if (!(anim_id.isNull()
|
||||
|| anim_step->mFlags & ANIM_FLAG_STOP
|
||||
|| self.mLoadingAssets.find(anim_id) == self.mLoadingAssets.end()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STEP_SOUND:
|
||||
{
|
||||
LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
|
||||
const LLUUID& sound_id = sound_step->mSoundAssetID;
|
||||
|
||||
if (!(sound_id.isNull()
|
||||
|| self.mLoadingAssets.find(sound_id) == self.mLoadingAssets.end()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STEP_CHAT:
|
||||
case STEP_WAIT:
|
||||
case STEP_EOF:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
llwarns << "Unknown gesture step type: " << step->getType() << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLGestureMgr::stopGesture(LLMultiGesture* gesture)
|
||||
{
|
||||
@@ -1181,6 +1386,27 @@ void LLGestureMgr::getItemIDs(uuid_vec_t* ids)
|
||||
}
|
||||
}
|
||||
|
||||
void LLGestureMgr::done()
|
||||
{
|
||||
bool notify = false;
|
||||
for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it)
|
||||
{
|
||||
if(it->second && it->second->mName.empty())
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(it->first);
|
||||
if(item)
|
||||
{
|
||||
it->second->mName = item->getName();
|
||||
notify = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(notify)
|
||||
{
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
const LLUUID& get_linked_uuid(const LLUUID &item_id)
|
||||
{
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llgesturemgr.h
|
||||
* @brief Manager for playing gestures on the viewer
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* 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
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* 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
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -38,6 +32,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "llassetstorage.h" // LLAssetType
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llsingleton.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
class LLMultiGesture;
|
||||
@@ -52,11 +48,14 @@ public:
|
||||
virtual void changed() = 0;
|
||||
};
|
||||
|
||||
class LLGestureMgr : public LLSingleton<LLGestureMgr>
|
||||
class LLGestureMgr : public LLSingleton<LLGestureMgr>, public LLInventoryFetchItemsObserver
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::function<void (LLMultiGesture* loaded_gesture)> gesture_loaded_callback_t;
|
||||
// Maps inventory item_id to gesture
|
||||
typedef std::map<LLUUID, LLMultiGesture*> item_map_t;
|
||||
typedef std::map<LLUUID, gesture_loaded_callback_t> callback_map_t;
|
||||
|
||||
LLGestureMgr();
|
||||
~LLGestureMgr();
|
||||
@@ -110,7 +109,15 @@ public:
|
||||
// Also remove from playing list
|
||||
void stopGesture(LLMultiGesture* gesture);
|
||||
void stopGesture(const LLUUID& item_id);
|
||||
|
||||
/**
|
||||
* Add cb into callbackMap.
|
||||
* Note:
|
||||
* Manager will call cb after gesture will be loaded and will remove cb automatically.
|
||||
*/
|
||||
void setGestureLoadedCallback(LLUUID inv_item_id, gesture_loaded_callback_t cb)
|
||||
{
|
||||
mCallbackMap[inv_item_id] = cb;
|
||||
}
|
||||
// Trigger the first gesture that matches this key.
|
||||
// Returns TRUE if it finds a gesture bound to that key.
|
||||
BOOL triggerGesture(KEY key, MASK mask);
|
||||
@@ -127,6 +134,9 @@ public:
|
||||
void removeObserver(LLGestureManagerObserver* observer);
|
||||
void notifyObservers();
|
||||
|
||||
// Overriding so we can update active gesture names and notify observers
|
||||
void changed(U32 mask);
|
||||
|
||||
BOOL matchPrefix(const std::string& in_str, std::string* out_str);
|
||||
|
||||
// Copy item ids into the vector
|
||||
@@ -139,14 +149,25 @@ protected:
|
||||
// Do a single step in a gesture
|
||||
void runStep(LLMultiGesture* gesture, LLGestureStep* step);
|
||||
|
||||
// LLInventoryCompletionObserver trigger
|
||||
void done();
|
||||
|
||||
// Used by loadGesture
|
||||
static void onLoadComplete(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
// Used by playGesture to load an asset file
|
||||
// required to play a gesture step
|
||||
static void onAssetLoadComplete(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
|
||||
// Checks whether all animation and sound assets
|
||||
// needed to play a gesture are loaded.
|
||||
static bool hasLoadingAssets(LLMultiGesture* gesture);
|
||||
|
||||
private:
|
||||
// Active gestures.
|
||||
@@ -157,9 +178,13 @@ private:
|
||||
|
||||
S32 mLoadingCount;
|
||||
std::string mDeactivateSimilarNames;
|
||||
|
||||
|
||||
std::vector<LLGestureManagerObserver*> mObservers;
|
||||
callback_map_t mCallbackMap;
|
||||
std::vector<LLMultiGesture*> mPlaying;
|
||||
BOOL mValid;
|
||||
|
||||
std::set<LLUUID> mLoadingAssets;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "message.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llcheckboxctrl.h" // for radio buttons
|
||||
#include "llfoldervieweventlistener.h"
|
||||
@@ -163,15 +164,9 @@ bool doToSelected(LLFolderView* folder, std::string action)
|
||||
LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
|
||||
if(!bridge) continue;
|
||||
|
||||
bridge->performAction(folder, model, action);
|
||||
bridge->performAction(model, action);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LLFloater::setFloaterHost(NULL);
|
||||
if (multi_previewp)
|
||||
{
|
||||
@@ -389,12 +384,7 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type,
|
||||
else
|
||||
{
|
||||
LLWearableType::EType wear_type = LLWearableType::typeNameToType(type);
|
||||
if(wear_type != LLWearableType::WT_NONE)
|
||||
{
|
||||
LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(LLWearableType::getAssetType(wear_type));
|
||||
LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(folder_type);
|
||||
LLFolderBridge::createWearable(parent_id, wear_type);
|
||||
}
|
||||
LLAgentWearables::createWearable(wear_type, false, self ? self->getUUID() : LLUUID::null);
|
||||
}
|
||||
ptr->getRootFolder()->setNeedsAutoRename(TRUE);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -48,75 +48,9 @@ class LLMenuGL;
|
||||
class LLCallingCardObserver;
|
||||
class LLViewerJointAttachment;
|
||||
|
||||
|
||||
typedef std::vector<std::string> menuentry_vec_t;
|
||||
|
||||
struct LLAttachmentRezAction
|
||||
{
|
||||
LLUUID mItemID;
|
||||
S32 mAttachPt;
|
||||
};
|
||||
|
||||
// [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i
|
||||
// Moved from llinventorybridge.cpp because we need it in RlvForceWearLegacy
|
||||
struct LLFoundData
|
||||
{
|
||||
LLFoundData(const LLUUID& item_id,
|
||||
const LLUUID& asset_id,
|
||||
const std::string& name,
|
||||
LLAssetType::EType asset_type) :
|
||||
mItemID(item_id),
|
||||
mAssetID(asset_id),
|
||||
mName(name),
|
||||
mAssetType(asset_type),
|
||||
mWearable( NULL ) {}
|
||||
|
||||
LLUUID mItemID;
|
||||
LLUUID mAssetID;
|
||||
std::string mName;
|
||||
LLAssetType::EType mAssetType;
|
||||
LLWearable* mWearable;
|
||||
};
|
||||
|
||||
struct LLWearableHoldingPattern
|
||||
{
|
||||
LLWearableHoldingPattern(BOOL fAddToOutfit) : mResolved(0), mAddToOutfit(fAddToOutfit) {}
|
||||
~LLWearableHoldingPattern()
|
||||
{
|
||||
for_each(mFoundList.begin(), mFoundList.end(), DeletePointer());
|
||||
mFoundList.clear();
|
||||
}
|
||||
typedef std::list<LLFoundData*> found_list_t;
|
||||
found_list_t mFoundList;
|
||||
S32 mResolved;
|
||||
BOOL mAddToOutfit;
|
||||
};
|
||||
// [/RLVa:KB]
|
||||
|
||||
//helper functions
|
||||
class LLShowProps
|
||||
{
|
||||
public:
|
||||
|
||||
static void showProperties(const LLUUID& uuid)
|
||||
{
|
||||
if(!LLFloaterProperties::show(uuid, LLUUID::null))
|
||||
{
|
||||
S32 left, top;
|
||||
gFloaterView->getNewFloaterPosition(&left, &top);
|
||||
LLRect rect = gSavedSettings.getRect("PropertiesRect");
|
||||
rect.translate( left - rect.mLeft, top - rect.mTop );
|
||||
LLFloaterProperties* floater;
|
||||
floater = new LLFloaterProperties("item properties",
|
||||
rect,
|
||||
"Inventory Item Properties",
|
||||
uuid,
|
||||
LLUUID::null);
|
||||
// keep onscreen
|
||||
gFloaterView->adjustToFitScreen(floater, FALSE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLInvFVBridge (& it's derived classes)
|
||||
//
|
||||
@@ -137,6 +71,7 @@ public:
|
||||
LLAssetType::EType actual_asset_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
LLInventoryPanel* inventory,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
U32 flags = 0x00);
|
||||
virtual ~LLInvFVBridge() {}
|
||||
@@ -162,12 +97,13 @@ public:
|
||||
virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
|
||||
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
|
||||
virtual void openItem() {}
|
||||
virtual void closeItem() {}
|
||||
virtual void previewItem() {openItem();}
|
||||
virtual void showProperties();
|
||||
virtual BOOL isItemRenameable() const { return TRUE; }
|
||||
//virtual BOOL renameItem(const std::string& new_name) {}
|
||||
virtual BOOL isItemRemovable();
|
||||
virtual BOOL isItemMovable();
|
||||
virtual BOOL isItemRemovable() const;
|
||||
virtual BOOL isItemMovable() const;
|
||||
virtual BOOL isItemInTrash() const;
|
||||
virtual BOOL isLink() const;
|
||||
//virtual BOOL removeItem() = 0;
|
||||
@@ -175,7 +111,7 @@ public:
|
||||
virtual void move(LLFolderViewEventListener* new_parent_bridge) {}
|
||||
virtual BOOL isItemCopyable() const { return FALSE; }
|
||||
virtual BOOL copyToClipboard() const { return FALSE; }
|
||||
virtual BOOL cutToClipboard() const { return FALSE; }
|
||||
virtual void cutToClipboard();
|
||||
virtual BOOL isClipboardPasteable() const;
|
||||
virtual BOOL isClipboardPasteableAsLink() const;
|
||||
virtual void pasteFromClipboard() {}
|
||||
@@ -197,7 +133,7 @@ protected:
|
||||
menuentry_vec_t &disabled_items);
|
||||
virtual void addOpenRightClickMenuOption(menuentry_vec_t &items);
|
||||
protected:
|
||||
LLInvFVBridge(LLInventoryPanel* inventory, /*LLFolderView* root,*/ const LLUUID& uuid);
|
||||
LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
|
||||
|
||||
LLInventoryObject* getInventoryObject() const;
|
||||
LLInventoryModel* getInventoryModel() const;
|
||||
@@ -221,9 +157,11 @@ protected:
|
||||
|
||||
protected:
|
||||
LLInventoryPanel* mInventoryPanel;
|
||||
LLFolderView* mRoot;
|
||||
LLUUID mUUID; // item id
|
||||
LLInventoryType::EType mInvType;
|
||||
BOOL mIsLink;
|
||||
void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
|
||||
};
|
||||
|
||||
class AIFilePicker;
|
||||
@@ -231,15 +169,16 @@ class AIFilePicker;
|
||||
class LLItemBridge : public LLInvFVBridge
|
||||
{
|
||||
public:
|
||||
LLItemBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
|
||||
LLInvFVBridge(inventory, uuid) {}
|
||||
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
LLItemBridge(LLInventoryPanel* inventory,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLInvFVBridge(inventory, root, uuid) {}
|
||||
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void selectItem();
|
||||
virtual void restoreItem();
|
||||
virtual void restoreToWorld();
|
||||
virtual void gotoItem(LLFolderView *folder);
|
||||
virtual void gotoItem();
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual const std::string& getDisplayName() const;
|
||||
virtual std::string getLabelSuffix() const;
|
||||
@@ -261,26 +200,28 @@ public:
|
||||
LLViewerInventoryItem* getItem() const;
|
||||
|
||||
protected:
|
||||
BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response);
|
||||
virtual BOOL isItemPermissive() const;
|
||||
static void buildDisplayName(LLInventoryItem* item, std::string& name);
|
||||
|
||||
mutable std::string mDisplayName;
|
||||
};
|
||||
|
||||
|
||||
class LLFolderBridge : public LLInvFVBridge
|
||||
{
|
||||
public:
|
||||
LLFolderBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLInvFVBridge(inventory, /*root,*/ uuid),
|
||||
LLInvFVBridge(inventory, root, uuid),
|
||||
mCallingCards(FALSE),
|
||||
mWearables(FALSE)
|
||||
{}
|
||||
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop);
|
||||
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop);
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual void closeItem();
|
||||
virtual BOOL isItemRenameable() const;
|
||||
virtual void selectItem();
|
||||
virtual void restoreItem();
|
||||
@@ -293,6 +234,9 @@ public:
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
|
||||
virtual BOOL removeItem();
|
||||
BOOL removeSystemFolder();
|
||||
bool removeItemResponse(const LLSD& notification, const LLSD& response);
|
||||
|
||||
virtual void pasteFromClipboard();
|
||||
virtual void pasteLinkFromClipboard();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
@@ -301,19 +245,22 @@ public:
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data);
|
||||
|
||||
virtual BOOL isItemRemovable();
|
||||
virtual BOOL isItemMovable();
|
||||
virtual BOOL isItemRemovable() const;
|
||||
virtual BOOL isItemMovable() const ;
|
||||
virtual BOOL isUpToDate() const;
|
||||
virtual BOOL isItemCopyable() const;
|
||||
virtual BOOL isClipboardPasteable() const;
|
||||
virtual BOOL isClipboardPasteableAsLink() const;
|
||||
|
||||
static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);
|
||||
static void createWearable(LLUUID parent_folder_id, LLWearableType::EType type);
|
||||
//static void createWearable(LLUUID parent_folder_id, LLWearableType::EType type);
|
||||
|
||||
LLViewerInventoryCategory* getCategory() const;
|
||||
LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
|
||||
|
||||
protected:
|
||||
void buildContextMenuBaseOptions(U32 flags);
|
||||
void buildContextMenuFolderOptions(U32 flags);
|
||||
// menu callbacks
|
||||
static void pasteClipboard(void* user_data);
|
||||
static void createNewCategory(void* user_data);
|
||||
@@ -337,16 +284,24 @@ protected:
|
||||
|
||||
BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck);
|
||||
|
||||
void modifyOutfit(BOOL append, BOOL replace = FALSE);
|
||||
void modifyOutfit(BOOL append);
|
||||
void determineFolderType();
|
||||
|
||||
menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items
|
||||
|
||||
void dropToFavorites(LLInventoryItem* inv_item);
|
||||
void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Messy hacks for handling folder options
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
static LLHandle<LLFolderBridge> sSelf;
|
||||
static void staticFolderOptionsMenu();
|
||||
void folderOptionsMenu();
|
||||
|
||||
private:
|
||||
BOOL mCallingCards;
|
||||
BOOL mWearables;
|
||||
BOOL mCallingCards;
|
||||
BOOL mWearables;
|
||||
LLHandle<LLView> mMenu;
|
||||
menuentry_vec_t mItems;
|
||||
menuentry_vec_t mDisabledItems;
|
||||
@@ -359,24 +314,27 @@ class LLTextureBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Texture: ");return ret; }
|
||||
LLTextureBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
LLInventoryType::EType type) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid)
|
||||
LLItemBridge(inventory, root, uuid)
|
||||
{
|
||||
mInvType = type;
|
||||
}
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void openItem();
|
||||
//virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
//virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
bool canSaveTexture(void);
|
||||
};
|
||||
|
||||
class LLSoundBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
LLSoundBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual void openItem();
|
||||
virtual void previewItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
@@ -390,10 +348,10 @@ public:
|
||||
static const std::string& prefix() { static std::string ret("Landmark: ");return ret; }
|
||||
virtual const std::string& getPrefix() { return prefix(); }
|
||||
LLLandmarkBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
U32 flags = 0x00);
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void openItem();
|
||||
@@ -406,17 +364,15 @@ class LLCallingCardBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Calling Card: ");return ret; }
|
||||
LLCallingCardBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* folder,
|
||||
const LLUUID& uuid );
|
||||
~LLCallingCardBridge();
|
||||
virtual std::string getLabelSuffix() const;
|
||||
//virtual const std::string& getDisplayName() const;
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
//virtual void renameItem(const std::string& new_name);
|
||||
//virtual BOOL removeItem();
|
||||
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data);
|
||||
@@ -431,9 +387,9 @@ class LLNotecardBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Notecard: ");return ret; }
|
||||
LLNotecardBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual void openItem();
|
||||
};
|
||||
|
||||
@@ -442,17 +398,18 @@ class LLGestureBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Gesture: ");return ret; }
|
||||
LLGestureBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
// Only suffix for gesture items, not task items, because only
|
||||
// gestures in your inventory can be active.
|
||||
virtual LLFontGL::StyleFlags getLabelStyle() const;
|
||||
virtual std::string getLabelSuffix() const;
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual BOOL removeItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
static void playGesture(const LLUUID& item_id);
|
||||
};
|
||||
|
||||
|
||||
@@ -461,10 +418,10 @@ class LLAnimationBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Animation: ");return ret; }
|
||||
LLAnimationBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual void openItem();
|
||||
};
|
||||
@@ -475,16 +432,15 @@ class LLObjectBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Object: ");return ret; }
|
||||
LLObjectBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
LLInventoryType::EType type,
|
||||
U32 flags);
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual std::string getLabelSuffix() const;
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual BOOL isItemRemovable();
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
LLInventoryObject* getObject() const;
|
||||
protected:
|
||||
@@ -498,9 +454,9 @@ class LLLSLTextBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Script: ");return ret; }
|
||||
LLLSLTextBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid ) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual void openItem();
|
||||
};
|
||||
|
||||
@@ -509,17 +465,16 @@ class LLWearableBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
LLWearableBridge(LLInventoryPanel* inventory,
|
||||
/*LLFolderView* root,*/
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
LLAssetType::EType asset_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
LLWearableType::EType wearable_type);
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual std::string getLabelSuffix() const;
|
||||
virtual BOOL isItemRemovable();
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
virtual LLWearableType::EType getWearableType() const { return mWearableType; }
|
||||
|
||||
@@ -528,13 +483,19 @@ public:
|
||||
static void onWearOnAvatarArrived( LLWearable* wearable, void* userdata );
|
||||
void wearOnAvatar();
|
||||
|
||||
static void onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata );
|
||||
void wearAddOnAvatar();
|
||||
|
||||
static BOOL canEditOnAvatar( void* userdata ); // Access to editOnAvatar() from menu
|
||||
static void onEditOnAvatar( void* userdata );
|
||||
void editOnAvatar();
|
||||
|
||||
static BOOL canRemoveFromAvatar( void* userdata );
|
||||
static void onRemoveFromAvatar( void* userdata );
|
||||
static void onRemoveFromAvatarArrived( LLWearable* wearable, void* userdata );
|
||||
static void onRemoveFromAvatarArrived( LLWearable* wearable, void* userdata );
|
||||
static void removeItemFromAvatar(LLViewerInventoryItem *item);
|
||||
static void removeAllClothesFromAvatar();
|
||||
void removeFromAvatar();
|
||||
protected:
|
||||
LLAssetType::EType mAssetType;
|
||||
LLWearableType::EType mWearableType;
|
||||
@@ -544,9 +505,9 @@ class LLLinkItemBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
LLLinkItemBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual const std::string& getPrefix() { return sPrefix; }
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
@@ -558,32 +519,34 @@ class LLLinkFolderBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
LLLinkFolderBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual const std::string& getPrefix() { return sPrefix; }
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void gotoItem(LLFolderView *folder);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void gotoItem();
|
||||
protected:
|
||||
const LLUUID &getFolderID() const;
|
||||
static std::string sPrefix;
|
||||
};
|
||||
|
||||
|
||||
class LLMeshBridge : public LLItemBridge
|
||||
{
|
||||
friend class LLInvFVBridge;
|
||||
friend class LLInvFVBridge;
|
||||
public:
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void openItem();
|
||||
virtual void previewItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void openItem();
|
||||
virtual void previewItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
|
||||
protected:
|
||||
LLMeshBridge(LLInventoryPanel* inventory,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, uuid) {}
|
||||
LLMeshBridge(LLInventoryPanel* inventory,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
};
|
||||
|
||||
void rez_attachment(LLViewerInventoryItem* item,
|
||||
@@ -597,4 +560,13 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
|
||||
BOOL drop,
|
||||
void (*callback)(S32, void*) = NULL,
|
||||
void* user_data = NULL);
|
||||
|
||||
// Utility function to hide all entries except those in the list
|
||||
// Can be called multiple times on the same menu (e.g. if multiple items
|
||||
// are selected). If "append" is false, then only common enabled items
|
||||
// are set as enabled.
|
||||
void hide_context_entries(LLMenuGL& menu,
|
||||
const menuentry_vec_t &entries_to_show,
|
||||
const menuentry_vec_t &disabled_entries);
|
||||
|
||||
#endif // LL_LLINVENTORYBRIDGE_H
|
||||
|
||||
@@ -41,6 +41,7 @@ LLInventoryClipboard LLInventoryClipboard::sInstance;
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLInventoryClipboard::LLInventoryClipboard()
|
||||
: mCutMode(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -71,6 +72,16 @@ void LLInventoryClipboard::store(const LLDynamicArray<LLUUID>& inv_objects)
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryClipboard::cut(const LLUUID& object)
|
||||
{
|
||||
if(!mCutMode && !mObjects.empty())
|
||||
{
|
||||
//looks like there are some stored items, reset clipboard state
|
||||
reset();
|
||||
}
|
||||
mCutMode = true;
|
||||
add(object);
|
||||
}
|
||||
void LLInventoryClipboard::retrieve(LLDynamicArray<LLUUID>& inv_objects) const
|
||||
{
|
||||
inv_objects.reset();
|
||||
@@ -84,6 +95,7 @@ void LLInventoryClipboard::retrieve(LLDynamicArray<LLUUID>& inv_objects) const
|
||||
void LLInventoryClipboard::reset()
|
||||
{
|
||||
mObjects.reset();
|
||||
mCutMode = false;
|
||||
}
|
||||
|
||||
// returns true if the clipboard has something pasteable in it.
|
||||
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
// this method stores an array of objects
|
||||
void store(const LLDynamicArray<LLUUID>& inventory_objects);
|
||||
|
||||
void cut(const LLUUID& object);
|
||||
// this method gets the objects in the clipboard by copying them
|
||||
// into the array provided.
|
||||
void retrieve(LLDynamicArray<LLUUID>& inventory_objects) const;
|
||||
@@ -63,11 +64,13 @@ public:
|
||||
|
||||
// returns true if the clipboard has something pasteable in it.
|
||||
BOOL hasContents() const;
|
||||
bool isCutMode() const { return mCutMode; }
|
||||
|
||||
protected:
|
||||
static LLInventoryClipboard sInstance;
|
||||
|
||||
LLDynamicArray<LLUUID> mObjects;
|
||||
bool mCutMode;
|
||||
|
||||
public:
|
||||
// please don't actually call these
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "message.h"
|
||||
|
||||
// newview includes
|
||||
#include "llappearancemgr.h"
|
||||
#include "llappviewer.h"
|
||||
//#include "llfirstuse.h"
|
||||
#include "llfloaterinventory.h"
|
||||
@@ -52,9 +53,11 @@
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventoryclipboard.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llmenugl.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpanelmaininventory.h"
|
||||
#include "llpreviewanim.h"
|
||||
#include "llpreviewgesture.h"
|
||||
#include "llpreviewnotecard.h"
|
||||
@@ -75,13 +78,13 @@
|
||||
#include "llvoavatarself.h"
|
||||
#include "llwearablelist.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
|
||||
#include "rlvhandler.h"
|
||||
#include "rlvlocks.h"
|
||||
// [/RLVa:KB]
|
||||
|
||||
#include "cofmgr.h"
|
||||
|
||||
BOOL LLInventoryState::sWearNewClothing = FALSE;
|
||||
LLUUID LLInventoryState::sWearNewClothingTransactionID;
|
||||
|
||||
@@ -164,7 +167,7 @@ void change_category_parent(LLInventoryModel* model,
|
||||
model->notifyObservers();
|
||||
}
|
||||
|
||||
/*void remove_category(LLInventoryModel* model, const LLUUID& cat_id)
|
||||
void remove_category(LLInventoryModel* model, const LLUUID& cat_id)
|
||||
{
|
||||
if (!model || !get_is_category_removable(model, cat_id))
|
||||
{
|
||||
@@ -195,7 +198,7 @@ void change_category_parent(LLInventoryModel* model,
|
||||
const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
|
||||
change_category_parent(model, cat, trash_id, TRUE);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name)
|
||||
{
|
||||
@@ -237,7 +240,7 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id)
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
LLInventoryCollectAllItems collect_all;
|
||||
gInventory.collectDescendentsIf(LLCOFMgr::instance().getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH, collect_all);
|
||||
gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH, collect_all);
|
||||
|
||||
for (LLInventoryModel::item_array_t::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
@@ -313,13 +316,13 @@ BOOL get_can_item_be_worn(const LLUUID& id)
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
if (LLCOFMgr::instance().isLinkInCOF(item->getLinkedUUID()))
|
||||
if (LLAppearanceMgr::isLinkInCOF(item->getLinkedUUID()))
|
||||
{
|
||||
// an item having links in COF (i.e. a worn item)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gInventory.isObjectDescendentOf(id, LLCOFMgr::instance().getCOF()))
|
||||
if (gInventory.isObjectDescendentOf(id, LLAppearanceMgr::instance().getCOF()))
|
||||
{
|
||||
// a non-link object in COF (should not normally happen)
|
||||
return FALSE;
|
||||
@@ -363,12 +366,10 @@ BOOL get_can_item_be_worn(const LLUUID& id)
|
||||
// Not being worn yet.
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -379,6 +380,11 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(id == gInventory.getRootFolderID())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Can't delete an item that's in the library.
|
||||
if(!model->isObjectDescendentOf(id, gInventory.getRootFolderID()))
|
||||
{
|
||||
@@ -387,7 +393,7 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
|
||||
// Disable delete from COF folder; have users explicitly choose "detach/take off",
|
||||
// unless the item is not worn but in the COF (i.e. is bugged).
|
||||
if (LLCOFMgr::instance().getIsProtectedCOFItem(id))
|
||||
if (LLAppearanceMgr::instance().getIsProtectedCOFItem(id))
|
||||
{
|
||||
if (get_is_item_worn(id))
|
||||
{
|
||||
@@ -415,7 +421,7 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
{
|
||||
// NOTE: This function doesn't check the folder's children.
|
||||
// See LLFolderBridge::isItemRemovable for a function that does
|
||||
@@ -465,7 +471,7 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}*/
|
||||
}
|
||||
|
||||
BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)
|
||||
{
|
||||
@@ -492,6 +498,26 @@ BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)
|
||||
}
|
||||
|
||||
|
||||
void show_item_profile(const LLUUID& item_uuid)
|
||||
{
|
||||
LLUUID linked_uuid = gInventory.getLinkedItemID(item_uuid);
|
||||
if(!LLFloaterProperties::show(linked_uuid, LLUUID::null))
|
||||
{
|
||||
S32 left, top;
|
||||
gFloaterView->getNewFloaterPosition(&left, &top);
|
||||
LLRect rect = gSavedSettings.getRect("PropertiesRect");
|
||||
rect.translate( left - rect.mLeft, top - rect.mTop );
|
||||
LLFloaterProperties* floater;
|
||||
floater = new LLFloaterProperties("item properties",
|
||||
rect,
|
||||
"Inventory Item Properties",
|
||||
linked_uuid,
|
||||
LLUUID::null);
|
||||
// keep onscreen
|
||||
gFloaterView->adjustToFitScreen(floater, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// LLInventoryCollectFunctor implementations
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -641,6 +667,33 @@ bool LLNameCategoryCollector::operator()(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item)
|
||||
{
|
||||
// Valid COF items are:
|
||||
// - links to wearables (body parts or clothing)
|
||||
// - links to attachments
|
||||
// - links to gestures
|
||||
// - links to ensemble folders
|
||||
LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem();
|
||||
if (linked_item)
|
||||
{
|
||||
LLAssetType::EType type = linked_item->getType();
|
||||
return (type == LLAssetType::AT_CLOTHING ||
|
||||
type == LLAssetType::AT_BODYPART ||
|
||||
type == LLAssetType::AT_GESTURE ||
|
||||
type == LLAssetType::AT_OBJECT);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory();
|
||||
// BAP remove AT_NONE support after ensembles are fully working?
|
||||
return (linked_category &&
|
||||
((linked_category->getPreferredType() == LLFolderType::FT_NONE) ||
|
||||
(LLFolderType::lookupIsEnsembleType(linked_category->getPreferredType()))));
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFindWearables::operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item)
|
||||
{
|
||||
@@ -686,6 +739,40 @@ bool LLFindWearablesEx::operator()(LLInventoryCategory* cat, LLInventoryItem* it
|
||||
return (bool) get_is_item_worn(item->getUUID()) == mIsWorn;
|
||||
}
|
||||
|
||||
bool LLFindWearablesOfType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if (!item) return false;
|
||||
if (item->getType() != LLAssetType::AT_CLOTHING &&
|
||||
item->getType() != LLAssetType::AT_BODYPART)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item);
|
||||
if (!vitem || vitem->getWearableType() != mWearableType) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLFindWearablesOfType::setType(LLWearableType::EType type)
|
||||
{
|
||||
mWearableType = type;
|
||||
}
|
||||
|
||||
bool LLFindNonRemovableObjects::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if (item)
|
||||
{
|
||||
return !get_is_item_removable(&gInventory, item->getUUID());
|
||||
}
|
||||
if (cat)
|
||||
{
|
||||
return !get_is_category_removable(&gInventory, cat->getUUID());
|
||||
}
|
||||
|
||||
llwarns << "Not a category and not an item?" << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// LLAssetIDMatches
|
||||
|
||||
@@ -53,6 +53,8 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id);
|
||||
|
||||
BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id);
|
||||
|
||||
void show_item_profile(const LLUUID& item_uuid);
|
||||
|
||||
void change_item_parent(LLInventoryModel* model,
|
||||
LLViewerInventoryItem* item,
|
||||
const LLUUID& new_parent_id,
|
||||
@@ -262,6 +264,77 @@ protected:
|
||||
std::string mName;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFindCOFValidItems
|
||||
//
|
||||
// Collects items that can be legitimately linked to in the COF.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLFindCOFValidItems : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLFindCOFValidItems() {}
|
||||
virtual ~LLFindCOFValidItems() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item);
|
||||
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFindByMask
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLFindByMask : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLFindByMask(U64 mask)
|
||||
: mFilterMask(mask)
|
||||
{}
|
||||
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
//converting an inventory type to a bitmap filter mask
|
||||
if(item && (mFilterMask & (1LL << item->getInventoryType())) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
U64 mFilterMask;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFindNonLinksByMask
|
||||
//
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLFindNonLinksByMask : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLFindNonLinksByMask(U64 mask)
|
||||
: mFilterMask(mask)
|
||||
{}
|
||||
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if(item && !item->getIsLinkType() && (mFilterMask & (1LL << item->getInventoryType())) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void setFilterMask(U64 mask)
|
||||
{
|
||||
mFilterMask = mask;
|
||||
}
|
||||
|
||||
private:
|
||||
U64 mFilterMask;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFindWearables
|
||||
//
|
||||
@@ -292,6 +365,52 @@ private:
|
||||
bool mIsWorn;
|
||||
};
|
||||
|
||||
//Inventory collect functor collecting wearables of a specific wearable type
|
||||
class LLFindWearablesOfType : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLFindWearablesOfType(LLWearableType::EType type) : mWearableType(type) {}
|
||||
virtual ~LLFindWearablesOfType() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
|
||||
void setType(LLWearableType::EType type);
|
||||
|
||||
private:
|
||||
LLWearableType::EType mWearableType;
|
||||
};
|
||||
|
||||
/** Filter out wearables-links */
|
||||
class LLFindActualWearablesOfType : public LLFindWearablesOfType
|
||||
{
|
||||
public:
|
||||
LLFindActualWearablesOfType(LLWearableType::EType type) : LLFindWearablesOfType(type) {}
|
||||
virtual ~LLFindActualWearablesOfType() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if (item && item->getIsLinkType()) return false;
|
||||
return LLFindWearablesOfType::operator()(cat, item);
|
||||
}
|
||||
};
|
||||
|
||||
/* Filters out items of a particular asset type */
|
||||
class LLIsTypeActual : public LLIsType
|
||||
{
|
||||
public:
|
||||
LLIsTypeActual(LLAssetType::EType type) : LLIsType(type) {}
|
||||
virtual ~LLIsTypeActual() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if (item && item->getIsLinkType()) return false;
|
||||
return LLIsType::operator()(cat, item);
|
||||
}
|
||||
};
|
||||
|
||||
// Collect non-removable folders and items.
|
||||
class LLFindNonRemovableObjects : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
|
||||
};
|
||||
|
||||
/** Inventory Collector Functions
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llinventorymodel.cpp
|
||||
* @brief Implementation of the inventory model used to track agent inventory.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* 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
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* 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
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -34,6 +28,8 @@
|
||||
#include "llinventorymodel.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
@@ -64,6 +60,7 @@
|
||||
// Increment this if the inventory contents change in a non-backwards-compatible way.
|
||||
// For viewers with link items support, former caches are incorrect.
|
||||
const S32 LLInventoryModel::sCurrentInvCacheVersion = 2;
|
||||
BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE;
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
@@ -244,6 +241,38 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Search up the parent chain until we get to the specified parent, then return the first child category under it
|
||||
//
|
||||
const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LLUUID& master_parent_id, const LLUUID& obj_id) const
|
||||
{
|
||||
if (master_parent_id == obj_id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const LLViewerInventoryCategory* current_cat = getCategory(obj_id);
|
||||
|
||||
if (current_cat == NULL)
|
||||
{
|
||||
current_cat = getCategory(getObject(obj_id)->getParentUUID());
|
||||
}
|
||||
|
||||
while (current_cat != NULL)
|
||||
{
|
||||
const LLUUID& current_parent_id = current_cat->getParentUUID();
|
||||
|
||||
if (current_parent_id == master_parent_id)
|
||||
{
|
||||
return current_cat;
|
||||
}
|
||||
|
||||
current_cat = getCategory(current_parent_id);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the object by id. Returns NULL if not found.
|
||||
LLInventoryObject* LLInventoryModel::getObject(const LLUUID& id) const
|
||||
{
|
||||
@@ -1091,6 +1120,7 @@ void LLInventoryModel::deleteObject(const LLUUID& id)
|
||||
}
|
||||
addChangedMask(LLInventoryObserver::REMOVE, id);
|
||||
obj = NULL; // delete obj
|
||||
updateLinkedObjectsFromPurge(id);
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
|
||||
@@ -1107,6 +1137,25 @@ void LLInventoryModel::purgeObject(const LLUUID &id)
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)
|
||||
{
|
||||
LLInventoryModel::item_array_t item_array = collectLinkedItems(baseobj_id);
|
||||
|
||||
// REBUILD is expensive, so clear the current change list first else
|
||||
// everything else on the changelist will also get rebuilt.
|
||||
gInventory.notifyObservers();
|
||||
for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
|
||||
iter != item_array.end();
|
||||
iter++)
|
||||
{
|
||||
const LLViewerInventoryItem *linked_item = (*iter);
|
||||
const LLUUID &item_id = linked_item->getUUID();
|
||||
if (item_id == baseobj_id) continue;
|
||||
addChangedMask(LLInventoryObserver::REBUILD, item_id);
|
||||
}
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
|
||||
// This is a method which collects the descendents of the id
|
||||
// provided. If the category is not found, no action is
|
||||
// taken. This method goes through the long winded process of
|
||||
@@ -1990,6 +2039,10 @@ void LLInventoryModel::buildParentChildMap()
|
||||
llwarns << "Found " << lost << " lost categories." << llendl;
|
||||
}
|
||||
|
||||
const BOOL COF_exists = (findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, FALSE) != LLUUID::null);
|
||||
sFirstTimeInViewer2 = !COF_exists || gAgent.isFirstLogin();
|
||||
|
||||
|
||||
// Now the items. We allocated in the last step, so now all we
|
||||
// have to do is iterate over the items and put them in the right
|
||||
// place.
|
||||
@@ -2870,7 +2923,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLViewerInventoryItem* wearable_item;
|
||||
wearable_item = gInventory.getItem(wearable_ids[i]);
|
||||
wear_inventory_item_on_avatar(wearable_item);
|
||||
LLAppearanceMgr::instance().wearItemOnAvatar(wearable_item->getUUID(), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3094,6 +3147,139 @@ void LLInventoryModel::setLibraryOwnerID(const LLUUID& val)
|
||||
mLibraryOwnerID = val;
|
||||
}
|
||||
|
||||
// static
|
||||
BOOL LLInventoryModel::getIsFirstTimeInViewer2()
|
||||
{
|
||||
// Do not call this before parentchild map is built.
|
||||
if (!gInventory.mIsAgentInvUsable)
|
||||
{
|
||||
llwarns << "Parent Child Map not yet built; guessing as first time in viewer2." << llendl;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return sFirstTimeInViewer2;
|
||||
}
|
||||
|
||||
LLInventoryModel::item_array_t::iterator LLInventoryModel::findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id)
|
||||
{
|
||||
LLInventoryModel::item_array_t::iterator curr_item = items.begin();
|
||||
|
||||
while (curr_item != items.end())
|
||||
{
|
||||
if ((*curr_item)->getUUID() == id)
|
||||
{
|
||||
break;
|
||||
}
|
||||
++curr_item;
|
||||
}
|
||||
|
||||
return curr_item;
|
||||
}
|
||||
|
||||
// static
|
||||
// * @param[in, out] items - vector with items to be updated. It should be sorted in a right way
|
||||
// * before calling this method.
|
||||
// * @param src_item_id - LLUUID of inventory item to be moved in new position
|
||||
// * @param dest_item_id - LLUUID of inventory item before (or after) which source item should
|
||||
// * be placed.
|
||||
// * @param insert_before - bool indicating if src_item_id should be placed before or after
|
||||
// * dest_item_id. Default is true.
|
||||
void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& src_item_id, const LLUUID& dest_item_id, bool insert_before)
|
||||
{
|
||||
LLInventoryModel::item_array_t::iterator it_src = findItemIterByUUID(items, src_item_id);
|
||||
LLInventoryModel::item_array_t::iterator it_dest = findItemIterByUUID(items, dest_item_id);
|
||||
|
||||
// If one of the passed UUID is not in the item list, bail out
|
||||
if ((it_src == items.end()) || (it_dest == items.end()))
|
||||
return;
|
||||
|
||||
// Erase the source element from the list, keep a copy before erasing.
|
||||
LLViewerInventoryItem* src_item = *it_src;
|
||||
items.erase(it_src);
|
||||
|
||||
// Note: Target iterator is not valid anymore because the container was changed, so update it.
|
||||
it_dest = findItemIterByUUID(items, dest_item_id);
|
||||
|
||||
// Go to the next element if one wishes to insert after the dest element
|
||||
if (!insert_before)
|
||||
{
|
||||
++it_dest;
|
||||
}
|
||||
|
||||
// Reinsert the source item in the right place
|
||||
if (it_dest != items.end())
|
||||
{
|
||||
items.insert(it_dest, src_item);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append to the list if it_dest reached the end
|
||||
items.push_back(src_item);
|
||||
}
|
||||
}
|
||||
|
||||
//* @param[in] items vector of items in order to be saved.
|
||||
/*void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items)
|
||||
{
|
||||
int sortField = 0;
|
||||
|
||||
// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
|
||||
for (item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
|
||||
{
|
||||
LLViewerInventoryItem* item = *i;
|
||||
|
||||
item->setSortField(++sortField);
|
||||
item->setComplete(TRUE);
|
||||
item->updateServer(FALSE);
|
||||
|
||||
updateItem(item);
|
||||
|
||||
// Tell the parent folder to refresh its sort order.
|
||||
addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
|
||||
}
|
||||
|
||||
notifyObservers();
|
||||
}*/
|
||||
|
||||
// See also LLInventorySort where landmarks in the Favorites folder are sorted.
|
||||
/*class LLViewerInventoryItemSort
|
||||
{
|
||||
public:
|
||||
bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
|
||||
{
|
||||
return a->getSortField() < b->getSortField();
|
||||
}
|
||||
};*/
|
||||
|
||||
/**
|
||||
* Sorts passed items by LLViewerInventoryItem sort field.
|
||||
*
|
||||
* @param[in, out] items - array of items, not sorted.
|
||||
*/
|
||||
/*static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
|
||||
{
|
||||
static LLViewerInventoryItemSort sort_functor;
|
||||
std::sort(items.begin(), items.end(), sort_functor);
|
||||
}*/
|
||||
|
||||
// * @param source_item_id - LLUUID of the source item to be moved into new position
|
||||
// * @param target_item_id - LLUUID of the target item before which source item should be placed.
|
||||
/*void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
LLIsType is_type(LLAssetType::AT_LANDMARK);
|
||||
LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
|
||||
gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
|
||||
|
||||
// ensure items are sorted properly before changing order. EXT-3498
|
||||
rearrange_item_order_by_sort_field(items);
|
||||
|
||||
// update order
|
||||
updateItemsOrder(items, source_item_id, target_item_id);
|
||||
|
||||
saveItemsOrder(items);
|
||||
}*/
|
||||
// *NOTE: DEBUG functionality
|
||||
void LLInventoryModel::dumpInventory() const
|
||||
{
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llinventorymodel.h
|
||||
* @brief LLInventoryModel class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* 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
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* 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
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -36,6 +30,7 @@
|
||||
#include "llassettype.h"
|
||||
#include "llfoldertype.h"
|
||||
#include "lldarray.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llhttpclient.h"
|
||||
#include "lluuid.h"
|
||||
#include "llpermissionsflags.h"
|
||||
@@ -72,7 +67,10 @@ class LLInventoryCollectFunctor;
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLInventoryModel
|
||||
{
|
||||
LOG_CLASS(LLInventoryModel);
|
||||
public:
|
||||
friend class LLInventoryModelFetchDescendentsResponder;
|
||||
|
||||
enum EHasChildren
|
||||
{
|
||||
CHILDREN_NO,
|
||||
@@ -90,8 +88,6 @@ public:
|
||||
fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
|
||||
void result(const LLSD& content);
|
||||
void error(U32 status, const std::string& reason);
|
||||
public:
|
||||
typedef std::vector<LLViewerInventoryCategory*> folder_ref_t;
|
||||
protected:
|
||||
LLSD mRequestSD;
|
||||
};
|
||||
@@ -251,6 +247,9 @@ public:
|
||||
|
||||
// Get whatever special folder this object is a child of, if any.
|
||||
const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const;
|
||||
|
||||
// Get first descendant of the child object under the specified parent
|
||||
const LLViewerInventoryCategory *getFirstDescendantOf(const LLUUID& master_parent_id, const LLUUID& obj_id) const;
|
||||
|
||||
// Get the object by id. Returns NULL if not found.
|
||||
// NOTE: Use the pointer returned for read operations - do
|
||||
@@ -339,28 +338,33 @@ public:
|
||||
// cache accounting in a fairly efficient manner. This method does
|
||||
// not notify observers (though maybe it should...)
|
||||
void purgeDescendentsOf(const LLUUID& id);
|
||||
|
||||
// This method optimally removes the referenced categories and
|
||||
// items from the current agent's inventory in the database. It
|
||||
// performs all of the during deletion. The local representation
|
||||
// is not removed.
|
||||
void deleteFromServer(LLDynamicArray<LLUUID>& category_ids,
|
||||
LLDynamicArray<LLUUID>& item_ids);
|
||||
|
||||
//
|
||||
// Misc Methods
|
||||
//
|
||||
|
||||
|
||||
// This method to prepares a set of mock inventory which provides
|
||||
// minimal functionality before the actual arrival of inventory.
|
||||
//void mock(const LLUUID& root_id);
|
||||
|
||||
protected:
|
||||
void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Reorder
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
// Changes items order by insertion of the item identified by src_item_id
|
||||
// before (or after) the item identified by dest_item_id. Both items must exist in items array.
|
||||
// Sorting is stored after method is finished. Only src_item_id is moved before (or after) dest_item_id.
|
||||
// The parameter "insert_before" controls on which side of dest_item_id src_item_id gets rensinserted.
|
||||
static void updateItemsOrder(LLInventoryModel::item_array_t& items,
|
||||
const LLUUID& src_item_id,
|
||||
const LLUUID& dest_item_id,
|
||||
bool insert_before = true);
|
||||
// Gets an iterator on an item vector knowing only the item UUID.
|
||||
// Returns end() of the vector if not found.
|
||||
static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
|
||||
|
||||
// call this method to request the inventory.
|
||||
//void requestFromServer(const LLUUID& agent_id);
|
||||
// Saves current order of the passed items using inventory item sort field.
|
||||
// Resets 'items' sort fields and saves them on server.
|
||||
// Is used to save order for Favorites folder.
|
||||
//void saveItemsOrder(const LLInventoryModel::item_array_t& items);
|
||||
|
||||
// Rearranges Landmarks inside Favorites folder.
|
||||
// Moves source landmark before target one.
|
||||
void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Creation
|
||||
|
||||
@@ -439,6 +439,7 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
|
||||
{
|
||||
cat->setVersion(version);
|
||||
cat->setDescendentCount(descendents);
|
||||
cat->determineFolderType();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -532,7 +533,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)
|
||||
U32 folder_count=0;
|
||||
U32 max_batch_size=5;
|
||||
|
||||
U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
|
||||
U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1;
|
||||
|
||||
uuid_vec_t recursive_cats;
|
||||
|
||||
|
||||
@@ -56,7 +56,9 @@ public:
|
||||
STRUCTURE = 16, // structural change, eg, item or folder moved
|
||||
CALLING_CARD = 32, // online, grant status, cancel, etc change
|
||||
GESTURE = 64,
|
||||
ALL = 0xffffffff
|
||||
REBUILD = 128, // Item UI changed (e.g. item type different)
|
||||
SORT = 256, // Folder needs to be resorted.
|
||||
ALL = 0xffffffff
|
||||
};
|
||||
LLInventoryObserver();
|
||||
virtual ~LLInventoryObserver();
|
||||
|
||||
@@ -121,7 +121,15 @@ BOOL LLInventoryPanel::postBuild()
|
||||
0,
|
||||
getRect().getWidth(),
|
||||
0);
|
||||
mFolderRoot = new LLFolderView(getName(), NULL, folder_rect, LLUUID::null, this);
|
||||
|
||||
LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(LLAssetType::AT_CATEGORY,
|
||||
LLAssetType::AT_CATEGORY,
|
||||
LLInventoryType::IT_CATEGORY,
|
||||
this,
|
||||
NULL,
|
||||
LLUUID::null);
|
||||
|
||||
mFolderRoot = new LLFolderView(getName(), NULL, folder_rect, LLUUID::null, this, new_listener);
|
||||
mFolderRoot->setAllowMultiSelect(mAllowMultiSelect);
|
||||
|
||||
// scroller
|
||||
@@ -475,16 +483,16 @@ const LLUUID& LLInventoryPanel::getRootFolderID() const
|
||||
{
|
||||
return mFolderRoot->getListener()->getUUID();
|
||||
}
|
||||
void LLInventoryPanel::rebuildViewsFor(const LLUUID& id, U32 mask)
|
||||
LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id, U32 mask)
|
||||
{
|
||||
// Destroy the old view for this ID so we can rebuild it.
|
||||
LLFolderViewItem* old_view = mFolderRoot->getItemByID(id);
|
||||
if (old_view && id.notNull())
|
||||
if (old_view)
|
||||
{
|
||||
old_view->destroyView();
|
||||
}
|
||||
|
||||
buildNewViews(id);
|
||||
return buildNewViews(id);
|
||||
}
|
||||
|
||||
LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
|
||||
@@ -506,71 +514,74 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
|
||||
bridge);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::buildNewViews(const LLUUID& id)
|
||||
LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
|
||||
{
|
||||
LLInventoryObject* const objectp = gInventory.getObject(id);
|
||||
LLInventoryObject const* objectp = gInventory.getObject(id);
|
||||
LLUUID root_id = mFolderRoot->getListener()->getUUID();
|
||||
LLFolderViewFolder* parent_folder = NULL;
|
||||
LLFolderViewItem* itemp = NULL;
|
||||
|
||||
|
||||
if (objectp)
|
||||
{
|
||||
const LLUUID &parent_id = objectp->getParentUUID();
|
||||
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
|
||||
if (objectp->getType() <= LLAssetType::AT_NONE ||
|
||||
objectp->getType() >= LLAssetType::AT_COUNT)
|
||||
{
|
||||
if (id == root_id)
|
||||
{
|
||||
parent_folder = mFolderRoot;
|
||||
}
|
||||
else if (objectp)
|
||||
{
|
||||
const LLUUID &parent_id = objectp->getParentUUID();
|
||||
parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
|
||||
|
||||
if (parent_folder)
|
||||
{
|
||||
if (objectp->getType() <= LLAssetType::AT_NONE ||
|
||||
objectp->getType() >= LLAssetType::AT_COUNT)
|
||||
{
|
||||
llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
|
||||
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
|
||||
<< llendl;
|
||||
}
|
||||
else if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
|
||||
(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)) // build new view for category
|
||||
{
|
||||
LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(),
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
|
||||
(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
|
||||
{
|
||||
LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(),
|
||||
objectp->getType(),
|
||||
LLInventoryType::IT_CATEGORY,
|
||||
this,
|
||||
mFolderRoot,
|
||||
objectp->getUUID());
|
||||
|
||||
if (new_listener)
|
||||
if (new_listener)
|
||||
{
|
||||
LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
|
||||
if (folderp)
|
||||
{
|
||||
folderp->setItemSortOrder(mFolderRoot->getSortOrder());
|
||||
}
|
||||
itemp = folderp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
|
||||
if (folderp)
|
||||
{
|
||||
folderp->setItemSortOrder(mFolderRoot->getSortOrder());
|
||||
}
|
||||
itemp = folderp;
|
||||
}
|
||||
}
|
||||
else // build new view for item
|
||||
{
|
||||
LLInventoryItem* item = (LLInventoryItem*)objectp;
|
||||
LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(
|
||||
item->getType(),
|
||||
// Build new view for item.
|
||||
LLInventoryItem* item = (LLInventoryItem*)objectp;
|
||||
LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(item->getType(),
|
||||
item->getActualType(),
|
||||
item->getInventoryType(),
|
||||
this,
|
||||
item->getUUID(),
|
||||
item->getFlags());
|
||||
this,
|
||||
mFolderRoot,
|
||||
item->getUUID(),
|
||||
item->getFlags());
|
||||
|
||||
if (new_listener)
|
||||
{
|
||||
itemp = createFolderViewItem(new_listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (itemp)
|
||||
{
|
||||
if (parent_folder)
|
||||
{
|
||||
itemp->addToFolder(parent_folder, mFolderRoot);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Couldn't find parent folder for child " << itemp->getLabel() << llendl;
|
||||
delete itemp;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemp)
|
||||
{
|
||||
itemp->addToFolder(parent_folder, mFolderRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -595,7 +606,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
|
||||
}
|
||||
}
|
||||
|
||||
if(items)
|
||||
if(items && parent_folder)
|
||||
{
|
||||
for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
|
||||
item_iter != items->end();
|
||||
@@ -607,6 +618,8 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
|
||||
}
|
||||
mInventory->unlockDirectDescendentArrays(id);
|
||||
}
|
||||
|
||||
return itemp;
|
||||
}
|
||||
|
||||
struct LLConfirmPurgeData
|
||||
@@ -728,19 +741,33 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
|
||||
mSelectThisID = obj_id;
|
||||
}
|
||||
}
|
||||
void LLInventoryPanel::setSelectCallback(LLFolderView::SelectCallback callback, void* user_data)
|
||||
{
|
||||
void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
|
||||
{
|
||||
if (mFolderRoot)
|
||||
{
|
||||
mFolderRoot->setSelectCallback(callback, user_data);
|
||||
mFolderRoot->setSelectCallback(cb);
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryPanel::clearSelection()
|
||||
{
|
||||
mFolderRoot->clearSelection();
|
||||
mSelectThisID.setNull();
|
||||
}
|
||||
|
||||
void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
|
||||
{
|
||||
LLFolderView* fv = getRootFolder();
|
||||
if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename
|
||||
{
|
||||
fv->setNeedsAutoRename(FALSE);
|
||||
if (items.size()) // new asset is visible and selected
|
||||
{
|
||||
fv->startRenamingSelectedItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryPanel::createNewItem(const std::string& name,
|
||||
const LLUUID& parent_id,
|
||||
LLAssetType::EType asset_type,
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
void closeAllFolders();
|
||||
void openDefaultFolderForType(LLAssetType::EType);
|
||||
void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
|
||||
void setSelectCallback(LLFolderView::SelectCallback callback, void* user_data);
|
||||
void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
|
||||
void clearSelection();
|
||||
LLInventoryFilter* getFilter();
|
||||
const LLInventoryFilter* getFilter() const;
|
||||
@@ -123,17 +123,14 @@ public:
|
||||
void modelChanged(U32 mask);
|
||||
LLFolderView* getRootFolder();
|
||||
LLScrollableContainerView* getScrollableContainer() { return mScroller; }
|
||||
|
||||
|
||||
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
|
||||
// DEBUG ONLY:
|
||||
static void dumpSelectionInformation(void* user_data);
|
||||
|
||||
void openSelected();
|
||||
void unSelectAll();
|
||||
|
||||
protected:
|
||||
// Given the id and the parent, build all of the folder views.
|
||||
void rebuildViewsFor(const LLUUID& id, U32 mask);
|
||||
void buildNewViews(const LLUUID& id);
|
||||
|
||||
public:
|
||||
// TomY TODO: Move this elsewhere?
|
||||
@@ -174,6 +171,10 @@ private:
|
||||
public:
|
||||
const LLUUID& getRootFolderID() const;
|
||||
protected:
|
||||
// Given the id and the parent, build all of the folder views.
|
||||
LLFolderViewItem* rebuildViewsFor(const LLUUID& id, U32 mask);
|
||||
|
||||
LLFolderViewItem* buildNewViews(const LLUUID& id);
|
||||
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge);
|
||||
virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge);
|
||||
};
|
||||
@@ -195,11 +196,6 @@ void init_inventory_panel_actions(LLInventoryPanel *panel);
|
||||
|
||||
class LLInventoryCategory;
|
||||
class LLInventoryItem;
|
||||
//void wear_inventory_category_on_avatar(LLInventoryCategory* category);
|
||||
|
||||
void wear_inventory_item_on_avatar(LLInventoryItem* item);
|
||||
void wear_outfit_by_name(const std::string& name);
|
||||
void wear_inventory_category(LLInventoryCategory* category, bool copy, bool append);
|
||||
|
||||
// These methods can open items without the inventory being visible
|
||||
void open_notecard(LLViewerInventoryItem* inv_item, const std::string& title, const LLUUID& object_id, BOOL show_keep_discard, const LLUUID& source_id = LLUUID::null, BOOL take_focus = TRUE);
|
||||
|
||||
212
indra/newview/lllocaltextureobject.cpp
Normal file
212
indra/newview/lllocaltextureobject.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* @file lllocaltextureobject.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lllocaltextureobject.h"
|
||||
|
||||
#include "lltexlayer.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "lltextureentry.h"
|
||||
#include "lluuid.h"
|
||||
#include "llwearable.h"
|
||||
|
||||
|
||||
LLLocalTextureObject::LLLocalTextureObject() :
|
||||
mIsBakedReady(FALSE),
|
||||
mDiscard(MAX_DISCARD_LEVEL+1)
|
||||
{
|
||||
mImage = NULL;
|
||||
}
|
||||
|
||||
LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id) :
|
||||
mIsBakedReady(FALSE),
|
||||
mDiscard(MAX_DISCARD_LEVEL+1)
|
||||
{
|
||||
mImage = image;
|
||||
gGL.getTexUnit(0)->bind(mImage);
|
||||
mID = id;
|
||||
}
|
||||
|
||||
LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject& lto) :
|
||||
mImage(lto.mImage),
|
||||
mID(lto.mID),
|
||||
mIsBakedReady(lto.mIsBakedReady),
|
||||
mDiscard(lto.mDiscard)
|
||||
{
|
||||
U32 num_layers = lto.getNumTexLayers();
|
||||
mTexLayers.reserve(num_layers);
|
||||
for (U32 index = 0; index < num_layers; index++)
|
||||
{
|
||||
LLTexLayer* original_layer = lto.getTexLayer(index);
|
||||
if (!original_layer)
|
||||
{
|
||||
llerrs << "could not clone Local Texture Object: unable to extract texlayer!" << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
LLTexLayer* new_layer = new LLTexLayer(*original_layer);
|
||||
new_layer->setLTO(this);
|
||||
mTexLayers.push_back(new_layer);
|
||||
}
|
||||
}
|
||||
|
||||
LLLocalTextureObject::~LLLocalTextureObject()
|
||||
{
|
||||
}
|
||||
|
||||
LLViewerFetchedTexture* LLLocalTextureObject::getImage() const
|
||||
{
|
||||
return mImage;
|
||||
}
|
||||
|
||||
LLTexLayer* LLLocalTextureObject::getTexLayer(U32 index) const
|
||||
{
|
||||
if (index >= getNumTexLayers())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mTexLayers[index];
|
||||
}
|
||||
|
||||
LLTexLayer* LLLocalTextureObject::getTexLayer(const std::string &name)
|
||||
{
|
||||
for( tex_layer_vec_t::iterator iter = mTexLayers.begin(); iter != mTexLayers.end(); iter++)
|
||||
{
|
||||
LLTexLayer *layer = *iter;
|
||||
if (layer->getName().compare(name) == 0)
|
||||
{
|
||||
return layer;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U32 LLLocalTextureObject::getNumTexLayers() const
|
||||
{
|
||||
return mTexLayers.size();
|
||||
}
|
||||
|
||||
LLUUID LLLocalTextureObject::getID() const
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
S32 LLLocalTextureObject::getDiscard() const
|
||||
{
|
||||
return mDiscard;
|
||||
}
|
||||
|
||||
BOOL LLLocalTextureObject::getBakedReady() const
|
||||
{
|
||||
return mIsBakedReady;
|
||||
}
|
||||
|
||||
void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image)
|
||||
{
|
||||
mImage = new_image;
|
||||
}
|
||||
|
||||
BOOL LLLocalTextureObject::setTexLayer(LLTexLayer *new_tex_layer, U32 index)
|
||||
{
|
||||
if (index >= getNumTexLayers() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (new_tex_layer == NULL)
|
||||
{
|
||||
return removeTexLayer(index);
|
||||
}
|
||||
|
||||
LLTexLayer *layer = new LLTexLayer(*new_tex_layer);
|
||||
layer->setLTO(this);
|
||||
|
||||
if (mTexLayers[index])
|
||||
{
|
||||
delete mTexLayers[index];
|
||||
}
|
||||
mTexLayers[index] = layer;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLLocalTextureObject::addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable)
|
||||
{
|
||||
if (new_tex_layer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLTexLayer *layer = new LLTexLayer(*new_tex_layer, wearable);
|
||||
layer->setLTO(this);
|
||||
mTexLayers.push_back(layer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLLocalTextureObject::addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable)
|
||||
{
|
||||
if (new_tex_layer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLTexLayer *layer = new LLTexLayer(*new_tex_layer, this, wearable);
|
||||
layer->setLTO(this);
|
||||
mTexLayers.push_back(layer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLLocalTextureObject::removeTexLayer(U32 index)
|
||||
{
|
||||
if (index >= getNumTexLayers())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
tex_layer_vec_t::iterator iter = mTexLayers.begin();
|
||||
iter += index;
|
||||
|
||||
delete *iter;
|
||||
mTexLayers.erase(iter);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLLocalTextureObject::setID(LLUUID new_id)
|
||||
{
|
||||
mID = new_id;
|
||||
}
|
||||
|
||||
void LLLocalTextureObject::setDiscard(S32 new_discard)
|
||||
{
|
||||
mDiscard = new_discard;
|
||||
}
|
||||
|
||||
void LLLocalTextureObject::setBakedReady(BOOL ready)
|
||||
{
|
||||
mIsBakedReady = ready;
|
||||
}
|
||||
|
||||
87
indra/newview/lllocaltextureobject.h
Normal file
87
indra/newview/lllocaltextureobject.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @file lllocaltextureobject.h
|
||||
* @brief LLLocalTextureObject class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LOCALTEXTUREOBJECT_H
|
||||
#define LL_LOCALTEXTUREOBJECT_H
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "llviewertexture.h"
|
||||
|
||||
class LLUUID;
|
||||
class LLTexLayer;
|
||||
class LLTextureEntry;
|
||||
class LLTexLayerTemplate;
|
||||
class LLWearable;
|
||||
|
||||
// Stores all relevant information for a single texture
|
||||
// assumed to have ownership of all objects referred to -
|
||||
// will delete objects when being replaced or if object is destroyed.
|
||||
class LLLocalTextureObject
|
||||
{
|
||||
public:
|
||||
LLLocalTextureObject();
|
||||
LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id);
|
||||
LLLocalTextureObject(const LLLocalTextureObject& lto);
|
||||
~LLLocalTextureObject();
|
||||
|
||||
LLViewerFetchedTexture* getImage() const;
|
||||
LLTexLayer* getTexLayer(U32 index) const;
|
||||
LLTexLayer* getTexLayer(const std::string &name);
|
||||
U32 getNumTexLayers() const;
|
||||
LLUUID getID() const;
|
||||
S32 getDiscard() const;
|
||||
BOOL getBakedReady() const;
|
||||
|
||||
void setImage(LLViewerFetchedTexture* new_image);
|
||||
BOOL setTexLayer(LLTexLayer *new_tex_layer, U32 index);
|
||||
BOOL addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable);
|
||||
BOOL addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable);
|
||||
BOOL removeTexLayer(U32 index);
|
||||
|
||||
void setID(LLUUID new_id);
|
||||
void setDiscard(S32 new_discard);
|
||||
void setBakedReady(BOOL ready);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
LLPointer<LLViewerFetchedTexture> mImage;
|
||||
// NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer
|
||||
// using shared pointers here only for smart assignment & cleanup
|
||||
// do NOT create new shared pointers to these objects, or keep pointers to them around
|
||||
typedef std::vector<LLTexLayer*> tex_layer_vec_t;
|
||||
tex_layer_vec_t mTexLayers;
|
||||
|
||||
LLUUID mID;
|
||||
|
||||
BOOL mIsBakedReady;
|
||||
S32 mDiscard;
|
||||
};
|
||||
|
||||
#endif // LL_LOCALTEXTUREOBJECT_H
|
||||
|
||||
153
indra/newview/lloutfitobserver.cpp
Normal file
153
indra/newview/lloutfitobserver.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @file lloutfitobserver.cpp
|
||||
* @brief Outfit observer facade.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llappearancemgr.h"
|
||||
#include "lloutfitobserver.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
LLOutfitObserver::LLOutfitObserver() :
|
||||
mCOFLastVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
|
||||
{
|
||||
mItemNameHash.finalize();
|
||||
gInventory.addObserver(this);
|
||||
}
|
||||
|
||||
LLOutfitObserver::~LLOutfitObserver()
|
||||
{
|
||||
if (gInventory.containsObserver(this))
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitObserver::changed(U32 mask)
|
||||
{
|
||||
if (!gInventory.isInventoryUsable())
|
||||
return;
|
||||
|
||||
checkCOF();
|
||||
|
||||
checkBaseOutfit();
|
||||
}
|
||||
|
||||
// static
|
||||
S32 LLOutfitObserver::getCategoryVersion(const LLUUID& cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||
if (!cat)
|
||||
return LLViewerInventoryCategory::VERSION_UNKNOWN;
|
||||
|
||||
return cat->getVersion();
|
||||
}
|
||||
|
||||
// static
|
||||
const std::string& LLOutfitObserver::getCategoryName(const LLUUID& cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||
if (!cat)
|
||||
return LLStringUtil::null;
|
||||
|
||||
return cat->getName();
|
||||
}
|
||||
|
||||
bool LLOutfitObserver::checkCOF()
|
||||
{
|
||||
LLUUID cof = LLAppearanceMgr::getInstance()->getCOF();
|
||||
if (cof.isNull())
|
||||
return false;
|
||||
|
||||
bool cof_changed = false;
|
||||
LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cof);
|
||||
if (item_name_hash != mItemNameHash)
|
||||
{
|
||||
cof_changed = true;
|
||||
mItemNameHash = item_name_hash;
|
||||
}
|
||||
|
||||
S32 cof_version = getCategoryVersion(cof);
|
||||
if (cof_version != mCOFLastVersion)
|
||||
{
|
||||
cof_changed = true;
|
||||
mCOFLastVersion = cof_version;
|
||||
}
|
||||
|
||||
if (!cof_changed)
|
||||
return false;
|
||||
|
||||
// dirtiness state should be updated before sending signal
|
||||
LLAppearanceMgr::getInstance()->updateIsDirty();
|
||||
mCOFChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLOutfitObserver::checkBaseOutfit()
|
||||
{
|
||||
LLUUID baseoutfit_id =
|
||||
LLAppearanceMgr::getInstance()->getBaseOutfitUUID();
|
||||
|
||||
if (baseoutfit_id == mBaseOutfitId)
|
||||
{
|
||||
if (baseoutfit_id.isNull())
|
||||
return;
|
||||
|
||||
const S32 baseoutfit_ver = getCategoryVersion(baseoutfit_id);
|
||||
const std::string& baseoutfit_name = getCategoryName(baseoutfit_id);
|
||||
|
||||
if (baseoutfit_ver == mBaseOutfitLastVersion
|
||||
// renaming category doesn't change version, so it's need to check it
|
||||
&& baseoutfit_name == mLastBaseOutfitName)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
mBaseOutfitId = baseoutfit_id;
|
||||
mBOFReplaced();
|
||||
|
||||
if (baseoutfit_id.isNull())
|
||||
return;
|
||||
}
|
||||
|
||||
mBaseOutfitLastVersion = getCategoryVersion(mBaseOutfitId);
|
||||
mLastBaseOutfitName = getCategoryName(baseoutfit_id);
|
||||
|
||||
LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance();
|
||||
// dirtiness state should be updated before sending signal
|
||||
app_mgr.updateIsDirty();
|
||||
mBOFChanged();
|
||||
|
||||
if (mLastOutfitDirtiness != app_mgr.isOutfitDirty())
|
||||
{
|
||||
if(!app_mgr.isOutfitDirty())
|
||||
{
|
||||
mCOFSaved();
|
||||
}
|
||||
mLastOutfitDirtiness = app_mgr.isOutfitDirty();
|
||||
}
|
||||
}
|
||||
96
indra/newview/lloutfitobserver.h
Normal file
96
indra/newview/lloutfitobserver.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file lloutfitobserver.h
|
||||
* @brief Outfit observer facade.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_OUTFITOBSERVER_H
|
||||
#define LL_OUTFITOBSERVER_H
|
||||
|
||||
#include "llsingleton.h"
|
||||
#include "llmd5.h"
|
||||
|
||||
/**
|
||||
* Outfit observer facade that provides simple possibility to subscribe on
|
||||
* BOF(base outfit) replaced, BOF changed, COF(current outfit) changed events.
|
||||
*/
|
||||
class LLOutfitObserver: public LLInventoryObserver, public LLSingleton<LLOutfitObserver>
|
||||
{
|
||||
public:
|
||||
virtual ~LLOutfitObserver();
|
||||
|
||||
friend class LLSingleton<LLOutfitObserver>;
|
||||
|
||||
virtual void changed(U32 mask);
|
||||
|
||||
void notifyOutfitLockChanged() { mOutfitLockChanged(); }
|
||||
|
||||
typedef boost::signals2::signal<void (void)> signal_t;
|
||||
|
||||
void addBOFReplacedCallback(const signal_t::slot_type& cb) { mBOFReplaced.connect(cb); }
|
||||
|
||||
void addBOFChangedCallback(const signal_t::slot_type& cb) { mBOFChanged.connect(cb); }
|
||||
|
||||
void addCOFChangedCallback(const signal_t::slot_type& cb) { mCOFChanged.connect(cb); }
|
||||
|
||||
void addCOFSavedCallback(const signal_t::slot_type& cb) { mCOFSaved.connect(cb); }
|
||||
|
||||
void addOutfitLockChangedCallback(const signal_t::slot_type& cb) { mOutfitLockChanged.connect(cb); }
|
||||
|
||||
protected:
|
||||
LLOutfitObserver();
|
||||
|
||||
/** Get a version of an inventory category specified by its UUID */
|
||||
static S32 getCategoryVersion(const LLUUID& cat_id);
|
||||
|
||||
static const std::string& getCategoryName(const LLUUID& cat_id);
|
||||
|
||||
bool checkCOF();
|
||||
|
||||
void checkBaseOutfit();
|
||||
|
||||
//last version number of a COF category
|
||||
S32 mCOFLastVersion;
|
||||
|
||||
LLUUID mBaseOutfitId;
|
||||
|
||||
S32 mBaseOutfitLastVersion;
|
||||
std::string mLastBaseOutfitName;
|
||||
|
||||
bool mLastOutfitDirtiness;
|
||||
|
||||
LLMD5 mItemNameHash;
|
||||
|
||||
private:
|
||||
signal_t mBOFReplaced;
|
||||
signal_t mBOFChanged;
|
||||
signal_t mCOFChanged;
|
||||
signal_t mCOFSaved;
|
||||
|
||||
/**
|
||||
* Signal for changing state of outfit lock.
|
||||
*/
|
||||
signal_t mOutfitLockChanged;
|
||||
};
|
||||
|
||||
#endif /* LL_OUTFITOBSERVER_H */
|
||||
@@ -152,7 +152,7 @@ BOOL LLInventoryView::postBuild()
|
||||
mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER));
|
||||
mActivePanel->getFilter()->markDefault();
|
||||
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
|
||||
mActivePanel->setSelectCallback(onSelectionChange, mActivePanel);
|
||||
mActivePanel->setSelectCallback(boost::bind(&LLInventoryView::onSelectionChange, this, mActivePanel, _1, _2));
|
||||
}
|
||||
LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
|
||||
if (recent_items_panel)
|
||||
@@ -161,7 +161,7 @@ BOOL LLInventoryView::postBuild()
|
||||
recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER));
|
||||
recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
recent_items_panel->getFilter()->markDefault();
|
||||
recent_items_panel->setSelectCallback(onSelectionChange, recent_items_panel);
|
||||
recent_items_panel->setSelectCallback(boost::bind(&LLInventoryView::onSelectionChange, this, recent_items_panel, _1, _2));
|
||||
}
|
||||
LLInventoryPanel* worn_items_panel = getChild<LLInventoryPanel>("Worn Items");
|
||||
if (worn_items_panel)
|
||||
@@ -170,7 +170,7 @@ BOOL LLInventoryView::postBuild()
|
||||
worn_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
worn_items_panel->getFilter()->markDefault();
|
||||
worn_items_panel->setFilterWorn(true);
|
||||
worn_items_panel->setSelectCallback(onSelectionChange, worn_items_panel);
|
||||
worn_items_panel->setSelectCallback(boost::bind(&LLInventoryView::onSelectionChange, this, worn_items_panel, _1, _2));
|
||||
}
|
||||
|
||||
// Now load the stored settings from disk, if available.
|
||||
@@ -581,79 +581,54 @@ void LLInventoryView::onSearchEdit(const std::string& search_string, void* user_
|
||||
self->mActivePanel->setFilterSubString(uppercase_search_string);
|
||||
}
|
||||
|
||||
struct FilterEntry : public LLDictionaryEntry
|
||||
{
|
||||
FilterEntry(const std::string &filter_name) :
|
||||
LLDictionaryEntry(filter_name){}
|
||||
};
|
||||
|
||||
class LLFilterDictionary : public LLSingleton<LLFilterDictionary>,
|
||||
public LLDictionary<U32, FilterEntry>
|
||||
{
|
||||
public:
|
||||
LLFilterDictionary()
|
||||
{}
|
||||
void init(LLInventoryView *view)
|
||||
{
|
||||
addEntry(0x1 << LLInventoryType::IT_ANIMATION, new FilterEntry(view->getString("filter_type_animation")));
|
||||
addEntry(0x1 << LLInventoryType::IT_CALLINGCARD, new FilterEntry(view->getString("filter_type_callingcard")));
|
||||
addEntry(0x1 << LLInventoryType::IT_WEARABLE, new FilterEntry(view->getString("filter_type_wearable")));
|
||||
addEntry(0x1 << LLInventoryType::IT_GESTURE, new FilterEntry(view->getString("filter_type_gesture")));
|
||||
addEntry(0x1 << LLInventoryType::IT_LANDMARK, new FilterEntry(view->getString("filter_type_landmark")));
|
||||
addEntry(0x1 << LLInventoryType::IT_NOTECARD, new FilterEntry(view->getString("filter_type_notecard")));
|
||||
addEntry(0x1 << LLInventoryType::IT_OBJECT, new FilterEntry(view->getString("filter_type_object")));
|
||||
addEntry(0x1 << LLInventoryType::IT_LSL, new FilterEntry(view->getString("filter_type_script")));
|
||||
addEntry(0x1 << LLInventoryType::IT_SOUND, new FilterEntry(view->getString("filter_type_sound")));
|
||||
addEntry(0x1 << LLInventoryType::IT_TEXTURE, new FilterEntry(view->getString("filter_type_texture")));
|
||||
addEntry(0x1 << LLInventoryType::IT_SNAPSHOT, new FilterEntry(view->getString("filter_type_snapshot")));
|
||||
addEntry(0xffffffff, new FilterEntry(view->getString("filter_type_all")));
|
||||
}
|
||||
virtual U32 notFound() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
//static
|
||||
void LLInventoryView::onQuickFilterCommit(LLUICtrl* ctrl, void* user_data)
|
||||
{
|
||||
|
||||
LLComboBox* quickfilter = (LLComboBox*)ctrl;
|
||||
|
||||
|
||||
LLInventoryView* view = (LLInventoryView*)(quickfilter->getParent());
|
||||
if (!view->mActivePanel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::string item_type = quickfilter->getSimple();
|
||||
U32 filter_type;
|
||||
|
||||
if (view->getString("filter_type_animation") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_ANIMATION;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_callingcard") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_CALLINGCARD;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_wearable") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_WEARABLE;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_gesture") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_GESTURE;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_landmark") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_LANDMARK;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_notecard") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_NOTECARD;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_object") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_OBJECT;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_script") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_LSL;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_sound") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_SOUND;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_texture") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_TEXTURE;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_snapshot") == item_type)
|
||||
{
|
||||
filter_type = 0x1 << LLInventoryType::IT_SNAPSHOT;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_custom") == item_type)
|
||||
if (view->getString("filter_type_custom") == item_type)
|
||||
{
|
||||
// When they select custom, show the floater then return
|
||||
if( !(view->filtersVisible(view)) )
|
||||
@@ -662,31 +637,27 @@ void LLInventoryView::onQuickFilterCommit(LLUICtrl* ctrl, void* user_data)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
else if (view->getString("filter_type_all") == item_type)
|
||||
else
|
||||
{
|
||||
// Show all types
|
||||
filter_type = 0xffffffff;
|
||||
if(!LLFilterDictionary::instanceExists())
|
||||
LLFilterDictionary::instance().init(view);
|
||||
|
||||
U32 filter_type = LLFilterDictionary::instance().lookup(item_type);
|
||||
if(!filter_type)
|
||||
{
|
||||
llwarns << "Ignoring unknown filter: " << item_type << llendl;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
view->mActivePanel->setFilterTypes( filter_type );
|
||||
|
||||
// Force the filters window to update itself, if it's open.
|
||||
LLFloaterInventoryFinder* finder = view->getFinder();
|
||||
if( finder )
|
||||
finder->updateElementsFromFilter();
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
llwarns << "Ignoring unknown filter: " << item_type << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
view->mActivePanel->setFilterTypes( filter_type );
|
||||
|
||||
|
||||
// Force the filters window to update itself, if it's open.
|
||||
LLFloaterInventoryFinder* finder = view->getFinder();
|
||||
if( finder )
|
||||
{
|
||||
finder->updateElementsFromFilter();
|
||||
}
|
||||
|
||||
// llinfos << "Quick Filter: " << item_type << llendl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -694,7 +665,6 @@ void LLInventoryView::onQuickFilterCommit(LLUICtrl* ctrl, void* user_data)
|
||||
//static
|
||||
void LLInventoryView::refreshQuickFilter(LLUICtrl* ctrl)
|
||||
{
|
||||
|
||||
LLInventoryView* view = (LLInventoryView*)(ctrl->getParent());
|
||||
if (!view->mActivePanel)
|
||||
{
|
||||
@@ -707,147 +677,48 @@ void LLInventoryView::refreshQuickFilter(LLUICtrl* ctrl)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
U32 filter_type = view->mActivePanel->getFilterTypes();
|
||||
|
||||
if(!LLFilterDictionary::instanceExists())
|
||||
LLFilterDictionary::instance().init(view);
|
||||
|
||||
// Mask to extract only the bit fields we care about.
|
||||
// *TODO: There's probably a cleaner way to construct this mask.
|
||||
U32 filter_mask = 0;
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_ANIMATION);
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_CALLINGCARD);
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_WEARABLE);
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_GESTURE);
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_LANDMARK);
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_NOTECARD);
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_OBJECT);
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_LSL);
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_SOUND);
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_TEXTURE);
|
||||
filter_mask |= (0x1 << LLInventoryType::IT_SNAPSHOT);
|
||||
|
||||
|
||||
filter_type &= filter_mask;
|
||||
|
||||
|
||||
// Mask to extract only the bit fields we care about.
|
||||
// *TODO: There's probably a cleaner way to construct this mask.
|
||||
U32 filter_mask = 0;
|
||||
for (LLFilterDictionary::const_iterator_t dictionary_iter = LLFilterDictionary::instance().map_t::begin();
|
||||
dictionary_iter != LLFilterDictionary::instance().map_t::end(); dictionary_iter++)
|
||||
{
|
||||
if(filter_mask != 0xffffffff)
|
||||
filter_mask |= dictionary_iter->first;
|
||||
}
|
||||
|
||||
filter_type &= filter_mask;
|
||||
|
||||
//llinfos << "filter_type: " << filter_type << llendl;
|
||||
|
||||
std::string selection;
|
||||
|
||||
|
||||
if (filter_type == filter_mask)
|
||||
{
|
||||
selection = view->getString("filter_type_all");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_ANIMATION))
|
||||
{
|
||||
selection = view->getString("filter_type_animation");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_CALLINGCARD))
|
||||
{
|
||||
selection = view->getString("filter_type_callingcard");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_WEARABLE))
|
||||
{
|
||||
selection = view->getString("filter_type_wearable");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_GESTURE))
|
||||
{
|
||||
selection = view->getString("filter_type_gesture");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_LANDMARK))
|
||||
{
|
||||
selection = view->getString("filter_type_landmark");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_NOTECARD))
|
||||
{
|
||||
selection = view->getString("filter_type_notecard");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_OBJECT))
|
||||
{
|
||||
selection = view->getString("filter_type_object");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_LSL))
|
||||
{
|
||||
selection = view->getString("filter_type_script");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_SOUND))
|
||||
{
|
||||
selection = view->getString("filter_type_sound");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_TEXTURE))
|
||||
{
|
||||
selection = view->getString("filter_type_texture");
|
||||
}
|
||||
|
||||
else if (filter_type == (0x1 << LLInventoryType::IT_SNAPSHOT))
|
||||
{
|
||||
selection = view->getString("filter_type_snapshot");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
selection = view->getString("filter_type_custom");
|
||||
const FilterEntry *entry = LLFilterDictionary::instance().lookup(filter_type);
|
||||
if(entry)
|
||||
selection = view->getString(entry->mName);
|
||||
else
|
||||
selection = view->getString("filter_type_custom");
|
||||
}
|
||||
|
||||
|
||||
// Select the chosen item by label text
|
||||
BOOL result = quickfilter->setSimple( (selection) );
|
||||
|
||||
if( !result )
|
||||
{
|
||||
llinfos << "The item didn't exist: " << selection << llendl;
|
||||
}
|
||||
|
||||
if( !result )
|
||||
{
|
||||
llinfos << "The item didn't exist: " << selection << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// static
|
||||
// BOOL LLInventoryView::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward)
|
||||
// {
|
||||
// LLInventoryView* active_view = NULL;
|
||||
|
||||
// for (S32 i = 0; i < sActiveViews.count(); i++)
|
||||
// {
|
||||
// if (gFocusMgr.childHasKeyboardFocus(sActiveViews[i]))
|
||||
// {
|
||||
// active_view = sActiveViews[i];
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (!active_view)
|
||||
// {
|
||||
// return FALSE;
|
||||
// }
|
||||
|
||||
// std::string search_string(find_text);
|
||||
|
||||
// if (search_string.empty())
|
||||
// {
|
||||
// return FALSE;
|
||||
// }
|
||||
|
||||
// if (active_view->mActivePanel &&
|
||||
// active_view->mActivePanel->getRootFolder()->search(first_item, search_string, backward))
|
||||
// {
|
||||
// return TRUE;
|
||||
// }
|
||||
|
||||
// return FALSE;
|
||||
// }
|
||||
|
||||
void LLInventoryView::onResetAll(void* userdata)
|
||||
{
|
||||
LLInventoryView* self = (LLInventoryView*) userdata;
|
||||
@@ -920,21 +791,6 @@ void LLInventoryView::onFilterSelected(void* userdata, bool from_click)
|
||||
self->updateSortControls();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLInventoryView::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
|
||||
{
|
||||
LLInventoryPanel* panel = (LLInventoryPanel*)data;
|
||||
LLFolderView* fv = panel->getRootFolder();
|
||||
if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename
|
||||
{
|
||||
fv->setNeedsAutoRename(FALSE);
|
||||
if (items.size()) // new asset is visible and selected
|
||||
{
|
||||
fv->startRenamingSelectedItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string LLInventoryView::getFilterSubString()
|
||||
{
|
||||
return mActivePanel->getFilterSubString();
|
||||
@@ -1040,9 +896,23 @@ void LLInventoryView::toggleFindOptions()
|
||||
mFloaterControls[std::string("Inventory.ShowFilters")]->setValue(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryView::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
|
||||
{
|
||||
getChild<LLInventoryPanel>("All Items")->setSelectCallback(cb);
|
||||
getChild<LLInventoryPanel>("Recent Items")->setSelectCallback(cb);
|
||||
getChild<LLInventoryPanel>("Worn Items")->setSelectCallback(cb);
|
||||
}
|
||||
|
||||
void LLInventoryView::onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action)
|
||||
{
|
||||
panel->onSelectionChange(items, user_action);
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// LLFloaterInventoryFinder
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLFloaterInventoryFinder* LLInventoryView::getFinder()
|
||||
{
|
||||
return (LLFloaterInventoryFinder*)mFinderHandle.get();
|
||||
@@ -1056,7 +926,7 @@ LLFloaterInventoryFinder::LLFloaterInventoryFinder(const std::string& name,
|
||||
INV_FINDER_WIDTH, INV_FINDER_HEIGHT, DRAG_ON_TOP,
|
||||
MINIMIZE_NO, CLOSE_YES),
|
||||
mInventoryView(inventory_view),
|
||||
mFilter(inventory_view->mActivePanel->getFilter())
|
||||
mFilter(inventory_view->getPanel()->getFilter())
|
||||
{
|
||||
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml");
|
||||
|
||||
@@ -89,6 +89,8 @@ public:
|
||||
const LLInventoryPanel* getActivePanel() const { return mActivePanel; }
|
||||
|
||||
const std::string& getFilterText() const { return mFilterText; }
|
||||
|
||||
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
|
||||
static void onSearchEdit(const std::string& search_string, void* user_data );
|
||||
//
|
||||
// Misc functions
|
||||
@@ -97,7 +99,8 @@ public:
|
||||
void startSearch();
|
||||
|
||||
void toggleFindOptions();
|
||||
static void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data);
|
||||
void onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action);
|
||||
|
||||
static BOOL filtersVisible(void* user_data);
|
||||
static void onClearSearch(void* user_data);
|
||||
static void onFoldersByName(void *user_data);
|
||||
|
||||
@@ -83,7 +83,10 @@ protected:
|
||||
mutable std::string mDisplayName;
|
||||
LLPanelObjectInventory* mPanel;
|
||||
U32 mFlags;
|
||||
LLAssetType::EType mAssetType;
|
||||
LLInventoryType::EType mInventoryType;
|
||||
|
||||
LLInventoryObject* findInvObject() const;
|
||||
LLInventoryItem* findItem() const;
|
||||
|
||||
public:
|
||||
@@ -107,30 +110,34 @@ public:
|
||||
virtual const std::string& getName() const;
|
||||
virtual const std::string& getDisplayName() const;
|
||||
virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
|
||||
/*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
|
||||
virtual const LLUUID& getUUID() const { return mUUID; }
|
||||
virtual time_t getCreationDate() const;
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void openItem();
|
||||
virtual BOOL canOpenItem() const { return FALSE; }
|
||||
virtual void closeItem() {}
|
||||
virtual void previewItem();
|
||||
virtual void selectItem() {}
|
||||
virtual BOOL isItemRenameable() const;
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
virtual BOOL isItemMovable();
|
||||
virtual BOOL isItemRemovable();
|
||||
virtual BOOL isItemMovable() const;
|
||||
virtual BOOL isItemRemovable() const;
|
||||
virtual BOOL removeItem();
|
||||
virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
|
||||
virtual void move(LLFolderViewEventListener* parent_listener);
|
||||
virtual BOOL isItemCopyable() const;
|
||||
virtual BOOL copyToClipboard() const;
|
||||
virtual BOOL cutToClipboard() const;
|
||||
virtual void cutToClipboard();
|
||||
virtual BOOL isClipboardPasteable() const;
|
||||
virtual void pasteFromClipboard();
|
||||
virtual void pasteLinkFromClipboard();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual BOOL isUpToDate() const { return TRUE; }
|
||||
virtual BOOL hasChildren() const { return FALSE; }
|
||||
virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
|
||||
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
|
||||
|
||||
// LLDragAndDropBridge functionality
|
||||
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
|
||||
@@ -149,19 +156,32 @@ LLTaskInvFVBridge::LLTaskInvFVBridge(
|
||||
mUUID(uuid),
|
||||
mName(name),
|
||||
mPanel(panel),
|
||||
mFlags(flags)
|
||||
mFlags(flags),
|
||||
mAssetType(LLAssetType::AT_NONE),
|
||||
mInventoryType(LLInventoryType::IT_NONE)
|
||||
{
|
||||
|
||||
const LLInventoryItem *item = findItem();
|
||||
if (item)
|
||||
{
|
||||
mAssetType = item->getType();
|
||||
mInventoryType = item->getInventoryType();
|
||||
}
|
||||
}
|
||||
|
||||
LLInventoryObject* LLTaskInvFVBridge::findInvObject() const
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
|
||||
if (object)
|
||||
{
|
||||
return object->getInventoryObject(mUUID);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
LLInventoryItem* LLTaskInvFVBridge::findItem() const
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
|
||||
if(object)
|
||||
{
|
||||
return (LLInventoryItem*)(object->getInventoryObject(mUUID));
|
||||
}
|
||||
return NULL;
|
||||
return dynamic_cast<LLInventoryItem*>(findInvObject());
|
||||
}
|
||||
|
||||
void LLTaskInvFVBridge::showProperties()
|
||||
@@ -333,7 +353,7 @@ LLUIImagePtr LLTaskInvFVBridge::getIcon() const
|
||||
{
|
||||
const BOOL item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS);
|
||||
|
||||
return LLInventoryIcon::getIcon(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT, 0, item_is_multi );
|
||||
return LLInventoryIcon::getIcon(mAssetType, mInventoryType, 0, item_is_multi );
|
||||
}
|
||||
|
||||
void LLTaskInvFVBridge::openItem()
|
||||
@@ -400,7 +420,7 @@ BOOL LLTaskInvFVBridge::renameItem(const std::string& new_name)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLTaskInvFVBridge::isItemMovable()
|
||||
BOOL LLTaskInvFVBridge::isItemMovable() const
|
||||
{
|
||||
//LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
|
||||
//if(object && (object->permModify() || gAgent.isGodlike()))
|
||||
@@ -430,7 +450,7 @@ BOOL LLTaskInvFVBridge::isItemMovable()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLTaskInvFVBridge::isItemRemovable()
|
||||
BOOL LLTaskInvFVBridge::isItemRemovable() const
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
|
||||
// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.2.0c) | Modified: RLVa-1.0.5a
|
||||
@@ -566,9 +586,8 @@ BOOL LLTaskInvFVBridge::copyToClipboard() const
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLTaskInvFVBridge::cutToClipboard() const
|
||||
void LLTaskInvFVBridge::cutToClipboard()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLTaskInvFVBridge::isClipboardPasteable() const
|
||||
@@ -643,7 +662,7 @@ BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop,
|
||||
//}
|
||||
|
||||
// virtual
|
||||
void LLTaskInvFVBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
|
||||
void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string action)
|
||||
{
|
||||
if (action == "task_buy")
|
||||
{
|
||||
@@ -720,7 +739,7 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (canOpenItem())
|
||||
{
|
||||
items.push_back(std::string("Task Open"));
|
||||
if (!isItemCopyable())
|
||||
@@ -780,16 +799,19 @@ public:
|
||||
const std::string& name);
|
||||
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual const std::string& getDisplayName() const { return getName(); }
|
||||
virtual const std::string& getDisplayName() const;
|
||||
virtual BOOL isItemRenameable() const;
|
||||
// virtual BOOL isItemCopyable() const { return FALSE; }
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
virtual BOOL isItemRemovable();
|
||||
virtual BOOL isItemRemovable() const;
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual BOOL hasChildren() const;
|
||||
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
|
||||
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data);
|
||||
virtual BOOL canOpenItem() const { return TRUE; }
|
||||
virtual void openItem();
|
||||
};
|
||||
|
||||
LLTaskCategoryBridge::LLTaskCategoryBridge(
|
||||
@@ -805,6 +827,12 @@ LLUIImagePtr LLTaskCategoryBridge::getIcon() const
|
||||
return LLUI::getUIImage("inv_folder_plain_closed.tga");
|
||||
}
|
||||
|
||||
// virtual
|
||||
const std::string& LLTaskCategoryBridge::getDisplayName() const
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
|
||||
BOOL LLTaskCategoryBridge::isItemRenameable() const
|
||||
{
|
||||
return FALSE;
|
||||
@@ -815,7 +843,7 @@ BOOL LLTaskCategoryBridge::renameItem(const std::string& new_name)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLTaskCategoryBridge::isItemRemovable()
|
||||
BOOL LLTaskCategoryBridge::isItemRemovable() const
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -835,10 +863,14 @@ BOOL LLTaskCategoryBridge::hasChildren() const
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLTaskCategoryBridge::openItem()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
|
||||
{
|
||||
//llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
|
||||
if(mPanel)
|
||||
if(mPanel && mUUID.notNull())
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
|
||||
if(object)
|
||||
@@ -943,21 +975,13 @@ class LLTaskTextureBridge : public LLTaskInvFVBridge
|
||||
public:
|
||||
LLTaskTextureBridge(LLPanelObjectInventory* panel,
|
||||
const LLUUID& uuid,
|
||||
LLInventoryType::EType it,
|
||||
const std::string& name) :
|
||||
LLTaskInvFVBridge(panel, uuid, name), mInventoryType(it){}
|
||||
LLTaskInvFVBridge(panel, uuid, name) {}
|
||||
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual BOOL canOpenItem() const { return TRUE; }
|
||||
virtual void openItem();
|
||||
protected:
|
||||
LLInventoryType::EType mInventoryType;
|
||||
};
|
||||
|
||||
LLUIImagePtr LLTaskTextureBridge::getIcon() const
|
||||
{
|
||||
return LLInventoryIcon::getIcon(LLAssetType::AT_TEXTURE, mInventoryType, 0, FALSE);
|
||||
}
|
||||
|
||||
void LLTaskTextureBridge::openItem()
|
||||
{
|
||||
// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
|
||||
@@ -998,18 +1022,13 @@ public:
|
||||
const std::string& name) :
|
||||
LLTaskInvFVBridge(panel, uuid, name) {}
|
||||
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual BOOL canOpenItem() const { return TRUE; }
|
||||
virtual void openItem();
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
static void openSoundPreview(void* data);
|
||||
};
|
||||
|
||||
|
||||
LLUIImagePtr LLTaskSoundBridge::getIcon() const
|
||||
{
|
||||
return LLInventoryIcon::getIcon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0, FALSE);
|
||||
}
|
||||
void LLTaskSoundBridge::openItem()
|
||||
{
|
||||
openSoundPreview((void*)this);
|
||||
@@ -1037,7 +1056,7 @@ void LLTaskSoundBridge::openSoundPreview(void* data)
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLTaskSoundBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
|
||||
void LLTaskSoundBridge::performAction(LLInventoryModel* model, std::string action)
|
||||
{
|
||||
if (action == "task_play")
|
||||
{
|
||||
@@ -1047,7 +1066,7 @@ void LLTaskSoundBridge::performAction(LLFolderView* folder, LLInventoryModel* mo
|
||||
send_sound_trigger(item->getAssetUUID(), 1.0);
|
||||
}
|
||||
}
|
||||
LLTaskInvFVBridge::performAction(folder, model, action);
|
||||
LLTaskInvFVBridge::performAction(model, action);
|
||||
}
|
||||
|
||||
void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
@@ -1128,14 +1147,8 @@ public:
|
||||
const LLUUID& uuid,
|
||||
const std::string& name) :
|
||||
LLTaskInvFVBridge(panel, uuid, name) {}
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
};
|
||||
|
||||
LLUIImagePtr LLTaskLandmarkBridge::getIcon() const
|
||||
{
|
||||
return LLInventoryIcon::getIcon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, 0, FALSE);
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLTaskCallingCardBridge
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -1148,14 +1161,9 @@ public:
|
||||
const std::string& name) :
|
||||
LLTaskInvFVBridge(panel, uuid, name) {}
|
||||
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual BOOL isItemRenameable() const;
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
};
|
||||
LLUIImagePtr LLTaskCallingCardBridge::getIcon() const
|
||||
{
|
||||
return LLInventoryIcon::getIcon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, 0, FALSE);
|
||||
}
|
||||
|
||||
BOOL LLTaskCallingCardBridge::isItemRenameable() const
|
||||
{
|
||||
@@ -1180,16 +1188,9 @@ public:
|
||||
const std::string& name) :
|
||||
LLTaskInvFVBridge(panel, uuid, name) {}
|
||||
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
//static BOOL enableIfCopyable( void* userdata );
|
||||
};
|
||||
|
||||
|
||||
LLUIImagePtr LLTaskScriptBridge::getIcon() const
|
||||
{
|
||||
return LLInventoryIcon::getIcon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE);
|
||||
}
|
||||
|
||||
class LLTaskLSLBridge : public LLTaskScriptBridge
|
||||
{
|
||||
public:
|
||||
@@ -1198,6 +1199,7 @@ public:
|
||||
const std::string& name) :
|
||||
LLTaskScriptBridge(panel, uuid, name) {}
|
||||
|
||||
virtual BOOL canOpenItem() const { return TRUE; }
|
||||
virtual void openItem();
|
||||
virtual BOOL removeItem();
|
||||
//virtual void buildContextMenu(LLMenuGL& menu);
|
||||
@@ -1273,22 +1275,8 @@ public:
|
||||
const std::string& name,
|
||||
U32 flags = 0) :
|
||||
LLTaskInvFVBridge(panel, uuid, name, flags) {}
|
||||
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
};
|
||||
|
||||
|
||||
LLUIImagePtr LLTaskObjectBridge::getIcon() const
|
||||
{
|
||||
BOOL item_is_multi = FALSE;
|
||||
if ( mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS )
|
||||
{
|
||||
item_is_multi = TRUE;
|
||||
}
|
||||
|
||||
return LLInventoryIcon::getIcon(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT, 0, item_is_multi);
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLTaskNotecardBridge
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -1301,16 +1289,11 @@ public:
|
||||
const std::string& name) :
|
||||
LLTaskInvFVBridge(panel, uuid, name) {}
|
||||
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual BOOL canOpenItem() const { return TRUE; }
|
||||
virtual void openItem();
|
||||
virtual BOOL removeItem();
|
||||
};
|
||||
|
||||
LLUIImagePtr LLTaskNotecardBridge::getIcon() const
|
||||
{
|
||||
return LLInventoryIcon::getIcon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE);
|
||||
}
|
||||
|
||||
void LLTaskNotecardBridge::openItem()
|
||||
{
|
||||
if(LLPreview::show(mUUID))
|
||||
@@ -1367,16 +1350,11 @@ public:
|
||||
const std::string& name) :
|
||||
LLTaskInvFVBridge(panel, uuid, name) {}
|
||||
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual BOOL canOpenItem() const { return TRUE; }
|
||||
virtual void openItem();
|
||||
virtual BOOL removeItem();
|
||||
};
|
||||
|
||||
LLUIImagePtr LLTaskGestureBridge::getIcon() const
|
||||
{
|
||||
return LLInventoryIcon::getIcon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0, FALSE);
|
||||
}
|
||||
|
||||
void LLTaskGestureBridge::openItem()
|
||||
{
|
||||
if(LLPreview::show(mUUID))
|
||||
@@ -1419,16 +1397,11 @@ public:
|
||||
const std::string& name) :
|
||||
LLTaskInvFVBridge(panel, uuid, name) {}
|
||||
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual BOOL canOpenItem() const { return TRUE; }
|
||||
virtual void openItem();
|
||||
virtual BOOL removeItem();
|
||||
};
|
||||
|
||||
LLUIImagePtr LLTaskAnimationBridge::getIcon() const
|
||||
{
|
||||
return LLInventoryIcon::getIcon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0, FALSE);
|
||||
}
|
||||
|
||||
void LLTaskAnimationBridge::openItem()
|
||||
{
|
||||
if(LLPreview::show(mUUID))
|
||||
@@ -1487,19 +1460,15 @@ public:
|
||||
LLTaskWearableBridge(LLPanelObjectInventory* panel,
|
||||
const LLUUID& uuid,
|
||||
const std::string& name,
|
||||
LLAssetType::EType asset_type,
|
||||
U32 flags) :
|
||||
LLTaskInvFVBridge(panel, uuid, name, flags), mAssetType(asset_type) {}
|
||||
LLTaskInvFVBridge(panel, uuid, name, flags) {}
|
||||
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
|
||||
protected:
|
||||
LLAssetType::EType mAssetType;
|
||||
};
|
||||
|
||||
LLUIImagePtr LLTaskWearableBridge::getIcon() const
|
||||
{
|
||||
return LLInventoryIcon::getIcon(mAssetType, LLInventoryType::IT_WEARABLE, mFlags, FALSE );
|
||||
return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE );
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -1521,7 +1490,6 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
|
||||
case LLAssetType::AT_TEXTURE:
|
||||
new_bridge = new LLTaskTextureBridge(panel,
|
||||
object_id,
|
||||
item->getInventoryType(),
|
||||
object_name);
|
||||
break;
|
||||
case LLAssetType::AT_SOUND:
|
||||
@@ -1549,7 +1517,8 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
|
||||
case LLAssetType::AT_OBJECT:
|
||||
new_bridge = new LLTaskObjectBridge(panel,
|
||||
object_id,
|
||||
object_name);
|
||||
object_name,
|
||||
itemflags);
|
||||
break;
|
||||
case LLAssetType::AT_NOTECARD:
|
||||
new_bridge = new LLTaskNotecardBridge(panel,
|
||||
@@ -1571,7 +1540,6 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
|
||||
new_bridge = new LLTaskWearableBridge(panel,
|
||||
object_id,
|
||||
object_name,
|
||||
type,
|
||||
itemflags);
|
||||
break;
|
||||
case LLAssetType::AT_CATEGORY:
|
||||
@@ -1650,7 +1618,7 @@ void LLPanelObjectInventory::reset()
|
||||
setBorderVisible(FALSE);
|
||||
|
||||
LLRect dummy_rect(0, 1, 1, 0);
|
||||
mFolders = new LLFolderView(std::string("task inventory"), NULL, dummy_rect, getTaskUUID(), this);
|
||||
mFolders = new LLFolderView(std::string("task inventory"), NULL, dummy_rect, getTaskUUID(), this, LLTaskInvFVBridge::createObjectBridge(this, NULL));
|
||||
// this ensures that we never say "searching..." or "no items found"
|
||||
mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
|
||||
|
||||
|
||||
@@ -37,12 +37,6 @@ class LLFolderView;
|
||||
class LLFolderViewFolder;
|
||||
class LLViewerObject;
|
||||
|
||||
// Utility function to hide all entries except those in the list
|
||||
class LLMenuGL;
|
||||
void hide_context_entries(LLMenuGL& menu,
|
||||
const std::vector<std::string> &entries_to_show,
|
||||
const std::vector<std::string> &disabled_entries);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLPanelObjectInventory
|
||||
//
|
||||
|
||||
@@ -1882,6 +1882,13 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
|
||||
{
|
||||
LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
|
||||
*new_param = *this;
|
||||
return new_param;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// apply()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -433,6 +433,8 @@ public:
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLPolySkeletalDistortionInfo *info);
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||
/*virtual*/ void apply( ESex sex );
|
||||
|
||||
@@ -446,10 +446,10 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
|
||||
}
|
||||
|
||||
// If we have a vertex mask, just remove it. It will be recreated.
|
||||
if (param->undoMask(TRUE))
|
||||
/*if (param->undoMask(TRUE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}*/
|
||||
|
||||
LLVector4 *mesh_coords = mesh->getWritableCoords();
|
||||
LLVector4 *mesh_normals = mesh->getWritableNormals();
|
||||
@@ -630,6 +630,13 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* LLPolyMorphTarget::cloneParam(LLWearable* wearable) const
|
||||
{
|
||||
LLPolyMorphTarget *new_param = new LLPolyMorphTarget(mMesh);
|
||||
*new_param = *this;
|
||||
return new_param;
|
||||
}
|
||||
|
||||
#if 0 // obsolete
|
||||
//-----------------------------------------------------------------------------
|
||||
// parseData()
|
||||
@@ -876,32 +883,10 @@ void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3
|
||||
else
|
||||
{
|
||||
// remove effect of previous mask
|
||||
undoMask(FALSE);
|
||||
}
|
||||
F32 *maskWeights = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL;
|
||||
|
||||
mLastWeight = 0.f;
|
||||
|
||||
mVertMask->generateMask(maskTextureData, width, height, num_components, invert, clothing_weights);
|
||||
|
||||
apply(mLastSex);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// undoMask()
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL LLPolyMorphTarget::undoMask(BOOL delete_mask)
|
||||
{
|
||||
if (!mVertMask)
|
||||
if (maskWeights)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// remove effect of previous mask
|
||||
|
||||
LLVector4 *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL;
|
||||
|
||||
F32 *mask_weights = mVertMask->getMorphMaskWeights();
|
||||
|
||||
LLVector4 *coords = mMesh->getWritableCoords();
|
||||
LLVector3 *scaled_normals = mMesh->getScaledNormals();
|
||||
LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
|
||||
@@ -909,13 +894,7 @@ BOOL LLPolyMorphTarget::undoMask(BOOL delete_mask)
|
||||
|
||||
for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++)
|
||||
{
|
||||
F32 mask_weight = 1.f;
|
||||
if (mask_weights)
|
||||
{
|
||||
mask_weight = mask_weights[vert];
|
||||
}
|
||||
|
||||
F32 lastMaskWeight = mLastWeight * mask_weights[vert];
|
||||
F32 lastMaskWeight = mLastWeight * maskWeights[vert];
|
||||
S32 out_vert = mMorphData->mVertexIndices[vert];
|
||||
|
||||
// remove effect of existing masked morph
|
||||
@@ -933,18 +912,15 @@ BOOL LLPolyMorphTarget::undoMask(BOOL delete_mask)
|
||||
clothing_weight->mV[VZ] -= clothing_offset.mV[VZ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set last weight to 0, since we've removed the effect of this morph
|
||||
mLastWeight = 0.f;
|
||||
|
||||
if (delete_mask)
|
||||
{
|
||||
delete mVertMask;
|
||||
mVertMask = NULL;
|
||||
addPendingMorphMask();
|
||||
}
|
||||
mVertMask->generateMask(maskTextureData, width, height, num_components, invert, clothing_weights);
|
||||
|
||||
return TRUE;
|
||||
apply(mLastSex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -159,6 +159,8 @@ public:
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLPolyMorphTargetInfo *info);
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||
/*virtual*/ void apply( ESex sex );
|
||||
@@ -172,7 +174,6 @@ public:
|
||||
/*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
|
||||
|
||||
void applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert);
|
||||
BOOL undoMask(BOOL delete_mask);
|
||||
void addPendingMorphMask() { mNumMorphMasksPending++; }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -458,9 +458,10 @@ void LLPreview::onBtnCopyToInv(void* userdata)
|
||||
// Copy to inventory
|
||||
if (self->mNotecardInventoryID.notNull())
|
||||
{
|
||||
copy_inventory_from_notecard(self->mObjectID,
|
||||
self->mNotecardInventoryID,
|
||||
item);
|
||||
copy_inventory_from_notecard(LLUUID::null,
|
||||
self->mObjectID,
|
||||
self->mNotecardInventoryID,
|
||||
item);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -484,7 +484,7 @@ void LLPreviewNotecard::onClickGetItems(void* user_data)
|
||||
LLInventoryItem* item = static_cast<LLInventoryItem*>(*iter);
|
||||
if(use_caps)
|
||||
{
|
||||
copy_inventory_from_notecard(preview->getObjectID(), preview->getNotecardItemID(), item, 0);
|
||||
copy_inventory_from_notecard(LLUUID::null, preview->getObjectID(), preview->getNotecardItemID(), item, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -206,6 +206,7 @@
|
||||
#include "llagentlanguage.h"
|
||||
#include "llwearable.h"
|
||||
#include "llinventorybridge.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llsocks5.h"
|
||||
#include "jcfloaterareasearch.h"
|
||||
|
||||
@@ -258,6 +259,7 @@ static BOOL gSkipOptionalUpdate = FALSE;
|
||||
static bool gGotUseCircuitCodeAck = false;
|
||||
static std::string sInitialOutfit;
|
||||
static std::string sInitialOutfitGender; // "male" or "female"
|
||||
static boost::signals2::connection sWearablesLoadedCon;
|
||||
|
||||
static bool gUseCircuitCallbackCalled = false;
|
||||
|
||||
@@ -2870,23 +2872,8 @@ bool idle_startup()
|
||||
LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender );
|
||||
}
|
||||
|
||||
display_startup();
|
||||
// We now have an inventory skeleton, so if this is a user's first
|
||||
// login, we can start setting up their clothing and avatar
|
||||
// appearance. This helps to avoid the generic "Ruth" avatar in
|
||||
// the orientation island tutorial experience. JC
|
||||
if (gAgent.isFirstLogin()
|
||||
&& !sInitialOutfit.empty() // registration set up an outfit
|
||||
&& !sInitialOutfitGender.empty() // and a gender
|
||||
&& gAgentAvatarp // can't wear clothes without object
|
||||
&& !gAgent.isGenderChosen() ) // nothing already loading
|
||||
{
|
||||
// Start loading the wearables, textures, gestures
|
||||
LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender );
|
||||
}
|
||||
|
||||
display_startup();
|
||||
|
||||
|
||||
// wait precache-delay and for agent's avatar or a lot longer.
|
||||
if(((timeout_frac > 1.f) && isAgentAvatarValid())
|
||||
|| (timeout_frac > 3.f))
|
||||
@@ -3573,7 +3560,7 @@ void register_viewer_callbacks(LLMessageSystem* msg)
|
||||
msg->setHandlerFuncFast(_PREHASH_AvatarAnimation, process_avatar_animation);
|
||||
msg->setHandlerFuncFast(_PREHASH_AvatarAppearance, process_avatar_appearance);
|
||||
msg->setHandlerFunc("AgentCachedTextureResponse", LLAgent::processAgentCachedTextureResponse);
|
||||
msg->setHandlerFunc("RebakeAvatarTextures", LLVOAvatar::processRebakeAvatarTextures);
|
||||
msg->setHandlerFunc("RebakeAvatarTextures", LLVOAvatarSelf::processRebakeAvatarTextures);
|
||||
msg->setHandlerFuncFast(_PREHASH_CameraConstraint, process_camera_constraint);
|
||||
msg->setHandlerFuncFast(_PREHASH_AvatarSitResponse, process_avatar_sit_response);
|
||||
msg->setHandlerFunc("SetFollowCamProperties", process_set_follow_cam_properties);
|
||||
@@ -3771,44 +3758,79 @@ bool callback_choose_gender(const LLSD& notification, const LLSD& response)
|
||||
void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
|
||||
const std::string& gender_name )
|
||||
{
|
||||
S32 gender = 0;
|
||||
std::string gestures;
|
||||
lldebugs << "starting" << llendl;
|
||||
|
||||
// Not going through the processAgentInitialWearables path, so need to set this here.
|
||||
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true);
|
||||
// Initiate creation of COF, since we're also bypassing that.
|
||||
gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
|
||||
|
||||
ESex gender;
|
||||
if (gender_name == "male")
|
||||
{
|
||||
gender = OPT_MALE;
|
||||
gestures = MALE_GESTURES_FOLDER;
|
||||
lldebugs << "male" << llendl;
|
||||
gender = SEX_MALE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gender = OPT_FEMALE;
|
||||
gestures = FEMALE_GESTURES_FOLDER;
|
||||
lldebugs << "female" << llendl;
|
||||
gender = SEX_FEMALE;
|
||||
}
|
||||
|
||||
if (!isAgentAvatarValid())
|
||||
{
|
||||
llwarns << "Trying to load an initial outfit for an invalid agent avatar" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
gAgentAvatarp->setSex(gender);
|
||||
|
||||
// try to find the outfit - if not there, create some default
|
||||
// wearables.
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
LLNameCategoryCollector has_name(outfit_folder_name);
|
||||
gInventory.collectDescendentsIf(LLUUID::null,
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
has_name);
|
||||
if (0 == cat_array.count())
|
||||
LLUUID cat_id = findDescendentCategoryIDByName(
|
||||
gInventory.getLibraryRootFolderID(),
|
||||
outfit_folder_name);
|
||||
if (cat_id.isNull())
|
||||
{
|
||||
gAgentWearables.createStandardWearables(gender);
|
||||
lldebugs << "standard wearables" << llendl;
|
||||
gAgentWearables.createStandardWearables();
|
||||
}
|
||||
else
|
||||
{
|
||||
wear_outfit_by_name(outfit_folder_name);
|
||||
sWearablesLoadedCon = gAgentWearables.addLoadedCallback(LLStartUp::saveInitialOutfit);
|
||||
|
||||
bool do_copy = true;
|
||||
bool do_append = false;
|
||||
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
|
||||
LLAppearanceMgr::instance().wearInventoryCategory(cat, do_copy, do_append);
|
||||
lldebugs << "initial outfit category id: " << cat_id << llendl;
|
||||
}
|
||||
wear_outfit_by_name(gestures);
|
||||
wear_outfit_by_name(COMMON_GESTURES_FOLDER);
|
||||
|
||||
// This is really misnamed -- it means we have started loading
|
||||
// an outfit/shape that will give the avatar a gender eventually. JC
|
||||
gAgent.setGenderChosen(TRUE);
|
||||
}
|
||||
|
||||
//static
|
||||
void LLStartUp::saveInitialOutfit()
|
||||
{
|
||||
if (sInitialOutfit.empty()) {
|
||||
lldebugs << "sInitialOutfit is empty" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sWearablesLoadedCon.connected())
|
||||
{
|
||||
lldebugs << "sWearablesLoadedCon is connected, disconnecting" << llendl;
|
||||
sWearablesLoadedCon.disconnect();
|
||||
}
|
||||
lldebugs << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << llendl;
|
||||
LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false);
|
||||
}
|
||||
|
||||
std::string& LLStartUp::getInitialOutfitName()
|
||||
{
|
||||
return sInitialOutfit;
|
||||
}
|
||||
|
||||
// Loads a bitmap to display during load
|
||||
|
||||
@@ -110,6 +110,11 @@ public:
|
||||
static void loadInitialOutfit( const std::string& outfit_folder_name,
|
||||
const std::string& gender_name );
|
||||
|
||||
//save loaded initial outfit into My Outfits category
|
||||
static void saveInitialOutfit();
|
||||
|
||||
static std::string& getInitialOutfitName();
|
||||
|
||||
// Load MD5 of user's password from local disk file.
|
||||
static std::string loadPasswordFromDisk();
|
||||
|
||||
|
||||
152
indra/newview/lltexglobalcolor.cpp
Normal file
152
indra/newview/lltexglobalcolor.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* @file lltexlayerglobalcolor.cpp
|
||||
* @brief Color for texture layers.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llagent.h"
|
||||
#include "lltexlayer.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llwearable.h"
|
||||
#include "lltexglobalcolor.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexGlobalColor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LLTexGlobalColor::LLTexGlobalColor(LLVOAvatar* avatar)
|
||||
:
|
||||
mAvatar(avatar),
|
||||
mInfo(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLTexGlobalColor::~LLTexGlobalColor()
|
||||
{
|
||||
// mParamColorList are LLViewerVisualParam's and get deleted with ~LLCharacter()
|
||||
//std::for_each(mParamColorList.begin(), mParamColorList.end(), DeletePointer());
|
||||
}
|
||||
|
||||
BOOL LLTexGlobalColor::setInfo(LLTexGlobalColorInfo *info)
|
||||
{
|
||||
llassert(mInfo == NULL);
|
||||
mInfo = info;
|
||||
//mID = info->mID; // No ID
|
||||
|
||||
mParamGlobalColorList.reserve(mInfo->mParamColorInfoList.size());
|
||||
for (param_color_info_list_t::iterator iter = mInfo->mParamColorInfoList.begin();
|
||||
iter != mInfo->mParamColorInfoList.end();
|
||||
iter++)
|
||||
{
|
||||
LLTexParamGlobalColor* param_color = new LLTexParamGlobalColor(this);
|
||||
if (!param_color->setInfo(*iter, TRUE))
|
||||
{
|
||||
mInfo = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
mParamGlobalColorList.push_back(param_color);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LLColor4 LLTexGlobalColor::getColor() const
|
||||
{
|
||||
// Sum of color params
|
||||
if (mParamGlobalColorList.empty())
|
||||
return LLColor4(1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
LLColor4 net_color(0.f, 0.f, 0.f, 0.f);
|
||||
LLTexLayer::calculateTexLayerColor(mParamGlobalColorList, net_color);
|
||||
return net_color;
|
||||
}
|
||||
|
||||
const std::string& LLTexGlobalColor::getName() const
|
||||
{
|
||||
return mInfo->mName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexParamGlobalColor
|
||||
//-----------------------------------------------------------------------------
|
||||
LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) :
|
||||
LLTexLayerParamColor(tex_global_color->getAvatar()),
|
||||
mTexGlobalColor(tex_global_color)
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* LLTexParamGlobalColor::cloneParam(LLWearable* wearable) const
|
||||
{
|
||||
LLTexParamGlobalColor *new_param = new LLTexParamGlobalColor(mTexGlobalColor);
|
||||
*new_param = *this;
|
||||
return new_param;
|
||||
}
|
||||
|
||||
void LLTexParamGlobalColor::onGlobalColorChanged(bool upload_bake)
|
||||
{
|
||||
mAvatar->onGlobalColorChanged(mTexGlobalColor, upload_bake);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexGlobalColorInfo
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LLTexGlobalColorInfo::LLTexGlobalColorInfo()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LLTexGlobalColorInfo::~LLTexGlobalColorInfo()
|
||||
{
|
||||
for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer());
|
||||
}
|
||||
|
||||
BOOL LLTexGlobalColorInfo::parseXml(LLXmlTreeNode* node)
|
||||
{
|
||||
// name attribute
|
||||
static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
|
||||
if (!node->getFastAttributeString(name_string, mName))
|
||||
{
|
||||
llwarns << "<global_color> element is missing name attribute." << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
// <param> sub-element
|
||||
for (LLXmlTreeNode* child = node->getChildByName("param");
|
||||
child;
|
||||
child = node->getNextNamedChild())
|
||||
{
|
||||
if (child->getChildByName("param_color"))
|
||||
{
|
||||
// <param><param_color/></param>
|
||||
LLTexLayerParamColorInfo* info = new LLTexLayerParamColorInfo();
|
||||
if (!info->parseXml(child))
|
||||
{
|
||||
delete info;
|
||||
return FALSE;
|
||||
}
|
||||
mParamColorInfoList.push_back(info);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
83
indra/newview/lltexglobalcolor.h
Normal file
83
indra/newview/lltexglobalcolor.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @file lltexglobalcolor.h
|
||||
* @brief This is global texture color info used by llvoavatar.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLTEXGLOBALCOLOR_H
|
||||
#define LL_LLTEXGLOBALCOLOR_H
|
||||
|
||||
#include "lltexlayer.h"
|
||||
#include "lltexlayerparams.h"
|
||||
|
||||
class LLVOAvatar;
|
||||
class LLWearable;
|
||||
class LLTexGlobalColorInfo;
|
||||
|
||||
class LLTexGlobalColor
|
||||
{
|
||||
public:
|
||||
LLTexGlobalColor( LLVOAvatar* avatar );
|
||||
~LLTexGlobalColor();
|
||||
|
||||
LLTexGlobalColorInfo* getInfo() const { return mInfo; }
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLTexGlobalColorInfo *info);
|
||||
|
||||
LLVOAvatar* getAvatar() const { return mAvatar; }
|
||||
LLColor4 getColor() const;
|
||||
const std::string& getName() const;
|
||||
|
||||
private:
|
||||
param_color_list_t mParamGlobalColorList;
|
||||
LLVOAvatar* mAvatar; // just backlink, don't LLPointer
|
||||
LLTexGlobalColorInfo *mInfo;
|
||||
};
|
||||
|
||||
// Used by llvoavatar to determine skin/eye/hair color.
|
||||
class LLTexGlobalColorInfo
|
||||
{
|
||||
friend class LLTexGlobalColor;
|
||||
public:
|
||||
LLTexGlobalColorInfo();
|
||||
~LLTexGlobalColorInfo();
|
||||
|
||||
BOOL parseXml(LLXmlTreeNode* node);
|
||||
|
||||
private:
|
||||
param_color_info_list_t mParamColorInfoList;
|
||||
std::string mName;
|
||||
};
|
||||
|
||||
class LLTexParamGlobalColor : public LLTexLayerParamColor
|
||||
{
|
||||
public:
|
||||
LLTexParamGlobalColor(LLTexGlobalColor *tex_color);
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
|
||||
protected:
|
||||
/*virtual*/ void onGlobalColorChanged(bool upload_bake);
|
||||
private:
|
||||
LLTexGlobalColor* mTexGlobalColor;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,524 +34,354 @@
|
||||
#define LL_LLTEXLAYER_H
|
||||
|
||||
#include <deque>
|
||||
#include "llassetstorage.h"
|
||||
#include "lldynamictexture.h"
|
||||
#include "llrect.h"
|
||||
#include "llstring.h"
|
||||
#include "lluuid.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llviewervisualparam.h"
|
||||
#include "llvoavatardefines.h"
|
||||
#include "llwearable.h"
|
||||
#include "v4color.h"
|
||||
#include "llfloater.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "lltexlayerparams.h"
|
||||
#include "lllocaltextureobject.h"
|
||||
|
||||
class LLTexLayerSetInfo;
|
||||
class LLTexLayerSet;
|
||||
class LLTexLayerInfo;
|
||||
class LLTexLayer;
|
||||
class LLViewerTexture;
|
||||
class LLImageTGA;
|
||||
class LLTexGlobalColorInfo;
|
||||
class LLTexLayerParamAlphaInfo;
|
||||
class LLTexLayerParamAlpha;
|
||||
class LLTexParamColorInfo;
|
||||
class LLTexParamColor;
|
||||
class LLPolyMesh;
|
||||
class LLXmlTreeNode;
|
||||
class LLImageRaw;
|
||||
class LLPolyMorphTarget;
|
||||
class LLViewerTexture;
|
||||
|
||||
class LLTextureCtrl;
|
||||
class LLVOAvatar;
|
||||
class LLVOAvatarSelf;
|
||||
class LLImageTGA;
|
||||
class LLImageRaw;
|
||||
class LLXmlTreeNode;
|
||||
class LLTexLayerSet;
|
||||
class LLTexLayerSetInfo;
|
||||
class LLTexLayerInfo;
|
||||
class LLTexLayerSetBuffer;
|
||||
class LLWearable;
|
||||
class LLViewerVisualParam;
|
||||
|
||||
|
||||
enum EColorOperation
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLTexLayerInterface
|
||||
//
|
||||
// Interface class to generalize functionality shared by LLTexLayer
|
||||
// and LLTexLayerTemplate.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLTexLayerInterface
|
||||
{
|
||||
OP_ADD = 0,
|
||||
OP_MULTIPLY = 1,
|
||||
OP_BLEND = 2,
|
||||
OP_COUNT = 3 // Number of operations
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexLayerParamAlphaInfo
|
||||
//-----------------------------------------------------------------------------
|
||||
class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
|
||||
{
|
||||
friend class LLTexLayerParamAlpha;
|
||||
public:
|
||||
LLTexLayerParamAlphaInfo();
|
||||
/*virtual*/ ~LLTexLayerParamAlphaInfo() {};
|
||||
enum ERenderPass
|
||||
{
|
||||
RP_COLOR,
|
||||
RP_BUMP,
|
||||
RP_SHINE
|
||||
};
|
||||
|
||||
/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
|
||||
LLTexLayerInterface(LLTexLayerSet* const layer_set);
|
||||
LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable);
|
||||
virtual ~LLTexLayerInterface() {}
|
||||
|
||||
virtual BOOL render(S32 x, S32 y, S32 width, S32 height) = 0;
|
||||
virtual void deleteCaches() = 0;
|
||||
virtual BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) = 0;
|
||||
virtual BOOL isInvisibleAlphaMask() const = 0;
|
||||
|
||||
const LLTexLayerInfo* getInfo() const { return mInfo; }
|
||||
virtual BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // sets mInfo, calls initialization functions
|
||||
|
||||
const std::string& getName() const;
|
||||
const LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; }
|
||||
LLTexLayerSet* const getTexLayerSet() { return mTexLayerSet; }
|
||||
|
||||
void invalidateMorphMasks();
|
||||
virtual void setHasMorph(BOOL newval) { mHasMorph = newval; }
|
||||
BOOL hasMorph() const { return mHasMorph; }
|
||||
BOOL isMorphValid() const { return mMorphMasksValid; }
|
||||
|
||||
void requestUpdate();
|
||||
virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0;
|
||||
BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); }
|
||||
|
||||
ERenderPass getRenderPass() const;
|
||||
BOOL isVisibilityMask() const;
|
||||
|
||||
protected:
|
||||
std::string mStaticImageFileName;
|
||||
BOOL mMultiplyBlend;
|
||||
BOOL mSkipIfZeroWeight;
|
||||
F32 mDomain;
|
||||
};
|
||||
const std::string& getGlobalColor() const;
|
||||
LLViewerVisualParam* getVisualParamPtr(S32 index) const;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexParamColorInfo
|
||||
//-----------------------------------------------------------------------------
|
||||
class LLTexParamColorInfo : public LLViewerVisualParamInfo
|
||||
{
|
||||
friend class LLTexParamColor;
|
||||
|
||||
public:
|
||||
LLTexParamColorInfo();
|
||||
virtual ~LLTexParamColorInfo() {};
|
||||
BOOL parseXml( LLXmlTreeNode* node );
|
||||
|
||||
protected:
|
||||
enum { MAX_COLOR_VALUES = 20 };
|
||||
EColorOperation mOperation;
|
||||
LLColor4 mColors[MAX_COLOR_VALUES];
|
||||
S32 mNumColors;
|
||||
LLTexLayerSet* const mTexLayerSet;
|
||||
const LLTexLayerInfo* mInfo;
|
||||
BOOL mMorphMasksValid;
|
||||
BOOL mHasMorph;
|
||||
|
||||
// Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order.
|
||||
param_color_list_t mParamColorList;
|
||||
param_alpha_list_t mParamAlphaList;
|
||||
// mGlobalColor name stored in mInfo
|
||||
// mFixedColor value stored in mInfo
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexGlobalColorInfo
|
||||
//-----------------------------------------------------------------------------
|
||||
class LLTexGlobalColorInfo
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLTexLayerTemplate
|
||||
//
|
||||
// Only exists for llvoavatarself.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLTexLayerTemplate : public LLTexLayerInterface
|
||||
{
|
||||
friend class LLTexGlobalColor;
|
||||
public:
|
||||
LLTexGlobalColorInfo();
|
||||
~LLTexGlobalColorInfo();
|
||||
LLTexLayerTemplate(LLTexLayerSet* const layer_set);
|
||||
LLTexLayerTemplate(const LLTexLayerTemplate &layer);
|
||||
/*virtual*/ ~LLTexLayerTemplate();
|
||||
/*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height);
|
||||
/*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions
|
||||
/*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
|
||||
/*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
|
||||
/*virtual*/ void setHasMorph(BOOL newval);
|
||||
/*virtual*/ void deleteCaches();
|
||||
/*virtual*/ BOOL isInvisibleAlphaMask() const;
|
||||
protected:
|
||||
U32 updateWearableCache() const;
|
||||
LLTexLayer* getLayer(U32 i) const;
|
||||
private:
|
||||
typedef std::vector<LLWearable*> wearable_cache_t;
|
||||
mutable wearable_cache_t mWearableCache; // mutable b/c most get- require updating this cache
|
||||
};
|
||||
|
||||
BOOL parseXml(LLXmlTreeNode* node);
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLTexLayer
|
||||
//
|
||||
// A single texture layer. Only exists for llvoavatarself.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLTexLayer : public LLTexLayerInterface
|
||||
{
|
||||
public:
|
||||
LLTexLayer(LLTexLayerSet* const layer_set);
|
||||
LLTexLayer(const LLTexLayer &layer, LLWearable *wearable);
|
||||
LLTexLayer(const LLTexLayerTemplate &layer_template, LLLocalTextureObject *lto, LLWearable *wearable);
|
||||
/*virtual*/ ~LLTexLayer();
|
||||
|
||||
/*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions
|
||||
/*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height);
|
||||
|
||||
/*virtual*/ void deleteCaches();
|
||||
const U8* getAlphaData() const;
|
||||
|
||||
BOOL findNetColor(LLColor4* color) const;
|
||||
/*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
|
||||
/*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
|
||||
BOOL renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color);
|
||||
void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
|
||||
/*virtual*/ BOOL isInvisibleAlphaMask() const;
|
||||
|
||||
void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; }
|
||||
LLLocalTextureObject* getLTO() { return mLocalTextureObject; }
|
||||
|
||||
static void calculateTexLayerColor(const param_color_list_t ¶m_list, LLColor4 &net_color);
|
||||
protected:
|
||||
LLUUID getUUID() const;
|
||||
private:
|
||||
typedef std::map<U32, U8*> alpha_cache_t;
|
||||
alpha_cache_t mAlphaCache;
|
||||
LLLocalTextureObject* mLocalTextureObject;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLTexLayerSet
|
||||
//
|
||||
// An ordered set of texture layers that gets composited into a single texture.
|
||||
// Only exists for llvoavatarself.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLTexLayerSet
|
||||
{
|
||||
friend class LLTexLayerSetBuffer;
|
||||
public:
|
||||
LLTexLayerSet(LLVOAvatarSelf* const avatar);
|
||||
~LLTexLayerSet();
|
||||
|
||||
const LLTexLayerSetInfo* getInfo() const { return mInfo; }
|
||||
BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
|
||||
|
||||
BOOL render(S32 x, S32 y, S32 width, S32 height);
|
||||
void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
|
||||
|
||||
BOOL isBodyRegion(const std::string& region) const;
|
||||
LLTexLayerSetBuffer* getComposite();
|
||||
const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist.
|
||||
void requestUpdate();
|
||||
void requestUpload();
|
||||
void cancelUpload();
|
||||
void updateComposite();
|
||||
BOOL isLocalTextureDataAvailable() const;
|
||||
BOOL isLocalTextureDataFinal() const;
|
||||
void createComposite();
|
||||
void destroyComposite();
|
||||
void setUpdatesEnabled(BOOL b);
|
||||
BOOL getUpdatesEnabled() const { return mUpdatesEnabled; }
|
||||
void deleteCaches();
|
||||
void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
|
||||
void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
|
||||
BOOL isMorphValid() const;
|
||||
void invalidateMorphMasks();
|
||||
LLTexLayerInterface* findLayerByName(const std::string& name);
|
||||
void cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable);
|
||||
|
||||
protected:
|
||||
typedef std::vector<LLTexParamColorInfo *> color_info_list_t;
|
||||
color_info_list_t mColorInfoList;
|
||||
std::string mName;
|
||||
LLVOAvatarSelf* getAvatar() const { return mAvatar; }
|
||||
const std::string getBodyRegionName() const;
|
||||
BOOL hasComposite() const { return (mComposite.notNull()); }
|
||||
LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
|
||||
void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
|
||||
BOOL isVisible() const { return mIsVisible; }
|
||||
|
||||
static BOOL sHasCaches;
|
||||
|
||||
private:
|
||||
typedef std::vector<LLTexLayerInterface *> layer_list_t;
|
||||
layer_list_t mLayerList;
|
||||
layer_list_t mMaskLayerList;
|
||||
LLPointer<LLTexLayerSetBuffer> mComposite;
|
||||
LLVOAvatarSelf* const mAvatar; // note: backlink only; don't make this an LLPointer.
|
||||
BOOL mUpdatesEnabled;
|
||||
BOOL mIsVisible;
|
||||
|
||||
LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex;
|
||||
const LLTexLayerSetInfo* mInfo;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLTexLayerSetInfo
|
||||
// Containes shared layer set data
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Contains shared layer set data.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLTexLayerSetInfo
|
||||
{
|
||||
friend class LLTexLayerSet;
|
||||
public:
|
||||
LLTexLayerSetInfo();
|
||||
~LLTexLayerSetInfo();
|
||||
|
||||
BOOL parseXml(LLXmlTreeNode* node);
|
||||
|
||||
protected:
|
||||
void createVisualParams(LLVOAvatar *avatar);
|
||||
private:
|
||||
std::string mBodyRegion;
|
||||
S32 mWidth;
|
||||
S32 mHeight;
|
||||
std::string mStaticAlphaFileName;
|
||||
BOOL mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName)
|
||||
|
||||
BOOL mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName)
|
||||
typedef std::vector<LLTexLayerInfo*> layer_info_list_t;
|
||||
layer_info_list_t mLayerInfoList;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexLayerInfo
|
||||
//-----------------------------------------------------------------------------
|
||||
enum ERenderPass
|
||||
{
|
||||
RP_COLOR,
|
||||
RP_BUMP,
|
||||
RP_SHINE
|
||||
};
|
||||
|
||||
class LLTexLayerInfo
|
||||
{
|
||||
friend class LLTexLayer;
|
||||
public:
|
||||
LLTexLayerInfo();
|
||||
~LLTexLayerInfo();
|
||||
|
||||
BOOL parseXml(LLXmlTreeNode* node);
|
||||
|
||||
protected:
|
||||
std::string mName;
|
||||
|
||||
BOOL mWriteAllChannels; // Don't use masking. Just write RGBA into buffer,
|
||||
ERenderPass mRenderPass;
|
||||
|
||||
std::string mGlobalColor;
|
||||
LLColor4 mFixedColor;
|
||||
|
||||
S32 mLocalTexture;
|
||||
std::string mStaticImageFileName;
|
||||
BOOL mStaticImageIsMask;
|
||||
BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask
|
||||
BOOL mIsVisibilityMask;
|
||||
|
||||
typedef std::vector<std::pair<std::string,BOOL> > morph_name_list_t;
|
||||
morph_name_list_t mMorphNameList;
|
||||
|
||||
typedef std::vector<LLTexParamColorInfo*> color_info_list_t;
|
||||
color_info_list_t mColorInfoList;
|
||||
|
||||
typedef std::vector<LLTexLayerParamAlphaInfo*> alpha_info_list_t;
|
||||
alpha_info_list_t mAlphaInfoList;
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLTexLayerSetBuffer
|
||||
//
|
||||
// The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one.
|
||||
//-----------------------------------------------------------------------------
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLTexLayerSetBuffer : public LLViewerDynamicTexture
|
||||
{
|
||||
LOG_CLASS(LLTexLayerSetBuffer);
|
||||
|
||||
public:
|
||||
LLTexLayerSetBuffer(LLTexLayerSet* owner, S32 width, S32 height);
|
||||
LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
|
||||
virtual ~LLTexLayerSetBuffer();
|
||||
|
||||
virtual void preRender(BOOL clear_depth);
|
||||
virtual void postRender(BOOL success);
|
||||
virtual BOOL render();
|
||||
BOOL updateImmediate();
|
||||
bool isInitialized(void) const;
|
||||
BOOL needsRender();
|
||||
void requestUpdate();
|
||||
void requestUpload();
|
||||
void requestDelayedUpload(U64 delay_usec);
|
||||
void cancelUpload();
|
||||
BOOL uploadPending() { return mUploadPending; }
|
||||
BOOL render( S32 x, S32 y, S32 width, S32 height );
|
||||
void readBackAndUpload();
|
||||
|
||||
static void onTextureUploadComplete( const LLUUID& uuid,
|
||||
void* userdata,
|
||||
S32 result, LLExtStat ext_status);
|
||||
public:
|
||||
/*virtual*/ S8 getType() const;
|
||||
BOOL isInitialized(void) const;
|
||||
static void dumpTotalByteCount();
|
||||
|
||||
virtual S8 getType() const ;
|
||||
virtual void restoreGLTexture() ;
|
||||
virtual void destroyGLTexture() ;
|
||||
|
||||
private:
|
||||
const std::string dumpTextureInfo() const;
|
||||
virtual void restoreGLTexture();
|
||||
virtual void destroyGLTexture();
|
||||
protected:
|
||||
void pushProjection() const;
|
||||
void popProjection() const;
|
||||
BOOL needsUploadNow() const;
|
||||
|
||||
private:
|
||||
BOOL mNeedsUpdate;
|
||||
BOOL mNeedsUpload;
|
||||
BOOL mUploadPending;
|
||||
LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit)
|
||||
S32 mUploadFailCount;
|
||||
U64 mUploadAfter; // delay upload until after this time (in microseconds)
|
||||
LLTexLayerSet* mTexLayerSet;
|
||||
|
||||
LLTexLayerSet* const mTexLayerSet;
|
||||
static S32 sGLByteCount;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexLayerSet
|
||||
// An ordered set of texture layers that get composited into a single texture.
|
||||
//-----------------------------------------------------------------------------
|
||||
class LLTexLayerSet
|
||||
{
|
||||
friend class LLTexLayerSetBuffer;
|
||||
//--------------------------------------------------------------------
|
||||
// Render
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
LLTexLayerSet( LLVOAvatar* avatar );
|
||||
~LLTexLayerSet();
|
||||
|
||||
//BOOL parseData(LLXmlTreeNode* node);
|
||||
LLTexLayerSetInfo* getInfo() const { return mInfo; }
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLTexLayerSetInfo *info);
|
||||
/*virtual*/ BOOL needsRender();
|
||||
protected:
|
||||
BOOL render(S32 x, S32 y, S32 width, S32 height);
|
||||
virtual void preRender(BOOL clear_depth);
|
||||
virtual void postRender(BOOL success);
|
||||
virtual BOOL render();
|
||||
|
||||
BOOL render( S32 x, S32 y, S32 width, S32 height );
|
||||
void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
|
||||
BOOL isBodyRegion( const std::string& region ) { return mInfo->mBodyRegion == region; }
|
||||
LLTexLayerSetBuffer* getComposite();
|
||||
void requestUpdate();
|
||||
//--------------------------------------------------------------------
|
||||
// Uploads
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void requestUpload();
|
||||
void cancelUpload();
|
||||
LLVOAvatar* getAvatar() { return mAvatar; }
|
||||
void updateComposite();
|
||||
BOOL isLocalTextureDataAvailable();
|
||||
BOOL isLocalTextureDataFinal();
|
||||
void createComposite();
|
||||
void destroyComposite();
|
||||
void setUpdatesEnabled( BOOL b );
|
||||
BOOL getUpdatesEnabled() { return mUpdatesEnabled; }
|
||||
void deleteCaches();
|
||||
void gatherAlphaMasks(U8 *data, S32 width, S32 height);
|
||||
void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
|
||||
const std::string getBodyRegion() { return mInfo->mBodyRegion; }
|
||||
BOOL hasComposite() { return (mComposite.notNull()); }
|
||||
LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
|
||||
void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
|
||||
BOOL isVisible() const { return mIsVisible; }
|
||||
|
||||
public:
|
||||
static BOOL sHasCaches;
|
||||
|
||||
BOOL uploadNeeded() const; // We need to upload a new texture
|
||||
BOOL uploadInProgress() const; // We have started uploading a new texture and are awaiting the result
|
||||
BOOL uploadPending() const; // We are expecting a new texture to be uploaded at some point
|
||||
static void onTextureUploadComplete(const LLUUID& uuid,
|
||||
void* userdata,
|
||||
S32 result, LLExtStat ext_status);
|
||||
protected:
|
||||
typedef std::vector<LLTexLayer *> layer_list_t;
|
||||
layer_list_t mLayerList;
|
||||
layer_list_t mMaskLayerList;
|
||||
LLPointer<LLTexLayerSetBuffer> mComposite;
|
||||
// Backlink only; don't make this an LLPointer.
|
||||
LLVOAvatar* mAvatar;
|
||||
BOOL mUpdatesEnabled;
|
||||
BOOL mIsVisible;
|
||||
BOOL isReadyToUpload() const;
|
||||
void doUpload(); // Does a read back and upload.
|
||||
void conditionalRestartUploadTimer();
|
||||
private:
|
||||
BOOL mNeedsUpload; // Whether we need to send our baked textures to the server
|
||||
U32 mNumLowresUploads; // Number of times we've sent a lowres version of our baked textures to the server
|
||||
BOOL mUploadPending; // Whether we have received back the new baked textures
|
||||
LLUUID mUploadID; // The current upload process (null if none).
|
||||
LLFrameTimer mNeedsUploadTimer; // Tracks time since upload was requested and performed.
|
||||
S32 mUploadFailCount; // Number of consecutive upload failures
|
||||
LLFrameTimer mUploadRetryTimer; // Tracks time since last upload failure.
|
||||
|
||||
LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex;
|
||||
|
||||
LLTexLayerSetInfo *mInfo;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexLayer
|
||||
// A single texture layer
|
||||
//-----------------------------------------------------------------------------
|
||||
class LLTexLayer
|
||||
{
|
||||
//--------------------------------------------------------------------
|
||||
// Updates
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
LLTexLayer( LLTexLayerSet* layer_set );
|
||||
~LLTexLayer();
|
||||
|
||||
//BOOL parseData(LLXmlTreeNode* node);
|
||||
LLTexLayerInfo* getInfo() const { return mInfo; }
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLTexLayerInfo *info);
|
||||
|
||||
BOOL render( S32 x, S32 y, S32 width, S32 height );
|
||||
void requestUpdate();
|
||||
LLTexLayerSet* getTexLayerSet() { return mTexLayerSet; }
|
||||
|
||||
const std::string& getName() { return mInfo->mName; }
|
||||
|
||||
void addMaskedMorph(LLPolyMorphTarget* morph_target, BOOL invert);
|
||||
void deleteCaches();
|
||||
U8* getAlphaData();
|
||||
void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
|
||||
|
||||
void invalidateMorphMasks();
|
||||
ERenderPass getRenderPass() { return mInfo->mRenderPass; }
|
||||
const std::string& getGlobalColor() { return mInfo->mGlobalColor; }
|
||||
BOOL findNetColor( LLColor4* color );
|
||||
BOOL renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 in_components, S32 width, S32 height, BOOL is_mask );
|
||||
BOOL renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4* colorp );
|
||||
BOOL hasAlphaParams() { return (!mParamAlphaList.empty());}
|
||||
BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height);
|
||||
BOOL isVisibilityMask() const;
|
||||
BOOL isInvisibleAlphaMask();
|
||||
|
||||
BOOL requestUpdateImmediate();
|
||||
protected:
|
||||
LLTexLayerSet* mTexLayerSet;
|
||||
LLPointer<LLImageRaw> mStaticImageRaw;
|
||||
|
||||
// Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order.
|
||||
typedef std::vector<LLTexParamColor *> color_list_t;
|
||||
color_list_t mParamColorList;
|
||||
// mGlobalColor name stored in mInfo
|
||||
// mFixedColor value stored in mInfo
|
||||
|
||||
typedef std::vector<LLTexLayerParamAlpha *> alpha_list_t;
|
||||
alpha_list_t mParamAlphaList;
|
||||
|
||||
|
||||
typedef std::deque<LLVOAvatar::LLMaskedMorph> morph_list_t;
|
||||
morph_list_t mMaskedMorphs;
|
||||
typedef std::map<U32, U8*> alpha_cache_t;
|
||||
alpha_cache_t mAlphaCache;
|
||||
BOOL mMorphMasksValid;
|
||||
BOOL mStaticImageInvalid;
|
||||
|
||||
LLTexLayerInfo *mInfo;
|
||||
BOOL isReadyToUpdate() const;
|
||||
void doUpdate();
|
||||
void restartUpdateTimer();
|
||||
private:
|
||||
BOOL mNeedsUpdate; // Whether we need to locally update our baked textures
|
||||
U32 mNumLowresUpdates; // Number of times we've locally updated with lowres version of our baked textures
|
||||
LLFrameTimer mNeedsUpdateTimer; // Tracks time since update was requested and performed.
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexLayerParamAlpha
|
||||
//-----------------------------------------------------------------------------
|
||||
class LLTexLayerParamAlpha : public LLViewerVisualParam
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLTexLayerStaticImageList
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
|
||||
{
|
||||
public:
|
||||
LLTexLayerParamAlpha( LLTexLayer* layer );
|
||||
/*virtual*/ ~LLTexLayerParamAlpha();
|
||||
|
||||
// Special: These functions are overridden by child classes
|
||||
LLTexLayerParamAlphaInfo* getInfo() const { return (LLTexLayerParamAlphaInfo*)mInfo; }
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLTexLayerParamAlphaInfo *info);
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||
/*virtual*/ void apply( ESex avatar_sex ) {}
|
||||
/*virtual*/ void setWeight(F32 weight, BOOL set_by_user);
|
||||
/*virtual*/ void setAnimationTarget(F32 target_value, BOOL set_by_user);
|
||||
/*virtual*/ void animate(F32 delta, BOOL set_by_user);
|
||||
|
||||
// LLViewerVisualParam Virtual functions
|
||||
/*virtual*/ F32 getTotalDistortion() { return 1.f; }
|
||||
/*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
|
||||
/*virtual*/ F32 getMaxDistortion() { return 3.f; }
|
||||
/*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f);}
|
||||
/*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
|
||||
/*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
|
||||
|
||||
// New functions
|
||||
BOOL render( S32 x, S32 y, S32 width, S32 height );
|
||||
BOOL getSkip();
|
||||
void deleteCaches();
|
||||
LLTexLayer* getTexLayer() { return mTexLayer; }
|
||||
BOOL getMultiplyBlend() { return getInfo()->mMultiplyBlend; }
|
||||
|
||||
protected:
|
||||
LLPointer<LLViewerTexture> mCachedProcessedTexture;
|
||||
LLTexLayer* mTexLayer;
|
||||
LLPointer<LLImageTGA> mStaticImageTGA;
|
||||
LLPointer<LLImageRaw> mStaticImageRaw;
|
||||
BOOL mNeedsCreateTexture;
|
||||
BOOL mStaticImageInvalid;
|
||||
LLVector3 mAvgDistortionVec;
|
||||
F32 mCachedEffectiveWeight;
|
||||
|
||||
public:
|
||||
// Global list of instances for gathering statistics
|
||||
static void dumpCacheByteCount();
|
||||
static void getCacheByteCount( S32* gl_bytes );
|
||||
|
||||
typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t;
|
||||
static param_alpha_ptr_list_t sInstances;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexGlobalColor
|
||||
//-----------------------------------------------------------------------------
|
||||
class LLTexGlobalColor
|
||||
{
|
||||
public:
|
||||
LLTexGlobalColor( LLVOAvatar* avatar );
|
||||
~LLTexGlobalColor();
|
||||
|
||||
//BOOL parseData(LLXmlTreeNode* node);
|
||||
LLTexGlobalColorInfo* getInfo() const { return mInfo; }
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLTexGlobalColorInfo *info);
|
||||
|
||||
void requstUpdate();
|
||||
LLVOAvatar* getAvatar() { return mAvatar; }
|
||||
LLColor4 getColor();
|
||||
const std::string& getName() { return mInfo->mName; }
|
||||
|
||||
protected:
|
||||
typedef std::vector<LLTexParamColor *> param_list_t;
|
||||
param_list_t mParamList;
|
||||
LLVOAvatar* mAvatar; // just backlink, don't LLPointer
|
||||
|
||||
LLTexGlobalColorInfo *mInfo;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexParamColor
|
||||
//-----------------------------------------------------------------------------
|
||||
class LLTexParamColor : public LLViewerVisualParam
|
||||
{
|
||||
public:
|
||||
LLTexParamColor( LLTexGlobalColor* tex_color );
|
||||
LLTexParamColor( LLTexLayer* layer );
|
||||
/* virtual */ ~LLTexParamColor();
|
||||
|
||||
// Special: These functions are overridden by child classes
|
||||
LLTexParamColorInfo* getInfo() const { return (LLTexParamColorInfo*)mInfo; }
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLTexParamColorInfo *info);
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||
/*virtual*/ void apply( ESex avatar_sex ) {}
|
||||
/*virtual*/ void setWeight(F32 weight, BOOL set_by_user);
|
||||
/*virtual*/ void setAnimationTarget(F32 target_value, BOOL set_by_user);
|
||||
/*virtual*/ void animate(F32 delta, BOOL set_by_user);
|
||||
|
||||
|
||||
// LLViewerVisualParam Virtual functions
|
||||
/*virtual*/ F32 getTotalDistortion() { return 1.f; }
|
||||
/*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
|
||||
/*virtual*/ F32 getMaxDistortion() { return 3.f; }
|
||||
/*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f); }
|
||||
/*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
|
||||
/*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
|
||||
|
||||
// New functions
|
||||
LLColor4 getNetColor();
|
||||
EColorOperation getOperation() const { return getInfo()->mOperation; }
|
||||
|
||||
|
||||
protected:
|
||||
LLVector3 mAvgDistortionVec;
|
||||
LLTexGlobalColor* mTexGlobalColor; // either has mTexGlobalColor or mTexLayer as its parent
|
||||
LLTexLayer* mTexLayer;
|
||||
LLVOAvatar* mAvatar; // redundant, but simplifies the code (don't LLPointer)
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexStaticImageList
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class LLTexStaticImageList
|
||||
{
|
||||
public:
|
||||
LLTexStaticImageList();
|
||||
~LLTexStaticImageList();
|
||||
|
||||
LLImageRaw* getImageRaw( const std::string& file_name );
|
||||
LLViewerTexture* getTexture( const std::string& file_name, BOOL is_mask );
|
||||
LLImageTGA* getImageTGA( const std::string& file_name );
|
||||
|
||||
LLTexLayerStaticImageList();
|
||||
~LLTexLayerStaticImageList();
|
||||
LLViewerTexture* getTexture(const std::string& file_name, BOOL is_mask);
|
||||
LLImageTGA* getImageTGA(const std::string& file_name);
|
||||
void deleteCachedImages();
|
||||
void dumpByteCount() const;
|
||||
protected:
|
||||
BOOL loadImageRaw(const std::string& file_name, LLImageRaw* image_raw);
|
||||
|
||||
private:
|
||||
static LLStringTable sImageNames;
|
||||
|
||||
LLStringTable mImageNames;
|
||||
typedef std::map<const char*, LLPointer<LLViewerTexture> > texture_map_t;
|
||||
texture_map_t mStaticImageList;
|
||||
typedef std::map<const char*, LLPointer<LLImageTGA> > image_tga_map_t;
|
||||
image_tga_map_t mStaticImageListTGA;
|
||||
public:
|
||||
S32 mGLBytes;
|
||||
S32 mTGABytes;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLBakedUploadData
|
||||
//
|
||||
// Used by LLTexLayerSetBuffer for a callback.
|
||||
|
||||
// For DEV-DEV-31590, "Heap corruption and crash after outfit
|
||||
// changes", added the mLayerSet member. The current
|
||||
// LLTexLayerSetBuffer can be found by querying mLayerSet->mComposite,
|
||||
// but we still store the original mLayerSetBuffer here so we can
|
||||
// detect when an upload is out of date. This prevents a memory
|
||||
// stomp. See LLTexLayerSetBuffer::onTextureUploadComplete() for usage.
|
||||
class LLBakedUploadData
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
struct LLBakedUploadData
|
||||
{
|
||||
public:
|
||||
LLBakedUploadData( LLVOAvatar* avatar, LLTexLayerSet* layerset, LLTexLayerSetBuffer* layerset_buffer, const LLUUID & id);
|
||||
LLBakedUploadData(const LLVOAvatarSelf* avatar,
|
||||
LLTexLayerSet* layerset,
|
||||
const LLUUID& id,
|
||||
bool highest_res);
|
||||
~LLBakedUploadData() {}
|
||||
|
||||
LLUUID mID;
|
||||
LLVOAvatar* mAvatar; // just backlink, don't LLPointer
|
||||
LLTexLayerSet* mTexLayerSet;
|
||||
LLTexLayerSetBuffer* mLayerSetBuffer;
|
||||
LLUUID mWearableAssets[LLWearableType::WT_COUNT];
|
||||
U64 mStartTime; // Used to measure time baked texture upload requires
|
||||
const LLUUID mID;
|
||||
const LLVOAvatarSelf* mAvatar; // note: backlink only; don't LLPointer
|
||||
LLTexLayerSet* mTexLayerSet;
|
||||
const U64 mStartTime; // for measuring baked texture upload time
|
||||
const bool mIsHighestRes; // whether this is a "final" bake, or intermediate low res
|
||||
};
|
||||
|
||||
extern LLTexStaticImageList gTexStaticImageList;
|
||||
|
||||
|
||||
#endif // LL_LLTEXLAYER_H
|
||||
|
||||
193
indra/newview/lltexlayerparams.h
Normal file
193
indra/newview/lltexlayerparams.h
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* @file lltexlayerparams.h
|
||||
* @brief Texture layer parameters, used by lltexlayer.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLTEXLAYERPARAMS_H
|
||||
#define LL_LLTEXLAYERPARAMS_H
|
||||
|
||||
#include "llviewervisualparam.h"
|
||||
|
||||
class LLImageRaw;
|
||||
class LLImageTGA;
|
||||
class LLTexLayer;
|
||||
class LLTexLayerInterface;
|
||||
class LLViewerTexture;
|
||||
class LLVOAvatar;
|
||||
class LLWearable;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLTexLayerParam
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLTexLayerParam : public LLViewerVisualParam
|
||||
{
|
||||
public:
|
||||
LLTexLayerParam(LLTexLayerInterface *layer);
|
||||
LLTexLayerParam(LLVOAvatar *avatar);
|
||||
/*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar );
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
|
||||
|
||||
protected:
|
||||
LLTexLayerInterface* mTexLayer;
|
||||
LLVOAvatar* mAvatar;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLTexLayerParamAlpha
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLTexLayerParamAlpha : public LLTexLayerParam
|
||||
{
|
||||
public:
|
||||
LLTexLayerParamAlpha( LLTexLayerInterface* layer );
|
||||
LLTexLayerParamAlpha( LLVOAvatar* avatar );
|
||||
/*virtual*/ ~LLTexLayerParamAlpha();
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||
/*virtual*/ void apply( ESex avatar_sex ) {}
|
||||
/*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
|
||||
/*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake);
|
||||
/*virtual*/ void animate(F32 delta, BOOL upload_bake);
|
||||
|
||||
// LLViewerVisualParam Virtual functions
|
||||
/*virtual*/ F32 getTotalDistortion() { return 1.f; }
|
||||
/*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
|
||||
/*virtual*/ F32 getMaxDistortion() { return 3.f; }
|
||||
/*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f);}
|
||||
/*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
|
||||
/*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
|
||||
|
||||
// New functions
|
||||
BOOL render( S32 x, S32 y, S32 width, S32 height );
|
||||
BOOL getSkip() const;
|
||||
void deleteCaches();
|
||||
BOOL getMultiplyBlend() const;
|
||||
|
||||
private:
|
||||
LLPointer<LLViewerTexture> mCachedProcessedTexture;
|
||||
LLPointer<LLImageTGA> mStaticImageTGA;
|
||||
LLPointer<LLImageRaw> mStaticImageRaw;
|
||||
BOOL mNeedsCreateTexture;
|
||||
BOOL mStaticImageInvalid;
|
||||
LLVector3 mAvgDistortionVec;
|
||||
F32 mCachedEffectiveWeight;
|
||||
|
||||
public:
|
||||
// Global list of instances for gathering statistics
|
||||
static void dumpCacheByteCount();
|
||||
static void getCacheByteCount( S32* gl_bytes );
|
||||
|
||||
typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t;
|
||||
static param_alpha_ptr_list_t sInstances;
|
||||
};
|
||||
class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
|
||||
{
|
||||
friend class LLTexLayerParamAlpha;
|
||||
public:
|
||||
LLTexLayerParamAlphaInfo();
|
||||
/*virtual*/ ~LLTexLayerParamAlphaInfo() {};
|
||||
|
||||
/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
|
||||
|
||||
private:
|
||||
std::string mStaticImageFileName;
|
||||
BOOL mMultiplyBlend;
|
||||
BOOL mSkipIfZeroWeight;
|
||||
F32 mDomain;
|
||||
};
|
||||
//
|
||||
// LLTexLayerParamAlpha
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLTexLayerParamColor
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLTexLayerParamColor : public LLTexLayerParam
|
||||
{
|
||||
public:
|
||||
enum EColorOperation
|
||||
{
|
||||
OP_ADD = 0,
|
||||
OP_MULTIPLY = 1,
|
||||
OP_BLEND = 2,
|
||||
OP_COUNT = 3 // Number of operations
|
||||
};
|
||||
|
||||
LLTexLayerParamColor( LLTexLayerInterface* layer );
|
||||
LLTexLayerParamColor( LLVOAvatar* avatar );
|
||||
/* virtual */ ~LLTexLayerParamColor();
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||
/*virtual*/ void apply( ESex avatar_sex ) {}
|
||||
/*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
|
||||
/*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake);
|
||||
/*virtual*/ void animate(F32 delta, BOOL upload_bake);
|
||||
|
||||
|
||||
// LLViewerVisualParam Virtual functions
|
||||
/*virtual*/ F32 getTotalDistortion() { return 1.f; }
|
||||
/*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
|
||||
/*virtual*/ F32 getMaxDistortion() { return 3.f; }
|
||||
/*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f); }
|
||||
/*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
|
||||
/*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
|
||||
|
||||
// New functions
|
||||
LLColor4 getNetColor() const;
|
||||
protected:
|
||||
virtual void onGlobalColorChanged(bool upload_bake) {}
|
||||
private:
|
||||
LLVector3 mAvgDistortionVec;
|
||||
};
|
||||
|
||||
class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
|
||||
{
|
||||
friend class LLTexLayerParamColor;
|
||||
|
||||
public:
|
||||
LLTexLayerParamColorInfo();
|
||||
virtual ~LLTexLayerParamColorInfo() {};
|
||||
BOOL parseXml( LLXmlTreeNode* node );
|
||||
LLTexLayerParamColor::EColorOperation getOperation() const { return mOperation; }
|
||||
private:
|
||||
enum { MAX_COLOR_VALUES = 20 };
|
||||
LLTexLayerParamColor::EColorOperation mOperation;
|
||||
LLColor4 mColors[MAX_COLOR_VALUES];
|
||||
S32 mNumColors;
|
||||
};
|
||||
|
||||
typedef std::vector<LLTexLayerParamColor *> param_color_list_t;
|
||||
typedef std::vector<LLTexLayerParamAlpha *> param_alpha_list_t;
|
||||
typedef std::vector<LLTexLayerParamColorInfo *> param_color_info_list_t;
|
||||
typedef std::vector<LLTexLayerParamAlphaInfo *> param_alpha_info_list_t;
|
||||
|
||||
#endif
|
||||
@@ -292,7 +292,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
|
||||
mInventoryPanel->setFilterTypes(filter_types);
|
||||
//mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
|
||||
mInventoryPanel->setFilterPermMask(immediate_filter_perm_mask);
|
||||
mInventoryPanel->setSelectCallback(onSelectionChange, this);
|
||||
mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, _1, _2, (void*)this));
|
||||
mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mInventoryPanel->setAllowMultiSelect(FALSE);
|
||||
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "lldictionary.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llfirstuse.h"
|
||||
#include "llfloater.h"
|
||||
@@ -1731,10 +1734,11 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
|
||||
{
|
||||
if(mSource == SOURCE_LIBRARY)
|
||||
{
|
||||
// LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
|
||||
LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
|
||||
//Reapply this patch later.
|
||||
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-08 (Catznip-2.2.0a) | Added: Catznip-2.2.0a
|
||||
// Make this behave consistent with dad3dWearItem
|
||||
LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0, !(mask & MASK_CONTROL));
|
||||
//LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0, !(mask & MASK_CONTROL)); // MULTI-WEARABLES TODO
|
||||
// [/SL:KB]
|
||||
copy_inventory_item(
|
||||
gAgent.getID(),
|
||||
@@ -2074,23 +2078,9 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem(
|
||||
return ACCEPT_NO;
|
||||
}
|
||||
|
||||
if(mSource == SOURCE_LIBRARY)
|
||||
{
|
||||
// create item based on that one, and put it on if that
|
||||
// was a success.
|
||||
LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
|
||||
copy_inventory_item(
|
||||
gAgent.getID(),
|
||||
item->getPermissions().getOwner(),
|
||||
item->getUUID(),
|
||||
LLUUID::null,
|
||||
std::string(),
|
||||
cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
wear_inventory_item_on_avatar( item );
|
||||
}
|
||||
// TODO: investigate wearables may not be loaded at this point EXT-8231
|
||||
|
||||
LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL));
|
||||
}
|
||||
return ACCEPT_YES_MULTI;
|
||||
}
|
||||
@@ -2181,7 +2171,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory(
|
||||
if(drop)
|
||||
{
|
||||
BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE );
|
||||
wear_inventory_category(category, false, append);
|
||||
LLAppearanceMgr::instance().wearInventoryCategory(category, false, append);
|
||||
}
|
||||
return ACCEPT_YES_MULTI;
|
||||
}
|
||||
@@ -2189,7 +2179,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory(
|
||||
{
|
||||
if(drop)
|
||||
{
|
||||
wear_inventory_category(category, true, false);
|
||||
LLAppearanceMgr::instance().wearInventoryCategory(category, true, false);
|
||||
}
|
||||
return ACCEPT_YES_MULTI;
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ static bool handleAvatarBoobXYInfluence(const LLSD& newvalue)
|
||||
|
||||
static bool handleSetSelfInvisible( const LLSD& newvalue)
|
||||
{
|
||||
LLVOAvatar::onChangeSelfInvisible( newvalue.asBoolean() );
|
||||
LLVOAvatarSelf::onChangeSelfInvisible( newvalue.asBoolean() );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry
|
||||
const std::string &icon_name_open, // name of the folder icon
|
||||
const std::string &icon_name_closed,
|
||||
BOOL is_quiet, // folder doesn't need a UI update when changed
|
||||
bool hide_if_empty, // folder not shown if empty
|
||||
const std::string &dictionary_name = empty_string // no reverse lookup needed on non-ensembles, so in most cases just leave this blank
|
||||
)
|
||||
:
|
||||
@@ -47,7 +48,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry
|
||||
mNewCategoryName(new_category_name),
|
||||
mIconNameOpen(icon_name_open),
|
||||
mIconNameClosed(icon_name_closed),
|
||||
mIsQuiet(is_quiet)
|
||||
mIsQuiet(is_quiet),
|
||||
mHideIfEmpty(hide_if_empty)
|
||||
{
|
||||
mAllowedNames.clear();
|
||||
}
|
||||
@@ -64,9 +66,10 @@ struct ViewerFolderEntry : public LLDictionaryEntry
|
||||
mIconNameOpen(icon_name),
|
||||
mIconNameClosed(icon_name),
|
||||
*/
|
||||
mIconNameOpen("Inv_FolderOpen"), mIconNameClosed("Inv_FolderClosed"),
|
||||
mIconNameOpen("inv_folder_plain_closed.tga"), mIconNameClosed("inv_folder_plain_closed.tga"),
|
||||
mNewCategoryName(new_category_name),
|
||||
mIsQuiet(FALSE)
|
||||
mIsQuiet(FALSE),
|
||||
mHideIfEmpty(false)
|
||||
{
|
||||
const std::string delims (",");
|
||||
LLStringUtilBase<char>::getTokens(allowed_names, mAllowedNames, delims);
|
||||
@@ -91,6 +94,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry
|
||||
typedef std::vector<std::string> name_vec_t;
|
||||
name_vec_t mAllowedNames;
|
||||
BOOL mIsQuiet;
|
||||
bool mHideIfEmpty;
|
||||
};
|
||||
|
||||
class LLViewerFolderDictionary : public LLSingleton<LLViewerFolderDictionary>,
|
||||
@@ -104,43 +108,43 @@ protected:
|
||||
|
||||
LLViewerFolderDictionary::LLViewerFolderDictionary()
|
||||
{
|
||||
// NEW CATEGORY NAME FOLDER OPEN FOLDER CLOSED QUIET?
|
||||
// |-------------------------|-----------------------|----------------------|-----------|
|
||||
addEntry(LLFolderType::FT_TEXTURE, new ViewerFolderEntry("Textures", "inv_folder_texture.tga", "inv_folder_texture.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_SOUND, new ViewerFolderEntry("Sounds", "inv_folder_sound.tga", "inv_folder_sound.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_CALLINGCARD, new ViewerFolderEntry("Calling Cards", "inv_folder_callingcard.tga", "inv_folder_callingcard.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_LANDMARK, new ViewerFolderEntry("Landmarks", "inv_folder_landmark.tga", "inv_folder_landmark.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_CLOTHING, new ViewerFolderEntry("Clothing", "inv_folder_clothing.tga", "inv_folder_clothing.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_OBJECT, new ViewerFolderEntry("Objects", "inv_folder_object.tga", "inv_folder_object.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_NOTECARD, new ViewerFolderEntry("Notecards", "inv_folder_notecard.tga", "inv_folder_notecard.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_ROOT_INVENTORY, new ViewerFolderEntry("My Inventory", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_LSL_TEXT, new ViewerFolderEntry("Scripts", "inv_folder_script.tga", "inv_folder_script.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_BODYPART, new ViewerFolderEntry("Body Parts", "inv_folder_bodypart.tga", "inv_folder_bodypart.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_TRASH, new ViewerFolderEntry("Trash", "inv_folder_trash.tga", "inv_folder_trash.tga", TRUE));
|
||||
addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, new ViewerFolderEntry("Photo Album", "inv_folder_snapshot.tga", "inv_folder_snapshot.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_LOST_AND_FOUND, new ViewerFolderEntry("Lost And Found", "inv_folder_lostandfound.tga", "inv_folder_lostandfound.tga", TRUE));
|
||||
addEntry(LLFolderType::FT_ANIMATION, new ViewerFolderEntry("Animations", "inv_folder_animation.tga", "inv_folder_animation.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_GESTURE, new ViewerFolderEntry("Gestures", "inv_folder_gesture.tga", "inv_folder_gesture.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_FAVORITE, new ViewerFolderEntry("Favorites", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE));
|
||||
// NEW CATEGORY NAME FOLDER OPEN FOLDER CLOSED QUIET? HIDE IF EMPTY?
|
||||
// |-------------------------|-----------------------------------|---------------------------|--------------|------------|
|
||||
addEntry(LLFolderType::FT_TEXTURE, new ViewerFolderEntry("Textures", "inv_folder_texture.tga", "inv_folder_texture.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_SOUND, new ViewerFolderEntry("Sounds", "inv_folder_sound.tga", "inv_folder_sound.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_CALLINGCARD, new ViewerFolderEntry("Calling Cards", "inv_folder_callingcard.tga", "inv_folder_callingcard.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_LANDMARK, new ViewerFolderEntry("Landmarks", "inv_folder_landmark.tga", "inv_folder_landmark.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_CLOTHING, new ViewerFolderEntry("Clothing", "inv_folder_clothing.tga", "inv_folder_clothing.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_OBJECT, new ViewerFolderEntry("Objects", "inv_folder_object.tga", "inv_folder_object.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_NOTECARD, new ViewerFolderEntry("Notecards", "inv_folder_notecard.tga", "inv_folder_notecard.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_ROOT_INVENTORY, new ViewerFolderEntry("My Inventory", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_LSL_TEXT, new ViewerFolderEntry("Scripts", "inv_folder_script.tga", "inv_folder_script.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_BODYPART, new ViewerFolderEntry("Body Parts", "inv_folder_bodypart.tga", "inv_folder_bodypart.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_TRASH, new ViewerFolderEntry("Trash", "inv_folder_trash.tga", "inv_folder_trash.tga", TRUE, false));
|
||||
addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, new ViewerFolderEntry("Photo Album", "inv_folder_snapshot.tga", "inv_folder_snapshot.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_LOST_AND_FOUND, new ViewerFolderEntry("Lost And Found", "inv_folder_lostandfound.tga", "inv_folder_lostandfound.tga", TRUE, false));
|
||||
addEntry(LLFolderType::FT_ANIMATION, new ViewerFolderEntry("Animations", "inv_folder_animation.tga", "inv_folder_animation.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_GESTURE, new ViewerFolderEntry("Gestures", "inv_folder_gesture.tga", "inv_folder_gesture.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_FAVORITE, new ViewerFolderEntry("Favorites", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
|
||||
|
||||
addEntry(LLFolderType::FT_CURRENT_OUTFIT, new ViewerFolderEntry("Current Outfit", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", TRUE));
|
||||
addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", TRUE));
|
||||
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", TRUE));
|
||||
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_CURRENT_OUTFIT, new ViewerFolderEntry("Current Outfit", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", TRUE, false));
|
||||
addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", TRUE, false));
|
||||
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", TRUE, false));
|
||||
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
|
||||
|
||||
addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
|
||||
addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
|
||||
|
||||
addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE));
|
||||
addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
|
||||
|
||||
addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, "default"));
|
||||
addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false, "default"));
|
||||
|
||||
#if SUPPORT_ENSEMBLES
|
||||
initEnsemblesFromFile();
|
||||
#else
|
||||
for (U32 type = (U32)LLFolderType::FT_ENSEMBLE_START; type <= (U32)LLFolderType::FT_ENSEMBLE_END; ++type)
|
||||
{
|
||||
addEntry((LLFolderType::EType)type, new ViewerFolderEntry("New Folder", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE));
|
||||
addEntry((LLFolderType::EType)type, new ViewerFolderEntry("New Folder", "inv_folder_plain_closed.tga", "inv_folder_plain_closed.tga", FALSE, false));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -259,6 +263,15 @@ BOOL LLViewerFolderType::lookupIsQuietType(LLFolderType::EType folder_type)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool LLViewerFolderType::lookupIsHiddenIfEmpty(LLFolderType::EType folder_type)
|
||||
{
|
||||
const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type);
|
||||
if (entry)
|
||||
{
|
||||
return entry->mHideIfEmpty;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string &LLViewerFolderType::lookupNewCategoryName(LLFolderType::EType folder_type)
|
||||
{
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
|
||||
static const std::string& lookupIconName(EType folder_type, BOOL is_open = FALSE); // folder icon name
|
||||
static BOOL lookupIsQuietType(EType folder_type); // folder doesn't require UI update when changes have occured
|
||||
static bool lookupIsHiddenIfEmpty(EType folder_type); // folder is not displayed if empty
|
||||
static const std::string& lookupNewCategoryName(EType folder_type); // default name when creating new category
|
||||
static LLFolderType::EType lookupTypeFromNewCategoryName(const std::string& name); // default name when creating new category
|
||||
|
||||
|
||||
@@ -34,29 +34,39 @@
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "message.h"
|
||||
#include "indra_constants.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llfloaterinventory.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llviewerfoldertype.h"
|
||||
#include "llfolderview.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llconsole.h"
|
||||
#include "llinventorydefines.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llnotify.h"
|
||||
#include "llimview.h"
|
||||
#include "llinventorymodelbackgroundfetch.h"
|
||||
#include "llgesturemgr.h"
|
||||
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventorydefines.h"
|
||||
#include "llinventorymodelbackgroundfetch.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "llfloaterinventory.h"
|
||||
|
||||
#include "lllandmark.h"
|
||||
#include "llviewerassettype.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llpreviewgesture.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "lltrans.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llcommandhandler.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llavatarnamecache.h"
|
||||
|
||||
#include "llfloatercustomize.h"
|
||||
// <edit>
|
||||
#include "llappviewer.h" // System Folders
|
||||
// </edit>
|
||||
@@ -276,8 +286,7 @@ BOOL LLViewerInventoryItem::unpackMessage(LLSD item)
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLViewerInventoryItem::unpackMessage(
|
||||
LLMessageSystem* msg, const char* block, S32 block_num)
|
||||
BOOL LLViewerInventoryItem::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num)
|
||||
{
|
||||
BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num);
|
||||
mIsComplete = TRUE;
|
||||
@@ -634,6 +643,78 @@ bool LLViewerInventoryCategory::exportFileLocal(LLFILE* fp) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLViewerInventoryCategory::determineFolderType()
|
||||
{
|
||||
/* Do NOT uncomment this code. This is for future 2.1 support of ensembles.
|
||||
llassert(FALSE);
|
||||
LLFolderType::EType original_type = getPreferredType();
|
||||
if (LLFolderType::lookupIsProtectedType(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->isWearableType())
|
||||
{
|
||||
const LLWearableType::EType wearable_type = item->getWearableType();
|
||||
const std::string& wearable_name = LLWearableType::getTypeName(wearable_type);
|
||||
U64 valid_folder_types = LLViewerFolderType::lookupValidFolderTypes(wearable_name);
|
||||
folder_valid |= valid_folder_types;
|
||||
folder_invalid |= ~valid_folder_types;
|
||||
}
|
||||
}
|
||||
for (U8 i = LLFolderType::FT_ENSEMBLE_START; i <= LLFolderType::FT_ENSEMBLE_END; i++)
|
||||
{
|
||||
if ((folder_valid & (1LL << i)) &&
|
||||
!(folder_invalid & (1LL << i)))
|
||||
{
|
||||
changeType((LLFolderType::EType)i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (LLFolderType::lookupIsEnsembleType(original_type))
|
||||
{
|
||||
changeType(LLFolderType::FT_NONE);
|
||||
}
|
||||
llassert(FALSE);
|
||||
*/
|
||||
}
|
||||
|
||||
void LLViewerInventoryCategory::changeType(LLFolderType::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);
|
||||
}
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function definitions
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -661,6 +742,21 @@ LLInventoryCallbackManager::~LLInventoryCallbackManager()
|
||||
sInstance = NULL;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLInventoryCallbackManager::destroyClass()
|
||||
{
|
||||
if (sInstance)
|
||||
{
|
||||
for (callback_map_t::iterator it = sInstance->mMap.begin(), end_it = sInstance->mMap.end(); it != end_it; ++it)
|
||||
{
|
||||
// drop LLPointer reference to callback
|
||||
it->second = NULL;
|
||||
}
|
||||
sInstance->mMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
U32 LLInventoryCallbackManager::registerCB(LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
if (cb.isNull())
|
||||
@@ -697,14 +793,33 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item)
|
||||
LLViewerInventoryItem *item = gInventory.getItem(inv_item);
|
||||
if (item)
|
||||
{
|
||||
wear_inventory_item_on_avatar(item);
|
||||
LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, mReplace);
|
||||
}
|
||||
}
|
||||
|
||||
RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp, bool replace)
|
||||
void ModifiedCOFCallback::fire(const LLUUID& inv_item)
|
||||
{
|
||||
LLAppearanceMgr::instance().updateAppearanceFromCOF();
|
||||
|
||||
// Start editing the item if previously requested.
|
||||
gAgentWearables.editWearableIfRequested(inv_item);
|
||||
|
||||
// TODO: camera mode may not be changed if a debug setting is tweaked
|
||||
if( gAgentCamera.cameraCustomizeAvatar() )
|
||||
{
|
||||
// If we're in appearance editing mode, the current tab may need to be refreshed
|
||||
/*LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
|
||||
if (panel)
|
||||
{
|
||||
panel->showDefaultSubpart();
|
||||
}*/
|
||||
gFloaterCustomize->switchToDefaultSubpart();
|
||||
}
|
||||
}
|
||||
|
||||
RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp)
|
||||
{
|
||||
mAttach = attachmentp;
|
||||
mReplace = replace;
|
||||
}
|
||||
RezAttachmentCallback::~RezAttachmentCallback()
|
||||
{
|
||||
@@ -718,7 +833,7 @@ void RezAttachmentCallback::fire(const LLUUID& inv_item)
|
||||
LLViewerInventoryItem *item = gInventory.getItem(inv_item);
|
||||
if (item)
|
||||
{
|
||||
rez_attachment(item, mAttach, mReplace);
|
||||
rez_attachment(item, mAttach);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -755,6 +870,13 @@ void CreateGestureCallback::fire(const LLUUID& inv_item)
|
||||
}
|
||||
}
|
||||
|
||||
void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
|
||||
{
|
||||
if (mTargetLandmarkId.isNull()) return;
|
||||
|
||||
//gInventory.rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId); // MULTI-WEARABLES TODO
|
||||
}
|
||||
|
||||
LLInventoryCallbackManager gInventoryCallbacks;
|
||||
|
||||
void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
|
||||
@@ -784,6 +906,16 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent /*= LLUUID::null*/, LLPointer<LLInventoryCallback> cb/*=NULL*/)
|
||||
{
|
||||
std::string item_desc = avatar_id.asString();
|
||||
std::string item_name;
|
||||
gCacheName->getFullName(avatar_id, item_name);
|
||||
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
|
||||
parent, LLTransactionID::tnull, item_name, item_desc, LLAssetType::AT_CALLINGCARD,
|
||||
LLInventoryType::IT_CALLINGCARD, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb);
|
||||
}
|
||||
|
||||
void copy_inventory_item(
|
||||
const LLUUID& agent_id,
|
||||
const LLUUID& current_owner,
|
||||
@@ -893,25 +1025,23 @@ void move_inventory_item(
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
class LLCopyInventoryFromNotecardResponder : public LLHTTPClient::Responder
|
||||
const LLUUID get_folder_by_itemtype(const LLInventoryItem *src)
|
||||
{
|
||||
public:
|
||||
//If we get back a normal response, handle it here
|
||||
virtual void result(const LLSD& content)
|
||||
LLUUID retval = LLUUID::null;
|
||||
|
||||
if (src)
|
||||
{
|
||||
// What do we do here?
|
||||
llinfos << "CopyInventoryFromNotecard request successful." << llendl;
|
||||
retval = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(src->getType()));
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
//If we get back an error (not found, etc...), handle it here
|
||||
virtual void error(U32 status, const std::string& reason)
|
||||
{
|
||||
llinfos << "LLCopyInventoryFromNotecardResponder::error "
|
||||
<< status << ": " << reason << llendl;
|
||||
}
|
||||
};
|
||||
|
||||
void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecard_inv_id, const LLInventoryItem *src, U32 callback_id)
|
||||
void copy_inventory_from_notecard(const LLUUID& destination_id,
|
||||
const LLUUID& object_id,
|
||||
const LLUUID& notecard_inv_id,
|
||||
const LLInventoryItem *src,
|
||||
U32 callback_id)
|
||||
{
|
||||
if (NULL == src)
|
||||
{
|
||||
@@ -957,12 +1087,114 @@ void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecar
|
||||
body["notecard-id"] = notecard_inv_id;
|
||||
body["object-id"] = object_id;
|
||||
body["item-id"] = src->getUUID();
|
||||
body["folder-id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(src->getType()));
|
||||
body["folder-id"] = destination_id;
|
||||
body["callback-id"] = (LLSD::Integer)callback_id;
|
||||
|
||||
LLHTTPClient::post(url, body, new LLCopyInventoryFromNotecardResponder());
|
||||
LLHTTPClient::post(url, body, new LLHTTPClient::Responder() );
|
||||
}
|
||||
|
||||
void create_new_item(const std::string& name,
|
||||
const LLUUID& parent_id,
|
||||
LLAssetType::EType asset_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
U32 next_owner_perm)
|
||||
{
|
||||
std::string desc;
|
||||
LLViewerAssetType::generateDescriptionFor(asset_type, desc);
|
||||
next_owner_perm = (next_owner_perm) ? next_owner_perm : PERM_MOVE | PERM_TRANSFER;
|
||||
|
||||
|
||||
if (inv_type == LLInventoryType::IT_GESTURE)
|
||||
{
|
||||
LLPointer<LLInventoryCallback> cb = new CreateGestureCallback();
|
||||
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
|
||||
parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
|
||||
NOT_WEARABLE, next_owner_perm, cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPointer<LLInventoryCallback> cb = NULL;
|
||||
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
|
||||
parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
|
||||
NOT_WEARABLE, next_owner_perm, cb);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
|
||||
const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
|
||||
const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
|
||||
|
||||
// ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements...
|
||||
/*void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
|
||||
{
|
||||
std::string type_name = userdata.asString();
|
||||
|
||||
if (("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))
|
||||
{
|
||||
LLFolderType::EType preferred_type = LLFolderType::lookup(type_name);
|
||||
|
||||
LLUUID parent_id;
|
||||
if (bridge)
|
||||
{
|
||||
parent_id = bridge->getUUID();
|
||||
}
|
||||
else if (default_parent_uuid.notNull())
|
||||
{
|
||||
parent_id = default_parent_uuid;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent_id = gInventory.getRootFolderID();
|
||||
}
|
||||
|
||||
LLUUID category = gInventory.createNewCategory(parent_id, preferred_type, LLStringUtil::null);
|
||||
gInventory.notifyObservers();
|
||||
root->setSelectionByID(category, TRUE);
|
||||
}
|
||||
else if ("lsl" == type_name)
|
||||
{
|
||||
const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_LSL_TEXT);
|
||||
create_new_item(NEW_LSL_NAME,
|
||||
parent_id,
|
||||
LLAssetType::AT_LSL_TEXT,
|
||||
LLInventoryType::IT_LSL,
|
||||
PERM_MOVE | PERM_TRANSFER);
|
||||
}
|
||||
else if ("notecard" == type_name)
|
||||
{
|
||||
const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_NOTECARD);
|
||||
create_new_item(NEW_NOTECARD_NAME,
|
||||
parent_id,
|
||||
LLAssetType::AT_NOTECARD,
|
||||
LLInventoryType::IT_NOTECARD,
|
||||
PERM_ALL);
|
||||
}
|
||||
else if ("gesture" == type_name)
|
||||
{
|
||||
const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE);
|
||||
create_new_item(NEW_GESTURE_NAME,
|
||||
parent_id,
|
||||
LLAssetType::AT_GESTURE,
|
||||
LLInventoryType::IT_GESTURE,
|
||||
PERM_ALL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use for all clothing and body parts. Adding new wearable types requires updating LLWearableDictionary.
|
||||
LLWearableType::EType wearable_type = LLWearableType::typeNameToType(type_name);
|
||||
if (wearable_type >= LLWearableType::WT_SHAPE && wearable_type < LLWearableType::WT_COUNT)
|
||||
{
|
||||
const LLUUID parent_id = bridge ? bridge->getUUID() : LLUUID::null;
|
||||
LLAgentWearables::createWearable(wearable_type, false, parent_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Can't create unrecognized type " << type_name << llendl;
|
||||
}
|
||||
}
|
||||
root->setNeedsAutoRename(TRUE);
|
||||
}*/
|
||||
|
||||
LLAssetType::EType LLViewerInventoryItem::getType() const
|
||||
{
|
||||
@@ -987,6 +1219,23 @@ const LLUUID& LLViewerInventoryItem::getAssetUUID() const
|
||||
return LLInventoryItem::getAssetUUID();
|
||||
}
|
||||
|
||||
const LLUUID& LLViewerInventoryItem::getProtectedAssetUUID() const
|
||||
{
|
||||
if (const LLViewerInventoryItem *linked_item = getLinkedItem())
|
||||
{
|
||||
return linked_item->getProtectedAssetUUID();
|
||||
}
|
||||
|
||||
// check for conditions under which we may return a visible UUID to the user
|
||||
bool item_is_fullperm = getIsFullPerm();
|
||||
bool agent_is_godlike = gAgent.isGodlikeWithoutAdminMenuFakery();
|
||||
if (item_is_fullperm || agent_is_godlike)
|
||||
{
|
||||
return LLInventoryItem::getAssetUUID();
|
||||
}
|
||||
|
||||
return LLUUID::null;
|
||||
}
|
||||
|
||||
const bool LLViewerInventoryItem::getIsFullPerm() const
|
||||
{
|
||||
@@ -1003,6 +1252,7 @@ const bool LLViewerInventoryItem::getIsFullPerm() const
|
||||
gAgent.getID(),
|
||||
gAgent.getGroupID()) );
|
||||
}
|
||||
|
||||
const std::string& LLViewerInventoryItem::getName() const
|
||||
{
|
||||
if (const LLViewerInventoryItem *linked_item = getLinkedItem())
|
||||
@@ -1017,6 +1267,327 @@ const std::string& LLViewerInventoryItem::getName() const
|
||||
return LLInventoryItem::getName();
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Class to store sorting order of favorites landmarks in a local file. EXT-3985.
|
||||
* It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
|
||||
* Data are stored in user home directory.
|
||||
*/
|
||||
class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
|
||||
, public LLDestroyClass<LLFavoritesOrderStorage>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Sets sort index for specified with LLUUID favorite landmark
|
||||
*/
|
||||
void setSortIndex(const LLUUID& inv_item_id, S32 sort_index);
|
||||
|
||||
/**
|
||||
* Gets sort index for specified with LLUUID favorite landmark
|
||||
*/
|
||||
S32 getSortIndex(const LLUUID& inv_item_id);
|
||||
void removeSortIndex(const LLUUID& inv_item_id);
|
||||
|
||||
void getSLURL(const LLUUID& asset_id);
|
||||
|
||||
/**
|
||||
* Implementation of LLDestroyClass. Calls cleanup() instance method.
|
||||
*
|
||||
* It is important this callback is called before gInventory is cleaned.
|
||||
* For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
|
||||
* Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
|
||||
* @see cleanup()
|
||||
*/
|
||||
static void destroyClass();
|
||||
|
||||
const static S32 NO_INDEX;
|
||||
private:
|
||||
friend class LLSingleton<LLFavoritesOrderStorage>;
|
||||
LLFavoritesOrderStorage() : mIsDirty(false) { load(); }
|
||||
~LLFavoritesOrderStorage() { save(); }
|
||||
|
||||
/**
|
||||
* Removes sort indexes for items which are not in Favorites bar for now.
|
||||
*/
|
||||
void cleanup();
|
||||
|
||||
const static std::string SORTING_DATA_FILE_NAME;
|
||||
|
||||
void load();
|
||||
void save();
|
||||
|
||||
void saveFavoritesSLURLs();
|
||||
|
||||
// Remove record of current user's favorites from file on disk.
|
||||
void removeFavoritesRecordOfUser();
|
||||
|
||||
void onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark);
|
||||
void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
|
||||
|
||||
typedef std::map<LLUUID, S32> sort_index_map_t;
|
||||
sort_index_map_t mSortIndexes;
|
||||
|
||||
typedef std::map<LLUUID, std::string> slurls_map_t;
|
||||
slurls_map_t mSLURLs;
|
||||
|
||||
bool mIsDirty;
|
||||
|
||||
struct IsNotInFavorites
|
||||
{
|
||||
IsNotInFavorites(const LLInventoryModel::item_array_t& items)
|
||||
: mFavoriteItems(items)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if specified item is not found among inventory items
|
||||
*//
|
||||
bool operator()(const sort_index_map_t::value_type& id_index_pair) const
|
||||
{
|
||||
LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first);
|
||||
if (item.isNull()) return true;
|
||||
|
||||
LLInventoryModel::item_array_t::const_iterator found_it =
|
||||
std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);
|
||||
|
||||
return found_it == mFavoriteItems.end();
|
||||
}
|
||||
private:
|
||||
LLInventoryModel::item_array_t mFavoriteItems;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
|
||||
const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
|
||||
|
||||
void LLFavoritesOrderStorage::setSortIndex(const LLUUID& inv_item_id, S32 sort_index)
|
||||
{
|
||||
mSortIndexes[inv_item_id] = sort_index;
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id)
|
||||
{
|
||||
sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id);
|
||||
if (it != mSortIndexes.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
return NO_INDEX;
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
|
||||
{
|
||||
mSortIndexes.erase(inv_item_id);
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
|
||||
{
|
||||
slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
|
||||
if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
|
||||
|
||||
LLLandmark* lm = gLandmarkList.getAsset(asset_id,
|
||||
boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
|
||||
if (lm)
|
||||
{
|
||||
onLandmarkLoaded(asset_id, lm);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFavoritesOrderStorage::destroyClass()
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().cleanup();
|
||||
if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::load()
|
||||
{
|
||||
// load per-resident sorting information
|
||||
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
|
||||
|
||||
LLSD settings_llsd;
|
||||
llifstream file;
|
||||
file.open(filename);
|
||||
if (file.is_open())
|
||||
{
|
||||
LLSDSerialize::fromXML(settings_llsd, file);
|
||||
}
|
||||
|
||||
for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
|
||||
iter != settings_llsd.endMap(); ++iter)
|
||||
{
|
||||
mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::saveFavoritesSLURLs()
|
||||
{
|
||||
// Do not change the file if we are not logged in yet.
|
||||
if (!LLLoginInstance::getInstance()->authSuccess()) return;
|
||||
|
||||
std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
|
||||
if (user_dir.empty()) return;
|
||||
|
||||
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
|
||||
llifstream in_file;
|
||||
in_file.open(filename);
|
||||
LLSD fav_llsd;
|
||||
if (in_file.is_open())
|
||||
{
|
||||
LLSDSerialize::fromXML(fav_llsd, in_file);
|
||||
}
|
||||
|
||||
const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
LLSD user_llsd;
|
||||
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
|
||||
{
|
||||
LLSD value;
|
||||
value["name"] = (*it)->getName();
|
||||
value["asset_id"] = (*it)->getAssetUUID();
|
||||
|
||||
slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
|
||||
if (slurl_iter != mSLURLs.end())
|
||||
{
|
||||
value["slurl"] = slurl_iter->second;
|
||||
user_llsd[(*it)->getSortField()] = value;
|
||||
}
|
||||
}
|
||||
|
||||
LLAvatarName av_name;
|
||||
LLAvatarNameCache::get( gAgentID, &av_name );
|
||||
fav_llsd[av_name.getLegacyName()] = user_llsd;
|
||||
|
||||
llofstream file;
|
||||
file.open(filename);
|
||||
LLSDSerialize::toPrettyXML(fav_llsd, file);
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
|
||||
{
|
||||
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
|
||||
LLSD fav_llsd;
|
||||
llifstream file;
|
||||
file.open(filename);
|
||||
if (!file.is_open()) return;
|
||||
LLSDSerialize::fromXML(fav_llsd, file);
|
||||
|
||||
LLAvatarName av_name;
|
||||
LLAvatarNameCache::get( gAgentID, &av_name );
|
||||
if (fav_llsd.has(av_name.getLegacyName()))
|
||||
{
|
||||
fav_llsd.erase(av_name.getLegacyName());
|
||||
}
|
||||
|
||||
llofstream out_file;
|
||||
out_file.open(filename);
|
||||
LLSDSerialize::toPrettyXML(fav_llsd, out_file);
|
||||
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
|
||||
{
|
||||
if (!landmark) return;
|
||||
|
||||
LLVector3d pos_global;
|
||||
if (!landmark->getGlobalPos(pos_global))
|
||||
{
|
||||
// If global position was unknown on first getGlobalPos() call
|
||||
// it should be set for the subsequent calls.
|
||||
landmark->getGlobalPos(pos_global);
|
||||
}
|
||||
|
||||
if (!pos_global.isExactlyZero())
|
||||
{
|
||||
LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
|
||||
boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
|
||||
{
|
||||
mSLURLs[asset_id] = slurl;
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::save()
|
||||
{
|
||||
// nothing to save if clean
|
||||
if (!mIsDirty) return;
|
||||
|
||||
// If we quit from the login screen we will not have an SL account
|
||||
// name. Don't try to save, otherwise we'll dump a file in
|
||||
// C:\Program Files\SecondLife\ or similar. JC
|
||||
std::string user_dir = gDirUtilp->getLindenUserDir();
|
||||
if (!user_dir.empty())
|
||||
{
|
||||
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
|
||||
LLSD settings_llsd;
|
||||
|
||||
for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
|
||||
{
|
||||
settings_llsd[iter->first.asString()] = iter->second;
|
||||
}
|
||||
|
||||
llofstream file;
|
||||
file.open(filename);
|
||||
LLSDSerialize::toPrettyXML(settings_llsd, file);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::cleanup()
|
||||
{
|
||||
// nothing to clean
|
||||
if (!mIsDirty) return;
|
||||
|
||||
const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
IsNotInFavorites is_not_in_fav(items);
|
||||
|
||||
sort_index_map_t aTempMap;
|
||||
//copy unremoved values from mSortIndexes to aTempMap
|
||||
std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(),
|
||||
inserter(aTempMap, aTempMap.begin()),
|
||||
is_not_in_fav);
|
||||
|
||||
//Swap the contents of mSortIndexes and aTempMap
|
||||
mSortIndexes.swap(aTempMap);
|
||||
}
|
||||
|
||||
|
||||
S32 LLViewerInventoryItem::getSortField() const
|
||||
{
|
||||
return LLFavoritesOrderStorage::instance().getSortIndex(mUUID);
|
||||
}
|
||||
|
||||
void LLViewerInventoryItem::setSortField(S32 sortField)
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField);
|
||||
getSLURL();
|
||||
}
|
||||
|
||||
void LLViewerInventoryItem::getSLURL()
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID);
|
||||
}
|
||||
#endif
|
||||
|
||||
const LLPermissions& LLViewerInventoryItem::getPermissions() const
|
||||
{
|
||||
// Use the actual permissions of the symlink, not its parent.
|
||||
@@ -1181,3 +1752,75 @@ void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std:
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, getUUID());
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
|
||||
class LLRegenerateLinkCollector : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLRegenerateLinkCollector(const LLViewerInventoryItem *target_item) : mTargetItem(target_item) {}
|
||||
virtual ~LLRegenerateLinkCollector() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item)
|
||||
{
|
||||
if (item)
|
||||
{
|
||||
if ((item->getName() == mTargetItem->getName()) &&
|
||||
(item->getInventoryType() == mTargetItem->getInventoryType()) &&
|
||||
(!item->getIsLinkType()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected:
|
||||
const LLViewerInventoryItem* mTargetItem;
|
||||
};
|
||||
|
||||
LLUUID find_possible_item_for_regeneration(const LLViewerInventoryItem *target_item)
|
||||
{
|
||||
LLViewerInventoryCategory::cat_array_t cats;
|
||||
LLViewerInventoryItem::item_array_t items;
|
||||
|
||||
LLRegenerateLinkCollector candidate_matches(target_item);
|
||||
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
|
||||
cats,
|
||||
items,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
candidate_matches);
|
||||
for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items.begin();
|
||||
item_iter != items.end();
|
||||
++item_iter)
|
||||
{
|
||||
const LLViewerInventoryItem *item = (*item_iter);
|
||||
if (true) return item->getUUID();
|
||||
}
|
||||
return LLUUID::null;
|
||||
}
|
||||
|
||||
// This currently dosen't work, because the sim does not allow us
|
||||
// to change an item's assetID.
|
||||
BOOL LLViewerInventoryItem::regenerateLink()
|
||||
{
|
||||
const LLUUID target_item_id = find_possible_item_for_regeneration(this);
|
||||
if (target_item_id.isNull())
|
||||
return FALSE;
|
||||
LLViewerInventoryCategory::cat_array_t cats;
|
||||
LLViewerInventoryItem::item_array_t items;
|
||||
LLAssetIDMatches asset_id_matches(getAssetUUID());
|
||||
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
|
||||
cats,
|
||||
items,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
asset_id_matches);
|
||||
for (LLViewerInventoryItem::item_array_t::iterator item_iter = items.begin();
|
||||
item_iter != items.end();
|
||||
item_iter++)
|
||||
{
|
||||
LLViewerInventoryItem *item = (*item_iter);
|
||||
item->setAssetUUID(target_item_id);
|
||||
item->updateServer(FALSE);
|
||||
gInventory.addChangedMask(LLInventoryObserver::REBUILD, item->getUUID());
|
||||
}
|
||||
gInventory.notifyObservers();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,12 @@
|
||||
#include "llinventory.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llwearable.h"
|
||||
#include "llui.h" //for LLDestroyClass
|
||||
|
||||
#include <boost/signals2.hpp> // boost::signals2::trackable
|
||||
|
||||
class LLFolderView;
|
||||
class LLFolderBridge;
|
||||
class LLViewerInventoryCategory;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -46,7 +51,7 @@ class LLViewerInventoryCategory;
|
||||
// their inventory.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLViewerInventoryItem : public LLInventoryItem
|
||||
class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::trackable
|
||||
{
|
||||
public:
|
||||
typedef LLDynamicArray<LLPointer<LLViewerInventoryItem> > item_array_t;
|
||||
@@ -57,6 +62,7 @@ protected:
|
||||
public:
|
||||
virtual LLAssetType::EType getType() const;
|
||||
virtual const LLUUID& getAssetUUID() const;
|
||||
virtual const LLUUID& getProtectedAssetUUID() const; // returns LLUUID::null if current agent does not have permission to expose this asset's UUID to the user
|
||||
virtual const std::string& getName() const;
|
||||
virtual const LLPermissions& getPermissions() const;
|
||||
virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied
|
||||
@@ -153,7 +159,11 @@ public:
|
||||
|
||||
// callback
|
||||
void onCallingCardNameLookup(const LLUUID& id, const std::string& name, bool is_group);
|
||||
protected:
|
||||
|
||||
// If this is a broken link, try to fix it and any other identical link.
|
||||
BOOL regenerateLink();
|
||||
|
||||
public:
|
||||
BOOL mIsComplete;
|
||||
LLTransactionID mTransactionID;
|
||||
};
|
||||
@@ -212,6 +222,11 @@ public:
|
||||
// other than cacheing.
|
||||
bool exportFileLocal(LLFILE* fp) const;
|
||||
bool importFileLocal(LLFILE* fp);
|
||||
void determineFolderType();
|
||||
void changeType(LLFolderType::EType new_folder_type);
|
||||
|
||||
private:
|
||||
friend class LLInventoryModel;
|
||||
|
||||
protected:
|
||||
LLUUID mOwnerID;
|
||||
@@ -228,15 +243,25 @@ public:
|
||||
|
||||
class WearOnAvatarCallback : public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
WearOnAvatarCallback(bool do_replace = false) : mReplace(do_replace) {}
|
||||
|
||||
void fire(const LLUUID& inv_item);
|
||||
|
||||
protected:
|
||||
bool mReplace;
|
||||
};
|
||||
|
||||
class ModifiedCOFCallback : public LLInventoryCallback
|
||||
{
|
||||
void fire(const LLUUID& inv_item);
|
||||
};
|
||||
class LLViewerJointAttachment;
|
||||
|
||||
class RezAttachmentCallback : public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
RezAttachmentCallback(LLViewerJointAttachment *attachmentp, bool replace = false);
|
||||
RezAttachmentCallback(LLViewerJointAttachment *attachmentp);
|
||||
void fire(const LLUUID& inv_item);
|
||||
|
||||
protected:
|
||||
@@ -244,7 +269,6 @@ protected:
|
||||
|
||||
private:
|
||||
LLViewerJointAttachment* mAttach;
|
||||
bool mReplace;
|
||||
};
|
||||
|
||||
class ActivateGestureCallback : public LLInventoryCallback
|
||||
@@ -259,11 +283,24 @@ public:
|
||||
void fire(const LLUUID& inv_item);
|
||||
};
|
||||
|
||||
class AddFavoriteLandmarkCallback : public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
|
||||
void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
|
||||
|
||||
private:
|
||||
void fire(const LLUUID& inv_item);
|
||||
|
||||
LLUUID mTargetLandmarkId;
|
||||
};
|
||||
|
||||
// misc functions
|
||||
//void inventory_reliable_callback(void**, S32 status);
|
||||
|
||||
class LLInventoryCallbackManager
|
||||
class LLInventoryCallbackManager : public LLDestroyClass<LLInventoryCallbackManager>
|
||||
{
|
||||
friend class LLDestroyClass<LLInventoryCallbackManager>;
|
||||
public:
|
||||
LLInventoryCallbackManager();
|
||||
~LLInventoryCallbackManager();
|
||||
@@ -275,6 +312,8 @@ private:
|
||||
callback_map_t mMap;
|
||||
U32 mLastCallback;
|
||||
static LLInventoryCallbackManager *sInstance;
|
||||
static void destroyClass();
|
||||
|
||||
public:
|
||||
static bool is_instantiated() { return sInstance != NULL; }
|
||||
};
|
||||
@@ -291,6 +330,8 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
|
||||
U32 next_owner_perm,
|
||||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent = LLUUID::null, LLPointer<LLInventoryCallback> cb=NULL);
|
||||
|
||||
/**
|
||||
* @brief Securely create a new inventory item by copying from another.
|
||||
*/
|
||||
@@ -319,10 +360,18 @@ void move_inventory_item(
|
||||
const std::string& new_name,
|
||||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
void copy_inventory_from_notecard(const LLUUID& object_id,
|
||||
const LLUUID get_folder_by_itemtype(const LLInventoryItem *src);
|
||||
|
||||
void copy_inventory_from_notecard(const LLUUID& destination_id,
|
||||
const LLUUID& object_id,
|
||||
const LLUUID& notecard_inv_id,
|
||||
const LLInventoryItem *src,
|
||||
U32 callback_id = 0);
|
||||
|
||||
|
||||
void menu_create_inventory_item(LLFolderView* root,
|
||||
LLFolderBridge* bridge,
|
||||
const LLSD& userdata,
|
||||
const LLUUID& default_parent_uuid = LLUUID::null);
|
||||
|
||||
#endif // LL_LLVIEWERINVENTORY_H
|
||||
|
||||
@@ -176,7 +176,7 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
|
||||
object->markDead();
|
||||
|
||||
// If this happens to be attached to self, then detach.
|
||||
LLVOAvatar::detachAttachmentIntoInventory(object->getAttachmentItemID());
|
||||
LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
// newview includes
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "jcfloaterareasearch.h"
|
||||
|
||||
@@ -271,7 +272,6 @@ void init_debug_rendering_menu(LLMenuGL* menu);
|
||||
void init_debug_ui_menu(LLMenuGL* menu);
|
||||
void init_debug_xui_menu(LLMenuGL* menu);
|
||||
void init_debug_avatar_menu(LLMenuGL* menu);
|
||||
void init_debug_baked_texture_menu(LLMenuGL* menu);
|
||||
// [RLVa:KB]
|
||||
#include "rlvhandler.h"
|
||||
#include "rlvfloaterbehaviour.h"
|
||||
@@ -590,8 +590,6 @@ void handle_mesh_load_obj(void*);
|
||||
void handle_morph_save_obj(void*);
|
||||
void handle_morph_load_obj(void*);
|
||||
void handle_debug_avatar_textures(void*);
|
||||
void handle_grab_texture(void*);
|
||||
BOOL enable_grab_texture(void*);
|
||||
void handle_dump_region_object_cache(void*);
|
||||
|
||||
BOOL menu_ui_enabled(void *user_data);
|
||||
@@ -1596,11 +1594,8 @@ void init_debug_rendering_menu(LLMenuGL* menu)
|
||||
|
||||
void init_debug_avatar_menu(LLMenuGL* menu)
|
||||
{
|
||||
LLMenuGL* sub_menu = new LLMenuGL("Grab Baked Texture");
|
||||
init_debug_baked_texture_menu(sub_menu);
|
||||
LLMenuGL* sub_menu = new LLMenuGL("Character Tests");
|
||||
menu->appendMenu(sub_menu);
|
||||
|
||||
sub_menu = new LLMenuGL("Character Tests");
|
||||
sub_menu->append(new LLMenuItemToggleGL("Go Away/AFK When Idle",
|
||||
&gAllowIdleAFK));
|
||||
|
||||
@@ -1672,17 +1667,6 @@ void init_debug_avatar_menu(LLMenuGL* menu)
|
||||
menu->createJumpKeys();
|
||||
}
|
||||
|
||||
void init_debug_baked_texture_menu(LLMenuGL* menu)
|
||||
{
|
||||
menu->append(new LLMenuItemCallGL("Iris", handle_grab_texture, enable_grab_texture, (void*) TEX_EYES_BAKED));
|
||||
menu->append(new LLMenuItemCallGL("Head", handle_grab_texture, enable_grab_texture, (void*) TEX_HEAD_BAKED));
|
||||
menu->append(new LLMenuItemCallGL("Upper Body", handle_grab_texture, enable_grab_texture, (void*) TEX_UPPER_BAKED));
|
||||
menu->append(new LLMenuItemCallGL("Lower Body", handle_grab_texture, enable_grab_texture, (void*) TEX_LOWER_BAKED));
|
||||
menu->append(new LLMenuItemCallGL("Skirt", handle_grab_texture, enable_grab_texture, (void*) TEX_SKIRT_BAKED));
|
||||
menu->append(new LLMenuItemCallGL("Hair", handle_grab_texture, enable_grab_texture, (void*) TEX_HAIR_BAKED));
|
||||
menu->createJumpKeys();
|
||||
}
|
||||
|
||||
// [RLVa:KB] - Checked: 2009-11-17 (RLVa-1.1.0d) | Modified: RLVa-1.1.0d | OK
|
||||
void init_debug_rlva_menu(LLMenuGL* menu)
|
||||
{
|
||||
@@ -3080,10 +3064,10 @@ class LLAvatarDebug : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
||||
if( avatar )
|
||||
//LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
avatar->dumpLocalTextures();
|
||||
gAgentAvatarp->dumpLocalTextures();
|
||||
// <edit> hell no don't tell them about that
|
||||
/*
|
||||
llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl;
|
||||
@@ -3093,7 +3077,7 @@ class LLAvatarDebug : public view_listener_t
|
||||
send_generic_message("dumptempassetdata", strings, invoice);
|
||||
*/
|
||||
// </edit>
|
||||
LLFloaterAvatarTextures::show( avatar->getID() );
|
||||
LLFloaterAvatarTextures::show( gAgentAvatarp->getID() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -7628,7 +7612,7 @@ void handle_test_male(void*)
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
wear_outfit_by_name("Male Shape & Outfit");
|
||||
LLAppearanceMgr::instance().wearOutfitByName("Male Shape & Outfit");
|
||||
//gGestureList.requestResetFromServer( TRUE );
|
||||
}
|
||||
|
||||
@@ -7643,7 +7627,7 @@ void handle_test_female(void*)
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
wear_outfit_by_name("Female Shape & Outfit");
|
||||
LLAppearanceMgr::instance().wearOutfitByName("Female Shape & Outfit");
|
||||
//gGestureList.requestResetFromServer( FALSE );
|
||||
}
|
||||
|
||||
@@ -8318,7 +8302,7 @@ void handle_meshes_and_morphs(void* menu_item)
|
||||
LLVOAvatar::mesh_info_t mesh_info;
|
||||
LLVOAvatar::getMeshInfo(&mesh_info);
|
||||
|
||||
for(LLVOAvatar::mesh_info_t::iterator info_iter = mesh_info.begin();
|
||||
for(LLVOAvatarSelf::mesh_info_t::iterator info_iter = mesh_info.begin();
|
||||
info_iter != mesh_info.end(); ++info_iter)
|
||||
{
|
||||
const std::string& type = info_iter->first;
|
||||
@@ -8725,110 +8709,6 @@ void handle_debug_avatar_textures(void*)
|
||||
// </edit>
|
||||
}
|
||||
|
||||
void handle_grab_texture(void* data)
|
||||
{
|
||||
ETextureIndex index = (ETextureIndex)((intptr_t)data);
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
if ( avatar )
|
||||
{
|
||||
const LLUUID& asset_id = avatar->grabLocalTexture(index);
|
||||
LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << llendl;
|
||||
LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE;
|
||||
LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE;
|
||||
LLUUID folder_id(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
|
||||
if(folder_id.notNull())
|
||||
{
|
||||
std::string name = "Baked ";
|
||||
switch (index)
|
||||
{
|
||||
case TEX_EYES_BAKED:
|
||||
name.append("Iris");
|
||||
break;
|
||||
case TEX_HEAD_BAKED:
|
||||
name.append("Head");
|
||||
break;
|
||||
case TEX_UPPER_BAKED:
|
||||
name.append("Upper Body");
|
||||
break;
|
||||
case TEX_LOWER_BAKED:
|
||||
name.append("Lower Body");
|
||||
break;
|
||||
case TEX_SKIRT_BAKED:
|
||||
name.append("Skirt");
|
||||
break;
|
||||
case TEX_HAIR_BAKED:
|
||||
name.append("Hair");
|
||||
break;
|
||||
default:
|
||||
name.append("Unknown");
|
||||
break;
|
||||
}
|
||||
name.append(" Texture");
|
||||
|
||||
LLUUID item_id;
|
||||
item_id.generate();
|
||||
LLPermissions perm;
|
||||
perm.init(gAgentID,
|
||||
gAgentID,
|
||||
LLUUID::null,
|
||||
LLUUID::null);
|
||||
U32 next_owner_perm = PERM_MOVE | PERM_TRANSFER;
|
||||
perm.initMasks(PERM_ALL,
|
||||
PERM_ALL,
|
||||
PERM_NONE,
|
||||
PERM_NONE,
|
||||
next_owner_perm);
|
||||
time_t creation_date_now = time_corrected();
|
||||
LLPointer<LLViewerInventoryItem> item
|
||||
= new LLViewerInventoryItem(item_id,
|
||||
folder_id,
|
||||
perm,
|
||||
asset_id,
|
||||
asset_type,
|
||||
inv_type,
|
||||
name,
|
||||
LLStringUtil::null,
|
||||
LLSaleInfo::DEFAULT,
|
||||
LLInventoryItemFlags::II_FLAGS_NONE,
|
||||
creation_date_now);
|
||||
|
||||
item->updateServer(TRUE);
|
||||
gInventory.updateItem(item);
|
||||
gInventory.notifyObservers();
|
||||
|
||||
LLInventoryView* view = LLInventoryView::getActiveInventory();
|
||||
|
||||
// Show the preview panel for textures to let
|
||||
// user know that the image is now in inventory.
|
||||
if(view)
|
||||
{
|
||||
LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus();
|
||||
|
||||
view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO);
|
||||
view->getPanel()->openSelected();
|
||||
//LLInventoryView::dumpSelectionInformation((void*)view);
|
||||
// restore keyboard focus
|
||||
gFocusMgr.setKeyboardFocus(focus_ctrl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Can't find a folder to put it in" << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL enable_grab_texture(void* data)
|
||||
{
|
||||
ETextureIndex index = (ETextureIndex)((intptr_t)data);
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
if ( avatar )
|
||||
{
|
||||
return avatar->canGrabLocalTexture(index);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Returns a pointer to the avatar give the UUID of the avatar OR of an attachment the avatar is wearing.
|
||||
// Returns NULL on failure.
|
||||
LLVOAvatar* find_avatar_from_object( LLViewerObject* object )
|
||||
@@ -9204,15 +9084,19 @@ class LLEditTakeOff : public view_listener_t
|
||||
{
|
||||
std::string clothing = userdata.asString();
|
||||
if (clothing == "all")
|
||||
{
|
||||
LLAgentWearables::userRemoveAllClothes();
|
||||
}
|
||||
LLWearableBridge::removeAllClothesFromAvatar();
|
||||
else
|
||||
{
|
||||
LLWearableType::EType type = LLWearableType::typeNameToType(clothing);
|
||||
if (type >= LLWearableType::WT_SHAPE
|
||||
&& type < LLWearableType::WT_COUNT)
|
||||
LLAgentWearables::userRemoveWearable(type,0); // TODO: MULTI-WEARABLE
|
||||
&& type < LLWearableType::WT_COUNT
|
||||
&& (gAgentWearables.getWearableCount(type) > 0))
|
||||
{
|
||||
// MULTI-WEARABLES: assuming user wanted to remove top shirt.
|
||||
U32 wearable_index = gAgentWearables.getWearableCount(type) - 1;
|
||||
LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,wearable_index));
|
||||
LLWearableBridge::removeItemFromAvatar(item);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -199,8 +199,6 @@ static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL = 10.0f; // seconds
|
||||
extern BOOL gDebugClicks;
|
||||
|
||||
// function prototypes
|
||||
void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
|
||||
bool highlight_offered_object(const LLUUID& obj_id);
|
||||
bool check_offer_throttle(const std::string& from_name, bool check_only);
|
||||
void callbackCacheEstateOwnerName(const LLUUID& id, const std::string& full_name, bool is_group);
|
||||
|
||||
@@ -810,6 +808,51 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void highlight_inventory_objects_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel)
|
||||
{
|
||||
if (NULL == inventory_panel) return;
|
||||
|
||||
for (std::vector<LLUUID>::const_iterator item_iter = items.begin();
|
||||
item_iter != items.end();
|
||||
++item_iter)
|
||||
{
|
||||
const LLUUID& item_id = (*item_iter);
|
||||
if(!highlight_offered_object(item_id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LLInventoryObject* item = gInventory.getObject(item_id);
|
||||
llassert(item);
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LL_DEBUGS("Inventory_Move") << "Highlighting inventory item: " << item->getName() << ", " << item_id << LL_ENDL;
|
||||
LLFolderView* fv = inventory_panel->getRootFolder();
|
||||
if (fv)
|
||||
{
|
||||
LLFolderViewItem* fv_item = fv->getItemByID(item_id);
|
||||
if (fv_item)
|
||||
{
|
||||
LLFolderViewItem* fv_folder = fv_item->getParentFolder();
|
||||
if (fv_folder)
|
||||
{
|
||||
// Parent folders can be different in case of 2 consecutive drag and drop
|
||||
// operations when the second one is started before the first one completes.
|
||||
LL_DEBUGS("Inventory_Move") << "Open folder: " << fv_folder->getName() << LL_ENDL;
|
||||
fv_folder->setOpen(TRUE);
|
||||
if (fv_folder->isSelected())
|
||||
{
|
||||
fv->changeSelection(fv_folder, FALSE);
|
||||
}
|
||||
}
|
||||
fv->changeSelection(fv_item, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static LLNotificationFunctorRegistration jgr_1("JoinGroup", join_group_response);
|
||||
static LLNotificationFunctorRegistration jgr_2("JoinedTooManyGroupsMember", join_group_response);
|
||||
static LLNotificationFunctorRegistration jgr_3("JoinGroupCanAfford", join_group_response);
|
||||
@@ -825,9 +868,21 @@ public:
|
||||
const std::string& from_name) :
|
||||
LLInventoryFetchItemsObserver(object_id),
|
||||
mFromName(from_name) {}
|
||||
/*virtual*/ void startFetch()
|
||||
{
|
||||
for (uuid_vec_t::const_iterator it = mIDs.begin(); it < mIDs.end(); ++it)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
|
||||
if (cat)
|
||||
{
|
||||
mComplete.push_back((*it));
|
||||
}
|
||||
}
|
||||
LLInventoryFetchItemsObserver::startFetch();
|
||||
}
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
open_offer(mComplete, mFromName);
|
||||
open_inventory_offer(mComplete, mFromName);
|
||||
gInventory.removeObserver(this);
|
||||
delete this;
|
||||
}
|
||||
@@ -835,6 +890,178 @@ private:
|
||||
std::string mFromName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class to observe adding of new items moved from the world to user's inventory to select them in inventory.
|
||||
*
|
||||
* We can't create it each time items are moved because "drop" event is sent separately for each
|
||||
* element even while multi-dragging. We have to have the only instance of the observer. See EXT-4347.
|
||||
*/
|
||||
class LLViewerInventoryMoveFromWorldObserver : public LLInventoryAddItemByAssetObserver
|
||||
{
|
||||
public:
|
||||
LLViewerInventoryMoveFromWorldObserver()
|
||||
: LLInventoryAddItemByAssetObserver()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void setMoveIntoFolderID(const LLUUID& into_folder_uuid) {mMoveIntoFolderID = into_folder_uuid; }
|
||||
|
||||
private:
|
||||
/*virtual */void onAssetAdded(const LLUUID& asset_id)
|
||||
{
|
||||
// Store active Inventory panel.
|
||||
if (LLInventoryPanel::getActiveInventoryPanel())
|
||||
{
|
||||
mActivePanel = LLInventoryPanel::getActiveInventoryPanel()->getHandle();
|
||||
}
|
||||
|
||||
// Store selected items (without destination folder)
|
||||
mSelectedItems.clear();
|
||||
if (LLInventoryPanel::getActiveInventoryPanel())
|
||||
{
|
||||
LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList(mSelectedItems);
|
||||
}
|
||||
mSelectedItems.erase(mMoveIntoFolderID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects added inventory items watched by their Asset UUIDs if selection was not changed since
|
||||
* all items were started to watch (dropped into a folder).
|
||||
*/
|
||||
void done()
|
||||
{
|
||||
LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get());
|
||||
|
||||
// if selection is not changed since watch started lets hightlight new items.
|
||||
if (active_panel && !isSelectionChanged())
|
||||
{
|
||||
LL_DEBUGS("Inventory_Move") << "Selecting new items..." << LL_ENDL;
|
||||
active_panel->clearSelection();
|
||||
highlight_inventory_objects_in_panel(mAddedItems, active_panel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if selected inventory items were changed since moved inventory items were started to watch.
|
||||
*/
|
||||
bool isSelectionChanged()
|
||||
{
|
||||
LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get());
|
||||
|
||||
if (NULL == active_panel)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// get selected items (without destination folder)
|
||||
selected_items_t selected_items;
|
||||
active_panel->getRootFolder()->getSelectionList(selected_items);
|
||||
selected_items.erase(mMoveIntoFolderID);
|
||||
|
||||
// compare stored & current sets of selected items
|
||||
selected_items_t different_items;
|
||||
std::set_symmetric_difference(mSelectedItems.begin(), mSelectedItems.end(),
|
||||
selected_items.begin(), selected_items.end(), std::inserter(different_items, different_items.begin()));
|
||||
|
||||
LL_DEBUGS("Inventory_Move") << "Selected firstly: " << mSelectedItems.size()
|
||||
<< ", now: " << selected_items.size() << ", difference: " << different_items.size() << LL_ENDL;
|
||||
|
||||
return different_items.size() > 0;
|
||||
}
|
||||
|
||||
LLHandle<LLPanel> mActivePanel;
|
||||
typedef std::set<LLUUID> selected_items_t;
|
||||
selected_items_t mSelectedItems;
|
||||
|
||||
/**
|
||||
* UUID of FolderViewFolder into which watched items are moved.
|
||||
*
|
||||
* Destination FolderViewFolder becomes selected while mouse hovering (when dragged items are dropped).
|
||||
*
|
||||
* If mouse is moved out it set unselected and number of selected items is changed
|
||||
* even if selected items in Inventory stay the same.
|
||||
* So, it is used to update stored selection list.
|
||||
*
|
||||
* @see onAssetAdded()
|
||||
* @see isSelectionChanged()
|
||||
*/
|
||||
LLUUID mMoveIntoFolderID;
|
||||
};
|
||||
|
||||
LLViewerInventoryMoveFromWorldObserver* gInventoryMoveObserver = NULL;
|
||||
|
||||
void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid)
|
||||
{
|
||||
start_new_inventory_observer();
|
||||
|
||||
gInventoryMoveObserver->setMoveIntoFolderID(into_folder_uuid);
|
||||
gInventoryMoveObserver->watchAsset(inv_item->getAssetUUID());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class to observe moving of items and to select them in inventory.
|
||||
*
|
||||
* Used currently for dragging from inbox to regular inventory folders
|
||||
*/
|
||||
|
||||
class LLViewerInventoryMoveObserver : public LLInventoryObserver
|
||||
{
|
||||
public:
|
||||
|
||||
LLViewerInventoryMoveObserver(const LLUUID& object_id)
|
||||
: LLInventoryObserver()
|
||||
, mObjectID(object_id)
|
||||
{
|
||||
if (LLInventoryPanel::getActiveInventoryPanel())
|
||||
{
|
||||
mActivePanel = LLInventoryPanel::getActiveInventoryPanel()->getHandle();
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~LLViewerInventoryMoveObserver() {}
|
||||
virtual void changed(U32 mask);
|
||||
|
||||
private:
|
||||
LLUUID mObjectID;
|
||||
LLHandle<LLPanel> mActivePanel;
|
||||
|
||||
};
|
||||
|
||||
void LLViewerInventoryMoveObserver::changed(U32 mask)
|
||||
{
|
||||
LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get());
|
||||
|
||||
if (NULL == active_panel)
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if((mask & (LLInventoryObserver::STRUCTURE)) != 0)
|
||||
{
|
||||
const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
|
||||
|
||||
std::set<LLUUID>::const_iterator id_it = changed_items.begin();
|
||||
std::set<LLUUID>::const_iterator id_end = changed_items.end();
|
||||
for (;id_it != id_end; ++id_it)
|
||||
{
|
||||
if ((*id_it) == mObjectID)
|
||||
{
|
||||
active_panel->clearSelection();
|
||||
std::vector<LLUUID> items;
|
||||
items.push_back(mObjectID);
|
||||
highlight_inventory_objects_in_panel(items, active_panel);
|
||||
active_panel->getRootFolder()->scrollToShowSelection();
|
||||
|
||||
gInventory.removeObserver(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//unlike the FetchObserver for AgentOffer, we only make one
|
||||
//instance of the AddedObserver for TaskOffers
|
||||
//and it never dies. We do this because we don't know the UUID of
|
||||
@@ -845,13 +1072,62 @@ class LLOpenTaskOffer : public LLInventoryAddedObserver
|
||||
protected:
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
open_offer(mAdded, "");
|
||||
for (uuid_vec_t::iterator it = mAdded.begin(); it != mAdded.end();)
|
||||
{
|
||||
const LLUUID& item_uuid = *it;
|
||||
bool was_moved = false;
|
||||
LLInventoryObject* added_object = gInventory.getObject(item_uuid);
|
||||
if (added_object)
|
||||
{
|
||||
// cast to item to get Asset UUID
|
||||
LLInventoryItem* added_item = dynamic_cast<LLInventoryItem*>(added_object);
|
||||
if (added_item)
|
||||
{
|
||||
const LLUUID& asset_uuid = added_item->getAssetUUID();
|
||||
if (gInventoryMoveObserver->isAssetWatched(asset_uuid))
|
||||
{
|
||||
LL_DEBUGS("Inventory_Move") << "Found asset UUID: " << asset_uuid << LL_ENDL;
|
||||
was_moved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (was_moved)
|
||||
{
|
||||
it = mAdded.erase(it);
|
||||
}
|
||||
else ++it;
|
||||
}
|
||||
|
||||
open_inventory_offer(mAdded, "");
|
||||
mAdded.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class LLOpenTaskGroupOffer : public LLInventoryAddedObserver
|
||||
{
|
||||
protected:
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
open_inventory_offer(mAdded, "group_offer");
|
||||
mAdded.clear();
|
||||
gInventory.removeObserver(this);
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
//one global instance to bind them
|
||||
LLOpenTaskOffer* gNewInventoryObserver=NULL;
|
||||
class LLNewInventoryHintObserver : public LLInventoryAddedObserver
|
||||
{
|
||||
protected:
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
//LLFirstUse::newInventory();
|
||||
}
|
||||
};
|
||||
|
||||
LLNewInventoryHintObserver* gNewInventoryHintObserver=NULL;
|
||||
|
||||
void start_new_inventory_observer()
|
||||
{
|
||||
@@ -861,10 +1137,19 @@ void start_new_inventory_observer()
|
||||
gNewInventoryObserver = new LLOpenTaskOffer;
|
||||
gInventory.addObserver(gNewInventoryObserver);
|
||||
}
|
||||
|
||||
if (!gInventoryMoveObserver) //inventory move from the world observer
|
||||
{
|
||||
// Observer is deleted by gInventory
|
||||
gInventoryMoveObserver = new LLViewerInventoryMoveFromWorldObserver;
|
||||
gInventory.addObserver(gInventoryMoveObserver);
|
||||
}
|
||||
}
|
||||
|
||||
class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver
|
||||
{
|
||||
LOG_CLASS(LLDiscardAgentOffer);
|
||||
|
||||
public:
|
||||
LLDiscardAgentOffer(const LLUUID& folder_id, const LLUUID& object_id) :
|
||||
LLInventoryFetchItemsObserver(object_id),
|
||||
@@ -954,7 +1239,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)
|
||||
}
|
||||
}
|
||||
|
||||
void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
|
||||
void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name)
|
||||
{
|
||||
uuid_vec_t::const_iterator it = items.begin();
|
||||
uuid_vec_t::const_iterator end = items.end();
|
||||
@@ -1059,16 +1344,9 @@ bool highlight_offered_object(const LLUUID& obj_id)
|
||||
if (parent)
|
||||
{
|
||||
const LLFolderType::EType parent_type = parent->getPreferredType();
|
||||
switch (parent_type)
|
||||
if (LLViewerFolderType::lookupIsQuietType(parent_type))
|
||||
{
|
||||
case LLFolderType::FT_TRASH:
|
||||
case LLFolderType::FT_LOST_AND_FOUND:
|
||||
case LLFolderType::FT_CURRENT_OUTFIT:
|
||||
case LLFolderType::FT_OUTFIT:
|
||||
case LLFolderType::FT_MY_OUTFITS:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,6 +206,14 @@ void invalid_message_callback(LLMessageSystem*, void*, EMessageException);
|
||||
|
||||
void process_initiate_download(LLMessageSystem* msg, void**);
|
||||
void start_new_inventory_observer();
|
||||
void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name);
|
||||
|
||||
// Returns true if item is not in certain "quiet" folder which don't need UI
|
||||
// notification (e.g. trash, cof, lost-and-found) and agent is not AFK, false otherwise.
|
||||
// Returns false if item is not found.
|
||||
bool highlight_offered_object(const LLUUID& obj_id);
|
||||
|
||||
void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid);
|
||||
|
||||
struct LLOfferInfo
|
||||
{
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
#include "lldebugview.h"
|
||||
#include "llfasttimerview.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llviewerwindow.h" // *TODO: remove, only used for width/height
|
||||
#include "llworld.h"
|
||||
#include "llfeaturemanager.h"
|
||||
@@ -525,10 +525,10 @@ void output_statistics(void*)
|
||||
|
||||
llinfos << "--------------------------------" << llendl;
|
||||
llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl;
|
||||
gTexStaticImageList.dumpByteCount();
|
||||
LLVOAvatar::dumpScratchTextureByteCount();
|
||||
LLTexLayerStaticImageList::getInstance()->dumpByteCount();
|
||||
LLVOAvatarSelf::dumpScratchTextureByteCount();
|
||||
LLTexLayerSetBuffer::dumpTotalByteCount();
|
||||
LLVOAvatar::dumpTotalLocalTextureByteCount();
|
||||
LLVOAvatarSelf::dumpTotalLocalTextureByteCount();
|
||||
LLTexLayerParamAlpha::dumpCacheByteCount();
|
||||
LLVOAvatar::dumpBakedStatus();
|
||||
|
||||
|
||||
@@ -1565,7 +1565,8 @@ bool LLViewerTextEditor::importStream(std::istream& str)
|
||||
|
||||
void LLViewerTextEditor::copyInventory(const LLInventoryItem* item, U32 callback_id)
|
||||
{
|
||||
copy_inventory_from_notecard(mObjectID,
|
||||
copy_inventory_from_notecard(LLUUID::null, // Don't specify a destination -- let the sim do that
|
||||
mObjectID,
|
||||
mNotecardInventoryID,
|
||||
item,
|
||||
callback_id);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
LLViewerVisualParamInfo::LLViewerVisualParamInfo()
|
||||
:
|
||||
mWearableType( LLWearableType::WT_INVALID ),
|
||||
mCrossWearable(FALSE),
|
||||
mCamDist( 0.5f ),
|
||||
mCamAngle( 0.f ),
|
||||
mCamElevation( 0.f ),
|
||||
@@ -85,6 +86,12 @@ BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node)
|
||||
mEditGroup = "";
|
||||
}
|
||||
|
||||
static LLStdStringHandle cross_wearable_string = LLXmlTree::addAttributeString("cross_wearable");
|
||||
if (!node->getFastAttributeBOOL(cross_wearable_string, mCrossWearable))
|
||||
{
|
||||
mCrossWearable = FALSE;
|
||||
}
|
||||
|
||||
// Optional camera offsets from the current joint center. Used for generating "hints" (thumbnails).
|
||||
static LLStdStringHandle camera_distance_string = LLXmlTree::addAttributeString("camera_distance");
|
||||
node->getFastAttributeF32( camera_distance_string, mCamDist );
|
||||
@@ -112,6 +119,15 @@ BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*virtual*/ void LLViewerVisualParamInfo::toStream(std::ostream &out)
|
||||
{
|
||||
LLVisualParamInfo::toStream(out);
|
||||
|
||||
out << mWearableType << "\t";
|
||||
out << mEditGroup << "\t";
|
||||
out << mEditGroupDisplayOrder << "\t";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLViewerVisualParam()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -45,8 +45,11 @@ public:
|
||||
|
||||
/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
|
||||
|
||||
/*virtual*/ void toStream(std::ostream &out);
|
||||
|
||||
protected:
|
||||
S32 mWearableType;
|
||||
BOOL mCrossWearable;
|
||||
std::string mEditGroup;
|
||||
F32 mCamDist;
|
||||
F32 mCamAngle; // degrees
|
||||
@@ -73,6 +76,8 @@ public:
|
||||
LLViewerVisualParamInfo *getInfo() const { return (LLViewerVisualParamInfo*)mInfo; };
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLViewerVisualParamInfo *info);
|
||||
|
||||
virtual LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||
@@ -86,7 +91,7 @@ public:
|
||||
virtual const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0;
|
||||
|
||||
// interface methods
|
||||
F32 getDisplayOrder() { return getInfo()->mEditGroupDisplayOrder; }
|
||||
F32 getDisplayOrder() const { return getInfo()->mEditGroupDisplayOrder; }
|
||||
S32 getWearableType() const { return getInfo()->mWearableType; }
|
||||
const std::string& getEditGroup() const { return getInfo()->mEditGroup; }
|
||||
|
||||
@@ -98,6 +103,9 @@ public:
|
||||
BOOL getShowSimple() const { return getInfo()->mShowSimple; }
|
||||
F32 getSimpleMin() const { return getInfo()->mSimpleMin; }
|
||||
F32 getSimpleMax() const { return getInfo()->mSimpleMax; }
|
||||
|
||||
BOOL getCrossWearable() const { return getInfo()->mCrossWearable; }
|
||||
|
||||
};
|
||||
|
||||
#endif // LL_LLViewerVisualParam_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,20 +39,25 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
#include "imageids.h" // IMG_INVISIBLE
|
||||
#include "llchat.h"
|
||||
#include "lldrawpoolalpha.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llcharacter.h"
|
||||
#include "llcontrol.h"
|
||||
#include "llviewerjointmesh.h"
|
||||
#include "llviewerjointattachment.h"
|
||||
#include "llrendertarget.h"
|
||||
#include "llwearable.h"
|
||||
#include "llvoavatardefines.h"
|
||||
#include "lltexglobalcolor.h"
|
||||
#include "lldriverparam.h"
|
||||
#include "material_codes.h" // LL_MCODE_END
|
||||
|
||||
#include "emeraldboobutils.h"
|
||||
#include "llavatarname.h"
|
||||
|
||||
|
||||
extern const LLUUID ANIM_AGENT_BODY_NOISE;
|
||||
extern const LLUUID ANIM_AGENT_BREATHE_ROT;
|
||||
extern const LLUUID ANIM_AGENT_PHYSICS_MOTION;
|
||||
@@ -70,9 +75,6 @@ class LLVoiceVisualizer;
|
||||
class LLHUDNameTag;
|
||||
class LLHUDEffectSpiral;
|
||||
class LLTexGlobalColor;
|
||||
class LLTexGlobalColorInfo;
|
||||
class LLTexLayerSetInfo;
|
||||
class LLDriverParamInfo;
|
||||
class LLVOAvatarBoneInfo;
|
||||
class LLVOAvatarSkeletonInfo;
|
||||
|
||||
@@ -82,12 +84,14 @@ class LLVOAvatarSkeletonInfo;
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLVOAvatar :
|
||||
public LLViewerObject,
|
||||
public LLCharacter
|
||||
public LLCharacter,
|
||||
public boost::signals2::trackable
|
||||
{
|
||||
public:
|
||||
friend class LLVOAvatarSelf;
|
||||
protected:
|
||||
struct LLVOAvatarXmlInfo;
|
||||
struct LLMaskedMorph;
|
||||
|
||||
/********************************************************************************
|
||||
** **
|
||||
@@ -104,6 +108,7 @@ protected:
|
||||
virtual ~LLVOAvatar();
|
||||
BOOL loadSkeletonNode();
|
||||
BOOL loadMeshNodes();
|
||||
virtual BOOL loadLayersets();
|
||||
|
||||
/** Initialization
|
||||
** **
|
||||
@@ -177,6 +182,7 @@ public:
|
||||
virtual void requestStopMotion(LLMotion* motion);
|
||||
LLMotion* findMotion(const LLUUID& id) const;
|
||||
void startDefaultMotions();
|
||||
void dumpAnimationState();
|
||||
|
||||
virtual LLJoint* getJoint(const std::string &name);
|
||||
virtual LLJoint* getRootJoint() { return &mRoot; }
|
||||
@@ -239,8 +245,6 @@ public:
|
||||
void idleUpdateBelowWater();
|
||||
void idleUpdateBoobEffect(); //Emerald
|
||||
|
||||
void updateAttachmentVisibility(U32 camera_mode); //Agent only
|
||||
|
||||
LLFrameTimer mIdleTimer;
|
||||
std::string getIdleTime();
|
||||
|
||||
@@ -276,10 +280,12 @@ public:
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
BOOL isFullyLoaded() const;
|
||||
//BOOL isReallyFullyLoaded();
|
||||
BOOL updateIsFullyLoaded();
|
||||
bool visualParamWeightsAreDefault();
|
||||
protected:
|
||||
bool sendAvatarTexturesRequest();
|
||||
virtual BOOL getIsCloud();
|
||||
BOOL updateIsFullyLoaded();
|
||||
BOOL processFullyLoadedChange(bool loading);
|
||||
|
||||
void updateRuthTimer(bool loading);
|
||||
F32 calcMorphAmount();
|
||||
private:
|
||||
@@ -290,6 +296,8 @@ private:
|
||||
S32 mVisualComplexity;
|
||||
LLFrameTimer mFullyLoadedTimer;
|
||||
LLFrameTimer mRuthTimer;
|
||||
protected:
|
||||
LLFrameTimer mInvisibleTimer;
|
||||
|
||||
/** State
|
||||
** **
|
||||
@@ -405,6 +413,14 @@ private:
|
||||
S32 mUpdatePeriod;
|
||||
S32 mNumInitFaces; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer.
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Morph masks
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
BOOL morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
|
||||
void addMaskedMorph(LLVOAvatarDefines::EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer);
|
||||
void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Visibility
|
||||
//--------------------------------------------------------------------
|
||||
@@ -448,6 +464,8 @@ private:
|
||||
F32 mImpostorDistance;
|
||||
F32 mImpostorPixelArea;
|
||||
LLVector3 mLastAnimExtents[2];
|
||||
|
||||
LLCachedControl<bool> mRenderUnloadedAvatar;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Wind rippling in clothes
|
||||
@@ -480,6 +498,15 @@ public:
|
||||
private:
|
||||
static S32 sFreezeCounter;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Constants
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
virtual LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR; }
|
||||
virtual LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED; }
|
||||
virtual S32 getTexImageSize() const;
|
||||
virtual S32 getTexImageArea() const { return getTexImageSize()*getTexImageSize(); }
|
||||
|
||||
/** Rendering
|
||||
** **
|
||||
*******************************************************************************/
|
||||
@@ -493,8 +520,9 @@ private:
|
||||
// Loading status
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
BOOL isTextureDefined(U8 te) const;
|
||||
BOOL isTextureVisible(U8 te) const;
|
||||
virtual BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
|
||||
virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
|
||||
virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const;
|
||||
|
||||
protected:
|
||||
BOOL isFullyBaked();
|
||||
@@ -512,6 +540,7 @@ protected:
|
||||
virtual void removeMissingBakedTextures();
|
||||
void useBakedTexture(const LLUUID& id);
|
||||
|
||||
typedef std::deque<LLMaskedMorph *> morph_list_t;
|
||||
struct BakedTextureData
|
||||
{
|
||||
LLUUID mLastTextureIndex;
|
||||
@@ -522,15 +551,35 @@ protected:
|
||||
U32 mMaskTexName;
|
||||
// Stores pointers to the joint meshes that this baked texture deals with
|
||||
std::vector< LLViewerJointMesh * > mMeshes; // std::vector<LLViewerJointMesh> mJoints[i]->mMeshParts
|
||||
morph_list_t mMaskedMorphs;
|
||||
};
|
||||
typedef std::vector<BakedTextureData> bakedtexturedata_vec_t;
|
||||
bakedtexturedata_vec_t mBakedTextureDatas;
|
||||
LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ;
|
||||
BOOL mLoadedCallbacksPaused;
|
||||
|
||||
public:
|
||||
const BakedTextureData& getBakedTextureData(LLVOAvatarDefines::ETextureIndex idx) const {return mBakedTextureDatas[idx];}
|
||||
//--------------------------------------------------------------------
|
||||
// Local Textures
|
||||
//--------------------------------------------------------------------
|
||||
protected:
|
||||
void setLocalTexture(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* tex, BOOL baked_version_exits);
|
||||
void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked);
|
||||
virtual void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0);
|
||||
virtual void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0);
|
||||
// MULTI-WEARABLE: make self-only?
|
||||
virtual void setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index = 0);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Texture accessors
|
||||
//--------------------------------------------------------------------
|
||||
private:
|
||||
virtual void setImage(const U8 te, LLViewerTexture *imagep, const U32 index);
|
||||
virtual LLViewerTexture* getImage(const U8 te, const U32 index) const;
|
||||
|
||||
virtual const LLTextureEntry* getTexEntry(const U8 te_num) const;
|
||||
virtual void setTexEntry(const U8 index, const LLTextureEntry &te);
|
||||
|
||||
void checkTextureLoading() ;
|
||||
//--------------------------------------------------------------------
|
||||
// Layers
|
||||
//--------------------------------------------------------------------
|
||||
@@ -544,6 +593,9 @@ protected:
|
||||
public:
|
||||
virtual void invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result);
|
||||
virtual void invalidateAll();
|
||||
virtual void setCompositeUpdatesEnabled(bool b) {}
|
||||
virtual void setCompositeUpdatesEnabled(U32 index, bool b) {}
|
||||
virtual bool isCompositeUpdateEnabled(U32 index) { return false; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Static texture/mesh/baked dictionary
|
||||
@@ -565,74 +617,7 @@ public:
|
||||
private:
|
||||
BOOL mFirstTEMessageReceived;
|
||||
BOOL mFirstAppearanceMessageReceived;
|
||||
|
||||
|
||||
//Most this stuff is Agent only
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Textures and Layers
|
||||
//--------------------------------------------------------------------
|
||||
protected:
|
||||
void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i);
|
||||
|
||||
|
||||
LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const;
|
||||
S32 getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex index);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Other public functions
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
static void dumpTotalLocalTextureByteCount();
|
||||
protected:
|
||||
void getLocalTextureByteCount( S32* gl_byte_count );
|
||||
|
||||
public:
|
||||
void dumpLocalTextures();
|
||||
const LLUUID& grabLocalTexture(LLVOAvatarDefines::ETextureIndex index);
|
||||
BOOL canGrabLocalTexture(LLVOAvatarDefines::ETextureIndex index);
|
||||
|
||||
void setCompositeUpdatesEnabled(BOOL b);
|
||||
|
||||
void setNameFromChat(const std::string &text);
|
||||
void clearNameFromChat();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// texture compositing (used only by the LLTexLayer series of classes)
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
BOOL isLocalTextureDataAvailable( const LLTexLayerSet* layerset );
|
||||
BOOL isLocalTextureDataFinal( const LLTexLayerSet* layerset );
|
||||
LLVOAvatarDefines::ETextureIndex getBakedTE( LLTexLayerSet* layerset );
|
||||
void updateComposites();
|
||||
//BOOL getLocalTextureRaw( LLVOAvatarDefines::ETextureIndex index, LLImageRaw* image_raw_pp );
|
||||
BOOL getLocalTextureGL( LLVOAvatarDefines::ETextureIndex index, LLViewerTexture** image_gl_pp );
|
||||
const LLUUID& getLocalTextureID( LLVOAvatarDefines::ETextureIndex index );
|
||||
LLGLuint getScratchTexName( LLGLenum format, U32* texture_bytes );
|
||||
BOOL bindScratchTexture( LLGLenum format );
|
||||
void forceBakeAllTextures(bool slam_for_debug = false);
|
||||
static void processRebakeAvatarTextures(LLMessageSystem* msg, void**);
|
||||
void setNewBakedTexture( LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid );
|
||||
void setCachedBakedTexture( LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid );
|
||||
void requestLayerSetUploads();
|
||||
void requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i);
|
||||
bool hasPendingBakedUploads();
|
||||
static void onLocalTextureLoaded( BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );
|
||||
static void onChangeSelfInvisible(BOOL newvalue);
|
||||
void setInvisible(BOOL newvalue);
|
||||
|
||||
void wearableUpdated(LLWearableType::EType type, BOOL upload_result = TRUE);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// texture compositing
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void setLocTexTE( U8 te, LLViewerTexture* image, BOOL set_by_user );
|
||||
void setupComposites();
|
||||
|
||||
/** Textures
|
||||
** **
|
||||
*******************************************************************************/
|
||||
@@ -702,16 +687,16 @@ public:
|
||||
// Clothing colors (convenience functions to access visual parameters)
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void setClothesColor( LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL set_by_user );
|
||||
void setClothesColor(LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
|
||||
LLColor4 getClothesColor(LLVOAvatarDefines::ETextureIndex te);
|
||||
static BOOL teToColorParams( LLVOAvatarDefines::ETextureIndex te, const char* param_name[3] );
|
||||
static BOOL teToColorParams(LLVOAvatarDefines::ETextureIndex te, U32 *param_name);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Global colors
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
LLColor4 getGlobalColor(const std::string& color_name ) const;
|
||||
void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL set_by_user );
|
||||
void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake);
|
||||
private:
|
||||
LLTexGlobalColor* mTexSkinColor;
|
||||
LLTexGlobalColor* mTexHairColor;
|
||||
@@ -743,17 +728,17 @@ public:
|
||||
**/
|
||||
|
||||
public:
|
||||
BOOL isWearingWearableType( LLWearableType::EType type ) const;
|
||||
virtual BOOL isWearingWearableType(LLWearableType::EType type ) const;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Attachments
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void clampAttachmentPositions();
|
||||
BOOL attachObject(LLViewerObject *viewer_object);
|
||||
BOOL detachObject(LLViewerObject *viewer_object);
|
||||
virtual const LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object);
|
||||
virtual BOOL detachObject(LLViewerObject *viewer_object);
|
||||
void cleanupAttachedMesh( LLViewerObject* pVO );
|
||||
static LLVOAvatar* findAvatarFromAttachment( LLViewerObject* obj );
|
||||
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
|
||||
protected:
|
||||
// [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i
|
||||
LLViewerJointAttachment* getTargetAttachmentPoint(const LLViewerObject* viewer_object) const;
|
||||
@@ -779,6 +764,7 @@ public:
|
||||
void rebuildHUD();
|
||||
void resetHUDAttachments();
|
||||
BOOL canAttachMoreObjects() const;
|
||||
BOOL canAttachMoreObjects(U32 n) const;
|
||||
protected:
|
||||
U32 getNumAttachments() const; // O(N), not O(1)
|
||||
|
||||
@@ -786,7 +772,6 @@ protected:
|
||||
// Old/nonstandard/Agent-only functions
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
static BOOL detachAttachmentIntoInventory(const LLUUID& item_id);
|
||||
BOOL isWearingAttachment( const LLUUID& inv_item_id );
|
||||
// <edit> testzone attachpt
|
||||
BOOL isWearingUnsupportedAttachment( const LLUUID& inv_item_id );
|
||||
@@ -839,6 +824,8 @@ public:
|
||||
// Chat
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void setNameFromChat(const std::string &text);
|
||||
void clearNameFromChat();
|
||||
void addChat(const LLChat& chat);
|
||||
void clearChat();
|
||||
void startTyping() { mTyping = TRUE; mTypingTimer.reset(); mIdleTimer.reset();}
|
||||
@@ -1066,7 +1053,6 @@ private:
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
static void dumpArchetypeXML(void*);
|
||||
static void dumpScratchTextureByteCount(); //Agent only
|
||||
static void dumpBakedStatus();
|
||||
const std::string getBakedStatusForPrintout() const;
|
||||
void dumpAvatarTEs(const std::string& context) const;
|
||||
@@ -1079,13 +1065,20 @@ protected:
|
||||
S32 getUnbakedPixelAreaRank();
|
||||
BOOL mHasGrey;
|
||||
private:
|
||||
LLUUID mSavedTE[ LLVOAvatarDefines::TEX_NUM_INDICES ];
|
||||
BOOL mHasBakedHair;
|
||||
F32 mMinPixelArea;
|
||||
F32 mMaxPixelArea;
|
||||
F32 mAdjustedPixelArea;
|
||||
std::string mDebugText;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Avatar Rez Metrics
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
F32 debugGetExistenceTimeElapsedF32() const { return mDebugExistenceTimer.getElapsedTimeF32(); }
|
||||
protected:
|
||||
LLFrameTimer mRuthDebugTimer; // For tracking how long it takes for av to rez
|
||||
LLFrameTimer mDebugExistenceTimer; // Debugging for how long the avatar has been in memory.
|
||||
|
||||
/** Diagnostics
|
||||
** **
|
||||
*******************************************************************************/
|
||||
@@ -1107,6 +1100,7 @@ protected: // Shared with LLVOAvatarSelf
|
||||
BOOL parseXmlColorNodes(LLXmlTreeNode* root);
|
||||
BOOL parseXmlLayerNodes(LLXmlTreeNode* root);
|
||||
BOOL parseXmlDriverNodes(LLXmlTreeNode* root);
|
||||
BOOL parseXmlMorphNodes(LLXmlTreeNode* root);
|
||||
|
||||
struct LLVOAvatarMeshInfo
|
||||
{
|
||||
@@ -1166,26 +1160,39 @@ protected: // Shared with LLVOAvatarSelf
|
||||
|
||||
typedef std::vector<LLDriverParamInfo*> driver_info_list_t;
|
||||
driver_info_list_t mDriverInfoList;
|
||||
|
||||
struct LLVOAvatarMorphInfo
|
||||
{
|
||||
LLVOAvatarMorphInfo()
|
||||
: mInvert(FALSE) {}
|
||||
std::string mName;
|
||||
std::string mRegion;
|
||||
std::string mLayer;
|
||||
BOOL mInvert;
|
||||
};
|
||||
|
||||
typedef std::vector<LLVOAvatarMorphInfo*> morph_info_list_t;
|
||||
morph_info_list_t mMorphMaskInfoList;
|
||||
};
|
||||
|
||||
public: //Public until pulled out of LLTexLayer
|
||||
struct LLMaskedMorph
|
||||
{
|
||||
LLMaskedMorph(LLPolyMorphTarget *morph_target, BOOL invert) :
|
||||
LLMaskedMorph(LLPolyMorphTarget *morph_target, BOOL invert, std::string layer) :
|
||||
mMorphTarget(morph_target),
|
||||
mInvert(invert)
|
||||
mInvert(invert),
|
||||
mLayer(layer)
|
||||
{
|
||||
morph_target->addPendingMorphMask();
|
||||
}
|
||||
|
||||
LLPolyMorphTarget *mMorphTarget;
|
||||
BOOL mInvert;
|
||||
std::string mLayer;
|
||||
};
|
||||
|
||||
/** Support classes
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
// <edit>
|
||||
|
||||
public:
|
||||
@@ -1196,61 +1203,11 @@ public:
|
||||
LLUUID mFocusObject;
|
||||
LLVector3d mFocusVector;
|
||||
//void resetIdleTime();
|
||||
// </edit>
|
||||
|
||||
private:
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// Per-avatar information about texture data.
|
||||
// To-do: Move this to private implementation class
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
struct LocalTextureData
|
||||
{
|
||||
LocalTextureData() : mIsBakedReady(false), mDiscard(MAX_DISCARD_LEVEL+1), mImage(NULL)
|
||||
{}
|
||||
LLPointer<LLViewerFetchedTexture> mImage;
|
||||
bool mIsBakedReady;
|
||||
S32 mDiscard;
|
||||
};
|
||||
typedef std::map<LLVOAvatarDefines::ETextureIndex, LocalTextureData> localtexture_map_t;
|
||||
localtexture_map_t mLocalTextureData;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Private member variables.
|
||||
//--------------------------------------------------------------------
|
||||
// Scratch textures used for compositing
|
||||
static LLMap< LLGLenum, LLGLuint*> sScratchTexNames;
|
||||
static LLMap< LLGLenum, F32*> sScratchTexLastBindTime;
|
||||
static S32 sScratchTexBytes;
|
||||
|
||||
static LLSD sClientResolutionList;
|
||||
|
||||
bool isUnknownClient();
|
||||
static void resolveClient(LLColor4& avatar_name_color, std::string& client, LLVOAvatar* avatar);
|
||||
friend class LLFloaterAvatarList;
|
||||
|
||||
|
||||
U64 mLastRegionHandle;
|
||||
LLFrameTimer mRegionCrossingTimer;
|
||||
S32 mRegionCrossingCount;
|
||||
|
||||
static bool sDoProperArc;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// Inlines
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
inline BOOL LLVOAvatar::isTextureDefined(U8 te) const
|
||||
{
|
||||
return (getTEImage(te)->getID() != IMG_DEFAULT_AVATAR && getTEImage(te)->getID() != IMG_DEFAULT);
|
||||
}
|
||||
|
||||
inline BOOL LLVOAvatar::isTextureVisible(U8 te) const
|
||||
{
|
||||
return ((isTextureDefined(te) || isSelf())
|
||||
&& (getTEImage(te)->getID() != IMG_INVISIBLE
|
||||
|| LLDrawPoolAlpha::sShowDebugAlpha));
|
||||
}
|
||||
// </edit>
|
||||
}; // LLVOAvatar
|
||||
extern const F32 SELF_ADDITIONAL_PRI;
|
||||
extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL;
|
||||
|
||||
#endif // LL_VO_AVATAR_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,8 @@
|
||||
#include "llviewertexture.h"
|
||||
#include "llvoavatar.h"
|
||||
|
||||
struct LocalTextureData;
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLVOAvatarSelf
|
||||
@@ -39,6 +41,7 @@
|
||||
class LLVOAvatarSelf :
|
||||
public LLVOAvatar
|
||||
{
|
||||
LOG_CLASS(LLVOAvatarSelf);
|
||||
|
||||
/********************************************************************************
|
||||
** **
|
||||
@@ -56,6 +59,7 @@ protected:
|
||||
BOOL loadAvatarSelf();
|
||||
BOOL buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info);
|
||||
BOOL buildMenus();
|
||||
/*virtual*/ BOOL loadLayersets();
|
||||
|
||||
/** Initialization
|
||||
** **
|
||||
@@ -83,6 +87,15 @@ public:
|
||||
|
||||
void resetJointPositions( void );
|
||||
|
||||
/*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
|
||||
/*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
|
||||
/*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );
|
||||
/*virtual*/ void updateVisualParams();
|
||||
/*virtual*/ void idleUpdateAppearanceAnimation();
|
||||
|
||||
private:
|
||||
// helper function. Passed in param is assumed to be in avatar's parameter list.
|
||||
BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE );
|
||||
|
||||
|
||||
/** Initialization
|
||||
@@ -104,7 +117,16 @@ public:
|
||||
/*virtual*/ BOOL updateCharacter(LLAgent &agent);
|
||||
/*virtual*/ void idleUpdateTractorBeam();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Loading state
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
/*virtual*/ BOOL getIsCloud();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Region state
|
||||
//--------------------------------------------------------------------
|
||||
void resetRegionCrossingTimer() { mRegionCrossingTimer.reset(); }
|
||||
|
||||
private:
|
||||
U64 mLastRegionHandle;
|
||||
@@ -129,12 +151,114 @@ private:
|
||||
LLPointer<LLHUDEffectSpiral> mBeam;
|
||||
LLFrameTimer mBeamTimer;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// LLVOAvatar Constants
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
/*virtual*/ LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_SELF; }
|
||||
/*virtual*/ LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED_SELF; }
|
||||
/*virtual*/ S32 getTexImageSize() const { return LLVOAvatar::getTexImageSize()*4; }
|
||||
|
||||
/** Rendering
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
** **
|
||||
** TEXTURES
|
||||
**/
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Loading status
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
/*virtual*/ bool hasPendingBakedUploads() const;
|
||||
S32 getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
|
||||
bool areTexturesCurrent() const;
|
||||
BOOL isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const;
|
||||
BOOL isLocalTextureDataFinal(const LLTexLayerSet* layerset) const;
|
||||
BOOL isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const;
|
||||
// If you want to check all textures of a given type, pass gAgentWearables.getWearableCount() for index
|
||||
/*virtual*/ BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
|
||||
/*virtual*/ BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
|
||||
/*virtual*/ BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Local Textures
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const;
|
||||
LLViewerFetchedTexture* getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
|
||||
const LLUUID& getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
|
||||
void setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index);
|
||||
/*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index);
|
||||
protected:
|
||||
/*virtual*/ void setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index);
|
||||
void localTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
|
||||
void getLocalTextureByteCount(S32* gl_byte_count) const;
|
||||
/*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index);
|
||||
LLLocalTextureObject* getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 index) const;
|
||||
|
||||
private:
|
||||
static void onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
|
||||
|
||||
/*virtual*/ void setImage(const U8 te, LLViewerTexture *imagep, const U32 index);
|
||||
/*virtual*/ LLViewerTexture* getImage(const U8 te, const U32 index) const;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Baked textures
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
LLVOAvatarDefines::ETextureIndex getBakedTE(const LLTexLayerSet* layerset ) const;
|
||||
void setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid);
|
||||
void setNewBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
|
||||
void setCachedBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
|
||||
void forceBakeAllTextures(bool slam_for_debug = false);
|
||||
static void processRebakeAvatarTextures(LLMessageSystem* msg, void**);
|
||||
BOOL isUsingBakedTextures() const; // e.g. false if in appearance edit mode
|
||||
protected:
|
||||
/*virtual*/ void removeMissingBakedTextures();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Layers
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void requestLayerSetUploads();
|
||||
void requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i);
|
||||
void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i);
|
||||
LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Composites
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
/* virtual */ void invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result);
|
||||
/* virtual */ void invalidateAll();
|
||||
/* virtual */ void setCompositeUpdatesEnabled(bool b); // only works for self
|
||||
/* virtual */ void setCompositeUpdatesEnabled(U32 index, bool b);
|
||||
/* virtual */ bool isCompositeUpdateEnabled(U32 index);
|
||||
void setupComposites();
|
||||
void updateComposites();
|
||||
|
||||
const LLUUID& grabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
|
||||
BOOL canGrabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Scratch textures (used for compositing)
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
static void deleteScratchTextures();
|
||||
private:
|
||||
static S32 sScratchTexBytes;
|
||||
static LLMap< LLGLenum, LLGLuint*> sScratchTexNames;
|
||||
static LLMap< LLGLenum, F32*> sScratchTexLastBindTime;
|
||||
|
||||
/** Textures
|
||||
** **
|
||||
*******************************************************************************/
|
||||
/********************************************************************************
|
||||
** **
|
||||
** MESHES
|
||||
@@ -146,6 +270,36 @@ protected:
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
** **
|
||||
** WEARABLES
|
||||
**/
|
||||
|
||||
public:
|
||||
/*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type) const;
|
||||
void wearableUpdated(LLWearableType::EType type, BOOL upload_result);
|
||||
protected:
|
||||
U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Attachments
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void updateAttachmentVisibility(U32 camera_mode);
|
||||
BOOL isWearingAttachment(const LLUUID& inv_item_id) const;
|
||||
BOOL attachmentWasRequested(const LLUUID& inv_item_id) const;
|
||||
void addAttachmentRequest(const LLUUID& inv_item_id);
|
||||
void removeAttachmentRequest(const LLUUID& inv_item_id);
|
||||
LLViewerObject* getWornAttachment(const LLUUID& inv_item_id);
|
||||
const std::string getAttachedPointName(const LLUUID& inv_item_id) const;
|
||||
/*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);
|
||||
/*virtual*/ BOOL detachObject(LLViewerObject *viewer_object);
|
||||
static BOOL detachAttachmentIntoInventory(const LLUUID& item_id);
|
||||
|
||||
private:
|
||||
// Track attachments that have been requested but have not arrived yet.
|
||||
mutable std::map<LLUUID,LLTimer> mAttachmentRequests;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// HUDs
|
||||
//--------------------------------------------------------------------
|
||||
@@ -155,6 +309,80 @@ private:
|
||||
/** Attachments
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
** **
|
||||
** APPEARANCE
|
||||
**/
|
||||
|
||||
public:
|
||||
static void onCustomizeStart();
|
||||
static void onCustomizeEnd();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Visibility
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
bool sendAppearanceMessage(LLMessageSystem *mesgsys) const;
|
||||
|
||||
/** Appearance
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
** **
|
||||
** DIAGNOSTICS
|
||||
**/
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// General
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
static void dumpTotalLocalTextureByteCount();
|
||||
void dumpLocalTextures() const;
|
||||
static void dumpScratchTextureByteCount();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Avatar Rez Metrics
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
struct LLAvatarTexData
|
||||
{
|
||||
LLAvatarTexData(const LLUUID& id, LLVOAvatarDefines::ETextureIndex index) :
|
||||
mAvatarID(id),
|
||||
mIndex(index)
|
||||
{}
|
||||
LLUUID mAvatarID;
|
||||
LLVOAvatarDefines::ETextureIndex mIndex;
|
||||
};
|
||||
void debugWearablesLoaded() { mDebugTimeWearablesLoaded = mDebugSelfLoadTimer.getElapsedTimeF32(); }
|
||||
void debugAvatarVisible() { mDebugTimeAvatarVisible = mDebugSelfLoadTimer.getElapsedTimeF32(); }
|
||||
void outputRezDiagnostics() const;
|
||||
void outputRezTiming(const std::string& msg) const;
|
||||
void reportAvatarRezTime() const;
|
||||
void debugBakedTextureUpload(LLVOAvatarDefines::EBakedTextureIndex index, BOOL finished);
|
||||
static void debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
|
||||
|
||||
BOOL isAllLocalTextureDataFinal() const;
|
||||
|
||||
const LLTexLayerSet* debugGetLayerSet(LLVOAvatarDefines::EBakedTextureIndex index) const { return mBakedTextureDatas[index].mTexLayerSet; }
|
||||
const std::string debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
|
||||
const std::string debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD
|
||||
private:
|
||||
LLFrameTimer mDebugSelfLoadTimer;
|
||||
F32 mDebugTimeWearablesLoaded;
|
||||
F32 mDebugTimeAvatarVisible;
|
||||
F32 mDebugTextureLoadTimes[LLVOAvatarDefines::TEX_NUM_INDICES][MAX_DISCARD_LEVEL+1]; // load time for each texture at each discard level
|
||||
F32 mDebugBakedTextureTimes[LLVOAvatarDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture
|
||||
void debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
|
||||
|
||||
/** Diagnostics
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
public:
|
||||
static void onChangeSelfInvisible(bool invisible);
|
||||
void setInvisible(bool invisible);
|
||||
};
|
||||
|
||||
extern LLVOAvatarSelf *gAgentAvatarp;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,8 +39,13 @@
|
||||
#include "llsaleinfo.h"
|
||||
#include "llassetstorage.h"
|
||||
#include "llwearabletype.h"
|
||||
#include "llfile.h"
|
||||
#include "lllocaltextureobject.h"
|
||||
|
||||
class LLViewerInventoryItem;
|
||||
class LLVisualParam;
|
||||
class LLTexGlobalColorInfo;
|
||||
class LLTexGlobalColor;
|
||||
|
||||
class LLWearable
|
||||
{
|
||||
@@ -73,22 +78,24 @@ public:
|
||||
const std::string& getName() const { return mName; }
|
||||
void setName( const std::string& name ) { mName = name; }
|
||||
const std::string& getDescription() const { return mDescription; }
|
||||
void setDescription( const std::string& desc ) { mDescription = desc; }
|
||||
void setDescription(const std::string& desc) { mDescription = desc; }
|
||||
const LLPermissions& getPermissions() const { return mPermissions; }
|
||||
void setPermissions( const LLPermissions& p ) { mPermissions = p; }
|
||||
void setPermissions(const LLPermissions& p) { mPermissions = p; }
|
||||
const LLSaleInfo& getSaleInfo() const { return mSaleInfo; }
|
||||
|
||||
|
||||
void setSaleInfo( const LLSaleInfo& info ) { mSaleInfo = info; }
|
||||
void setSaleInfo(const LLSaleInfo& info) { mSaleInfo = info; }
|
||||
const std::string& getTypeLabel() const;
|
||||
const std::string& getTypeName() const;
|
||||
LLAssetType::EType getAssetType() const;
|
||||
S32 getDefinitionVersion() const { return mDefinitionVersion; }
|
||||
void setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; }
|
||||
|
||||
public:
|
||||
typedef std::vector<LLVisualParam*> visual_param_vec_t;
|
||||
|
||||
BOOL isDirty() const;
|
||||
BOOL isOldVersion() const;
|
||||
|
||||
void writeToAvatar( BOOL set_by_user );
|
||||
void readFromAvatar();
|
||||
void writeToAvatar();
|
||||
void removeFromAvatar( BOOL upload_bake ) { LLWearable::removeFromAvatar( mType, upload_bake ); }
|
||||
static void removeFromAvatar( LLWearableType::EType type, BOOL upload_bake );
|
||||
|
||||
@@ -101,15 +108,34 @@ public:
|
||||
void saveNewAsset() const;
|
||||
static void onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status );
|
||||
|
||||
BOOL isMatchedToInventoryItem( LLViewerInventoryItem* item );
|
||||
|
||||
void copyDataFrom( LLWearable* src );
|
||||
void copyDataFrom(const LLWearable* src);
|
||||
|
||||
static void setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; }
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &s, const LLWearable &w);
|
||||
void setItemID(const LLUUID& item_id);
|
||||
|
||||
LLLocalTextureObject* getLocalTextureObject(S32 index);
|
||||
const LLLocalTextureObject* getLocalTextureObject(S32 index) const;
|
||||
|
||||
void setLocalTextureObject(S32 index, LLLocalTextureObject <o);
|
||||
void addVisualParam(LLVisualParam *param);
|
||||
void setVisualParams();
|
||||
void setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);
|
||||
F32 getVisualParamWeight(S32 index) const;
|
||||
LLVisualParam* getVisualParam(S32 index) const;
|
||||
void getVisualParams(visual_param_vec_t &list);
|
||||
void animateParams(F32 delta, BOOL upload_bake);
|
||||
|
||||
LLColor4 getClothesColor(S32 te) const;
|
||||
void setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
|
||||
|
||||
void revertValues();
|
||||
void saveValues();
|
||||
void pullCrossWearableValues();
|
||||
|
||||
BOOL isOnTop() const;
|
||||
|
||||
// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
|
||||
void setLabelUpdated() const;
|
||||
|
||||
@@ -118,7 +144,13 @@ public:
|
||||
void refreshName();
|
||||
|
||||
private:
|
||||
typedef std::map<S32, LLUUID> te_map_t;
|
||||
typedef std::map<S32, LLLocalTextureObject*> te_map_t;
|
||||
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
|
||||
|
||||
void createLayers(S32 te);
|
||||
void createVisualParams();
|
||||
void syncImages(te_map_t &src, te_map_t &dst);
|
||||
void destroyTextures();
|
||||
|
||||
static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml.
|
||||
S32 mDefinitionVersion; // Depends on the state of the avatar_lad.xml when this asset was created.
|
||||
@@ -131,9 +163,12 @@ private:
|
||||
LLWearableType::EType mType;
|
||||
|
||||
typedef std::map<S32, F32> param_map_t;
|
||||
param_map_t mVisualParamMap; // maps visual param id to weight
|
||||
|
||||
te_map_t mTEMap; // maps TE to Image ID
|
||||
param_map_t mSavedVisualParamMap; // last saved version of visual params
|
||||
|
||||
visual_param_index_map_t mVisualParamIndexMap;
|
||||
|
||||
te_map_t mTEMap; // maps TE to LocalTextureObject
|
||||
te_map_t mSavedTEMap; // last saved version of TEMap
|
||||
LLUUID mItemID; // ID of the inventory item in the agent's inventory
|
||||
};
|
||||
|
||||
|
||||
@@ -38,10 +38,10 @@
|
||||
#include "llassetstorage.h"
|
||||
#include "llagent.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llviewerinventory.h"
|
||||
//#include "llfloaterchat.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
// Callback struct
|
||||
struct LLWearableArrivedData
|
||||
@@ -71,7 +71,7 @@ struct LLWearableArrivedData
|
||||
|
||||
LLWearableList::~LLWearableList()
|
||||
{
|
||||
llassert_always(mList.empty()) ;
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void LLWearableList::cleanup()
|
||||
@@ -231,7 +231,7 @@ LLWearable* LLWearableList::createWearableMatchedToInventoryItem( LLWearable* ol
|
||||
return wearable;
|
||||
}
|
||||
|
||||
LLWearable* LLWearableList::createCopyFromAvatar( LLWearable* old_wearable, const std::string& new_name )
|
||||
/*LLWearable* LLWearableList::createCopyFromAvatar( LLWearable* old_wearable, const std::string& new_name )
|
||||
{
|
||||
lldebugs << "LLWearableList::createCopyFromAvatar()" << llendl;
|
||||
|
||||
@@ -248,10 +248,10 @@ LLWearable* LLWearableList::createCopyFromAvatar( LLWearable* old_wearable, cons
|
||||
wearable->saveNewAsset();
|
||||
|
||||
return wearable;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
LLWearable* LLWearableList::createCopy( LLWearable* old_wearable )
|
||||
LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std::string& new_name)
|
||||
{
|
||||
lldebugs << "LLWearableList::createCopy()" << llendl;
|
||||
|
||||
@@ -262,6 +262,7 @@ LLWearable* LLWearableList::createCopy( LLWearable* old_wearable )
|
||||
perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true);
|
||||
wearable->setPermissions(perm);
|
||||
|
||||
if (!new_name.empty()) wearable->setName(new_name);
|
||||
|
||||
// Send to the dataserver
|
||||
wearable->saveNewAsset();
|
||||
@@ -276,8 +277,7 @@ LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
|
||||
LLWearable *wearable = generateNewWearable();
|
||||
wearable->setType( type );
|
||||
|
||||
std::string name = "New ";
|
||||
name.append( wearable->getTypeLabel() );
|
||||
std::string name = LLWearableType::getTypeDefaultNewName(wearable->getType());
|
||||
wearable->setName( name );
|
||||
|
||||
LLPermissions perm;
|
||||
@@ -289,6 +289,9 @@ LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
|
||||
wearable->setParamsToDefaults();
|
||||
wearable->setTexturesToDefaults();
|
||||
|
||||
//mark all values (params & images) as saved
|
||||
wearable->saveValues();
|
||||
|
||||
// Send to the dataserver
|
||||
wearable->saveNewAsset();
|
||||
|
||||
|
||||
@@ -61,8 +61,8 @@ public:
|
||||
void* userdata);
|
||||
|
||||
LLWearable* createWearableMatchedToInventoryItem( LLWearable* old_wearable, LLViewerInventoryItem* item );
|
||||
LLWearable* createCopyFromAvatar( LLWearable* old_wearable, const std::string& new_name = std::string() );
|
||||
LLWearable* createCopy( LLWearable* old_wearable );
|
||||
//LLWearable* createCopyFromAvatar( LLWearable* old_wearable, const std::string& new_name = std::string() );
|
||||
LLWearable* createCopy(const LLWearable* old_wearable, const std::string& new_name = std::string());
|
||||
LLWearable* createNewWearable( LLWearableType::EType type );
|
||||
|
||||
// Callback
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llwearabletype.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
struct WearableEntry : public LLDictionaryEntry
|
||||
@@ -150,9 +151,9 @@ BOOL LLWearableType::getDisableCameraSwitch(LLWearableType::EType type)
|
||||
// static
|
||||
BOOL LLWearableType::getAllowMultiwear(LLWearableType::EType type)
|
||||
{
|
||||
return false; //Disabled
|
||||
/*const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
|
||||
const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
|
||||
const WearableEntry *entry = dict->lookup(type);
|
||||
if (!entry) return FALSE;
|
||||
return entry->mAllowMultiwear;*/
|
||||
return entry->mAllowMultiwear;
|
||||
}
|
||||
|
||||
|
||||
@@ -1721,7 +1721,7 @@ ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const
|
||||
const LLViewerObject* pAttachObj = gObjectList.findObject(rlvCmd.getObjectID());
|
||||
if ( (pAttachObj) && (pAttachObj->isAttachment()) )
|
||||
{
|
||||
LLVOAvatar::detachAttachmentIntoInventory(pAttachObj->getAttachmentItemID());
|
||||
LLVOAvatarSelf::detachAttachmentIntoInventory(pAttachObj->getAttachmentItemID());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llattachmentsmgr.h"
|
||||
#include "llfloaterinventory.h"
|
||||
#include "llfloaterwindlight.h"
|
||||
@@ -39,9 +40,6 @@
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
// Defined in llinventorybridge.cpp
|
||||
void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*);
|
||||
|
||||
// ============================================================================
|
||||
// RlvCommmand
|
||||
//
|
||||
@@ -830,6 +828,8 @@ void RlvForceWear::done()
|
||||
return;
|
||||
}
|
||||
|
||||
LLAppearanceMgr* pAppearanceMgr = LLAppearanceMgr::getInstance();
|
||||
|
||||
//
|
||||
// Process removals
|
||||
//
|
||||
@@ -838,20 +838,16 @@ void RlvForceWear::done()
|
||||
if (m_remWearables.size())
|
||||
{
|
||||
for (std::list<const LLWearable*>::const_iterator itWearable = m_remWearables.begin(); itWearable != m_remWearables.end(); ++itWearable)
|
||||
gAgentWearables.removeWearable((*itWearable)->getType(), false, 0); // TODO: MULTI-WEARABLE
|
||||
pAppearanceMgr->removeItemFromAvatar((*itWearable)->getItemID());
|
||||
m_remWearables.clear();
|
||||
}
|
||||
|
||||
// Gestures
|
||||
if (m_remGestures.size())
|
||||
{
|
||||
for (S32 idxGesture = 0, cntGesture = m_remGestures.count(); idxGesture < cntGesture; idxGesture++)
|
||||
{
|
||||
LLViewerInventoryItem* pItem = m_remGestures.get(idxGesture);
|
||||
LLGestureMgr::instance().deactivateGesture(pItem->getUUID());
|
||||
gInventory.updateItem(pItem);
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
// NOTE: LLGestureMgr::deactivateGesture() will call LLAppearanceMgr::removeCOFItemLinks() for us
|
||||
for (S32 idxItem = 0, cntItem = m_remGestures.count(); idxItem < cntItem; idxItem++)
|
||||
LLGestureMgr::instance().deactivateGesture(m_remGestures.get(idxItem)->getUUID());
|
||||
m_remGestures.clear();
|
||||
}
|
||||
|
||||
@@ -871,6 +867,12 @@ void RlvForceWear::done()
|
||||
}
|
||||
gMessageSystem->sendReliable(gAgent.getRegionHost());
|
||||
|
||||
for (std::list<const LLViewerObject*>::const_iterator itAttachObj = m_remAttachments.begin();
|
||||
itAttachObj != m_remAttachments.end(); ++itAttachObj)
|
||||
{
|
||||
pAppearanceMgr->removeCOFItemLinks((*itAttachObj)->getAttachmentItemID(), false);
|
||||
}
|
||||
|
||||
m_remAttachments.clear();
|
||||
}
|
||||
|
||||
@@ -878,48 +880,24 @@ void RlvForceWear::done()
|
||||
// Process additions
|
||||
//
|
||||
|
||||
// Process wearables
|
||||
if (m_addWearables.size())
|
||||
// Wearables need to be split into AT_BODYPART and AT_CLOTHING for COF
|
||||
LLInventoryModel::item_array_t addBodyParts, addClothing;
|
||||
for (addwearables_map_t::const_iterator itAddWearables = m_addWearables.begin(); itAddWearables != m_addWearables.end(); ++itAddWearables)
|
||||
{
|
||||
// [See wear_inventory_category_on_avatar_step2()]
|
||||
LLWearableHoldingPattern* pWearData = new LLWearableHoldingPattern(TRUE);
|
||||
|
||||
// We need to populate 'pWearData->mFoundList' before doing anything else because (some of) the assets might already be available
|
||||
for (addwearables_map_t::const_iterator itAddWearables = m_addWearables.begin();
|
||||
itAddWearables != m_addWearables.end(); ++itAddWearables)
|
||||
const LLInventoryModel::item_array_t& wearItems = itAddWearables->second;
|
||||
for (S32 idxItem = 0, cntItem = wearItems.count(); idxItem < cntItem; idxItem++)
|
||||
{
|
||||
const LLInventoryModel::item_array_t& wearItems = itAddWearables->second;
|
||||
|
||||
RLV_VERIFY(1 == wearItems.count());
|
||||
if (wearItems.count() > 0)
|
||||
LLViewerInventoryItem* pItem = wearItems.get(idxItem);
|
||||
if (!pAppearanceMgr->isLinkInCOF(pItem->getUUID())) // It's important to examine COF here and *not* gAgentWearables
|
||||
{
|
||||
LLViewerInventoryItem* pItem = wearItems.get(0);
|
||||
if ( (pItem) && ((LLAssetType::AT_BODYPART == pItem->getType()) || (LLAssetType::AT_CLOTHING == pItem->getType())) )
|
||||
{
|
||||
LLFoundData* pFound = new LLFoundData(pItem->getLinkedUUID(), pItem->getAssetUUID(), pItem->getName(), pItem->getType());
|
||||
pWearData->mFoundList.push_front(pFound);
|
||||
}
|
||||
if (LLAssetType::AT_BODYPART == pItem->getType())
|
||||
addBodyParts.push_back(pItem);
|
||||
else
|
||||
addClothing.push_back(pItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pWearData->mFoundList.size())
|
||||
{
|
||||
delete pWearData;
|
||||
return;
|
||||
}
|
||||
|
||||
// If all the assets are available locally then "pWearData" will be freed *before* the last "LLWearableList::instance().getAsset()" call returns
|
||||
bool fContinue = true; LLWearableHoldingPattern::found_list_t::const_iterator itWearable = pWearData->mFoundList.begin();
|
||||
while ( (fContinue) && (itWearable != pWearData->mFoundList.end()) )
|
||||
{
|
||||
const LLFoundData* pFound = *itWearable;
|
||||
++itWearable;
|
||||
fContinue = (itWearable != pWearData->mFoundList.end());
|
||||
LLWearableList::instance().getAsset(pFound->mAssetID, pFound->mName, pFound->mAssetType, wear_inventory_category_on_avatar_loop, (void*)pWearData);
|
||||
}
|
||||
|
||||
m_addWearables.clear();
|
||||
}
|
||||
m_addWearables.clear();
|
||||
|
||||
// Until LL provides a way for updateCOF to selectively attach add/replace we have to deal with attachments ourselves
|
||||
for (addattachments_map_t::const_iterator itAddAttachments = m_addAttachments.begin();
|
||||
@@ -929,22 +907,20 @@ void RlvForceWear::done()
|
||||
for (S32 idxItem = 0, cntItem = wearItems.count(); idxItem < cntItem; idxItem++)
|
||||
{
|
||||
const LLUUID& idItem = wearItems.get(idxItem)->getLinkedUUID();
|
||||
// if (gAgentAvatarp->attachmentWasRequested(idItem))
|
||||
// continue;
|
||||
// gAgentAvatarp->addAttachmentRequest(idItem);
|
||||
if (gAgentAvatarp->attachmentWasRequested(idItem))
|
||||
continue;
|
||||
gAgentAvatarp->addAttachmentRequest(idItem);
|
||||
|
||||
LLAttachmentsMgr::instance().addAttachment(idItem, itAddAttachments->first & ~ATTACHMENT_ADD, itAddAttachments->first & ATTACHMENT_ADD);
|
||||
}
|
||||
}
|
||||
m_addAttachments.clear();
|
||||
|
||||
// Process gestures
|
||||
if (m_addGestures.size())
|
||||
// If there are additions we need to call LLAppearanceManager::updateCOF(), otherwise LLAppearanceManager::updateAppearanceFromCOF()
|
||||
if ( (!addBodyParts.empty()) || (!addClothing.empty()) || (!m_addGestures.empty()) )
|
||||
{
|
||||
LLGestureMgr::instance().activateGestures(m_addGestures);
|
||||
for (S32 idxGesture = 0, cntGesture = m_addGestures.count(); idxGesture < cntGesture; idxGesture++)
|
||||
gInventory.updateItem(m_addGestures.get(idxGesture));
|
||||
gInventory.notifyObservers();
|
||||
LLInventoryModel::item_array_t addAttachments;
|
||||
pAppearanceMgr->updateCOF(addBodyParts, addClothing, addAttachments, m_addGestures, true);
|
||||
|
||||
m_addGestures.clear();
|
||||
}
|
||||
|
||||
@@ -200,16 +200,6 @@ void RlvInventory::fetchWornItems()
|
||||
itemFetcher.startFetch();
|
||||
}
|
||||
|
||||
// Checked: 2010-09-27 (RLVa-1.1.3a) | Added: RLVa-1.1.3a
|
||||
void RlvInventory::fetchWornItem(const LLUUID& idItem)
|
||||
{
|
||||
if (idItem.notNull())
|
||||
{
|
||||
RlvItemFetcher itemFetcher(idItem);
|
||||
itemFetcher.startFetch();
|
||||
}
|
||||
}
|
||||
|
||||
// Checked: 2010-04-07 (RLVa-1.2.0a) | Modified: RLVa-1.0.0h
|
||||
bool RlvInventory::findSharedFolders(const std::string& strCriteria, LLInventoryModel::cat_array_t& folders) const
|
||||
{
|
||||
|
||||
@@ -66,7 +66,6 @@ public:
|
||||
public:
|
||||
void fetchSharedInventory();
|
||||
void fetchWornItems();
|
||||
void fetchWornItem(const LLUUID& idItem);
|
||||
protected:
|
||||
void fetchSharedLinks();
|
||||
|
||||
|
||||
@@ -15,15 +15,17 @@
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llagent.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llattachmentsmgr.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "lloutfitobserver.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "pipeline.h"
|
||||
#include "cofmgr.h"
|
||||
#include "llagentwearables.h"
|
||||
|
||||
#include "rlvlocks.h"
|
||||
#include "rlvhelper.h"
|
||||
#include "rlvinventory.h"
|
||||
#include "rlvlocks.h"
|
||||
|
||||
// ============================================================================
|
||||
// RlvAttachPtLookup member functions
|
||||
@@ -1023,7 +1025,7 @@ protected:
|
||||
RlvFolderLocks::RlvFolderLocks()
|
||||
: m_fLookupDirty(false), m_fLockedRoot(false)
|
||||
{
|
||||
LLCOFObserver::instance().addCOFChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this));
|
||||
LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this));
|
||||
RlvInventory::instance().addSharedRootIDChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this));
|
||||
}
|
||||
|
||||
@@ -1272,7 +1274,7 @@ void RlvFolderLocks::refreshLockedLookups() const
|
||||
m_LockedWearableRem.clear();
|
||||
|
||||
LLInventoryModel::item_array_t lockedItems;
|
||||
if (getLockedItems(LLCOFMgr::instance().getCOF(), lockedItems, true))
|
||||
if (getLockedItems(LLAppearanceMgr::instance().getCOF(), lockedItems, true))
|
||||
{
|
||||
for (S32 idxItem = 0, cntItem = lockedItems.count(); idxItem < cntItem; idxItem++)
|
||||
{
|
||||
|
||||
@@ -26,106 +26,4 @@
|
||||
#include "llgesturemgr.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "cofmgr.h"
|
||||
#include "rlvviewer2.h"
|
||||
|
||||
// ============================================================================
|
||||
// From lloutfitobserver.cpp
|
||||
|
||||
LLCOFObserver::LLCOFObserver() :
|
||||
mCOFLastVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
|
||||
{
|
||||
mItemNameHash.finalize();
|
||||
gInventory.addObserver(this);
|
||||
}
|
||||
|
||||
LLCOFObserver::~LLCOFObserver()
|
||||
{
|
||||
if (gInventory.containsObserver(this))
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFObserver::changed(U32 mask)
|
||||
{
|
||||
if (!gInventory.isInventoryUsable())
|
||||
return;
|
||||
|
||||
checkCOF();
|
||||
}
|
||||
|
||||
// static
|
||||
S32 LLCOFObserver::getCategoryVersion(const LLUUID& cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||
if (!cat)
|
||||
return LLViewerInventoryCategory::VERSION_UNKNOWN;
|
||||
|
||||
return cat->getVersion();
|
||||
}
|
||||
|
||||
// static
|
||||
const std::string& LLCOFObserver::getCategoryName(const LLUUID& cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||
if (!cat)
|
||||
return LLStringUtil::null;
|
||||
|
||||
return cat->getName();
|
||||
}
|
||||
|
||||
bool LLCOFObserver::checkCOF()
|
||||
{
|
||||
LLUUID cof = LLCOFMgr::getInstance()->getCOF();
|
||||
if (cof.isNull())
|
||||
return false;
|
||||
|
||||
bool cof_changed = false;
|
||||
LLMD5 item_name_hash = hashDirectDescendentNames(cof);
|
||||
if (item_name_hash != mItemNameHash)
|
||||
{
|
||||
cof_changed = true;
|
||||
mItemNameHash = item_name_hash;
|
||||
}
|
||||
|
||||
S32 cof_version = getCategoryVersion(cof);
|
||||
if (cof_version != mCOFLastVersion)
|
||||
{
|
||||
cof_changed = true;
|
||||
mCOFLastVersion = cof_version;
|
||||
}
|
||||
|
||||
if (!cof_changed)
|
||||
return false;
|
||||
|
||||
mCOFChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LLMD5 LLCOFObserver::hashDirectDescendentNames(const LLUUID& cat_id)
|
||||
{
|
||||
LLInventoryModel::cat_array_t* cat_array;
|
||||
LLInventoryModel::item_array_t* item_array;
|
||||
gInventory.getDirectDescendentsOf(cat_id,cat_array,item_array);
|
||||
LLMD5 item_name_hash;
|
||||
if (!item_array)
|
||||
{
|
||||
item_name_hash.finalize();
|
||||
return item_name_hash;
|
||||
}
|
||||
for (LLInventoryModel::item_array_t::const_iterator iter = item_array->begin();
|
||||
iter != item_array->end();
|
||||
iter++)
|
||||
{
|
||||
const LLViewerInventoryItem *item = (*iter);
|
||||
if (!item)
|
||||
continue;
|
||||
item_name_hash.update(item->getName());
|
||||
}
|
||||
item_name_hash.finalize();
|
||||
return item_name_hash;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -29,35 +29,4 @@
|
||||
|
||||
#include "boost/function.hpp"
|
||||
|
||||
// ============================================================================
|
||||
// From lloutfitobserver.h
|
||||
|
||||
class LLCOFObserver : public LLInventoryObserver, public LLSingleton<LLCOFObserver>
|
||||
{
|
||||
friend class LLSingleton<LLCOFObserver>;
|
||||
protected:
|
||||
LLCOFObserver();
|
||||
public:
|
||||
virtual ~LLCOFObserver();
|
||||
|
||||
virtual void changed(U32 mask);
|
||||
|
||||
typedef boost::signals2::signal<void (void)> signal_t;
|
||||
void addCOFChangedCallback(const signal_t::slot_type& cb) { mCOFChanged.connect(cb); }
|
||||
void addCOFSavedCallback(const signal_t::slot_type& cb) { mCOFSaved.connect(cb); }
|
||||
|
||||
protected:
|
||||
bool checkCOF();
|
||||
static S32 getCategoryVersion(const LLUUID& cat_id);
|
||||
static const std::string& getCategoryName(const LLUUID& cat_id);
|
||||
static LLMD5 hashDirectDescendentNames(const LLUUID& cat_id);
|
||||
|
||||
private:
|
||||
signal_t mCOFChanged;
|
||||
signal_t mCOFSaved;
|
||||
S32 mCOFLastVersion;
|
||||
LLMD5 mItemNameHash;
|
||||
};
|
||||
|
||||
|
||||
#endif // RLV_VIEWER2_H
|
||||
|
||||
@@ -274,13 +274,13 @@
|
||||
name="Deactivate" width="128">
|
||||
<on_click filter="" function="Inventory.DoToSelected" userdata="deactivate" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator name="Attach Separator" />
|
||||
<menu_item_separator name="Wearable And Object Separator" />
|
||||
<menu_item_call bottom_delta="-18" height="18" label="Wear" left="0" mouse_opaque="true"
|
||||
name="Object Wear" width="128">
|
||||
name="Wearable And Object Wear" width="128">
|
||||
<on_click filter="" function="Inventory.DoToSelected" userdata="attach" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom_delta="-18" height="18" label="Add to Worn" left="0" mouse_opaque="true"
|
||||
name="Object Add" width="128">
|
||||
name="Wearable Add" width="128">
|
||||
<on_click filter="" function="Inventory.DoToSelected" userdata="wear_add" />
|
||||
</menu_item_call>
|
||||
<menu bottom_delta="-18" height="18" label="Attach To" left="0" mouse_opaque="true"
|
||||
|
||||
@@ -2319,6 +2319,19 @@ Price to pay for listing must be at least [CURRENCY][MIN_PRICE].
|
||||
Please enter a higher price.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ConfirmItemDeleteHasLinks"
|
||||
type="alertmodal">
|
||||
At least one of the items you has link items that point to it. If you delete this item, its links will permanently stop working. It is strongly advised to delete the links first.
|
||||
|
||||
Are you sure you want to delete these items?
|
||||
<usetemplate
|
||||
name="okcancelbuttons"
|
||||
notext="Cancel"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ConfirmObjectDeleteLock"
|
||||
@@ -4591,6 +4604,18 @@ Would you like to leave Busy Mode before completing this transaction?
|
||||
</form>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ConfirmDeleteProtectedCategory"
|
||||
type="alertmodal">
|
||||
The folder '[FOLDERNAME]' is a system folder. Deleting system folders can cause instability. Are you sure you want to delete it?
|
||||
<usetemplate
|
||||
ignoretext="Confirm before I delete a system folder"
|
||||
name="okcancelignore"
|
||||
notext="Cancel"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ConfirmEmptyTrash"
|
||||
|
||||
@@ -1821,6 +1821,20 @@ Returns a key that is the UUID of the user seated on the prim.
|
||||
|
||||
<!-- mouselook -->
|
||||
<string name="LeaveMouselook">Press ESC to return to World View</string>
|
||||
<!-- use value="" because they have preceding spaces -->
|
||||
<string name="no_transfer" value=" (no transfer)" />
|
||||
<string name="no_modify" value=" (no modify)" />
|
||||
<string name="no_copy" value=" (no copy)" />
|
||||
<string name="temporary" value=" (temporary)" />
|
||||
<string name="worn" value=" (worn)" />
|
||||
<string name="locked" value=" (locked)" />
|
||||
<string name="link" value=" (link)" />
|
||||
<string name="broken_link" value=" (broken_link)" />
|
||||
<string name="LoadingContents">Loading contents...</string>
|
||||
<string name="NoContents">No contents</string>
|
||||
<string name="WornOnAttachmentPoint" value=" (worn on [ATTACHMENT_POINT])" />
|
||||
<string name="LockedOnAttachmentPoint" value=" (locked to [ATTACHMENT_POINT])" />
|
||||
<string name="ActiveGesture" value="[GESLABEL] (active)"/>
|
||||
<string name="Stone">Stone</string>
|
||||
<string name="Metal">Metal</string>
|
||||
<string name="Glass">Glass</string>
|
||||
|
||||
Reference in New Issue
Block a user