Merged with RLVa-1.4.3 tip

Kitty Barnett 2011-11-26 21:09:30 +01:00
commit d5f18eca8b
4 changed files with 66 additions and 15 deletions

View File

@ -207,4 +207,4 @@ fc0cbb86f5bd6e7737159e35aea2c4cf9f619b62 RLVa-1.2.1
a563f7e215c7883c1cfd20908085687a0ed96284 RLVa-1.4.0
40644beae9c4a617504163d5c9f195dc7bfff1b4 RLVa-1.4.1
8787094c309a44ca32b7472acc9217a3c37f00c3 RLVa-1.4.2
9faa527558a1906a5754cd9f4b3641eaa0fd2978 RLVa-1.4.3
11c6c85ddd223bcbd6b3afc53f9a0f5fd349ba65 RLVa-1.4.3

View File

@ -18,6 +18,7 @@
#define RLV_INVENTORY_H
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
#include "llsingleton.h"
#include "llviewerinventory.h"
@ -78,6 +79,8 @@ public:
static S32 getDirectDescendentsFolderCount(const LLInventoryCategory* pFolder);
// Returns the number of direct descendents of the specified folder that have the specified type asset type
static S32 getDirectDescendentsItemCount(const LLInventoryCategory* pFolder, LLAssetType::EType filterType);
// Returns the folder the items of the specified folder should folded into (can be the folder itself)
static const LLUUID& getFoldedParent(const LLUUID& idFolder, bool fCheckComposite);
// A "folded folder" is a folder whose items logically belong to the grandparent rather than the parent
static bool isFoldedFolder(const LLInventoryCategory* pFolder, bool fCheckComposite);
@ -245,6 +248,15 @@ inline LLViewerInventoryCategory* RlvInventory::getSharedRoot() const
return (idRlvRoot.notNull()) ? gInventory.getCategory(idRlvRoot) : NULL;
}
// Checked: 2011-11-26 (RLVa-1.5.4a) | Added: RLVa-1.5.4a
inline const LLUUID& RlvInventory::getFoldedParent(const LLUUID& idFolder, bool fCheckComposite)
{
LLViewerInventoryCategory* pFolder = gInventory.getCategory(idFolder);
while ((pFolder) && (isFoldedFolder(pFolder, fCheckComposite)))
pFolder = gInventory.getCategory(pFolder->getParentUUID());
return (pFolder) ? pFolder->getUUID() : LLUUID::null;
}
// Checked: 2010-03-19 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
inline bool RlvInventory::isFoldedFolder(const LLInventoryCategory* pFolder, bool fCheckComposite)
{

View File

@ -970,7 +970,7 @@ protected:
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
RlvFolderLocks::RlvFolderLocks()
: m_fLookupDirty(false), m_fLockedRoot(false)
: m_fLookupDirty(false), m_fLockedRoot(false), m_cntLockAdd(0), m_cntLockRem(0)
{
LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this));
RlvInventory::instance().addSharedRootIDChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this));
@ -1064,29 +1064,63 @@ bool RlvFolderLocks::getLockedFolders(const folderlock_source_t& lockSource, LLI
return cntFolders != lockFolders.count();
}
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
bool RlvFolderLocks::getLockedItems(const LLUUID& idFolder, LLInventoryModel::item_array_t& lockItems, bool fFollowLinks) const
// Checked: 2011-11-26 (RLVa-1.5.4a) | Modified: RLVa-1.5.4a
bool RlvFolderLocks::getLockedItems(const LLUUID& idFolder, LLInventoryModel::item_array_t& lockItems) const
{
S32 cntItems = lockItems.count();
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
LLFindWearablesEx f(true, true); // Collect all worn wearables and body parts
LLFindWearablesEx f(true, true); // Collect all worn items
gInventory.collectDescendentsIf(idFolder, folders, items, FALSE, f);
LLUUID idPrev; bool fPrevLocked = false;
// Generally several of the worn items will belong to the same folder so we'll cache the results of each lookup
std::map<LLUUID, bool> folderLookups; std::map<LLUUID, bool>::const_iterator itLookup;
bool fItemLocked = false;
for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
{
LLViewerInventoryItem* pItem = items.get(idxItem);
if ( (fFollowLinks) && (LLAssetType::AT_LINK == pItem->getActualType()) )
if (LLAssetType::AT_LINK == pItem->getActualType())
pItem = pItem->getLinkedItem();
if (!pItem)
continue;
if (pItem->getParentUUID() != idPrev)
// Check the actual item's parent folder
const LLUUID& idItemParent = RlvInventory::getFoldedParent(pItem->getParentUUID(), true);
if ((itLookup = folderLookups.find(idItemParent)) != folderLookups.end())
{
idPrev = pItem->getParentUUID();
fPrevLocked = isLockedFolder(idPrev, RLV_LOCK_REMOVE);
fItemLocked = itLookup->second;
}
if (fPrevLocked)
else
{
fItemLocked = isLockedFolder(idItemParent, RLV_LOCK_REMOVE);
folderLookups.insert(std::pair<LLUUID, bool>(idItemParent, fItemLocked));
}
// Check the parent folders of any links to this item that exist under #RLV
if (!fItemLocked)
{
LLInventoryModel::item_array_t itemLinks =
gInventory.collectLinkedItems(pItem->getUUID(), RlvInventory::instance().getSharedRootID());
for (LLInventoryModel::item_array_t::iterator itItemLink = itemLinks.begin();
(itItemLink < itemLinks.end()) && (!fItemLocked); ++itItemLink)
{
LLViewerInventoryItem* pItemLink = *itItemLink;
const LLUUID& idItemLinkParent = (pItemLink) ? RlvInventory::getFoldedParent(pItemLink->getParentUUID(), true) : LLUUID::null;
if ((itLookup = folderLookups.find(idItemLinkParent)) != folderLookups.end())
{
fItemLocked = itLookup->second;
}
else
{
fItemLocked = isLockedFolder(idItemLinkParent, RLV_LOCK_REMOVE);
folderLookups.insert(std::pair<LLUUID, bool>(idItemLinkParent, fItemLocked));
}
}
}
if (fItemLocked)
lockItems.push_back(pItem);
}
@ -1127,12 +1161,17 @@ bool RlvFolderLocks::isLockedFolderEntry(const LLUUID& idFolder, int eSourceType
}
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
bool RlvFolderLocks::isLockedFolder(const LLUUID& idFolder, ERlvLockMask eLockTypeMask, int eSourceTypeMask, folderlock_source_t* plockSource) const
bool RlvFolderLocks::isLockedFolder(LLUUID idFolder, ERlvLockMask eLockTypeMask, int eSourceTypeMask, folderlock_source_t* plockSource) const
{
// Sanity check - if there are no folder locks then we don't have to actually do anything
if (!hasLockedFolder(eLockTypeMask))
return false;
// Folded folders will be locked if their "parent" is locked
idFolder = RlvInventory::getFoldedParent(idFolder, true);
if (idFolder.isNull())
return false;
if (m_fLookupDirty)
refreshLockedLookups();
@ -1221,7 +1260,7 @@ void RlvFolderLocks::refreshLockedLookups() const
m_LockedWearableRem.clear();
LLInventoryModel::item_array_t lockedItems;
if (getLockedItems(LLAppearanceMgr::instance().getCOF(), lockedItems, true))
if (getLockedItems(LLAppearanceMgr::instance().getCOF(), lockedItems))
{
for (S32 idxItem = 0, cntItem = lockedItems.count(); idxItem < cntItem; idxItem++)
{

View File

@ -326,7 +326,7 @@ public:
// Returns TRUE if the attachment (specified by item UUID) is non-detachable as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
bool isLockedAttachment(const LLUUID& idItem) const;
// Returns TRUE if the folder is locked as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
bool isLockedFolder(const LLUUID& idFolder, ERlvLockMask eLock, int eSourceTypeMask = ST_MASK_ANY, folderlock_source_t* plockSource = NULL) const;
bool isLockedFolder(LLUUID idFolder, ERlvLockMask eLock, int eSourceTypeMask = ST_MASK_ANY, folderlock_source_t* plockSource = NULL) const;
// Returns TRUE if the wearable (specified by item UUID) is non-removable as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
bool isLockedWearable(const LLUUID& idItem) const;
@ -353,7 +353,7 @@ public:
*/
protected:
bool getLockedFolders(const folderlock_source_t& lockSource, LLInventoryModel::cat_array_t& lockFolders) const;
bool getLockedItems(const LLUUID& idFolder, LLInventoryModel::item_array_t& lockItems, bool fFollowLinks) const;
bool getLockedItems(const LLUUID& idFolder, LLInventoryModel::item_array_t& lockItems) const;
void onNeedsLookupRefresh();
void refreshLockedLookups() const;