diff options
Diffstat (limited to 'indra/newview/llinventoryfunctions.cpp')
-rw-r--r-- | indra/newview/llinventoryfunctions.cpp | 687 |
1 files changed, 481 insertions, 206 deletions
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 56de7cc771..a44a1fb0f0 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1,5 +1,5 @@ /** - * @file llfloaterinventory.cpp + * @file llinventoryfunctions.cpp * @brief Implementation of the inventory view and associated stuff. * * $LicenseInfo:firstyear=2001&license=viewergpl$ @@ -41,6 +41,7 @@ #include "llagentwearables.h" #include "llcallingcard.h" #include "llfloaterreg.h" +#include "llinventorydefines.h" #include "llsdserialize.h" #include "llfiltereditor.h" #include "llspinctrl.h" @@ -51,7 +52,7 @@ #include "llappearancemgr.h" #include "llappviewer.h" //#include "llfirstuse.h" -#include "llfloatercustomize.h" +#include "llfloaterinventory.h" #include "llfocusmgr.h" #include "llfolderview.h" #include "llgesturemgr.h" @@ -63,6 +64,7 @@ #include "llinventorypanel.h" #include "lllineeditor.h" #include "llmenugl.h" +#include "llpanelmaininventory.h" #include "llpreviewanim.h" #include "llpreviewgesture.h" #include "llpreviewnotecard.h" @@ -73,6 +75,8 @@ #include "llscrollbar.h" #include "llscrollcontainer.h" #include "llselectmgr.h" +#include "llsidetray.h" +#include "llsidepanelinventory.h" #include "lltabcontainer.h" #include "lltooldraganddrop.h" #include "lluictrlfactory.h" @@ -86,46 +90,422 @@ BOOL LLInventoryState::sWearNewClothing = FALSE; LLUUID LLInventoryState::sWearNewClothingTransactionID; +// Generates a string containing the path to the item specified by +// item_id. +void append_path(const LLUUID& id, std::string& path) +{ + std::string temp; + const LLInventoryObject* obj = gInventory.getObject(id); + LLUUID parent_id; + if(obj) parent_id = obj->getParentUUID(); + std::string forward_slash("/"); + while(obj) + { + obj = gInventory.getCategory(parent_id); + if(obj) + { + temp.assign(forward_slash + obj->getName() + temp); + parent_id = obj->getParentUUID(); + } + } + path.append(temp); +} -///---------------------------------------------------------------------------- -/// LLInventoryCollectFunctor implementations -///---------------------------------------------------------------------------- +void change_item_parent(LLInventoryModel* model, + LLViewerInventoryItem* item, + const LLUUID& new_parent_id, + BOOL restamp) +{ + if (item->getParentUUID() != new_parent_id) + { + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); + update.push_back(new_folder); + gInventory.accountForUpdate(update); + + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); + new_item->setParent(new_parent_id); + new_item->updateParentOnServer(restamp); + model->updateItem(new_item); + model->notifyObservers(); + } +} -// static -bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(LLInventoryItem* item) +void change_category_parent(LLInventoryModel* model, + LLViewerInventoryCategory* cat, + const LLUUID& new_parent_id, + BOOL restamp) +{ + if (!model || !cat) + { + return; + } + + // Can't move a folder into a child of itself. + if (model->isObjectDescendentOf(new_parent_id, cat->getUUID())) + { + return; + } + + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); + update.push_back(new_folder); + model->accountForUpdate(update); + + LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); + new_cat->setParent(new_parent_id); + new_cat->updateParentOnServer(restamp); + model->updateCategory(new_cat); + model->notifyObservers(); +} + +void remove_category(LLInventoryModel* model, const LLUUID& cat_id) +{ + if (!model || !get_is_category_removable(model, cat_id)) + { + return; + } + + // Look for any gestures and deactivate them + LLInventoryModel::cat_array_t descendent_categories; + LLInventoryModel::item_array_t descendent_items; + gInventory.collectDescendents(cat_id, descendent_categories, descendent_items, FALSE); + + for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin(); + iter != descendent_items.end(); + ++iter) + { + const LLViewerInventoryItem* item = (*iter); + const LLUUID& item_id = item->getUUID(); + if (item->getType() == LLAssetType::AT_GESTURE + && LLGestureMgr::instance().isGestureActive(item_id)) + { + LLGestureMgr::instance().deactivateGesture(item_id); + } + } + + LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + if (cat) + { + const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); + change_category_parent(model, cat, trash_id, TRUE); + } +} + +void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name) { + LLViewerInventoryCategory* cat; + + if (!model || + !get_is_category_renameable(model, cat_id) || + (cat = model->getCategory(cat_id)) == NULL || + cat->getName() == new_name) + { + return; + } + + LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); + new_cat->rename(new_name); + new_cat->updateServer(FALSE); + model->updateCategory(new_cat); + + model->notifyObservers(); +} + +BOOL get_is_item_worn(const LLUUID& id) +{ + const LLViewerInventoryItem* item = gInventory.getItem(id); if (!item) - return false; + return FALSE; + + // Consider the item as worn if it has links in COF. + if (LLAppearanceMgr::instance().isLinkInCOF(id)) + { + return TRUE; + } + + switch(item->getType()) + { + case LLAssetType::AT_OBJECT: + { + if (isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item->getLinkedUUID())) + return TRUE; + break; + } + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_CLOTHING: + if(gAgentWearables.isWearingItem(item->getLinkedUUID())) + return TRUE; + break; + case LLAssetType::AT_GESTURE: + if (LLGestureMgr::instance().isGestureActive(item->getLinkedUUID())) + return TRUE; + break; + default: + break; + } + return FALSE; +} + +BOOL get_can_item_be_worn(const LLUUID& id) +{ + const LLViewerInventoryItem* item = gInventory.getItem(id); + if (!item) + return FALSE; + + if (LLAppearanceMgr::isLinkInCOF(item->getLinkedUUID())) + { + // an item having links in COF (i.e. a worn item) + return FALSE; + } + + if (gInventory.isObjectDescendentOf(id, LLAppearanceMgr::instance().getCOF())) + { + // a non-link object in COF (should not normally happen) + return FALSE; + } + + const LLUUID trash_id = gInventory.findCategoryUUIDForType( + LLFolderType::FT_TRASH); - bool allowed = false; + // item can't be worn if base obj in trash, see EXT-7015 + if (gInventory.isObjectDescendentOf(item->getLinkedUUID(), + trash_id)) + { + return false; + } switch(item->getType()) { - case LLAssetType::AT_CALLINGCARD: - // not allowed - break; - - case LLAssetType::AT_OBJECT: - if (isAgentAvatarValid() && !gAgentAvatarp->isWearingAttachment(item->getUUID())) + case LLAssetType::AT_OBJECT: + { + if (isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item->getLinkedUUID())) + { + // Already being worn + return FALSE; + } + else + { + // Not being worn yet. + return TRUE; + } + break; + } + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_CLOTHING: + if(gAgentWearables.isWearingItem(item->getLinkedUUID())) + { + // Already being worn + return FALSE; + } + else + { + // Not being worn yet. + return TRUE; + } + break; + default: + break; + } + return FALSE; +} + +BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id) +{ + if (!model) + { + return FALSE; + } + + // Can't delete an item that's in the library. + if (!model->isObjectDescendentOf(id, 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(id)) + { + if (get_is_item_worn(id)) + { + return FALSE; + } + } + + const LLInventoryObject *obj = model->getItem(id); + if (obj && obj->getIsLinkType()) + { + return TRUE; + } + if (get_is_item_worn(id)) + { + return FALSE; + } + return TRUE; +} + +BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id) +{ + // NOTE: This function doesn't check the folder's children. + // See LLFolderBridge::isItemRemovable for a function that does + // consider the children. + + if (!model) + { + return FALSE; + } + + if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID())) + { + return FALSE; + } + + if (!isAgentAvatarValid()) return FALSE; + + const LLInventoryCategory* category = model->getCategory(id); + if (!category) + { + return FALSE; + } + + const LLFolderType::EType folder_type = category->getPreferredType(); + + if (LLFolderType::lookupIsProtectedType(folder_type)) + { + return FALSE; + } + + // Can't delete the outfit that is currently being worn. + if (folder_type == LLFolderType::FT_OUTFIT) + { + const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink(); + if (base_outfit_link && (category == base_outfit_link->getLinkedCategory())) + { + return FALSE; + } + } + + return TRUE; +} + +BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id) +{ + if (!model) + { + return FALSE; + } + + LLViewerInventoryCategory* cat = model->getCategory(id); + + if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) && + cat->getOwnerID() == gAgent.getID()) + { + return TRUE; + } + return FALSE; +} + +void show_task_item_profile(const LLUUID& item_uuid, const LLUUID& object_id) +{ + LLSideTray::getInstance()->showPanel("sidepanel_inventory", LLSD().with("id", item_uuid).with("object", object_id)); +} + +void show_item_profile(const LLUUID& item_uuid) +{ + LLUUID linked_uuid = gInventory.getLinkedItemID(item_uuid); + LLSideTray::getInstance()->showPanel("sidepanel_inventory", LLSD().with("id", linked_uuid)); +} + +void show_item_original(const LLUUID& item_uuid) +{ + //sidetray inventory panel + LLSidepanelInventory *sidepanel_inventory = + dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->getPanel("sidepanel_inventory")); + + bool reset_inventory_filter = !LLSideTray::getInstance()->isPanelActive("sidepanel_inventory"); + + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if (!active_panel) + { + //this may happen when there is no floatera and other panel is active in inventory tab + + if (sidepanel_inventory) + { + sidepanel_inventory->showInventoryPanel(); + } + } + + active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if (!active_panel) + { + return; + } + active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_NO); + + if(reset_inventory_filter) + { + //inventory floater + bool floater_inventory_visible = false; + + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) { - allowed = true; + LLFloaterInventory* floater_inventory = dynamic_cast<LLFloaterInventory*>(*iter); + if (floater_inventory) + { + LLPanelMainInventory* main_inventory = floater_inventory->getMainInventoryPanel(); + + main_inventory->onFilterEdit(""); + + if(floater_inventory->getVisible()) + { + floater_inventory_visible = true; + } + } } - break; - - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_CLOTHING: - if(!gAgentWearables.isWearingItem(item->getUUID())) + if(sidepanel_inventory && !floater_inventory_visible) { - allowed = true; + LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); + + main_inventory->onFilterEdit(""); } - break; - - default: - allowed = true; - break; } +} + +///---------------------------------------------------------------------------- +/// LLInventoryCollectFunctor implementations +///---------------------------------------------------------------------------- + +// static +bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(const LLInventoryItem* item) +{ + if (!item) + return false; - return allowed; + switch(item->getType()) + { + case LLAssetType::AT_CALLINGCARD: + return false; + break; + case LLAssetType::AT_OBJECT: + if (isAgentAvatarValid() && !gAgentAvatarp->isWearingAttachment(item->getUUID())) + return true; + break; + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_CLOTHING: + if(!gAgentWearables.isWearingItem(item->getUUID())) + return true; + break; + default: + return true; + break; + } + return false; } bool LLIsType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) @@ -155,6 +535,19 @@ bool LLIsNotType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) return TRUE; } +bool LLIsOfAssetType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + if(mType == LLAssetType::AT_CATEGORY) + { + if(cat) return TRUE; + } + if(item) + { + if(item->getActualType() == mType) return TRUE; + } + return FALSE; +} + bool LLIsTypeWithPermissions::operator()(LLInventoryCategory* cat, LLInventoryItem* item) { if(mType == LLAssetType::AT_CATEGORY) @@ -280,6 +673,66 @@ bool LLFindWearables::operator()(LLInventoryCategory* cat, return FALSE; } +LLFindWearablesEx::LLFindWearablesEx(bool is_worn, bool include_body_parts) +: mIsWorn(is_worn) +, mIncludeBodyParts(include_body_parts) +{} + +bool LLFindWearablesEx::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item); + if (!vitem) return false; + + // Skip non-wearables. + if (!vitem->isWearableType() && vitem->getType() != LLAssetType::AT_OBJECT) + { + return false; + } + + // Skip body parts if requested. + if (!mIncludeBodyParts && vitem->getType() == LLAssetType::AT_BODYPART) + { + return false; + } + + return (bool) get_is_item_worn(item->getUUID()) == mIsWorn; +} + +bool LLFindWearablesOfType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + if (!item) return false; + if (item->getType() != LLAssetType::AT_CLOTHING && + item->getType() != LLAssetType::AT_BODYPART) + { + return false; + } + + LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item); + if (!vitem || vitem->getWearableType() != mWearableType) return false; + + return true; +} + +void LLFindWearablesOfType::setType(LLWearableType::EType type) +{ + mWearableType = type; +} + +bool LLFindNonRemovableObjects::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + if (item) + { + return !get_is_item_removable(&gInventory, item->getUUID()); + } + if (cat) + { + return !get_is_category_removable(&gInventory, cat->getUUID()); + } + + llwarns << "Not a category and not an item?" << llendl; + return false; +} + ///---------------------------------------------------------------------------- /// LLAssetIDMatches ///---------------------------------------------------------------------------- @@ -407,181 +860,3 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder) } } -static void assign_clothing_bodypart_icon(EInventoryIcon &idx, U32 attachment_point) -{ - const EWearableType wearable_type = EWearableType(LLInventoryItem::II_FLAGS_WEARABLES_MASK & attachment_point); - switch(wearable_type) - { - case WT_SHAPE: - idx = BODYPART_SHAPE_ICON_NAME; - break; - case WT_SKIN: - idx = BODYPART_SKIN_ICON_NAME; - break; - case WT_HAIR: - idx = BODYPART_HAIR_ICON_NAME; - break; - case WT_EYES: - idx = BODYPART_EYES_ICON_NAME; - break; - case WT_SHIRT: - idx = CLOTHING_SHIRT_ICON_NAME; - break; - case WT_PANTS: - idx = CLOTHING_PANTS_ICON_NAME; - break; - case WT_SHOES: - idx = CLOTHING_SHOES_ICON_NAME; - break; - case WT_SOCKS: - idx = CLOTHING_SOCKS_ICON_NAME; - break; - case WT_JACKET: - idx = CLOTHING_JACKET_ICON_NAME; - break; - case WT_GLOVES: - idx = CLOTHING_GLOVES_ICON_NAME; - break; - case WT_UNDERSHIRT: - idx = CLOTHING_UNDERSHIRT_ICON_NAME; - break; - case WT_UNDERPANTS: - idx = CLOTHING_UNDERPANTS_ICON_NAME; - break; - case WT_SKIRT: - idx = CLOTHING_SKIRT_ICON_NAME; - break; - case WT_ALPHA: - idx = CLOTHING_ALPHA_ICON_NAME; - break; - case WT_TATTOO: - idx = CLOTHING_TATTOO_ICON_NAME; - break; - default: - break; - } -} - - -const std::string& get_item_icon_name(LLAssetType::EType asset_type, - LLInventoryType::EType inventory_type, - U32 attachment_point, - BOOL item_is_multi ) -{ - EInventoryIcon idx = OBJECT_ICON_NAME; - if ( item_is_multi ) - { - idx = OBJECT_MULTI_ICON_NAME; - } - - switch(asset_type) - { - case LLAssetType::AT_TEXTURE: - if(LLInventoryType::IT_SNAPSHOT == inventory_type) - { - idx = SNAPSHOT_ICON_NAME; - } - else - { - idx = TEXTURE_ICON_NAME; - } - break; - - case LLAssetType::AT_SOUND: - idx = SOUND_ICON_NAME; - break; - case LLAssetType::AT_CALLINGCARD: - if(attachment_point!= 0) - { - idx = CALLINGCARD_ONLINE_ICON_NAME; - } - else - { - idx = CALLINGCARD_OFFLINE_ICON_NAME; - } - break; - case LLAssetType::AT_LANDMARK: - if(attachment_point!= 0) - { - idx = LANDMARK_VISITED_ICON_NAME; - } - else - { - idx = LANDMARK_ICON_NAME; - } - break; - case LLAssetType::AT_SCRIPT: - case LLAssetType::AT_LSL_TEXT: - case LLAssetType::AT_LSL_BYTECODE: - idx = SCRIPT_ICON_NAME; - break; - case LLAssetType::AT_CLOTHING: - idx = CLOTHING_ICON_NAME; - assign_clothing_bodypart_icon(idx, attachment_point); - break; - case LLAssetType::AT_BODYPART: - idx = BODYPART_ICON_NAME; - assign_clothing_bodypart_icon(idx, attachment_point); - break; - case LLAssetType::AT_NOTECARD: - idx = NOTECARD_ICON_NAME; - break; - case LLAssetType::AT_ANIMATION: - idx = ANIMATION_ICON_NAME; - break; - case LLAssetType::AT_GESTURE: - idx = GESTURE_ICON_NAME; - break; - case LLAssetType::AT_LINK: - idx = LINKITEM_ICON_NAME; - break; - case LLAssetType::AT_LINK_FOLDER: - idx = LINKFOLDER_ICON_NAME; - break; - case LLAssetType::AT_MESH: - idx = MESH_ICON_NAME; - break; - default: - break; - } - - return ICON_NAME[idx]; -} - -LLUIImagePtr get_item_icon(LLAssetType::EType asset_type, - LLInventoryType::EType inventory_type, - U32 attachment_point, - BOOL item_is_multi) -{ - const std::string& icon_name = get_item_icon_name(asset_type, inventory_type, attachment_point, item_is_multi ); - return LLUI::getUIImage(icon_name); -} - -BOOL get_is_item_worn(const LLUUID& id) -{ - const LLViewerInventoryItem* item = gInventory.getItem(id); - if (!item) - return FALSE; - - switch(item->getType()) - { - case LLAssetType::AT_OBJECT: - { - if (isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item->getLinkedUUID())) - return TRUE; - break; - } - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_CLOTHING: - if(gAgentWearables.isWearingItem(item->getLinkedUUID())) - return TRUE; - break; - case LLAssetType::AT_GESTURE: - if (LLGestureMgr::instance().isGestureActive(item->getLinkedUUID())) - return TRUE; - break; - default: - break; - } - return FALSE; -} |