From 019a7687aec7236e0f5782b2ef7a043111714c2b Mon Sep 17 00:00:00 2001 From: Tozh Date: Tue, 8 Mar 2011 08:15:44 -0500 Subject: [PATCH] //-TT Patch: "Wear Items" option in inventory to Replace Worn Items Only - WIP --- indra/newview/llappearancemgr.cpp | 23 ++ indra/newview/llappearancemgr.h | 9 + indra/newview/llavatarlistitem.cpp | 2 +- indra/newview/llbottomtray.cpp | 4 + indra/newview/llbottomtray.h | 1 + indra/newview/llinventorybridge.cpp | 230 +++++++++++++++++- indra/newview/llinventorybridge.h | 3 + indra/newview/lloutfitslist.cpp | 24 +- .../skins/default/xui/en/menu_inventory.xml | 8 + 9 files changed, 298 insertions(+), 6 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 14a934251e..67d7bb2a00 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2121,6 +2121,12 @@ void LLAppearanceMgr::getUserDescendents(const LLUUID& category, } void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append) +//-TT Patch: ReplaceWornItemsOnly +{ + wearInventoryCategory(category, copy, append, false); +} +void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append, bool replace) +//-TT { if(!category) return; @@ -2132,9 +2138,26 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal, &LLAppearanceMgr::instance(), category->getUUID(), copy, append)); +//-TT Patch: ReplaceWornItemsOnly + //category->getUUID(), copy, append, replace)); +//-TT } +//-TT Patch: ReplaceWornItemsOnly +void LLAppearanceMgr::replaceCategoryInCurrentOutfit(const LLUUID& cat_id) +{ + LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + wearInventoryCategory(cat, false, true); +} +//-TT void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append) +//-TT Patch: ReplaceWornItemsOnly +{ + wearCategoryFinal(cat_id, copy_items, append, false); +} + +void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append, bool replace) +//-TT { llinfos << "starting" << llendl; diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 80088f4a28..4b39b2470c 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -62,8 +62,17 @@ public: bool append = false, const LLUUID& idOutfit = LLUUID::null); // [/RLVa:KB] void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append); +//-TT Patch: ReplaceWornItemsOnly + void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append, bool items); +//-TT void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append); void wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append); +//-TT Patch: ReplaceWornItemsOnly + void wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append, bool items); +//-TT +//-TT Patch: ReplaceWornItemsOnly + void replaceCategoryInCurrentOutfit(const LLUUID& cat_id); +//-TT void wearOutfitByName(const std::string& name); void changeOutfit(bool proceed, const LLUUID& category, bool append); void replaceCurrentOutfit(const LLUUID& new_outfit); diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 128fbfd270..956b7f08a5 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -717,7 +717,7 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item) sChildrenWidths[--index] = info_btn_width; sChildrenWidths[--index] = profile_btn_width; sChildrenWidths[--index] = speaking_indicator_width; - llassert(index == 0); + //llassert(index == 0); } void LLAvatarListItem::updateChildren() diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 362e167731..7c7fc977eb 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -494,6 +494,10 @@ void LLBottomTray::updateContextMenu(S32 x, S32 y, MASK mask) mBottomTrayContextMenu->setItemVisible("NearbyChatBar_Delete", in_edit_box); mBottomTrayContextMenu->setItemVisible("NearbyChatBar_Select_All", in_edit_box); } +//void LLBottomTray::showVoiceButton(BOOL visible) +//{ +// setTrayButtonVisibleIfPossible(RS_BUTTON_SPEAK, visible); +//} void LLBottomTray::showGestureButton(BOOL visible) { diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index d594d40d6b..6f1c28ed7a 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -111,6 +111,7 @@ public: void showBottomTrayContextMenu(S32 x, S32 y, MASK mask); + //void showVoiceButton(BOOL visible); void showGestureButton(BOOL visible); void showMoveButton(BOOL visible); void showCameraButton(BOOL visible); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 2d7cbf21da..8b8e7e7966 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -104,6 +104,9 @@ void dec_busy_count() // Function declarations void remove_inventory_category_from_avatar(LLInventoryCategory* category); void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id); +//-TT Patch: ReplaceWornItemsOnly +void wear_inventory_category_on_avatar(LLInventoryCategory* category, LLFolderView *fView); +//-TT bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*); bool confirm_attachment_rez(const LLSD& notification, const LLSD& response); void teleport_via_landmark(const LLUUID& asset_id); @@ -191,12 +194,12 @@ void LLInvFVBridge::cutToClipboard() // *TODO: make sure this does the right thing void LLInvFVBridge::showProperties() { - show_item_profile(mUUID); + //show_item_profile(mUUID); // Disable old properties floater; this is replaced by the sidepanel. - /* + /**/ + //-TT Experiment. LLFloaterReg::showInstance("properties", mUUID); - */ } void LLInvFVBridge::removeBatch(LLDynamicArray& batch) @@ -2176,6 +2179,20 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) modifyOutfit(TRUE); return; } +//-TT Patch: ReplaceWornItemsOnly + else if ("replaceitems" == action) + { + LLInventoryModel* model = getInventoryModel(); + if(!model) return; + LLViewerInventoryCategory* cat = getCategory(); + if(!cat) return; + + wear_inventory_category_on_avatar ( cat, mRoot ); + + // modifyOutfit(TRUE, TRUE); + return; + } +//-TT else if ("copy" == action) { copyToClipboard(); @@ -2569,6 +2586,9 @@ void LLFolderBridge::folderOptionsMenu() if (type != LLFolderType::FT_OUTFIT) { mItems.push_back(std::string("Add To Outfit")); +//-TT Patch: ReplaceWornItemsOnly + mItems.push_back(std::string("Wear Items")); +//-TT } mItems.push_back(std::string("Replace Outfit")); } @@ -2938,13 +2958,20 @@ void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::ETyp } void LLFolderBridge::modifyOutfit(BOOL append) +//-TT Patch: ReplaceWornItemsOnly +{ + modifyOutfit(append, false); +} + +void LLFolderBridge::modifyOutfit(BOOL append, BOOL replace) +//-TT { LLInventoryModel* model = getInventoryModel(); if(!model) return; LLViewerInventoryCategory* cat = getCategory(); if(!cat) return; - LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append ); + LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append, replace ); } // helper stuff @@ -4542,6 +4569,201 @@ LLWearableBridge::LLWearableBridge(LLInventoryPanel* inventory, mInvType = inv_type; } +//-TT Patch: ReplaceWornItemsOnly +// Collect all wearables, objects and gestures in the subtree, then wear them, +// replacing only relevant layers and attachment points +void wear_inventory_category_on_avatar(LLInventoryCategory* category, LLFolderView *fView) +{ + if(!category) return; + llinfos << "ReplaceWornItemsOnly wear_inventory_category_on_avatar( " << category->getName() + << " )" << llendl; + + LLUUID category_id = category->getUUID(); + + // Find all the wearables that are in the category's subtree. + llinfos << "ReplaceWornItemsOnly find all wearables" << llendl; + + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + LLFindWearables is_wearable; + gInventory.collectDescendentsIf(category_id, + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_wearable); + S32 i; + S32 wearable_count = item_array.count(); + + LLInventoryModel::cat_array_t obj_cat_array; + LLInventoryModel::item_array_t obj_item_array; + LLIsType is_object( LLAssetType::AT_OBJECT ); + gInventory.collectDescendentsIf(category_id, + obj_cat_array, + obj_item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_object); + S32 obj_count = obj_item_array.count(); + + // Find all gestures in this folder + LLInventoryModel::cat_array_t gest_cat_array; + LLInventoryModel::item_array_t gest_item_array; + LLIsType is_gesture( LLAssetType::AT_GESTURE ); + gInventory.collectDescendentsIf(category_id, + gest_cat_array, + gest_item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_gesture); + S32 gest_count = gest_item_array.count(); + + if (wearable_count > 0) //Loop through wearables. + { + //llinfos << "ReplaceWornItemsOnly wearable_count" << wearable_count << llendl; + int aTypes[LLWearableType::WT_COUNT] = {0}; + + for(i = 0; i < wearable_count; ++i) + { + //llinfos << "ReplaceWornItemsOnly wearable_count loop, i=" << i << llendl; + LLViewerInventoryItem *item = item_array.get(i); + int iType = (int)item->getWearableType(); + //llinfos << "ReplaceWornItemsOnly wearable_count loop, iType=" << iType << llendl; + if (item->isWearableType() + && iType != LLWearableType::WT_INVALID + && iType != LLWearableType::WT_NONE + && !get_is_item_worn(item->getUUID()) + ) + { +/* +// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.0c) | Modified: RLVa-0.2.2a + if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(item)) ) + continue; +// [/RLVa:KB] + LLWearableList::instance().getAsset(item->getAssetUUID(), + item->getName(), + item->getType(), + LLWearableBridge::onRemoveFromAvatarArrived, + new OnRemoveStruct(item->getLinkedUUID())); +*/ +// [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-2.2.0a) | Added: Catznip-2.1.1d + aTypes[iType]++; + if (aTypes[iType] == 1) //first occurence of type, remove first + { + U32 count = gAgentWearables.getWearableCount((LLWearableType::EType)iType); + //llinfos << "Type: " << iType << " count " << count << llendl; + + for (U32 j=0; jgetItemID()); + //llinfos << "Removing wearable name: " << wearable->getName() << llendl; + } + //now add the first item (replace just in case) + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true); + //llinfos << " Wearing item: " << item->getName() << " with replace=true" << llendl; + } + else // just add - unless it's body + { + if (!(iType == LLWearableType::WT_SHAPE) && !(iType == LLWearableType::WT_SKIN) && + !(iType == LLWearableType::WT_HAIR) && !(iType == LLWearableType::WT_EYES)) + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, false); + } + } + } + } + + if (obj_count > 0) + { + //all attachment points + //int oTypes[LLWearableType::WT_COUNT] = {0}; + LLVOAvatar::attachment_map_t attachment_map; + //LLVector3 oTypes[obj_count] = {NULL}; + + for(i = 0; i < obj_count; ++i) + { + LLViewerInventoryItem *obj_item = obj_item_array.get(i); + + //rez_attachment(item, NULL, true); // Replace if "Wear"ing. + ////LLFolderViewItem* folder_item = fView->getItemByID(obj_item->getLinkedUUID()); + ////if(!folder_item) continue; + ////LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener(); + //////LLInvFVBridge* bridge = (LLInvFVBridge*)obj_item->getListener(); + ////if(!bridge) continue; + ////bridge->performAction(&gInventory, "wear"); + + if (!get_is_item_worn(obj_item->getUUID())) + { + // first add the item without removing others + LLAppearanceMgr::instance().wearItemOnAvatar(obj_item->getUUID(), true, true); + //} + //} + ////figure out where we added it + std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(obj_item->getUUID()); + std::string attachment_point_name2 = gAgentAvatarp->getAttachedPointName(obj_item->getAssetUUID); + ////S32 iCnt = gAgentAvatarp->getAttachmentCount(); + ////LLUUID attID = gAgentAvatarp->getAttachmentItemID(); + //LLViewerJointAttachment *attPoint = gAgentAvatarp->getWornAttachmentPoint(obj_item->getUUID()); + //std::string attName = attPoint->getName(); + // + ////check if there are other things on same point already + //S32 numCnt = attPoint->getNumObjects(); + //if (numCnt > 1) + //{ + // //attPoint-> + // //gAgentAvatarp->clampAttachmentPositions(); + // //LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID()); + //} + ////if any of those things aren't in our list - remove them + + //if (attachment_point_name == LLStringUtil::null) // Error condition, invalid attach point + //{ + // attachment_point_name = "Invalid Attachment"; + //} + //llinfos << "attachment_point_name" << attachment_point_name << llendl; + //llinfos << "attName" << attName << llendl; + //llinfos << "numCnt" << numCnt << llendl; + ////// e.g. "(worn on ...)" / "(attached to ...)" + ////LLStringUtil::format_map_t args; + ////args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name); + + //LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID()); + //LLVOAvatarSelf::attachObject(obj_item); + } + } + + ////ok, this is a kludge, but can we wait for the item to get attached + ////in order to query where it got attached? + //for(i = 0; i < obj_count; ++i) + //{ + // LLViewerInventoryItem *obj_item = obj_item_array.get(i); + // if (!get_is_item_worn(obj_item->getUUID())) + // { + // // first add the item without removing others + // LLAppearanceMgr::instance().wearItemOnAvatar(obj_item->getUUID(), true, false); + // } + //} + + } + + if (gest_count > 0) + { + for(i = 0; i < gest_count; ++i) + { + LLViewerInventoryItem *gest_item = gest_item_array.get(i); + if (get_is_item_worn(gest_item->getUUID())) + { + LLGestureMgr::instance().activateGesture( gest_item->getLinkedUUID() ); + gInventory.updateItem( gest_item ); + gInventory.notifyObservers(); + } + } + } +} +//-TT + + void remove_inventory_category_from_avatar( LLInventoryCategory* category ) { if(!category) return; diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 1507f50cf5..a9ef943185 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -291,6 +291,9 @@ protected: BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck); void modifyOutfit(BOOL append); +//-TT Patch: ReplaceWornItemsOnly + void modifyOutfit(BOOL append, BOOL replace); +//-TT void determineFolderType(); menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index db9d386b6b..c320ce983a 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -117,7 +117,9 @@ public: registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2)); registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenu::onAdd, this)); - +//-TT Patch: ReplaceWornItemsOnly + registrar.add("Gear.WearReplaceItems",boost::bind(&LLOutfitListGearMenu::onReplaceItems, this)); +//-TT enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2)); enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenu::onVisible, this, _2)); @@ -186,6 +188,17 @@ private: } } +//-TT Patch: ReplaceWornItemsOnly + void onReplaceItems() + { + const LLUUID& selected_id = getSelectedOutfitID(); + + if (selected_id.notNull()) + { + //LLAppearanceMgr::getInstance()->replaceCategoryInCurrentOutfit(selected_id); + } + } +//-TT void onTakeOff() { // Take off selected outfit. @@ -279,6 +292,10 @@ protected: boost::bind(&LLAppearanceMgr::replaceCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); registrar.add("Outfit.WearAdd", boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); +//-TT Patch: ReplaceWornItemsOnly + registrar.add("Outfit.WearReplaceItems", + boost::bind(&LLAppearanceMgr::replaceCategoryInCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); +//-TT registrar.add("Outfit.TakeOff", boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id)); registrar.add("Outfit.Edit", boost::bind(editOutfit)); @@ -626,6 +643,11 @@ void LLOutfitsList::performAction(std::string action) { LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, FALSE ); } + if ("replaceitems" == action) + { + llinfos << "replaceitems" << llendl; + LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE ); + } else if ("addtooutfit" == action) { LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE ); diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 1aceb530aa..60aaf08887 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -366,6 +366,14 @@ function="Inventory.DoToSelected" parameter="addtooutfit" /> + + +