BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
{
	BOOL rv = isInviteAllowed();
	if(rv && category)
	{
		LLInventoryModel::cat_array_t cats;
		LLInventoryModel::item_array_t items;
		LLUniqueBuddyCollector buddies;
		gInventory.collectDescendentsIf(category->getUUID(),
										cats,
										items,
										LLInventoryModel::EXCLUDE_TRASH,
										buddies);
		S32 count = items.count();
		if(count == 0)
		{
			rv = FALSE;
		}
		else if(drop)
		{
			uuid_vec_t ids;
			ids.reserve(count);
			for(S32 i = 0; i < count; ++i)
			{
				ids.push_back(items.get(i)->getCreatorUUID());
			}
			inviteToSession(ids);
		}
	}
	return rv;
}
예제 #2
0
BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop)
{
	if (category)
	{
		LLInventoryModel::cat_array_t cats;
		LLInventoryModel::item_array_t items;
		LLUniqueBuddyCollector buddies;
		gInventory.collectDescendentsIf(category->getUUID(),
										cats,
										items,
										LLInventoryModel::EXCLUDE_TRASH,
										buddies);
		S32 count = items.count();
		if(count == 0)
		{
			return false;
		}
		else if(drop)
		{
			LLDynamicArray<LLUUID> ids;
			for(S32 i = 0; i < count; ++i)
			{
				ids.put(items.get(i)->getCreatorUUID());
			}
			inviteToSession(ids);
		}
	}
	return true;
}
예제 #3
0
void LLFloaterOutbox::updateFolderCount()
{
	if (mOutboxInventoryPanel.get() && mOutboxId.notNull())
	{
		S32 item_count = 0;

		if (mOutboxId.notNull())
		{
			LLInventoryModel::cat_array_t * cats;
			LLInventoryModel::item_array_t * items;
			gInventory.getDirectDescendentsOf(mOutboxId, cats, items);

			item_count = cats->count() + items->count();
		}

		mOutboxItemCount = item_count;
	}
	else
	{
		// If there's no outbox, the number of items in it should be set to 0 for consistency
		mOutboxItemCount = 0;
	}

	if (!mImportBusy)
	{
		updateFolderCountStatus();
	}
}
예제 #4
0
bool LLFriendCardsManager::isItemInAnyFriendsList(const LLViewerInventoryItem* item)
{
	if (item->getType() != LLAssetType::AT_CALLINGCARD)
		return false;

	LLInventoryModel::item_array_t items;
	findMatchedFriendCards(item->getCreatorUUID(), items);

	return items.count() > 0;
}
예제 #5
0
void LLFloaterWorldMap::buildLandmarkIDLists()
{
	LLCtrlListInterface *list = childGetListInterface("landmark combo");
	if (!list)
	{
		return;
	}

    // Delete all but the "None" entry
	S32 list_size = list->getItemCount();
	if (list_size > 1)
	{
		list->selectItemRange(1, -1);
		list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
	}

	mLandmarkItemIDList.reset();
	mLandmarkAssetIDList.reset();

	// Get all of the current landmarks
	mLandmarkAssetIDList.put( LLUUID::null );
	mLandmarkItemIDList.put( LLUUID::null );

	mLandmarkAssetIDList.put( sHomeID );
	mLandmarkItemIDList.put( sHomeID );

	LLInventoryModel::cat_array_t cats;
	LLInventoryModel::item_array_t items;
	LLIsType is_landmark(LLAssetType::AT_LANDMARK);
	gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
									cats,
									items,
									LLInventoryModel::EXCLUDE_TRASH,
									is_landmark);

	std::sort(items.begin(), items.end(), LLViewerInventoryItem::comparePointers());
	
	S32 count = items.count();
	for(S32 i = 0; i < count; ++i)
	{
		LLInventoryItem* item = items.get(i);

		list->addSimpleElement(item->getName(), ADD_BOTTOM, item->getUUID());

		mLandmarkAssetIDList.put( item->getAssetUUID() );
		mLandmarkItemIDList.put( item->getUUID() );
	}
	list->sortByColumn(std::string("landmark name"), TRUE);

	list->selectFirstItem();
}
예제 #6
0
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());
    }
}
예제 #7
0
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());
    }
}
예제 #8
0
// Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d
S32 RlvInventory::getDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType filterType)
{
	S32 cntType = 0;
	if (pFolder)
	{
		LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems;
		gInventory.getDirectDescendentsOf(pFolder->getUUID(), pFolders, pItems);

		if (pItems)
		{
			for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++)
				if (pItems->get(idxItem)->getType() == filterType)
					cntType++;
		}
	}
	return cntType;
}
예제 #9
0
bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)
{
	S32 version = LLViewerInventoryCategory::VERSION_UNKNOWN;
	S32 current_num_known_descendents = LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN;
	bool can_be_added = true;

	LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
	// If category could not be retrieved it might mean that
	// inventory is unusable at the moment so the category is
	// stored with VERSION_UNKNOWN and DESCENDENT_COUNT_UNKNOWN,
	// it may be updated later.
	if (category)
	{
		// Inventory category version is used to find out if some changes
		// to a category have been made.
		version = category->getVersion();

		LLInventoryModel::cat_array_t* cats;
		LLInventoryModel::item_array_t* items;
		gInventory.getDirectDescendentsOf(cat_id, cats, items);
		if (!cats || !items)
		{
			llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl;
			// NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean
			// that the cat just doesn't have any items or subfolders).
			// Unrecoverable, so just return "false" meaning that the category can't be observed.
			can_be_added = false;

			llassert(cats != NULL && items != NULL);
		}
		else
		{
			current_num_known_descendents = cats->count() + items->count();
		}
	}

	if (can_be_added)
	{
		mCategoryMap.insert(category_map_value_t(
								cat_id,LLCategoryData(cat_id, cb, version, current_num_known_descendents)));
	}

	return can_be_added;
}
예제 #10
0
BOOL LLInventoryFetchDescendentsObserver::isCategoryComplete(const LLViewerInventoryCategory* cat) const
{
	const S32 version = cat->getVersion();
	const S32 expected_num_descendents = cat->getDescendentCount();
	if ((version == LLViewerInventoryCategory::VERSION_UNKNOWN) ||
		(expected_num_descendents == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN))
	{
		return FALSE;
	}
	// it might be complete - check known descendents against
	// currently available.
	LLInventoryModel::cat_array_t* cats;
	LLInventoryModel::item_array_t* items;
	gInventory.getDirectDescendentsOf(cat->getUUID(), cats, items);
	if (!cats || !items)
	{
		llwarns << "Category '" << cat->getName() << "' descendents corrupted, fetch failed." << llendl;
		// NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean
		// that the cat just doesn't have any items or subfolders).
		// Unrecoverable, so just return done so that this observer can be cleared
		// from memory.
		return TRUE;
	}
	const S32 current_num_known_descendents = cats->count() + items->count();
	
	// Got the number of descendents that we were expecting, so we're done.
	if (current_num_known_descendents == expected_num_descendents)
	{
		return TRUE;
	}

	// Error condition, but recoverable.  This happens if something was added to the
	// category before it was initialized, so accountForUpdate didn't update descendent
	// count and thus the category thinks it has fewer descendents than it actually has.
	if (current_num_known_descendents >= expected_num_descendents)
	{
		llwarns << "Category '" << cat->getName() << "' expected descendentcount:" << expected_num_descendents << " descendents but got descendentcount:" << current_num_known_descendents << llendl;
		const_cast<LLViewerInventoryCategory *>(cat)->setDescendentCount(current_num_known_descendents);
		return TRUE;
	}
	return FALSE;
}
void LLFloaterOutbox::updateFolderCount()
{
    S32 item_count = 0;

    if (mOutboxId.notNull())
    {
        LLInventoryModel::cat_array_t * cats;
        LLInventoryModel::item_array_t * items;
        gInventory.getDirectDescendentsOf(mOutboxId, cats, items);

        item_count = cats->count() + items->count();
    }

    mOutboxItemCount = item_count;

    if (!mImportBusy)
    {
        updateFolderCountStatus();
    }
}
예제 #12
0
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);
        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);
}
예제 #13
0
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);
    }
}
예제 #14
0
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.0.0h
void RlvInventory::fetchSharedLinks()
{
	// TOFIX-RLVa: [RLVa-1.2.1] Finish adding support for AT_LINK_FOLDER
	const LLViewerInventoryCategory* pRlvRoot = getSharedRoot();
	if (!pRlvRoot)
		return;

	// Grab all the inventory links under the shared root
	LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; RlvIsLinkType f;
	gInventory.collectDescendentsIf(pRlvRoot->getUUID(), folders, items, FALSE, f, FALSE);

	// Add them to the "to fetch" list based on link type
	uuid_vec_t idFolders, idItems;
	for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
	{
		const LLViewerInventoryItem* pItem = items.get(idxItem);
		switch (pItem->getActualType())
		{
			case LLAssetType::AT_LINK:
				idItems.push_back(pItem->getLinkedUUID());
				break;
			case LLAssetType::AT_LINK_FOLDER:
				idFolders.push_back(pItem->getLinkedUUID());
				break;
			default:
				break;;
		}
	}

	RLV_INFOS << "Starting link target fetch of " << idItems.size() << " items and " << idFolders.size() << " folders" << RLV_ENDL;

	// Fetch all the link item targets
	RlvItemFetcher itemFetcher(idItems);
	itemFetcher.startFetch();

	// Fetch all the link folder targets
	// TODO!
}
예제 #15
0
// Checked: 2010-03-14 (RLVa-1.1.3a) | Added: RLVa-1.2.0a
void RlvRenameOnWearObserver::doneIdle()
{
	const LLViewerInventoryCategory* pRlvRoot = NULL; LLVOAvatar* pAvatar = gAgentAvatarp;
	if ( (RlvSettings::getEnableSharedWear()) || (!RlvSettings::getSharedInvAutoRename()) || (LLStartUp::getStartupState() < STATE_STARTED) || 
		 (!pAvatar) || ((pRlvRoot = RlvInventory::instance().getSharedRoot()) == NULL) )
	{
		delete this;
		return;
	}

	const LLViewerJointAttachment* pAttachPt = NULL; S32 idxAttachPt = 0;
//	RLV_ASSERT(mComplete.size() > 0);	// Catch instances where we forgot to call startFetch()
	for (uuid_vec_t::const_iterator itItem = mComplete.begin(); itItem != mComplete.end(); ++itItem)
	{
		const LLUUID& idAttachItem = *itItem;

		// If the item resides under #RLV we'll rename it directly; otherwise settle for "renaming" all of its links residing under #RLV
		LLInventoryModel::item_array_t items;
		if (gInventory.isObjectDescendentOf(idAttachItem, pRlvRoot->getUUID()))
			items.push_back(gInventory.getItem(idAttachItem));
		else
			items = gInventory.collectLinkedItems(idAttachItem, pRlvRoot->getUUID());
		if (items.empty())
			continue;

		if ( ((pAttachPt = pAvatar->getWornAttachmentPoint(idAttachItem)) == NULL) ||
			 ((idxAttachPt = RlvAttachPtLookup::getAttachPointIndex(pAttachPt)) == 0) )
		{
//			RLV_ASSERT(false);
			continue;
		}

		static const std::string &new_category_name = LLViewerFolderType::lookupNewCategoryName(LLFolderType::FT_NONE);
		for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
		{
			LLViewerInventoryItem* pItem = items.get(idxItem);
			if (!pItem)
				continue;

			S32 idxAttachPtItem = RlvAttachPtLookup::getAttachPointIndex(pItem);
			if ( (idxAttachPt == idxAttachPtItem) || (idxAttachPtItem) )
				continue;

			std::string strAttachPt = pAttachPt->getName();
			LLStringUtil::toLower(strAttachPt);

			// If we can modify the item then we rename it directly, otherwise we create a new folder and move it
			if (pItem->getPermissions().allowModifyBy(gAgent.getID()))
			{
				std::string strName = pItem->getName();
				LLStringUtil::truncate(strName, DB_INV_ITEM_NAME_STR_LEN - strAttachPt.length() - 3);

				strName += " (" + strAttachPt + ")";

				pItem->rename(strName);
				pItem->updateServer(FALSE);
				gInventory.addChangedMask(LLInventoryObserver::LABEL, pItem->getUUID());
			}
			else
			{
				// Don't do anything if the item is a direct descendant of the shared root, or a folded folder
				LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID());
				if ( (pFolder) && (pFolder->getUUID() != pRlvRoot->getUUID()) && (!RlvInventory::isFoldedFolder(pFolder, false)) )
				{
					std::string strFolderName = ".(" + strAttachPt + ")";

					// Rename the item's parent folder if it's called "New Folder", isn't directly under #RLV and contains exactly 1 object
					if ( (new_category_name == pFolder->getName()) && 
						 (pFolder->getParentUUID() != pRlvRoot->getUUID()) && 
						 (1 == RlvInventory::getDirectDescendentsCount(pFolder, LLAssetType::AT_OBJECT)) )
					{
						pFolder->rename(strFolderName);
						pFolder->updateServer(FALSE);
						gInventory.addChangedMask(LLInventoryObserver::LABEL, pFolder->getUUID());
					}
					else
					{
						// "No modify" item with a non-renameable parent: create a new folder named and move the item into it
						LLUUID idAttachFolder = gInventory.createNewCategory(pFolder->getUUID(), LLFolderType::FT_NONE, strFolderName);
						move_inventory_item(gAgent.getID(), gAgent.getSessionID(), pItem->getUUID(), idAttachFolder, std::string(), NULL);
					}
				}
			}
		}
	}
	gInventory.notifyObservers();

	delete this;
}
예제 #16
0
// Checked: 2010-03-21 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAction eAction, EWearFlags eFlags)
{
	// [See LLWearableBridge::wearOnAvatar(): don't wear anything until initial wearables are loaded, can destroy clothing items]
	if (!gAgentWearables.areWearablesLoaded())
	{
		LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded");
		return;
	}
	if (!isAgentAvatarValid())
		return;

	// Grab a list of all the items we'll be wearing/attaching
	LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
	RlvWearableItemCollector f(pFolder, eAction, eFlags);
	gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, f, TRUE);

	// TRUE if we've already encountered this LLWearableType::EType (used only on wear actions and only for AT_CLOTHING)
	bool fSeenWType[LLWearableType::WT_COUNT] = { false };

	EWearAction eCurAction = eAction;
	for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
	{
		LLViewerInventoryItem* pRlvItem = items.get(idxItem);
		LLViewerInventoryItem* pItem = (LLAssetType::AT_LINK == pRlvItem->getActualType()) ? pRlvItem->getLinkedItem() : pRlvItem;

		// If it's wearable it should be worn on detach
//		if ( (ACTION_DETACH == eAction) && (isWearableItem(pItem)) && (!isWearingItem(pItem)) )
//			continue;

		// Each folder can specify its own EWearAction override
		if (isWearAction(eAction))
			eCurAction = f.getWearAction(pRlvItem->getParentUUID());
		else
			eCurAction = eAction;

		//  NOTES: * if there are composite items then RlvWearableItemCollector made sure they can be worn (or taken off depending)
		//         * some scripts issue @remattach=force,attach:worn-items=force so we need to attach items even if they're currently worn
		switch (pItem->getType())
		{
			case LLAssetType::AT_BODYPART:
				RLV_ASSERT(isWearAction(eAction));	// RlvWearableItemCollector shouldn't be supplying us with body parts on detach
			case LLAssetType::AT_CLOTHING:
				if (isWearAction(eAction))
				{
					// The first time we encounter any given clothing type we use 'eCurAction' (replace or add)
					// The second time we encounter a given clothing type we'll always add (rather than replace the previous iteration)
					eCurAction = (!fSeenWType[pItem->getWearableType()]) ? eCurAction : ACTION_WEAR_ADD;

					ERlvWearMask eWearMask = gRlvWearableLocks.canWear(pRlvItem);
					if ( ((ACTION_WEAR_REPLACE == eCurAction) && (eWearMask & RLV_WEAR_REPLACE)) ||
						 ((ACTION_WEAR_ADD == eCurAction) && (eWearMask & RLV_WEAR_ADD)) )
					{
						// The check for whether we're replacing a currently worn composite item happens in onWearableArrived()
						if (!isAddWearable(pItem))
							addWearable(pRlvItem, eCurAction);
						fSeenWType[pItem->getWearableType()] = true;
					}
				}
				else
				{
					const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(pItem->getUUID());
					if ( (pWearable) && (isForceRemovable(pWearable, false)) )
						remWearable(pWearable);
				}
				break;

			case LLAssetType::AT_OBJECT:
				if (isWearAction(eAction))
				{
					ERlvWearMask eWearMask = gRlvAttachmentLocks.canAttach(pRlvItem);
					if ( ((ACTION_WEAR_REPLACE == eCurAction) && (eWearMask & RLV_WEAR_REPLACE)) ||
						 ((ACTION_WEAR_ADD == eCurAction) && (eWearMask & RLV_WEAR_ADD)) )
					{
						if (!isAddAttachment(pRlvItem))
						{
							#ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
							// We still need to check whether we're about to replace a currently worn composite item
							// (which we're not if we're just reattaching an attachment we're already wearing)
							LLViewerInventoryCategory* pCompositeFolder = NULL;
							if ( (pAttachPt->getObject()) && (RlvSettings::getEnableComposites()) && 
								 (pAttachPt->getItemID() != pItem->getUUID()) &&
								 (gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pCompositeFolder)) )
							{
								// If we can't take off the composite folder this item would replace then don't allow it to get attached
								if (gRlvHandler.canTakeOffComposite(pCompositeFolder))
								{
									forceFolder(pCompositeFolder, ACTION_DETACH, FLAG_DEFAULT);
									addAttachment(pRlvItem);
								}
							}
							else
							#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
							{
								addAttachment(pRlvItem, eCurAction);
							}
						}
					}
				}
				else
				{
					const LLViewerObject* pAttachObj = gAgentAvatarp->getWornAttachment(pItem->getUUID());
					if ( (pAttachObj) && (isForceDetachable(pAttachObj, false)) )
						remAttachment(pAttachObj);
				}
				break;

			#ifdef RLV_EXTENSION_FORCEWEAR_GESTURES
			case LLAssetType::AT_GESTURE:
				if (isWearAction(eAction))
				{
					if (std::find_if(m_addGestures.begin(), m_addGestures.end(), RlvPredIsEqualOrLinkedItem(pRlvItem)) == m_addGestures.end())
						m_addGestures.push_back(pRlvItem);
				}
				else
				{
					if (std::find_if(m_remGestures.begin(), m_remGestures.end(), RlvPredIsEqualOrLinkedItem(pRlvItem)) == m_remGestures.end())
						m_remGestures.push_back(pRlvItem);
				}
				break;
			#endif // RLV_EXTENSION_FORCEWEAR_GESTURES

			default:
				break;
		}
	}
}
예제 #17
0
    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);
            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;
    }
