diff options
| author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 21:25:21 +0200 |
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-22 22:40:26 +0300 |
| commit | e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch) | |
| tree | 1bb897489ce524986f6196201c10ac0d8861aa5f /indra/newview/llpanelobjectinventory.cpp | |
| parent | 069ea06848f766466f1a281144c82a0f2bd79f3a (diff) | |
Fix line endlings
Diffstat (limited to 'indra/newview/llpanelobjectinventory.cpp')
| -rw-r--r-- | indra/newview/llpanelobjectinventory.cpp | 3866 |
1 files changed, 1933 insertions, 1933 deletions
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 46712020b2..d33ccc0216 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1,1933 +1,1933 @@ -/**
- * @file llsidepanelinventory.cpp
- * @brief LLPanelObjectInventory class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-//*****************************************************************************
-//
-// Implementation of the panel inventory - used to view and control a
-// task's inventory.
-//
-//*****************************************************************************
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelobjectinventory.h"
-
-#include "llmenugl.h"
-#include "llnotificationsutil.h"
-#include "roles_constants.h"
-
-#include "llagent.h"
-#include "llavataractions.h"
-#include "llcallbacklist.h"
-#include "llbuycurrencyhtml.h"
-#include "llfloaterreg.h"
-#include "llfolderview.h"
-#include "llinventorybridge.h"
-#include "llinventorydefines.h"
-#include "llinventoryicon.h"
-#include "llinventoryfilter.h"
-#include "llinventoryfunctions.h"
-#include "llmaterialeditor.h"
-#include "llpreviewanim.h"
-#include "llpreviewgesture.h"
-#include "llpreviewnotecard.h"
-#include "llpreviewscript.h"
-#include "llpreviewsound.h"
-#include "llpreviewtexture.h"
-#include "llscrollcontainer.h"
-#include "llselectmgr.h"
-#include "llstatusbar.h"
-#include "lltooldraganddrop.h"
-#include "lltrans.h"
-#include "llviewerassettype.h"
-#include "llviewerinventory.h"
-#include "llviewerregion.h"
-#include "llviewerobjectlist.h"
-#include "llviewermessage.h"
-
-const LLColor4U DEFAULT_WHITE(255, 255, 255);
-
-///----------------------------------------------------------------------------
-/// Class LLTaskInvFVBridge
-///----------------------------------------------------------------------------
-
-class LLTaskInvFVBridge : public LLFolderViewModelItemInventory
-{
-protected:
- LLUUID mUUID;
- std::string mName;
- mutable std::string mDisplayName;
- mutable std::string mSearchableName;
- LLPanelObjectInventory* mPanel;
- U32 mFlags;
- LLAssetType::EType mAssetType;
- LLInventoryType::EType mInventoryType;
-
- LLInventoryObject* findInvObject() const;
- LLInventoryItem* findItem() const;
-
-public:
- LLTaskInvFVBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name,
- U32 flags=0);
- virtual ~LLTaskInvFVBridge() {}
-
- virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
- virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
-
- static LLTaskInvFVBridge* createObjectBridge(LLPanelObjectInventory* panel,
- LLInventoryObject* object);
- void showProperties();
- S32 getPrice();
-
- // LLFolderViewModelItemInventory functionality
- virtual const std::string& getName() const;
- virtual const std::string& getDisplayName() const;
- virtual const std::string& getSearchableName() const;
-
- virtual std::string getSearchableDescription() const {return LLStringUtil::null;}
- virtual std::string getSearchableCreatorName() const {return LLStringUtil::null;}
- virtual std::string getSearchableUUIDString() const {return LLStringUtil::null;}
-
-
- virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
- /*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
- virtual const LLUUID& getUUID() const { return mUUID; }
- virtual const LLUUID& getThumbnailUUID() const { return LLUUID::null;}
- virtual time_t getCreationDate() const;
- virtual void setCreationDate(time_t creation_date_utc);
-
- virtual LLUIImagePtr getIcon() const;
- virtual void openItem();
- virtual bool canOpenItem() const { return false; }
- virtual void closeItem() {}
- virtual void selectItem() {}
- virtual void navigateToFolder(bool new_window = false, bool change_mode = false) {}
- virtual bool isItemRenameable() const;
- virtual bool renameItem(const std::string& new_name);
- virtual bool isItemMovable() const;
- virtual bool isItemRemovable(bool check_worn = true) const;
- virtual bool removeItem();
- virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
- virtual void move(LLFolderViewModelItem* parent_listener);
- virtual bool isItemCopyable(bool can_copy_as_link = true) const;
- virtual bool copyToClipboard() const;
- virtual bool cutToClipboard();
- virtual bool isClipboardPasteable() const;
- virtual void pasteFromClipboard();
- virtual void pasteLinkFromClipboard();
- virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
- virtual void performAction(LLInventoryModel* model, std::string action);
- virtual bool isUpToDate() const { return true; }
- virtual bool hasChildren() const { return false; }
- virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
- virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
- virtual LLSettingsType::type_e getSettingsType() const { return LLSettingsType::ST_NONE; }
- virtual EInventorySortGroup getSortGroup() const { return SG_ITEM; }
- virtual LLInventoryObject* getInventoryObject() const { return findInvObject(); }
-
-
- // LLDragAndDropBridge functionality
- virtual LLToolDragAndDrop::ESource getDragSource() const { return LLToolDragAndDrop::SOURCE_WORLD; }
- virtual bool startDrag(EDragAndDropType* type, LLUUID* id) const;
- virtual bool dragOrDrop(MASK mask, bool drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- std::string& tooltip_msg);
-};
-
-LLTaskInvFVBridge::LLTaskInvFVBridge(
- LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name,
- U32 flags)
-: LLFolderViewModelItemInventory(panel->getRootViewModel()),
- mUUID(uuid),
- mName(name),
- mPanel(panel),
- mFlags(flags),
- mAssetType(LLAssetType::AT_NONE),
- mInventoryType(LLInventoryType::IT_NONE)
-{
- const LLInventoryItem *item = findItem();
- if (item)
- {
- mAssetType = item->getType();
- mInventoryType = item->getInventoryType();
- }
-}
-
-LLInventoryObject* LLTaskInvFVBridge::findInvObject() const
-{
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if (object)
- {
- return object->getInventoryObject(mUUID);
- }
- return NULL;
-}
-
-
-LLInventoryItem* LLTaskInvFVBridge::findItem() const
-{
- return dynamic_cast<LLInventoryItem*>(findInvObject());
-}
-
-void LLTaskInvFVBridge::showProperties()
-{
- show_task_item_profile(mUUID, mPanel->getTaskUUID());
-}
-
-S32 LLTaskInvFVBridge::getPrice()
-{
- LLInventoryItem* item = findItem();
- if(item)
- {
- return item->getSaleInfo().getSalePrice();
- }
- else
- {
- return -1;
- }
-}
-
-const std::string& LLTaskInvFVBridge::getName() const
-{
- return mName;
-}
-
-const std::string& LLTaskInvFVBridge::getDisplayName() const
-{
- LLInventoryItem* item = findItem();
-
- if(item)
- {
- mDisplayName.assign(item->getName());
-
- // Localize "New Script", "New Script 1", "New Script 2", etc.
- if (item->getType() == LLAssetType::AT_LSL_TEXT &&
- LLStringUtil::startsWith(item->getName(), "New Script"))
- {
- LLStringUtil::replaceString(mDisplayName, "New Script", LLTrans::getString("PanelContentsNewScript"));
- }
-
- const LLPermissions& perm(item->getPermissions());
- bool copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
- bool mod = gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE);
- bool xfer = gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE);
-
- if(!copy)
- {
- mDisplayName.append(LLTrans::getString("no_copy"));
- }
- if(!mod)
- {
- mDisplayName.append(LLTrans::getString("no_modify"));
- }
- if(!xfer)
- {
- mDisplayName.append(LLTrans::getString("no_transfer"));
- }
- }
-
- mSearchableName.assign(mDisplayName + getLabelSuffix());
-
- return mDisplayName;
-}
-
-const std::string& LLTaskInvFVBridge::getSearchableName() const
-{
- return mSearchableName;
-}
-
-
-// BUG: No creation dates for task inventory
-time_t LLTaskInvFVBridge::getCreationDate() const
-{
- return 0;
-}
-
-void LLTaskInvFVBridge::setCreationDate(time_t creation_date_utc)
-{}
-
-
-LLUIImagePtr LLTaskInvFVBridge::getIcon() const
-{
- const bool item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS);
-
- return LLInventoryIcon::getIcon(mAssetType, mInventoryType, 0, item_is_multi );
-}
-
-void LLTaskInvFVBridge::openItem()
-{
- // no-op.
- LL_DEBUGS() << "LLTaskInvFVBridge::openItem()" << LL_ENDL;
-}
-
-bool LLTaskInvFVBridge::isItemRenameable() const
-{
- if(gAgent.isGodlike()) return true;
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(object)
- {
- LLInventoryItem* item = (LLInventoryItem*)(object->getInventoryObject(mUUID));
- if(item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
- GP_OBJECT_MANIPULATE, GOD_LIKE))
- {
- return true;
- }
- }
- return false;
-}
-
-bool LLTaskInvFVBridge::renameItem(const std::string& new_name)
-{
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(object)
- {
- LLViewerInventoryItem* item = NULL;
- item = (LLViewerInventoryItem*)object->getInventoryObject(mUUID);
- if(item && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
- GP_OBJECT_MANIPULATE, GOD_LIKE)))
- {
- LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
- new_item->rename(new_name);
- object->updateInventory(
- new_item,
- TASK_INVENTORY_ITEM_KEY,
- false);
- }
- }
- return true;
-}
-
-bool LLTaskInvFVBridge::isItemMovable() const
-{
- //LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- //if(object && (object->permModify() || gAgent.isGodlike()))
- //{
- // return true;
- //}
- //return false;
- return true;
-}
-
-bool LLTaskInvFVBridge::isItemRemovable(bool check_worn) const
-{
- const LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(object
- && (object->permModify() || object->permYouOwner()))
- {
- return true;
- }
- return false;
-}
-
-bool remove_task_inventory_callback(const LLSD& notification, const LLSD& response, LLPanelObjectInventory* panel)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
- if(option == 0 && object)
- {
- // yes
- LLSD::array_const_iterator list_end = notification["payload"]["inventory_ids"].endArray();
- for (LLSD::array_const_iterator list_it = notification["payload"]["inventory_ids"].beginArray();
- list_it != list_end;
- ++list_it)
- {
- object->removeInventory(list_it->asUUID());
- }
-
- // refresh the UI.
- panel->refresh();
- }
- return false;
-}
-
-// helper for remove
-// ! REFACTOR ! two_uuids_list_t is also defined in llinventorybridge.h, but differently.
-typedef std::pair<LLUUID, std::list<LLUUID> > panel_two_uuids_list_t;
-typedef std::pair<LLPanelObjectInventory*, panel_two_uuids_list_t> remove_data_t;
-bool LLTaskInvFVBridge::removeItem()
-{
- if(isItemRemovable() && mPanel)
- {
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(object)
- {
- if(object->permModify())
- {
- // just do it.
- object->removeInventory(mUUID);
- return true;
- }
- else
- {
- LLSD payload;
- payload["task_id"] = mPanel->getTaskUUID();
- payload["inventory_ids"].append(mUUID);
- LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel));
- return false;
- }
- }
- }
- return false;
-}
-
-void LLTaskInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
-{
- if (!mPanel)
- {
- return;
- }
-
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if (!object)
- {
- return;
- }
-
- if (!object->permModify())
- {
- LLSD payload;
- payload["task_id"] = mPanel->getTaskUUID();
- for (S32 i = 0; i < (S32)batch.size(); i++)
- {
- LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
- payload["inventory_ids"].append(itemp->getUUID());
- }
- LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel));
-
- }
- else
- {
- for (S32 i = 0; i < (S32)batch.size(); i++)
- {
- LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
-
- if(itemp->isItemRemovable())
- {
- // just do it.
- object->removeInventory(itemp->getUUID());
- }
- }
- }
-}
-
-void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener)
-{
-}
-
-bool LLTaskInvFVBridge::isItemCopyable(bool can_link) const
-{
- LLInventoryItem* item = findItem();
- if(!item) return false;
- return gAgent.allowOperation(PERM_COPY, item->getPermissions(),
- GP_OBJECT_MANIPULATE);
-}
-
-bool LLTaskInvFVBridge::copyToClipboard() const
-{
- return false;
-}
-
-bool LLTaskInvFVBridge::cutToClipboard()
-{
- return false;
-}
-
-bool LLTaskInvFVBridge::isClipboardPasteable() const
-{
- return false;
-}
-
-void LLTaskInvFVBridge::pasteFromClipboard()
-{
-}
-
-void LLTaskInvFVBridge::pasteLinkFromClipboard()
-{
-}
-
-bool LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
-{
- //LL_INFOS() << "LLTaskInvFVBridge::startDrag()" << LL_ENDL;
- if(mPanel)
- {
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(object)
- {
- LLInventoryItem* inv = NULL;
- if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID)))
- {
- const LLPermissions& perm = inv->getPermissions();
- bool can_copy = gAgent.allowOperation(PERM_COPY, perm,
- GP_OBJECT_MANIPULATE);
- if (object->isAttachment() && !can_copy)
- {
- //RN: no copy contents of attachments cannot be dragged out
- // due to a race condition and possible exploit where
- // attached objects do not update their inventory items
- // when their contents are manipulated
- return false;
- }
- if((can_copy && perm.allowTransferTo(gAgent.getID()))
- || object->permYouOwner())
-// || gAgent.isGodlike())
-
- {
- *type = LLViewerAssetType::lookupDragAndDropType(inv->getType());
-
- *id = inv->getUUID();
- return true;
- }
- }
- }
- }
- return false;
-}
-
-bool LLTaskInvFVBridge::dragOrDrop(MASK mask, bool drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- std::string& tooltip_msg)
-{
- //LL_INFOS() << "LLTaskInvFVBridge::dragOrDrop()" << LL_ENDL;
- return false;
-}
-
-// virtual
-void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string action)
-{
- if (action == "task_open")
- {
- openItem();
- }
- else if (action == "task_properties")
- {
- showProperties();
- }
-}
-
-void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
- LLInventoryItem* item = findItem();
- std::vector<std::string> items;
- std::vector<std::string> disabled_items;
-
- if (!item)
- {
- hide_context_entries(menu, items, disabled_items);
- return;
- }
-
- if (canOpenItem())
- {
- items.push_back(std::string("Task Open"));
- }
- items.push_back(std::string("Task Properties"));
- if ((flags & FIRST_SELECTED_ITEM) == 0)
- {
- disabled_items.push_back(std::string("Task Properties"));
- }
- if(isItemRenameable())
- {
- items.push_back(std::string("Task Rename"));
- if ((flags & FIRST_SELECTED_ITEM) == 0)
- {
- disabled_items.push_back(std::string("Task Rename"));
- }
- }
- if(isItemRemovable())
- {
- items.push_back(std::string("Task Remove"));
- }
-
- hide_context_entries(menu, items, disabled_items);
-}
-
-
-///----------------------------------------------------------------------------
-/// Class LLTaskFolderBridge
-///----------------------------------------------------------------------------
-
-class LLTaskCategoryBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskCategoryBridge(
- LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name);
-
- virtual LLUIImagePtr getIcon() const;
- virtual const std::string& getDisplayName() const;
- virtual bool isItemRenameable() const;
- // virtual bool isItemCopyable() const { return false; }
- virtual bool renameItem(const std::string& new_name);
- virtual bool isItemRemovable(bool check_worn = true) const;
- virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
- virtual bool hasChildren() const;
- virtual bool startDrag(EDragAndDropType* type, LLUUID* id) const;
- virtual bool dragOrDrop(MASK mask, bool drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- std::string& tooltip_msg);
- virtual bool canOpenItem() const { return true; }
- virtual void openItem();
- virtual EInventorySortGroup getSortGroup() const { return SG_NORMAL_FOLDER; }
-};
-
-LLTaskCategoryBridge::LLTaskCategoryBridge(
- LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name)
-{
-}
-
-LLUIImagePtr LLTaskCategoryBridge::getIcon() const
-{
- return LLUI::getUIImage("Inv_FolderClosed");
-}
-
-// virtual
-const std::string& LLTaskCategoryBridge::getDisplayName() const
-{
- LLInventoryObject* cat = findInvObject();
-
- if (cat)
- {
- std::string name = cat->getName();
- if (mChildren.size() > 0)
- {
- // Add item count
- // Normally we would be using getLabelSuffix for this
- // but object's inventory just uses displaynames
- LLStringUtil::format_map_t args;
- args["[ITEMS_COUNT]"] = llformat("%d", mChildren.size());
-
- name.append(" " + LLTrans::getString("InventoryItemsCount", args));
- }
- mDisplayName.assign(name);
- }
-
- return mDisplayName;
-}
-
-bool LLTaskCategoryBridge::isItemRenameable() const
-{
- return false;
-}
-
-bool LLTaskCategoryBridge::renameItem(const std::string& new_name)
-{
- return false;
-}
-
-bool LLTaskCategoryBridge::isItemRemovable(bool check_worn) const
-{
- return false;
-}
-
-void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
- std::vector<std::string> items;
- std::vector<std::string> disabled_items;
- hide_context_entries(menu, items, disabled_items);
-}
-
-bool LLTaskCategoryBridge::hasChildren() const
-{
- // return true if we have or do know know if we have children.
- // *FIX: For now, return false - we will know for sure soon enough.
- return false;
-}
-
-void LLTaskCategoryBridge::openItem()
-{
-}
-
-bool LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
-{
- //LL_INFOS() << "LLTaskInvFVBridge::startDrag()" << LL_ENDL;
- if(mPanel && mUUID.notNull())
- {
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(object)
- {
- const LLInventoryObject* cat = object->getInventoryObject(mUUID);
- if ( (cat) && (move_inv_category_world_to_agent(mUUID, LLUUID::null, false)) )
- {
- *type = LLViewerAssetType::lookupDragAndDropType(cat->getType());
- *id = mUUID;
- return true;
- }
- }
- }
- return false;
-}
-
-bool LLTaskCategoryBridge::dragOrDrop(MASK mask, bool drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- std::string& tooltip_msg)
-{
- //LL_INFOS() << "LLTaskCategoryBridge::dragOrDrop()" << LL_ENDL;
- bool accept = false;
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(object)
- {
- switch(cargo_type)
- {
- case DAD_CATEGORY:
- accept = LLToolDragAndDrop::getInstance()->dadUpdateInventoryCategory(object,drop);
- break;
- case DAD_TEXTURE:
- case DAD_SOUND:
- case DAD_LANDMARK:
- case DAD_OBJECT:
- case DAD_NOTECARD:
- case DAD_CLOTHING:
- case DAD_BODYPART:
- case DAD_ANIMATION:
- case DAD_GESTURE:
- case DAD_CALLINGCARD:
- case DAD_MESH:
- case DAD_SETTINGS:
- case DAD_MATERIAL:
- accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
- if(accept && drop)
- {
- LLToolDragAndDrop::dropInventory(object,
- (LLViewerInventoryItem*)cargo_data,
- LLToolDragAndDrop::getInstance()->getSource(),
- LLToolDragAndDrop::getInstance()->getSourceID());
- }
- break;
- case DAD_SCRIPT:
- // *HACK: In order to resolve SL-22177, we need to block
- // drags from notecards and objects onto other
- // objects. uncomment the simpler version when we have
- // that right.
- //accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
- if(LLToolDragAndDrop::isInventoryDropAcceptable(
- object, (LLViewerInventoryItem*)cargo_data)
- && (LLToolDragAndDrop::SOURCE_WORLD != LLToolDragAndDrop::getInstance()->getSource())
- && (LLToolDragAndDrop::SOURCE_NOTECARD != LLToolDragAndDrop::getInstance()->getSource()))
- {
- accept = true;
- }
- if(accept && drop)
- {
- LLViewerInventoryItem* item = (LLViewerInventoryItem*)cargo_data;
- // rez in the script active by default, rez in
- // inactive if the control key is being held down.
- bool active = ((mask & MASK_CONTROL) == 0);
- LLToolDragAndDrop::dropScript(object, item, active,
- LLToolDragAndDrop::getInstance()->getSource(),
- LLToolDragAndDrop::getInstance()->getSourceID());
- }
- break;
- default:
- break;
- }
- }
- return accept;
-}
-
-///----------------------------------------------------------------------------
-/// Class LLTaskTextureBridge
-///----------------------------------------------------------------------------
-
-class LLTaskTextureBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskTextureBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name) {}
-
- virtual bool canOpenItem() const { return true; }
- virtual void openItem();
-};
-
-void LLTaskTextureBridge::openItem()
-{
- LL_INFOS() << "LLTaskTextureBridge::openItem()" << LL_ENDL;
- LLPreviewTexture* preview = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES);
- if(preview)
- {
- LLInventoryItem* item = findItem();
- if(item)
- {
- preview->setAuxItem(item);
- }
- preview->setObjectID(mPanel->getTaskUUID());
- }
-}
-
-
-///----------------------------------------------------------------------------
-/// Class LLTaskSoundBridge
-///----------------------------------------------------------------------------
-
-class LLTaskSoundBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskSoundBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name) {}
-
- virtual bool canOpenItem() const { return true; }
- virtual void openItem();
- virtual void performAction(LLInventoryModel* model, std::string action);
- virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
- static void openSoundPreview(void* data);
-};
-
-void LLTaskSoundBridge::openItem()
-{
- openSoundPreview((void*)this);
-}
-
-void LLTaskSoundBridge::openSoundPreview(void* data)
-{
- LLTaskSoundBridge* self = (LLTaskSoundBridge*)data;
- if(!self)
- return;
-
- LLPreviewSound* preview = LLFloaterReg::showTypedInstance<LLPreviewSound>("preview_sound", LLSD(self->mUUID), TAKE_FOCUS_YES);
- if (preview)
- {
- preview->setObjectID(self->mPanel->getTaskUUID());
- }
-}
-
-// virtual
-void LLTaskSoundBridge::performAction(LLInventoryModel* model, std::string action)
-{
- if (action == "task_play")
- {
- LLInventoryItem* item = findItem();
- if(item)
- {
- send_sound_trigger(item->getAssetUUID(), 1.0);
- }
- }
- LLTaskInvFVBridge::performAction(model, action);
-}
-
-void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
- LLInventoryItem* item = findItem();
- std::vector<std::string> items;
- std::vector<std::string> disabled_items;
- if (!item)
- {
- hide_context_entries(menu, items, disabled_items);
- return;
- }
-
- if (canOpenItem())
- {
- if (!isItemCopyable())
- {
- disabled_items.push_back(std::string("Task Open"));
- }
- }
- items.push_back(std::string("Task Properties"));
- if ((flags & FIRST_SELECTED_ITEM) == 0)
- {
- disabled_items.push_back(std::string("Task Properties"));
- }
- if(isItemRenameable())
- {
- items.push_back(std::string("Task Rename"));
- }
- if(isItemRemovable())
- {
- items.push_back(std::string("Task Remove"));
- }
-
- items.push_back(std::string("Task Play"));
-
-
- hide_context_entries(menu, items, disabled_items);
-}
-
-///----------------------------------------------------------------------------
-/// Class LLTaskLandmarkBridge
-///----------------------------------------------------------------------------
-
-class LLTaskLandmarkBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskLandmarkBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name) {}
-};
-
-///----------------------------------------------------------------------------
-/// Class LLTaskCallingCardBridge
-///----------------------------------------------------------------------------
-
-class LLTaskCallingCardBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskCallingCardBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name) {}
-
- virtual bool isItemRenameable() const;
- virtual bool renameItem(const std::string& new_name);
-};
-
-bool LLTaskCallingCardBridge::isItemRenameable() const
-{
- return false;
-}
-
-bool LLTaskCallingCardBridge::renameItem(const std::string& new_name)
-{
- return false;
-}
-
-
-///----------------------------------------------------------------------------
-/// Class LLTaskScriptBridge
-///----------------------------------------------------------------------------
-
-class LLTaskScriptBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskScriptBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name) {}
-
- //static bool enableIfCopyable( void* userdata );
-};
-
-class LLTaskLSLBridge : public LLTaskScriptBridge
-{
-public:
- LLTaskLSLBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskScriptBridge(panel, uuid, name) {}
-
- virtual bool canOpenItem() const { return true; }
- virtual void openItem();
- virtual bool removeItem();
- //virtual void buildContextMenu(LLMenuGL& menu);
-
- //static void copyToInventory(void* userdata);
-};
-
-void LLTaskLSLBridge::openItem()
-{
- LL_INFOS() << "LLTaskLSLBridge::openItem() " << mUUID << LL_ENDL;
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(!object || object->isInventoryPending())
- {
- return;
- }
- if (object->permModify() || gAgent.isGodlike())
- {
- LLSD floater_key;
- floater_key["taskid"] = mPanel->getTaskUUID();
- floater_key["itemid"] = mUUID;
-
- LLLiveLSLEditor* preview = LLFloaterReg::showTypedInstance<LLLiveLSLEditor>("preview_scriptedit", floater_key, TAKE_FOCUS_YES);
- if (preview)
- {
- LLSelectNode *node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, true);
- if (node && node->mValid)
- {
- preview->setObjectName(node->mName);
- }
- preview->setObjectID(mPanel->getTaskUUID());
- }
- }
- else
- {
- LLNotificationsUtil::add("CannotOpenScriptObjectNoMod");
- }
-}
-
-bool LLTaskLSLBridge::removeItem()
-{
- LLFloaterReg::hideInstance("preview_scriptedit", LLSD(mUUID));
- return LLTaskInvFVBridge::removeItem();
-}
-
-///----------------------------------------------------------------------------
-/// Class LLTaskObjectBridge
-///----------------------------------------------------------------------------
-
-class LLTaskObjectBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskObjectBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name,
- U32 flags = 0) :
- LLTaskInvFVBridge(panel, uuid, name, flags) {}
-};
-
-///----------------------------------------------------------------------------
-/// Class LLTaskNotecardBridge
-///----------------------------------------------------------------------------
-
-class LLTaskNotecardBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskNotecardBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name) {}
-
- virtual bool canOpenItem() const { return true; }
- virtual void openItem();
- virtual bool removeItem();
-};
-
-void LLTaskNotecardBridge::openItem()
-{
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(!object || object->isInventoryPending())
- {
- return;
- }
-
- // Note: even if we are not allowed to modify copyable notecard, we should be able to view it
- LLInventoryItem *item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID));
- bool item_copy = item && gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE);
- if( item_copy
- || object->permModify()
- || gAgent.isGodlike())
- {
- LLSD floater_key;
- floater_key["taskid"] = mPanel->getTaskUUID();
- floater_key["itemid"] = mUUID;
- LLPreviewNotecard* preview = LLFloaterReg::showTypedInstance<LLPreviewNotecard>("preview_notecard", floater_key, TAKE_FOCUS_YES);
- if (preview)
- {
- preview->setObjectID(mPanel->getTaskUUID());
- }
- }
-}
-
-bool LLTaskNotecardBridge::removeItem()
-{
- LLFloaterReg::hideInstance("preview_notecard", LLSD(mUUID));
- return LLTaskInvFVBridge::removeItem();
-}
-
-///----------------------------------------------------------------------------
-/// Class LLTaskGestureBridge
-///----------------------------------------------------------------------------
-
-class LLTaskGestureBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskGestureBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name) {}
-
- virtual bool canOpenItem() const { return true; }
- virtual void openItem();
- virtual bool removeItem();
-};
-
-void LLTaskGestureBridge::openItem()
-{
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(!object || object->isInventoryPending())
- {
- return;
- }
- LLPreviewGesture::show(mUUID, mPanel->getTaskUUID());
-}
-
-bool LLTaskGestureBridge::removeItem()
-{
- // Don't need to deactivate gesture because gestures inside objects can never be active.
- LLFloaterReg::hideInstance("preview_gesture", LLSD(mUUID));
- return LLTaskInvFVBridge::removeItem();
-}
-
-///----------------------------------------------------------------------------
-/// Class LLTaskAnimationBridge
-///----------------------------------------------------------------------------
-
-class LLTaskAnimationBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskAnimationBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name) {}
-
- virtual bool canOpenItem() const { return true; }
- virtual void openItem();
- virtual bool removeItem();
-};
-
-void LLTaskAnimationBridge::openItem()
-{
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(!object || object->isInventoryPending())
- {
- return;
- }
-
- LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES);
- if (preview && (object->permModify() || gAgent.isGodlike()))
- {
- preview->setObjectID(mPanel->getTaskUUID());
- }
-}
-
-bool LLTaskAnimationBridge::removeItem()
-{
- LLFloaterReg::hideInstance("preview_anim", LLSD(mUUID));
- return LLTaskInvFVBridge::removeItem();
-}
-
-///----------------------------------------------------------------------------
-/// Class LLTaskWearableBridge
-///----------------------------------------------------------------------------
-
-class LLTaskWearableBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskWearableBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name,
- U32 flags) :
- LLTaskInvFVBridge(panel, uuid, name, flags) {}
-
- virtual LLUIImagePtr getIcon() const;
-};
-
-LLUIImagePtr LLTaskWearableBridge::getIcon() const
-{
- return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, false );
-}
-
-///----------------------------------------------------------------------------
-/// Class LLTaskSettingsBridge
-///----------------------------------------------------------------------------
-
-class LLTaskSettingsBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskSettingsBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name,
- U32 flags) :
- LLTaskInvFVBridge(panel, uuid, name, flags) {}
-
- virtual LLUIImagePtr getIcon() const;
- virtual LLSettingsType::type_e getSettingsType() const;
-};
-
-LLUIImagePtr LLTaskSettingsBridge::getIcon() const
-{
- return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, false);
-}
-
-LLSettingsType::type_e LLTaskSettingsBridge::getSettingsType() const
-{
- return LLSettingsType::ST_NONE;
-}
-
-///----------------------------------------------------------------------------
-/// Class LLTaskMaterialBridge
-///----------------------------------------------------------------------------
-
-class LLTaskMaterialBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskMaterialBridge(LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name) {}
-
- bool canOpenItem() const override { return true; }
- void openItem() override;
- bool removeItem() override;
-};
-
-void LLTaskMaterialBridge::openItem()
-{
- LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
- if(!object || object->isInventoryPending())
- {
- return;
- }
-
- // Note: even if we are not allowed to modify copyable notecard, we should be able to view it
- LLInventoryItem *item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID));
- bool item_copy = item && gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE);
- if( item_copy
- || object->permModify()
- || gAgent.isGodlike())
- {
- LLSD floater_key;
- floater_key["taskid"] = mPanel->getTaskUUID();
- floater_key["itemid"] = mUUID;
- LLMaterialEditor* mat = LLFloaterReg::getTypedInstance<LLMaterialEditor>("material_editor", floater_key);
- if (mat)
- {
- mat->setObjectID(mPanel->getTaskUUID());
- mat->openFloater(floater_key);
- mat->setFocus(true);
- }
- }
-}
-
-bool LLTaskMaterialBridge::removeItem()
-{
- LLFloaterReg::hideInstance("material_editor", LLSD(mUUID));
- return LLTaskInvFVBridge::removeItem();
-}
-
-
-///----------------------------------------------------------------------------
-/// LLTaskInvFVBridge impl
-//----------------------------------------------------------------------------
-
-LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory* panel,
- LLInventoryObject* object)
-{
- LLTaskInvFVBridge* new_bridge = NULL;
- const LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(object);
- const U32 itemflags = ( NULL == item ? 0 : item->getFlags() );
- LLAssetType::EType type = object ? object->getType() : LLAssetType::AT_CATEGORY;
- LLUUID object_id = object ? object->getUUID() : LLUUID::null;
- std::string object_name = object ? object->getName() : std::string();
-
- switch(type)
- {
- case LLAssetType::AT_TEXTURE:
- new_bridge = new LLTaskTextureBridge(panel,
- object_id,
- object_name);
- break;
- case LLAssetType::AT_SOUND:
- new_bridge = new LLTaskSoundBridge(panel,
- object_id,
- object_name);
- break;
- case LLAssetType::AT_LANDMARK:
- new_bridge = new LLTaskLandmarkBridge(panel,
- object_id,
- object_name);
- break;
- case LLAssetType::AT_CALLINGCARD:
- new_bridge = new LLTaskCallingCardBridge(panel,
- object_id,
- object_name);
- break;
- case LLAssetType::AT_SCRIPT:
- // OLD SCRIPTS DEPRECATED - JC
- LL_WARNS() << "Old script" << LL_ENDL;
- //new_bridge = new LLTaskOldScriptBridge(panel,
- // object_id,
- // object_name);
- break;
- case LLAssetType::AT_OBJECT:
- new_bridge = new LLTaskObjectBridge(panel,
- object_id,
- object_name,
- itemflags);
- break;
- case LLAssetType::AT_NOTECARD:
- new_bridge = new LLTaskNotecardBridge(panel,
- object_id,
- object_name);
- break;
- case LLAssetType::AT_ANIMATION:
- new_bridge = new LLTaskAnimationBridge(panel,
- object_id,
- object_name);
- break;
- case LLAssetType::AT_GESTURE:
- new_bridge = new LLTaskGestureBridge(panel,
- object_id,
- object_name);
- break;
- case LLAssetType::AT_CLOTHING:
- case LLAssetType::AT_BODYPART:
- new_bridge = new LLTaskWearableBridge(panel,
- object_id,
- object_name,
- itemflags);
- break;
- case LLAssetType::AT_CATEGORY:
- new_bridge = new LLTaskCategoryBridge(panel,
- object_id,
- object_name);
- break;
- case LLAssetType::AT_LSL_TEXT:
- new_bridge = new LLTaskLSLBridge(panel,
- object_id,
- object_name);
- break;
- case LLAssetType::AT_SETTINGS:
- new_bridge = new LLTaskSettingsBridge(panel,
- object_id,
- object_name,
- itemflags);
- break;
- case LLAssetType::AT_MATERIAL:
- new_bridge = new LLTaskMaterialBridge(panel,
- object_id,
- object_name);
- break;
- default:
- LL_INFOS() << "Unhandled inventory type (llassetstorage.h): "
- << (S32)type << LL_ENDL;
- break;
- }
- return new_bridge;
-}
-
-
-///----------------------------------------------------------------------------
-/// Class LLPanelObjectInventory
-///----------------------------------------------------------------------------
-
-static LLDefaultChildRegistry::Register<LLPanelObjectInventory> r("panel_inventory_object");
-
-void do_nothing()
-{
-}
-
-// Default constructor
-LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Params& p) :
- LLPanel(p),
- mScroller(NULL),
- mFolders(NULL),
- mHaveInventory(false),
- mIsInventoryEmpty(true),
- mInventoryNeedsUpdate(false),
- mInventoryViewModel(p.name),
- mShowRootFolder(p.show_root_folder)
-{
- // Setup context menu callbacks
- mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2));
- mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
- mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
- mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing));
- mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing));
- mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing));
- mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this));
- mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&do_nothing));
-}
-
-// Destroys the object
-LLPanelObjectInventory::~LLPanelObjectInventory()
-{
- if (!gIdleCallbacks.deleteFunction(idle, this))
- {
- LL_WARNS() << "LLPanelObjectInventory::~LLPanelObjectInventory() failed to delete callback" << LL_ENDL;
- }
-}
-
-bool LLPanelObjectInventory::postBuild()
-{
- // clear contents and initialize menus, sets up mFolders
- reset();
-
- // Register an idle update callback
- gIdleCallbacks.addFunction(idle, this);
-
- return true;
-}
-
-void LLPanelObjectInventory::doToSelected(const LLSD& userdata)
-{
- LLInventoryAction::doToSelected(&gInventory, mFolders, userdata.asString());
-}
-
-void LLPanelObjectInventory::clearContents()
-{
- mHaveInventory = false;
- mIsInventoryEmpty = true;
- if (LLToolDragAndDrop::getInstance() && LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_WORLD)
- {
- LLToolDragAndDrop::getInstance()->endDrag();
- }
-
- clearItemIDs();
-
- if( mScroller )
- {
- // removes mFolders
- removeChild( mScroller ); //*TODO: Really shouldn't do this during draw()/refresh()
- mScroller->die();
- mScroller = NULL;
- mFolders = NULL;
- }
-}
-
-
-void LLPanelObjectInventory::reset()
-{
- clearContents();
-
- mCommitCallbackRegistrar.pushScope(); // push local callbacks
-
- // Reset the inventory model to show all folders by default
- mInventoryViewModel.getFilter().setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
-
- // Create a new folder view root
- LLRect dummy_rect(0, 1, 1, 0);
- LLFolderView::Params p;
- p.name = "task inventory";
- p.title = "task inventory";
- p.parent_panel = this;
- p.tool_tip= LLTrans::getString("PanelContentsTooltip");
- p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
- p.folder_indentation = -14; // subtract space normally reserved for folder expanders
- p.view_model = &mInventoryViewModel;
- p.root = NULL;
- p.options_menu = "menu_inventory.xml";
-
- mFolders = LLUICtrlFactory::create<LLFolderView>(p);
-
- mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
- mFolders->setEnableRegistrar(&mEnableCallbackRegistrar);
-
- if (hasFocus())
- {
- LLEditMenuHandler::gEditMenuHandler = mFolders;
- }
-
- int offset = hasBorder() ? getBorder()->getBorderWidth() << 1 : 0;
- LLRect scroller_rect(0, getRect().getHeight() - offset, getRect().getWidth() - offset, 0);
- LLScrollContainer::Params scroll_p;
- scroll_p.name("task inventory scroller");
- scroll_p.rect(scroller_rect);
- scroll_p.tab_stop(true);
- scroll_p.follows.flags(FOLLOWS_ALL);
- mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroll_p);
- addChild(mScroller);
- mScroller->addChild(mFolders);
-
- mFolders->setScrollContainer( mScroller );
-
- mCommitCallbackRegistrar.popScope();
-}
-
-void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object,
- LLInventoryObject::object_list_t* inventory,
- S32 serial_num,
- void* data)
-{
- if(!object) return;
-
- //LL_INFOS() << "invetnory arrived: \n"
- // << " panel UUID: " << panel->mTaskUUID << "\n"
- // << " task UUID: " << object->mID << LL_ENDL;
- if(mTaskUUID == object->mID)
- {
- mInventoryNeedsUpdate = true;
- }
-}
-
-void LLPanelObjectInventory::updateInventory()
-{
- //LL_INFOS() << "inventory arrived: \n"
- // << " panel UUID: " << panel->mTaskUUID << "\n"
- // << " task UUID: " << object->mID << LL_ENDL;
- // We're still interested in this task's inventory.
- std::vector<LLUUID> selected_item_ids;
- std::set<LLFolderViewItem*> selected_items;
- bool inventory_has_focus = false;
- if (mHaveInventory && mFolders)
- {
- selected_items = mFolders->getSelectionList();
- inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
- }
- for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end();
- it != end_it;
- ++it)
- {
- selected_item_ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
- }
-
- LLViewerObject* objectp = gObjectList.findObject(mTaskUUID);
- if (objectp)
- {
- LLInventoryObject* inventory_root = objectp->getInventoryRoot();
- LLInventoryObject::object_list_t contents;
- objectp->getInventoryContents(contents);
-
- if (inventory_root)
- {
- reset();
- mIsInventoryEmpty = false;
- createFolderViews(inventory_root, contents);
- mFolders->setEnabled(true);
- }
- else
- {
- // TODO: create an empty inventory
- mIsInventoryEmpty = true;
- }
-
- mHaveInventory = !mIsInventoryEmpty || !objectp->isInventoryDirty();
- if (objectp->isInventoryDirty())
- {
- // Inventory is dirty, yet we received inventoryChanged() callback.
- // User changed something during ongoing request.
- // Rerequest. It will clear dirty flag and won't create dupplicate requests.
- objectp->requestInventory();
- }
- }
- else
- {
- // TODO: create an empty inventory
- mIsInventoryEmpty = true;
- mHaveInventory = true;
- }
-
- // restore previous selection
- std::vector<LLUUID>::iterator selection_it;
- bool first_item = true;
- for (selection_it = selected_item_ids.begin(); selection_it != selected_item_ids.end(); ++selection_it)
- {
- LLFolderViewItem* selected_item = getItemByID(*selection_it);
-
- if (selected_item)
- {
- //HACK: "set" first item then "change" each other one to get keyboard focus right
- if (first_item)
- {
- mFolders->setSelection(selected_item, true, inventory_has_focus);
- first_item = false;
- }
- else
- {
- mFolders->changeSelection(selected_item, true);
- }
- }
- }
-
- if (mFolders)
- {
- mFolders->requestArrange();
- }
- mInventoryNeedsUpdate = false;
- // Edit menu handler is set in onFocusReceived
-}
-
-// *FIX: This is currently a very expensive operation, because we have
-// to iterate through the inventory one time for each category. This
-// leads to an N^2 based on the category count. This could be greatly
-// speeded with an efficient multimap implementation, but we don't
-// have that in our current arsenal.
-void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root, LLInventoryObject::object_list_t& contents)
-{
- if (!inventory_root)
- {
- return;
- }
- // Create a visible root category.
- LLTaskInvFVBridge* bridge = NULL;
- bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
- if(bridge)
- {
- LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
-
- LLFolderViewFolder::Params p;
- p.name = inventory_root->getName();
- p.tool_tip = p.name;
- p.root = mFolders;
- p.listener = bridge;
- p.font_color = item_color;
- p.font_highlight_color = item_color;
-
- LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
-
- if (mShowRootFolder)
- {
- new_folder->addToFolder(mFolders);
- new_folder->toggleOpen();
- }
-
- if (!contents.empty())
- {
- createViewsForCategory(&contents, inventory_root, mShowRootFolder ? new_folder : mFolders);
- }
-
- if (mShowRootFolder)
- {
- // Refresh for label to add item count
- new_folder->refresh();
- }
- }
-}
-
-typedef std::pair<LLInventoryObject*, LLFolderViewFolder*> obj_folder_pair;
-
-void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_list_t* inventory,
- LLInventoryObject* parent,
- LLFolderViewFolder* folder)
-{
- LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
-
- // Find all in the first pass
- std::vector<obj_folder_pair*> child_categories;
- LLTaskInvFVBridge* bridge;
- LLFolderViewItem* view;
-
- LLInventoryObject::object_list_t::iterator it = inventory->begin();
- LLInventoryObject::object_list_t::iterator end = inventory->end();
- for( ; it != end; ++it)
- {
- LLInventoryObject* obj = *it;
-
- if(parent->getUUID() == obj->getParentUUID())
- {
- bridge = LLTaskInvFVBridge::createObjectBridge(this, obj);
- if(!bridge)
- {
- continue;
- }
- if(LLAssetType::AT_CATEGORY == obj->getType())
- {
- LLFolderViewFolder::Params p;
- p.name = obj->getName();
- p.root = mFolders;
- p.listener = bridge;
- p.tool_tip = p.name;
- p.font_color = item_color;
- p.font_highlight_color = item_color;
- view = LLUICtrlFactory::create<LLFolderViewFolder>(p);
- child_categories.push_back(new obj_folder_pair(obj,
- (LLFolderViewFolder*)view));
- }
- else
- {
- LLFolderViewItem::Params params;
- params.name(obj->getName());
- params.creation_date(bridge->getCreationDate());
- params.root(mFolders);
- params.listener(bridge);
- params.rect(LLRect());
- params.tool_tip = params.name;
- params.font_color = item_color;
- params.font_highlight_color = item_color;
- view = LLUICtrlFactory::create<LLFolderViewItem> (params);
- }
- view->addToFolder(folder);
- addItemID(obj->getUUID(), view);
- }
- }
-
- // now, for each category, do the second pass
- for(S32 i = 0; i < child_categories.size(); i++)
- {
- createViewsForCategory(inventory, child_categories[i]->first,
- child_categories[i]->second );
- delete child_categories[i];
- }
- folder->setChildrenInited(true);
-}
-
-void LLPanelObjectInventory::refresh()
-{
- //LL_INFOS() << "LLPanelObjectInventory::refresh()" << LL_ENDL;
- bool has_inventory = false;
- const bool non_root_ok = true;
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- LLSelectNode* node = selection->getFirstRootNode(NULL, non_root_ok);
- if(node && node->mValid)
- {
- LLViewerObject* object = node->getObject();
- if(object && ((selection->getRootObjectCount() == 1)
- || (selection->getObjectCount() == 1)))
- {
- // determine if we need to make a request. Start with a
- // default based on if we have inventory at all.
- bool make_request = !mHaveInventory;
-
- // If the task id is different than what we've stored,
- // then make the request.
- if(mTaskUUID != object->mID)
- {
- mTaskUUID = object->mID;
- mAttachmentUUID = object->getAttachmentItemID();
- make_request = true;
-
- // This is a new object so pre-emptively clear the contents
- // Otherwise we show the old stuff until the update comes in
- clearContents();
-
- // Register for updates from this object,
- registerVOInventoryListener(object,NULL);
- }
- else if (mAttachmentUUID != object->getAttachmentItemID())
- {
- mAttachmentUUID = object->getAttachmentItemID();
- if (mAttachmentUUID.notNull())
- {
- // Server unsubsribes viewer (deselects object) from property
- // updates after "ObjectAttach" so we need to resubscribe
- LLSelectMgr::getInstance()->sendSelect();
- }
- }
-
- // Based on the node information, we may need to dirty the
- // object inventory and get it again.
- if(node->mValid)
- {
- if(node->mInventorySerial != object->getInventorySerial() || object->isInventoryDirty())
- {
- make_request = true;
- }
- }
-
- // do the request if necessary.
- if(make_request)
- {
- requestVOInventory();
- }
- has_inventory = true;
- }
- }
- if(!has_inventory)
- {
- clearInventoryTask();
- }
- mInventoryViewModel.setTaskID(mTaskUUID);
- //LL_INFOS() << "LLPanelObjectInventory::refresh() " << mTaskUUID << LL_ENDL;
-}
-
-void LLPanelObjectInventory::clearInventoryTask()
-{
- mTaskUUID = LLUUID::null;
- mAttachmentUUID = LLUUID::null;
- removeVOInventoryListener();
- clearContents();
-}
-
-void LLPanelObjectInventory::removeSelectedItem()
-{
- if(mFolders)
- {
- mFolders->removeSelectedItems();
- }
-}
-
-void LLPanelObjectInventory::startRenamingSelectedItem()
-{
- if(mFolders)
- {
- mFolders->startRenamingSelectedItem();
- }
-}
-
-void LLPanelObjectInventory::draw()
-{
- LLPanel::draw();
-
- if(mIsInventoryEmpty)
- {
- if((LLUUID::null != mTaskUUID) && (!mHaveInventory))
- {
- LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("LoadingContents"), 0,
- (S32)(getRect().getWidth() * 0.5f),
- 10,
- LLColor4( 1, 1, 1, 1 ),
- LLFontGL::HCENTER,
- LLFontGL::BOTTOM);
- }
- else if(mHaveInventory)
- {
- LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("NoContents"), 0,
- (S32)(getRect().getWidth() * 0.5f),
- 10,
- LLColor4( 1, 1, 1, 1 ),
- LLFontGL::HCENTER,
- LLFontGL::BOTTOM);
- }
- }
-}
-
-void LLPanelObjectInventory::deleteAllChildren()
-{
- mScroller = NULL;
- mFolders = NULL;
- LLView::deleteAllChildren();
-}
-
-bool LLPanelObjectInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
-{
- if (mFolders)
- {
- LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL);
- if (!folderp)
- {
- return false;
- }
- // Try to pass on unmodified mouse coordinates
- S32 local_x = x - mFolders->getRect().mLeft;
- S32 local_y = y - mFolders->getRect().mBottom;
-
- if (mFolders->pointInView(local_x, local_y))
- {
- return mFolders->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
- }
- else
- {
- //force mouse coordinates to be inside folder rectangle
- return mFolders->handleDragAndDrop(5, 1, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
- }
- }
- else
- {
- return false;
- }
-}
-
-//static
-void LLPanelObjectInventory::idle(void* user_data)
-{
- LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data;
-
- if (self->mFolders)
- {
- self->mFolders->update();
- }
- if (self->mInventoryNeedsUpdate)
- {
- self->updateInventory();
- }
-}
-
-void LLPanelObjectInventory::onFocusLost()
-{
- // inventory no longer handles cut/copy/paste/delete
- if (LLEditMenuHandler::gEditMenuHandler == mFolders)
- {
- LLEditMenuHandler::gEditMenuHandler = NULL;
- }
-
- LLPanel::onFocusLost();
-}
-
-void LLPanelObjectInventory::onFocusReceived()
-{
- // inventory now handles cut/copy/paste/delete
- LLEditMenuHandler::gEditMenuHandler = mFolders;
-
- LLPanel::onFocusReceived();
-}
-
-
-LLFolderViewItem* LLPanelObjectInventory::getItemByID( const LLUUID& id )
-{
- std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
- map_it = mItemMap.find(id);
- if (map_it != mItemMap.end())
- {
- return map_it->second;
- }
-
- return NULL;
-}
-
-void LLPanelObjectInventory::removeItemID( const LLUUID& id )
-{
- mItemMap.erase(id);
-}
-
-void LLPanelObjectInventory::addItemID( const LLUUID& id, LLFolderViewItem* itemp )
-{
- mItemMap[id] = itemp;
-}
-
-void LLPanelObjectInventory::clearItemIDs()
-{
- mItemMap.clear();
-}
-
-bool LLPanelObjectInventory::handleKeyHere( KEY key, MASK mask )
-{
- bool handled = false;
- switch (key)
- {
- case KEY_DELETE:
-#if LL_DARWIN
- case KEY_BACKSPACE:
-#endif
- // Delete selected items if delete or backspace key hit on the inventory panel
- // Note: on Mac laptop keyboards, backspace and delete are one and the same
- if (isSelectionRemovable() && mask == MASK_NONE)
- {
- LLInventoryAction::doToSelected(&gInventory, mFolders, "delete");
- handled = true;
- }
- break;
- }
- return handled;
-}
-
-bool LLPanelObjectInventory::isSelectionRemovable()
-{
- if (!mFolders || !mFolders->getRoot())
- {
- return false;
- }
- std::set<LLFolderViewItem*> selection_set = mFolders->getRoot()->getSelectionList();
- if (selection_set.empty())
- {
- return false;
- }
- for (std::set<LLFolderViewItem*>::iterator iter = selection_set.begin();
- iter != selection_set.end();
- ++iter)
- {
- LLFolderViewItem *item = *iter;
- const LLFolderViewModelItemInventory *listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
- if (!listener || !listener->isItemRemovable() || listener->isItemInTrash())
- {
- return false;
- }
- }
- return true;
-}
+/** + * @file llsidepanelinventory.cpp + * @brief LLPanelObjectInventory class implementation + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +//***************************************************************************** +// +// Implementation of the panel inventory - used to view and control a +// task's inventory. +// +//***************************************************************************** + +#include "llviewerprecompiledheaders.h" + +#include "llpanelobjectinventory.h" + +#include "llmenugl.h" +#include "llnotificationsutil.h" +#include "roles_constants.h" + +#include "llagent.h" +#include "llavataractions.h" +#include "llcallbacklist.h" +#include "llbuycurrencyhtml.h" +#include "llfloaterreg.h" +#include "llfolderview.h" +#include "llinventorybridge.h" +#include "llinventorydefines.h" +#include "llinventoryicon.h" +#include "llinventoryfilter.h" +#include "llinventoryfunctions.h" +#include "llmaterialeditor.h" +#include "llpreviewanim.h" +#include "llpreviewgesture.h" +#include "llpreviewnotecard.h" +#include "llpreviewscript.h" +#include "llpreviewsound.h" +#include "llpreviewtexture.h" +#include "llscrollcontainer.h" +#include "llselectmgr.h" +#include "llstatusbar.h" +#include "lltooldraganddrop.h" +#include "lltrans.h" +#include "llviewerassettype.h" +#include "llviewerinventory.h" +#include "llviewerregion.h" +#include "llviewerobjectlist.h" +#include "llviewermessage.h" + +const LLColor4U DEFAULT_WHITE(255, 255, 255); + +///---------------------------------------------------------------------------- +/// Class LLTaskInvFVBridge +///---------------------------------------------------------------------------- + +class LLTaskInvFVBridge : public LLFolderViewModelItemInventory +{ +protected: + LLUUID mUUID; + std::string mName; + mutable std::string mDisplayName; + mutable std::string mSearchableName; + LLPanelObjectInventory* mPanel; + U32 mFlags; + LLAssetType::EType mAssetType; + LLInventoryType::EType mInventoryType; + + LLInventoryObject* findInvObject() const; + LLInventoryItem* findItem() const; + +public: + LLTaskInvFVBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name, + U32 flags=0); + virtual ~LLTaskInvFVBridge() {} + + virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; } + virtual std::string getLabelSuffix() const { return LLStringUtil::null; } + + static LLTaskInvFVBridge* createObjectBridge(LLPanelObjectInventory* panel, + LLInventoryObject* object); + void showProperties(); + S32 getPrice(); + + // LLFolderViewModelItemInventory functionality + virtual const std::string& getName() const; + virtual const std::string& getDisplayName() const; + virtual const std::string& getSearchableName() const; + + virtual std::string getSearchableDescription() const {return LLStringUtil::null;} + virtual std::string getSearchableCreatorName() const {return LLStringUtil::null;} + virtual std::string getSearchableUUIDString() const {return LLStringUtil::null;} + + + virtual PermissionMask getPermissionMask() const { return PERM_NONE; } + /*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; } + virtual const LLUUID& getUUID() const { return mUUID; } + virtual const LLUUID& getThumbnailUUID() const { return LLUUID::null;} + virtual time_t getCreationDate() const; + virtual void setCreationDate(time_t creation_date_utc); + + virtual LLUIImagePtr getIcon() const; + virtual void openItem(); + virtual bool canOpenItem() const { return false; } + virtual void closeItem() {} + virtual void selectItem() {} + virtual void navigateToFolder(bool new_window = false, bool change_mode = false) {} + virtual bool isItemRenameable() const; + virtual bool renameItem(const std::string& new_name); + virtual bool isItemMovable() const; + virtual bool isItemRemovable(bool check_worn = true) const; + virtual bool removeItem(); + virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch); + virtual void move(LLFolderViewModelItem* parent_listener); + virtual bool isItemCopyable(bool can_copy_as_link = true) const; + virtual bool copyToClipboard() const; + virtual bool cutToClipboard(); + virtual bool isClipboardPasteable() const; + virtual void pasteFromClipboard(); + virtual void pasteLinkFromClipboard(); + virtual void buildContextMenu(LLMenuGL& menu, U32 flags); + virtual void performAction(LLInventoryModel* model, std::string action); + virtual bool isUpToDate() const { return true; } + virtual bool hasChildren() const { return false; } + virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; } + virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; } + virtual LLSettingsType::type_e getSettingsType() const { return LLSettingsType::ST_NONE; } + virtual EInventorySortGroup getSortGroup() const { return SG_ITEM; } + virtual LLInventoryObject* getInventoryObject() const { return findInvObject(); } + + + // LLDragAndDropBridge functionality + virtual LLToolDragAndDrop::ESource getDragSource() const { return LLToolDragAndDrop::SOURCE_WORLD; } + virtual bool startDrag(EDragAndDropType* type, LLUUID* id) const; + virtual bool dragOrDrop(MASK mask, bool drop, + EDragAndDropType cargo_type, + void* cargo_data, + std::string& tooltip_msg); +}; + +LLTaskInvFVBridge::LLTaskInvFVBridge( + LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name, + U32 flags) +: LLFolderViewModelItemInventory(panel->getRootViewModel()), + mUUID(uuid), + mName(name), + mPanel(panel), + mFlags(flags), + mAssetType(LLAssetType::AT_NONE), + mInventoryType(LLInventoryType::IT_NONE) +{ + const LLInventoryItem *item = findItem(); + if (item) + { + mAssetType = item->getType(); + mInventoryType = item->getInventoryType(); + } +} + +LLInventoryObject* LLTaskInvFVBridge::findInvObject() const +{ + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if (object) + { + return object->getInventoryObject(mUUID); + } + return NULL; +} + + +LLInventoryItem* LLTaskInvFVBridge::findItem() const +{ + return dynamic_cast<LLInventoryItem*>(findInvObject()); +} + +void LLTaskInvFVBridge::showProperties() +{ + show_task_item_profile(mUUID, mPanel->getTaskUUID()); +} + +S32 LLTaskInvFVBridge::getPrice() +{ + LLInventoryItem* item = findItem(); + if(item) + { + return item->getSaleInfo().getSalePrice(); + } + else + { + return -1; + } +} + +const std::string& LLTaskInvFVBridge::getName() const +{ + return mName; +} + +const std::string& LLTaskInvFVBridge::getDisplayName() const +{ + LLInventoryItem* item = findItem(); + + if(item) + { + mDisplayName.assign(item->getName()); + + // Localize "New Script", "New Script 1", "New Script 2", etc. + if (item->getType() == LLAssetType::AT_LSL_TEXT && + LLStringUtil::startsWith(item->getName(), "New Script")) + { + LLStringUtil::replaceString(mDisplayName, "New Script", LLTrans::getString("PanelContentsNewScript")); + } + + const LLPermissions& perm(item->getPermissions()); + bool copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE); + bool mod = gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE); + bool xfer = gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE); + + if(!copy) + { + mDisplayName.append(LLTrans::getString("no_copy")); + } + if(!mod) + { + mDisplayName.append(LLTrans::getString("no_modify")); + } + if(!xfer) + { + mDisplayName.append(LLTrans::getString("no_transfer")); + } + } + + mSearchableName.assign(mDisplayName + getLabelSuffix()); + + return mDisplayName; +} + +const std::string& LLTaskInvFVBridge::getSearchableName() const +{ + return mSearchableName; +} + + +// BUG: No creation dates for task inventory +time_t LLTaskInvFVBridge::getCreationDate() const +{ + return 0; +} + +void LLTaskInvFVBridge::setCreationDate(time_t creation_date_utc) +{} + + +LLUIImagePtr LLTaskInvFVBridge::getIcon() const +{ + const bool item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS); + + return LLInventoryIcon::getIcon(mAssetType, mInventoryType, 0, item_is_multi ); +} + +void LLTaskInvFVBridge::openItem() +{ + // no-op. + LL_DEBUGS() << "LLTaskInvFVBridge::openItem()" << LL_ENDL; +} + +bool LLTaskInvFVBridge::isItemRenameable() const +{ + if(gAgent.isGodlike()) return true; + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(object) + { + LLInventoryItem* item = (LLInventoryItem*)(object->getInventoryObject(mUUID)); + if(item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), + GP_OBJECT_MANIPULATE, GOD_LIKE)) + { + return true; + } + } + return false; +} + +bool LLTaskInvFVBridge::renameItem(const std::string& new_name) +{ + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(object) + { + LLViewerInventoryItem* item = NULL; + item = (LLViewerInventoryItem*)object->getInventoryObject(mUUID); + if(item && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), + GP_OBJECT_MANIPULATE, GOD_LIKE))) + { + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); + new_item->rename(new_name); + object->updateInventory( + new_item, + TASK_INVENTORY_ITEM_KEY, + false); + } + } + return true; +} + +bool LLTaskInvFVBridge::isItemMovable() const +{ + //LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + //if(object && (object->permModify() || gAgent.isGodlike())) + //{ + // return true; + //} + //return false; + return true; +} + +bool LLTaskInvFVBridge::isItemRemovable(bool check_worn) const +{ + const LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(object + && (object->permModify() || object->permYouOwner())) + { + return true; + } + return false; +} + +bool remove_task_inventory_callback(const LLSD& notification, const LLSD& response, LLPanelObjectInventory* panel) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID()); + if(option == 0 && object) + { + // yes + LLSD::array_const_iterator list_end = notification["payload"]["inventory_ids"].endArray(); + for (LLSD::array_const_iterator list_it = notification["payload"]["inventory_ids"].beginArray(); + list_it != list_end; + ++list_it) + { + object->removeInventory(list_it->asUUID()); + } + + // refresh the UI. + panel->refresh(); + } + return false; +} + +// helper for remove +// ! REFACTOR ! two_uuids_list_t is also defined in llinventorybridge.h, but differently. +typedef std::pair<LLUUID, std::list<LLUUID> > panel_two_uuids_list_t; +typedef std::pair<LLPanelObjectInventory*, panel_two_uuids_list_t> remove_data_t; +bool LLTaskInvFVBridge::removeItem() +{ + if(isItemRemovable() && mPanel) + { + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(object) + { + if(object->permModify()) + { + // just do it. + object->removeInventory(mUUID); + return true; + } + else + { + LLSD payload; + payload["task_id"] = mPanel->getTaskUUID(); + payload["inventory_ids"].append(mUUID); + LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel)); + return false; + } + } + } + return false; +} + +void LLTaskInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch) +{ + if (!mPanel) + { + return; + } + + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if (!object) + { + return; + } + + if (!object->permModify()) + { + LLSD payload; + payload["task_id"] = mPanel->getTaskUUID(); + for (S32 i = 0; i < (S32)batch.size(); i++) + { + LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i]; + payload["inventory_ids"].append(itemp->getUUID()); + } + LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel)); + + } + else + { + for (S32 i = 0; i < (S32)batch.size(); i++) + { + LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i]; + + if(itemp->isItemRemovable()) + { + // just do it. + object->removeInventory(itemp->getUUID()); + } + } + } +} + +void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener) +{ +} + +bool LLTaskInvFVBridge::isItemCopyable(bool can_link) const +{ + LLInventoryItem* item = findItem(); + if(!item) return false; + return gAgent.allowOperation(PERM_COPY, item->getPermissions(), + GP_OBJECT_MANIPULATE); +} + +bool LLTaskInvFVBridge::copyToClipboard() const +{ + return false; +} + +bool LLTaskInvFVBridge::cutToClipboard() +{ + return false; +} + +bool LLTaskInvFVBridge::isClipboardPasteable() const +{ + return false; +} + +void LLTaskInvFVBridge::pasteFromClipboard() +{ +} + +void LLTaskInvFVBridge::pasteLinkFromClipboard() +{ +} + +bool LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const +{ + //LL_INFOS() << "LLTaskInvFVBridge::startDrag()" << LL_ENDL; + if(mPanel) + { + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(object) + { + LLInventoryItem* inv = NULL; + if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID))) + { + const LLPermissions& perm = inv->getPermissions(); + bool can_copy = gAgent.allowOperation(PERM_COPY, perm, + GP_OBJECT_MANIPULATE); + if (object->isAttachment() && !can_copy) + { + //RN: no copy contents of attachments cannot be dragged out + // due to a race condition and possible exploit where + // attached objects do not update their inventory items + // when their contents are manipulated + return false; + } + if((can_copy && perm.allowTransferTo(gAgent.getID())) + || object->permYouOwner()) +// || gAgent.isGodlike()) + + { + *type = LLViewerAssetType::lookupDragAndDropType(inv->getType()); + + *id = inv->getUUID(); + return true; + } + } + } + } + return false; +} + +bool LLTaskInvFVBridge::dragOrDrop(MASK mask, bool drop, + EDragAndDropType cargo_type, + void* cargo_data, + std::string& tooltip_msg) +{ + //LL_INFOS() << "LLTaskInvFVBridge::dragOrDrop()" << LL_ENDL; + return false; +} + +// virtual +void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string action) +{ + if (action == "task_open") + { + openItem(); + } + else if (action == "task_properties") + { + showProperties(); + } +} + +void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + LLInventoryItem* item = findItem(); + std::vector<std::string> items; + std::vector<std::string> disabled_items; + + if (!item) + { + hide_context_entries(menu, items, disabled_items); + return; + } + + if (canOpenItem()) + { + items.push_back(std::string("Task Open")); + } + items.push_back(std::string("Task Properties")); + if ((flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Task Properties")); + } + if(isItemRenameable()) + { + items.push_back(std::string("Task Rename")); + if ((flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Task Rename")); + } + } + if(isItemRemovable()) + { + items.push_back(std::string("Task Remove")); + } + + hide_context_entries(menu, items, disabled_items); +} + + +///---------------------------------------------------------------------------- +/// Class LLTaskFolderBridge +///---------------------------------------------------------------------------- + +class LLTaskCategoryBridge : public LLTaskInvFVBridge +{ +public: + LLTaskCategoryBridge( + LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name); + + virtual LLUIImagePtr getIcon() const; + virtual const std::string& getDisplayName() const; + virtual bool isItemRenameable() const; + // virtual bool isItemCopyable() const { return false; } + virtual bool renameItem(const std::string& new_name); + virtual bool isItemRemovable(bool check_worn = true) const; + virtual void buildContextMenu(LLMenuGL& menu, U32 flags); + virtual bool hasChildren() const; + virtual bool startDrag(EDragAndDropType* type, LLUUID* id) const; + virtual bool dragOrDrop(MASK mask, bool drop, + EDragAndDropType cargo_type, + void* cargo_data, + std::string& tooltip_msg); + virtual bool canOpenItem() const { return true; } + virtual void openItem(); + virtual EInventorySortGroup getSortGroup() const { return SG_NORMAL_FOLDER; } +}; + +LLTaskCategoryBridge::LLTaskCategoryBridge( + LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskCategoryBridge::getIcon() const +{ + return LLUI::getUIImage("Inv_FolderClosed"); +} + +// virtual +const std::string& LLTaskCategoryBridge::getDisplayName() const +{ + LLInventoryObject* cat = findInvObject(); + + if (cat) + { + std::string name = cat->getName(); + if (mChildren.size() > 0) + { + // Add item count + // Normally we would be using getLabelSuffix for this + // but object's inventory just uses displaynames + LLStringUtil::format_map_t args; + args["[ITEMS_COUNT]"] = llformat("%d", mChildren.size()); + + name.append(" " + LLTrans::getString("InventoryItemsCount", args)); + } + mDisplayName.assign(name); + } + + return mDisplayName; +} + +bool LLTaskCategoryBridge::isItemRenameable() const +{ + return false; +} + +bool LLTaskCategoryBridge::renameItem(const std::string& new_name) +{ + return false; +} + +bool LLTaskCategoryBridge::isItemRemovable(bool check_worn) const +{ + return false; +} + +void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + std::vector<std::string> items; + std::vector<std::string> disabled_items; + hide_context_entries(menu, items, disabled_items); +} + +bool LLTaskCategoryBridge::hasChildren() const +{ + // return true if we have or do know know if we have children. + // *FIX: For now, return false - we will know for sure soon enough. + return false; +} + +void LLTaskCategoryBridge::openItem() +{ +} + +bool LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const +{ + //LL_INFOS() << "LLTaskInvFVBridge::startDrag()" << LL_ENDL; + if(mPanel && mUUID.notNull()) + { + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(object) + { + const LLInventoryObject* cat = object->getInventoryObject(mUUID); + if ( (cat) && (move_inv_category_world_to_agent(mUUID, LLUUID::null, false)) ) + { + *type = LLViewerAssetType::lookupDragAndDropType(cat->getType()); + *id = mUUID; + return true; + } + } + } + return false; +} + +bool LLTaskCategoryBridge::dragOrDrop(MASK mask, bool drop, + EDragAndDropType cargo_type, + void* cargo_data, + std::string& tooltip_msg) +{ + //LL_INFOS() << "LLTaskCategoryBridge::dragOrDrop()" << LL_ENDL; + bool accept = false; + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(object) + { + switch(cargo_type) + { + case DAD_CATEGORY: + accept = LLToolDragAndDrop::getInstance()->dadUpdateInventoryCategory(object,drop); + break; + case DAD_TEXTURE: + case DAD_SOUND: + case DAD_LANDMARK: + case DAD_OBJECT: + case DAD_NOTECARD: + case DAD_CLOTHING: + case DAD_BODYPART: + case DAD_ANIMATION: + case DAD_GESTURE: + case DAD_CALLINGCARD: + case DAD_MESH: + case DAD_SETTINGS: + case DAD_MATERIAL: + accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data); + if(accept && drop) + { + LLToolDragAndDrop::dropInventory(object, + (LLViewerInventoryItem*)cargo_data, + LLToolDragAndDrop::getInstance()->getSource(), + LLToolDragAndDrop::getInstance()->getSourceID()); + } + break; + case DAD_SCRIPT: + // *HACK: In order to resolve SL-22177, we need to block + // drags from notecards and objects onto other + // objects. uncomment the simpler version when we have + // that right. + //accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data); + if(LLToolDragAndDrop::isInventoryDropAcceptable( + object, (LLViewerInventoryItem*)cargo_data) + && (LLToolDragAndDrop::SOURCE_WORLD != LLToolDragAndDrop::getInstance()->getSource()) + && (LLToolDragAndDrop::SOURCE_NOTECARD != LLToolDragAndDrop::getInstance()->getSource())) + { + accept = true; + } + if(accept && drop) + { + LLViewerInventoryItem* item = (LLViewerInventoryItem*)cargo_data; + // rez in the script active by default, rez in + // inactive if the control key is being held down. + bool active = ((mask & MASK_CONTROL) == 0); + LLToolDragAndDrop::dropScript(object, item, active, + LLToolDragAndDrop::getInstance()->getSource(), + LLToolDragAndDrop::getInstance()->getSourceID()); + } + break; + default: + break; + } + } + return accept; +} + +///---------------------------------------------------------------------------- +/// Class LLTaskTextureBridge +///---------------------------------------------------------------------------- + +class LLTaskTextureBridge : public LLTaskInvFVBridge +{ +public: + LLTaskTextureBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) {} + + virtual bool canOpenItem() const { return true; } + virtual void openItem(); +}; + +void LLTaskTextureBridge::openItem() +{ + LL_INFOS() << "LLTaskTextureBridge::openItem()" << LL_ENDL; + LLPreviewTexture* preview = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES); + if(preview) + { + LLInventoryItem* item = findItem(); + if(item) + { + preview->setAuxItem(item); + } + preview->setObjectID(mPanel->getTaskUUID()); + } +} + + +///---------------------------------------------------------------------------- +/// Class LLTaskSoundBridge +///---------------------------------------------------------------------------- + +class LLTaskSoundBridge : public LLTaskInvFVBridge +{ +public: + LLTaskSoundBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) {} + + virtual bool canOpenItem() const { return true; } + virtual void openItem(); + virtual void performAction(LLInventoryModel* model, std::string action); + virtual void buildContextMenu(LLMenuGL& menu, U32 flags); + static void openSoundPreview(void* data); +}; + +void LLTaskSoundBridge::openItem() +{ + openSoundPreview((void*)this); +} + +void LLTaskSoundBridge::openSoundPreview(void* data) +{ + LLTaskSoundBridge* self = (LLTaskSoundBridge*)data; + if(!self) + return; + + LLPreviewSound* preview = LLFloaterReg::showTypedInstance<LLPreviewSound>("preview_sound", LLSD(self->mUUID), TAKE_FOCUS_YES); + if (preview) + { + preview->setObjectID(self->mPanel->getTaskUUID()); + } +} + +// virtual +void LLTaskSoundBridge::performAction(LLInventoryModel* model, std::string action) +{ + if (action == "task_play") + { + LLInventoryItem* item = findItem(); + if(item) + { + send_sound_trigger(item->getAssetUUID(), 1.0); + } + } + LLTaskInvFVBridge::performAction(model, action); +} + +void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + LLInventoryItem* item = findItem(); + std::vector<std::string> items; + std::vector<std::string> disabled_items; + if (!item) + { + hide_context_entries(menu, items, disabled_items); + return; + } + + if (canOpenItem()) + { + if (!isItemCopyable()) + { + disabled_items.push_back(std::string("Task Open")); + } + } + items.push_back(std::string("Task Properties")); + if ((flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Task Properties")); + } + if(isItemRenameable()) + { + items.push_back(std::string("Task Rename")); + } + if(isItemRemovable()) + { + items.push_back(std::string("Task Remove")); + } + + items.push_back(std::string("Task Play")); + + + hide_context_entries(menu, items, disabled_items); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskLandmarkBridge +///---------------------------------------------------------------------------- + +class LLTaskLandmarkBridge : public LLTaskInvFVBridge +{ +public: + LLTaskLandmarkBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) {} +}; + +///---------------------------------------------------------------------------- +/// Class LLTaskCallingCardBridge +///---------------------------------------------------------------------------- + +class LLTaskCallingCardBridge : public LLTaskInvFVBridge +{ +public: + LLTaskCallingCardBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) {} + + virtual bool isItemRenameable() const; + virtual bool renameItem(const std::string& new_name); +}; + +bool LLTaskCallingCardBridge::isItemRenameable() const +{ + return false; +} + +bool LLTaskCallingCardBridge::renameItem(const std::string& new_name) +{ + return false; +} + + +///---------------------------------------------------------------------------- +/// Class LLTaskScriptBridge +///---------------------------------------------------------------------------- + +class LLTaskScriptBridge : public LLTaskInvFVBridge +{ +public: + LLTaskScriptBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) {} + + //static bool enableIfCopyable( void* userdata ); +}; + +class LLTaskLSLBridge : public LLTaskScriptBridge +{ +public: + LLTaskLSLBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskScriptBridge(panel, uuid, name) {} + + virtual bool canOpenItem() const { return true; } + virtual void openItem(); + virtual bool removeItem(); + //virtual void buildContextMenu(LLMenuGL& menu); + + //static void copyToInventory(void* userdata); +}; + +void LLTaskLSLBridge::openItem() +{ + LL_INFOS() << "LLTaskLSLBridge::openItem() " << mUUID << LL_ENDL; + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(!object || object->isInventoryPending()) + { + return; + } + if (object->permModify() || gAgent.isGodlike()) + { + LLSD floater_key; + floater_key["taskid"] = mPanel->getTaskUUID(); + floater_key["itemid"] = mUUID; + + LLLiveLSLEditor* preview = LLFloaterReg::showTypedInstance<LLLiveLSLEditor>("preview_scriptedit", floater_key, TAKE_FOCUS_YES); + if (preview) + { + LLSelectNode *node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, true); + if (node && node->mValid) + { + preview->setObjectName(node->mName); + } + preview->setObjectID(mPanel->getTaskUUID()); + } + } + else + { + LLNotificationsUtil::add("CannotOpenScriptObjectNoMod"); + } +} + +bool LLTaskLSLBridge::removeItem() +{ + LLFloaterReg::hideInstance("preview_scriptedit", LLSD(mUUID)); + return LLTaskInvFVBridge::removeItem(); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskObjectBridge +///---------------------------------------------------------------------------- + +class LLTaskObjectBridge : public LLTaskInvFVBridge +{ +public: + LLTaskObjectBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name, + U32 flags = 0) : + LLTaskInvFVBridge(panel, uuid, name, flags) {} +}; + +///---------------------------------------------------------------------------- +/// Class LLTaskNotecardBridge +///---------------------------------------------------------------------------- + +class LLTaskNotecardBridge : public LLTaskInvFVBridge +{ +public: + LLTaskNotecardBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) {} + + virtual bool canOpenItem() const { return true; } + virtual void openItem(); + virtual bool removeItem(); +}; + +void LLTaskNotecardBridge::openItem() +{ + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(!object || object->isInventoryPending()) + { + return; + } + + // Note: even if we are not allowed to modify copyable notecard, we should be able to view it + LLInventoryItem *item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID)); + bool item_copy = item && gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE); + if( item_copy + || object->permModify() + || gAgent.isGodlike()) + { + LLSD floater_key; + floater_key["taskid"] = mPanel->getTaskUUID(); + floater_key["itemid"] = mUUID; + LLPreviewNotecard* preview = LLFloaterReg::showTypedInstance<LLPreviewNotecard>("preview_notecard", floater_key, TAKE_FOCUS_YES); + if (preview) + { + preview->setObjectID(mPanel->getTaskUUID()); + } + } +} + +bool LLTaskNotecardBridge::removeItem() +{ + LLFloaterReg::hideInstance("preview_notecard", LLSD(mUUID)); + return LLTaskInvFVBridge::removeItem(); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskGestureBridge +///---------------------------------------------------------------------------- + +class LLTaskGestureBridge : public LLTaskInvFVBridge +{ +public: + LLTaskGestureBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) {} + + virtual bool canOpenItem() const { return true; } + virtual void openItem(); + virtual bool removeItem(); +}; + +void LLTaskGestureBridge::openItem() +{ + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(!object || object->isInventoryPending()) + { + return; + } + LLPreviewGesture::show(mUUID, mPanel->getTaskUUID()); +} + +bool LLTaskGestureBridge::removeItem() +{ + // Don't need to deactivate gesture because gestures inside objects can never be active. + LLFloaterReg::hideInstance("preview_gesture", LLSD(mUUID)); + return LLTaskInvFVBridge::removeItem(); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskAnimationBridge +///---------------------------------------------------------------------------- + +class LLTaskAnimationBridge : public LLTaskInvFVBridge +{ +public: + LLTaskAnimationBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) {} + + virtual bool canOpenItem() const { return true; } + virtual void openItem(); + virtual bool removeItem(); +}; + +void LLTaskAnimationBridge::openItem() +{ + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(!object || object->isInventoryPending()) + { + return; + } + + LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES); + if (preview && (object->permModify() || gAgent.isGodlike())) + { + preview->setObjectID(mPanel->getTaskUUID()); + } +} + +bool LLTaskAnimationBridge::removeItem() +{ + LLFloaterReg::hideInstance("preview_anim", LLSD(mUUID)); + return LLTaskInvFVBridge::removeItem(); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskWearableBridge +///---------------------------------------------------------------------------- + +class LLTaskWearableBridge : public LLTaskInvFVBridge +{ +public: + LLTaskWearableBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name, + U32 flags) : + LLTaskInvFVBridge(panel, uuid, name, flags) {} + + virtual LLUIImagePtr getIcon() const; +}; + +LLUIImagePtr LLTaskWearableBridge::getIcon() const +{ + return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, false ); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskSettingsBridge +///---------------------------------------------------------------------------- + +class LLTaskSettingsBridge : public LLTaskInvFVBridge +{ +public: + LLTaskSettingsBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name, + U32 flags) : + LLTaskInvFVBridge(panel, uuid, name, flags) {} + + virtual LLUIImagePtr getIcon() const; + virtual LLSettingsType::type_e getSettingsType() const; +}; + +LLUIImagePtr LLTaskSettingsBridge::getIcon() const +{ + return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, false); +} + +LLSettingsType::type_e LLTaskSettingsBridge::getSettingsType() const +{ + return LLSettingsType::ST_NONE; +} + +///---------------------------------------------------------------------------- +/// Class LLTaskMaterialBridge +///---------------------------------------------------------------------------- + +class LLTaskMaterialBridge : public LLTaskInvFVBridge +{ +public: + LLTaskMaterialBridge(LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) {} + + bool canOpenItem() const override { return true; } + void openItem() override; + bool removeItem() override; +}; + +void LLTaskMaterialBridge::openItem() +{ + LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); + if(!object || object->isInventoryPending()) + { + return; + } + + // Note: even if we are not allowed to modify copyable notecard, we should be able to view it + LLInventoryItem *item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID)); + bool item_copy = item && gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE); + if( item_copy + || object->permModify() + || gAgent.isGodlike()) + { + LLSD floater_key; + floater_key["taskid"] = mPanel->getTaskUUID(); + floater_key["itemid"] = mUUID; + LLMaterialEditor* mat = LLFloaterReg::getTypedInstance<LLMaterialEditor>("material_editor", floater_key); + if (mat) + { + mat->setObjectID(mPanel->getTaskUUID()); + mat->openFloater(floater_key); + mat->setFocus(true); + } + } +} + +bool LLTaskMaterialBridge::removeItem() +{ + LLFloaterReg::hideInstance("material_editor", LLSD(mUUID)); + return LLTaskInvFVBridge::removeItem(); +} + + +///---------------------------------------------------------------------------- +/// LLTaskInvFVBridge impl +//---------------------------------------------------------------------------- + +LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory* panel, + LLInventoryObject* object) +{ + LLTaskInvFVBridge* new_bridge = NULL; + const LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(object); + const U32 itemflags = ( NULL == item ? 0 : item->getFlags() ); + LLAssetType::EType type = object ? object->getType() : LLAssetType::AT_CATEGORY; + LLUUID object_id = object ? object->getUUID() : LLUUID::null; + std::string object_name = object ? object->getName() : std::string(); + + switch(type) + { + case LLAssetType::AT_TEXTURE: + new_bridge = new LLTaskTextureBridge(panel, + object_id, + object_name); + break; + case LLAssetType::AT_SOUND: + new_bridge = new LLTaskSoundBridge(panel, + object_id, + object_name); + break; + case LLAssetType::AT_LANDMARK: + new_bridge = new LLTaskLandmarkBridge(panel, + object_id, + object_name); + break; + case LLAssetType::AT_CALLINGCARD: + new_bridge = new LLTaskCallingCardBridge(panel, + object_id, + object_name); + break; + case LLAssetType::AT_SCRIPT: + // OLD SCRIPTS DEPRECATED - JC + LL_WARNS() << "Old script" << LL_ENDL; + //new_bridge = new LLTaskOldScriptBridge(panel, + // object_id, + // object_name); + break; + case LLAssetType::AT_OBJECT: + new_bridge = new LLTaskObjectBridge(panel, + object_id, + object_name, + itemflags); + break; + case LLAssetType::AT_NOTECARD: + new_bridge = new LLTaskNotecardBridge(panel, + object_id, + object_name); + break; + case LLAssetType::AT_ANIMATION: + new_bridge = new LLTaskAnimationBridge(panel, + object_id, + object_name); + break; + case LLAssetType::AT_GESTURE: + new_bridge = new LLTaskGestureBridge(panel, + object_id, + object_name); + break; + case LLAssetType::AT_CLOTHING: + case LLAssetType::AT_BODYPART: + new_bridge = new LLTaskWearableBridge(panel, + object_id, + object_name, + itemflags); + break; + case LLAssetType::AT_CATEGORY: + new_bridge = new LLTaskCategoryBridge(panel, + object_id, + object_name); + break; + case LLAssetType::AT_LSL_TEXT: + new_bridge = new LLTaskLSLBridge(panel, + object_id, + object_name); + break; + case LLAssetType::AT_SETTINGS: + new_bridge = new LLTaskSettingsBridge(panel, + object_id, + object_name, + itemflags); + break; + case LLAssetType::AT_MATERIAL: + new_bridge = new LLTaskMaterialBridge(panel, + object_id, + object_name); + break; + default: + LL_INFOS() << "Unhandled inventory type (llassetstorage.h): " + << (S32)type << LL_ENDL; + break; + } + return new_bridge; +} + + +///---------------------------------------------------------------------------- +/// Class LLPanelObjectInventory +///---------------------------------------------------------------------------- + +static LLDefaultChildRegistry::Register<LLPanelObjectInventory> r("panel_inventory_object"); + +void do_nothing() +{ +} + +// Default constructor +LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Params& p) : + LLPanel(p), + mScroller(NULL), + mFolders(NULL), + mHaveInventory(false), + mIsInventoryEmpty(true), + mInventoryNeedsUpdate(false), + mInventoryViewModel(p.name), + mShowRootFolder(p.show_root_folder) +{ + // Setup context menu callbacks + mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2)); + mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH)); + mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND)); + mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing)); + mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing)); + mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing)); + mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this)); + mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&do_nothing)); +} + +// Destroys the object +LLPanelObjectInventory::~LLPanelObjectInventory() +{ + if (!gIdleCallbacks.deleteFunction(idle, this)) + { + LL_WARNS() << "LLPanelObjectInventory::~LLPanelObjectInventory() failed to delete callback" << LL_ENDL; + } +} + +bool LLPanelObjectInventory::postBuild() +{ + // clear contents and initialize menus, sets up mFolders + reset(); + + // Register an idle update callback + gIdleCallbacks.addFunction(idle, this); + + return true; +} + +void LLPanelObjectInventory::doToSelected(const LLSD& userdata) +{ + LLInventoryAction::doToSelected(&gInventory, mFolders, userdata.asString()); +} + +void LLPanelObjectInventory::clearContents() +{ + mHaveInventory = false; + mIsInventoryEmpty = true; + if (LLToolDragAndDrop::getInstance() && LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_WORLD) + { + LLToolDragAndDrop::getInstance()->endDrag(); + } + + clearItemIDs(); + + if( mScroller ) + { + // removes mFolders + removeChild( mScroller ); //*TODO: Really shouldn't do this during draw()/refresh() + mScroller->die(); + mScroller = NULL; + mFolders = NULL; + } +} + + +void LLPanelObjectInventory::reset() +{ + clearContents(); + + mCommitCallbackRegistrar.pushScope(); // push local callbacks + + // Reset the inventory model to show all folders by default + mInventoryViewModel.getFilter().setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); + + // Create a new folder view root + LLRect dummy_rect(0, 1, 1, 0); + LLFolderView::Params p; + p.name = "task inventory"; + p.title = "task inventory"; + p.parent_panel = this; + p.tool_tip= LLTrans::getString("PanelContentsTooltip"); + p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL); + p.folder_indentation = -14; // subtract space normally reserved for folder expanders + p.view_model = &mInventoryViewModel; + p.root = NULL; + p.options_menu = "menu_inventory.xml"; + + mFolders = LLUICtrlFactory::create<LLFolderView>(p); + + mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); + mFolders->setEnableRegistrar(&mEnableCallbackRegistrar); + + if (hasFocus()) + { + LLEditMenuHandler::gEditMenuHandler = mFolders; + } + + int offset = hasBorder() ? getBorder()->getBorderWidth() << 1 : 0; + LLRect scroller_rect(0, getRect().getHeight() - offset, getRect().getWidth() - offset, 0); + LLScrollContainer::Params scroll_p; + scroll_p.name("task inventory scroller"); + scroll_p.rect(scroller_rect); + scroll_p.tab_stop(true); + scroll_p.follows.flags(FOLLOWS_ALL); + mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroll_p); + addChild(mScroller); + mScroller->addChild(mFolders); + + mFolders->setScrollContainer( mScroller ); + + mCommitCallbackRegistrar.popScope(); +} + +void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* data) +{ + if(!object) return; + + //LL_INFOS() << "invetnory arrived: \n" + // << " panel UUID: " << panel->mTaskUUID << "\n" + // << " task UUID: " << object->mID << LL_ENDL; + if(mTaskUUID == object->mID) + { + mInventoryNeedsUpdate = true; + } +} + +void LLPanelObjectInventory::updateInventory() +{ + //LL_INFOS() << "inventory arrived: \n" + // << " panel UUID: " << panel->mTaskUUID << "\n" + // << " task UUID: " << object->mID << LL_ENDL; + // We're still interested in this task's inventory. + std::vector<LLUUID> selected_item_ids; + std::set<LLFolderViewItem*> selected_items; + bool inventory_has_focus = false; + if (mHaveInventory && mFolders) + { + selected_items = mFolders->getSelectionList(); + inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders); + } + for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end(); + it != end_it; + ++it) + { + selected_item_ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID()); + } + + LLViewerObject* objectp = gObjectList.findObject(mTaskUUID); + if (objectp) + { + LLInventoryObject* inventory_root = objectp->getInventoryRoot(); + LLInventoryObject::object_list_t contents; + objectp->getInventoryContents(contents); + + if (inventory_root) + { + reset(); + mIsInventoryEmpty = false; + createFolderViews(inventory_root, contents); + mFolders->setEnabled(true); + } + else + { + // TODO: create an empty inventory + mIsInventoryEmpty = true; + } + + mHaveInventory = !mIsInventoryEmpty || !objectp->isInventoryDirty(); + if (objectp->isInventoryDirty()) + { + // Inventory is dirty, yet we received inventoryChanged() callback. + // User changed something during ongoing request. + // Rerequest. It will clear dirty flag and won't create dupplicate requests. + objectp->requestInventory(); + } + } + else + { + // TODO: create an empty inventory + mIsInventoryEmpty = true; + mHaveInventory = true; + } + + // restore previous selection + std::vector<LLUUID>::iterator selection_it; + bool first_item = true; + for (selection_it = selected_item_ids.begin(); selection_it != selected_item_ids.end(); ++selection_it) + { + LLFolderViewItem* selected_item = getItemByID(*selection_it); + + if (selected_item) + { + //HACK: "set" first item then "change" each other one to get keyboard focus right + if (first_item) + { + mFolders->setSelection(selected_item, true, inventory_has_focus); + first_item = false; + } + else + { + mFolders->changeSelection(selected_item, true); + } + } + } + + if (mFolders) + { + mFolders->requestArrange(); + } + mInventoryNeedsUpdate = false; + // Edit menu handler is set in onFocusReceived +} + +// *FIX: This is currently a very expensive operation, because we have +// to iterate through the inventory one time for each category. This +// leads to an N^2 based on the category count. This could be greatly +// speeded with an efficient multimap implementation, but we don't +// have that in our current arsenal. +void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root, LLInventoryObject::object_list_t& contents) +{ + if (!inventory_root) + { + return; + } + // Create a visible root category. + LLTaskInvFVBridge* bridge = NULL; + bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root); + if(bridge) + { + LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + + LLFolderViewFolder::Params p; + p.name = inventory_root->getName(); + p.tool_tip = p.name; + p.root = mFolders; + p.listener = bridge; + p.font_color = item_color; + p.font_highlight_color = item_color; + + LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p); + + if (mShowRootFolder) + { + new_folder->addToFolder(mFolders); + new_folder->toggleOpen(); + } + + if (!contents.empty()) + { + createViewsForCategory(&contents, inventory_root, mShowRootFolder ? new_folder : mFolders); + } + + if (mShowRootFolder) + { + // Refresh for label to add item count + new_folder->refresh(); + } + } +} + +typedef std::pair<LLInventoryObject*, LLFolderViewFolder*> obj_folder_pair; + +void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_list_t* inventory, + LLInventoryObject* parent, + LLFolderViewFolder* folder) +{ + LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + + // Find all in the first pass + std::vector<obj_folder_pair*> child_categories; + LLTaskInvFVBridge* bridge; + LLFolderViewItem* view; + + LLInventoryObject::object_list_t::iterator it = inventory->begin(); + LLInventoryObject::object_list_t::iterator end = inventory->end(); + for( ; it != end; ++it) + { + LLInventoryObject* obj = *it; + + if(parent->getUUID() == obj->getParentUUID()) + { + bridge = LLTaskInvFVBridge::createObjectBridge(this, obj); + if(!bridge) + { + continue; + } + if(LLAssetType::AT_CATEGORY == obj->getType()) + { + LLFolderViewFolder::Params p; + p.name = obj->getName(); + p.root = mFolders; + p.listener = bridge; + p.tool_tip = p.name; + p.font_color = item_color; + p.font_highlight_color = item_color; + view = LLUICtrlFactory::create<LLFolderViewFolder>(p); + child_categories.push_back(new obj_folder_pair(obj, + (LLFolderViewFolder*)view)); + } + else + { + LLFolderViewItem::Params params; + params.name(obj->getName()); + params.creation_date(bridge->getCreationDate()); + params.root(mFolders); + params.listener(bridge); + params.rect(LLRect()); + params.tool_tip = params.name; + params.font_color = item_color; + params.font_highlight_color = item_color; + view = LLUICtrlFactory::create<LLFolderViewItem> (params); + } + view->addToFolder(folder); + addItemID(obj->getUUID(), view); + } + } + + // now, for each category, do the second pass + for(S32 i = 0; i < child_categories.size(); i++) + { + createViewsForCategory(inventory, child_categories[i]->first, + child_categories[i]->second ); + delete child_categories[i]; + } + folder->setChildrenInited(true); +} + +void LLPanelObjectInventory::refresh() +{ + //LL_INFOS() << "LLPanelObjectInventory::refresh()" << LL_ENDL; + bool has_inventory = false; + const bool non_root_ok = true; + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + LLSelectNode* node = selection->getFirstRootNode(NULL, non_root_ok); + if(node && node->mValid) + { + LLViewerObject* object = node->getObject(); + if(object && ((selection->getRootObjectCount() == 1) + || (selection->getObjectCount() == 1))) + { + // determine if we need to make a request. Start with a + // default based on if we have inventory at all. + bool make_request = !mHaveInventory; + + // If the task id is different than what we've stored, + // then make the request. + if(mTaskUUID != object->mID) + { + mTaskUUID = object->mID; + mAttachmentUUID = object->getAttachmentItemID(); + make_request = true; + + // This is a new object so pre-emptively clear the contents + // Otherwise we show the old stuff until the update comes in + clearContents(); + + // Register for updates from this object, + registerVOInventoryListener(object,NULL); + } + else if (mAttachmentUUID != object->getAttachmentItemID()) + { + mAttachmentUUID = object->getAttachmentItemID(); + if (mAttachmentUUID.notNull()) + { + // Server unsubsribes viewer (deselects object) from property + // updates after "ObjectAttach" so we need to resubscribe + LLSelectMgr::getInstance()->sendSelect(); + } + } + + // Based on the node information, we may need to dirty the + // object inventory and get it again. + if(node->mValid) + { + if(node->mInventorySerial != object->getInventorySerial() || object->isInventoryDirty()) + { + make_request = true; + } + } + + // do the request if necessary. + if(make_request) + { + requestVOInventory(); + } + has_inventory = true; + } + } + if(!has_inventory) + { + clearInventoryTask(); + } + mInventoryViewModel.setTaskID(mTaskUUID); + //LL_INFOS() << "LLPanelObjectInventory::refresh() " << mTaskUUID << LL_ENDL; +} + +void LLPanelObjectInventory::clearInventoryTask() +{ + mTaskUUID = LLUUID::null; + mAttachmentUUID = LLUUID::null; + removeVOInventoryListener(); + clearContents(); +} + +void LLPanelObjectInventory::removeSelectedItem() +{ + if(mFolders) + { + mFolders->removeSelectedItems(); + } +} + +void LLPanelObjectInventory::startRenamingSelectedItem() +{ + if(mFolders) + { + mFolders->startRenamingSelectedItem(); + } +} + +void LLPanelObjectInventory::draw() +{ + LLPanel::draw(); + + if(mIsInventoryEmpty) + { + if((LLUUID::null != mTaskUUID) && (!mHaveInventory)) + { + LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("LoadingContents"), 0, + (S32)(getRect().getWidth() * 0.5f), + 10, + LLColor4( 1, 1, 1, 1 ), + LLFontGL::HCENTER, + LLFontGL::BOTTOM); + } + else if(mHaveInventory) + { + LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("NoContents"), 0, + (S32)(getRect().getWidth() * 0.5f), + 10, + LLColor4( 1, 1, 1, 1 ), + LLFontGL::HCENTER, + LLFontGL::BOTTOM); + } + } +} + +void LLPanelObjectInventory::deleteAllChildren() +{ + mScroller = NULL; + mFolders = NULL; + LLView::deleteAllChildren(); +} + +bool LLPanelObjectInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg) +{ + if (mFolders) + { + LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL); + if (!folderp) + { + return false; + } + // Try to pass on unmodified mouse coordinates + S32 local_x = x - mFolders->getRect().mLeft; + S32 local_y = y - mFolders->getRect().mBottom; + + if (mFolders->pointInView(local_x, local_y)) + { + return mFolders->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + } + else + { + //force mouse coordinates to be inside folder rectangle + return mFolders->handleDragAndDrop(5, 1, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + } + } + else + { + return false; + } +} + +//static +void LLPanelObjectInventory::idle(void* user_data) +{ + LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data; + + if (self->mFolders) + { + self->mFolders->update(); + } + if (self->mInventoryNeedsUpdate) + { + self->updateInventory(); + } +} + +void LLPanelObjectInventory::onFocusLost() +{ + // inventory no longer handles cut/copy/paste/delete + if (LLEditMenuHandler::gEditMenuHandler == mFolders) + { + LLEditMenuHandler::gEditMenuHandler = NULL; + } + + LLPanel::onFocusLost(); +} + +void LLPanelObjectInventory::onFocusReceived() +{ + // inventory now handles cut/copy/paste/delete + LLEditMenuHandler::gEditMenuHandler = mFolders; + + LLPanel::onFocusReceived(); +} + + +LLFolderViewItem* LLPanelObjectInventory::getItemByID( const LLUUID& id ) +{ + std::map<LLUUID, LLFolderViewItem*>::iterator map_it; + map_it = mItemMap.find(id); + if (map_it != mItemMap.end()) + { + return map_it->second; + } + + return NULL; +} + +void LLPanelObjectInventory::removeItemID( const LLUUID& id ) +{ + mItemMap.erase(id); +} + +void LLPanelObjectInventory::addItemID( const LLUUID& id, LLFolderViewItem* itemp ) +{ + mItemMap[id] = itemp; +} + +void LLPanelObjectInventory::clearItemIDs() +{ + mItemMap.clear(); +} + +bool LLPanelObjectInventory::handleKeyHere( KEY key, MASK mask ) +{ + bool handled = false; + switch (key) + { + case KEY_DELETE: +#if LL_DARWIN + case KEY_BACKSPACE: +#endif + // Delete selected items if delete or backspace key hit on the inventory panel + // Note: on Mac laptop keyboards, backspace and delete are one and the same + if (isSelectionRemovable() && mask == MASK_NONE) + { + LLInventoryAction::doToSelected(&gInventory, mFolders, "delete"); + handled = true; + } + break; + } + return handled; +} + +bool LLPanelObjectInventory::isSelectionRemovable() +{ + if (!mFolders || !mFolders->getRoot()) + { + return false; + } + std::set<LLFolderViewItem*> selection_set = mFolders->getRoot()->getSelectionList(); + if (selection_set.empty()) + { + return false; + } + for (std::set<LLFolderViewItem*>::iterator iter = selection_set.begin(); + iter != selection_set.end(); + ++iter) + { + LLFolderViewItem *item = *iter; + const LLFolderViewModelItemInventory *listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem()); + if (!listener || !listener->isItemRemovable() || listener->isItemInTrash()) + { + return false; + } + } + return true; +} |
