summaryrefslogtreecommitdiff
path: root/indra/newview/llinventorybridge.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llinventorybridge.cpp')
-rw-r--r--indra/newview/llinventorybridge.cpp576
1 files changed, 385 insertions, 191 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index a6a5ecb8e7..26a8a707b8 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -38,7 +38,6 @@
#include "llappearancemgr.h"
#include "llavataractions.h"
#include "llfloatercustomize.h"
-#include "llfloaterinventory.h"
#include "llfloateropenobject.h"
#include "llfloaterreg.h"
#include "llfloaterworldmap.h"
@@ -50,6 +49,8 @@
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llinventorypanel.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewtexture.h"
@@ -62,6 +63,7 @@
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llwearablelist.h"
+#include "llpaneloutfitsinventory.h"
using namespace LLOldEvents;
@@ -122,8 +124,8 @@ std::string ICON_NAME[ICON_NAME_COUNT] =
"Inv_Animation",
"Inv_Gesture",
- "inv_item_linkitem.tga",
- "inv_item_linkfolder.tga"
+ "Inv_LinkItem",
+ "Inv_LinkFolder"
};
// +=================================================+
@@ -171,16 +173,33 @@ time_t LLInvFVBridge::getCreationDate() const
return 0;
}
-// Can be destoryed (or moved to trash)
+// Can be destroyed (or moved to trash)
BOOL LLInvFVBridge::isItemRemovable()
{
- LLInventoryModel* model = getInventoryModel();
- if(!model) return FALSE;
- if(model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
+ const LLInventoryModel* model = getInventoryModel();
+ if(!model)
+ {
+ return FALSE;
+ }
+ if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
+ {
+ return FALSE;
+ }
+ const LLInventoryObject *obj = model->getItem(mUUID);
+ if (obj && obj->getIsLinkType())
{
return TRUE;
}
- return FALSE;
+ if (gAgentWearables.isWearingItem(mUUID))
+ {
+ return FALSE;
+ }
+ const LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
+ if (avatar && avatar->isWearingAttachment(mUUID))
+ {
+ return FALSE;
+ }
+ return TRUE;
}
// Can be moved to another folder
@@ -475,6 +494,7 @@ void hide_context_entries(LLMenuGL& menu,
}
else
{
+ (*itor)->setVisible(TRUE);
for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2)
{
if (*itor2 == name)
@@ -486,33 +506,98 @@ void hide_context_entries(LLMenuGL& menu,
}
}
+bool isWornLink(LLUUID link_id)
+{
+ LLViewerInventoryItem *link = gInventory.getItem(link_id);
+ if (!link)
+ return false;
+ LLViewerInventoryItem *item = link->getLinkedItem();
+ if (!item)
+ return false;
+
+ switch(item->getType())
+ {
+ case LLAssetType::AT_OBJECT:
+ {
+ LLVOAvatarSelf* my_avatar = gAgent.getAvatarObject();
+ if(my_avatar && my_avatar->isWearingAttachment(item->getUUID()))
+ return true;
+ }
+ break;
+
+ case LLAssetType::AT_BODYPART:
+ case LLAssetType::AT_CLOTHING:
+ if(gAgentWearables.isWearingItem(item->getUUID()))
+ return true;
+ break;
+
+ case LLAssetType::AT_GESTURE:
+ if (LLGestureManager::instance().isGestureActive(item->getUUID()))
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
// Helper for commonly-used entries
void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
std::vector<std::string> &items,
std::vector<std::string> &disabled_items, U32 flags)
{
- items.push_back(std::string("Rename"));
- if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
- {
- disabled_items.push_back(std::string("Rename"));
- }
+ const LLInventoryObject *obj = getInventoryObject();
- if (show_asset_id)
+ bool is_sidepanel = isInOutfitsSidePanel();
+ if (is_sidepanel)
{
- items.push_back(std::string("Copy Asset UUID"));
- if ( (! ( isItemPermissive() || gAgent.isGodlike() ) )
- || (flags & FIRST_SELECTED_ITEM) == 0)
+ // Sidepanel includes restricted menu.
+ if (obj && obj->getIsLinkType() && !isWornLink(mUUID))
{
- disabled_items.push_back(std::string("Copy Asset UUID"));
+ items.push_back(std::string("Remove Link"));
}
+ return;
}
- items.push_back(std::string("Copy Separator"));
-
- items.push_back(std::string("Copy"));
- if (!isItemCopyable())
+ if (obj)
{
- disabled_items.push_back(std::string("Copy"));
+ if (obj->getIsLinkType())
+ {
+ items.push_back(std::string("Find Original"));
+ if (isLinkedObjectMissing())
+ {
+ disabled_items.push_back(std::string("Find Original"));
+ }
+ }
+ else
+ {
+ if (LLAssetType::lookupCanLink(obj->getType()))
+ {
+ items.push_back(std::string("Find Links"));
+ }
+ items.push_back(std::string("Rename"));
+ if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Rename"));
+ }
+
+ if (show_asset_id)
+ {
+ items.push_back(std::string("Copy Asset UUID"));
+ if ( (! ( isItemPermissive() || gAgent.isGodlike() ) )
+ || (flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Copy Asset UUID"));
+ }
+ }
+ items.push_back(std::string("Copy Separator"));
+
+ items.push_back(std::string("Copy"));
+ if (!isItemCopyable())
+ {
+ disabled_items.push_back(std::string("Copy"));
+ }
+ }
}
items.push_back(std::string("Paste"));
@@ -528,6 +613,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
items.push_back(std::string("Paste Separator"));
+
+ if (obj && obj->getIsLinkType() && !isWornLink(mUUID))
+ {
+ items.push_back(std::string("Remove Link"));
+ }
+
items.push_back(std::string("Delete"));
if (!isItemRemovable())
{
@@ -634,6 +725,20 @@ BOOL LLInvFVBridge::isLinkedObjectInTrash() const
return FALSE;
}
+BOOL LLInvFVBridge::isLinkedObjectMissing() const
+{
+ const LLInventoryObject *obj = getInventoryObject();
+ if (!obj)
+ {
+ return TRUE;
+ }
+ if (obj->getIsLinkType() && LLAssetType::lookupIsLinkType(obj->getType()))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
BOOL LLInvFVBridge::isAgentInventory() const
{
const LLInventoryModel* model = getInventoryModel();
@@ -662,20 +767,20 @@ BOOL LLInvFVBridge::isItemPermissive() const
// static
void LLInvFVBridge::changeItemParent(LLInventoryModel* model,
LLViewerInventoryItem* item,
- const LLUUID& new_parent,
+ const LLUUID& new_parent_id,
BOOL restamp)
{
- if(item->getParentUUID() != new_parent)
+ if(item->getParentUUID() != new_parent_id)
{
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
update.push_back(old_folder);
- LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1);
+ LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
- new_item->setParent(new_parent);
+ new_item->setParent(new_parent_id);
new_item->updateParentOnServer(restamp);
model->updateItem(new_item);
model->notifyObservers();
@@ -685,24 +790,27 @@ void LLInvFVBridge::changeItemParent(LLInventoryModel* model,
// static
void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model,
LLViewerInventoryCategory* cat,
- const LLUUID& new_parent,
+ const LLUUID& new_parent_id,
BOOL restamp)
{
- if(cat->getParentUUID() != new_parent)
+ // Can't move a folder into a child of itself.
+ if (model->isObjectDescendentOf(new_parent_id, cat->getUUID()))
{
- LLInventoryModel::update_list_t update;
- LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
- update.push_back(old_folder);
- LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1);
- update.push_back(new_folder);
- gInventory.accountForUpdate(update);
-
- LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
- new_cat->setParent(new_parent);
- new_cat->updateParentOnServer(restamp);
- model->updateCategory(new_cat);
- model->notifyObservers();
+ return;
}
+
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
+ update.push_back(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
+ update.push_back(new_folder);
+ model->accountForUpdate(update);
+
+ LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
+ new_cat->setParent(new_parent_id);
+ new_cat->updateParentOnServer(restamp);
+ model->updateCategory(new_cat);
+ model->notifyObservers();
}
@@ -824,9 +932,6 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
new_listener = new LLFolderBridge(inventory, uuid);
break;
case LLAssetType::AT_LINK:
- // Only should happen for broken links.
- new_listener = new LLLinkItemBridge(inventory, uuid);
- break;
case LLAssetType::AT_LINK_FOLDER:
// Only should happen for broken links.
new_listener = new LLLinkItemBridge(inventory, uuid);
@@ -861,6 +966,16 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
}
}
+bool LLInvFVBridge::isInOutfitsSidePanel() const
+{
+ LLInventoryPanel *my_panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
+ LLPanelOutfitsInventory *outfit_panel =
+ dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
+ if (!outfit_panel)
+ return false;
+ return outfit_panel->isAccordionPanel(my_panel);
+}
+
// +=================================================+
// | InventoryFVBridgeBuilder |
// +=================================================+
@@ -889,6 +1004,7 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model,
{
gotoItem(folder);
}
+
if ("open" == action)
{
openItem();
@@ -1023,7 +1139,7 @@ void LLItemBridge::gotoItem(LLFolderView *folder)
LLInventoryObject *obj = getInventoryObject();
if (obj && obj->getIsLinkType())
{
- LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel();
+ LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
if (active_panel)
{
active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
@@ -1281,6 +1397,16 @@ BOOL LLItemBridge::isItemPermissive() const
return FALSE;
}
+bool LLItemBridge::isAddAction(std::string action) const
+{
+ return ("wear" == action || "attach" == action || "activate" == action);
+}
+
+bool LLItemBridge::isRemoveAction(std::string action) const
+{
+ return ("take_off" == action || "detach" == action || "deactivate" == action);
+}
+
// +=================================================+
// | LLFolderBridge |
// +=================================================+
@@ -1303,6 +1429,23 @@ void LLFolderBridge::selectItem()
}
+// Iterate through a folder's children to determine if
+// all the children are removable.
+class LLIsItemRemovable : public LLFolderViewFunctor
+{
+public:
+ LLIsItemRemovable() : mPassed(TRUE) {}
+ virtual void doFolder(LLFolderViewFolder* folder)
+ {
+ mPassed &= folder->getListener()->isItemRemovable();
+ }
+ virtual void doItem(LLFolderViewItem* item)
+ {
+ mPassed &= item->getListener()->isItemRemovable();
+ }
+ BOOL mPassed;
+};
+
// Can be destroyed (or moved to trash)
BOOL LLFolderBridge::isItemRemovable()
{
@@ -1328,47 +1471,25 @@ BOOL LLFolderBridge::isItemRemovable()
{
return FALSE;
}
-
+ // Allow protected types to be removed, but issue a warning.
+ /*
if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
{
return FALSE;
}
+ */
- LLInventoryModel::cat_array_t descendent_categories;
- LLInventoryModel::item_array_t descendent_items;
- gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
-
- S32 i;
- for( i = 0; i < descendent_categories.count(); i++ )
+ LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
+ LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
+ if (folderp)
{
- LLInventoryCategory* category = descendent_categories[i];
- if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
+ LLIsItemRemovable folder_test;
+ folderp->applyFunctorToChildren(folder_test);
+ if (!folder_test.mPassed)
{
return FALSE;
}
}
-
- for( i = 0; i < descendent_items.count(); i++ )
- {
- LLInventoryItem* item = descendent_items[i];
- if( (item->getType() == LLAssetType::AT_CLOTHING) ||
- (item->getType() == LLAssetType::AT_BODYPART) )
- {
- if(gAgentWearables.isWearingItem(item->getUUID()))
- {
- return FALSE;
- }
- }
- else
- if( item->getType() == LLAssetType::AT_OBJECT )
- {
- if(avatar->isWearingAttachment(item->getUUID()))
- {
- return FALSE;
- }
- }
- }
-
return TRUE;
}
@@ -1678,7 +1799,7 @@ void warn_move_inventory(LLViewerObject* object, LLMoveInv* move_inv)
{
dialog = "MoveInventoryFromObject";
}
- LLNotifications::instance().add(dialog, LLSD(), LLSD(), boost::bind(move_task_inventory_callback, _1, _2, move_inv));
+ LLNotificationsUtil::add(dialog, LLSD(), LLSD(), boost::bind(move_task_inventory_callback, _1, _2, move_inv));
}
// Move/copy all inventory items from the Contents folder of an in-world
@@ -2180,38 +2301,67 @@ BOOL LLFolderBridge::removeItem()
{
return FALSE;
}
- // move it to the trash
- LLPreview::hide(mUUID);
- LLInventoryModel* model = getInventoryModel();
- if(!model) return FALSE;
+ const LLViewerInventoryCategory *cat = getCategory();
+
+ LLSD payload;
+ LLSD args;
+ args["FOLDERNAME"] = cat->getName();
- const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ LLNotification::Params params("ConfirmDeleteProtectedCategory");
+ params.payload(payload).substitutions(args).functor.function(boost::bind(&LLFolderBridge::removeItemResponse, this, _1, _2));
+ if (LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
+ {
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+ return TRUE;
+}
- // Look for any gestures and deactivate them
- LLInventoryModel::cat_array_t descendent_categories;
- LLInventoryModel::item_array_t descendent_items;
- gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
+bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
- S32 i;
- for (i = 0; i < descendent_items.count(); i++)
+ // if they choose delete, do it. Otherwise, don't do anything
+ if(option == 0)
{
- LLInventoryItem* item = descendent_items[i];
- if (item->getType() == LLAssetType::AT_GESTURE
- && LLGestureManager::instance().isGestureActive(item->getUUID()))
+ // move it to the trash
+ LLPreview::hide(mUUID);
+ LLInventoryModel* model = getInventoryModel();
+ if(!model) return FALSE;
+
+ const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
+
+ // Look for any gestures and deactivate them
+ LLInventoryModel::cat_array_t descendent_categories;
+ LLInventoryModel::item_array_t descendent_items;
+ gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
+
+ for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin();
+ iter != descendent_items.end();
+ ++iter)
+ {
+ const LLViewerInventoryItem* item = (*iter);
+ const LLUUID& item_id = item->getUUID();
+ if (item->getType() == LLAssetType::AT_GESTURE
+ && LLGestureManager::instance().isGestureActive(item_id))
+ {
+ LLGestureManager::instance().deactivateGesture(item_id);
+ }
+ }
+
+ // go ahead and do the normal remove if no 'last calling
+ // cards' are being removed.
+ LLViewerInventoryCategory* cat = getCategory();
+ if(cat)
{
- LLGestureManager::instance().deactivateGesture(item->getUUID());
+ LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE);
}
+ return TRUE;
}
-
- // go ahead and do the normal remove if no 'last calling
- // cards' are being removed.
- LLViewerInventoryCategory* cat = getCategory();
- if(cat)
- {
- LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE);
- }
-
- return TRUE;
+ return FALSE;
}
void LLFolderBridge::pasteFromClipboard()
@@ -2219,14 +2369,16 @@ void LLFolderBridge::pasteFromClipboard()
LLInventoryModel* model = getInventoryModel();
if(model && isClipboardPasteable())
{
- LLInventoryItem* item = NULL;
+ const LLUUID parent_id(mUUID);
+
LLDynamicArray<LLUUID> objects;
LLInventoryClipboard::instance().retrieve(objects);
- S32 count = objects.count();
- const LLUUID parent_id(mUUID);
- for(S32 i = 0; i < count; i++)
+ for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
+ iter != objects.end();
+ ++iter)
{
- item = model->getItem(objects.get(i));
+ const LLUUID& item_id = (*iter);
+ LLInventoryItem *item = model->getItem(item_id);
if (item)
{
if(LLInventoryClipboard::instance().isCutMode())
@@ -2255,13 +2407,15 @@ void LLFolderBridge::pasteLinkFromClipboard()
const LLInventoryModel* model = getInventoryModel();
if(model)
{
+ const LLUUID parent_id(mUUID);
+
LLDynamicArray<LLUUID> objects;
LLInventoryClipboard::instance().retrieve(objects);
- S32 count = objects.count();
- LLUUID parent_id(mUUID);
- for(S32 i = 0; i < count; i++)
+ for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
+ iter != objects.end();
+ ++iter)
{
- const LLUUID &object_id = objects.get(i);
+ const LLUUID &object_id = (*iter);
#if SUPPORT_ENSEMBLES
if (LLInventoryCategory *cat = model->getCategory(object_id))
{
@@ -2311,8 +2465,15 @@ void LLFolderBridge::folderOptionsMenu()
// calling card related functionality for folders.
+ const bool is_sidepanel = isInOutfitsSidePanel();
+ if (is_sidepanel)
+ {
+ mItems.push_back("Rename");
+ mItems.push_back("Delete");
+ }
+
// Only enable calling-card related options for non-default folders.
- if (!is_default_folder)
+ if (!is_sidepanel && !is_default_folder)
{
LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
@@ -2347,8 +2508,14 @@ void LLFolderBridge::folderOptionsMenu()
mItems.push_back(std::string("Wear As Ensemble"));
}
mItems.push_back(std::string("Remove From Outfit"));
+ if (is_sidepanel)
+ mItems.push_back(std::string("Outfit Separator"));
}
hide_context_entries(*mMenu, mItems, disabled_items);
+
+ // Reposition the menu, in case we're adding items to an existing menu.
+ mMenu->needsArrange();
+ mMenu->arrangeAndClear();
}
BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type)
@@ -2370,14 +2537,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
mDisabledItems.clear();
lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
+
// std::vector<std::string> disabled_items;
LLInventoryModel* model = getInventoryModel();
if(!model) return;
const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
const LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
- mItems.clear(); //adding code to clear out member Items (which means Items should not have other data here at this point)
- mDisabledItems.clear(); //adding code to clear out disabled members from previous
if (lost_and_found_id == mUUID)
{
// This is the lost+found folder.
@@ -2406,7 +2572,7 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
LLViewerInventoryCategory *cat = getCategory();
// BAP removed protected check to re-enable standard ops in untyped folders.
// Not sure what the right thing is to do here.
- if (!isCOFFolder() && cat /*&&
+ if (!isCOFFolder() && cat && cat->getPreferredType()!=LLFolderType::FT_OUTFIT /*&&
LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())*/)
{
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
@@ -2680,7 +2846,7 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
{
LLFloaterOpenObject::LLCatAndWear* cat_and_wear = (LLFloaterOpenObject::LLCatAndWear* )move_inv->mUserData;
LLViewerObject* object = gObjectList.findObject(move_inv->mObjectID);
- S32 option = LLNotification::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if(option == 0 && object)
{
@@ -2769,7 +2935,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
BOOL drop)
{
LLInventoryModel* model = getInventoryModel();
- if(!model) return FALSE;
+ if(!model || !inv_item) return FALSE;
// cannot drag into library
if(!isAgentInventory())
@@ -2847,9 +3013,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// everything in the active window so that we don't follow
// the selection to its new location (which is very
// annoying).
- if (LLFloaterInventory::getActiveInventory())
+ LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
+ if (active_panel)
{
- LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel();
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
if (active_panel && (panel != active_panel))
{
@@ -3032,6 +3198,22 @@ void LLTextureBridge::openItem()
}
}
+bool LLTextureBridge::canSaveTexture(void)
+{
+ const LLInventoryModel* model = getInventoryModel();
+ if(!model)
+ {
+ return false;
+ }
+
+ const LLViewerInventoryItem *item = model->getItem(mUUID);
+ if (item)
+ {
+ return item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
+ }
+ return false;
+}
+
void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
lldebugs << "LLTextureBridge::buildContextMenu()" << llendl;
@@ -3056,6 +3238,10 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Texture Separator"));
items.push_back(std::string("Save As"));
+ if (!canSaveTexture())
+ {
+ disabled_items.push_back(std::string("Save As"));
+ }
}
hide_context_entries(menu, items, disabled_items);
}
@@ -3253,7 +3439,7 @@ void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* mod
static bool open_landmark_callback(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotification::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLUUID asset_id = notification["payload"]["asset_id"].asUUID();
if (option == 0)
@@ -3283,7 +3469,7 @@ void LLLandmarkBridge::openItem()
// open_landmark(item);
LLSD payload;
payload["asset_id"] = item->getAssetUUID();
- LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload);
+ LLNotificationsUtil::add("TeleportFromLandmark", LLSD(), payload);
}
*/
}
@@ -3589,7 +3775,7 @@ std::string LLGestureBridge::getLabelSuffix() const
// virtual
void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
{
- if ("activate" == action)
+ if (isAddAction(action))
{
LLGestureManager::instance().activateGesture(mUUID);
@@ -3601,7 +3787,7 @@ void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode
gInventory.updateItem(item);
gInventory.notifyObservers();
}
- else if ("deactivate" == action)
+ else if (isRemoveAction(action))
{
LLGestureManager::instance().deactivateGesture(mUUID);
@@ -3658,19 +3844,25 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
- LLInventoryItem* item = getItem();
- if (item && item->getIsLinkType())
+ bool is_sidepanel = isInOutfitsSidePanel();
+
+ if (!is_sidepanel)
{
- items.push_back(std::string("Find Original"));
+ items.push_back(std::string("Open"));
+ items.push_back(std::string("Properties"));
}
- items.push_back(std::string("Open"));
- items.push_back(std::string("Properties"));
getClipboardEntries(true, items, disabled_items, flags);
items.push_back(std::string("Gesture Separator"));
- items.push_back(std::string("Activate"));
- items.push_back(std::string("Deactivate"));
+ if (LLGestureManager::instance().isGestureActive(getUUID()))
+ {
+ items.push_back(std::string("Deactivate"));
+ }
+ else
+ {
+ items.push_back(std::string("Activate"));
+ }
}
hide_context_entries(menu, items, disabled_items);
}
@@ -3772,14 +3964,6 @@ LLItemBridge(inventory, uuid), mInvType(type)
mIsMultiObject = ( flags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) ? TRUE: FALSE;
}
-BOOL LLObjectBridge::isItemRemovable()
-{
- LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
- if(!avatar) return FALSE;
- if(avatar->isWearingAttachment(mUUID)) return FALSE;
- return LLInvFVBridge::isItemRemovable();
-}
-
LLUIImagePtr LLObjectBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject );
@@ -3799,7 +3983,7 @@ LLInventoryObject* LLObjectBridge::getObject() const
// virtual
void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
{
- if ("attach" == action)
+ if (isAddAction(action))
{
LLUUID object_id = mUUID;
LLViewerInventoryItem* item;
@@ -3822,7 +4006,7 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model
}
gFocusMgr.setKeyboardFocus(NULL);
}
- else if ("detach" == action)
+ else if (isRemoveAction(action))
{
LLInventoryItem* item = gInventory.getItem(mUUID);
if(item)
@@ -3923,7 +4107,7 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
#if !ENABLE_MULTIATTACHMENTS
if (attachment && attachment->getNumObjects() > 0)
{
- LLNotifications::instance().add("ReplaceAttachment", LLSD(), payload, confirm_replace_attachment_rez);
+ LLNotificationsUtil::add("ReplaceAttachment", LLSD(), payload, confirm_replace_attachment_rez);
}
else
#endif
@@ -3940,11 +4124,11 @@ bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& respon
{
LLSD args;
args["MAX_ATTACHMENTS"] = llformat("%d", MAX_AGENT_ATTACHMENTS);
- LLNotifications::instance().add("MaxAttachmentsOnOutfit", args);
+ LLNotificationsUtil::add("MaxAttachmentsOnOutfit", args);
return false;
}
- S32 option = LLNotification::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0/*YES*/)
{
LLViewerInventoryItem* itemp = gInventory.getItem(notification["payload"]["item_id"].asUUID());
@@ -3990,18 +4174,18 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
- LLInventoryItem* item = getItem();
- if (item && item->getIsLinkType())
+ bool is_sidepanel = isInOutfitsSidePanel();
+
+ if (!is_sidepanel)
{
- items.push_back(std::string("Find Original"));
+ items.push_back(std::string("Properties"));
}
- items.push_back(std::string("Properties"));
-
getClipboardEntries(true, items, disabled_items, flags);
LLObjectBridge::sContextMenuItemID = mUUID;
+ LLInventoryItem *item = getItem();
if(item)
{
LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
@@ -4015,7 +4199,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Detach From Yourself"));
}
else
- if( !isInTrash() && !isLinkedObjectInTrash() )
+ if( !isInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing())
{
items.push_back(std::string("Attach Separator"));
items.push_back(std::string("Object Wear"));
@@ -4235,32 +4419,37 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
{
for(i = 0; i < wearable_count; ++i)
{
- if( gAgentWearables.isWearingItem (item_array.get(i)->getUUID()) )
+ LLViewerInventoryItem *item = item_array.get(i);
+ if (item->getType() == LLAssetType::AT_BODYPART)
+ continue;
+ if (gAgent.isTeen() && item->isWearableType() &&
+ (item->getWearableType() == WT_UNDERPANTS || item->getWearableType() == WT_UNDERSHIRT))
+ continue;
+ if( gAgentWearables.isWearingItem (item->getLinkedUUID()) )
{
- LLWearableList::instance().getAsset(item_array.get(i)->getAssetUUID(),
- item_array.get(i)->getName(),
- item_array.get(i)->getType(),
+ LLWearableList::instance().getAsset(item->getAssetUUID(),
+ item->getName(),
+ item->getType(),
LLWearableBridge::onRemoveFromAvatarArrived,
- new OnRemoveStruct(item_array.get(i)->getUUID()));
-
+ new OnRemoveStruct(item->getLinkedUUID()));
}
}
}
-
if (obj_count > 0)
{
for(i = 0; i < obj_count; ++i)
{
+ LLViewerInventoryItem *obj_item = obj_item_array.get(i);
gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
gMessageSystem->nextBlockFast(_PREHASH_ObjectData );
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item_array.get(i)->getUUID() );
+ gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item->getLinkedUUID() );
gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
// this object might have been selected, so let the selection manager know it's gone now
- LLViewerObject *found_obj = gObjectList.findObject( obj_item_array.get(i)->getUUID());
+ LLViewerObject *found_obj = gObjectList.findObject( obj_item->getLinkedUUID());
if (found_obj)
{
LLSelectMgr::getInstance()->remove(found_obj);
@@ -4272,10 +4461,11 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
{
for(i = 0; i < gest_count; ++i)
{
- if ( LLGestureManager::instance().isGestureActive( gest_item_array.get(i)->getUUID()) )
+ LLViewerInventoryItem *gest_item = gest_item_array.get(i);
+ if ( LLGestureManager::instance().isGestureActive( gest_item->getLinkedUUID()) )
{
- LLGestureManager::instance().deactivateGesture( gest_item_array.get(i)->getUUID() );
- gInventory.updateItem( gest_item_array.get(i) );
+ LLGestureManager::instance().deactivateGesture( gest_item->getLinkedUUID() );
+ gInventory.updateItem( gest_item );
gInventory.notifyObservers();
}
@@ -4293,12 +4483,6 @@ BOOL LLWearableBridge::renameItem(const std::string& new_name)
return LLItemBridge::renameItem(new_name);
}
-BOOL LLWearableBridge::isItemRemovable()
-{
- if (gAgentWearables.isWearingItem(mUUID)) return FALSE;
- return LLInvFVBridge::isItemRemovable();
-}
-
std::string LLWearableBridge::getLabelSuffix() const
{
if( gAgentWearables.isWearingItem( mUUID ) )
@@ -4320,7 +4504,7 @@ LLUIImagePtr LLWearableBridge::getIcon() const
// virtual
void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
{
- if ("wear" == action)
+ if (isAddAction(action))
{
wearOnAvatar();
}
@@ -4333,7 +4517,7 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod
editOnAvatar();
return;
}
- else if ("take_off" == action)
+ else if (isRemoveAction(action))
{
if(gAgentWearables.isWearingItem(mUUID))
{
@@ -4362,7 +4546,7 @@ void LLWearableBridge::openItem()
/*
if( isInTrash() )
{
- LLNotifications::instance().add("CannotWearTrash");
+ LLNotificationsUtil::add("CannotWearTrash");
}
else if(isAgentInventory())
{
@@ -4391,7 +4575,7 @@ void LLWearableBridge::openItem()
{
// *TODO: We should fetch the item details, and then do
// the operation above.
- LLNotifications::instance().add("CannotWearInfoNotComplete");
+ LLNotificationsUtil::add("CannotWearInfoNotComplete");
}
}
*/
@@ -4414,33 +4598,36 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{ // FWIW, it looks like SUPPRESS_OPEN_ITEM is not set anywhere
- BOOL no_open = ((flags & SUPPRESS_OPEN_ITEM) == SUPPRESS_OPEN_ITEM);
+ BOOL can_open = ((flags & SUPPRESS_OPEN_ITEM) != SUPPRESS_OPEN_ITEM);
// If we have clothing, don't add "Open" as it's the same action as "Wear" SL-18976
LLViewerInventoryItem* item = getItem();
- if( !no_open && item )
+ if (can_open && item)
{
- no_open = (item->getType() == LLAssetType::AT_CLOTHING) ||
- (item->getType() == LLAssetType::AT_BODYPART);
+ can_open = (item->getType() != LLAssetType::AT_CLOTHING) &&
+ (item->getType() != LLAssetType::AT_BODYPART);
}
- if (!no_open)
+ if (isLinkedObjectMissing())
{
- items.push_back(std::string("Open"));
+ can_open = FALSE;
}
- if (item && item->getIsLinkType())
+ bool is_sidepanel = isInOutfitsSidePanel();
+
+ if (can_open && !is_sidepanel)
{
- items.push_back(std::string("Find Original"));
+ items.push_back(std::string("Open"));
}
- items.push_back(std::string("Properties"));
+ if (!is_sidepanel)
+ {
+ items.push_back(std::string("Properties"));
+ }
getClipboardEntries(true, items, disabled_items, flags);
items.push_back(std::string("Wearable Separator"));
- items.push_back(std::string("Wearable Wear"));
- items.push_back(std::string("Wearable Add"));
items.push_back(std::string("Wearable Edit"));
if ((flags & FIRST_SELECTED_ITEM) == 0)
@@ -4448,7 +4635,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
disabled_items.push_back(std::string("Wearable Edit"));
}
// Don't allow items to be worn if their baseobj is in the trash.
- if (isLinkedObjectInTrash())
+ if (isLinkedObjectInTrash() || isLinkedObjectMissing())
{
disabled_items.push_back(std::string("Wearable Wear"));
disabled_items.push_back(std::string("Wearable Add"));
@@ -4470,6 +4657,8 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Wearable Wear"));
+ items.push_back(std::string("Wearable Add"));
disabled_items.push_back(std::string("Take Off"));
}
break;
@@ -4510,7 +4699,7 @@ void LLWearableBridge::wearOnAvatar()
// destroy clothing items.
if (!gAgentWearables.areWearablesLoaded())
{
- LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
+ LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded");
return;
}
@@ -4541,7 +4730,7 @@ void LLWearableBridge::wearAddOnAvatar()
// destroy clothing items.
if (!gAgentWearables.areWearablesLoaded())
{
- LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
+ LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded");
return;
}
@@ -4639,7 +4828,8 @@ void LLWearableBridge::onEditOnAvatar(void* user_data)
void LLWearableBridge::editOnAvatar()
{
- const LLWearable* wearable = gAgentWearables.getWearableFromItemID(mUUID);
+ LLUUID linked_id = gInventory.getLinkedItemID(mUUID);
+ const LLWearable* wearable = gAgentWearables.getWearableFromItemID(linked_id);
if( wearable )
{
// Set the tab to the right wearable.
@@ -4842,7 +5032,7 @@ void LLLandmarkBridgeAction::doIt()
// but warns you the first time.
LLSD payload;
payload["asset_id"] = item->getAssetUUID();
- LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload);
+ LLNotificationsUtil::add("TeleportFromLandmark", LLSD(), payload);
}
LLInvFVBridgeAction::doIt();
@@ -4942,7 +5132,7 @@ void LLWearableBridgeAction::wearOnAvatar()
// destroy clothing items.
if (!gAgentWearables.areWearablesLoaded())
{
- LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
+ LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded");
return;
}
@@ -4972,7 +5162,7 @@ void LLWearableBridgeAction::doIt()
{
if(isInTrash())
{
- LLNotifications::instance().add("CannotWearTrash");
+ LLNotificationsUtil::add("CannotWearTrash");
}
else if(isAgentInventory())
{
@@ -5001,7 +5191,7 @@ void LLWearableBridgeAction::doIt()
{
// *TODO: We should fetch the item details, and then do
// the operation above.
- LLNotifications::instance().add("CannotWearInfoNotComplete");
+ LLNotificationsUtil::add("CannotWearInfoNotComplete");
}
}
@@ -5020,7 +5210,7 @@ LLUIImagePtr LLLinkItemBridge::getIcon() const
{
if (LLViewerInventoryItem *item = getItem())
{
- return get_item_icon(item->getActualType(), LLInventoryType::IT_NONE, 0, FALSE);
+ return get_item_icon(item->getActualType(), item->getInventoryType(), 0, FALSE);
}
return get_item_icon(LLAssetType::AT_LINK, LLInventoryType::IT_NONE, 0, FALSE);
}
@@ -5032,6 +5222,9 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
std::vector<std::string> items;
std::vector<std::string> disabled_items;
+ items.push_back(std::string("Find Original"));
+ disabled_items.push_back(std::string("Find Original"));
+
if(isInTrash())
{
items.push_back(std::string("Purge Item"));
@@ -5044,6 +5237,7 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Properties"));
items.push_back(std::string("Delete"));
if (!isItemRemovable())
{