예제 #18
0
void LLFloaterWorldMap::buildLandmarkIDLists()
{
	LLCtrlListInterface *list = mListLandmarkCombo;
	if (!list) return;
	
    // Delete all but the "None" entry
	S32 list_size = list->getItemCount();
	if (list_size > 1)
	{
		list->selectItemRange(1, -1);
		list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
	}
	
	mLandmarkItemIDList.reset();
	mLandmarkAssetIDList.reset();
	
	// Get all of the current landmarks
	mLandmarkAssetIDList.put( LLUUID::null );
	mLandmarkItemIDList.put( LLUUID::null );
	
	mLandmarkAssetIDList.put( sHomeID );
	mLandmarkItemIDList.put( sHomeID );
	
	LLInventoryModel::cat_array_t cats;
	LLInventoryModel::item_array_t items;
	LLIsType is_landmark(LLAssetType::AT_LANDMARK);
	gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
									cats,
									items,
									LLInventoryModel::EXCLUDE_TRASH,
									is_landmark);
	
	std::sort(items.begin(), items.end(), LLViewerInventoryItem::comparePointers());
	std::list<LLInventoryItem*> usedLMs;

	BOOL filterLandmarks = gSavedSettings.getBOOL("WorldmapFilterDuplicateLandmarks");
	S32 count = items.count();
	for(S32 i = 0; i < count; ++i)
	{
		LLInventoryItem* item = items.get(i);

		if (filterLandmarks)
		{
			bool skip = false;
			for (std::list<LLInventoryItem*>::iterator it = usedLMs.begin(); it != usedLMs.end(); ++it)
			{
				if ((*it)->getAssetUUID() == item->getAssetUUID())
				{
					skip = true;
					break;
				}
			}
			if (skip) continue;
			usedLMs.push_front(item);
		}
		
		list->addSimpleElement(item->getName(), ADD_BOTTOM, item->getUUID());
		
		mLandmarkAssetIDList.put( item->getAssetUUID() );
		mLandmarkItemIDList.put( item->getUUID() );
	}
	
	list->selectFirstItem();
}
예제 #19
0
void LLInventoryCategoriesObserver::changed(U32 mask)
{
	if (!mCategoryMap.size())
		return;

	for (category_map_t::iterator iter = mCategoryMap.begin();
		 iter != mCategoryMap.end();
		 ++iter)
	{
		const LLUUID& cat_id = (*iter).first;

		LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
		if (!category)
			continue;

		const S32 version = category->getVersion();
		const S32 expected_num_descendents = category->getDescendentCount();
		if ((version == LLViewerInventoryCategory::VERSION_UNKNOWN) ||
			(expected_num_descendents == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN))
		{
			continue;
		}

		// Check number of known descendents to find out whether it has changed.
		LLInventoryModel::cat_array_t* cats;
		LLInventoryModel::item_array_t* items;
		gInventory.getDirectDescendentsOf(cat_id, cats, items);
		if (!cats || !items)
		{
			llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl;
			// NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean
			// that the cat just doesn't have any items or subfolders).
			// Unrecoverable, so just skip this category.

			llassert(cats != NULL && items != NULL);

			continue;
		}
		
		const S32 current_num_known_descendents = cats->count() + items->count();

		LLCategoryData& cat_data = (*iter).second;

		bool cat_changed = false;

		// If category version or descendents count has changed
		// update category data in mCategoryMap
		if (version != cat_data.mVersion || current_num_known_descendents != cat_data.mDescendentsCount)
		{
			cat_data.mVersion = version;
			cat_data.mDescendentsCount = current_num_known_descendents;
			cat_changed = true;
		}

		// If any item names have changed, update the name hash 
		// Only need to check if (a) name hash has not previously been
		// computed, or (b) a name has changed.
		if (!cat_data.mIsNameHashInitialized || (mask & LLInventoryObserver::LABEL))
		{
			LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cat_id);
			if (cat_data.mItemNameHash != item_name_hash)
			{
				cat_data.mIsNameHashInitialized = true;
				cat_data.mItemNameHash = item_name_hash;
				cat_changed = true;
			}
		}

		// If anything has changed above, fire the callback.
		if (cat_changed)
			cat_data.mCallback();
	}
}
예제 #20
0
void LLFloaterClothing::buildClothingList()
{
	//llinfos << "buildClothingList" << llendl;

	LLScrollListCtrl* list = gUICtrlFactory->getScrollListByName(this, "clothing_list");
	if (!list) return;

	list->operateOnAll(LLCtrlListInterface::OP_DELETE);

	LLInventoryModel::cat_array_t cats;
	LLInventoryModel::item_array_t items;

	LLIsClothing is_clothing;
	gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
									cats,
									items,
									LLInventoryModel::EXCLUDE_TRASH,
									is_clothing);

	S32 count = items.count();
	for(S32 i = 0; i < count; ++i)
	{
		LLInventoryItem* item = items.get(i);

		LLSD row;
		row["id"] = item->getUUID();

		BOOL item_is_multi = FALSE;
		if ( item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS )
		{
			item_is_multi = TRUE;
		}

		LLUUID image_id = get_item_icon_uuid(item->getType(),
											 item->getInventoryType(),
											 item->getFlags(), item_is_multi);		// flags = wearable type
		row["columns"][0]["column"] = "icon";
		row["columns"][0]["type"] = "icon";
		row["columns"][0]["value"] = image_id;

		LLString text = item->getName();
		LLString style = "NORMAL";
		if( gAgent.isWearingItem( item->getUUID() ) )
		{
			text.append(" (worn)");
			style = "BOLD";
		}
		row["columns"][1]["column"] = "name";
		row["columns"][1]["value"] = text;
		row["columns"][1]["font"] = "SANSSERIFSMALL";
		row["columns"][1]["font-style"] = style;

		// hidden column for sorting
		U32 flags = item->getFlags();	// flags = wearable type
		enum EWearableType wearable_type = (enum EWearableType)flags;
		const char* wearable_label = LLWearable::typeToTypeLabel(wearable_type);
		//line->addColumn(wearable_label, FONT, -1);	// invisible
		row["columns"][2]["column"] = "sort";
		row["columns"][2]["value"] = wearable_label;

		list->addElement(row);
	}

	if (count > 0)
	{
		mAllowSelection = TRUE;
	}
	else if (LLInventoryModel::backgroundFetchActive())
	{
		// We're loading
		list->addCommentText(LOADING_STRING);
		mAllowSelection = FALSE;
	}
	else
	{
		// Weird case, we're done loading but have no clothing
		list->addCommentText("No clothing found.");
		mAllowSelection = FALSE;
	}
}
예제 #21
0
bool LLFriendCardsManager::isObjDirectDescendentOfCategory(const LLInventoryObject* obj, 
	const LLViewerInventoryCategory* cat) const
{
	// we need both params to proceed.
	if ( !obj || !cat )
		return false;

	// Need to check that target category is in the Calling Card/Friends folder. 
	// In other case function returns unpredictable result.
	if ( !isCategoryInFriendFolder(cat) )
		return false;

	bool result = false;

	LLInventoryModel::item_array_t* items;
	LLInventoryModel::cat_array_t* cats;

	gInventory.lockDirectDescendentArrays(cat->getUUID(), cats, items);
	if ( items )
	{
		if ( obj->getType() == LLAssetType::AT_CALLINGCARD )
		{
			// For CALLINGCARD compare items by creator's id, if they are equal assume
			// that it is same card and return true. Note: UUID's of compared items
			// may be not equal. Also, we already know that obj should be type of LLInventoryItem,
			// but in case inventory database is broken check what dynamic_cast returns.
			const LLInventoryItem* item = dynamic_cast < const LLInventoryItem* > (obj);
			if ( item )
			{
				LLUUID creator_id = item->getCreatorUUID();
				LLViewerInventoryItem* cur_item = NULL;
				for ( S32 i = items->count() - 1; i >= 0; --i )
				{
					cur_item = items->get(i);
					if ( creator_id == cur_item->getCreatorUUID() )
					{
						result = true;
						break;
					}
				}
			}
		}
		else
		{
			// Else check that items have same type and name.
			// Note: UUID's of compared items also may be not equal.
			std::string obj_name = obj->getName();
			LLViewerInventoryItem* cur_item = NULL;
			for ( S32 i = items->count() - 1; i >= 0; --i )
			{
				cur_item = items->get(i);
				if ( obj->getType() != cur_item->getType() )
					continue;
				if ( obj_name == cur_item->getName() )
				{
					result = true;
					break;
				}
			}
		}
	}
	if ( !result && cats )
	{
		// There is no direct descendent in items, so check categories.
		// If target obj and descendent category have same type and name
		// then return true. Note: UUID's of compared items also may be not equal.
		std::string obj_name = obj->getName();
		LLViewerInventoryCategory* cur_cat = NULL;
		for ( S32 i = cats->count() - 1; i >= 0; --i )
		{
			cur_cat = cats->get(i);
			if ( obj->getType() != cur_cat->getType() )
				continue;
			if ( obj_name == cur_cat->getName() )
			{
				result = true;
				break;
			}
		}
	}
	gInventory.unlockDirectDescendentArrays(cat->getUUID());

	return result;
}