BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
{
	if (!model)
	{
		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;
		}
	}

	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_item_removable(const LLInventoryModel* model, const LLUUID& id)
{
	if (!model)
	{
		return FALSE;
	}

	// Can't delete an item that's in the library.
	if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID()))
	{
		return FALSE;
	}

	// ## Zi: Animation Overrider
	if((model->isObjectDescendentOf(id,AOEngine::instance().getAOFolder())
		&& gSavedPerAccountSettings.getBOOL("ProtectAOFolders"))
//-TT Client LSL Bridge
		|| (model->isObjectDescendentOf(id,FSLSLBridge::instance().getBridgeFolder())
			&& gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder"))
		)
//-TT
		return FALSE;
	// ## Zi: Animation Overrider

	// 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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
	void onTakeOff()
	{
		// Take off selected items if there are any
		if (mOutfitList->hasItemSelected())
		{
			uuid_vec_t selected_uuids;
			mOutfitList->getSelectedItemsUUIDs(selected_uuids);

			for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it)
			{
				if (get_is_item_worn(*it))
				{
					LLAppearanceMgr::instance().removeItemFromAvatar(*it);
				}
			}
		}
		else // or take off the whole selected outfit if no items specified.
		{
			const LLUUID& selected_outfit_id = getSelectedOutfitID();
			if (selected_outfit_id.notNull())
			{
				LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id);
			}
		}
	}
Beispiel #5
0
	bool onEnable(const LLSD& data)
	{
		std::string param = data.asString();
		LLUUID selected_id = mUUIDs.back();

		if ("take_off" == param)
		{
			return get_is_item_worn(selected_id);
		}
		else if ("edit" == param)
		{
			return mUUIDs.size() == 1 && gAgentWearables.isWearableModifiable(selected_id);
		}
		else if ("replace" == param)
		{
			return get_is_item_worn(selected_id) && mUUIDs.size() == 1;
		}

		return true;
	}
