summaryrefslogtreecommitdiff
path: root/indra/newview/llinventoryfunctions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llinventoryfunctions.cpp')
-rw-r--r--indra/newview/llinventoryfunctions.cpp331
1 files changed, 316 insertions, 15 deletions
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index db3b968730..f74a239fd3 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -47,17 +47,19 @@
#include "llappviewer.h"
//#include "llfirstuse.h"
#include "llfloaterinventory.h"
+#include "llfloatersidepanelcontainer.h"
#include "llfocusmgr.h"
#include "llfolderview.h"
#include "llgesturemgr.h"
#include "lliconctrl.h"
#include "llimview.h"
#include "llinventorybridge.h"
-#include "llinventoryclipboard.h"
#include "llinventorymodel.h"
#include "llinventorypanel.h"
#include "lllineeditor.h"
+#include "llmarketplacenotifications.h"
#include "llmenugl.h"
+#include "llnotificationsutil.h"
#include "llpanelmaininventory.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
@@ -69,7 +71,6 @@
#include "llscrollbar.h"
#include "llscrollcontainer.h"
#include "llselectmgr.h"
-#include "llsidetray.h"
#include "llsidepanelinventory.h"
#include "lltabcontainer.h"
#include "lltooldraganddrop.h"
@@ -81,6 +82,8 @@
#include "llvoavatarself.h"
#include "llwearablelist.h"
+#include <boost/foreach.hpp>
+
BOOL LLInventoryState::sWearNewClothing = FALSE;
LLUUID LLInventoryState::sWearNewClothingTransactionID;
@@ -157,6 +160,31 @@ void change_category_parent(LLInventoryModel* model,
model->notifyObservers();
}
+// Move the item to the trash. Works for folders and objects.
+// Caution: This method assumes that the item is removable!
+void remove_item(LLInventoryModel* model, const LLUUID& id)
+{
+ LLViewerInventoryItem* item = model->getItem(id);
+ if (!item)
+ return;
+
+ if (item->getType() == LLAssetType::AT_CATEGORY)
+ {
+ // Call the general helper function to delete a folder
+ remove_category(model, id);
+ }
+ else
+ {
+ // Get the trash UUID
+ LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false);
+ if (trash_id.notNull())
+ {
+ // Finally, move the item to the trash
+ change_item_parent(model, item, trash_id, true);
+ }
+ }
+}
+
void remove_category(LLInventoryModel* model, const LLUUID& cat_id)
{
if (!model || !get_is_category_removable(model, cat_id))
@@ -210,6 +238,101 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s
model->notifyObservers();
}
+void copy_inventory_category(LLInventoryModel* model,
+ LLViewerInventoryCategory* cat,
+ const LLUUID& parent_id,
+ const LLUUID& root_copy_id)
+{
+ // Create the initial folder
+ LLUUID new_cat_uuid = gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName());
+ model->notifyObservers();
+
+ // We need to exclude the initial root of the copy to avoid recursively copying the copy, etc...
+ LLUUID root_id = (root_copy_id.isNull() ? new_cat_uuid : root_copy_id);
+
+ // Get the content of the folder
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array);
+
+ // Copy all the items
+ LLInventoryModel::item_array_t item_array_copy = *item_array;
+ for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
+ {
+ LLInventoryItem* item = *iter;
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ new_cat_uuid,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+
+ // Copy all the folders
+ LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
+ for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
+ {
+ LLViewerInventoryCategory* category = *iter;
+ if (category->getUUID() != root_id)
+ {
+ copy_inventory_category(model, category, new_cat_uuid, root_id);
+ }
+ }
+}
+
+class LLInventoryCollectAllItems : public LLInventoryCollectFunctor
+{
+public:
+ virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+ {
+ return true;
+ }
+};
+
+BOOL get_is_parent_to_worn_item(const LLUUID& id)
+{
+ const LLViewerInventoryCategory* cat = gInventory.getCategory(id);
+ if (!cat)
+ {
+ return FALSE;
+ }
+
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLInventoryCollectAllItems collect_all;
+ gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH, collect_all);
+
+ for (LLInventoryModel::item_array_t::const_iterator it = items.begin(); it != items.end(); ++it)
+ {
+ const LLViewerInventoryItem * const item = *it;
+
+ llassert(item->getIsLinkType());
+
+ LLUUID linked_id = item->getLinkedUUID();
+ const LLViewerInventoryItem * const linked_item = gInventory.getItem(linked_id);
+
+ if (linked_item)
+ {
+ LLUUID parent_id = linked_item->getParentUUID();
+
+ while (!parent_id.isNull())
+ {
+ LLInventoryCategory * parent_cat = gInventory.getCategory(parent_id);
+
+ if (cat == parent_cat)
+ {
+ return TRUE;
+ }
+
+ parent_id = parent_cat->getParentUUID();
+ }
+ }
+ }
+
+ return FALSE;
+}
+
BOOL get_is_item_worn(const LLUUID& id)
{
const LLViewerInventoryItem* item = gInventory.getItem(id);
@@ -406,22 +529,28 @@ BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)
void show_task_item_profile(const LLUUID& item_uuid, const LLUUID& object_id)
{
- LLSideTray::getInstance()->showPanel("sidepanel_inventory", LLSD().with("id", item_uuid).with("object", object_id));
+ LLFloaterSidePanelContainer::showPanel("inventory", LLSD().with("id", item_uuid).with("object", object_id));
}
void show_item_profile(const LLUUID& item_uuid)
{
LLUUID linked_uuid = gInventory.getLinkedItemID(item_uuid);
- LLSideTray::getInstance()->showPanel("sidepanel_inventory", LLSD().with("id", linked_uuid));
+ LLFloaterSidePanelContainer::showPanel("inventory", LLSD().with("id", linked_uuid));
}
void show_item_original(const LLUUID& item_uuid)
{
+ LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
+ if (!floater_inventory)
+ {
+ llwarns << "Could not find My Inventory floater" << llendl;
+ return;
+ }
+
//sidetray inventory panel
- LLSidepanelInventory *sidepanel_inventory =
- dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
+ LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
- bool reset_inventory_filter = !LLSideTray::getInstance()->isPanelActive("sidepanel_inventory");
+ bool reset_inventory_filter = !floater_inventory->isInVisibleChain();
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel();
if (!active_panel)
@@ -471,6 +600,178 @@ void show_item_original(const LLUUID& item_uuid)
}
}
+
+void open_outbox()
+{
+ LLFloaterReg::showInstance("outbox");
+}
+
+LLUUID create_folder_in_outbox_for_item(LLInventoryItem* item, const LLUUID& destFolderId, S32 operation_id)
+{
+ llassert(item);
+ llassert(destFolderId.notNull());
+
+ LLUUID created_folder_id = gInventory.createNewCategory(destFolderId, LLFolderType::FT_NONE, item->getName());
+ gInventory.notifyObservers();
+
+ LLNotificationsUtil::add("OutboxFolderCreated");
+
+ return created_folder_id;
+}
+
+void move_to_outbox_cb_action(const LLSD& payload)
+{
+ LLViewerInventoryItem * viitem = gInventory.getItem(payload["item_id"].asUUID());
+ LLUUID dest_folder_id = payload["dest_folder_id"].asUUID();
+
+ if (viitem)
+ {
+ // when moving item directly into outbox create folder with that name
+ if (dest_folder_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
+ {
+ S32 operation_id = payload["operation_id"].asInteger();
+ dest_folder_id = create_folder_in_outbox_for_item(viitem, dest_folder_id, operation_id);
+ }
+
+ LLUUID parent = viitem->getParentUUID();
+
+ change_item_parent(
+ &gInventory,
+ viitem,
+ dest_folder_id,
+ false);
+
+ LLUUID top_level_folder = payload["top_level_folder"].asUUID();
+
+ if (top_level_folder != LLUUID::null)
+ {
+ LLViewerInventoryCategory* category;
+
+ while (parent.notNull())
+ {
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(parent,cat_array,item_array);
+
+ LLUUID next_parent;
+
+ category = gInventory.getCategory(parent);
+
+ if (!category) break;
+
+ next_parent = category->getParentUUID();
+
+ if (cat_array->empty() && item_array->empty())
+ {
+ remove_category(&gInventory, parent);
+ }
+
+ if (parent == top_level_folder)
+ {
+ break;
+ }
+
+ parent = next_parent;
+ }
+ }
+
+ open_outbox();
+ }
+}
+
+void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder, S32 operation_id)
+{
+ // Collapse links directly to items/folders
+ LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item;
+ LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory();
+ if (linked_category != NULL)
+ {
+ copy_folder_to_outbox(linked_category, dest_folder, top_level_folder, operation_id);
+ }
+ else
+ {
+ LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem();
+ if (linked_item != NULL)
+ {
+ inv_item = (LLInventoryItem *) linked_item;
+ }
+
+ // Check for copy permissions
+ if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
+ {
+ // when moving item directly into outbox create folder with that name
+ if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
+ {
+ dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, operation_id);
+ }
+
+ copy_inventory_item(gAgent.getID(),
+ inv_item->getPermissions().getOwner(),
+ inv_item->getUUID(),
+ dest_folder,
+ inv_item->getName(),
+ LLPointer<LLInventoryCallback>(NULL));
+
+ open_outbox();
+ }
+ else
+ {
+ LLSD payload;
+ payload["item_id"] = inv_item->getUUID();
+ payload["dest_folder_id"] = dest_folder;
+ payload["top_level_folder"] = top_level_folder;
+ payload["operation_id"] = operation_id;
+
+ LLMarketplaceInventoryNotifications::addNoCopyNotification(payload, move_to_outbox_cb_action);
+ }
+ }
+}
+
+void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id)
+{
+ // when moving item directly into outbox create folder with that name
+ if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
+ {
+ dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, operation_id);
+ }
+
+ LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item;
+
+ change_item_parent(&gInventory,
+ viewer_inv_item,
+ dest_folder,
+ false);
+}
+
+void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id)
+{
+ LLUUID new_folder_id = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, inv_cat->getName());
+ gInventory.notifyObservers();
+
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(inv_cat->getUUID(),cat_array,item_array);
+
+ // copy the vector because otherwise the iterator won't be happy if we delete from it
+ LLInventoryModel::item_array_t item_array_copy = *item_array;
+
+ for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
+ {
+ LLInventoryItem* item = *iter;
+ copy_item_to_outbox(item, new_folder_id, top_level_folder, operation_id);
+ }
+
+ LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
+
+ for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
+ {
+ LLViewerInventoryCategory* category = *iter;
+ copy_folder_to_outbox(category, new_folder_id, top_level_folder, operation_id);
+ }
+
+ open_outbox();
+}
+
///----------------------------------------------------------------------------
/// LLInventoryCollectFunctor implementations
///----------------------------------------------------------------------------
@@ -758,20 +1059,24 @@ void LLSaveFolderState::setApply(BOOL apply)
void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER);
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
+ if(!bridge) return;
+
if(mApply)
{
// we're applying the open state
- LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
- if(!bridge) return;
LLUUID id(bridge->getUUID());
if(mOpenFolders.find(id) != mOpenFolders.end())
{
- folder->setOpen(TRUE);
+ if (!folder->isOpen())
+ {
+ folder->setOpen(TRUE);
+ }
}
else
{
// keep selected filter in its current state, this is less jarring to user
- if (!folder->isSelected())
+ if (!folder->isSelected() && folder->isOpen())
{
folder->setOpen(FALSE);
}
@@ -782,8 +1087,6 @@ void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
// we're recording state at this point
if(folder->isOpen())
{
- LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
- if(!bridge) return;
mOpenFolders.insert(bridge->getUUID());
}
}
@@ -819,7 +1122,6 @@ void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
{
item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
- item->getRoot()->scrollToShowSelection();
mItemSelected = TRUE;
}
}
@@ -833,7 +1135,6 @@ void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
{
folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
- folder->getRoot()->scrollToShowSelection();
mItemSelected = TRUE;
}
}