diff options
Diffstat (limited to 'indra/newview/llpanelobjectinventory.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/newview/llpanelobjectinventory.cpp | 540 |
1 files changed, 406 insertions, 134 deletions
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 0b6267c9e6..bf15f56b44 100644..100755 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -44,8 +44,10 @@ #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 "llpreviewanim.h" @@ -56,30 +58,34 @@ #include "llpreviewtexture.h" #include "llscrollcontainer.h" #include "llselectmgr.h" -#include "llsidetray.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 LLFolderViewEventListener +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: @@ -99,51 +105,60 @@ public: S32 getPrice(); static bool commitBuyItem(const LLSD& notification, const LLSD& response); - // LLFolderViewEventListener functionality + // LLFolderViewModelItemInventory functionality virtual const std::string& getName() const; virtual const std::string& getDisplayName() const; + virtual const std::string& getSearchableName() const; + virtual PermissionMask getPermissionMask() const { return PERM_NONE; } /*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; } virtual const LLUUID& getUUID() const { return mUUID; } 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 previewItem(); virtual void selectItem() {} virtual BOOL isItemRenameable() const; virtual BOOL renameItem(const std::string& new_name); virtual BOOL isItemMovable() const; virtual BOOL isItemRemovable() const; virtual BOOL removeItem(); - virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch); - virtual void move(LLFolderViewEventListener* parent_listener); + virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch); + virtual void move(LLFolderViewModelItem* parent_listener); virtual BOOL isItemCopyable() const; virtual BOOL copyToClipboard() const; - virtual void cutToClipboard(); + virtual BOOL cutToClipboard() const; 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 bool hasChildren() const { return FALSE; } virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; } virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_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); + void* cargo_data, + std::string& tooltip_msg); }; LLTaskInvFVBridge::LLTaskInvFVBridge( LLPanelObjectInventory* panel, const LLUUID& uuid, const std::string& name, - U32 flags): + U32 flags) +: LLFolderViewModelItemInventory(panel->getRootViewModel()), mUUID(uuid), mName(name), mPanel(panel), @@ -159,16 +174,22 @@ LLTaskInvFVBridge::LLTaskInvFVBridge( } } -LLInventoryItem* LLTaskInvFVBridge::findItem() const +LLInventoryObject* LLTaskInvFVBridge::findInvObject() const { LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); - if(object) + if (object) { - return dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID)); + 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()); @@ -189,7 +210,7 @@ struct LLBuyInvItemData void LLTaskInvFVBridge::buyItem() { - llinfos << "LLTaskInvFVBridge::buyItem()" << llendl; + LL_INFOS() << "LLTaskInvFVBridge::buyItem()" << LL_ENDL; LLInventoryItem* item = findItem(); if(!item || !item->getSaleInfo().isForSale()) return; LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(), @@ -204,7 +225,7 @@ void LLTaskInvFVBridge::buyItem() if( ( obj = gObjectList.findObject( mPanel->getTaskUUID() ) ) && obj->isAttachment() ) { LLNotificationsUtil::add("Cannot_Purchase_an_Attachment"); - llinfos << "Attempt to purchase an attachment" << llendl; + LL_INFOS() << "Attempt to purchase an attachment" << LL_ENDL; delete inv; } else @@ -292,21 +313,15 @@ const std::string& LLTaskInvFVBridge::getDisplayName() const if(item) { - if(item->getParentUUID().isNull()) - { - if(item->getName() == "Contents") - { - mDisplayName.assign(LLTrans::getString("ViewerObjectContents")); - } - else - { - mDisplayName.assign(item->getName()); - } - } - else + 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")) { - mDisplayName.assign(item->getName()); + 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); @@ -326,15 +341,27 @@ const std::string& LLTaskInvFVBridge::getDisplayName() const } } + 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); @@ -345,12 +372,7 @@ LLUIImagePtr LLTaskInvFVBridge::getIcon() const void LLTaskInvFVBridge::openItem() { // no-op. - lldebugs << "LLTaskInvFVBridge::openItem()" << llendl; -} - -void LLTaskInvFVBridge::previewItem() -{ - openItem(); + LL_DEBUGS() << "LLTaskInvFVBridge::openItem()" << LL_ENDL; } BOOL LLTaskInvFVBridge::isItemRenameable() const @@ -463,7 +485,7 @@ BOOL LLTaskInvFVBridge::removeItem() return FALSE; } -void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) +void LLTaskInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch) { if (!mPanel) { @@ -503,7 +525,7 @@ void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& } } -void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener) +void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener) { } @@ -520,8 +542,9 @@ BOOL LLTaskInvFVBridge::copyToClipboard() const return FALSE; } -void LLTaskInvFVBridge::cutToClipboard() +BOOL LLTaskInvFVBridge::cutToClipboard() const { + return FALSE; } BOOL LLTaskInvFVBridge::isClipboardPasteable() const @@ -539,7 +562,7 @@ void LLTaskInvFVBridge::pasteLinkFromClipboard() BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const { - //llinfos << "LLTaskInvFVBridge::startDrag()" << llendl; + //LL_INFOS() << "LLTaskInvFVBridge::startDrag()" << LL_ENDL; if(mPanel) { LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); @@ -577,9 +600,10 @@ BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, - void* cargo_data) + void* cargo_data, + std::string& tooltip_msg) { - //llinfos << "LLTaskInvFVBridge::dragOrDrop()" << llendl; + //LL_INFOS() << "LLTaskInvFVBridge::dragOrDrop()" << LL_ENDL; return FALSE; } @@ -592,7 +616,7 @@ void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string actio S32 price = getPrice(); if (-1 == price) { - llwarns << "label_buy_task_bridged_item: Invalid price" << llendl; + LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; } else { @@ -630,7 +654,7 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) return; } - if(gAgent.allowOperation(PERM_OWNER, item->getPermissions(), + if(!gAgent.allowOperation(PERM_OWNER, item->getPermissions(), GP_OBJECT_MANIPULATE) && item->getSaleInfo().isForSale()) { @@ -641,7 +665,7 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) S32 price = getPrice(); if (-1 == price) { - llwarns << "label_buy_task_bridged_item: Invalid price" << llendl; + LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; } else { @@ -665,15 +689,15 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) else if (canOpenItem()) { items.push_back(std::string("Task Open")); - if (!isItemCopyable()) - { - disabled_items.push_back(std::string("Task Open")); - } } 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()) { @@ -697,19 +721,21 @@ public: const std::string& name); virtual LLUIImagePtr getIcon() const; - virtual const std::string& getDisplayName() const { return getName(); } + 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() const; virtual void buildContextMenu(LLMenuGL& menu, U32 flags); - virtual BOOL hasChildren() const; + 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); + 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( @@ -725,6 +751,19 @@ LLUIImagePtr LLTaskCategoryBridge::getIcon() const return LLUI::getUIImage("Inv_FolderClosed"); } +// virtual +const std::string& LLTaskCategoryBridge::getDisplayName() const +{ + LLInventoryObject* cat = findInvObject(); + + if (cat) + { + mDisplayName.assign(cat->getName()); + } + + return mDisplayName; +} + BOOL LLTaskCategoryBridge::isItemRenameable() const { return FALSE; @@ -747,7 +786,7 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } -BOOL LLTaskCategoryBridge::hasChildren() const +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. @@ -760,8 +799,8 @@ void LLTaskCategoryBridge::openItem() BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const { - //llinfos << "LLTaskInvFVBridge::startDrag()" << llendl; - if(mPanel) + //LL_INFOS() << "LLTaskInvFVBridge::startDrag()" << LL_ENDL; + if(mPanel && mUUID.notNull()) { LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); if(object) @@ -780,9 +819,10 @@ BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, - void* cargo_data) + void* cargo_data, + std::string& tooltip_msg) { - //llinfos << "LLTaskCategoryBridge::dragOrDrop()" << llendl; + //LL_INFOS() << "LLTaskCategoryBridge::dragOrDrop()" << LL_ENDL; BOOL accept = FALSE; LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); if(object) @@ -802,6 +842,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_ANIMATION: case DAD_GESTURE: case DAD_CALLINGCARD: + case DAD_MESH: accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data); if(accept && drop) { @@ -860,10 +901,11 @@ public: void LLTaskTextureBridge::openItem() { - llinfos << "LLTaskTextureBridge::openItem()" << llendl; + LL_INFOS() << "LLTaskTextureBridge::openItem()" << LL_ENDL; LLPreviewTexture* preview = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES); if(preview) { + preview->setAuxItem(findItem()); preview->setObjectID(mPanel->getTaskUUID()); } } @@ -937,7 +979,7 @@ void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) S32 price = getPrice(); if (-1 == price) { - llwarns << "label_buy_task_bridged_item: Invalid price" << llendl; + LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; } else { @@ -1054,7 +1096,7 @@ public: void LLTaskLSLBridge::openItem() { - llinfos << "LLTaskLSLBridge::openItem() " << mUUID << llendl; + LL_INFOS() << "LLTaskLSLBridge::openItem() " << mUUID << LL_ENDL; LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); if(!object || object->isInventoryPending()) { @@ -1062,7 +1104,10 @@ void LLTaskLSLBridge::openItem() } if (object->permModify() || gAgent.isGodlike()) { - LLLiveLSLEditor* preview = LLFloaterReg::showTypedInstance<LLLiveLSLEditor>("preview_scriptedit", LLSD(mUUID), TAKE_FOCUS_YES); + 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) { preview->setObjectID(mPanel->getTaskUUID()); @@ -1227,6 +1272,116 @@ LLUIImagePtr LLTaskWearableBridge::getIcon() const return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE ); } +///---------------------------------------------------------------------------- +/// Class LLTaskMeshBridge +///---------------------------------------------------------------------------- + +class LLTaskMeshBridge : public LLTaskInvFVBridge +{ +public: + LLTaskMeshBridge( + LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name); + + virtual LLUIImagePtr getIcon() const; + virtual void openItem(); + virtual void performAction(LLInventoryModel* model, std::string action); + virtual void buildContextMenu(LLMenuGL& menu, U32 flags); +}; + +LLTaskMeshBridge::LLTaskMeshBridge( + LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskMeshBridge::getIcon() const +{ + return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE); +} + +void LLTaskMeshBridge::openItem() +{ + // open mesh +} + + +// virtual +void LLTaskMeshBridge::performAction(LLInventoryModel* model, std::string action) +{ + if (action == "mesh action") + { + LLInventoryItem* item = findItem(); + if(item) + { + // do action + } + } + LLTaskInvFVBridge::performAction(model, action); +} + +void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + LLInventoryItem* item = findItem(); + if(!item) return; + std::vector<std::string> items; + std::vector<std::string> disabled_items; + + if(item->getPermissions().getOwner() != gAgent.getID() + && item->getSaleInfo().isForSale()) + { + items.push_back(std::string("Task Buy")); + + std::string label= LLTrans::getString("Buy"); + // Check the price of the item. + S32 price = getPrice(); + if (-1 == price) + { + LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; + } + else + { + std::ostringstream info; + info << LLTrans::getString("BuyforL$") << price; + label.assign(info.str()); + } + + const LLView::child_list_t *list = menu.getChildList(); + LLView::child_list_t::const_iterator itor; + for (itor = list->begin(); itor != list->end(); ++itor) + { + std::string name = (*itor)->getName(); + LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor); + if (name == "Task Buy" && menu_itemp) + { + menu_itemp->setLabel(label); + } + } + } + else + { + items.push_back(std::string("Task Open")); + if (!isItemCopyable()) + { + disabled_items.push_back(std::string("Task Open")); + } + } + 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")); + } + + + hide_context_entries(menu, items, disabled_items); +} ///---------------------------------------------------------------------------- /// LLTaskInvFVBridge impl @@ -1238,78 +1393,85 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory* LLTaskInvFVBridge* new_bridge = NULL; const LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(object); const U32 itemflags = ( NULL == item ? 0 : item->getFlags() ); - LLAssetType::EType type = object->getType(); + 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->getUUID(), - object->getName()); + object_id, + object_name); break; case LLAssetType::AT_SOUND: new_bridge = new LLTaskSoundBridge(panel, - object->getUUID(), - object->getName()); + object_id, + object_name); break; case LLAssetType::AT_LANDMARK: new_bridge = new LLTaskLandmarkBridge(panel, - object->getUUID(), - object->getName()); + object_id, + object_name); break; case LLAssetType::AT_CALLINGCARD: new_bridge = new LLTaskCallingCardBridge(panel, - object->getUUID(), - object->getName()); + object_id, + object_name); break; case LLAssetType::AT_SCRIPT: // OLD SCRIPTS DEPRECATED - JC - llwarns << "Old script" << llendl; + LL_WARNS() << "Old script" << LL_ENDL; //new_bridge = new LLTaskOldScriptBridge(panel, - // object->getUUID(), - // object->getName()); + // object_id, + // object_name); break; case LLAssetType::AT_OBJECT: new_bridge = new LLTaskObjectBridge(panel, - object->getUUID(), - object->getName(), + object_id, + object_name, itemflags); break; case LLAssetType::AT_NOTECARD: new_bridge = new LLTaskNotecardBridge(panel, - object->getUUID(), - object->getName()); + object_id, + object_name); break; case LLAssetType::AT_ANIMATION: new_bridge = new LLTaskAnimationBridge(panel, - object->getUUID(), - object->getName()); + object_id, + object_name); break; case LLAssetType::AT_GESTURE: new_bridge = new LLTaskGestureBridge(panel, - object->getUUID(), - object->getName()); + object_id, + object_name); break; case LLAssetType::AT_CLOTHING: case LLAssetType::AT_BODYPART: new_bridge = new LLTaskWearableBridge(panel, - object->getUUID(), - object->getName(), + object_id, + object_name, itemflags); break; case LLAssetType::AT_CATEGORY: new_bridge = new LLTaskCategoryBridge(panel, - object->getUUID(), - object->getName()); + object_id, + object_name); break; case LLAssetType::AT_LSL_TEXT: new_bridge = new LLTaskLSLBridge(panel, - object->getUUID(), - object->getName()); + object_id, + object_name); + break; + case LLAssetType::AT_MESH: + new_bridge = new LLTaskMeshBridge(panel, + object_id, + object_name); break; default: - llinfos << "Unhandled inventory type (llassetstorage.h): " - << (S32)type << llendl; + LL_INFOS() << "Unhandled inventory type (llassetstorage.h): " + << (S32)type << LL_ENDL; break; } return new_bridge; @@ -1333,7 +1495,8 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par mFolders(NULL), mHaveInventory(FALSE), mIsInventoryEmpty(TRUE), - mInventoryNeedsUpdate(FALSE) + mInventoryNeedsUpdate(FALSE), + mInventoryViewModel(p.name) { // Setup context menu callbacks mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2)); @@ -1342,7 +1505,7 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par 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)); + mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this)); } // Destroys the object @@ -1350,7 +1513,7 @@ LLPanelObjectInventory::~LLPanelObjectInventory() { if (!gIdleCallbacks.deleteFunction(idle, this)) { - llwarns << "LLPanelObjectInventory::~LLPanelObjectInventory() failed to delete callback" << llendl; + LL_WARNS() << "LLPanelObjectInventory::~LLPanelObjectInventory() failed to delete callback" << LL_ENDL; } } @@ -1367,7 +1530,7 @@ BOOL LLPanelObjectInventory::postBuild() void LLPanelObjectInventory::doToSelected(const LLSD& userdata) { - mFolders->doToSelected(&gInventory, userdata); + LLInventoryAction::doToSelected(&gInventory, mFolders, userdata.asString()); } void LLPanelObjectInventory::clearContents() @@ -1379,6 +1542,8 @@ void LLPanelObjectInventory::clearContents() LLToolDragAndDrop::getInstance()->endDrag(); } + clearItemIDs(); + if( mScroller ) { // removes mFolders @@ -1394,20 +1559,26 @@ void LLPanelObjectInventory::reset() { clearContents(); - //setBorderVisible(FALSE); - 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.task_id = getTaskUUID(); 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); - // this ensures that we never say "searching..." or "no items found" - mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); + mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); if (hasFocus()) @@ -1421,7 +1592,7 @@ void LLPanelObjectInventory::reset() scroll_p.rect(scroller_rect); scroll_p.tab_stop(true); scroll_p.follows.flags(FOLLOWS_ALL); - mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_p); + mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroll_p); addChild(mScroller); mScroller->addChild(mFolders); @@ -1437,9 +1608,9 @@ void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object, { if(!object) return; - //llinfos << "invetnory arrived: \n" + //LL_INFOS() << "invetnory arrived: \n" // << " panel UUID: " << panel->mTaskUUID << "\n" - // << " task UUID: " << object->mID << llendl; + // << " task UUID: " << object->mID << LL_ENDL; if(mTaskUUID == object->mID) { mInventoryNeedsUpdate = TRUE; @@ -1452,7 +1623,7 @@ void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object, iter != inventory->end(); ) { LLInventoryObject* item = *iter++; - LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properites", item->getUUID()); + LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properties", item->getUUID()); if(floater) { floater->refresh(); @@ -1463,19 +1634,24 @@ void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object, void LLPanelObjectInventory::updateInventory() { - //llinfos << "inventory arrived: \n" + //LL_INFOS() << "inventory arrived: \n" // << " panel UUID: " << panel->mTaskUUID << "\n" - // << " task UUID: " << object->mID << llendl; + // << " task UUID: " << object->mID << LL_ENDL; // We're still interested in this task's inventory. - std::set<LLUUID> selected_items; + std::vector<LLUUID> selected_item_ids; + std::set<LLFolderViewItem*> selected_items; BOOL inventory_has_focus = FALSE; - if (mHaveInventory) + if (mHaveInventory && mFolders) { selected_items = mFolders->getSelectionList(); inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders); } - - reset(); + 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) @@ -1483,19 +1659,21 @@ void LLPanelObjectInventory::updateInventory() LLInventoryObject* inventory_root = objectp->getInventoryRoot(); LLInventoryObject::object_list_t contents; objectp->getInventoryContents(contents); + if (inventory_root) { - createFolderViews(inventory_root, contents); - mHaveInventory = TRUE; + reset(); mIsInventoryEmpty = FALSE; + createFolderViews(inventory_root, contents); mFolders->setEnabled(TRUE); } else { // TODO: create an empty inventory mIsInventoryEmpty = TRUE; - mHaveInventory = TRUE; } + + mHaveInventory = TRUE; } else { @@ -1505,11 +1683,12 @@ void LLPanelObjectInventory::updateInventory() } // restore previous selection - std::set<LLUUID>::iterator selection_it; - BOOL first_item = TRUE; - for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it) + 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 = mFolders->getItemByID(*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 @@ -1525,7 +1704,10 @@ void LLPanelObjectInventory::updateInventory() } } - mFolders->requestArrange(); + if (mFolders) + { + mFolders->requestArrange(); + } mInventoryNeedsUpdate = FALSE; // Edit menu handler is set in onFocusReceived } @@ -1546,19 +1728,24 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root); if(bridge) { - LLFolderViewFolder* new_folder = NULL; + LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + LLFolderViewFolder::Params p; p.name = inventory_root->getName(); - p.icon = LLUI::getUIImage("Inv_FolderClosed"); - p.icon_open = LLUI::getUIImage("Inv_FolderOpen"); + p.tool_tip = p.name; p.root = mFolders; p.listener = bridge; - p.tool_tip = p.name; - new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p); - new_folder->addToFolder(mFolders, mFolders); + p.font_color = item_color; + p.font_highlight_color = item_color; + + LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p); + new_folder->addToFolder(mFolders); new_folder->toggleOpen(); - createViewsForCategory(&contents, inventory_root, new_folder); + if (!contents.empty()) + { + createViewsForCategory(&contents, inventory_root, new_folder); + } } } @@ -1568,8 +1755,10 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li LLInventoryObject* parent, LLFolderViewFolder* folder) { + LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + // Find all in the first pass - LLDynamicArray<obj_folder_pair*> child_categories; + std::vector<obj_folder_pair*> child_categories; LLTaskInvFVBridge* bridge; LLFolderViewItem* view; @@ -1590,33 +1779,35 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li { LLFolderViewFolder::Params p; p.name = obj->getName(); - p.icon = LLUI::getUIImage("Inv_FolderClosed"); - p.icon_open = LLUI::getUIImage("Inv_FolderOpen"); 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.put(new obj_folder_pair(obj, + child_categories.push_back(new obj_folder_pair(obj, (LLFolderViewFolder*)view)); } else { LLFolderViewItem::Params params; params.name(obj->getName()); - params.icon(bridge->getIcon()); 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, mFolders); + view->addToFolder(folder); + addItemID(obj->getUUID(), view); } } // now, for each category, do the second pass - for(S32 i = 0; i < child_categories.count(); i++) + for(S32 i = 0; i < child_categories.size(); i++) { createViewsForCategory(inventory, child_categories[i]->first, child_categories[i]->second ); @@ -1626,7 +1817,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li void LLPanelObjectInventory::refresh() { - //llinfos << "LLPanelObjectInventory::refresh()" << llendl; + //LL_INFOS() << "LLPanelObjectInventory::refresh()" << LL_ENDL; BOOL has_inventory = FALSE; const BOOL non_root_ok = TRUE; LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok); @@ -1675,11 +1866,17 @@ void LLPanelObjectInventory::refresh() } if(!has_inventory) { - mTaskUUID = LLUUID::null; - removeVOInventoryListener(); - clearContents(); + clearInventoryTask(); } - //llinfos << "LLPanelObjectInventory::refresh() " << mTaskUUID << llendl; + mInventoryViewModel.setTaskID(mTaskUUID); + //LL_INFOS() << "LLPanelObjectInventory::refresh() " << mTaskUUID << LL_ENDL; +} + +void LLPanelObjectInventory::clearInventoryTask() +{ + mTaskUUID = LLUUID::null; + removeVOInventoryListener(); + clearContents(); } void LLPanelObjectInventory::removeSelectedItem() @@ -1766,7 +1963,10 @@ void LLPanelObjectInventory::idle(void* user_data) { LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data; - + if (self->mFolders) + { + self->mFolders->update(); + } if (self->mInventoryNeedsUpdate) { self->updateInventory(); @@ -1791,3 +1991,75 @@ void LLPanelObjectInventory::onFocusReceived() 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: + case KEY_BACKSPACE: + // 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; +} |