diff options
Diffstat (limited to 'indra/newview/llinventorybridge.cpp')
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 2007 |
1 files changed, 1084 insertions, 923 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 099f863dc9..c6f806178c 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -33,7 +33,11 @@ #include "llviewerprecompiledheaders.h" #include "llinventorybridge.h" +// external projects +#include "lltransfersourceasset.h" + #include "llagent.h" +#include "llagentcamera.h" #include "llagentwearables.h" #include "llappearancemgr.h" #include "llavataractions.h" @@ -46,8 +50,10 @@ #include "llimfloater.h" #include "llimview.h" #include "llinventoryclipboard.h" +#include "llinventorydefines.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" +#include "llinventorymodelbackgroundfetch.h" #include "llinventorypanel.h" #include "llnotifications.h" #include "llnotificationsutil.h" @@ -65,6 +71,18 @@ #include "llwearablelist.h" #include "llpaneloutfitsinventory.h" +typedef std::pair<LLUUID, LLUUID> two_uuids_t; +typedef std::list<two_uuids_t> two_uuids_list_t; + +struct LLMoveInv +{ + LLUUID mObjectID; + LLUUID mCategoryID; + two_uuids_list_t mMoveList; + void (*mCallback)(S32, void*); + void* mUserData; +}; + using namespace LLOldEvents; // Helpers @@ -88,6 +106,7 @@ void remove_inventory_category_from_avatar(LLInventoryCategory* category); void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id); bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*); bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response); +void teleport_via_landmark(const LLUUID& asset_id); std::string ICON_NAME[ICON_NAME_COUNT] = { @@ -100,7 +119,7 @@ std::string ICON_NAME[ICON_NAME_COUNT] = "Inv_Script", "Inv_Clothing", "Inv_Object", - "Inv_Object", + "Inv_Object_Multi", "Inv_Notecard", "Inv_Skin", "Inv_Snapshot", @@ -132,8 +151,12 @@ std::string ICON_NAME[ICON_NAME_COUNT] = // | LLInvFVBridge | // +=================================================+ -LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory, const LLUUID& uuid) : -mUUID(uuid), mInvType(LLInventoryType::IT_NONE) +LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory, + LLFolderView* root, + const LLUUID& uuid) : + mUUID(uuid), + mRoot(root), + mInvType(LLInventoryType::IT_NONE) { mInventoryPanel = inventory->getHandle(); } @@ -174,17 +197,30 @@ time_t LLInvFVBridge::getCreationDate() const } // Can be destroyed (or moved to trash) -BOOL LLInvFVBridge::isItemRemovable() +BOOL LLInvFVBridge::isItemRemovable() const { const LLInventoryModel* model = getInventoryModel(); if(!model) { return FALSE; } + + // Can't delete an item that's in the library. if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) { return FALSE; } + + // Disable delete from COF folder; have users explicitly choose "detach/take off", + // unless the item is not worn but in the COF (i.e. is bugged). + if (LLAppearanceMgr::instance().getIsProtectedCOFItem(mUUID)) + { + if (get_is_item_worn(mUUID)) + { + return FALSE; + } + } + const LLInventoryObject *obj = model->getItem(mUUID); if (obj && obj->getIsLinkType()) { @@ -223,7 +259,7 @@ void LLInvFVBridge::showProperties() // Disable old properties floater; this is replaced by the sidepanel. /* - LLFloaterReg::showInstance("properties", mUUID); + LLFloaterReg::showInstance("properties", mUUID); */ } @@ -247,7 +283,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc { if(LLAssetType::AT_GESTURE == item->getType()) { - LLGestureManager::instance().deactivateGesture(item->getUUID()); + LLGestureMgr::instance().deactivateGesture(item->getUUID()); } } } @@ -263,7 +299,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc { if(LLAssetType::AT_GESTURE == descendent_items[j]->getType()) { - LLGestureManager::instance().deactivateGesture(descendent_items[j]->getUUID()); + LLGestureMgr::instance().deactivateGesture(descendent_items[j]->getUUID()); } } } @@ -284,12 +320,27 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* LLMessageSystem* msg = gMessageSystem; const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); LLViewerInventoryItem* item = NULL; - LLViewerInventoryCategory* cat = NULL; - std::vector<LLUUID> move_ids; + uuid_vec_t move_ids; LLInventoryModel::update_map_t update; bool start_new_message = true; S32 count = batch.count(); S32 i; + + // first, hide any 'preview' floaters that correspond to the items + // being deleted. + for(i = 0; i < count; ++i) + { + bridge = (LLInvFVBridge*)(batch.get(i)); + if(!bridge || !bridge->isItemRemovable()) continue; + item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID()); + if(item) + { + LLPreview::hide(item->getUUID()); + } + } + + // do the inventory move to trash + for(i = 0; i < count; ++i) { bridge = (LLInvFVBridge*)(batch.get(i)); @@ -299,7 +350,6 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* { if(item->getParentUUID() == trash_id) continue; move_ids.push_back(item->getUUID()); - LLPreview::hide(item->getUUID()); --update[item->getParentUUID()]; ++update[trash_id]; if(start_new_message) @@ -331,11 +381,12 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* gInventory.accountForUpdate(update); update.clear(); } + for(i = 0; i < count; ++i) { bridge = (LLInvFVBridge*)(batch.get(i)); if(!bridge || !bridge->isItemRemovable()) continue; - cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID()); + LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID()); if(cat) { if(cat->getParentUUID() == trash_id) continue; @@ -370,8 +421,8 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener* } // move everything. - std::vector<LLUUID>::iterator it = move_ids.begin(); - std::vector<LLUUID>::iterator end = move_ids.end(); + uuid_vec_t::iterator it = move_ids.begin(); + uuid_vec_t::iterator end = move_ids.end(); for(; it != end; ++it) { gInventory.moveObject((*it), trash_id); @@ -447,7 +498,7 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const } } const LLViewerInventoryCategory *cat = model->getCategory(objects.get(i)); - if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType())) + if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) { return FALSE; } @@ -456,11 +507,15 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const } void hide_context_entries(LLMenuGL& menu, - const std::vector<std::string> &entries_to_show, - const std::vector<std::string> &disabled_entries) + const menuentry_vec_t &entries_to_show, + const menuentry_vec_t &disabled_entries) { const LLView::child_list_t *list = menu.getChildList(); + // For removing double separators or leading separator. Start at true so that + // if the first element is a separator, it will not be shown. + BOOL is_previous_entry_separator = TRUE; + LLView::child_list_t::const_iterator itor; for (itor = list->begin(); itor != list->end(); ++itor) { @@ -475,7 +530,7 @@ void hide_context_entries(LLMenuGL& menu, bool found = false; - std::vector<std::string>::const_iterator itor2; + menuentry_vec_t::const_iterator itor2; for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2) { if (*itor2 == name) @@ -483,6 +538,17 @@ void hide_context_entries(LLMenuGL& menu, found = true; } } + + // Don't allow multiple separators in a row (e.g. such as if there are no items + // between two separators). + if (found) + { + const BOOL is_entry_separator = (dynamic_cast<LLMenuItemSeparatorGL *>(*itor) != NULL); + if (is_entry_separator && is_previous_entry_separator) + found = false; + is_previous_entry_separator = is_entry_separator; + } + if (!found) { (*itor)->setVisible(FALSE); @@ -503,8 +569,8 @@ void hide_context_entries(LLMenuGL& menu, // Helper for commonly-used entries void LLInvFVBridge::getClipboardEntries(bool show_asset_id, - std::vector<std::string> &items, - std::vector<std::string> &disabled_items, U32 flags) + menuentry_vec_t &items, + menuentry_vec_t &disabled_items, U32 flags) { const LLInventoryObject *obj = getInventoryObject(); @@ -544,7 +610,16 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (show_asset_id) { items.push_back(std::string("Copy Asset UUID")); - if ( (! ( isItemPermissive() || gAgent.isGodlike() ) ) + + bool is_asset_knowable = false; + + LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID); + if (inv_item) + { + is_asset_knowable = LLAssetType::lookupIsAssetIDKnowable(inv_item->getType()); + } + if ( !is_asset_knowable // disable menu item for Inventory items with unknown asset. EXT-5308 + || (! ( isItemPermissive() || gAgent.isGodlike() ) ) || (flags & FIRST_SELECTED_ITEM) == 0) { disabled_items.push_back(std::string("Copy Asset UUID")); @@ -560,33 +635,25 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } } - items.push_back(std::string("Paste")); - if (!isClipboardPasteable() || (flags & FIRST_SELECTED_ITEM) == 0) + // Don't allow items to be pasted directly into the COF. + if (!isCOFFolder()) { - disabled_items.push_back(std::string("Paste")); + items.push_back(std::string("Paste")); } - - if (gAgent.isGodlike()) + if (!isClipboardPasteable() || ((flags & FIRST_SELECTED_ITEM) == 0)) { - items.push_back(std::string("Paste As Link")); - if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) - { - disabled_items.push_back(std::string("Paste As Link")); - } + disabled_items.push_back(std::string("Paste")); } - items.push_back(std::string("Paste Separator")); - - if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID)) + items.push_back(std::string("Paste As Link")); + if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) { - items.push_back(std::string("Remove Link")); + disabled_items.push_back(std::string("Paste As Link")); } - items.push_back(std::string("Delete")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("Delete")); - } + items.push_back(std::string("Paste Separator")); + + addDeleteContextMenuOptions(items, disabled_items); // If multiple items are selected, disable properties (if it exists). if ((flags & FIRST_SELECTED_ITEM) == 0) @@ -598,20 +665,21 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { lldebugs << "LLInvFVBridge::buildContextMenu()" << llendl; - std::vector<std::string> items; - std::vector<std::string> disabled_items; - if(isInTrash()) + menuentry_vec_t items; + menuentry_vec_t disabled_items; + if(isItemInTrash()) { - items.push_back(std::string("PurgeItem")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("PurgeItem")); - } - items.push_back(std::string("RestoreItem")); + addTrashContextMenuOptions(items, disabled_items); } else { - items.push_back(std::string("Open")); + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } + + addOpenRightClickMenuOption(items); items.push_back(std::string("Properties")); getClipboardEntries(true, items, disabled_items, flags); @@ -619,6 +687,65 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } +void LLInvFVBridge::addTrashContextMenuOptions(menuentry_vec_t &items, + menuentry_vec_t &disabled_items) +{ + const LLInventoryObject *obj = getInventoryObject(); + if (obj && obj->getIsLinkType()) + { + items.push_back(std::string("Find Original")); + if (isLinkedObjectMissing()) + { + disabled_items.push_back(std::string("Find Original")); + } + } + items.push_back(std::string("Purge Item")); + if (!isItemRemovable()) + { + disabled_items.push_back(std::string("Purge Item")); + } + items.push_back(std::string("Restore Item")); +} + +void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items, + menuentry_vec_t &disabled_items) +{ + + const LLInventoryObject *obj = getInventoryObject(); + + // Don't allow delete as a direct option from COF folder. + if (obj && obj->getIsLinkType() && isCOFFolder() && get_is_item_worn(mUUID)) + { + return; + } + + // "Remove link" and "Delete" are the same operation. + if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID)) + { + items.push_back(std::string("Remove Link")); + } + else + { + items.push_back(std::string("Delete")); + } + + if (!isItemRemovable()) + { + disabled_items.push_back(std::string("Delete")); + } +} + +void LLInvFVBridge::addOpenRightClickMenuOption(menuentry_vec_t &items) +{ + const LLInventoryObject *obj = getInventoryObject(); + const BOOL is_link = (obj && obj->getIsLinkType()); + + if (is_link) + items.push_back(std::string("Open Original")); + else + items.push_back(std::string("Open")); +} + // *TODO: remove this BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const { @@ -639,7 +766,7 @@ BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const if (*type == DAD_CATEGORY) { - gInventory.startBackgroundFetch(obj->getUUID()); + LLInventoryModelBackgroundFetch::instance().start(obj->getUUID()); } rv = TRUE; @@ -665,7 +792,7 @@ LLInventoryModel* LLInvFVBridge::getInventoryModel() const return panel ? panel->getModel() : NULL; } -BOOL LLInvFVBridge::isInTrash() const +BOOL LLInvFVBridge::isItemInTrash() const { LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; @@ -675,7 +802,7 @@ BOOL LLInvFVBridge::isInTrash() const BOOL LLInvFVBridge::isLinkedObjectInTrash() const { - if (isInTrash()) return TRUE; + if (isItemInTrash()) return TRUE; const LLInventoryObject *obj = getInventoryObject(); if (obj && obj->getIsLinkType()) @@ -712,14 +839,7 @@ BOOL LLInvFVBridge::isAgentInventory() const BOOL LLInvFVBridge::isCOFFolder() const { - const LLInventoryModel* model = getInventoryModel(); - if(!model) return TRUE; - const LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); - if (mUUID == cof_id || model->isObjectDescendentOf(mUUID, cof_id)) - { - return TRUE; - } - return FALSE; + return LLAppearanceMgr::instance().getIsInCOF(mUUID); } BOOL LLInvFVBridge::isItemPermissive() const @@ -733,7 +853,7 @@ void LLInvFVBridge::changeItemParent(LLInventoryModel* model, const LLUUID& new_parent_id, BOOL restamp) { - if(item->getParentUUID() != new_parent_id) + if (item->getParentUUID() != new_parent_id) { LLInventoryModel::update_list_t update; LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); @@ -776,21 +896,11 @@ void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model, model->notifyObservers(); } - -const std::string safe_inv_type_lookup(LLInventoryType::EType inv_type) -{ - const std::string rv= LLInventoryType::lookup(inv_type); - if(rv.empty()) - { - return std::string("<invalid>"); - } - return rv; -} - LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, + LLFolderView* root, const LLUUID& uuid, U32 flags) { @@ -800,104 +910,104 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, case LLAssetType::AT_TEXTURE: if(!(inv_type == LLInventoryType::IT_TEXTURE || inv_type == LLInventoryType::IT_SNAPSHOT)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLTextureBridge(inventory, uuid, inv_type); + new_listener = new LLTextureBridge(inventory, root, uuid, inv_type); break; case LLAssetType::AT_SOUND: if(!(inv_type == LLInventoryType::IT_SOUND)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLSoundBridge(inventory, uuid); + new_listener = new LLSoundBridge(inventory, root, uuid); break; case LLAssetType::AT_LANDMARK: if(!(inv_type == LLInventoryType::IT_LANDMARK)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLLandmarkBridge(inventory, uuid, flags); + new_listener = new LLLandmarkBridge(inventory, root, uuid, flags); break; case LLAssetType::AT_CALLINGCARD: if(!(inv_type == LLInventoryType::IT_CALLINGCARD)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLCallingCardBridge(inventory, uuid); + new_listener = new LLCallingCardBridge(inventory, root, uuid); break; case LLAssetType::AT_SCRIPT: if(!(inv_type == LLInventoryType::IT_LSL)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLScriptBridge(inventory, uuid); + new_listener = new LLScriptBridge(inventory, root, uuid); break; case LLAssetType::AT_OBJECT: if(!(inv_type == LLInventoryType::IT_OBJECT || inv_type == LLInventoryType::IT_ATTACHMENT)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLObjectBridge(inventory, uuid, inv_type, flags); + new_listener = new LLObjectBridge(inventory, root, uuid, inv_type, flags); break; case LLAssetType::AT_NOTECARD: if(!(inv_type == LLInventoryType::IT_NOTECARD)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLNotecardBridge(inventory, uuid); + new_listener = new LLNotecardBridge(inventory, root, uuid); break; case LLAssetType::AT_ANIMATION: if(!(inv_type == LLInventoryType::IT_ANIMATION)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLAnimationBridge(inventory, uuid); + new_listener = new LLAnimationBridge(inventory, root, uuid); break; case LLAssetType::AT_GESTURE: if(!(inv_type == LLInventoryType::IT_GESTURE)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLGestureBridge(inventory, uuid); + new_listener = new LLGestureBridge(inventory, root, uuid); break; case LLAssetType::AT_LSL_TEXT: if(!(inv_type == LLInventoryType::IT_LSL)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLLSLTextBridge(inventory, uuid); + new_listener = new LLLSLTextBridge(inventory, root, uuid); break; case LLAssetType::AT_CLOTHING: case LLAssetType::AT_BODYPART: if(!(inv_type == LLInventoryType::IT_WEARABLE)) { - llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl; + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; } - new_listener = new LLWearableBridge(inventory, uuid, asset_type, inv_type, (EWearableType)flags); + new_listener = new LLWearableBridge(inventory, root, uuid, asset_type, inv_type, (EWearableType)flags); break; case LLAssetType::AT_CATEGORY: if (actual_asset_type == LLAssetType::AT_LINK_FOLDER) { // Create a link folder handler instead. - new_listener = new LLLinkFolderBridge(inventory, uuid); + new_listener = new LLLinkFolderBridge(inventory, root, uuid); break; } - new_listener = new LLFolderBridge(inventory, uuid); + new_listener = new LLFolderBridge(inventory, root, uuid); break; case LLAssetType::AT_LINK: case LLAssetType::AT_LINK_FOLDER: // Only should happen for broken links. - new_listener = new LLLinkItemBridge(inventory, uuid); + new_listener = new LLLinkItemBridge(inventory, root, uuid); break; default: llinfos << "Unhandled asset type (llassetstorage.h): " @@ -939,6 +1049,38 @@ bool LLInvFVBridge::isInOutfitsSidePanel() const return outfit_panel->isTabPanel(my_panel); } +bool LLInvFVBridge::canShare() +{ + const LLInventoryModel* model = getInventoryModel(); + if(!model) + { + return false; + } + + LLViewerInventoryItem *item = model->getItem(mUUID); + if (item) + { + bool allowed = false; + allowed = LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item); + if (allowed && + !item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) + { + allowed = false; + } + if (allowed && + !item->getPermissions().allowCopyBy(gAgent.getID())) + { + allowed = false; + } + return allowed; + } + + LLViewerInventoryCategory* cat = model->getCategory(mUUID); + + // All categories can be given. + return cat != NULL; +} + // +=================================================+ // | InventoryFVBridgeBuilder | // +=================================================+ @@ -946,29 +1088,31 @@ LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset LLAssetType::EType actual_asset_type, LLInventoryType::EType inv_type, LLInventoryPanel* inventory, + LLFolderView* root, const LLUUID& uuid, U32 flags /* = 0x00 */) const { return LLInvFVBridge::createBridge(asset_type, - actual_asset_type, - inv_type, - inventory, - uuid, - flags); + actual_asset_type, + inv_type, + inventory, + root, + uuid, + flags); } // +=================================================+ // | LLItemBridge | // +=================================================+ -void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +void LLItemBridge::performAction(LLInventoryModel* model, std::string action) { if ("goto" == action) { - gotoItem(folder); + gotoItem(); } - if ("open" == action) + if ("open" == action || "open_original" == action) { openItem(); return; @@ -996,9 +1140,9 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, else if ("copy_uuid" == action) { // Single item only - LLInventoryItem* item = model->getItem(mUUID); + LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem()); if(!item) return; - LLUUID asset_id = item->getAssetUUID(); + LLUUID asset_id = item->getProtectedAssetUUID(); std::string buffer; asset_id.toString(buffer); @@ -1016,7 +1160,7 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLInventoryItem* itemp = model->getItem(mUUID); if (!itemp) return; - LLFolderViewItem* folder_view_itemp = folder->getItemByID(itemp->getParentUUID()); + LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID()); if (!folder_view_itemp) return; folder_view_itemp->getListener()->pasteFromClipboard(); @@ -1028,7 +1172,7 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, LLInventoryItem* itemp = model->getItem(mUUID); if (!itemp) return; - LLFolderViewItem* folder_view_itemp = folder->getItemByID(itemp->getParentUUID()); + LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID()); if (!folder_view_itemp) return; folder_view_itemp->getListener()->pasteLinkFromClipboard(); @@ -1038,8 +1182,8 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, void LLItemBridge::selectItem() { - LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem(); - if(item && !item->isComplete()) + LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem()); + if(item && !item->isFinished()) { item->fetchFromServer(); } @@ -1047,7 +1191,7 @@ void LLItemBridge::selectItem() void LLItemBridge::restoreItem() { - LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem(); + LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem()); if(item) { LLInventoryModel* model = getInventoryModel(); @@ -1059,7 +1203,10 @@ void LLItemBridge::restoreItem() void LLItemBridge::restoreToWorld() { - LLViewerInventoryItem* itemp = (LLViewerInventoryItem*)getItem(); + //Similar functionality to the drag and drop rez logic + bool remove_from_inventory = false; + + LLViewerInventoryItem* itemp = static_cast<LLViewerInventoryItem*>(getItem()); if (itemp) { LLMessageSystem* msg = gMessageSystem; @@ -1071,23 +1218,20 @@ void LLItemBridge::restoreToWorld() msg->nextBlockFast(_PREHASH_InventoryData); itemp->packMessage(msg); msg->sendReliable(gAgent.getRegion()->getHost()); - } - - //Similar functionality to the drag and drop rez logic - BOOL remove_from_inventory = FALSE; - //remove local inventory copy, sim will deal with permissions and removing the item - //from the actual inventory if its a no-copy etc - if(!itemp->getPermissions().allowCopyBy(gAgent.getID())) - { - remove_from_inventory = TRUE; - } - - // Check if it's in the trash. (again similar to the normal rez logic) - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if(gInventory.isObjectDescendentOf(itemp->getUUID(), trash_id)) - { - remove_from_inventory = TRUE; + //remove local inventory copy, sim will deal with permissions and removing the item + //from the actual inventory if its a no-copy etc + if(!itemp->getPermissions().allowCopyBy(gAgent.getID())) + { + remove_from_inventory = true; + } + + // Check if it's in the trash. (again similar to the normal rez logic) + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if(gInventory.isObjectDescendentOf(itemp->getUUID(), trash_id)) + { + remove_from_inventory = true; + } } if(remove_from_inventory) @@ -1097,7 +1241,7 @@ void LLItemBridge::restoreToWorld() } } -void LLItemBridge::gotoItem(LLFolderView *folder) +void LLItemBridge::gotoItem() { LLInventoryObject *obj = getInventoryObject(); if (obj && obj->getIsLinkType()) @@ -1314,17 +1458,11 @@ BOOL LLItemBridge::isItemCopyable() const return FALSE; } - if (gAgent.isGodlike()) - { - // All items can be copied in god mode since you can - // at least paste-as-link the item, though you - // still may not be able paste the item. - return TRUE; - } - else - { - return (item->getPermissions().allowCopyBy(gAgent.getID())); - } + // All items can be copied in god mode since you can + // at least paste-as-link the item, though you + // still may not be able paste the item. + return TRUE; + // return (item->getPermissions().allowCopyBy(gAgent.getID())); } return FALSE; } @@ -1355,11 +1493,7 @@ BOOL LLItemBridge::isItemPermissive() const LLViewerInventoryItem* item = getItem(); if(item) { - U32 mask = item->getPermissions().getMaskBase(); - if((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) - { - return TRUE; - } + return item->getIsFullPerm(); } return FALSE; } @@ -1414,7 +1548,7 @@ public: }; // Can be destroyed (or moved to trash) -BOOL LLFolderBridge::isItemRemovable() +BOOL LLFolderBridge::isItemRemovable() const { LLInventoryModel* model = getInventoryModel(); if(!model) @@ -1427,14 +1561,10 @@ BOOL LLFolderBridge::isItemRemovable() return FALSE; } - LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); - if( !avatar ) - { - return FALSE; - } + if (!isAgentAvatarValid()) return FALSE; LLInventoryCategory* category = model->getCategory(mUUID); - if( !category ) + if(!category) { return FALSE; } @@ -1473,6 +1603,7 @@ BOOL LLFolderBridge::isUpToDate() const BOOL LLFolderBridge::isItemCopyable() const { + // Can copy folders to paste-as-link, but not for straight paste. return TRUE; } @@ -1582,8 +1713,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; - LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); - if(!avatar) return FALSE; + if (!isAgentAvatarValid()) return FALSE; // cannot drag categories into library if(!isAgentInventory()) @@ -1607,7 +1737,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // Is the destination the trash? const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); BOOL move_is_into_trash = (mUUID == trash_id) - || model->isObjectDescendentOf(mUUID, trash_id); + || model->isObjectDescendentOf(mUUID, trash_id); BOOL is_movable = (!LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())); const LLUUID current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); @@ -1655,12 +1785,11 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } } - - accept = is_movable - && (mUUID != cat_id) // Can't move a folder into itself - && (mUUID != inv_cat->getParentUUID()) // Avoid moves that would change nothing - && !(model->isObjectDescendentOf(mUUID, cat_id)); // Avoid circularity - if(accept && drop) + accept = is_movable + && (mUUID != cat_id) // Can't move a folder into itself + && (mUUID != inv_cat->getParentUUID()) // Avoid moves that would change nothing + && !(model->isObjectDescendentOf(mUUID, cat_id)); // Avoid circularity + if (accept && drop) { // Look for any gestures and deactivate them if (move_is_into_trash) @@ -1669,9 +1798,9 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, { LLInventoryItem* item = descendent_items[i]; if (item->getType() == LLAssetType::AT_GESTURE - && LLGestureManager::instance().isGestureActive(item->getUUID())) + && LLGestureMgr::instance().isGestureActive(item->getUUID())) { - LLGestureManager::instance().deactivateGesture(item->getUUID()); + LLGestureMgr::instance().deactivateGesture(item->getUUID()); } } } @@ -1684,7 +1813,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, { // traverse category and add all contents to currently worn. BOOL append = true; - LLAppearanceManager::instance().wearInventoryCategory(inv_cat, false, append); + LLAppearanceMgr::instance().wearInventoryCategory(inv_cat, false, append); } else { @@ -1692,28 +1821,30 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; gInventory.collectDescendents(inv_cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH); - LLAppearanceManager::instance().linkAll(mUUID,items,NULL); + LLAppearanceMgr::instance().linkAll(mUUID,items,NULL); } } else { #if SUPPORT_ENSEMBLES - // BAP - should skip if dup. - if (move_is_into_current_outfit) - { - LLAppearanceManager::instance().addEnsembleLink(inv_cat); - } - else - { - LLPointer<LLInventoryCallback> cb = NULL; - link_inventory_item( - gAgent.getID(), - inv_cat->getUUID(), - mUUID, - inv_cat->getName(), - LLAssetType::AT_LINK_FOLDER, - cb); - } + // BAP - should skip if dup. + if (move_is_into_current_outfit) + { + LLAppearanceMgr::instance().addEnsembleLink(inv_cat); + } + else + { + LLPointer<LLInventoryCallback> cb = NULL; + const std::string empty_description = ""; + link_inventory_item( + gAgent.getID(), + inv_cat->getUUID(), + mUUID, + inv_cat->getName(), + empty_description, + LLAssetType::AT_LINK_FOLDER, + cb); + } #endif } } @@ -1730,7 +1861,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } } } - else if(LLToolDragAndDrop::SOURCE_WORLD == source) + else if (LLToolDragAndDrop::SOURCE_WORLD == source) { // content category has same ID as object itself LLUUID object_id = inv_cat->getUUID(); @@ -1775,7 +1906,7 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, // this folder is coming from an object, as there is only one folder in an object, the root, // we need to collect the entire contents and handle them as a group - InventoryObjectList inventory_objects; + LLInventoryObject::object_list_t inventory_objects; object->getInventoryContents(inventory_objects); if (inventory_objects.empty()) @@ -1789,8 +1920,8 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, // coming from a task. Need to figure out if the person can // move/copy this item. - InventoryObjectList::iterator it = inventory_objects.begin(); - InventoryObjectList::iterator end = inventory_objects.end(); + LLInventoryObject::object_list_t::iterator it = inventory_objects.begin(); + LLInventoryObject::object_list_t::iterator end = inventory_objects.end(); for ( ; it != end; ++it) { // coming from a task. Need to figure out if the person can @@ -1820,7 +1951,7 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, if(drop && accept) { it = inventory_objects.begin(); - InventoryObjectList::iterator first_it = inventory_objects.begin(); + LLInventoryObject::object_list_t::iterator first_it = inventory_objects.begin(); LLMoveInv* move_inv = new LLMoveInv; move_inv->mObjectID = object_id; move_inv->mCategoryID = category_id; @@ -1848,61 +1979,21 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, return accept; } -bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat, - LLInventoryItem* item) -{ - // Valid COF items are: - // - links to wearables (body parts or clothing) - // - links to attachments - // - links to gestures - // - links to ensemble folders - LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem(); // BAP - safe? - if (linked_item) - { - LLAssetType::EType type = linked_item->getType(); - return (type == LLAssetType::AT_CLOTHING || - type == LLAssetType::AT_BODYPART || - type == LLAssetType::AT_GESTURE || - type == LLAssetType::AT_OBJECT); - } - else - { - LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory(); // BAP - safe? - // BAP remove AT_NONE support after ensembles are fully working? - return (linked_category && - ((linked_category->getPreferredType() == LLFolderType::FT_NONE) || - (LLFolderType::lookupIsEnsembleType(linked_category->getPreferredType())))); - } -} - - -bool LLFindWearables::operator()(LLInventoryCategory* cat, - LLInventoryItem* item) -{ - if(item) - { - if((item->getType() == LLAssetType::AT_CLOTHING) - || (item->getType() == LLAssetType::AT_BODYPART)) - { - return TRUE; - } - } - return FALSE; -} - - - //Used by LLFolderBridge as callback for directory recursion. -class LLRightClickInventoryFetchObserver : public LLInventoryFetchObserver +class LLRightClickInventoryFetchObserver : public LLInventoryFetchItemsObserver { public: - LLRightClickInventoryFetchObserver() : + LLRightClickInventoryFetchObserver(const uuid_vec_t& ids) : + LLInventoryFetchItemsObserver(ids), mCopyItems(false) { }; - LLRightClickInventoryFetchObserver(const LLUUID& cat_id, bool copy_items) : + LLRightClickInventoryFetchObserver(const uuid_vec_t& ids, + const LLUUID& cat_id, + bool copy_items) : + LLInventoryFetchItemsObserver(ids), mCatID(cat_id), mCopyItems(copy_items) - { }; + { }; virtual void done() { // we've downloaded all the items, so repaint the dialog @@ -1923,7 +2014,11 @@ protected: class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver { public: - LLRightClickInventoryFetchDescendentsObserver(bool copy_items) : mCopyItems(copy_items) {} + LLRightClickInventoryFetchDescendentsObserver(const uuid_vec_t& ids, + bool copy_items) : + LLInventoryFetchDescendentsObserver(ids), + mCopyItems(copy_items) + {} ~LLRightClickInventoryFetchDescendentsObserver() {} virtual void done(); protected: @@ -1934,7 +2029,7 @@ void LLRightClickInventoryFetchDescendentsObserver::done() { // Avoid passing a NULL-ref as mCompleteFolders.front() down to // gInventory.collectDescendents() - if( mCompleteFolders.empty() ) + if( mComplete.empty() ) { llwarns << "LLRightClickInventoryFetchDescendentsObserver::done with empty mCompleteFolders" << llendl; dec_busy_count(); @@ -1948,7 +2043,7 @@ void LLRightClickInventoryFetchDescendentsObserver::done() // happen. LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t item_array; - gInventory.collectDescendents(mCompleteFolders.front(), + gInventory.collectDescendents(mComplete.front(), cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH); @@ -1966,14 +2061,14 @@ void LLRightClickInventoryFetchDescendentsObserver::done() } #endif - LLRightClickInventoryFetchObserver* outfit; - outfit = new LLRightClickInventoryFetchObserver(mCompleteFolders.front(), mCopyItems); - LLInventoryFetchObserver::item_ref_t ids; + uuid_vec_t ids; for(S32 i = 0; i < count; ++i) { ids.push_back(item_array.get(i)->getUUID()); } + LLRightClickInventoryFetchObserver* outfit = new LLRightClickInventoryFetchObserver(ids, mComplete.front(), mCopyItems); + // clean up, and remove this as an observer since the call to the // outfit could notify observers and throw us into an infinite // loop. @@ -1986,19 +2081,19 @@ void LLRightClickInventoryFetchDescendentsObserver::done() inc_busy_count(); // do the fetch - outfit->fetchItems(ids); + outfit->startFetch(); outfit->done(); //Not interested in waiting and this will be right 99% of the time. //Uncomment the following code for laggy Inventory UI. -/* if(outfit->isEverythingComplete()) +/* if(outfit->isFinished()) { - // everything is already here - call done. - outfit->done(); + // everything is already here - call done. + outfit->done(); } else { - // it's all on it's way - add an observer, and the inventory - // will call done for us when everything is here. - gInventory.addObserver(outfit); + // it's all on it's way - add an observer, and the inventory + // will call done for us when everything is here. + gInventory.addObserver(outfit); }*/ } @@ -2012,7 +2107,8 @@ void LLRightClickInventoryFetchDescendentsObserver::done() class LLInventoryCopyAndWearObserver : public LLInventoryObserver { public: - LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count) :mCatID(cat_id), mContentsCount(count), mFolderAdded(FALSE) {} + LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count) : + mCatID(cat_id), mContentsCount(count), mFolderAdded(FALSE) {} virtual ~LLInventoryCopyAndWearObserver() {} virtual void changed(U32 mask); @@ -2051,7 +2147,7 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask) if (NULL == category) { llwarns << "gInventory.getCategory(" << mCatID - << ") was NULL" << llendl; + << ") was NULL" << llendl; } else { @@ -2059,7 +2155,7 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask) mContentsCount) { gInventory.removeObserver(this); - LLAppearanceManager::instance().wearInventoryCategory(category, FALSE, TRUE); + LLAppearanceMgr::instance().wearInventoryCategory(category, FALSE, TRUE); delete this; } } @@ -2070,11 +2166,11 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask) -void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) { if ("open" == action) { - LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(folder->getItemByID(mUUID)); + LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(mRoot->getItemByID(mUUID)); if (f) { f->setOpen(TRUE); @@ -2109,7 +2205,7 @@ void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model if(!model) return; LLViewerInventoryCategory* cat = getCategory(); if(!cat) return; - LLAppearanceManager::instance().addEnsembleLink(cat,true); + LLAppearanceMgr::instance().addEnsembleLink(cat,true); return; } #endif @@ -2178,7 +2274,10 @@ void LLFolderBridge::determineFolderType() { LLInventoryModel* model = getInventoryModel(); LLViewerInventoryCategory* category = model->getCategory(mUUID); - category->determineFolderType(); + if (category) + { + category->determineFolderType(); + } } } @@ -2336,9 +2435,9 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re const LLViewerInventoryItem* item = (*iter); const LLUUID& item_id = item->getUUID(); if (item->getType() == LLAssetType::AT_GESTURE - && LLGestureManager::instance().isGestureActive(item_id)) + && LLGestureMgr::instance().isGestureActive(item_id)) { - LLGestureManager::instance().deactivateGesture(item_id); + LLGestureMgr::instance().deactivateGesture(item_id); } } @@ -2375,7 +2474,12 @@ void LLFolderBridge::pasteFromClipboard() { // move_inventory_item() is not enough, //we have to update inventory locally too - changeItemParent(model, dynamic_cast<LLViewerInventoryItem*>(item), parent_id, FALSE); + LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item); + llassert(viitem); + if (viitem) + { + changeItemParent(model, viitem, parent_id, FALSE); + } } else { @@ -2406,26 +2510,26 @@ void LLFolderBridge::pasteLinkFromClipboard() ++iter) { const LLUUID &object_id = (*iter); -#if SUPPORT_ENSEMBLES if (LLInventoryCategory *cat = model->getCategory(object_id)) { + const std::string empty_description = ""; link_inventory_item( gAgent.getID(), cat->getUUID(), parent_id, cat->getName(), + empty_description, LLAssetType::AT_LINK_FOLDER, LLPointer<LLInventoryCallback>(NULL)); } - else -#endif - if (LLInventoryItem *item = model->getItem(object_id)) + else if (LLInventoryItem *item = model->getItem(object_id)) { link_inventory_item( gAgent.getID(), item->getLinkedUUID(), parent_id, item->getName(), + item->getDescription(), LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL)); } @@ -2441,17 +2545,19 @@ void LLFolderBridge::staticFolderOptionsMenu() void LLFolderBridge::folderOptionsMenu() { - std::vector<std::string> disabled_items; + menuentry_vec_t disabled_items; LLInventoryModel* model = getInventoryModel(); if(!model) return; const LLInventoryCategory* category = model->getCategory(mUUID); + if(!category) return; + LLFolderType::EType type = category->getPreferredType(); - const bool is_system_folder = category && LLFolderType::lookupIsProtectedType(type); + const bool is_system_folder = LLFolderType::lookupIsProtectedType(type); // BAP change once we're no longer treating regular categories as ensembles. - const bool is_ensemble = category && (type == LLFolderType::FT_NONE || - LLFolderType::lookupIsEnsembleType(type)); + const bool is_ensemble = (type == LLFolderType::FT_NONE || + LLFolderType::lookupIsEnsembleType(type)); // calling card related functionality for folders. @@ -2459,7 +2565,7 @@ void LLFolderBridge::folderOptionsMenu() if (is_sidepanel) { mItems.push_back("Rename"); - mItems.push_back("Delete"); + addDeleteContextMenuOptions(mItems, disabled_items); } // Only enable calling-card related options for non-system folders. @@ -2574,42 +2680,42 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) lldebugs << "LLFolderBridge::buildContextMenu()" << llendl; -// std::vector<std::string> disabled_items; +// menuentry_vec_t disabled_items; LLInventoryModel* model = getInventoryModel(); if(!model) return; const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); const LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); if (lost_and_found_id == mUUID) - { + { // This is the lost+found folder. - mItems.push_back(std::string("Empty Lost And Found")); - } + mItems.push_back(std::string("Empty Lost And Found")); + + mDisabledItems.push_back(std::string("New Folder")); + mDisabledItems.push_back(std::string("New Script")); + mDisabledItems.push_back(std::string("New Note")); + mDisabledItems.push_back(std::string("New Gesture")); + mDisabledItems.push_back(std::string("New Clothes")); + mDisabledItems.push_back(std::string("New Body Parts")); + } if(trash_id == mUUID) { // This is the trash. mItems.push_back(std::string("Empty Trash")); } - else if(model->isObjectDescendentOf(mUUID, trash_id)) + else if(isItemInTrash()) { // This is a folder in the trash. mItems.clear(); // clear any items that used to exist - mItems.push_back(std::string("Purge Item")); - if (!isItemRemovable()) - { - mDisabledItems.push_back(std::string("Purge Item")); - } - - mItems.push_back(std::string("Restore Item")); + addTrashContextMenuOptions(mItems, mDisabledItems); } else if(isAgentInventory()) // do not allow creating in library { LLViewerInventoryCategory *cat = getCategory(); // BAP removed protected check to re-enable standard ops in untyped folders. // Not sure what the right thing is to do here. - if (!isCOFFolder() && cat && cat->getPreferredType()!=LLFolderType::FT_OUTFIT /*&& - LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())*/) + if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT)) { // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) @@ -2619,26 +2725,29 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) mItems.push_back(std::string("New Gesture")); mItems.push_back(std::string("New Clothes")); mItems.push_back(std::string("New Body Parts")); - mItems.push_back(std::string("Change Type")); - LLViewerInventoryCategory *cat = getCategory(); + // Changing folder types is just a debug feature; this is fairly unsupported + // and can lead to unexpected behavior if enabled. +#if !LL_RELEASE_FOR_DOWNLOAD + mItems.push_back(std::string("Change Type")); + const LLViewerInventoryCategory *cat = getCategory(); if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) { mDisabledItems.push_back(std::string("Change Type")); } - +#endif getClipboardEntries(false, mItems, mDisabledItems, flags); } else { // Want some but not all of the items from getClipboardEntries for outfits. - if (cat && cat->getPreferredType()==LLFolderType::FT_OUTFIT) + if (cat && (cat->getPreferredType() == LLFolderType::FT_OUTFIT)) { mItems.push_back(std::string("Rename")); - mItems.push_back(std::string("Delete")); + addDeleteContextMenuOptions(mItems, mDisabledItems); // EXT-4030: disallow deletion of currently worn outfit - const LLViewerInventoryItem *base_outfit_link = LLAppearanceManager::instance().getBaseOutfitLink(); + const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink(); if (base_outfit_link && (cat == base_outfit_link->getLinkedCategory())) { mDisabledItems.push_back(std::string("Delete")); @@ -2668,17 +2777,18 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) mMenu = &menu; sSelf = this; - LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(FALSE); - LLInventoryFetchDescendentsObserver::folder_ref_t folders; + + uuid_vec_t folders; LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID); if (category) { folders.push_back(category->getUUID()); } - fetch->fetchDescendents(folders); + LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE); + fetch->startFetch(); inc_busy_count(); - if(fetch->isEverythingComplete()) + if(fetch->isFinished()) { // everything is already here - call done. fetch->done(); @@ -2701,7 +2811,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { mDisabledItems.push_back(std::string("Delete System Folder")); } - + + mItems.push_back(std::string("Share")); + if (!canShare()) + { + mDisabledItems.push_back(std::string("Share")); + } + hide_context_entries(menu, mItems, mDisabledItems); } @@ -2873,10 +2989,10 @@ void LLFolderBridge::createWearable(const LLUUID &parent_id, EWearableType type) LLAssetType::EType asset_type = wearable->getAssetType(); LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - parent_id, wearable->getTransactionID(), wearable->getName(), - wearable->getDescription(), asset_type, inv_type, wearable->getType(), - wearable->getPermissions().getMaskNextOwner(), - LLPointer<LLInventoryCallback>(NULL)); + parent_id, wearable->getTransactionID(), wearable->getName(), + wearable->getDescription(), asset_type, inv_type, wearable->getType(), + wearable->getPermissions().getMaskNextOwner(), + LLPointer<LLInventoryCallback>(NULL)); } void LLFolderBridge::modifyOutfit(BOOL append) @@ -2886,9 +3002,7 @@ void LLFolderBridge::modifyOutfit(BOOL append) LLViewerInventoryCategory* cat = getCategory(); if(!cat) return; - // BAP - was: - // wear_inventory_category_on_avatar( cat, append ); - LLAppearanceManager::instance().wearInventoryCategory( cat, FALSE, append ); + LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append ); } // helper stuff @@ -2902,7 +3016,7 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response { if (cat_and_wear && cat_and_wear->mWear) { - InventoryObjectList inventory_objects; + LLInventoryObject::object_list_t inventory_objects; object->getInventoryContents(inventory_objects); int contents_count = inventory_objects.size()-1; //subtract one for containing folder @@ -2912,8 +3026,8 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response two_uuids_list_t::iterator move_it; for (move_it = move_inv->mMoveList.begin(); - move_it != move_inv->mMoveList.end(); - ++move_it) + move_it != move_inv->mMoveList.end(); + ++move_it) { object->moveInventory(move_it->first, move_it->second); } @@ -2943,31 +3057,36 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, return FALSE; } - LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); - if(!avatar) return FALSE; + if (!isAgentAvatarValid()) return FALSE; LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); BOOL accept = FALSE; LLViewerObject* object = NULL; if(LLToolDragAndDrop::SOURCE_AGENT == source) { - BOOL is_movable = TRUE; switch( inv_item->getActualType() ) { - case LLAssetType::AT_CATEGORY: - is_movable = !LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)inv_item)->getPreferredType()); - break; - default: - break; + case LLAssetType::AT_CATEGORY: + is_movable = !LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)inv_item)->getPreferredType()); + break; + default: + break; } const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); - BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); + const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); const LLUUID current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); - BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); - BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); + const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); + const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); + const BOOL move_is_outof_current_outfit = LLAppearanceMgr::instance().getIsInCOF(inv_item->getUUID()); + // Can't explicitly drag things out of the COF. + if (move_is_outof_current_outfit) + { + is_movable = FALSE; + } + if(is_movable && move_is_into_trash) { is_movable = inv_item->getIsLinkType() || !get_is_item_worn(inv_item->getUUID()); @@ -2992,9 +3111,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, if(accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE - && LLGestureManager::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash) + && LLGestureMgr::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash) { - LLGestureManager::instance().deactivateGesture(inv_item->getUUID()); + LLGestureMgr::instance().deactivateGesture(inv_item->getUUID()); } // If an item is being dragged between windows, unselect // everything in the active window so that we don't follow @@ -3047,7 +3166,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // BAP - should skip if dup. if (move_is_into_current_outfit) { - LLAppearanceManager::instance().addCOFItemLink(inv_item); + LLAppearanceMgr::instance().addCOFItemLink(inv_item); } else { @@ -3057,6 +3176,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, inv_item->getLinkedUUID(), mUUID, inv_item->getName(), + inv_item->getDescription(), LLAssetType::AT_LINK, cb); } @@ -3117,6 +3237,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } else { + // store dad inventory item to select added one later. See EXT-4347 + set_dad_inventory_item(inv_item, mUUID); + LLNotification::Params params("MoveInventoryFromObject"); params.functor.function(boost::bind(move_task_inventory_callback, _1, _2, move_inv)); LLNotifications::instance().forceResponse(params, 0); @@ -3130,13 +3253,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, if(drop) { copy_inventory_from_notecard(LLToolDragAndDrop::getInstance()->getObjectID(), - LLToolDragAndDrop::getInstance()->getSourceID(), inv_item); + LLToolDragAndDrop::getInstance()->getSourceID(), inv_item); } } else if(LLToolDragAndDrop::SOURCE_LIBRARY == source) { LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_item; - if(item && item->isComplete()) + if(item && item->isFinished()) { accept = TRUE; if(drop) @@ -3205,21 +3328,21 @@ bool LLTextureBridge::canSaveTexture(void) void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { lldebugs << "LLTextureBridge::buildContextMenu()" << llendl; - std::vector<std::string> items; - std::vector<std::string> disabled_items; - if(isInTrash()) + menuentry_vec_t items; + menuentry_vec_t disabled_items; + if(isItemInTrash()) { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("Purge Item")); - } - - items.push_back(std::string("Restore Item")); + addTrashContextMenuOptions(items, disabled_items); } else { - items.push_back(std::string("Open")); + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } + + addOpenRightClickMenuOption(items); items.push_back(std::string("Properties")); getClipboardEntries(true, items, disabled_items, flags); @@ -3235,7 +3358,7 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } // virtual -void LLTextureBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +void LLTextureBridge::performAction(LLInventoryModel* model, std::string action) { if ("save_as" == action) { @@ -3246,7 +3369,7 @@ void LLTextureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode preview_texture->openToSave(); } } - else LLItemBridge::performAction(folder, model, action); + else LLItemBridge::performAction(model, action); } // +=================================================+ @@ -3271,14 +3394,14 @@ void LLSoundBridge::openItem() // only open the preview dialog through the contextual right-click menu // double-click just plays the sound - LLViewerInventoryItem* item = getItem(); - if(item) - { - openSoundPreview((void*)this); - //send_uuid_sound_trigger(item->getAssetUUID(), 1.0); - } -*/ +LLViewerInventoryItem* item = getItem(); +if(item) +{ +openSoundPreview((void*)this); +//send_uuid_sound_trigger(item->getAssetUUID(), 1.0); } +*/ + } void LLSoundBridge::previewItem() { @@ -3298,21 +3421,20 @@ void LLSoundBridge::openSoundPreview(void* which) void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { lldebugs << "LLSoundBridge::buildContextMenu()" << llendl; - std::vector<std::string> items; - std::vector<std::string> disabled_items; + menuentry_vec_t items; + menuentry_vec_t disabled_items; - if(isInTrash()) + if(isItemInTrash()) { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("Purge Item")); - } - - items.push_back(std::string("Restore Item")); + addTrashContextMenuOptions(items, disabled_items); } else { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } items.push_back(std::string("Sound Open")); items.push_back(std::string("Properties")); @@ -3329,11 +3451,14 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // | LLLandmarkBridge | // +=================================================+ -LLLandmarkBridge::LLLandmarkBridge(LLInventoryPanel* inventory, const LLUUID& uuid, U32 flags/* = 0x00*/) : -LLItemBridge(inventory, uuid) +LLLandmarkBridge::LLLandmarkBridge(LLInventoryPanel* inventory, + LLFolderView* root, + const LLUUID& uuid, + U32 flags/* = 0x00*/) : + LLItemBridge(inventory, root, uuid) { mVisited = FALSE; - if (flags & LLInventoryItem::II_FLAGS_LANDMARK_VISITED) + if (flags & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED) { mVisited = TRUE; } @@ -3346,22 +3471,21 @@ LLUIImagePtr LLLandmarkBridge::getIcon() const void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { - std::vector<std::string> items; - std::vector<std::string> disabled_items; + menuentry_vec_t items; + menuentry_vec_t disabled_items; lldebugs << "LLLandmarkBridge::buildContextMenu()" << llendl; - if(isInTrash()) + if(isItemInTrash()) { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("Purge Item")); - } - - items.push_back(std::string("Restore Item")); + addTrashContextMenuOptions(items, disabled_items); } else { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } items.push_back(std::string("Landmark Open")); items.push_back(std::string("Properties")); @@ -3397,7 +3521,7 @@ void teleport_via_landmark(const LLUUID& asset_id) } // virtual -void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +void LLLandmarkBridge::performAction(LLInventoryModel* model, std::string action) { if ("teleport" == action) { @@ -3421,7 +3545,7 @@ void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* mod } else { - LLItemBridge::performAction(folder, model, action); + LLItemBridge::performAction(model, action); } } @@ -3448,35 +3572,33 @@ void LLLandmarkBridge::openItem() { LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); } -/* - LLViewerInventoryItem* item = getItem(); - if( item ) - { - // Opening (double-clicking) a landmark immediately teleports, - // but warns you the first time. - // open_landmark(item); - LLSD payload; - payload["asset_id"] = item->getAssetUUID(); - LLNotificationsUtil::add("TeleportFromLandmark", LLSD(), payload); - } -*/ } // +=================================================+ // | LLCallingCardObserver | // +=================================================+ -void LLCallingCardObserver::changed(U32 mask) +class LLCallingCardObserver : public LLFriendObserver { - mBridgep->refreshFolderViewItem(); -} +public: + LLCallingCardObserver(LLCallingCardBridge* bridge) : mBridgep(bridge) {} + virtual ~LLCallingCardObserver() { mBridgep = NULL; } + virtual void changed(U32 mask) + { + mBridgep->refreshFolderViewItem(); + } +protected: + LLCallingCardBridge* mBridgep; +}; // +=================================================+ // | LLCallingCardBridge | // +=================================================+ -LLCallingCardBridge::LLCallingCardBridge( LLInventoryPanel* inventory, const LLUUID& uuid ) : - LLItemBridge(inventory, uuid) +LLCallingCardBridge::LLCallingCardBridge(LLInventoryPanel* inventory, + LLFolderView* root, + const LLUUID& uuid ) : + LLItemBridge(inventory, root, uuid) { mObserver = new LLCallingCardObserver(this); LLAvatarTracker::instance().addObserver(mObserver); @@ -3499,7 +3621,7 @@ void LLCallingCardBridge::refreshFolderViewItem() } // virtual -void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string action) { if ("begin_im" == action) { @@ -3525,7 +3647,7 @@ void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel* LLAvatarActions::offerTeleport(item->getCreatorUUID()); } } - else LLItemBridge::performAction(folder, model, action); + else LLItemBridge::performAction(model, action); } LLUIImagePtr LLCallingCardBridge::getIcon() const @@ -3561,33 +3683,32 @@ void LLCallingCardBridge::openItem() LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); } /* - LLViewerInventoryItem* item = getItem(); - if(item && !item->getCreatorUUID().isNull()) - { - LLAvatarActions::showProfile(item->getCreatorUUID()); - } + LLViewerInventoryItem* item = getItem(); + if(item && !item->getCreatorUUID().isNull()) + { + LLAvatarActions::showProfile(item->getCreatorUUID()); + } */ } void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { lldebugs << "LLCallingCardBridge::buildContextMenu()" << llendl; - std::vector<std::string> items; - std::vector<std::string> disabled_items; + menuentry_vec_t items; + menuentry_vec_t disabled_items; - if(isInTrash()) + if(isItemInTrash()) { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("Purge Item")); - } - - items.push_back(std::string("Restore Item")); + addTrashContextMenuOptions(items, disabled_items); } else { - items.push_back(std::string("Open")); + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } + addOpenRightClickMenuOption(items); items.push_back(std::string("Properties")); getClipboardEntries(true, items, disabled_items, flags); @@ -3596,7 +3717,11 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) BOOL good_card = (item && (LLUUID::null != item->getCreatorUUID()) && (item->getCreatorUUID() != gAgent.getID())); - BOOL user_online = (LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID())); + BOOL user_online = FALSE; + if (item) + { + user_online = (LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID())); + } items.push_back(std::string("Send Instant Message Separator")); items.push_back(std::string("Send Instant Message")); items.push_back(std::string("Offer Teleport...")); @@ -3626,16 +3751,16 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, // check the type switch(cargo_type) { - case DAD_TEXTURE: - case DAD_SOUND: - case DAD_LANDMARK: - case DAD_SCRIPT: - case DAD_CLOTHING: - case DAD_OBJECT: - case DAD_NOTECARD: - case DAD_BODYPART: - case DAD_ANIMATION: - case DAD_GESTURE: + case DAD_TEXTURE: + case DAD_SOUND: + case DAD_LANDMARK: + case DAD_SCRIPT: + case DAD_CLOTHING: + case DAD_OBJECT: + case DAD_NOTECARD: + case DAD_BODYPART: + case DAD_ANIMATION: + case DAD_GESTURE: { LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data; const LLPermissions& perm = inv_item->getPermissions(); @@ -3658,7 +3783,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, } break; } - case DAD_CATEGORY: + case DAD_CATEGORY: { LLInventoryCategory* inv_cat = (LLInventoryCategory*)cargo_data; if( gInventory.getCategory( inv_cat->getUUID() ) ) @@ -3680,25 +3805,13 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, } break; } - default: - break; + default: + break; } } return rv; } -BOOL LLCallingCardBridge::removeItem() -{ - if (LLFriendCardsManager::instance().isItemInAnyFriendsList(getItem())) - { - LLAvatarActions::removeFriendDialog(getItem()->getCreatorUUID()); - return FALSE; - } - else - { - return LLItemBridge::removeItem(); - } -} // +=================================================+ // | LLNotecardBridge | // +=================================================+ @@ -3718,11 +3831,11 @@ void LLNotecardBridge::openItem() } /* - LLViewerInventoryItem* item = getItem(); - if (item) - { - LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES); - } + LLViewerInventoryItem* item = getItem(); + if (item) + { + LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES); + } */ } @@ -3738,7 +3851,7 @@ LLUIImagePtr LLGestureBridge::getIcon() const LLFontGL::StyleFlags LLGestureBridge::getLabelStyle() const { - if( LLGestureManager::instance().isGestureActive(mUUID) ) + if( LLGestureMgr::instance().isGestureActive(mUUID) ) { return LLFontGL::BOLD; } @@ -3750,9 +3863,11 @@ LLFontGL::StyleFlags LLGestureBridge::getLabelStyle() const std::string LLGestureBridge::getLabelSuffix() const { - if( LLGestureManager::instance().isGestureActive(mUUID) ) + if( LLGestureMgr::instance().isGestureActive(mUUID) ) { - return LLItemBridge::getLabelSuffix() + " (active)"; + LLStringUtil::format_map_t args; + args["[GESLABEL]"] = LLItemBridge::getLabelSuffix(); + return LLTrans::getString("ActiveGesture", args); } else { @@ -3761,11 +3876,11 @@ std::string LLGestureBridge::getLabelSuffix() const } // virtual -void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +void LLGestureBridge::performAction(LLInventoryModel* model, std::string action) { if (isAddAction(action)) { - LLGestureManager::instance().activateGesture(mUUID); + LLGestureMgr::instance().activateGesture(mUUID); LLViewerInventoryItem* item = gInventory.getItem(mUUID); if (!item) return; @@ -3777,7 +3892,7 @@ void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode } else if (isRemoveAction(action)) { - LLGestureManager::instance().deactivateGesture(mUUID); + LLGestureMgr::instance().deactivateGesture(mUUID); LLViewerInventoryItem* item = gInventory.getItem(mUUID); if (!item) return; @@ -3787,7 +3902,27 @@ void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode gInventory.updateItem(item); gInventory.notifyObservers(); } - else LLItemBridge::performAction(folder, model, action); + else if("play" == action) + { + if(!LLGestureMgr::instance().isGestureActive(mUUID)) + { + // we need to inform server about gesture activating to be consistent with LLPreviewGesture and LLGestureComboList. + BOOL inform_server = TRUE; + BOOL deactivate_similar = FALSE; + LLGestureMgr::instance().setGestureLoadedCallback(mUUID, boost::bind(&LLGestureBridge::playGesture, mUUID)); + LLViewerInventoryItem* item = gInventory.getItem(mUUID); + llassert(item); + if (item) + { + LLGestureMgr::instance().activateGestureWithAsset(mUUID, item->getAssetUUID(), inform_server, deactivate_similar); + } + } + else + { + playGesture(mUUID); + } + } + else LLItemBridge::performAction(model, action); } void LLGestureBridge::openItem() @@ -3799,51 +3934,67 @@ void LLGestureBridge::openItem() LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); } /* - LLViewerInventoryItem* item = getItem(); - if (item) - { - LLPreviewGesture* preview = LLPreviewGesture::show(mUUID, LLUUID::null); - preview->setFocus(TRUE); - } + LLViewerInventoryItem* item = getItem(); + if (item) + { + LLPreviewGesture* preview = LLPreviewGesture::show(mUUID, LLUUID::null); + preview->setFocus(TRUE); + } */ } BOOL LLGestureBridge::removeItem() { - // Force close the preview window, if it exists - LLGestureManager::instance().deactivateGesture(mUUID); + // Grab class information locally since *this may be deleted + // within this function. Not a great pattern... + const LLInventoryModel* model = getInventoryModel(); + if(!model) + { + return FALSE; + } + const LLUUID item_id = mUUID; + + // This will also force close the preview window, if it exists. + // This may actually delete *this, if mUUID is in the COF. + LLGestureMgr::instance().deactivateGesture(item_id); + + // If deactivateGesture deleted *this, then return out immediately. + if (!model->getObject(item_id)) + { + return TRUE; + } + return LLItemBridge::removeItem(); } void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { lldebugs << "LLGestureBridge::buildContextMenu()" << llendl; - std::vector<std::string> items; - std::vector<std::string> disabled_items; - if(isInTrash()) + menuentry_vec_t items; + menuentry_vec_t disabled_items; + if(isItemInTrash()) { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("Purge Item")); - } - - items.push_back(std::string("Restore Item")); + addTrashContextMenuOptions(items, disabled_items); } else { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } bool is_sidepanel = isInOutfitsSidePanel(); if (!is_sidepanel) { - items.push_back(std::string("Open")); + addOpenRightClickMenuOption(items); items.push_back(std::string("Properties")); } getClipboardEntries(true, items, disabled_items, flags); items.push_back(std::string("Gesture Separator")); - if (LLGestureManager::instance().isGestureActive(getUUID())) + if (LLGestureMgr::instance().isGestureActive(getUUID())) { items.push_back(std::string("Deactivate")); } @@ -3855,6 +4006,20 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } +// static +void LLGestureBridge::playGesture(const LLUUID& item_id) +{ + if (LLGestureMgr::instance().isGesturePlaying(item_id)) + { + LLGestureMgr::instance().stopGesture(item_id); + } + else + { + LLGestureMgr::instance().playGesture(item_id); + } +} + + // +=================================================+ // | LLAnimationBridge | // +=================================================+ @@ -3866,22 +4031,21 @@ LLUIImagePtr LLAnimationBridge::getIcon() const void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { - std::vector<std::string> items; - std::vector<std::string> disabled_items; + menuentry_vec_t items; + menuentry_vec_t disabled_items; lldebugs << "LLAnimationBridge::buildContextMenu()" << llendl; - if(isInTrash()) + if(isItemInTrash()) { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("Purge Item")); - } - - items.push_back(std::string("Restore Item")); + addTrashContextMenuOptions(items, disabled_items); } else { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } items.push_back(std::string("Animation Open")); items.push_back(std::string("Properties")); @@ -3897,7 +4061,7 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } // virtual -void LLAnimationBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +void LLAnimationBridge::performAction(LLInventoryModel* model, std::string action) { if ((action == "playworld") || (action == "playlocal")) { @@ -3916,7 +4080,7 @@ void LLAnimationBridge::performAction(LLFolderView* folder, LLInventoryModel* mo } else { - LLItemBridge::performAction(folder, model, action); + LLItemBridge::performAction(model, action); } } @@ -3929,11 +4093,11 @@ void LLAnimationBridge::openItem() LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); } /* - LLViewerInventoryItem* item = getItem(); - if (item) - { - LLFloaterReg::showInstance("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES); - } + LLViewerInventoryItem* item = getItem(); + if (item) + { + LLFloaterReg::showInstance("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES); + } */ } @@ -3944,12 +4108,17 @@ void LLAnimationBridge::openItem() // static LLUUID LLObjectBridge::sContextMenuItemID; -LLObjectBridge::LLObjectBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLInventoryType::EType type, U32 flags) : -LLItemBridge(inventory, uuid), mInvType(type) +LLObjectBridge::LLObjectBridge(LLInventoryPanel* inventory, + LLFolderView* root, + const LLUUID& uuid, + LLInventoryType::EType type, + U32 flags) : + LLItemBridge(inventory, root, uuid), + mInvType(type) { mAttachPt = (flags & 0xff); // low bye of inventory flags - mIsMultiObject = ( flags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) ? TRUE: FALSE; + mIsMultiObject = ( flags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) ? TRUE: FALSE; } LLUIImagePtr LLObjectBridge::getIcon() const @@ -3969,7 +4138,7 @@ LLInventoryObject* LLObjectBridge::getObject() const } // virtual -void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +void LLObjectBridge::performAction(LLInventoryModel* model, std::string action) { if (isAddAction(action)) { @@ -3980,7 +4149,7 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model { rez_attachment(item, NULL); } - else if(item && item->isComplete()) + else if(item && item->isFinished()) { // must be in library. copy it to our inventory and put it on. LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0); @@ -4004,15 +4173,16 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); gMessageSystem->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); gMessageSystem->sendReliable( gAgent.getRegion()->getHost()); - } - // this object might have been selected, so let the selection manager know it's gone now - LLViewerObject *found_obj = gObjectList.findObject(item->getLinkedUUID()); - if (found_obj) - { - LLSelectMgr::getInstance()->remove(found_obj); + + // this object might have been selected, so let the selection manager know it's gone now + LLViewerObject *found_obj = gObjectList.findObject(item->getLinkedUUID()); + if (found_obj) + { + LLSelectMgr::getInstance()->remove(found_obj); + } } } - else LLItemBridge::performAction(folder, model, action); + else LLItemBridge::performAction(model, action); } void LLObjectBridge::openItem() @@ -4030,7 +4200,7 @@ void LLObjectBridge::openItem() // Disable old properties floater; this is replaced by the sidepanel. /* - LLFloaterReg::showInstance("properties", mUUID); + LLFloaterReg::showInstance("properties", mUUID); */ } @@ -4056,12 +4226,11 @@ std::string LLObjectBridge::getLabelSuffix() const { if (get_is_item_worn(mUUID)) { - LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); - std::string attachment_point_name = avatar->getAttachedPointName(mUUID); + std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID); // e.g. "(worn on ...)" / "(attached to ...)" LLStringUtil::format_map_t args; - args["[ATTACHMENT_POINT]"] = attachment_point_name.c_str(); + args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name); return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args); } else @@ -4076,10 +4245,10 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach payload["item_id"] = item->getLinkedUUID(); // Wear the base object in case this is a link. S32 attach_pt = 0; - if (gAgent.getAvatarObject() && attachment) + if (isAgentAvatarValid() && attachment) { - for (LLVOAvatar::attachment_map_t::iterator iter = gAgent.getAvatarObject()->mAttachmentPoints.begin(); - iter != gAgent.getAvatarObject()->mAttachmentPoints.end(); ++iter) + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter) { if (iter->second == attachment) { @@ -4105,9 +4274,7 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response) { - LLVOAvatar *avatarp = gAgent.getAvatarObject(); - - if (!avatarp->canAttachMoreObjects()) + if (!gAgentAvatarp->canAttachMoreObjects()) { LLSD args; args["MAX_ATTACHMENTS"] = llformat("%d", MAX_AGENT_ATTACHMENTS); @@ -4147,20 +4314,19 @@ static LLNotificationFunctorRegistration confirm_replace_attachment_rez_reg("Rep void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { - std::vector<std::string> items; - std::vector<std::string> disabled_items; - if(isInTrash()) + menuentry_vec_t items; + menuentry_vec_t disabled_items; + if(isItemInTrash()) { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("Purge Item")); - } - - items.push_back(std::string("Restore Item")); + addTrashContextMenuOptions(items, disabled_items); } else { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } bool is_sidepanel = isInOutfitsSidePanel(); if (!is_sidepanel) @@ -4175,17 +4341,14 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) LLInventoryItem *item = getItem(); if(item) { - LLVOAvatarSelf* avatarp = gAgent.getAvatarObject(); - if( !avatarp ) - { - return; - } + if (!isAgentAvatarValid()) return; if( get_is_item_worn( mUUID ) ) { + items.push_back(std::string("Attach Separator")); items.push_back(std::string("Detach From Yourself")); } - else if (!isInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing()) + else if (!isItemInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing() && !isCOFFolder()) { items.push_back(std::string("Attach Separator")); items.push_back(std::string("Object Wear")); @@ -4194,7 +4357,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // commented out for DEV-32347 //items.push_back(std::string("Restore to Last Position")); - if (!avatarp->canAttachMoreObjects()) + if (!gAgentAvatarp->canAttachMoreObjects()) { disabled_items.push_back(std::string("Object Wear")); disabled_items.push_back(std::string("Attach To")); @@ -4202,15 +4365,14 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } LLMenuGL* attach_menu = menu.findChildMenuByName("Attach To", TRUE); LLMenuGL* attach_hud_menu = menu.findChildMenuByName("Attach To HUD", TRUE); - LLVOAvatar *avatarp = gAgent.getAvatarObject(); if (attach_menu && (attach_menu->getChildCount() == 0) && attach_hud_menu && (attach_hud_menu->getChildCount() == 0) - && avatarp) + && isAgentAvatarValid()) { - for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); - iter != avatarp->mAttachmentPoints.end(); ) + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ) { LLVOAvatar::attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; @@ -4260,11 +4422,10 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name) model->notifyObservers(); - LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); - if( avatar ) + if (isAgentAvatarValid()) { - LLViewerObject* obj = avatar->getWornAttachment( item->getUUID() ); - if( obj ) + LLViewerObject* obj = gAgentAvatarp->getWornAttachment( item->getUUID() ); + if(obj) { LLSelectMgr::getInstance()->deselectAll(); LLSelectMgr::getInstance()->addAsIndividual( obj, SELECT_ALL_TES, FALSE ); @@ -4295,19 +4456,25 @@ void LLLSLTextBridge::openItem() { LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); } - /* - LLViewerInventoryItem* item = getItem(); - if (item) - { - LLFloaterReg::showInstance("preview_script", LLSD(mUUID), TAKE_FOCUS_YES); - } - */ } // +=================================================+ // | LLWearableBridge | // +=================================================+ +LLWearableBridge::LLWearableBridge(LLInventoryPanel* inventory, + LLFolderView* root, + const LLUUID& uuid, + LLAssetType::EType asset_type, + LLInventoryType::EType inv_type, + EWearableType wearable_type) : + LLItemBridge(inventory, root, uuid), + mAssetType( asset_type ), + mInvType(inv_type), + mWearableType(wearable_type) +{ +} + // *NOTE: hack to get from avatar inventory to avatar void wear_inventory_item_on_avatar( LLInventoryItem* item ) { @@ -4316,7 +4483,7 @@ void wear_inventory_item_on_avatar( LLInventoryItem* item ) lldebugs << "wear_inventory_item_on_avatar( " << item->getName() << " )" << llendl; - LLAppearanceManager::instance().addCOFItemLink(item); + LLAppearanceMgr::instance().addCOFItemLink(item); } } @@ -4328,10 +4495,10 @@ void wear_add_inventory_item_on_avatar( LLInventoryItem* item ) << " )" << llendl; LLWearableList::instance().getAsset(item->getAssetUUID(), - item->getName(), - item->getType(), - LLWearableBridge::onWearAddOnAvatarArrived, - new LLUUID(item->getUUID())); + item->getName(), + item->getType(), + LLWearableBridge::onWearAddOnAvatarArrived, + new LLUUID(item->getUUID())); } } @@ -4453,7 +4620,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_ LLViewerInventoryItem *gest_item = gest_item_array.get(i); if (get_is_item_worn(gest_item->getUUID())) { - LLGestureManager::instance().deactivateGesture( gest_item->getLinkedUUID() ); + LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() ); gInventory.updateItem( gest_item ); gInventory.notifyObservers(); } @@ -4491,7 +4658,7 @@ LLUIImagePtr LLWearableBridge::getIcon() const } // virtual -void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +void LLWearableBridge::performAction(LLInventoryModel* model, std::string action) { if (isAddAction(action)) { @@ -4511,7 +4678,7 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod removeFromAvatar(); return; } - else LLItemBridge::performAction(folder, model, action); + else LLItemBridge::performAction(model, action); } void LLWearableBridge::openItem() @@ -4522,58 +4689,16 @@ void LLWearableBridge::openItem() { LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); } - /* - if( isInTrash() ) - { - LLNotificationsUtil::add("CannotWearTrash"); - } - else if(isAgentInventory()) - { - if( !get_is_item_worn( mUUID ) ) - { - wearOnAvatar(); - } - } - else - { - // must be in the inventory library. copy it to our inventory - // and put it on right away. - LLViewerInventoryItem* item = getItem(); - if(item && item->isComplete()) - { - LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - else if(item) - { - // *TODO: We should fetch the item details, and then do - // the operation above. - LLNotificationsUtil::add("CannotWearInfoNotComplete"); - } - } - */ } void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { lldebugs << "LLWearableBridge::buildContextMenu()" << llendl; - std::vector<std::string> items; - std::vector<std::string> disabled_items; - if(isInTrash()) + menuentry_vec_t items; + menuentry_vec_t disabled_items; + if(isItemInTrash()) { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("Purge Item")); - } - - items.push_back(std::string("Restore Item")); + addTrashContextMenuOptions(items, disabled_items); } else { // FWIW, it looks like SUPPRESS_OPEN_ITEM is not set anywhere @@ -4591,11 +4716,16 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) can_open = FALSE; } + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } bool is_sidepanel = isInOutfitsSidePanel(); if (can_open && !is_sidepanel) { - items.push_back(std::string("Open")); + addOpenRightClickMenuOption(items); } if (!is_sidepanel) @@ -4605,7 +4735,10 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) getClipboardEntries(true, items, disabled_items, flags); - items.push_back(std::string("Wearable Separator")); + if (!is_sidepanel) + { + items.push_back(std::string("Wearable Separator")); + } items.push_back(std::string("Wearable Edit")); @@ -4614,7 +4747,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) disabled_items.push_back(std::string("Wearable Edit")); } // Don't allow items to be worn if their baseobj is in the trash. - if (isLinkedObjectInTrash() || isLinkedObjectMissing()) + if (isLinkedObjectInTrash() || isLinkedObjectMissing() || isCOFFolder()) { disabled_items.push_back(std::string("Wearable Wear")); disabled_items.push_back(std::string("Wearable Add")); @@ -4628,6 +4761,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { case LLAssetType::AT_CLOTHING: items.push_back(std::string("Take Off")); + // Fallthrough since clothing and bodypart share wear options case LLAssetType::AT_BODYPART: if (get_is_item_worn(item->getUUID())) { @@ -4658,7 +4792,7 @@ BOOL LLWearableBridge::canWearOnAvatar(void* user_data) if(!self->isAgentInventory()) { LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem(); - if(!item || !item->isComplete()) return FALSE; + if(!item || !item->isFinished()) return FALSE; } return (!get_is_item_worn(self->mUUID)); } @@ -4815,10 +4949,10 @@ void LLWearableBridge::editOnAvatar() if (gFloaterCustomize) gFloaterCustomize->setCurrentWearableType( wearable->getType() ); - if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() ) + if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() ) { // Start Avatar Customization - gAgent.changeCameraToCustomizeAvatar(); + gAgentCamera.changeCameraToCustomizeAvatar(); } } } @@ -4869,30 +5003,21 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable, if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR || type==WT_EYES ) ) //&& //!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) ) { - // MULTI_WEARABLE: FIXME HACK - always remove all bool do_remove_all = false; - gAgentWearables.removeWearable( type, do_remove_all, 0 ); + U32 index = gAgentWearables.getWearableIndex(wearable); + gAgentWearables.removeWearable( type, do_remove_all, index ); } } } // Find and remove this item from the COF. - LLInventoryModel::item_array_t items = gInventory.collectLinkedItems(item_id, LLAppearanceManager::instance().getCOF()); - llassert(items.size() == 1); // Should always have one and only one item linked to this in the COF. - for (LLInventoryModel::item_array_t::const_iterator iter = items.begin(); - iter != items.end(); - ++iter) - { - const LLViewerInventoryItem *linked_item = (*iter); - const LLUUID &item_id = linked_item->getUUID(); - gInventory.purgeObject(item_id); - } + LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false); gInventory.notifyObservers(); delete on_remove_struct; } -/* static */ +// static void LLWearableBridge::removeAllClothesFromAvatar() { // Remove COF links. @@ -4912,17 +5037,7 @@ void LLWearableBridge::removeAllClothesFromAvatar() continue; // Find and remove this item from the COF. - LLInventoryModel::item_array_t items = gInventory.collectLinkedItems( - item_id, LLAppearanceManager::instance().getCOF()); - llassert(items.size() == 1); // Should always have one and only one item linked to this in the COF. - for (LLInventoryModel::item_array_t::const_iterator iter = items.begin(); - iter != items.end(); - ++iter) - { - const LLViewerInventoryItem *linked_item = (*iter); - const LLUUID &item_id = linked_item->getUUID(); - gInventory.purgeObject(item_id); - } + LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false); } gInventory.notifyObservers(); @@ -4930,7 +5045,7 @@ void LLWearableBridge::removeAllClothesFromAvatar() LLAgentWearables::userRemoveAllClothes(); } -/* static */ +// static void LLWearableBridge::removeItemFromAvatar(LLViewerInventoryItem *item) { if (item) @@ -4952,429 +5067,475 @@ void LLWearableBridge::removeFromAvatar() } } -LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type, - const LLUUID& uuid,LLInventoryModel* model) +// +=================================================+ +// | LLLinkItemBridge | +// +=================================================+ +// For broken item links +std::string LLLinkItemBridge::sPrefix("Link: "); +LLUIImagePtr LLLinkItemBridge::getIcon() const { - LLInvFVBridgeAction* action = NULL; - switch(asset_type) + if (LLViewerInventoryItem *item = getItem()) { - case LLAssetType::AT_TEXTURE: - action = new LLTextureBridgeAction(uuid,model); - break; - - case LLAssetType::AT_SOUND: - action = new LLSoundBridgeAction(uuid,model); - break; - - case LLAssetType::AT_LANDMARK: - action = new LLLandmarkBridgeAction(uuid,model); - break; - - case LLAssetType::AT_CALLINGCARD: - action = new LLCallingCardBridgeAction(uuid,model); - break; + U32 attachment_point = (item->getFlags() & 0xff); // low byte of inventory flags + bool is_multi = LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS & item->getFlags(); - case LLAssetType::AT_OBJECT: - action = new LLObjectBridgeAction(uuid,model); - break; - - case LLAssetType::AT_NOTECARD: - action = new LLNotecardBridgeAction(uuid,model); - break; - - case LLAssetType::AT_ANIMATION: - action = new LLAnimationBridgeAction(uuid,model); - break; - - case LLAssetType::AT_GESTURE: - action = new LLGestureBridgeAction(uuid,model); - break; - - case LLAssetType::AT_LSL_TEXT: - action = new LLLSLTextBridgeAction(uuid,model); - break; - - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_BODYPART: - action = new LLWearableBridgeAction(uuid,model); - - break; - - default: - break; + return get_item_icon(item->getActualType(), item->getInventoryType(), attachment_point, is_multi); } - return action; + return get_item_icon(LLAssetType::AT_LINK, LLInventoryType::IT_NONE, 0, FALSE); } - -//static -void LLInvFVBridgeAction::doAction(LLAssetType::EType asset_type, - const LLUUID& uuid,LLInventoryModel* model) +void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { - LLInvFVBridgeAction* action = createAction(asset_type,uuid,model); - if(action) - { - action->doIt(); - delete action; - } -} + // *TODO: Translate + lldebugs << "LLLink::buildContextMenu()" << llendl; + menuentry_vec_t items; + menuentry_vec_t disabled_items; -//static -void LLInvFVBridgeAction::doAction(const LLUUID& uuid, LLInventoryModel* model) -{ - LLAssetType::EType asset_type = model->getItem(uuid)->getType(); - LLInvFVBridgeAction* action = createAction(asset_type,uuid,model); - if(action) + items.push_back(std::string("Find Original")); + disabled_items.push_back(std::string("Find Original")); + + if(isItemInTrash()) { - action->doIt(); - delete action; + addTrashContextMenuOptions(items, disabled_items); } -} - -LLViewerInventoryItem* LLInvFVBridgeAction::getItem() const -{ - if(mModel) - return (LLViewerInventoryItem*)mModel->getItem(mUUID); - return NULL; -} - -//virtual -void LLTextureBridgeAction::doIt() -{ - if (getItem()) + else { - LLFloaterReg::showInstance("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES); + items.push_back(std::string("Properties")); + addDeleteContextMenuOptions(items, disabled_items); } - - LLInvFVBridgeAction::doIt(); + hide_context_entries(menu, items, disabled_items); } -//virtual -void LLSoundBridgeAction::doIt() +// +=================================================+ +// | LLLinkBridge | +// +=================================================+ +// For broken folder links. +std::string LLLinkFolderBridge::sPrefix("Link: "); +LLUIImagePtr LLLinkFolderBridge::getIcon() const { - LLViewerInventoryItem* item = getItem(); - if(item) + LLFolderType::EType preferred_type = LLFolderType::FT_NONE; + if (LLViewerInventoryItem *item = getItem()) { - LLFloaterReg::showInstance("preview_sound", LLSD(mUUID), TAKE_FOCUS_YES); + if (const LLViewerInventoryCategory* cat = item->getLinkedCategory()) + { + preferred_type = cat->getPreferredType(); + } } - - LLInvFVBridgeAction::doIt(); + return LLFolderBridge::getIcon(preferred_type); } - - -//virtual -void LLLandmarkBridgeAction::doIt() +void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { - LLViewerInventoryItem* item = getItem(); - if( item ) + // *TODO: Translate + lldebugs << "LLLink::buildContextMenu()" << llendl; + menuentry_vec_t items; + menuentry_vec_t disabled_items; + + if (isItemInTrash()) { - // Opening (double-clicking) a landmark immediately teleports, - // but warns you the first time. - LLSD payload; - payload["asset_id"] = item->getAssetUUID(); - LLNotificationsUtil::add("TeleportFromLandmark", LLSD(), payload); + addTrashContextMenuOptions(items, disabled_items); } - - LLInvFVBridgeAction::doIt(); -} - - -//virtual -void LLCallingCardBridgeAction::doIt() -{ - LLViewerInventoryItem* item = getItem(); - if(item && item->getCreatorUUID().notNull()) + else { - LLAvatarActions::showProfile(item->getCreatorUUID()); + items.push_back(std::string("Find Original")); + addDeleteContextMenuOptions(items, disabled_items); } - - LLInvFVBridgeAction::doIt(); + hide_context_entries(menu, items, disabled_items); } - -//virtual -void -LLNotecardBridgeAction::doIt() +void LLLinkFolderBridge::performAction(LLInventoryModel* model, std::string action) { - LLViewerInventoryItem* item = getItem(); - if (item) + if ("goto" == action) { - LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES); + gotoItem(); + return; } - - LLInvFVBridgeAction::doIt(); + LLItemBridge::performAction(model,action); } - -//virtual -void LLGestureBridgeAction::doIt() +void LLLinkFolderBridge::gotoItem() { - LLViewerInventoryItem* item = getItem(); - if (item) + const LLUUID &cat_uuid = getFolderID(); + if (!cat_uuid.isNull()) { - LLPreviewGesture* preview = LLPreviewGesture::show(mUUID, LLUUID::null); - preview->setFocus(TRUE); + if (LLFolderViewItem *base_folder = mRoot->getItemByID(cat_uuid)) + { + if (LLInventoryModel* model = getInventoryModel()) + { + model->fetchDescendentsOf(cat_uuid); + } + base_folder->setOpen(TRUE); + mRoot->setSelectionFromRoot(base_folder,TRUE); + mRoot->scrollToShowSelection(); + } } - - LLInvFVBridgeAction::doIt(); } - -//virtual -void LLAnimationBridgeAction::doIt() +const LLUUID &LLLinkFolderBridge::getFolderID() const { - LLViewerInventoryItem* item = getItem(); - if (item) + if (LLViewerInventoryItem *link_item = getItem()) { - LLFloaterReg::showInstance("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES); + if (const LLViewerInventoryCategory *cat = link_item->getLinkedCategory()) + { + const LLUUID& cat_uuid = cat->getUUID(); + return cat_uuid; + } } - - LLInvFVBridgeAction::doIt(); + return LLUUID::null; } +/******************************************************************************** + ** + ** BRIDGE ACTIONS + **/ -//virtual -void LLObjectBridgeAction::doIt() +// static +void LLInvFVBridgeAction::doAction(LLAssetType::EType asset_type, + const LLUUID& uuid, + LLInventoryModel* model) { - /* - LLFloaterReg::showInstance("properties", mUUID); - */ - LLInvFVBridgeAction::doIt(); -} - + // Perform indirection in case of link. + const LLUUID& linked_uuid = gInventory.getLinkedItemID(uuid); -//virtual -void LLLSLTextBridgeAction::doIt() -{ - LLViewerInventoryItem* item = getItem(); - if (item) + LLInvFVBridgeAction* action = createAction(asset_type,linked_uuid,model); + if(action) { - LLFloaterReg::showInstance("preview_script", LLSD(mUUID), TAKE_FOCUS_YES); + action->doIt(); + delete action; } - - LLInvFVBridgeAction::doIt(); } - -BOOL LLWearableBridgeAction::isInTrash() const +// static +void LLInvFVBridgeAction::doAction(const LLUUID& uuid, LLInventoryModel* model) { - if(!mModel) return FALSE; - const LLUUID trash_id = mModel->findCategoryUUIDForType(LLFolderType::FT_TRASH); - return mModel->isObjectDescendentOf(mUUID, trash_id); + llassert(model); + LLViewerInventoryItem* item = model->getItem(uuid); + llassert(item); + if (item) + { + LLAssetType::EType asset_type = item->getType(); + LLInvFVBridgeAction* action = createAction(asset_type,uuid,model); + if(action) + { + action->doIt(); + delete action; + } + } } -BOOL LLWearableBridgeAction::isAgentInventory() const +LLViewerInventoryItem* LLInvFVBridgeAction::getItem() const { - if(!mModel) return FALSE; - if(gInventory.getRootFolderID() == mUUID) return TRUE; - return mModel->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()); + if (mModel) + return (LLViewerInventoryItem*)mModel->getItem(mUUID); + return NULL; } -void LLWearableBridgeAction::wearOnAvatar() +class LLTextureBridgeAction: public LLInvFVBridgeAction { - // Don't wear anything until initial wearables are loaded, can - // destroy clothing items. - if (!gAgentWearables.areWearablesLoaded()) + friend class LLInvFVBridgeAction; +public: + virtual void doIt() { - LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); - return; + if (getItem()) + { + LLFloaterReg::showInstance("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES); + } + LLInvFVBridgeAction::doIt(); } + virtual ~LLTextureBridgeAction(){} +protected: + LLTextureBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} +}; - LLViewerInventoryItem* item = getItem(); - if(item) +class LLSoundBridgeAction: public LLInvFVBridgeAction +{ + friend class LLInvFVBridgeAction; +public: + virtual void doIt() { - if(!isAgentInventory()) - { - LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - else + LLViewerInventoryItem* item = getItem(); + if (item) { - wear_inventory_item_on_avatar(item); + LLFloaterReg::showInstance("preview_sound", LLSD(mUUID), TAKE_FOCUS_YES); } + LLInvFVBridgeAction::doIt(); } -} + virtual ~LLSoundBridgeAction(){} +protected: + LLSoundBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} +}; -//virtual -void LLWearableBridgeAction::doIt() +class LLLandmarkBridgeAction: public LLInvFVBridgeAction { - if(isInTrash()) - { - LLNotificationsUtil::add("CannotWearTrash"); - } - else if(isAgentInventory()) + friend class LLInvFVBridgeAction; +public: + virtual void doIt() { - if(!get_is_item_worn(mUUID)) + LLViewerInventoryItem* item = getItem(); + if (item) { - wearOnAvatar(); + // Opening (double-clicking) a landmark immediately teleports, + // but warns you the first time. + LLSD payload; + payload["asset_id"] = item->getAssetUUID(); + + LLSD args; + args["LOCATION"] = item->getName(); + + LLNotificationsUtil::add("TeleportFromLandmark", args, payload); } + LLInvFVBridgeAction::doIt(); } - else + virtual ~LLLandmarkBridgeAction(){} +protected: + LLLandmarkBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} +}; + +class LLCallingCardBridgeAction: public LLInvFVBridgeAction +{ + friend class LLInvFVBridgeAction; +public: + virtual void doIt() { - // must be in the inventory library. copy it to our inventory - // and put it on right away. LLViewerInventoryItem* item = getItem(); - if(item && item->isComplete()) + if (item && item->getCreatorUUID().notNull()) { - LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - else if(item) - { - // *TODO: We should fetch the item details, and then do - // the operation above. - LLNotificationsUtil::add("CannotWearInfoNotComplete"); + LLAvatarActions::showProfile(item->getCreatorUUID()); } + LLInvFVBridgeAction::doIt(); } + virtual ~LLCallingCardBridgeAction(){} +protected: + LLCallingCardBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} - LLInvFVBridgeAction::doIt(); -} - -// +=================================================+ -// | LLLinkItemBridge | -// +=================================================+ -// For broken links - -std::string LLLinkItemBridge::sPrefix("Link: "); - +}; -LLUIImagePtr LLLinkItemBridge::getIcon() const +class LLNotecardBridgeAction +: public LLInvFVBridgeAction { - if (LLViewerInventoryItem *item = getItem()) + friend class LLInvFVBridgeAction; +public: + virtual void doIt() { - return get_item_icon(item->getActualType(), item->getInventoryType(), 0, FALSE); + LLViewerInventoryItem* item = getItem(); + if (item) + { + LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES); + } + LLInvFVBridgeAction::doIt(); } - return get_item_icon(LLAssetType::AT_LINK, LLInventoryType::IT_NONE, 0, FALSE); -} + virtual ~LLNotecardBridgeAction(){} +protected: + LLNotecardBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} +}; -void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +class LLGestureBridgeAction: public LLInvFVBridgeAction { - // *TODO: Translate - lldebugs << "LLLink::buildContextMenu()" << llendl; - std::vector<std::string> items; - std::vector<std::string> disabled_items; - - items.push_back(std::string("Find Original")); - disabled_items.push_back(std::string("Find Original")); - - if(isInTrash()) + friend class LLInvFVBridgeAction; +public: + virtual void doIt() { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) + LLViewerInventoryItem* item = getItem(); + if (item) { - disabled_items.push_back(std::string("Purge Item")); + LLPreviewGesture* preview = LLPreviewGesture::show(mUUID, LLUUID::null); + preview->setFocus(TRUE); } - - items.push_back(std::string("Restore Item")); + LLInvFVBridgeAction::doIt(); } - else + virtual ~LLGestureBridgeAction(){} +protected: + LLGestureBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} +}; + +class LLAnimationBridgeAction: public LLInvFVBridgeAction +{ + friend class LLInvFVBridgeAction; +public: + virtual void doIt() { - items.push_back(std::string("Properties")); - items.push_back(std::string("Delete")); - if (!isItemRemovable()) + LLViewerInventoryItem* item = getItem(); + if (item) { - disabled_items.push_back(std::string("Delete")); + LLFloaterReg::showInstance("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES); } + LLInvFVBridgeAction::doIt(); } - hide_context_entries(menu, items, disabled_items); -} - - -// +=================================================+ -// | LLLinkBridge | -// +=================================================+ -// For broken links. - -std::string LLLinkFolderBridge::sPrefix("Link: "); + virtual ~LLAnimationBridgeAction(){} +protected: + LLAnimationBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} +}; +class LLObjectBridgeAction: public LLInvFVBridgeAction +{ + friend class LLInvFVBridgeAction; +public: + virtual void doIt() + { + /* + LLFloaterReg::showInstance("properties", mUUID); + */ + LLInvFVBridgeAction::doIt(); + } + virtual ~LLObjectBridgeAction(){} +protected: + LLObjectBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} +}; -LLUIImagePtr LLLinkFolderBridge::getIcon() const +class LLLSLTextBridgeAction: public LLInvFVBridgeAction { - LLFolderType::EType preferred_type = LLFolderType::FT_NONE; - if (LLViewerInventoryItem *item = getItem()) + friend class LLInvFVBridgeAction; +public: + virtual void doIt() { - if (const LLViewerInventoryCategory* cat = item->getLinkedCategory()) + LLViewerInventoryItem* item = getItem(); + if (item) { - preferred_type = cat->getPreferredType(); + LLFloaterReg::showInstance("preview_script", LLSD(mUUID), TAKE_FOCUS_YES); } + LLInvFVBridgeAction::doIt(); } - return LLFolderBridge::getIcon(preferred_type); -} + virtual ~LLLSLTextBridgeAction(){} +protected: + LLLSLTextBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} +}; -void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +class LLWearableBridgeAction: public LLInvFVBridgeAction { - // *TODO: Translate - lldebugs << "LLLink::buildContextMenu()" << llendl; - std::vector<std::string> items; - std::vector<std::string> disabled_items; - - if(isInTrash()) + friend class LLInvFVBridgeAction; +public: + virtual void doIt() { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) + if(isItemInTrash()) { - disabled_items.push_back(std::string("Purge Item")); + LLNotificationsUtil::add("CannotWearTrash"); } - - items.push_back(std::string("Restore Item")); - } - else - { - items.push_back(std::string("Find Original")); - items.push_back(std::string("Delete")); - if (!isItemRemovable()) + else if(isAgentInventory()) + { + if(!get_is_item_worn(mUUID)) + { + wearOnAvatar(); + } + } + else { - disabled_items.push_back(std::string("Delete")); + // must be in the inventory library. copy it to our inventory + // and put it on right away. + LLViewerInventoryItem* item = getItem(); + if(item && item->isFinished()) + { + LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(); + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + LLUUID::null, + std::string(), + cb); + } + else if(item) + { + // *TODO: We should fetch the item details, and then do + // the operation above. + LLNotificationsUtil::add("CannotWearInfoNotComplete"); + } } + LLInvFVBridgeAction::doIt(); } - hide_context_entries(menu, items, disabled_items); + virtual ~LLWearableBridgeAction(){} +protected: + LLWearableBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} + BOOL isItemInTrash() const; + // return true if the item is in agent inventory. if false, it + // must be lost or in the inventory library. + BOOL isAgentInventory() const; + void wearOnAvatar(); +}; + +BOOL LLWearableBridgeAction::isItemInTrash() const +{ + if(!mModel) return FALSE; + const LLUUID trash_id = mModel->findCategoryUUIDForType(LLFolderType::FT_TRASH); + return mModel->isObjectDescendentOf(mUUID, trash_id); } -void LLLinkFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +BOOL LLWearableBridgeAction::isAgentInventory() const { - if ("goto" == action) + if(!mModel) return FALSE; + if(gInventory.getRootFolderID() == mUUID) return TRUE; + return mModel->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()); +} + +void LLWearableBridgeAction::wearOnAvatar() +{ + // Don't wear anything until initial wearables are loaded, can + // destroy clothing items. + if (!gAgentWearables.areWearablesLoaded()) { - gotoItem(folder); + LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); return; } - LLItemBridge::performAction(folder,model,action); -} -void LLLinkFolderBridge::gotoItem(LLFolderView *folder) -{ - const LLUUID &cat_uuid = getFolderID(); - if (!cat_uuid.isNull()) + LLViewerInventoryItem* item = getItem(); + if(item) { - if (LLFolderViewItem *base_folder = folder->getItemByID(cat_uuid)) + if(!isAgentInventory()) { - if (LLInventoryModel* model = getInventoryModel()) - { - model->fetchDescendentsOf(cat_uuid); - } - base_folder->setOpen(TRUE); - folder->setSelectionFromRoot(base_folder,TRUE); - folder->scrollToShowSelection(); + LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(); + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + LLUUID::null, + std::string(), + cb); + } + else + { + wear_inventory_item_on_avatar(item); } } } -const LLUUID &LLLinkFolderBridge::getFolderID() const +LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type, + const LLUUID& uuid, + LLInventoryModel* model) { - if (LLViewerInventoryItem *link_item = getItem()) + LLInvFVBridgeAction* action = NULL; + switch(asset_type) { - if (const LLViewerInventoryCategory *cat = link_item->getLinkedCategory()) - { - const LLUUID& cat_uuid = cat->getUUID(); - return cat_uuid; - } + case LLAssetType::AT_TEXTURE: + action = new LLTextureBridgeAction(uuid,model); + break; + case LLAssetType::AT_SOUND: + action = new LLSoundBridgeAction(uuid,model); + break; + case LLAssetType::AT_LANDMARK: + action = new LLLandmarkBridgeAction(uuid,model); + break; + case LLAssetType::AT_CALLINGCARD: + action = new LLCallingCardBridgeAction(uuid,model); + break; + case LLAssetType::AT_OBJECT: + action = new LLObjectBridgeAction(uuid,model); + break; + case LLAssetType::AT_NOTECARD: + action = new LLNotecardBridgeAction(uuid,model); + break; + case LLAssetType::AT_ANIMATION: + action = new LLAnimationBridgeAction(uuid,model); + break; + case LLAssetType::AT_GESTURE: + action = new LLGestureBridgeAction(uuid,model); + break; + case LLAssetType::AT_LSL_TEXT: + action = new LLLSLTextBridgeAction(uuid,model); + break; + case LLAssetType::AT_CLOTHING: + case LLAssetType::AT_BODYPART: + action = new LLWearableBridgeAction(uuid,model); + break; + default: + break; } - return LLUUID::null; + return action; } + +/** Bridge Actions + ** + ********************************************************************************/ |