static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
{
	LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);

	// Add descendent folders of the "Landmarks" category.
	LLInventoryModel::item_array_t items; // unused
	LLIsType is_category(LLAssetType::AT_CATEGORY);
	gInventory.collectDescendentsIf(
		landmarks_id,
		cats,
		items,
		LLInventoryModel::EXCLUDE_TRASH,
		is_category);

	// Add the "My Favorites" category.
	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
	LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
	if (!favorites_cat)
	{
		LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL;
	}
	else
	{
		cats.push_back(favorites_cat);
	}
}
Пример #2
0
void LLOutfitsList::refreshList(const LLUUID& category_id)
{
	LLInventoryModel::cat_array_t cat_array;
	LLInventoryModel::item_array_t item_array;

	// Collect all sub-categories of a given category.
	LLIsType is_category(LLAssetType::AT_CATEGORY);
	gInventory.collectDescendentsIf(
		category_id,
		cat_array,
		item_array,
		LLInventoryModel::EXCLUDE_TRASH,
		is_category);

	uuid_vec_t vadded;
	uuid_vec_t vremoved;

	// Create added and removed items vectors.
	computeDifference(cat_array, vadded, vremoved);

	// Handle added tabs.
	for (uuid_vec_t::const_iterator iter = vadded.begin();
		 iter != vadded.end();
		 ++iter)
	{
		const LLUUID cat_id = (*iter);
		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
		if (!cat) continue;

		std::string name = cat->getName();

		outfit_accordion_tab_params tab_params(get_accordion_tab_params());
		LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(tab_params);
		if (!tab) continue;
		LLWearableItemsList* wearable_list = LLUICtrlFactory::create<LLWearableItemsList>(tab_params.wearable_list);
		wearable_list->setShape(tab->getLocalRect());
		tab->addChild(wearable_list);

		tab->setName(name);
		tab->setTitle(name);

		// *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated.
		tab->setDisplayChildren(false);
		mAccordion->addCollapsibleCtrl(tab);

		// Start observing the new outfit category.
		LLWearableItemsList* list  = tab->getChild<LLWearableItemsList>("wearable_items_list");
		if (!mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id)))
		{
			// Remove accordion tab if category could not be added to observer.
			mAccordion->removeCollapsibleCtrl(tab);

			// kill removed tab
				tab->die();
			continue;
		}

		// Map the new tab with outfit category UUID.
		mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab));

		tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this,
			_1, _2, _3, cat_id));

		// Setting tab focus callback to monitor currently selected outfit.
		tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id));

		// Setting callback to reset items selection inside outfit on accordion collapsing and expanding (EXT-7875)
		tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::resetItemSelection, this, list, cat_id));

		// force showing list items that don't match current filter(EXT-7158)
		list->setForceShowingUnmatchedItems(true);

		// Setting list commit callback to monitor currently selected wearable item.
		list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1));

		// Setting list refresh callback to apply filter on list change.
		list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1));

		list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));

		// Fetch the new outfit contents.
		cat->fetch();

		// Refresh the list of outfit items after fetch().
		// Further list updates will be triggered by the category observer.
		list->updateList(cat_id);

		// If filter is currently applied we store the initial tab state and
		// open it to show matched items if any.
		if (!sFilterSubString.empty())
		{
			tab->notifyChildren(LLSD().with("action","store_state"));
			tab->setDisplayChildren(true);

			// Setting mForceRefresh flag will make the list refresh its contents
			// even if it is not currently visible. This is required to apply the
			// filter to the newly added list.
			list->setForceRefresh(true);

			list->setFilterSubString(sFilterSubString);
		}
	}

	// Handle removed tabs.
	for (uuid_vec_t::const_iterator iter=vremoved.begin(); iter != vremoved.end(); ++iter)
	{
		outfits_map_t::iterator outfits_iter = mOutfitsMap.find((*iter));
		if (outfits_iter != mOutfitsMap.end())
		{
			const LLUUID& outfit_id = outfits_iter->first;
			LLAccordionCtrlTab* tab = outfits_iter->second;

			// An outfit is removed from the list. Do the following:
			// 1. Remove outfit category from observer to stop monitoring its changes.
			mCategoriesObserver->removeCategory(outfit_id);

			// 2. Remove the outfit from selection.
			deselectOutfit(outfit_id);

			// 3. Remove category UUID to accordion tab mapping.
			mOutfitsMap.erase(outfits_iter);

			// 4. Remove outfit tab from accordion.
			mAccordion->removeCollapsibleCtrl(tab);

			// kill removed tab
			if (tab != NULL)
			{
				tab->die();
			}
		}
	}

	// Get changed items from inventory model and update outfit tabs
	// which might have been renamed.
	const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs();
	for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin();
		 items_iter != changed_items.end();
		 ++items_iter)
	{
		updateOutfitTab(*items_iter);
	}

	mAccordion->sort();
}