Example #1
0
// static
void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id)
{
    LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id);
    if (!item || !item->isWearableType()) return;

    LLAgentWearables::createWearable(item->getWearableType(), true);
}
void LLMakeOutfitDialog::getIncludedItems(LLInventoryModel::item_array_t& item_list)
{
	LLInventoryModel::cat_array_t *cats;
	LLInventoryModel::item_array_t *items;
	gInventory.getDirectDescendentsOf(LLAppearanceMgr::instance().getCOF(), cats, items);
	for (LLInventoryModel::item_array_t::const_iterator iter = items->begin(); iter != items->end(); ++iter)
	{
		LLViewerInventoryItem* item = (*iter);
		if (!item)
			continue;
		if (item->isWearableType())
		{
			LLWearableType::EType type = item->getWearableType();
			if (type < LLWearableType::WT_COUNT && childGetValue(mCheckBoxList[type].first).asBoolean())
			{
				item_list.push_back(item);
			}
		}
		else
		{
			LLViewerJointAttachment* attachment = gAgentAvatarp->getWornAttachmentPoint(item->getLinkedUUID());
			if (attachment && childGetValue(std::string("checkbox_")+attachment->getName()).asBoolean())
			{
				item_list.push_back(item);
			}
		}
	}
}
void LLPanelOutfitEdit::onReplaceMenuItemClicked(LLUUID selected_item_id)
{
	LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id);

	if (item)
	{
		showFilteredWearablesListView(item->getWearableType());
	}
}
Example #4
0
// Can we wear another wearable of the given item's wearable type?
// static
bool LLWearableItemsList::ContextMenu::canAddWearable(const LLUUID& item_id)
{
    // TODO: investigate wearables may not be loaded at this point EXT-8231

    LLViewerInventoryItem* item = gInventory.getItem(item_id);
    if (!item || item->getType() != LLAssetType::AT_CLOTHING)
    {
        return false;
    }

    U32 wearable_count = gAgentWearables.getWearableCount(item->getWearableType());
    return wearable_count < LLAgentWearables::MAX_CLOTHING_PER_TYPE;
}
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;
}
Example #6
0
void LLWearableItemsList::ContextMenu::updateItemsLabels(LLContextMenu* menu)
{
    llassert(menu);
    if (!menu) return;

    // Set proper label for the "Create new <WEARABLE_TYPE>" menu item.
    LLViewerInventoryItem* item = gInventory.getLinkedItem(mUUIDs.back());
    if (!item || !item->isWearableType()) return;

    LLWearableType::EType w_type = item->getWearableType();
    std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getTypeName(w_type));

    LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new");
    menu_item->setLabel(new_label);
}
Example #7
0
	// Get wearable type of the given item.
	//
	// There is a special case: so-called "dummy items"
	// (i.e. the ones that are there just to indicate that you're not wearing
	// any wearables of the corresponding type. They are currently grayed out
	// and suffixed with "not worn").
	// Those items don't have an UUID, but they do have an associated wearable type.
	// If the user has invoked context menu for such item,
	// we ignore the passed item_id and retrieve wearable type from the item.
	LLWearableType::EType getWearableType(const LLUUID& item_id)
	{
		if (!isDummyItem(item_id))
		{
			LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id);
			if (item && item->isWearableType())
			{
				return item->getWearableType();
			}
		}
		else if (mCOFWearables) // dummy item selected
		{
			LLPanelDummyClothingListItem* item;

			item = dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem());
			if (item)
			{
				return item->getWearableType();
			}
		}

		return LLWearableType::WT_NONE;
	}
