Files
SingularityViewer/indra/newview/llinventoryfunctions.cpp
Lirusaito 821c03a389 Copy folders support!
Sync with v-d/rlva for Copy folder support
Also, guard against outboxy stuff, like when we're importing, don't show the Marketplace Send menu entry.
Fixed a few comments
Please view this commit with space/tab changes off! There were a lot of retabbing cases that don't need to waste anymore of anyone's time.
2012-11-13 00:06:47 -05:00

1028 lines
26 KiB
C++

/**
* @file llinventoryfunctions.cpp
* @brief Implementation of the inventory view and associated stuff.
*
* $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 <utility> // for std::pair<>
#include "llinventoryfunctions.h"
// library includes
#include "llagent.h"
#include "llagentwearables.h"
#include "llcallingcard.h"
#include "llinventorydefines.h"
#include "llsdserialize.h"
#include "llspinctrl.h"
#include "llui.h"
#include "message.h"
// newview includes
#include "llappearancemgr.h"
#include "llappviewer.h"
//#include "llfirstuse.h"
#include "llfloaterinventory.h"
#include "llfloateroutbox.h"
#include "llfocusmgr.h"
#include "llfolderview.h"
#include "llgesturemgr.h"
#include "lliconctrl.h"
#include "llimview.h"
#include "llinventorybridge.h"
#include "llinventoryclipboard.h"
#include "llinventorymodel.h"
#include "llinventorypanel.h"
#include "lllineeditor.h"
#include "llmarketplacenotifications.h"
#include "llmenugl.h"
#include "llnotificationsutil.h"
#include "llpanelmaininventory.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewnotecard.h"
#include "llpreviewscript.h"
#include "llpreviewsound.h"
#include "llpreviewtexture.h"
#include "llresmgr.h"
#include "llscrollbar.h"
#include "llscrollcontainer.h"
#include "llselectmgr.h"
#include "lltabcontainer.h"
#include "lltooldraganddrop.h"
#include "lluictrlfactory.h"
#include "llviewermessage.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
#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]
BOOL LLInventoryState::sWearNewClothing = FALSE;
LLUUID LLInventoryState::sWearNewClothingTransactionID;
// Generates a string containing the path to the item specified by
// item_id.
void append_path(const LLUUID& id, std::string& path)
{
std::string temp;
const LLInventoryObject* obj = gInventory.getObject(id);
LLUUID parent_id;
if(obj) parent_id = obj->getParentUUID();
std::string forward_slash("/");
while(obj)
{
obj = gInventory.getCategory(parent_id);
if(obj)
{
temp.assign(forward_slash + obj->getName() + temp);
parent_id = obj->getParentUUID();
}
}
path.append(temp);
}
void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name)
{
LLViewerInventoryCategory* cat;
if (!model ||
!get_is_category_renameable(model, cat_id) ||
(cat = model->getCategory(cat_id)) == NULL ||
cat->getName() == new_name)
{
return;
}
LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
new_cat->rename(new_name);
new_cat->updateServer(FALSE);
model->updateCategory(new_cat);
model->notifyObservers();
}
void copy_inventory_category(LLInventoryModel* model,
LLViewerInventoryCategory* cat,
const LLUUID& parent_id,
const LLUUID& root_copy_id)
{
// Create the initial folder
LLUUID new_cat_uuid = gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName());
model->notifyObservers();
// We need to exclude the initial root of the copy to avoid recursively copying the copy, etc...
LLUUID root_id = (root_copy_id.isNull() ? new_cat_uuid : root_copy_id);
// Get the content of the folder
LLInventoryModel::cat_array_t* cat_array;
LLInventoryModel::item_array_t* item_array;
gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array);
// Copy all the items
LLInventoryModel::item_array_t item_array_copy = *item_array;
for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
{
LLInventoryItem* item = *iter;
copy_inventory_item(
gAgent.getID(),
item->getPermissions().getOwner(),
item->getUUID(),
new_cat_uuid,
std::string(),
LLPointer<LLInventoryCallback>(NULL));
}
// Copy all the folders
LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
{
LLViewerInventoryCategory* category = *iter;
if (category->getUUID() != root_id)
{
copy_inventory_category(model, category, new_cat_uuid, root_id);
}
}
}
class LLInventoryCollectAllItems : public LLInventoryCollectFunctor
{
public:
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
return true;
}
};
BOOL get_is_parent_to_worn_item(const LLUUID& id)
{
const LLViewerInventoryCategory* cat = gInventory.getCategory(id);
if (!cat)
{
return FALSE;
}
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLInventoryCollectAllItems 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)
{
const LLViewerInventoryItem * const item = *it;
llassert(item->getIsLinkType());
LLUUID linked_id = item->getLinkedUUID();
const LLViewerInventoryItem * const linked_item = gInventory.getItem(linked_id);
if (linked_item)
{
LLUUID parent_id = linked_item->getParentUUID();
while (!parent_id.isNull())
{
LLInventoryCategory * parent_cat = gInventory.getCategory(parent_id);
if (cat == parent_cat)
{
return TRUE;
}
parent_id = parent_cat->getParentUUID();
}
}
}
return FALSE;
}
BOOL get_is_item_worn(const LLInventoryItem *item)
{
if (!item)
return FALSE;
// Consider the item as worn if it has links in COF.
/* if (LLCOFMgr::instance().isLinkInCOF(item->getUUID()))
{ REMOVED due to advice from Kitty Barnett, looks like it WILL cause trouble on some grids -SG
return TRUE;
} */
switch(item->getType())
{
case LLAssetType::AT_OBJECT:
{
if (isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item->getLinkedUUID()))
return TRUE;
break;
}
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
if(gAgentWearables.isWearingItem(item->getLinkedUUID()))
return TRUE;
break;
case LLAssetType::AT_GESTURE:
if (LLGestureMgr::instance().isGestureActive(item->getLinkedUUID()))
return TRUE;
break;
default:
break;
}
return FALSE;
}
BOOL get_is_item_worn(const LLUUID& id)
{
return get_is_item_worn(gInventory.getItem(id));
}
BOOL get_can_item_be_worn(const LLUUID& id)
{
const LLViewerInventoryItem* item = gInventory.getItem(id);
if (!item)
return FALSE;
if (LLAppearanceMgr::isLinkInCOF(item->getLinkedUUID()))
{
// an item having links in COF (i.e. a worn item)
return FALSE;
}
if (gInventory.isObjectDescendentOf(id, LLAppearanceMgr::instance().getCOF()))
{
// a non-link object in COF (should not normally happen)
return FALSE;
}
const LLUUID trash_id = gInventory.findCategoryUUIDForType(
LLFolderType::FT_TRASH);
// item can't be worn if base obj in trash, see EXT-7015
if (gInventory.isObjectDescendentOf(item->getLinkedUUID(),
trash_id))
{
return false;
}
switch(item->getType())
{
case LLAssetType::AT_OBJECT:
{
if (isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item->getLinkedUUID()))
{
// Already being worn
return FALSE;
}
else
{
// Not being worn yet.
return TRUE;
}
break;
}
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
if(gAgentWearables.isWearingItem(item->getLinkedUUID()))
{
// Already being worn
return FALSE;
}
else
{
// Not being worn yet.
return TRUE;
}
break;
default:
break;
}
return FALSE;
}
BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
{
if (!model)
{
return FALSE;
}
if(id == gInventory.getRootFolderID())
{
return FALSE;
}
// Can't delete an item that's in the library.
if(!model->isObjectDescendentOf(id, gInventory.getRootFolderID()))
{
return FALSE;
}
// 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 (LLAppearanceMgr::instance().getIsProtectedCOFItem(id))
{
if (get_is_item_worn(id))
{
return FALSE;
}
}
// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
if ( (rlv_handler_t::isEnabled()) &&
(RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (!RlvFolderLocks::instance().canRemoveItem(id)) )
{
return FALSE;
}
// [/RLVa:KB]
const LLInventoryObject *obj = model->getItem(id);
if (obj && obj->getIsLinkType())
{
return TRUE;
}
if (get_is_item_worn(id))
{
return FALSE;
}
return TRUE;
}
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
// consider the children.
if (!model)
{
return FALSE;
}
if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID()))
{
return FALSE;
}
// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
if ( ((rlv_handler_t::isEnabled()) &&
(RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (!RlvFolderLocks::instance().canRemoveFolder(id))) )
{
return FALSE;
}
// [/RLVa:KB]
if (!isAgentAvatarValid()) return FALSE;
const LLInventoryCategory* category = model->getCategory(id);
if (!category)
{
return FALSE;
}
const LLFolderType::EType folder_type = category->getPreferredType();
if (LLFolderType::lookupIsProtectedType(folder_type))
{
return FALSE;
}
// Can't delete the outfit that is currently being worn.
if (folder_type == LLFolderType::FT_OUTFIT)
{
const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
if (base_outfit_link && (category == base_outfit_link->getLinkedCategory()))
{
return FALSE;
}
}
return TRUE;
}
BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)
{
if (!model)
{
return FALSE;
}
// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
if ( (rlv_handler_t::isEnabled()) && (model == &gInventory) && (!RlvFolderLocks::instance().canRenameFolder(id)) )
{
return FALSE;
}
// [/RLVa:KB]
LLViewerInventoryCategory* cat = model->getCategory(id);
if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) &&
cat->getOwnerID() == gAgent.getID())
{
return TRUE;
}
return FALSE;
}
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);
}
}
void open_outbox()
{
LLFloaterOutbox::showInstance();
}
LLUUID create_folder_in_outbox_for_item(LLInventoryItem* item, const LLUUID& destFolderId, S32 operation_id)
{
llassert(item);
llassert(destFolderId.notNull());
LLUUID created_folder_id = gInventory.createNewCategory(destFolderId, LLFolderType::FT_NONE, item->getName());
gInventory.notifyObservers();
LLNotificationsUtil::add("OutboxFolderCreated");
return created_folder_id;
}
void move_to_outbox_cb_action(const LLSD& payload)
{
LLViewerInventoryItem * viitem = gInventory.getItem(payload["item_id"].asUUID());
LLUUID dest_folder_id = payload["dest_folder_id"].asUUID();
if (viitem)
{
// when moving item directly into outbox create folder with that name
if (dest_folder_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
{
S32 operation_id = payload["operation_id"].asInteger();
dest_folder_id = create_folder_in_outbox_for_item(viitem, dest_folder_id, operation_id);
}
LLUUID parent = viitem->getParentUUID();
gInventory.changeItemParent(
viitem,
dest_folder_id,
false);
LLUUID top_level_folder = payload["top_level_folder"].asUUID();
if (top_level_folder != LLUUID::null)
{
LLViewerInventoryCategory* category;
while (parent.notNull())
{
LLInventoryModel::cat_array_t* cat_array;
LLInventoryModel::item_array_t* item_array;
gInventory.getDirectDescendentsOf(parent,cat_array,item_array);
LLUUID next_parent;
category = gInventory.getCategory(parent);
if (!category) break;
next_parent = category->getParentUUID();
if (cat_array->empty() && item_array->empty())
{
gInventory.removeCategory(parent);
}
if (parent == top_level_folder)
{
break;
}
parent = next_parent;
}
}
open_outbox();
}
}
void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder, S32 operation_id)
{
// Collapse links directly to items/folders
LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item;
LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory();
if (linked_category != NULL)
{
copy_folder_to_outbox(linked_category, dest_folder, top_level_folder, operation_id);
}
else
{
LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem();
if (linked_item != NULL)
{
inv_item = (LLInventoryItem *) linked_item;
}
// Check for copy permissions
if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
{
// when moving item directly into outbox create folder with that name
if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
{
dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, operation_id);
}
copy_inventory_item(gAgent.getID(),
inv_item->getPermissions().getOwner(),
inv_item->getUUID(),
dest_folder,
inv_item->getName(),
LLPointer<LLInventoryCallback>(NULL));
open_outbox();
}
else
{
LLSD payload;
payload["item_id"] = inv_item->getUUID();
payload["dest_folder_id"] = dest_folder;
payload["top_level_folder"] = top_level_folder;
payload["operation_id"] = operation_id;
LLMarketplaceInventoryNotifications::addNoCopyNotification(payload, move_to_outbox_cb_action);
}
}
}
void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id)
{
// when moving item directly into outbox create folder with that name
if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
{
dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, operation_id);
}
LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item;
gInventory.changeItemParent(
viewer_inv_item,
dest_folder,
false);
}
void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id)
{
LLUUID new_folder_id = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, inv_cat->getName());
gInventory.notifyObservers();
LLInventoryModel::cat_array_t* cat_array;
LLInventoryModel::item_array_t* item_array;
gInventory.getDirectDescendentsOf(inv_cat->getUUID(),cat_array,item_array);
// copy the vector because otherwise the iterator won't be happy if we delete from it
LLInventoryModel::item_array_t item_array_copy = *item_array;
for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
{
LLInventoryItem* item = *iter;
copy_item_to_outbox(item, new_folder_id, top_level_folder, operation_id);
}
LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
{
LLViewerInventoryCategory* category = *iter;
copy_folder_to_outbox(category, new_folder_id, top_level_folder, operation_id);
}
open_outbox();
}
///----------------------------------------------------------------------------
/// LLInventoryCollectFunctor implementations
///----------------------------------------------------------------------------
// static
bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(const LLInventoryItem* item)
{
if (!item)
return false;
switch(item->getType())
{
case LLAssetType::AT_OBJECT:
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
if (!get_is_item_worn(item->getUUID()))
return true;
break;
default:
return true;
break;
}
return false;
}
bool LLIsType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(mType == LLAssetType::AT_CATEGORY)
{
if(cat) return TRUE;
}
if(item)
{
if(item->getType() == mType) return TRUE;
}
return FALSE;
}
bool LLIsNotType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(mType == LLAssetType::AT_CATEGORY)
{
if(cat) return FALSE;
}
if(item)
{
if(item->getType() == mType) return FALSE;
else return TRUE;
}
return TRUE;
}
bool LLIsOfAssetType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(mType == LLAssetType::AT_CATEGORY)
{
if(cat) return TRUE;
}
if(item)
{
if(item->getActualType() == mType) return TRUE;
}
return FALSE;
}
bool LLIsTypeWithPermissions::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(mType == LLAssetType::AT_CATEGORY)
{
if(cat)
{
return TRUE;
}
}
if(item)
{
if(item->getType() == mType)
{
LLPermissions perm = item->getPermissions();
if ((perm.getMaskBase() & mPerm) == mPerm)
{
return TRUE;
}
}
}
return FALSE;
}
bool LLBuddyCollector::operator()(LLInventoryCategory* cat,
LLInventoryItem* item)
{
if(item)
{
if((LLAssetType::AT_CALLINGCARD == item->getType())
&& (!item->getCreatorUUID().isNull())
&& (item->getCreatorUUID() != gAgent.getID()))
{
return true;
}
}
return false;
}
bool LLUniqueBuddyCollector::operator()(LLInventoryCategory* cat,
LLInventoryItem* item)
{
if(item)
{
if((LLAssetType::AT_CALLINGCARD == item->getType())
&& (item->getCreatorUUID().notNull())
&& (item->getCreatorUUID() != gAgent.getID()))
{
mSeen.insert(item->getCreatorUUID());
return true;
}
}
return false;
}
bool LLParticularBuddyCollector::operator()(LLInventoryCategory* cat,
LLInventoryItem* item)
{
if(item)
{
if((LLAssetType::AT_CALLINGCARD == item->getType())
&& (item->getCreatorUUID() == mBuddyID))
{
return TRUE;
}
}
return FALSE;
}
bool LLNameCategoryCollector::operator()(
LLInventoryCategory* cat, LLInventoryItem* item)
{
if(cat)
{
if (!LLStringUtil::compareInsensitive(mName, cat->getName()))
{
return true;
}
}
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)
{
if(item)
{
if((item->getType() == LLAssetType::AT_CLOTHING)
|| (item->getType() == LLAssetType::AT_BODYPART))
{
return TRUE;
}
}
return FALSE;
}
LLFindWearablesEx::LLFindWearablesEx(bool is_worn, bool include_body_parts)
: mIsWorn(is_worn)
, mIncludeBodyParts(include_body_parts)
{}
bool LLFindWearablesEx::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item);
if (!vitem) return false;
// Skip non-wearables.
if (!vitem->isWearableType() && vitem->getType() != LLAssetType::AT_OBJECT)
{
return false;
}
// Skip body parts if requested.
if (!mIncludeBodyParts && vitem->getType() == LLAssetType::AT_BODYPART)
{
return false;
}
// Skip broken links.
if (vitem->getIsBrokenLink())
{
return false;
}
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
///----------------------------------------------------------------------------
bool LLAssetIDMatches ::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
return (item && item->getAssetUUID() == mAssetID);
}
///----------------------------------------------------------------------------
/// LLLinkedItemIDMatches
///----------------------------------------------------------------------------
bool LLLinkedItemIDMatches::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
return (item &&
(item->getIsLinkType()) &&
(item->getLinkedUUID() == mBaseItemID)); // A linked item's assetID will be the compared-to item's itemID.
}
void LLSaveFolderState::setApply(BOOL apply)
{
mApply = apply;
// before generating new list of open folders, clear the old one
if(!apply)
{
clearOpenFolders();
}
}
void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
{
LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
if(!bridge) return;
if(mApply)
{
// we're applying the open state
LLUUID id(bridge->getUUID());
if(mOpenFolders.find(id) != mOpenFolders.end())
{
if (!folder->isOpen())
{
folder->setOpen(TRUE);
}
}
else
{
// keep selected filter in its current state, this is less jarring to user
if (!folder->isSelected() && folder->isOpen())
{
folder->setOpen(FALSE);
}
}
}
else
{
// we're recording state at this point
if(folder->isOpen())
{
mOpenFolders.insert(bridge->getUUID());
}
}
}
void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
{
if (item->getFiltered())
{
item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
}
void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
{
if (folder->getFiltered() && folder->getParentFolder())
{
folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
// if this folder didn't pass the filter, and none of its descendants did
else if (!folder->getFiltered() && !folder->hasFilteredDescendants())
{
folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO);
}
}
void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
{
if (item->getFiltered() && !mItemSelected)
{
item->getRoot()->setSelection(item, FALSE, FALSE);
if (item->getParentFolder())
{
item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
item->getRoot()->scrollToShowSelection();
mItemSelected = TRUE;
}
}
void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
{
if (folder->getFiltered() && !mItemSelected)
{
folder->getRoot()->setSelection(folder, FALSE, FALSE);
if (folder->getParentFolder())
{
folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
folder->getRoot()->scrollToShowSelection();
mItemSelected = TRUE;
}
}
void LLOpenFoldersWithSelection::doItem(LLFolderViewItem *item)
{
if (item->getParentFolder() && item->isSelected())
{
item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
}
void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder)
{
if (folder->getParentFolder() && folder->isSelected())
{
folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
}