From 6d789f59f8d8b3d195090f972f783727037790c2 Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Thu, 21 Jul 2011 17:07:05 -0700 Subject: Added handling for RemoveInventoryObjects message. Fixed handling of RemoveInventoryFolder --- indra/newview/llinventorymodel.cpp | 80 ++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 21 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 21d5de9a5b..50b5a2a5e5 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2168,6 +2168,9 @@ void LLInventoryModel::registerCallbacks(LLMessageSystem* msg) msg->setHandlerFuncFast(_PREHASH_RemoveInventoryFolder, processRemoveInventoryFolder, NULL); + msg->setHandlerFuncFast(_PREHASH_RemoveInventoryObjects, + processRemoveInventoryObjects, + NULL); //msg->setHandlerFuncFast(_PREHASH_ExchangeCallingCard, // processExchangeCallingcard, // NULL); @@ -2284,17 +2287,9 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account) } // static -void LLInventoryModel::processRemoveInventoryItem(LLMessageSystem* msg, void**) +void LLInventoryModel::removeInventoryItem(LLUUID agent_id, LLMessageSystem* msg) { - lldebugs << "LLInventoryModel::processRemoveInventoryItem()" << llendl; - LLUUID agent_id, item_id; - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); - if(agent_id != gAgent.getID()) - { - llwarns << "Got a RemoveInventoryItem for the wrong agent." - << llendl; - return; - } + LLUUID item_id; S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData); uuid_vec_t item_ids; update_map_t update; @@ -2316,6 +2311,21 @@ void LLInventoryModel::processRemoveInventoryItem(LLMessageSystem* msg, void**) { gInventory.deleteObject(*it); } +} + +// static +void LLInventoryModel::processRemoveInventoryItem(LLMessageSystem* msg, void**) +{ + lldebugs << "LLInventoryModel::processRemoveInventoryItem()" << llendl; + LLUUID agent_id, item_id; + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + if(agent_id != gAgent.getID()) + { + llwarns << "Got a RemoveInventoryItem for the wrong agent." + << llendl; + return; + } + LLInventoryModel::removeInventoryItem(agent_id, msg); gInventory.notifyObservers(); } @@ -2380,18 +2390,10 @@ void LLInventoryModel::processUpdateInventoryFolder(LLMessageSystem* msg, } // static -void LLInventoryModel::processRemoveInventoryFolder(LLMessageSystem* msg, - void**) +void LLInventoryModel::removeInventoryFolder(LLUUID agent_id, + LLMessageSystem* msg) { - lldebugs << "LLInventoryModel::processRemoveInventoryFolder()" << llendl; - LLUUID agent_id, folder_id; - msg->getUUIDFast(_PREHASH_FolderData, _PREHASH_AgentID, agent_id); - if(agent_id != gAgent.getID()) - { - llwarns << "Got a RemoveInventoryFolder for the wrong agent." - << llendl; - return; - } + LLUUID folder_id; uuid_vec_t folder_ids; update_map_t update; S32 count = msg->getNumberOfBlocksFast(_PREHASH_FolderData); @@ -2410,6 +2412,42 @@ void LLInventoryModel::processRemoveInventoryFolder(LLMessageSystem* msg, { gInventory.deleteObject(*it); } +} + +// static +void LLInventoryModel::processRemoveInventoryFolder(LLMessageSystem* msg, + void**) +{ + lldebugs << "LLInventoryModel::processRemoveInventoryFolder()" << llendl; + LLUUID agent_id, session_id; + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id); + if(agent_id != gAgent.getID()) + { + llwarns << "Got a RemoveInventoryFolder for the wrong agent." + << llendl; + return; + } + LLInventoryModel::removeInventoryFolder( agent_id, msg ); + gInventory.notifyObservers(); +} + +// static +void LLInventoryModel::processRemoveInventoryObjects(LLMessageSystem* msg, + void**) +{ + lldebugs << "LLInventoryModel::processRemoveInventoryObjects()" << llendl; + LLUUID agent_id, session_id; + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id); + if(agent_id != gAgent.getID()) + { + llwarns << "Got a RemoveInventoryObjects for the wrong agent." + << llendl; + return; + } + LLInventoryModel::removeInventoryFolder( agent_id, msg ); + LLInventoryModel::removeInventoryItem( agent_id, msg ); gInventory.notifyObservers(); } -- cgit v1.3 From 5e989213ad5869c21b3b595f3b4d63e31087f8d0 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Wed, 27 Jul 2011 16:24:08 -0700 Subject: CHOP-761 Items now disappear when the sim says so. --- indra/newview/llinventorymodel.cpp | 14 +++++++++----- indra/newview/llinventorymodel.h | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 50b5a2a5e5..e86c427ae2 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2287,18 +2287,21 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account) } // static -void LLInventoryModel::removeInventoryItem(LLUUID agent_id, LLMessageSystem* msg) +void LLInventoryModel::removeInventoryItem(LLUUID agent_id, LLMessageSystem* msg, const char* msg_label) { LLUUID item_id; - S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData); + S32 count = msg->getNumberOfBlocksFast(msg_label); + lldebugs << "Message has " << count << " item blocks" << llendl; uuid_vec_t item_ids; update_map_t update; for(S32 i = 0; i < count; ++i) { - msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_ItemID, item_id, i); + msg->getUUIDFast(msg_label, _PREHASH_ItemID, item_id, i); + lldebugs << "Checking for item-to-be-removed " << item_id << llendl; LLViewerInventoryItem* itemp = gInventory.getItem(item_id); if(itemp) { + lldebugs << "Item will be removed " << item_id << llendl; // we only bother with the delete and account if we found // the item - this is usually a back-up for permissions, // so frequently the item will already be gone. @@ -2309,6 +2312,7 @@ void LLInventoryModel::removeInventoryItem(LLUUID agent_id, LLMessageSystem* msg gInventory.accountForUpdate(update); for(uuid_vec_t::iterator it = item_ids.begin(); it != item_ids.end(); ++it) { + lldebugs << "Calling deleteObject " << *it << llendl; gInventory.deleteObject(*it); } } @@ -2325,7 +2329,7 @@ void LLInventoryModel::processRemoveInventoryItem(LLMessageSystem* msg, void**) << llendl; return; } - LLInventoryModel::removeInventoryItem(agent_id, msg); + LLInventoryModel::removeInventoryItem(agent_id, msg, _PREHASH_InventoryData); gInventory.notifyObservers(); } @@ -2447,7 +2451,7 @@ void LLInventoryModel::processRemoveInventoryObjects(LLMessageSystem* msg, return; } LLInventoryModel::removeInventoryFolder( agent_id, msg ); - LLInventoryModel::removeInventoryItem( agent_id, msg ); + LLInventoryModel::removeInventoryItem( agent_id, msg, _PREHASH_ItemData ); gInventory.notifyObservers(); } diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index c3775ac088..e0e81f1006 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -492,7 +492,7 @@ protected: //-------------------------------------------------------------------- public: static void processUpdateCreateInventoryItem(LLMessageSystem* msg, void**); - static void removeInventoryItem(LLUUID agent_id, LLMessageSystem* msg); + static void removeInventoryItem(LLUUID agent_id, LLMessageSystem* msg, const char* msg_label); static void processRemoveInventoryItem(LLMessageSystem* msg, void**); static void processUpdateInventoryFolder(LLMessageSystem* msg, void**); static void removeInventoryFolder(LLUUID agent_id, LLMessageSystem* msg); -- cgit v1.3 From 5676e4a62efd2636840395a0667e3df3a48f1989 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 21 Oct 2011 18:36:06 -0700 Subject: EXP-1439 : Modify DaD on the Favorite toolbar so that reordering visible landmarks don't send any back to the end of the list --- indra/newview/llfavoritesbar.cpp | 65 ++++++++++++++++++++++++-------------- indra/newview/llfavoritesbar.h | 2 +- indra/newview/llinventorymodel.cpp | 50 +++++++++++++++++++++-------- indra/newview/llinventorymodel.h | 11 +++++-- 4 files changed, 86 insertions(+), 42 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 98de418878..4e0c838454 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -504,20 +504,29 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y) { + // Identify the button hovered and the side to drop LLFavoriteLandmarkButton* dest = dynamic_cast(mLandingTab); + bool insert_before = true; + if (!dest) + { + insert_before = false; + dest = dynamic_cast(mLastTab); + } - // there is no need to handle if an item was dragged onto itself + // There is no need to handle if an item was dragged onto itself if (dest && dest->getLandmarkId() == mDragItemId) { return; } + // Insert the dragged item in the right place if (dest) { - LLInventoryModel::updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId()); + LLInventoryModel::updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId(), insert_before); } else { + // This can happen when the item list is empty mItems.push_back(gInventory.getItem(mDragItemId)); } @@ -534,22 +543,31 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y) void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y) { + // Identify the button hovered and the side to drop LLFavoriteLandmarkButton* dest = dynamic_cast(mLandingTab); - - // there is no need to handle if an item was dragged onto itself + bool insert_before = true; + if (!dest) + { + insert_before = false; + dest = dynamic_cast(mLastTab); + } + + // There is no need to handle if an item was dragged onto itself if (dest && dest->getLandmarkId() == mDragItemId) { return; } - + LLPointer viewer_item = new LLViewerInventoryItem(item); + // Insert the dragged item in the right place if (dest) { - insertBeforeItem(mItems, dest->getLandmarkId(), viewer_item); + insertItem(mItems, dest->getLandmarkId(), viewer_item, insert_before); } else { + // This can happen when the item list is empty mItems.push_back(viewer_item); } @@ -1337,29 +1355,28 @@ BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array return result; } -LLInventoryModel::item_array_t::iterator LLFavoritesBarCtrl::findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id) +void LLFavoritesBarCtrl::insertItem(LLInventoryModel::item_array_t& items, const LLUUID& dest_item_id, LLViewerInventoryItem* insertedItem, bool insert_before) { - LLInventoryModel::item_array_t::iterator result = items.end(); + // Get the iterator to the destination item + LLInventoryModel::item_array_t::iterator it_dest = LLInventoryModel::findItemIterByUUID(items, dest_item_id); + if (it_dest == items.end()) + return; - for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) + // Go to the next element if one wishes to insert after the dest element + if (!insert_before) { - if ((*i)->getUUID() == id) - { - result = i; - break; - } + ++it_dest; } - - return result; -} - -void LLFavoritesBarCtrl::insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, LLViewerInventoryItem* insertedItem) -{ - LLViewerInventoryItem* beforeItem = gInventory.getItem(beforeItemId); - llassert(beforeItem); - if (beforeItem) + + // Insert the source item in the right place + if (it_dest != items.end()) + { + items.insert(it_dest, insertedItem); + } + else { - items.insert(findItemByUUID(items, beforeItem->getUUID()), insertedItem); + // Append to the list if it_dest reached the end + items.push_back(insertedItem); } } diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 1b11d6196e..2f75b3bb0e 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -130,7 +130,7 @@ private: * inserts an item identified by insertedItemId BEFORE an item identified by beforeItemId. * this function assumes that an item identified by insertedItemId doesn't exist in items array. */ - void insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, LLViewerInventoryItem* insertedItem); + void insertItem(LLInventoryModel::item_array_t& items, const LLUUID& dest_item_id, LLViewerInventoryItem* insertedItem, bool insert_before); // finds an item by it's UUID in the items array LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index e86c427ae2..fb02fe0ff7 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2879,40 +2879,62 @@ BOOL LLInventoryModel::getIsFirstTimeInViewer2() return sFirstTimeInViewer2; } -static LLInventoryModel::item_array_t::iterator find_item_iter_by_uuid(LLInventoryModel::item_array_t& items, const LLUUID& id) +LLInventoryModel::item_array_t::iterator LLInventoryModel::findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id) { - LLInventoryModel::item_array_t::iterator result = items.end(); + LLInventoryModel::item_array_t::iterator curr_item = items.begin(); - for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) + while (curr_item != items.end()) { - if ((*i)->getUUID() == id) + if ((*curr_item)->getUUID() == id) { - result = i; break; } + ++curr_item; } - return result; + return curr_item; } // static // * @param[in, out] items - vector with items to be updated. It should be sorted in a right way // * before calling this method. // * @param src_item_id - LLUUID of inventory item to be moved in new position -// * @param dest_item_id - LLUUID of inventory item before which source item should be placed. -void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& src_item_id, const LLUUID& dest_item_id) +// * @param dest_item_id - LLUUID of inventory item before (or after) which source item should +// * be placed. +// * @param insert_before - bool indicating if src_item_id should be placed before or after +// * dest_item_id. Default is true. +void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& src_item_id, const LLUUID& dest_item_id, bool insert_before) { - LLInventoryModel::item_array_t::iterator it_src = find_item_iter_by_uuid(items, src_item_id); - LLInventoryModel::item_array_t::iterator it_dest = find_item_iter_by_uuid(items, dest_item_id); + LLInventoryModel::item_array_t::iterator it_src = findItemIterByUUID(items, src_item_id); + LLInventoryModel::item_array_t::iterator it_dest = findItemIterByUUID(items, dest_item_id); - if (it_src == items.end() || it_dest == items.end()) return; + // If one of the passed UUID is not in the item list, bail out + if ((it_src == items.end()) || (it_dest == items.end())) + return; + // Erase the source element from the list, keep a copy before erasing. LLViewerInventoryItem* src_item = *it_src; items.erase(it_src); - // target iterator can not be valid because the container was changed, so update it. - it_dest = find_item_iter_by_uuid(items, dest_item_id); - items.insert(it_dest, src_item); + // Note: Target iterator is not valid anymore because the container was changed, so update it. + it_dest = findItemIterByUUID(items, dest_item_id); + + // Go to the next element if one wishes to insert after the dest element + if (!insert_before) + { + ++it_dest; + } + + // Reinsert the source item in the right place + if (it_dest != items.end()) + { + items.insert(it_dest, src_item); + } + else + { + // Append to the list if it_dest reached the end + items.push_back(src_item); + } } //* @param[in] items vector of items in order to be saved. diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index e0e81f1006..a0fd455cf3 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -332,11 +332,16 @@ protected: //-------------------------------------------------------------------- public: // Changes items order by insertion of the item identified by src_item_id - // before the item identified by dest_item_id. Both items must exist in items array. - // Sorting is stored after method is finished. Only src_item_id is moved before dest_item_id. + // before (or after) the item identified by dest_item_id. Both items must exist in items array. + // Sorting is stored after method is finished. Only src_item_id is moved before (or after) dest_item_id. + // The parameter "insert_before" controls on which side of dest_item_id src_item_id gets rensinserted. static void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& src_item_id, - const LLUUID& dest_item_id); + const LLUUID& dest_item_id, + bool insert_before = true); + // Gets an iterator on an item vector knowing only the item UUID. + // Returns end() of the vector if not found. + static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id); // Saves current order of the passed items using inventory item sort field. // Resets 'items' sort fields and saves them on server. -- cgit v1.3 From 130d017085a4fa609970245a49b6d1a97de404b2 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Mon, 31 Oct 2011 12:01:10 -0700 Subject: * Updated inventory code to handle creation of the "Received Items" panel when the sim notifies the viewer that the folder is created. Unfortunately, the sim is not yet doing this so a relog is required to properly get this working. --- indra/newview/llinventorymodel.cpp | 10 +++++----- indra/newview/llsidepanelinventory.cpp | 21 ++++++--------------- 2 files changed, 11 insertions(+), 20 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index fb02fe0ff7..dc25689fa3 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2528,9 +2528,9 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) { LLPointer tfolder = new LLViewerInventoryCategory(gAgent.getID()); tfolder->unpackMessage(msg, _PREHASH_FolderData, i); - //llinfos << "unpaked folder '" << tfolder->getName() << "' (" - // << tfolder->getUUID() << ") in " << tfolder->getParentUUID() - // << llendl; + llinfos << "unpacked folder '" << tfolder->getName() << "' (" + << tfolder->getUUID() << ") in " << tfolder->getParentUUID() + << llendl; if(tfolder->getUUID().notNull()) { folders.push_back(tfolder); @@ -2570,8 +2570,8 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) { LLPointer titem = new LLViewerInventoryItem; titem->unpackMessage(msg, _PREHASH_ItemData, i); - //llinfos << "unpaked item '" << titem->getName() << "' in " - // << titem->getParentUUID() << llendl; + llinfos << "unpaked item '" << titem->getName() << "' in " + << titem->getParentUUID() << llendl; U32 callback_id; msg->getU32Fast(_PREHASH_ItemData, _PREHASH_CallbackID, callback_id); if(titem->getUUID().notNull()) diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index a24f6b24f0..91f8035556 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -113,21 +113,13 @@ public: switch (added_category_type) { case LLFolderType::FT_INBOX: + mSidepanelInventory->enableInbox(true); mSidepanelInventory->observeInboxModifications(added_category->getUUID()); break; case LLFolderType::FT_OUTBOX: + mSidepanelInventory->enableOutbox(true); mSidepanelInventory->observeOutboxModifications(added_category->getUUID()); break; - case LLFolderType::FT_NONE: - // HACK until sim update to properly create folder with system type - if (added_category->getName() == "Received Items") - { - mSidepanelInventory->observeInboxModifications(added_category->getUUID()); - } - else if (added_category->getName() == "Merchant Outbox") - { - mSidepanelInventory->observeOutboxModifications(added_category->getUUID()); - } default: break; } @@ -288,7 +280,6 @@ BOOL LLSidepanelInventory::postBuild() gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged)); gSavedSettings.getControl("InventoryDisplayOutbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayOutboxChanged)); - updateInboxOutbox(); // Update the verbs buttons state. updateVerbs(); @@ -316,20 +307,20 @@ void LLSidepanelInventory::updateInboxOutbox() // Set up observer for inbox changes, if we have an inbox already if (!inbox_id.isNull()) { - observeInboxModifications(inbox_id); - // Enable the display of the inbox if it exists enableInbox(true); + + observeInboxModifications(inbox_id); } #if ENABLE_MERCHANT_OUTBOX_PANEL // Set up observer for outbox changes, if we have an outbox already if (!outbox_id.isNull()) { - observeOutboxModifications(outbox_id); - // Enable the display of the outbox if it exists enableOutbox(true); + + observeOutboxModifications(outbox_id); } #endif } -- cgit v1.3 From 2e564abcd682c348de3a2d3a50ef58df545c143b Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Thu, 15 Dec 2011 14:26:42 -0800 Subject: EXP-1730 FIX EXP-1731 FIX EXP-1735 FIX EXP-1736 FIX EXP-1737 FIX EXP-1738 FIX EXP-1739 FIX * Users can no longer drag and drop items to the outbox from in world, notecards or the library. * Drag and drop now blocks the creation of hierarchies that are too deep, too many folders or contain too many items. * Settings now exist to specify drag and drop limitations to the outbox, named: InventoryOutboxMaxFolderDepth (4) InventoryOutboxMaxFolderCount (20) InventoryOutboxMaxItemCount (200) --- indra/newview/app_settings/settings.xml | 32 +++- indra/newview/llinventorybridge.cpp | 208 ++++++++++++++++++------- indra/newview/llinventorymodel.cpp | 32 ++++ indra/newview/llinventorymodel.h | 3 + indra/newview/skins/default/xui/en/strings.xml | 2 + 5 files changed, 214 insertions(+), 63 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index aa8ad53a3d..a6d859aab2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4260,16 +4260,38 @@ Value 0 - InventoryMarketplaceUserStatus + InventoryOutboxMaxFolderCount Comment - Marketplace user status. + Maximum number of subfolders allowed in a listing in the merchant outbox. Persist - 1 + 0 Type - String + U32 Value - + 20 + + InventoryOutboxMaxFolderDepth + + Comment + Maximum number of nested levels of subfolders allowed in a listing in the merchant outbox. + Persist + 0 + Type + U32 + Value + 4 + + InventoryOutboxMaxItemCount + + Comment + Maximum number of items allowed in a listing in the merchant outbox. + Persist + 0 + Type + U32 + Value + 200 InventorySortOrder diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d6b520d75e..26e7dab270 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1815,7 +1815,7 @@ static BOOL can_move_to_outbox(LLInventoryItem* inv_item, std::string& tooltip_m return false; } #endif - + return true; } @@ -1874,28 +1874,28 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, if (!isAgentAvatarValid()) return FALSE; if (!isAgentInventory()) return FALSE; // cannot drag categories into library + const LLUUID &cat_id = inv_cat->getUUID(); + const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); + const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + + const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); + const BOOL move_is_from_outbox = model->isObjectDescendentOf(cat_id, outbox_id); // 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) + const BOOL is_agent_inventory = (model->getCategory(cat_id) != NULL) && (LLToolDragAndDrop::SOURCE_AGENT == source); - const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); - const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); - BOOL accept = FALSE; if (is_agent_inventory) { - const LLUUID &cat_id = inv_cat->getUUID(); const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false); const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); - const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, 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_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id); - const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); - const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_cat->getUUID(), outbox_id); //-------------------------------------------------------------------------------- // Determine if folder can be moved. @@ -1950,24 +1950,58 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } if (move_is_into_outbox) { - for (S32 i=0; i < descendent_items.count(); ++i) + int nested_folder_levels = (get_folder_path_length(outbox_id, mUUID) - 1) + get_folder_levels(inv_cat); + + if (nested_folder_levels >= gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) { - LLInventoryItem* item = descendent_items[i]; - if (!can_move_to_outbox(item, tooltip_msg)) - { - is_movable = FALSE; - break; - } + tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels"); + is_movable = FALSE; } + else + { + const LLViewerInventoryCategory * master_folder = model->getFirstDescendantOf(outbox_id, mUUID); + + int existing_item_count = 0; + int existing_folder_count = 0; + + if (master_folder != NULL) + { + LLInventoryModel::cat_array_t existing_categories; + LLInventoryModel::item_array_t existing_items; - int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat); + gInventory.collectDescendents(master_folder->getUUID(), existing_categories, existing_items, FALSE); + + existing_item_count = existing_items.count(); + existing_folder_count = existing_categories.count(); + } - if (nested_folder_levels > 4) - { - tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels"); - is_movable = FALSE; + const int nested_folder_count = existing_folder_count + descendent_categories.count(); + const int nested_item_count = existing_item_count + descendent_items.count(); + + if (nested_folder_count >= gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) + { + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyFolders"); + is_movable = FALSE; + } + else if (nested_item_count >= gSavedSettings.getU32("InventoryOutboxMaxItemCount")) + { + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects"); + is_movable = FALSE; + } + + if (is_movable == TRUE); + { + for (S32 i=0; i < descendent_items.count(); ++i) + { + LLInventoryItem* item = descendent_items[i]; + if (!can_move_to_outbox(item, tooltip_msg)) + { + is_movable = FALSE; + break; + } + } + } } - } // @@ -2008,7 +2042,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // Recursively create links in target outfit. LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - gInventory.collectDescendents(inv_cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH); + gInventory.collectDescendents(cat_id, cats, items, LLInventoryModel::EXCLUDE_TRASH); LLAppearanceMgr::instance().linkAll(mUUID,items,NULL); } } @@ -2026,7 +2060,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, const std::string empty_description = ""; link_inventory_item( gAgent.getID(), - inv_cat->getUUID(), + cat_id, mUUID, inv_cat->getName(), empty_description, @@ -2038,13 +2072,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } else if (move_is_into_outbox && !move_is_from_outbox) { - copy_folder_to_outbox(inv_cat, mUUID, inv_cat->getUUID()); + copy_folder_to_outbox(inv_cat, mUUID, cat_id); } else { - if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) + if (gInventory.isObjectDescendentOf(cat_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) { - set_dad_inbox_object(inv_cat->getUUID()); + set_dad_inbox_object(cat_id); } // Reparent the folder and restamp children if it's moving @@ -2059,15 +2093,28 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } else if (LLToolDragAndDrop::SOURCE_WORLD == source) { - // content category has same ID as object itself - LLUUID object_id = inv_cat->getUUID(); - LLUUID category_id = mUUID; - accept = move_inv_category_world_to_agent(object_id, category_id, drop); + if (move_is_into_outbox) + { + tooltip_msg = tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else + { + accept = move_inv_category_world_to_agent(cat_id, mUUID, drop); + } } else if (LLToolDragAndDrop::SOURCE_LIBRARY == source) { - // Accept folders that contain complete outfits. - accept = move_is_into_current_outfit && LLAppearanceMgr::instance().getCanMakeFolderIntoOutfit(inv_cat->getUUID()); + if (move_is_into_outbox) + { + tooltip_msg = tooltip_msg = LLTrans::getString("TooltipOutboxNoTransferLibrary"); + accept = FALSE; + } + else + { + // Accept folders that contain complete outfits. + accept = move_is_into_current_outfit && LLAppearanceMgr::instance().getCanMakeFolderIntoOutfit(cat_id); + } if (accept && drop) { @@ -3317,8 +3364,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { LLInventoryModel* model = getInventoryModel(); - if(!model || !inv_item) return FALSE; - if(!isAgentInventory()) return FALSE; // cannot drag into library + if (!model || !inv_item) return FALSE; + if (!isAgentInventory()) return FALSE; // cannot drag into library if (!isAgentAvatarValid()) return FALSE; const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); @@ -3386,10 +3433,14 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, accept = TRUE; if (!is_movable) + { accept = FALSE; - if ((mUUID == inv_item->getParentUUID()) && !move_is_into_favorites) + } + else if ((mUUID == inv_item->getParentUUID()) && !move_is_into_favorites) + { accept = FALSE; - if (move_is_into_current_outfit || move_is_into_outfit) + } + else if (move_is_into_current_outfit || move_is_into_outfit) { accept = can_move_to_outfit(inv_item, move_is_into_current_outfit); } @@ -3400,9 +3451,32 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, else if (move_is_into_outbox) { accept = can_move_to_outbox(inv_item, tooltip_msg); + + if (accept) + { + const LLViewerInventoryCategory * master_folder = model->getFirstDescendantOf(outbox_id, mUUID); + + int existing_item_count = 0; + + if (master_folder != NULL) + { + LLInventoryModel::cat_array_t existing_categories; + LLInventoryModel::item_array_t existing_items; + + gInventory.collectDescendents(master_folder->getUUID(), existing_categories, existing_items, FALSE); + + existing_item_count = existing_items.count(); + } + + if (existing_item_count >= gSavedSettings.getU32("InventoryOutboxMaxItemCount")) + { + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects"); + accept = FALSE; + } + } } - if(accept && drop) + if (accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE && LLGestureMgr::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash) @@ -3451,13 +3525,16 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { dropToOutfit(inv_item, move_is_into_current_outfit); } - else if (move_is_into_outbox && !move_is_from_outbox) + else if (move_is_into_outbox) { - copy_item_to_outbox(inv_item, mUUID, LLUUID::null); - } - else if (move_is_into_outbox && move_is_from_outbox) - { - move_item_within_outbox(inv_item, mUUID); + if (move_is_from_outbox) + { + move_item_within_outbox(inv_item, mUUID); + } + else + { + copy_item_to_outbox(inv_item, mUUID, LLUUID::null); + } } // NORMAL or TRASH folder // (move the item, restamp if into trash) @@ -3478,7 +3555,6 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // //-------------------------------------------------------------------------------- - } } else if (LLToolDragAndDrop::SOURCE_WORLD == source) @@ -3487,7 +3563,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // anonymous objects, it would be possible to bypass // permissions. object = gObjectList.findObject(inv_item->getParentUUID()); - if(!object) + if (!object) { llinfos << "Object not found for drop." << llendl; return FALSE; @@ -3497,10 +3573,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // move/copy this item. LLPermissions perm(inv_item->getPermissions()); BOOL is_move = FALSE; - if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) + if ((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) && perm.allowTransferTo(gAgent.getID()))) // || gAgent.isGodlike()) - { accept = TRUE; } @@ -3516,7 +3591,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // Don't allow placing an original item into Current Outfit or an outfit folder // because they must contain only links to wearable items. // *TODO: Probably we should create a link to an item if it was dragged to outfit or COF. - if(move_is_into_current_outfit || move_is_into_outfit) + if (move_is_into_current_outfit || move_is_into_outfit) { accept = FALSE; } @@ -3527,8 +3602,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { accept = FALSE; } - - if(drop && accept) + else if (move_is_into_outbox) + { + tooltip_msg = tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + + if (accept && drop) { LLMoveInv* move_inv = new LLMoveInv; move_inv->mObjectID = inv_item->getParentUUID(); @@ -3550,15 +3630,22 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, LLNotifications::instance().forceResponse(params, 0); } } - } else if(LLToolDragAndDrop::SOURCE_NOTECARD == source) { - // Don't allow placing an original item from a notecard to Current Outfit or an outfit folder - // because they must contain only links to wearable items. - accept = !(move_is_into_current_outfit || move_is_into_outfit); - - if(accept && drop) + if (move_is_into_outbox) + { + tooltip_msg = tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else + { + // Don't allow placing an original item from a notecard to Current Outfit or an outfit folder + // because they must contain only links to wearable items. + accept = !(move_is_into_current_outfit || move_is_into_outfit); + } + + if (accept && drop) { copy_inventory_from_notecard(mUUID, // Drop to the chosen destination folder LLToolDragAndDrop::getInstance()->getObjectID(), @@ -3573,7 +3660,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { accept = TRUE; - if (move_is_into_current_outfit || move_is_into_outfit) + if (move_is_into_outbox) + { + tooltip_msg = tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else if (move_is_into_current_outfit || move_is_into_outfit) { accept = can_move_to_outfit(inv_item, move_is_into_current_outfit); } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index dc25689fa3..2fb9c53857 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -217,6 +217,38 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons return NULL; } +// +// Search up the parent chain until we get to the specified parent, then return the first child category under it +// +const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LLUUID& master_parent_id, const LLUUID& obj_id) const +{ + if (master_parent_id == obj_id) + { + return NULL; + } + + const LLViewerInventoryCategory* current_cat = getCategory(obj_id); + + if (current_cat == NULL) + { + current_cat = getCategory(getObject(obj_id)->getParentUUID()); + } + + while (current_cat != NULL) + { + const LLUUID& current_parent_id = current_cat->getParentUUID(); + + if (current_parent_id == master_parent_id) + { + return current_cat; + } + + current_cat = getCategory(current_parent_id); + } + + return NULL; +} + // Get the object by id. Returns NULL if not found. LLInventoryObject* LLInventoryModel::getObject(const LLUUID& id) const { diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 340c1b0c22..1740c4151d 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -238,6 +238,9 @@ public: // Get whatever special folder this object is a child of, if any. const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const; + + // Get first descendant of the child object under the specified parent + const LLViewerInventoryCategory *getFirstDescendantOf(const LLUUID& master_parent_id, const LLUUID& obj_id) const; // Get the object by id. Returns NULL if not found. // NOTE: Use the pointer returned for read operations - do diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index b83571a106..0d9a7e5c41 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -165,8 +165,10 @@ Please try logging in again in a minute. Only a single item can be dragged here One or more of these objects cannot be sold or transferred to another user. + You can only transfer objects in your inventory to your merchant outbox. You are wearing one or more of these objects. Remove them from your avatar and try moving them again. This folder has too many levels of subfolders. Rearrange the interior folders to a maximum of 4 levels deep (Root Folder contains A contains B contains C). + This folder has too many subfolders. Reorganize the interior to a maximum of 20 folders. This folder contains more than 200 objects. Box some of the items to reduce the object count. -- cgit v1.3 From bd3a652eabf09a5843a6a0b8a9f60c4b402ecce5 Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Fri, 6 Jan 2012 07:46:53 -0500 Subject: Add capability-based create folder routine for more reliable inventory, with fix for copy and wear --- indra/newview/llfloateropenobject.cpp | 60 ++++++++++++++++++++---- indra/newview/llfloateropenobject.h | 11 +++++ indra/newview/llinventorybridge.cpp | 13 +++--- indra/newview/llinventorymodel.cpp | 87 +++++++++++++++++++++++++++++++++-- indra/newview/llinventorymodel.h | 4 +- indra/newview/llviewerregion.cpp | 1 + 6 files changed, 155 insertions(+), 21 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 8b6619def2..4bfef8b45f 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -162,26 +162,66 @@ void LLFloaterOpenObject::moveToInventory(bool wear) { parent_category_id = gInventory.getRootFolderID(); } + + LLCategoryCreate* cat_data = new LLCategoryCreate(object_id, wear); + LLUUID category_id = gInventory.createNewCategory(parent_category_id, - LLFolderType::FT_NONE, - name); + LLFolderType::FT_NONE, + name, + callbackCreateInventoryCategory, + (void*)cat_data); + + //If we get a null category ID, we are using a capability in createNewCategory and we will + //handle the following in the callbackCreateInventoryCategory routine. + if ( category_id.notNull() ) + { + delete cat_data; + + LLCatAndWear* data = new LLCatAndWear; + data->mCatID = category_id; + data->mWear = wear; + data->mFolderResponded = false; + + // Copy and/or move the items into the newly created folder. + // Ignore any "you're going to break this item" messages. + BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE, + callbackMoveInventory, + (void*)data); + if (!success) + { + delete data; + data = NULL; - LLCatAndWear* data = new LLCatAndWear; - data->mCatID = category_id; - data->mWear = wear; + LLNotificationsUtil::add("OpenObjectCannotCopy"); + } + } +} +// static +void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, void* data) +{ + LLCategoryCreate* cat_data = (LLCategoryCreate*)data; + + LLUUID category_id = result["folder_id"].asUUID(); + LLCatAndWear* wear_data = new LLCatAndWear; + + wear_data->mCatID = category_id; + wear_data->mWear = cat_data->mWear; + wear_data->mFolderResponded = true; + // Copy and/or move the items into the newly created folder. // Ignore any "you're going to break this item" messages. - BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE, + BOOL success = move_inv_category_world_to_agent(cat_data->mObjectID, category_id, TRUE, callbackMoveInventory, - (void*)data); + (void*)wear_data); if (!success) { - delete data; - data = NULL; - + delete wear_data; + wear_data = NULL; + LLNotificationsUtil::add("OpenObjectCannotCopy"); } + delete cat_data; } // static diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h index 0706e99f16..bf7fe69c65 100644 --- a/indra/newview/llfloateropenobject.h +++ b/indra/newview/llfloateropenobject.h @@ -45,10 +45,20 @@ public: void dirty(); + class LLCategoryCreate + { + public: + LLCategoryCreate(LLUUID object_id, bool wear) : mObjectID(object_id), mWear(wear) {} + public: + LLUUID mObjectID; + bool mWear; + }; + struct LLCatAndWear { LLUUID mCatID; bool mWear; + bool mFolderResponded; }; protected: @@ -62,6 +72,7 @@ protected: void onClickMoveToInventory(); void onClickMoveAndWear(); + static void callbackCreateInventoryCategory(const LLSD& result, void* data); static void callbackMoveInventory(S32 result, void* data); private: diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0c092e9a56..eaf9b53eb9 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2305,15 +2305,15 @@ void LLRightClickInventoryFetchDescendentsObserver::done() class LLInventoryCopyAndWearObserver : public LLInventoryObserver { public: - LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count) : - mCatID(cat_id), mContentsCount(count), mFolderAdded(FALSE) {} + LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count, bool folder_added=false) : + mCatID(cat_id), mContentsCount(count), mFolderAdded(folder_added) {} virtual ~LLInventoryCopyAndWearObserver() {} virtual void changed(U32 mask); protected: LLUUID mCatID; int mContentsCount; - BOOL mFolderAdded; + bool mFolderAdded; }; @@ -2341,7 +2341,6 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask) if (mFolderAdded) { LLViewerInventoryCategory* category = gInventory.getCategory(mCatID); - if (NULL == category) { llwarns << "gInventory.getCategory(" << mCatID @@ -3188,13 +3187,13 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response if(option == 0 && object) { - if (cat_and_wear && cat_and_wear->mWear) + if (cat_and_wear && cat_and_wear->mWear) // && !cat_and_wear->mFolderResponded) { LLInventoryObject::object_list_t inventory_objects; object->getInventoryContents(inventory_objects); int contents_count = inventory_objects.size()-1; //subtract one for containing folder - - LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count); + LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count, cat_and_wear->mFolderResponded); + gInventory.addObserver(inventoryObserver); } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index dc25689fa3..568ec4c5e2 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -377,14 +377,67 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe return rv; } +class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder +{ +public: + LLCreateInventoryCategoryResponder(LLInventoryModel* model, + void (*callback)(const LLSD&, void*), + void* user_data) : + mModel(model), + mCallback(callback), + mData(user_data) + { + } + + virtual void error(U32 status, const std::string& reason) + { + LL_WARNS("InvAPI") << "CreateInventoryCategory failed. status = " << status << ", reasion = \"" << reason << "\"" << LL_ENDL; + } + + virtual void result(const LLSD& content) + { + //Server has created folder. + + LLUUID category_id = content["folder_id"].asUUID(); + + + // Add the category to the internal representation + LLPointer cat = + new LLViewerInventoryCategory( category_id, + content["parent_id"].asUUID(), + (LLFolderType::EType)content["type"].asInteger(), + content["name"].asString(), + gAgent.getID() ); + cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL); + cat->setDescendentCount(0); + LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1); + mModel->accountForUpdate(update); + mModel->updateCategory(cat); + + if (mCallback && mData) + { + mCallback(content, mData); + } + + } + +private: + void (*mCallback)(const LLSD&, void*); + void* mData; + LLInventoryModel* mModel; +}; + // Convenience function to create a new category. You could call // updateCategory() with a newly generated UUID category, but this // version will take care of details like what the name should be // based on preferred type. Returns the UUID of the new category. LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, LLFolderType::EType preferred_type, - const std::string& pname) + const std::string& pname, + void (*callback)(const LLSD&, void*), //Default to NULL + void* user_data) //Default to NULL { + LLUUID id; if(!isInventoryUsable()) { @@ -408,6 +461,35 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, { name.assign(LLViewerFolderType::lookupNewCategoryName(preferred_type)); } + + if ( callback && user_data ) //callback required for acked message. + { + LLViewerRegion* viewer_region = gAgent.getRegion(); + std::string url; + if ( viewer_region ) + url = viewer_region->getCapability("CreateInventoryCategory"); + + if (!url.empty()) + { + //Let's use the new capability. + + LLSD request, body; + body["folder_id"] = id; + body["parent_id"] = parent_id; + body["type"] = (LLSD::Integer) preferred_type; + body["name"] = name; + + request["message"] = "CreateInventoryCategory"; + request["payload"] = body; + + // viewer_region->getCapAPI().post(request); + LLHTTPClient::post( + url, + body, + new LLCreateInventoryCategoryResponder(this, callback, user_data) ); + return LLUUID::null; + } + } // Add the category to the internal representation LLPointer cat = @@ -1087,7 +1169,6 @@ void LLInventoryModel::notifyObservers() iter != mObservers.end(); ) { LLInventoryObserver* observer = *iter; - observer->changed(mModifyMask); // safe way to increment since changed may delete entries! (@!##%@!@&*!) @@ -2574,7 +2655,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) << titem->getParentUUID() << llendl; U32 callback_id; msg->getU32Fast(_PREHASH_ItemData, _PREHASH_CallbackID, callback_id); - if(titem->getUUID().notNull()) + if(titem->getUUID().notNull() ) // && callback_id.notNull() ) { items.push_back(titem); cblist.push_back(InventoryCallbackInfo(callback_id, titem->getUUID())); diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 340c1b0c22..0a564d353a 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -360,7 +360,9 @@ public: // name based on type, pass in a NULL to the 'name' parameter. LLUUID createNewCategory(const LLUUID& parent_id, LLFolderType::EType preferred_type, - const std::string& name); + const std::string& name, + void (*callback)(const LLSD&, void*) = NULL, + void* user_data = NULL ); protected: // Internal methods that add inventory and make sure that all of // the internal data structures are consistent. These methods diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index ed943964f9..e3cb985ddb 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1493,6 +1493,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("AvatarPickerSearch"); capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); + capabilityNames.append("CreateInventoryCategory"); capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); -- cgit v1.3