diff options
Diffstat (limited to 'indra/newview/llinventoryfunctions.cpp')
-rw-r--r-- | indra/newview/llinventoryfunctions.cpp | 331 |
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; } } |