Esempio n. 1
0
// Checked: 2011-10-06 (RLVa-1.4.2a) | Added: RLVa-1.4.2a
S32 RlvInventory::getDirectDescendentsFolderCount(const LLInventoryCategory* pFolder)
{
	LLInventoryModel::cat_array_t* pFolders = NULL; LLInventoryModel::item_array_t* pItems = NULL;
	if (pFolder)
		gInventory.getDirectDescendentsOf(pFolder->getUUID(), pFolders, pItems);
	return (pFolders) ? pFolders->size() : 0;
}
// Tell if a listing has one only version folder
bool hasUniqueVersionFolder(const LLUUID& folder_id)
{
	LLInventoryModel::cat_array_t* categories;
	LLInventoryModel::item_array_t* items;
	gInventory.getDirectDescendentsOf(folder_id, categories, items);
	return (categories->size() == 1);
}
S32 LLFloaterMarketplaceListings::getFolderCount()
{
	if (mPanelListings && mRootFolderId.notNull())
	{
		LLInventoryModel::cat_array_t * cats;
		LLInventoryModel::item_array_t * items;
		gInventory.getDirectDescendentsOf(mRootFolderId, cats, items);

		return (cats->size() + items->size());
	}
	else
	{
		return 0;
	}
}
void LLFloaterGesture::done()
{
	//this method can be called twice: for GestureFolder and once after loading all sudir of GestureFolder
	if (gInventory.isCategoryComplete(mGestureFolderID))
	{
		LL_DEBUGS("Gesture")<< "mGestureFolderID loaded" << LL_ENDL;
		// we load only gesture folder without childred.
		LLInventoryModel::cat_array_t* categories;
		LLInventoryModel::item_array_t* items;
		uuid_vec_t unloaded_folders;
		LL_DEBUGS("Gesture")<< "Get subdirs of Gesture Folder...." << LL_ENDL;
		gInventory.getDirectDescendentsOf(mGestureFolderID, categories, items);
		if (categories->empty())
		{
			gInventory.removeObserver(this);
			LL_INFOS("Gesture")<< "Gesture dos NOT contains sub-directories."<< LL_ENDL;
			return;
		}
		LL_DEBUGS("Gesture")<< "There are " << categories->size() << " Folders "<< LL_ENDL;
		for (LLInventoryModel::cat_array_t::iterator it = categories->begin(); it != categories->end(); it++)
		{
			if (!gInventory.isCategoryComplete(it->get()->getUUID()))
			{
				unloaded_folders.push_back(it->get()->getUUID());
				LL_DEBUGS("Gesture")<< it->get()->getName()<< " Folder added to fetchlist"<< LL_ENDL;
			}

		}
		if (!unloaded_folders.empty())
		{
			LL_DEBUGS("Gesture")<< "Fetching subdirectories....." << LL_ENDL;
			setFetchIDs(unloaded_folders);
			startFetch();
		}
		else
		{
			LL_DEBUGS("Gesture")<< "All Gesture subdirectories have been loaded."<< LL_ENDL;
			gInventory.removeObserver(this);
			buildGestureList();
		}
	}
	else
	{
		LL_WARNS("Gesture")<< "Gesture list was NOT loaded"<< LL_ENDL;
	}
}
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)
		{
			LL_WARNS() << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << LL_ENDL;
			// 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->size() + items->size();
		}
	}

	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;
}
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)
	{
		LL_WARNS() << "Category '" << cat->getName() << "' descendents corrupted, fetch failed." << LL_ENDL;
		// 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->size() + items->size();
	
	// 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)
	{
		LL_WARNS() << "Category '" << cat->getName() << "' expected descendentcount:" << expected_num_descendents << " descendents but got descendentcount:" << current_num_known_descendents << LL_ENDL;
		const_cast<LLViewerInventoryCategory *>(cat)->setDescendentCount(current_num_known_descendents);
		return TRUE;
	}
	return FALSE;
}
	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;
	}
void LLPanelLandmarkInfo::populateFoldersList()
{
	// Collect all folders that can contain landmarks.
	LLInventoryModel::cat_array_t cats;
	collectLandmarkFolders(cats);

	mFolderCombo->removeall();

	// Put the "Landmarks" folder first in list.
	LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
	const LLViewerInventoryCategory* lmcat = gInventory.getCategory(landmarks_id);
	if (!lmcat)
	{
		LL_WARNS() << "Cannot find the landmarks folder" << LL_ENDL;
	}
	else
	{
		std::string cat_full_name = getFullFolderName(lmcat);
		mFolderCombo->add(cat_full_name, lmcat->getUUID());
	}

	typedef std::vector<folder_pair_t> folder_vec_t;
	folder_vec_t folders;
	// Sort the folders by their full name.
	for (S32 i = 0; i < cats.size(); i++)
	{
		const LLViewerInventoryCategory* cat = cats.at(i);
		std::string cat_full_name = getFullFolderName(cat);
		folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name));
	}
	sort(folders.begin(), folders.end(), cmp_folders);

	// Finally, populate the combobox.
	for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++)
		mFolderCombo->add(it->second, LLSD(it->first));
}
void LLInventoryCategoriesObserver::changed(U32 mask)
{
	if (!mCategoryMap.size())
		return;

	std::vector<LLUUID> deleted_categories_ids;

	for (category_map_t::iterator iter = mCategoryMap.begin();
		 iter != mCategoryMap.end();
		 ++iter)
	{
		const LLUUID& cat_id = (*iter).first;
		LLCategoryData& cat_data = (*iter).second;
        
		LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
		if (!category)
        {
            LL_WARNS() << "Category : Category id = " << cat_id << " disappeared" << LL_ENDL;
			cat_data.mCallback();
            // Keep track of those deleted categories so we can remove them
            deleted_categories_ids.push_back(cat_id);
			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)
		{
			LL_WARNS() << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << LL_ENDL;
			// 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->size() + items->size();

		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();
	}
    
    // Remove deleted categories from the list
 	for (std::vector<LLUUID>::iterator deleted_id = deleted_categories_ids.begin(); deleted_id != deleted_categories_ids.end(); ++deleted_id)
	{
		removeCategory(*deleted_id);
    }
}