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.cpp301
1 files changed, 169 insertions, 132 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 26a8a707b8..3fc2cbecbe 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -190,12 +190,7 @@ BOOL LLInvFVBridge::isItemRemovable()
{
return TRUE;
}
- if (gAgentWearables.isWearingItem(mUUID))
- {
- return FALSE;
- }
- const LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
- if (avatar && avatar->isWearingAttachment(mUUID))
+ if (get_is_item_worn(mUUID))
{
return FALSE;
}
@@ -506,41 +501,6 @@ 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,
@@ -552,7 +512,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
if (is_sidepanel)
{
// Sidepanel includes restricted menu.
- if (obj && obj->getIsLinkType() && !isWornLink(mUUID))
+ if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID))
{
items.push_back(std::string("Remove Link"));
}
@@ -606,15 +566,18 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Paste"));
}
- items.push_back(std::string("Paste As Link"));
- if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0)
+ if (gAgent.isGodlike())
{
- disabled_items.push_back(std::string("Paste As Link"));
+ items.push_back(std::string("Paste As Link"));
+ if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Paste As Link"));
+ }
}
items.push_back(std::string("Paste Separator"));
- if (obj && obj->getIsLinkType() && !isWornLink(mUUID))
+ if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID))
{
items.push_back(std::string("Remove Link"));
}
@@ -973,7 +936,7 @@ bool LLInvFVBridge::isInOutfitsSidePanel() const
dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
if (!outfit_panel)
return false;
- return outfit_panel->isAccordionPanel(my_panel);
+ return outfit_panel->isTabPanel(my_panel);
}
// +=================================================+
@@ -1196,7 +1159,7 @@ LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const
{
U8 font = LLFontGL::NORMAL;
- if( gAgentWearables.isWearingItem( mUUID ) )
+ if (get_is_item_worn(mUUID))
{
// llinfos << "BOLD" << llendl;
font |= LLFontGL::BOLD;
@@ -1339,29 +1302,33 @@ BOOL LLItemBridge::isItemCopyable() const
LLViewerInventoryItem* item = getItem();
if (item)
{
- // can't copy worn objects. DEV-15183
- LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
- if( !avatarp )
+ // Can't copy worn objects. DEV-15183
+ if(get_is_item_worn(mUUID))
{
return FALSE;
}
- if(avatarp->isWearingAttachment(mUUID))
+ // You can never copy a link.
+ if (item->getIsLinkType())
{
return FALSE;
}
- // All items can be copied, not all can be pasted.
- // The only time an item can't be copied is if it's a link
- // return (item->getPermissions().allowCopyBy(gAgent.getID()));
- if (item->getIsLinkType())
+ if (gAgent.isGodlike())
{
- return FALSE;
+ // All items can be copied in god mode since you can
+ // at least paste-as-link the item, though you
+ // still may not be able paste the item.
+ return TRUE;
+ }
+ else
+ {
+ return (item->getPermissions().allowCopyBy(gAgent.getID()));
}
- return TRUE;
}
return FALSE;
}
+
BOOL LLItemBridge::copyToClipboard() const
{
if(isItemCopyable())
@@ -1471,13 +1438,11 @@ BOOL LLFolderBridge::isItemRemovable()
{
return FALSE;
}
- // Allow protected types to be removed, but issue a warning.
- /*
+
if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
{
return FALSE;
}
- */
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
@@ -1680,23 +1645,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
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() ) )
- {
- is_movable = FALSE; // It's generally movable, but not into the trash!
- break;
- }
- }
- else
- if( item->getType() == LLAssetType::AT_OBJECT )
+ if (get_is_item_worn(item->getUUID()))
{
- if( avatar->isWearingAttachment( item->getUUID() ) )
- {
- is_movable = FALSE; // It's generally movable, but not into the trash!
- break;
- }
+ is_movable = FALSE;
+ break; // It's generally movable, but not into the trash!
}
}
}
@@ -2186,6 +2138,12 @@ void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model
restoreItem();
return;
}
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ else if ("delete_system_folder" == action)
+ {
+ removeSystemFolder();
+ }
+#endif
}
void LLFolderBridge::openItem()
@@ -2309,13 +2267,27 @@ BOOL LLFolderBridge::removeItem()
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().forceResponse(params, 0);
+ return TRUE;
+}
+
+
+BOOL LLFolderBridge::removeSystemFolder()
+{
+ const LLViewerInventoryCategory *cat = getCategory();
+ if (!LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
{
- LLNotifications::instance().add(params);
+ return FALSE;
}
- else
+
+ LLSD payload;
+ LLSD args;
+ args["FOLDERNAME"] = cat->getName();
+
+ LLNotification::Params params("ConfirmDeleteProtectedCategory");
+ params.payload(payload).substitutions(args).functor.function(boost::bind(&LLFolderBridge::removeItemResponse, this, _1, _2));
{
- LLNotifications::instance().forceResponse(params, 0);
+ LLNotifications::instance().add(params);
}
return TRUE;
}
@@ -2484,6 +2456,13 @@ void LLFolderBridge::folderOptionsMenu()
}
}
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ if (LLFolderType::lookupIsProtectedType(type))
+ {
+ mItems.push_back(std::string("Delete System Folder"));
+ }
+#endif
+
// wearables related functionality for folders.
//is_wearable
LLFindWearables is_wearable;
@@ -2495,7 +2474,10 @@ void LLFolderBridge::folderOptionsMenu()
checkFolderForContentsOfType(model, is_object) ||
checkFolderForContentsOfType(model, is_gesture) )
{
- mItems.push_back(std::string("Folder Wearables Separator"));
+ if (!is_sidepanel)
+ {
+ mItems.push_back(std::string("Folder Wearables Separator"));
+ }
// Only enable add/replace outfit for non-default folders.
if (!is_default_folder)
@@ -2508,8 +2490,11 @@ 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"));
+ if (!areAnyContentsWorn(model))
+ {
+ disabled_items.push_back(std::string("Remove From Outfit"));
+ }
+ mItems.push_back(std::string("Outfit Separator"));
}
hide_context_entries(*mMenu, mItems, disabled_items);
@@ -2530,6 +2515,35 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv
return ((item_array.count() > 0) ? TRUE : FALSE );
}
+class LLFindWorn : public LLInventoryCollectFunctor
+{
+public:
+ LLFindWorn() {}
+ virtual ~LLFindWorn() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item)
+ {
+ if (item && get_is_item_worn(item->getUUID()))
+ {
+ return TRUE;
+ }
+ return FALSE;
+ }
+};
+
+BOOL LLFolderBridge::areAnyContentsWorn(LLInventoryModel* model) const
+{
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ LLFindWorn is_worn;
+ model->collectDescendentsIf(mUUID,
+ cat_array,
+ item_array,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_worn);
+ return (item_array.size() > 0);
+}
+
// Flags unused
void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
@@ -2652,6 +2666,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
mItems.push_back(std::string("--no options--"));
mDisabledItems.push_back(std::string("--no options--"));
}
+
+ // Preemptively disable system folder removal if more than one item selected.
+ if ((flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ mDisabledItems.push_back(std::string("Delete System Folder"));
+ }
+
hide_context_entries(menu, mItems, mDisabledItems);
}
@@ -2901,6 +2922,9 @@ void saveItemsOrder(LLInventoryModel::item_array_t& items)
item->updateServer(FALSE);
gInventory.updateItem(item);
+
+ // Tell the parent folder to refresh its sort order.
+ gInventory.addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
}
gInventory.notifyObservers();
@@ -2922,6 +2946,27 @@ LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_a
return result;
}
+// See also LLInventorySort where landmarks in the Favorites folder are sorted.
+class LLViewerInventoryItemSort
+{
+public:
+ bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
+ {
+ return a->getSortField() < b->getSortField();
+ }
+};
+
+/**
+ * Sorts passed items by LLViewerInventoryItem sort field.
+ *
+ * @param[in, out] items - array of items, not sorted.
+ */
+void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
+{
+ static LLViewerInventoryItemSort sort_functor;
+ std::sort(items.begin(), items.end(), sort_functor);
+}
+
void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId)
{
LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId);
@@ -2970,19 +3015,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
if(is_movable && move_is_into_trash)
{
- switch(inv_item->getType())
- {
- case LLAssetType::AT_CLOTHING:
- case LLAssetType::AT_BODYPART:
- is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID());
- break;
-
- case LLAssetType::AT_OBJECT:
- is_movable = !avatar->isWearingAttachment(inv_item->getUUID());
- break;
- default:
- break;
- }
+ is_movable = inv_item->getIsLinkType() || !get_is_item_worn(inv_item->getUUID());
}
if ( is_movable )
@@ -2997,8 +3030,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
}
const LLUUID& favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- const LLUUID& landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
- const BOOL folder_allows_reorder = ((mUUID == landmarks_id) || (mUUID == favorites_id));
+ const BOOL folder_allows_reorder = (mUUID == favorites_id);
// we can move item inside a folder only if this folder is Favorites. See EXT-719
accept = is_movable && ((mUUID != inv_item->getParentUUID()) || folder_allows_reorder);
@@ -3013,7 +3045,7 @@ 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).
- LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
+ LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
if (active_panel)
{
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
@@ -3038,6 +3070,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLUUID srcItemId = inv_item->getUUID();
LLUUID destItemId = itemp->getListener()->getUUID();
+ // ensure items are sorted properly before changing order. EXT-3498
+ rearrange_item_order_by_sort_field(items);
+
// update order
updateItemsOrder(items, srcItemId, destItemId);
@@ -4050,8 +4085,7 @@ LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const
{
U8 font = LLFontGL::NORMAL;
- LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
- if( avatar && avatar->isWearingAttachment( mUUID ) )
+ if(get_is_item_worn( mUUID ) )
{
font |= LLFontGL::BOLD;
}
@@ -4067,9 +4101,9 @@ LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const
std::string LLObjectBridge::getLabelSuffix() const
{
- LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
- if( avatar && avatar->isWearingAttachment( mUUID ) )
+ if (get_is_item_worn(mUUID))
{
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
std::string attachment_point_name = avatar->getAttachedPointName(mUUID);
// e.g. "(worn on ...)" / "(attached to ...)"
@@ -4194,12 +4228,11 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
return;
}
- if( avatarp->isWearingAttachment( mUUID ) )
+ if( get_is_item_worn( mUUID ) )
{
items.push_back(std::string("Detach From Yourself"));
}
- else
- if( !isInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing())
+ else if (!isInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing())
{
items.push_back(std::string("Attach Separator"));
items.push_back(std::string("Object Wear"));
@@ -4425,7 +4458,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
if (gAgent.isTeen() && item->isWearableType() &&
(item->getWearableType() == WT_UNDERPANTS || item->getWearableType() == WT_UNDERSHIRT))
continue;
- if( gAgentWearables.isWearingItem (item->getLinkedUUID()) )
+ if (get_is_item_worn(item->getUUID()))
{
LLWearableList::instance().getAsset(item->getAssetUUID(),
item->getName(),
@@ -4441,18 +4474,21 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
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->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->getLinkedUUID());
- if (found_obj)
+ if (get_is_item_worn(obj_item->getUUID()))
{
- LLSelectMgr::getInstance()->remove(found_obj);
+ gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData );
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ 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->getLinkedUUID());
+ if (found_obj)
+ {
+ LLSelectMgr::getInstance()->remove(found_obj);
+ }
}
}
}
@@ -4462,7 +4498,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
for(i = 0; i < gest_count; ++i)
{
LLViewerInventoryItem *gest_item = gest_item_array.get(i);
- if ( LLGestureManager::instance().isGestureActive( gest_item->getLinkedUUID()) )
+ if (get_is_item_worn(gest_item->getUUID()))
{
LLGestureManager::instance().deactivateGesture( gest_item->getLinkedUUID() );
gInventory.updateItem( gest_item );
@@ -4476,7 +4512,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
BOOL LLWearableBridge::renameItem(const std::string& new_name)
{
- if( gAgentWearables.isWearingItem( mUUID ) )
+ if (get_is_item_worn(mUUID))
{
gAgentWearables.setWearableName( mUUID, new_name );
}
@@ -4485,7 +4521,7 @@ BOOL LLWearableBridge::renameItem(const std::string& new_name)
std::string LLWearableBridge::getLabelSuffix() const
{
- if( gAgentWearables.isWearingItem( mUUID ) )
+ if (get_is_item_worn(mUUID))
{
// e.g. "(worn)"
return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn");
@@ -4519,7 +4555,7 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod
}
else if (isRemoveAction(action))
{
- if(gAgentWearables.isWearingItem(mUUID))
+ if (get_is_item_worn(mUUID))
{
LLViewerInventoryItem* item = getItem();
if (item)
@@ -4550,7 +4586,7 @@ void LLWearableBridge::openItem()
}
else if(isAgentInventory())
{
- if( !gAgentWearables.isWearingItem( mUUID ) )
+ if( !get_is_item_worn( mUUID ) )
{
wearOnAvatar();
}
@@ -4650,7 +4686,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
case LLAssetType::AT_CLOTHING:
items.push_back(std::string("Take Off"));
case LLAssetType::AT_BODYPART:
- if (gAgentWearables.isWearingItem(item->getUUID()))
+ if (get_is_item_worn(item->getUUID()))
{
disabled_items.push_back(std::string("Wearable Wear"));
disabled_items.push_back(std::string("Wearable Add"));
@@ -4681,7 +4717,7 @@ BOOL LLWearableBridge::canWearOnAvatar(void* user_data)
LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem();
if(!item || !item->isComplete()) return FALSE;
}
- return (!gAgentWearables.isWearingItem(self->mUUID));
+ return (!get_is_item_worn(self->mUUID));
}
// Called from menus
@@ -4813,7 +4849,7 @@ BOOL LLWearableBridge::canEditOnAvatar(void* user_data)
LLWearableBridge* self = (LLWearableBridge*)user_data;
if(!self) return FALSE;
- return (gAgentWearables.isWearingItem(self->mUUID));
+ return (get_is_item_worn(self->mUUID));
}
// static
@@ -4850,7 +4886,7 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data)
LLWearableBridge* self = (LLWearableBridge*)user_data;
if( self && (LLAssetType::AT_BODYPART != self->mAssetType) )
{
- return gAgentWearables.isWearingItem( self->mUUID );
+ return get_is_item_worn( self->mUUID );
}
return FALSE;
}
@@ -4860,7 +4896,7 @@ void LLWearableBridge::onRemoveFromAvatar(void* user_data)
{
LLWearableBridge* self = (LLWearableBridge*)user_data;
if(!self) return;
- if(gAgentWearables.isWearingItem(self->mUUID))
+ if(get_is_item_worn(self->mUUID))
{
LLViewerInventoryItem* item = self->getItem();
if (item)
@@ -4883,7 +4919,7 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID);
if(wearable)
{
- if( gAgentWearables.isWearingItem( item_id ) )
+ if( get_is_item_worn( item_id ) )
{
EWearableType type = wearable->getType();
@@ -5093,8 +5129,9 @@ void LLAnimationBridgeAction::doIt()
//virtual
void LLObjectBridgeAction::doIt()
{
+ /*
LLFloaterReg::showInstance("properties", mUUID);
-
+ */
LLInvFVBridgeAction::doIt();
}
@@ -5166,7 +5203,7 @@ void LLWearableBridgeAction::doIt()
}
else if(isAgentInventory())
{
- if(!gAgentWearables.isWearingItem(mUUID))
+ if(!get_is_item_worn(mUUID))
{
wearOnAvatar();
}