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.cpp563
1 files changed, 296 insertions, 267 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index beeac86f94..7ce96a6ac1 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2,25 +2,31 @@
* @file llinventorybridge.cpp
* @brief Implementation of the Inventory-Folder-View-Bridge classes.
*
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
* 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
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
@@ -66,6 +72,7 @@
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llwearablelist.h"
+#include "llpaneloutfitsinventory.h"
typedef std::pair<LLUUID, LLUUID> two_uuids_t;
typedef std::list<two_uuids_t> two_uuids_list_t;
@@ -438,8 +445,7 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const
void hide_context_entries(LLMenuGL& menu,
const menuentry_vec_t &entries_to_show,
- const menuentry_vec_t &disabled_entries,
- BOOL append) // If append is TRUE, then new enabled entries
+ const menuentry_vec_t &disabled_entries)
{
const LLView::child_list_t *list = menu.getChildList();
@@ -447,15 +453,13 @@ void hide_context_entries(LLMenuGL& menu,
// if the first element is a separator, it will not be shown.
BOOL is_previous_entry_separator = TRUE;
- for (LLView::child_list_t::const_iterator itor = list->begin();
- itor != list->end();
- ++itor)
+ LLView::child_list_t::const_iterator itor;
+ for (itor = list->begin(); itor != list->end(); ++itor)
{
- LLView *menu_item = (*itor);
- std::string name = menu_item->getName();
+ std::string name = (*itor)->getName();
// descend into split menus:
- LLMenuItemBranchGL* branchp = dynamic_cast<LLMenuItemBranchGL*>(menu_item);
+ LLMenuItemBranchGL* branchp = dynamic_cast<LLMenuItemBranchGL*>(*itor);
if ((name == "More") && branchp)
{
hide_context_entries(*branchp->getBranch(), entries_to_show, disabled_entries);
@@ -476,7 +480,7 @@ void hide_context_entries(LLMenuGL& menu,
// between two separators).
if (found)
{
- const BOOL is_entry_separator = (dynamic_cast<LLMenuItemSeparatorGL *>(menu_item) != NULL);
+ const BOOL is_entry_separator = (dynamic_cast<LLMenuItemSeparatorGL *>(*itor) != NULL);
if (is_entry_separator && is_previous_entry_separator)
found = false;
is_previous_entry_separator = is_entry_separator;
@@ -484,27 +488,16 @@ void hide_context_entries(LLMenuGL& menu,
if (!found)
{
- if (!menu_item->getLastVisible())
- {
- menu_item->setVisible(FALSE);
- }
- menu_item->setEnabled(FALSE);
+ (*itor)->setVisible(FALSE);
}
else
{
- menu_item->setVisible(TRUE);
- // A bit of a hack so we can remember that some UI element explicitly set this to be visible
- // so that some other UI element from multi-select doesn't later set this invisible.
- menu_item->pushVisible(TRUE);
- if (append)
- {
- menu_item->setEnabled(TRUE);
- }
+ (*itor)->setVisible(TRUE);
for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2)
{
if (*itor2 == name)
{
- menu_item->setEnabled(FALSE);
+ (*itor)->setEnabled(FALSE);
}
}
}
@@ -518,6 +511,17 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
{
const LLInventoryObject *obj = getInventoryObject();
+ bool is_sidepanel = isInOutfitsSidePanel();
+ if (is_sidepanel)
+ {
+ // Sidepanel includes restricted menu.
+ if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID))
+ {
+ items.push_back(std::string("Remove Link"));
+ }
+ return;
+ }
+
if (obj)
{
if (obj->getIsLinkType())
@@ -944,10 +948,18 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
}
}
-BOOL LLInvFVBridge::canShare() const
+BOOL LLInvFVBridge::isInOutfitsSidePanel() const
{
- if (!isAgentInventory()) return FALSE;
+ 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->isTabPanel(my_panel);
+}
+BOOL LLInvFVBridge::canShare() const
+{
const LLInventoryModel* model = getInventoryModel();
if (!model) return FALSE;
@@ -959,10 +971,9 @@ BOOL LLInvFVBridge::canShare() const
return (BOOL)LLGiveInventory::isInventoryGiveAcceptable(item);
}
- // Categories can be given.
- if (model->getCategory(mUUID)) return TRUE;
-
- return FALSE;
+ // All categories can be given.
+ const LLViewerInventoryCategory* cat = model->getCategory(mUUID);
+ return (cat != NULL);
}
// +=================================================+
@@ -1441,7 +1452,7 @@ bool LLItemBridge::isRemoveAction(std::string action) const
// | LLFolderBridge |
// +=================================================+
-LLHandle<LLFolderBridge> LLFolderBridge::sSelf;
+LLFolderBridge* LLFolderBridge::sSelf=NULL;
// Can be moved to another folder
BOOL LLFolderBridge::isItemMovable() const
@@ -1621,70 +1632,84 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const
BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
BOOL drop)
{
+ // This should never happen, but if an inventory item is incorrectly parented,
+ // the UI will get confused and pass in a NULL.
+ if(!inv_cat) return FALSE;
LLInventoryModel* model = getInventoryModel();
+ if(!model) return FALSE;
- if (!inv_cat) return FALSE; // shouldn't happen, but in case item is incorrectly parented in which case inv_cat will be NULL
- if (!model) return FALSE;
if (!isAgentAvatarValid()) return FALSE;
- if (!isAgentInventory()) return FALSE; // cannot drag categories into library
+ // cannot drag categories into library
+ if(!isAgentInventory())
+ {
+ return FALSE;
+ }
// check to make sure source is agent inventory, and is represented there.
LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
- const BOOL is_agent_inventory = (model->getCategory(inv_cat->getUUID()) != NULL)
+ BOOL is_agent_inventory = (model->getCategory(inv_cat->getUUID()) != NULL)
&& (LLToolDragAndDrop::SOURCE_AGENT == source);
BOOL accept = FALSE;
- if (is_agent_inventory)
+ S32 i;
+ LLInventoryModel::cat_array_t descendent_categories;
+ LLInventoryModel::item_array_t descendent_items;
+ if(is_agent_inventory)
{
- const LLUUID &cat_id = inv_cat->getUUID();
- const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false);
- const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
-
- const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
- const BOOL move_is_into_outfit = getCategory() && (getCategory()->getPreferredType() == LLFolderType::FT_OUTFIT);
- const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
+ const LLUUID& cat_id = inv_cat->getUUID();
- //--------------------------------------------------------------------------------
- // Determine if folder can be moved.
- //
+ // Is the destination the trash?
+ const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ BOOL move_is_into_trash = (mUUID == trash_id)
+ || model->isObjectDescendentOf(mUUID, trash_id);
+ BOOL is_movable = (!LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()));
+ const LLUUID current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
+ BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
+ if (move_is_into_current_outfit || move_is_into_outfit)
+ {
+ // BAP - restrictions?
+ is_movable = true;
+ }
- BOOL is_movable = TRUE;
- if (LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
- is_movable = FALSE;
- if (move_is_into_outfit)
- is_movable = FALSE;
if (mUUID == gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE))
- is_movable = FALSE;
- LLInventoryModel::cat_array_t descendent_categories;
- LLInventoryModel::item_array_t descendent_items;
- gInventory.collectDescendents(cat_id, descendent_categories, descendent_items, FALSE);
- for (S32 i=0; i < descendent_categories.count(); ++i)
{
- LLInventoryCategory* category = descendent_categories[i];
- if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
- {
- // Can't move "special folders" (e.g. Textures Folder).
- is_movable = FALSE;
- break;
- }
+ is_movable = FALSE; // It's generally movable but not into Favorites folder. EXT-1604
}
- if (move_is_into_trash)
+
+ if( is_movable )
{
- for (S32 i=0; i < descendent_items.count(); ++i)
+ gInventory.collectDescendents( cat_id, descendent_categories, descendent_items, FALSE );
+
+ for( i = 0; i < descendent_categories.count(); i++ )
{
- LLInventoryItem* item = descendent_items[i];
- if (get_is_item_worn(item->getUUID()))
+ LLInventoryCategory* category = descendent_categories[i];
+ if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
{
+ // ...can't move "special folders" like Textures
is_movable = FALSE;
- break; // It's generally movable, but not into the trash.
+ break;
}
}
- }
- //
- //--------------------------------------------------------------------------------
+ if( is_movable )
+ {
+ if( move_is_into_trash )
+ {
+ for( i = 0; i < descendent_items.count(); i++ )
+ {
+ LLInventoryItem* item = descendent_items[i];
+ if (get_is_item_worn(item->getUUID()))
+ {
+ is_movable = FALSE;
+ break; // It's generally movable, but not into the trash!
+ }
+ }
+ }
+ }
+ }
accept = is_movable
&& (mUUID != cat_id) // Can't move a folder into itself
@@ -1695,7 +1720,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
// Look for any gestures and deactivate them
if (move_is_into_trash)
{
- for (S32 i=0; i < descendent_items.count(); i++)
+ for (i = 0; i < descendent_items.count(); i++)
{
LLInventoryItem* item = descendent_items[i];
if (item->getType() == LLAssetType::AT_GESTURE
@@ -2056,7 +2081,7 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask)
mContentsCount)
{
gInventory.removeObserver(this);
- LLAppearanceMgr::instance().wearInventoryCategory(category, FALSE, FALSE);
+ LLAppearanceMgr::instance().wearInventoryCategory(category, FALSE, TRUE);
delete this;
}
}
@@ -2385,11 +2410,8 @@ void LLFolderBridge::pasteLinkFromClipboard()
void LLFolderBridge::staticFolderOptionsMenu()
{
- LLFolderBridge* selfp = sSelf.get();
- if (selfp)
- {
- selfp->folderOptionsMenu();
- }
+ if (!sSelf) return;
+ sSelf->folderOptionsMenu();
}
void LLFolderBridge::folderOptionsMenu()
@@ -2402,19 +2424,23 @@ void LLFolderBridge::folderOptionsMenu()
const LLInventoryCategory* category = model->getCategory(mUUID);
if(!category) return;
- const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if (trash_id == mUUID) return;
- if (isItemInTrash()) return;
- if (!isAgentInventory()) return;
-
LLFolderType::EType type = category->getPreferredType();
const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
// BAP change once we're no longer treating regular categories as ensembles.
const bool is_ensemble = (type == LLFolderType::FT_NONE ||
LLFolderType::lookupIsEnsembleType(type));
+ // calling card related functionality for folders.
+
+ const bool is_sidepanel = isInOutfitsSidePanel();
+ if (is_sidepanel)
+ {
+ mItems.push_back("Rename");
+ addDeleteContextMenuOptions(mItems, disabled_items);
+ }
+
// Only enable calling-card related options for non-system folders.
- if (!is_system_folder)
+ if (!is_sidepanel && !is_system_folder)
{
LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
@@ -2443,7 +2469,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-system folders.
if (!is_system_folder)
@@ -2460,21 +2489,17 @@ void LLFolderBridge::folderOptionsMenu()
mItems.push_back(std::string("Wear As Ensemble"));
}
mItems.push_back(std::string("Remove From Outfit"));
- if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
+ if (!areAnyContentsWorn(model))
{
disabled_items.push_back(std::string("Remove From Outfit"));
}
mItems.push_back(std::string("Outfit Separator"));
}
- LLMenuGL* menup = dynamic_cast<LLMenuGL*>(mMenu.get());
- if (menup)
- {
- hide_context_entries(*menup, mItems, disabled_items, TRUE);
+ hide_context_entries(*mMenu, mItems, disabled_items);
- // Reposition the menu, in case we're adding items to an existing menu.
- menup->needsArrange();
- menup->arrangeAndClear();
- }
+ // 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)
@@ -2489,6 +2514,19 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv
return ((item_array.count() > 0) ? TRUE : 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)
{
@@ -2516,10 +2554,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
mDisabledItems.push_back(std::string("New Body Parts"));
}
- // clear out old menu and folder pointers
- mMenu.markDead();
- sSelf.markDead();
-
if(trash_id == mUUID)
{
// This is the trash.
@@ -2547,9 +2581,9 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
mItems.push_back(std::string("New Clothes"));
mItems.push_back(std::string("New Body Parts"));
-#if SUPPORT_ENSEMBLES
- // Changing folder types is an unfinished unsupported feature
+ // Changing folder types is just a debug feature; this is fairly unsupported
// and can lead to unexpected behavior if enabled.
+#if !LL_RELEASE_FOR_DOWNLOAD
mItems.push_back(std::string("Change Type"));
const LLViewerInventoryCategory *cat = getCategory();
if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
@@ -2595,6 +2629,36 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
mWearables=TRUE;
}
+
+ mMenu = &menu;
+ sSelf = this;
+
+
+ uuid_vec_t folders;
+ LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
+ if (category)
+ {
+ folders.push_back(category->getUUID());
+ }
+ LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE);
+ fetch->startFetch();
+ inc_busy_count();
+ if(fetch->isFinished())
+ {
+ // everything is already here - call done.
+ fetch->done();
+ }
+ else
+ {
+ // it's all on it's way - add an observer, and the inventory
+ // will call done for us when everything is here.
+ gInventory.addObserver(fetch);
+ }
+ }
+ else
+ {
+ 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.
@@ -2610,30 +2674,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
hide_context_entries(menu, mItems, mDisabledItems);
-
- // Add menu items that are dependent on the contents of the folder.
- uuid_vec_t folders;
- LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
- if (category)
- {
- folders.push_back(category->getUUID());
- }
-
- mMenu = menu.getHandle();
- sSelf = getHandle();
- LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE);
- fetch->startFetch();
- inc_busy_count();
- if(fetch->isFinished())
- {
- // everything is already here - call done.
- fetch->done();
- }
- else
- {
- // it's all on its way - add an observer, and the inventory will call done for us when everything is here.
- gInventory.addObserver(fetch);
- }
}
BOOL LLFolderBridge::hasChildren() const
@@ -2845,16 +2885,18 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
return false;
}
-// This is used both for testing whether an item can be dropped
-// into the folder, as well as performing the actual drop, depending
-// if drop == TRUE.
BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
BOOL drop)
{
LLInventoryModel* model = getInventoryModel();
-
if(!model || !inv_item) return FALSE;
- if(!isAgentInventory()) return FALSE; // cannot drag into library
+
+ // cannot drag into library
+ if(!isAgentInventory())
+ {
+ return FALSE;
+ }
+
if (!isAgentAvatarValid()) return FALSE;
LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
@@ -2862,23 +2904,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLViewerObject* object = NULL;
if(LLToolDragAndDrop::SOURCE_AGENT == source)
{
- const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false);
- const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
- const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false);
-
- const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
- const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
- const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
- const BOOL move_is_outof_current_outfit = LLAppearanceMgr::instance().getIsInCOF(inv_item->getUUID());
- const BOOL folder_allows_reorder = (mUUID == favorites_id);
-
- //--------------------------------------------------------------------------------
- // Determine if item can be moved.
- //
-
BOOL is_movable = TRUE;
-
- switch (inv_item->getActualType())
+ switch( inv_item->getActualType() )
{
case LLAssetType::AT_CATEGORY:
is_movable = !LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)inv_item)->getPreferredType());
@@ -2886,50 +2913,41 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
default:
break;
}
+
+ const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
+ const LLUUID current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
+ const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
+ const BOOL move_is_outof_current_outfit = LLAppearanceMgr::instance().getIsInCOF(inv_item->getUUID());
+
// Can't explicitly drag things out of the COF.
if (move_is_outof_current_outfit)
{
is_movable = FALSE;
}
- if (move_is_into_trash)
+
+ if(is_movable && move_is_into_trash)
{
- is_movable &= inv_item->getIsLinkType() || !get_is_item_worn(inv_item->getUUID());
+ is_movable = inv_item->getIsLinkType() || !get_is_item_worn(inv_item->getUUID());
}
- if (is_movable)
+
+ if ( is_movable )
{
// Don't allow creating duplicates in the Calling Card/Friends
// subfolders, see bug EXT-1599. Check is item direct descendent
// of target folder and forbid item's movement if it so.
// Note: isItemDirectDescendentOfCategory checks if
// passed category is in the Calling Card/Friends folder
- is_movable &= !LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(inv_item, getCategory());
- }
-
- //
- //--------------------------------------------------------------------------------
-
- //--------------------------------------------------------------------------------
- // Determine if item can be moved & dropped
- //
-
- accept = TRUE;
-
- if (!is_movable)
- accept = FALSE;
- if ((mUUID == inv_item->getParentUUID()) && !folder_allows_reorder)
- accept = FALSE;
- if (move_is_into_current_outfit || move_is_into_outfit)
- {
- if ((inv_item->getInventoryType() != LLInventoryType::IT_WEARABLE) &&
- (inv_item->getInventoryType() != LLInventoryType::IT_GESTURE) &&
- (inv_item->getInventoryType() != LLInventoryType::IT_OBJECT))
- accept = FALSE;
- }
- if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID()))
- {
- accept = FALSE;
+ is_movable = ! LLFriendCardsManager::instance()
+ .isObjDirectDescendentOfCategory (inv_item, getCategory());
}
+ const LLUUID& favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ 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);
if(accept && drop)
{
if (inv_item->getType() == LLAssetType::AT_GESTURE
@@ -2937,8 +2955,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
LLGestureMgr::instance().deactivateGesture(inv_item->getUUID());
}
- // If an item is being dragged between windows, unselect everything in the active window
- // so that we don't follow the selection to its new location (which is very annoying).
+ // If an item is being dragged between windows, unselect
+ // 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(FALSE);
if (active_panel)
{
@@ -2949,12 +2969,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
}
}
- //--------------------------------------------------------------------------------
- // Destination folder logic
- //
-
- // REORDER
- // (only reorder the item)
+ // if dragging from/into favorites folder only reorder items
if ((mUUID == inv_item->getParentUUID()) && folder_allows_reorder)
{
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
@@ -2966,10 +2981,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
gInventory.rearrangeFavoriteLandmarks(srcItemId, destItemId);
}
}
-
- // FAVORITES folder
- // (copy the item)
- else if (favorites_id == mUUID)
+ else if (favorites_id == mUUID) // if target is the favorites folder we use copy
{
// use callback to rearrange favorite landmarks after adding
// to have new one placed before target (on which it was dropped). See EXT-4312.
@@ -2989,50 +3001,38 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
std::string(),
cb);
}
- // CURRENT OUTFIT or OUTFIT folder
- // (link the item)
else if (move_is_into_current_outfit || move_is_into_outfit)
{
- if ((inv_item->getInventoryType() == LLInventoryType::IT_WEARABLE) ||
- (inv_item->getInventoryType() == LLInventoryType::IT_GESTURE) ||
- (inv_item->getInventoryType() == LLInventoryType::IT_OBJECT))
+ // BAP - should skip if dup.
+ if (move_is_into_current_outfit)
{
- // BAP - should skip if dup.
- if (move_is_into_current_outfit)
- {
- LLAppearanceMgr::instance().wearItemOnAvatar(inv_item->getUUID(), true, true);
- }
- else
- {
- LLPointer<LLInventoryCallback> cb = NULL;
- link_inventory_item(
- gAgent.getID(),
- inv_item->getLinkedUUID(),
- mUUID,
- inv_item->getName(),
- inv_item->getDescription(),
- LLAssetType::AT_LINK,
- cb);
- }
+ LLAppearanceMgr::instance().addCOFItemLink(inv_item);
+ }
+ else
+ {
+ LLPointer<LLInventoryCallback> cb = NULL;
+ link_inventory_item(
+ gAgent.getID(),
+ inv_item->getLinkedUUID(),
+ mUUID,
+ inv_item->getName(),
+ inv_item->getDescription(),
+ LLAssetType::AT_LINK,
+ cb);
}
}
- // NORMAL or TRASH folder
- // (move the item, restamp if into trash)
else
{
+ // restamp if the move is into the trash.
LLInvFVBridge::changeItemParent(
model,
(LLViewerInventoryItem*)inv_item,
mUUID,
move_is_into_trash);
}
-
- //
- //--------------------------------------------------------------------------------
-
}
}
- else if (LLToolDragAndDrop::SOURCE_WORLD == source)
+ else if(LLToolDragAndDrop::SOURCE_WORLD == source)
{
// Make sure the object exists. If we allowed dragging from
// anonymous objects, it would be possible to bypass
@@ -3050,7 +3050,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
BOOL is_move = FALSE;
if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID())
&& perm.allowTransferTo(gAgent.getID())))
- // || gAgent.isGodlike())
+// || gAgent.isGodlike())
{
accept = TRUE;
@@ -3776,9 +3776,13 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
disabled_items.push_back(std::string("Share"));
}
+ bool is_sidepanel = isInOutfitsSidePanel();
- addOpenRightClickMenuOption(items);
- items.push_back(std::string("Properties"));
+ if (!is_sidepanel)
+ {
+ addOpenRightClickMenuOption(items);
+ items.push_back(std::string("Properties"));
+ }
getClipboardEntries(true, items, disabled_items, flags);
@@ -4013,12 +4017,13 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
payload["attachment_point"] = attach_pt;
- if (!gSavedSettings.getBOOL("MultipleAttachments") &&
- (attachment && attachment->getNumObjects() > 0))
+#if !ENABLE_MULTIATTACHMENTS
+ if (attachment && attachment->getNumObjects() > 0)
{
LLNotificationsUtil::add("ReplaceAttachment", LLSD(), payload, confirm_replace_attachment_rez);
}
else
+#endif
{
LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/);
}
@@ -4041,10 +4046,6 @@ bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& respon
if (itemp)
{
- U8 attachment_pt = notification["payload"]["attachment_point"].asInteger();
- if (gSavedSettings.getBOOL("MultipleAttachments"))
- attachment_pt |= ATTACHMENT_ADD;
-
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -4053,6 +4054,10 @@ bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& respon
msg->nextBlockFast(_PREHASH_ObjectData);
msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
+ U8 attachment_pt = notification["payload"]["attachment_point"].asInteger();
+#if ENABLE_MULTIATTACHMENTS
+ attachment_pt |= ATTACHMENT_ADD;
+#endif
msg->addU8Fast(_PREHASH_AttachmentPt, attachment_pt);
pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
msg->addStringFast(_PREHASH_Name, itemp->getName());
@@ -4079,8 +4084,12 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
disabled_items.push_back(std::string("Share"));
}
+ bool is_sidepanel = isInOutfitsSidePanel();
- items.push_back(std::string("Properties"));
+ if (!is_sidepanel)
+ {
+ items.push_back(std::string("Properties"));
+ }
getClipboardEntries(true, items, disabled_items, flags);
@@ -4093,13 +4102,13 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
if( get_is_item_worn( mUUID ) )
{
- items.push_back(std::string("Wearable And Object Separator"));
+ items.push_back(std::string("Attach Separator"));
items.push_back(std::string("Detach From Yourself"));
}
else if (!isItemInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing() && !isCOFFolder())
{
- items.push_back(std::string("Wearable And Object Separator"));
- items.push_back(std::string("Wearable And Object Wear"));
+ items.push_back(std::string("Attach Separator"));
+ items.push_back(std::string("Object Wear"));
items.push_back(std::string("Attach To"));
items.push_back(std::string("Attach To HUD"));
// commented out for DEV-32347
@@ -4107,7 +4116,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
if (!gAgentAvatarp->canAttachMoreObjects())
{
- disabled_items.push_back(std::string("Wearable And Object Wear"));
+ disabled_items.push_back(std::string("Object Wear"));
disabled_items.push_back(std::string("Attach To"));
disabled_items.push_back(std::string("Attach To HUD"));
}
@@ -4136,7 +4145,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
LLSD cbparams;
cbparams["index"] = curiter->first;
- cbparams["label"] = p.name;
+ cbparams["label"] = attachment->getName();
p.on_click.function_name = "Inventory.AttachObject";
p.on_click.parameter = LLSD(attachment->getName());
p.on_enable.function_name = "Attachment.Label";
@@ -4429,27 +4438,30 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
can_open = FALSE;
}
+
items.push_back(std::string("Share"));
if (!canShare())
{
disabled_items.push_back(std::string("Share"));
}
+ bool is_sidepanel = isInOutfitsSidePanel();
- if (can_open)
+ if (can_open && !is_sidepanel)
{
addOpenRightClickMenuOption(items);
}
- else
+
+ if (!is_sidepanel)
{
- disabled_items.push_back(std::string("Open"));
- disabled_items.push_back(std::string("Open Original"));
+ items.push_back(std::string("Properties"));
}
- items.push_back(std::string("Properties"));
-
getClipboardEntries(true, items, disabled_items, flags);
- items.push_back(std::string("Wearable And Object Separator"));
+ if (!is_sidepanel)
+ {
+ items.push_back(std::string("Wearable Separator"));
+ }
items.push_back(std::string("Wearable Edit"));
@@ -4460,7 +4472,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// Don't allow items to be worn if their baseobj is in the trash.
if (isLinkedObjectInTrash() || isLinkedObjectMissing() || isCOFFolder())
{
- disabled_items.push_back(std::string("Wearable And Object Wear"));
+ disabled_items.push_back(std::string("Wearable Wear"));
disabled_items.push_back(std::string("Wearable Add"));
disabled_items.push_back(std::string("Wearable Edit"));
}
@@ -4476,15 +4488,14 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
case LLAssetType::AT_BODYPART:
if (get_is_item_worn(item->getUUID()))
{
- disabled_items.push_back(std::string("Wearable And Object Wear"));
+ disabled_items.push_back(std::string("Wearable Wear"));
disabled_items.push_back(std::string("Wearable Add"));
}
else
{
- items.push_back(std::string("Wearable And Object Wear"));
+ items.push_back(std::string("Wearable Wear"));
items.push_back(std::string("Wearable Add"));
disabled_items.push_back(std::string("Take Off"));
- disabled_items.push_back(std::string("Wearable Edit"));
}
break;
default:
@@ -4520,7 +4531,13 @@ void LLWearableBridge::onWearOnAvatar(void* user_data)
void LLWearableBridge::wearOnAvatar()
{
- // TODO: investigate wearables may not be loaded at this point EXT-8231
+ // Don't wear anything until initial wearables are loaded, can
+ // destroy clothing items.
+ if (!gAgentWearables.areWearablesLoaded())
+ {
+ LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded");
+ return;
+ }
LLViewerInventoryItem* item = getItem();
if(item)
@@ -4531,7 +4548,13 @@ void LLWearableBridge::wearOnAvatar()
void LLWearableBridge::wearAddOnAvatar()
{
- // TODO: investigate wearables may not be loaded at this point EXT-8231
+ // Don't wear anything until initial wearables are loaded, can
+ // destroy clothing items.
+ if (!gAgentWearables.areWearablesLoaded())
+ {
+ LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded");
+ return;
+ }
LLViewerInventoryItem* item = getItem();
if(item)
@@ -5089,7 +5112,13 @@ BOOL LLWearableBridgeAction::isAgentInventory() const
void LLWearableBridgeAction::wearOnAvatar()
{
- // TODO: investigate wearables may not be loaded at this point EXT-8231
+ // Don't wear anything until initial wearables are loaded, can
+ // destroy clothing items.
+ if (!gAgentWearables.areWearablesLoaded())
+ {
+ LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded");
+ return;
+ }
LLViewerInventoryItem* item = getItem();
if(item)
@@ -5155,12 +5184,12 @@ void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
menuentry_vec_t disabled_items, items = getMenuItems();
- items.erase(std::remove(items.begin(), items.end(), std::string("New Body Parts")), items.end());
- items.erase(std::remove(items.begin(), items.end(), std::string("New Clothes")), items.end());
- items.erase(std::remove(items.begin(), items.end(), std::string("New Note")), items.end());
- items.erase(std::remove(items.begin(), items.end(), std::string("New Gesture")), items.end());
- items.erase(std::remove(items.begin(), items.end(), std::string("New Script")), items.end());
- items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end());
+ items.erase(std::find(items.begin(), items.end(), std::string("New Folder")));
+ items.erase(std::find(items.begin(), items.end(), std::string("New Script")));
+ items.erase(std::find(items.begin(), items.end(), std::string("New Note")));
+ items.erase(std::find(items.begin(), items.end(), std::string("New Gesture")));
+ items.erase(std::find(items.begin(), items.end(), std::string("New Clothes")));
+ items.erase(std::find(items.begin(), items.end(), std::string("New Body Parts")));
hide_context_entries(menu, items, disabled_items);
}