// virtual
void LLPanelWearableOutfitItem::updateItem(const std::string& name,
        EItemState item_state)
{
    std::string search_label = name;

    if (mWornIndicationEnabled && get_is_item_worn(mInventoryItemUUID))
    {
        search_label += LLTrans::getString("worn");
        item_state = IS_WORN;
    }

    LLPanelInventoryListItemBase::updateItem(search_label, item_state);
}
// static
bool LLGiveInventory::isInventoryGiveAcceptable(const LLInventoryItem* item)
{
	if (!item) return false;

	if (!isAgentAvatarValid()) return false;

	if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID))
	{
		return false;
	}

	bool acceptable = true;
	switch(item->getType())
	{
	case LLAssetType::AT_OBJECT:
		if (get_is_item_worn(item->getUUID()))
		{
			acceptable = false;
		}
		break;
	case LLAssetType::AT_BODYPART:
	case LLAssetType::AT_CLOTHING:
		{
			BOOL copyable = false;
			if (item->getPermissions().allowCopyBy(gAgentID)) copyable = true;

			if (!copyable && get_is_item_worn(item->getUUID()))
			{
				acceptable = false;
			}
		}
		break;
	default:
		break;
	}
	return acceptable;
}
// 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;
}
//
//Bridge initialization
//
void FSLSLBridge :: recreateBridge()
{
	if (!gSavedSettings.getBOOL("UseLSLBridge"))
		return;

	LLUUID catID = findFSCategory();

	LLViewerInventoryItem* fsBridge = findInvObject(mCurrentFullName, catID, LLAssetType::AT_OBJECT);
	if (fsBridge != NULL)
	{
		if (get_is_item_worn(fsBridge->getUUID()))
		{
			LLVOAvatarSelf::detachAttachmentIntoInventory(fsBridge->getUUID());
		}
	}
	if (mpBridge != NULL)
		mpBridge = NULL; //the object itself will get cleaned up when new one is created.

	initCreationStep();
}
void FSLSLBridge::detachOtherBridges()
{
	LLUUID catID = findFSCategory();
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;

	LLViewerInventoryItem* fsBridge = findInvObject(mCurrentFullName, catID, LLAssetType::AT_OBJECT);

	//detach everything except current valid bridge - if any
	gInventory.collectDescendents(catID,cats,items,FALSE);

	for (S32 iIndex = 0; iIndex < items.count(); iIndex++)
	{
		const LLViewerInventoryItem* itemp = items.get(iIndex);
		if (get_is_item_worn(itemp->getUUID()) &&
			((fsBridge == NULL) || (itemp->getUUID() != fsBridge->getUUID())))
		{
			LLVOAvatarSelf::detachAttachmentIntoInventory(itemp->getUUID());
		}
	}
}
//
//Bridge initialization
//
void FSLSLBridge::recreateBridge()
{
	if (!gSavedSettings.getBOOL("UseLSLBridge"))
	{
		return;
	}

	if (gSavedSettings.getBOOL("NoInventoryLibrary"))
	{
		llwarns << "Asked to create bridge, but we don't have a library. Aborting." << llendl;
		reportToNearbyChat(LLTrans::getString("fsbridge_no_library"));
		mBridgeCreating = false;
		return;
	}

	if (mBridgeCreating)
	{
		llwarns << "Bridge creation already in progress, aborting new attempt." << llendl;
		reportToNearbyChat(LLTrans::getString("fsbridge_already_creating"));
		return;
	}

	LLUUID catID = findFSCategory();

	LLViewerInventoryItem* fsBridge = findInvObject(mCurrentFullName, catID, LLAssetType::AT_OBJECT);
	if (fsBridge != NULL)
	{
		if (get_is_item_worn(fsBridge->getUUID()))
		{
			LLVOAvatarSelf::detachAttachmentIntoInventory(fsBridge->getUUID());
		}
	}
	// clear the stored bridge ID - we are starting over.
	mpBridge = 0; //the object itself will get cleaned up when new one is created.

	initCreationStep();
}
Beispiel #12
0
void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu)
{
    if (!menu)
    {
        llwarns << "Invalid menu" << llendl;
        return;
    }

    const uuid_vec_t& ids = mUUIDs;	// selected items IDs
    U32 mask = 0;					// mask of selected items' types
    U32 n_items = ids.size();		// number of selected items
    U32 n_worn = 0;					// number of worn items among the selected ones
    U32 n_already_worn = 0;			// number of items worn of same type as selected items
    U32 n_links = 0;				// number of links among the selected items
    U32 n_editable = 0;				// number of editable items among the selected ones

    for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
    {
        LLUUID id = *it;
        LLViewerInventoryItem* item = gInventory.getItem(id);

        if (!item)
        {
            llwarns << "Invalid item" << llendl;
            // *NOTE: the logic below may not work in this case
            continue;
        }

        updateMask(mask, item->getType());

        const LLWearableType::EType wearable_type = item->getWearableType();
        const bool is_link = item->getIsLinkType();
        const bool is_worn = get_is_item_worn(id);
        const bool is_editable = gAgentWearables.isWearableModifiable(id);
        const bool is_already_worn = gAgentWearables.selfHasWearable(wearable_type);
        if (is_worn)
        {
            ++n_worn;
        }
        if (is_editable)
        {
            ++n_editable;
        }
        if (is_link)
        {
            ++n_links;
        }
        if (is_already_worn)
        {
            ++n_already_worn;
        }
    } // for

    bool standalone = mParent ? mParent->isStandalone() : false;

    // *TODO: eliminate multiple traversals over the menu items
    setMenuItemVisible(menu, "wear_wear", 			n_already_worn == 0 && n_worn == 0);
    setMenuItemEnabled(menu, "wear_wear", 			n_already_worn == 0 && n_worn == 0);
    setMenuItemVisible(menu, "wear_add",			mask == MASK_CLOTHING && n_worn == 0 && n_already_worn != 0);
    setMenuItemEnabled(menu, "wear_add",			n_items == 1 && canAddWearable(ids.front()) && n_already_worn != 0);
    setMenuItemVisible(menu, "wear_replace",		n_worn == 0 && n_already_worn != 0);
    //visible only when one item selected and this item is worn
    setMenuItemVisible(menu, "edit",				!standalone && mask & (MASK_CLOTHING|MASK_BODYPART) && n_worn == n_items && n_worn == 1);
    setMenuItemEnabled(menu, "edit",				n_editable == 1 && n_worn == 1 && n_items == 1);
    setMenuItemVisible(menu, "create_new",			mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1);
    setMenuItemVisible(menu, "show_original",		!standalone);
    setMenuItemEnabled(menu, "show_original",		n_items == 1 && n_links == n_items);
    setMenuItemVisible(menu, "take_off",			mask == MASK_CLOTHING && n_worn == n_items);
    setMenuItemVisible(menu, "detach",				mask == MASK_ATTACHMENT && n_worn == n_items);
    setMenuItemVisible(menu, "take_off_or_detach",	mask == (MASK_ATTACHMENT|MASK_CLOTHING));
    setMenuItemEnabled(menu, "take_off_or_detach",	n_worn == n_items);
    setMenuItemVisible(menu, "object_profile",		!standalone);
    setMenuItemEnabled(menu, "object_profile",		n_items == 1);
    setMenuItemVisible(menu, "--no options--", 		FALSE);
    setMenuItemEnabled(menu, "--no options--",		FALSE);

    // Populate or hide the "Attach to..." / "Attach to HUD..." submenus.
    if (mask == MASK_ATTACHMENT && n_worn == 0)
    {
        LLViewerAttachMenu::populateMenus("wearable_attach_to", "wearable_attach_to_hud");
    }
    else
    {
        setMenuItemVisible(menu, "wearable_attach_to",			false);
        setMenuItemVisible(menu, "wearable_attach_to_hud",		false);
    }

    if (mask & MASK_UNKNOWN)
    {
        llwarns << "Non-wearable items passed." << llendl;
    }

    U32 num_visible_items = 0;
    for (U32 menu_item_index = 0; menu_item_index < menu->getItemCount(); ++menu_item_index)
    {
        const LLMenuItemGL* menu_item = menu->getItem(menu_item_index);
        if (menu_item && menu_item->getVisible())
        {
            num_visible_items++;
        }
    }
    if (num_visible_items == 0)
    {
        setMenuItemVisible(menu, "--no options--", TRUE);
    }
}
BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
{
	const LLFolderViewEventListener* listener = item->getListener();
	if (!listener) return FALSE;

	LLInventoryType::EType object_type = listener->getInventoryType();
	const LLUUID object_id = listener->getUUID();
	const LLInventoryObject *object = gInventory.getObject(object_id);

	const U32 filterTypes = mFilterOps.mFilterTypes;

	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_OBJECT
	// Pass if this item's type is of the correct filter type
	if (filterTypes & FILTERTYPE_OBJECT)
	{
		// If it has no type, pass it, unless it's a link.
		if (object_type == LLInventoryType::IT_NONE)
		{
			if (object && object->getIsLinkType())
			{
				return FALSE;
			}
		}
		else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
		{
			return FALSE;
		}
	}
	
	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_UUID
	// Pass if this item is the target UUID or if it links to the target UUID
	if (filterTypes & FILTERTYPE_UUID)
	{
		if (!object) return FALSE;

		if (object->getLinkedUUID() != mFilterOps.mFilterUUID)
			return FALSE;
	}

	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_DATE
	// Pass if this item is within the date range.
	if (filterTypes & FILTERTYPE_DATE)
	{
		const U16 HOURS_TO_SECONDS = 3600;
		time_t earliest = time_corrected() - mFilterOps.mHoursAgo * HOURS_TO_SECONDS;
		if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
		{
			earliest = mFilterOps.mMinDate;
		}
		else if (!mFilterOps.mHoursAgo)
		{
			earliest = 0;
		}
		if (listener->getCreationDate() < earliest ||
			listener->getCreationDate() > mFilterOps.mMaxDate)
			return FALSE;
	}

	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_WEARABLE
	// Pass if this item is a wearable of the appropriate type
	if (filterTypes & FILTERTYPE_WEARABLE)
	{
		LLWearableType::EType type = listener->getWearableType();
		if ((0x1LL << type & mFilterOps.mFilterWearableTypes) == 0)
		{
			return FALSE;
		}
	}

	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_WORN
	// Pass if this item is worn (hiding COF and Outfits folders)
	if (filterTypes & FILTERTYPE_WORN)
	{
		if (!object) return FALSE;
		LLUUID cat_id = object->getParentUUID();
		const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
		return !LLAppearanceMgr::instance().getIsInCOF(object_id)
			&& (!cat || cat->getPreferredType() != LLFolderType::FT_OUTFIT)
			&& get_is_item_worn(object_id);
	}

	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_EMPTYFOLDERS
	// Pass if this item is a folder and is not a system folder that should be hidden
	if (filterTypes & FILTERTYPE_EMPTYFOLDERS)
	{
		if (object_type == LLInventoryType::IT_CATEGORY)
		{
			bool is_hidden_if_empty = LLViewerFolderType::lookupIsHiddenIfEmpty(listener->getPreferredType());
			if (is_hidden_if_empty)
			{
				// Force the fetching of those folders so they are hidden iff they really are empty...
				gInventory.fetchDescendentsOf(object_id);
				return FALSE;
			}
		}
	}

	return TRUE;
}
bool FSLSLBridge::lslToViewer(std::string message, LLUUID fromID, LLUUID ownerID)
{
	if (!gSavedSettings.getBOOL("UseLSLBridge"))
	{
		return false;
	}

	lldebugs << message << llendl;
	
	//<FS:TS> FIRE-962: Script controls for built-in AO
	if ((message[0]) != '<')
	{
		return false; 		// quick exit if no leading <
	}
	S32 closebracket = message.find('>');
	S32 firstblank = message.find(' ');
	S32 tagend;
	if (closebracket == std::string::npos)
	{
		tagend = firstblank;
	}
	else if (firstblank == std::string::npos)
	{
		tagend = closebracket;
	}
	else
	{
		tagend = (closebracket < firstblank) ? closebracket : firstblank;
	}
	if (tagend == std::string::npos)
	{
		return false;
	}
	std::string tag = message.substr(0, tagend + 1);
	std::string ourBridge = gSavedPerAccountSettings.getString("FSLSLBridgeUUID");
	//</FS:TS> FIRE-962
	
	bool status = false;
	if (tag == "<bridgeURL>")
	{

		// brutish parsing
		S32 urlStart  = message.find("<bridgeURL>") + 11;
		S32 urlEnd    = message.find("</bridgeURL>");
		S32 authStart = message.find("<bridgeAuth>") + 12;
		S32 authEnd   = message.find("</bridgeAuth>");
		S32 verStart  = message.find("<bridgeVer>") + 11;
		S32 verEnd    = message.find("</bridgeVer>");
		std::string bURL = message.substr(urlStart,urlEnd - urlStart);
		std::string bAuth = message.substr(authStart,authEnd - authStart);
		std::string bVer = message.substr(verStart,verEnd - verStart);

		// Verify Version
		// todo

		// Verify Authorization
		if (ourBridge != bAuth)
		{
			llwarns << "BridgeURL message received from ("<< bAuth <<") , but not from our registered bridge ("<< ourBridge <<"). Ignoring." << llendl;
			// Failing bridge authorization automatically kicks off a bridge rebuild. This correctly handles the
			// case where a user logs in from multiple computers which cannot have the bridgeAuth ID locally 
			// synchronized.
			
			
			// If something that looks like our current bridge is attached but failed auth, detach and recreate.
			LLUUID catID = findFSCategory();
			LLViewerInventoryItem* fsBridge = findInvObject(mCurrentFullName, catID, LLAssetType::AT_OBJECT);
			if (fsBridge != NULL)
			{
				if (get_is_item_worn(fsBridge->getUUID()))
				{
					LLVOAvatarSelf::detachAttachmentIntoInventory(fsBridge->getUUID());
					//This may have been an unfinished bridge. If so - stop the process before recreating.
					if (mBridgeCreating)
						mBridgeCreating = false;
					recreateBridge();
					return true; 
				}
			}
			
			// If something that didn't look like our current bridge failed auth, don't recreate, it might interfere with a bridge creation in progress
			// or normal bridge startup.  Bridge creation isn't threadsafe yet.
			return true;
		}

		// Save the inworld UUID of this attached bridge for later checking
		mBridgeUUID = fromID;
		
		// Get URL
		mCurrentURL = bURL;
		llinfos << "New Bridge URL is: " << mCurrentURL << llendl;
		
		if (mpBridge == NULL)
		{
			LLUUID catID = findFSCategory();
			LLViewerInventoryItem* fsBridge = findInvObject(mCurrentFullName, catID, LLAssetType::AT_OBJECT);
			mpBridge = fsBridge;
		}

		status = viewerToLSL("URL Confirmed", new FSLSLBridgeRequestResponder());
		//updateBoolSettingValue("UseLSLFlightAssist");
		if (!mIsFirstCallDone)
		{
			//on first call from bridge, confirm that we are here
			//then check options use
			updateBoolSettingValue("UseLSLFlightAssist");
			updateBoolSettingValue("FSPublishRadarTag");
			mIsFirstCallDone = true;
		}
		return true;
	}
	
	//<FS:TS> FIRE-962: Script controls for built-in AO
	if (fromID != mBridgeUUID)
	{
		return false;		// ignore if not from the bridge
	}
	if (tag == "<clientAO ")
	{
		status = true;
		S32 valuepos = message.find("state=") + 6;
		if (valuepos != std::string::npos)
		{
			if (message.substr(valuepos, 2) == "on")
			{
				gSavedPerAccountSettings.setBOOL("UseAO", TRUE);
			}
			else if (message.substr(valuepos, 3) == "off")
			{
				gSavedPerAccountSettings.setBOOL("UseAO", FALSE);
			}
		}
	}
	//</FS:TS> FIRE-962
	return status;
}
BOOL get_is_item_worn(const LLUUID& id)
{
	return get_is_item_worn(gInventory.getItem(id));
}
BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
{
	const LLFolderViewEventListener* listener = item->getListener();
	if (!listener) return FALSE;

	LLInventoryType::EType object_type = listener->getInventoryType();
	const LLUUID object_id = listener->getUUID();
	const LLInventoryObject *object = gInventory.getObject(object_id);

	const U32 filterTypes = mFilterOps.mFilterTypes;

	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_OBJECT
	// Pass if this item's type is of the correct filter type
	if (filterTypes & FILTERTYPE_OBJECT)
	{
		// If it has no type, pass it, unless it's a link.
		if (object_type == LLInventoryType::IT_NONE)
		{
			if (object && object->getIsLinkType())
			{
				return FALSE;
			}
		}
		else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
		{
			return FALSE;
		}
	}
	
	
	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_CATEGORY
	// Pass if this item is a category of the filter type, or
	// if its parent is a category of the filter type.
	if (filterTypes & FILTERTYPE_CATEGORY)
	{
		// Can only filter categories for items in your inventory 
		// (e.g. versus in-world object contents).
		if (!object) return FALSE;

		LLUUID cat_id = object_id;
		if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
		{
			cat_id = object->getParentUUID();
		}
		const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
		if (!cat) 
			return FALSE;
		if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0))
			return FALSE;
	}


	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_UUID
	// Pass if this item is the target UUID or if it links to the target UUID
	if (filterTypes & FILTERTYPE_UUID)
	{
		if (!object) return FALSE;

		if (object->getLinkedUUID() != mFilterOps.mFilterUUID)
			return FALSE;
	}


	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_DATE
	// Pass if this item is within the date range.
	if (filterTypes & FILTERTYPE_DATE)
	{
		const U16 HOURS_TO_SECONDS = 3600;
		time_t earliest = time_corrected() - mFilterOps.mHoursAgo * HOURS_TO_SECONDS;
		if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
		{
			earliest = mFilterOps.mMinDate;
		}
		else if (!mFilterOps.mHoursAgo)
		{
			earliest = 0;
		}
		if (listener->getCreationDate() < earliest ||
			listener->getCreationDate() > mFilterOps.mMaxDate)
			return FALSE;
	}

	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_WEARABLE
	// Pass if this item is a wearable of the appropriate type
	if (filterTypes & FILTERTYPE_WEARABLE)
	{
		LLWearableType::EType type = listener->getWearableType();
		if ((0x1LL << type & mFilterOps.mFilterWearableTypes) == 0)
		{
			return FALSE;
		}
	}

	////////////////////////////////////////////////////////////////////////////////
	// FILTERTYPE_WORN
	// Pass if this item is worn (hiding COF and Outfits folders)
	if (filterTypes & FILTERTYPE_WORN)
	{
		if (!object) return FALSE;
		LLUUID cat_id = object->getParentUUID();
		const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
		return !LLAppearanceMgr::instance().getIsInCOF(object_id)
			&& (!cat || cat->getPreferredType() != LLFolderType::FT_OUTFIT)
			&& get_is_item_worn(object_id);
	}
	return TRUE;
}