Example #8
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);
    }
}
LLWearableType::EType LLPanelOutfitEdit::getWearableTypeByItemUUID(const LLUUID& item_uuid) const
{
	LLViewerInventoryItem* item = gInventory.getLinkedItem(item_uuid);
	return (item != NULL) ? item->getWearableType() : LLWearableType::WT_NONE;
}
void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
{
	if (!mAddWearablesPanel->getVisible()) return;
	
	uuid_vec_t ids;
	mCOFWearables->getSelectedUUIDs(ids);

	bool nothing_selected = ids.empty();
	bool one_selected = ids.size() == 1;
	bool more_than_one_selected = ids.size() > 1;
	bool is_dummy_item = (ids.size() && dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem()));

	// selected, expanded accordion tabs and selection in flat list view determine filtering when no item is selected in COF
	// selection in flat list view participates in determining filtering because of EXT-7963
	// So the priority of criterions in is:
	//                   1. Selected accordion tab            |  IF (any accordion selected)
	//                                                        |     filter_type = selected_accordion_type
	//                   2. Selected item in flat list view   |  ELSEIF (any item in flat list view selected)
	//                                                        |     filter_type = selected_item_type
	//                   3. Expanded accordion tab            |  ELSEIF (any accordion expanded)
	//                                                        |      filter_type = expanded accordion_type
	if (nothing_selected)
	{
		if (mInventoryItemsPanel->getVisible())
		{
			return;
		}
		showWearablesListView();

		//selected accordion tab is more priority than expanded tab
		//and selected item in flat list view of 'Add more' panel when
		//determining filtering
		LLAssetType::EType type = mCOFWearables->getSelectedAccordionAssetType();
		if (type == LLAssetType::AT_NONE)
		{ //no accordion selected

			// when no accordion selected then selected item from flat list view
			// has more priority than expanded when determining filtering
			LLUUID selected_item_id = mWearableItemsList->getSelectedUUID();
			LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id);
			if(item)
		{
				showFilteredWearablesListView(item->getWearableType());
				return;
			}

			// when no accordion selected and no selected items in flat list view
			// determine filtering according to expanded accordion
			type = mCOFWearables->getExpandedAccordionAssetType();
		}

		switch (type)
		{
		case LLAssetType::AT_OBJECT:
			applyListViewFilter(LVIT_ATTACHMENT);
			break;
		case LLAssetType::AT_BODYPART:
			applyListViewFilter(LVIT_BODYPART);
			break;
		case LLAssetType::AT_CLOTHING:
		default:
			applyListViewFilter(LVIT_CLOTHING);
			break;
		}

		return;
	}

	//resetting selection if more than one item is selected
	if (more_than_one_selected)
	{
		if (mInventoryItemsPanel->getVisible())
		{
			applyFolderViewFilter(FVIT_ALL);
			return;
		}

		showWearablesListView();
		applyListViewFilter(LVIT_ALL);
		return;
	}


	//filter wearables by a type represented by a dummy item
	if (one_selected && is_dummy_item)
	{
		if (mInventoryItemsPanel->getVisible())
		{
			applyFolderViewFilter(FVIT_WEARABLE);
			return;
		}

		onAddWearableClicked();
		return;
	}

	LLViewerInventoryItem* item = gInventory.getItem(ids[0]);
	if (!item && ids[0].notNull())
	{
		if (mInventoryItemsPanel->getVisible())
		{
			applyFolderViewFilter(FVIT_ALL);
			return;
		}
		//Inventory misses an item with non-zero id
		showWearablesListView();
		applyListViewFilter(LVIT_ALL);
		return;
	}

	if (item && one_selected && !is_dummy_item)
	{
		if (item->isWearableType())
		{
			if (mInventoryItemsPanel->getVisible())
			{
				applyFolderViewFilter(FVIT_WEARABLE);
				return;
			}
			//single clothing or bodypart item is selected
			showFilteredWearablesListView(item->getWearableType());
			return;
		}
		else
		{
			if (mInventoryItemsPanel->getVisible())
			{
				applyFolderViewFilter(FVIT_ATTACHMENT);
				return;
			}
			//attachment is selected
			showWearablesListView();
			applyListViewFilter(LVIT_ATTACHMENT);
			return;
		}
	}

}
Example #11
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;
		}
	}
}