summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2013-04-25 17:09:05 -0400
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2013-04-25 17:09:05 -0400
commitd843a0d8bef5d36d3a4ef838b1b0335b4532147b (patch)
tree8861ebcde11e00cc7b900de7bd4cef8869730357
parente60cb90b632d175690f48b783ece272deff524cd (diff)
SH-4137 WIP - added callback-based support for purge descendents, remove category
-rw-r--r--indra/llinventory/llinventory.cpp7
-rw-r--r--indra/llinventory/llinventory.h1
-rw-r--r--indra/newview/llinventorybridge.cpp9
-rwxr-xr-xindra/newview/llinventorymodel.cpp207
-rwxr-xr-xindra/newview/llinventorymodel.h19
-rw-r--r--indra/newview/llpreview.cpp7
-rwxr-xr-xindra/newview/llviewerinventory.cpp286
-rwxr-xr-xindra/newview/llviewerinventory.h14
8 files changed, 321 insertions, 229 deletions
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 41d58c6deb..a4cd8333cf 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -249,13 +249,6 @@ BOOL LLInventoryObject::exportLegacyStream(std::ostream& output_stream, BOOL) co
return TRUE;
}
-
-void LLInventoryObject::removeFromServer()
-{
- // don't do nothin'
- llwarns << "LLInventoryObject::removeFromServer() called. Doesn't do anything." << llendl;
-}
-
void LLInventoryObject::updateParentOnServer(BOOL) const
{
// don't do nothin'
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 99716ed7be..8b865f044d 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -101,7 +101,6 @@ public:
virtual BOOL importLegacyStream(std::istream& input_stream);
virtual BOOL exportLegacyStream(std::ostream& output_stream, BOOL include_asset_key = TRUE) const;
- virtual void removeFromServer();
virtual void updateParentOnServer(BOOL) const;
virtual void updateServer(BOOL) const;
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index a5043a30ac..27f35c5946 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1159,17 +1159,10 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
{
- LLInventoryCategory* cat = model->getCategory(uuid);
- if (cat)
- {
- model->purgeDescendentsOf(uuid);
- model->notifyObservers();
- }
LLInventoryObject* obj = model->getObject(uuid);
if (obj)
{
- model->purgeObject(uuid);
- model->notifyObservers();
+ remove_inventory_object(uuid, NULL);
}
}
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index a0b9e7b0ec..ae8efeecda 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1136,6 +1136,79 @@ void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat,
notifyObservers();
}
+// Update model after descendents have been purged.
+void LLInventoryModel::onDescendentsPurgedFromServer(const LLUUID& object_id)
+{
+ LLPointer<LLViewerInventoryCategory> cat = getCategory(object_id);
+ if (cat.notNull())
+ {
+ // do the cache accounting
+ S32 descendents = cat->getDescendentCount();
+ if(descendents > 0)
+ {
+ LLInventoryModel::LLCategoryUpdate up(object_id, -descendents);
+ accountForUpdate(up);
+ }
+
+ // we know that descendent count is 0, however since the
+ // accounting may actually not do an update, we should force
+ // it here.
+ cat->setDescendentCount(0);
+
+ // unceremoniously remove anything we have locally stored.
+ LLInventoryModel::cat_array_t categories;
+ LLInventoryModel::item_array_t items;
+ collectDescendents(object_id,
+ categories,
+ items,
+ LLInventoryModel::INCLUDE_TRASH);
+ S32 count = items.count();
+
+ LLUUID uu_id;
+ for(S32 i = 0; i < count; ++i)
+ {
+ uu_id = items.get(i)->getUUID();
+
+ // This check prevents the deletion of a previously deleted item.
+ // This is necessary because deletion is not done in a hierarchical
+ // order. The current item may have been already deleted as a child
+ // of its deleted parent.
+ if (getItem(uu_id))
+ {
+ deleteObject(uu_id);
+ }
+ }
+
+ count = categories.count();
+ for(S32 i = 0; i < count; ++i)
+ {
+ uu_id = categories.get(i)->getUUID();
+ if (getCategory(uu_id))
+ {
+ deleteObject(uu_id);
+ }
+ }
+ }
+}
+
+// Update model after an item is confirmed as removed from
+// server. Works for categories or items.
+void LLInventoryModel::onObjectDeletedFromServer(const LLUUID& object_id)
+{
+ LLPointer<LLInventoryObject> obj = getObject(object_id);
+ if(obj)
+ {
+ // From item/cat removeFromServer()
+ LLInventoryModel::LLCategoryUpdate up(obj->getParentUUID(), -1);
+ accountForUpdate(up);
+
+ // From purgeObject()
+ LLPreview::hide(object_id);
+ deleteObject(object_id);
+ }
+}
+
+
// Delete a particular inventory object by ID.
void LLInventoryModel::deleteObject(const LLUUID& id)
{
@@ -1187,20 +1260,7 @@ void LLInventoryModel::deleteObject(const LLUUID& id)
{
updateLinkedObjectsFromPurge(id);
}
- gInventory.notifyObservers();
-}
-
-// Delete a particular inventory item by ID, and remove it from the server.
-void LLInventoryModel::purgeObject(const LLUUID &id)
-{
- lldebugs << "LLInventoryModel::purgeObject() [ id: " << id << " ] " << llendl;
- LLPointer<LLInventoryObject> obj = getObject(id);
- if(obj)
- {
- obj->removeFromServer();
- LLPreview::hide(id);
- deleteObject(id);
- }
+ notifyObservers();
}
void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)
@@ -1225,119 +1285,6 @@ void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)
}
}
-// This is a method which collects the descendents of the id
-// provided. If the category is not found, no action is
-// taken. This method goes through the long winded process of
-// cancelling any calling cards, removing server representation of
-// folders, items, etc in a fairly efficient manner.
-void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
-{
- EHasChildren children = categoryHasChildren(id);
- if(children == CHILDREN_NO)
- {
- llinfos << "Not purging descendents of " << id << llendl;
- return;
- }
- LLPointer<LLViewerInventoryCategory> cat = getCategory(id);
- if (cat.notNull())
- {
- if (LLClipboard::instance().hasContents() && LLClipboard::instance().isCutMode())
- {
- // Something on the clipboard is in "cut mode" and needs to be preserved
- llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName()
- << " iterate and purge non hidden items" << llendl;
- cat_array_t* categories;
- item_array_t* items;
- // Get the list of direct descendants in tha categoy passed as argument
- getDirectDescendentsOf(id, categories, items);
- std::vector<LLUUID> list_uuids;
- // Make a unique list with all the UUIDs of the direct descendants (items and categories are not treated differently)
- // Note: we need to do that shallow copy as purging things will invalidate the categories or items lists
- for (cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it)
- {
- list_uuids.push_back((*it)->getUUID());
- }
- for (item_array_t::const_iterator it = items->begin(); it != items->end(); ++it)
- {
- list_uuids.push_back((*it)->getUUID());
- }
- // Iterate through the list and only purge the UUIDs that are not on the clipboard
- for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
- {
- if (!LLClipboard::instance().isOnClipboard(*it))
- {
- purgeObject(*it);
- }
- }
- }
- else
- {
- // Fast purge
- // do the cache accounting
- llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName()
- << llendl;
- S32 descendents = cat->getDescendentCount();
- if(descendents > 0)
- {
- LLCategoryUpdate up(id, -descendents);
- accountForUpdate(up);
- }
-
- // we know that descendent count is 0, however since the
- // accounting may actually not do an update, we should force
- // it here.
- cat->setDescendentCount(0);
-
- // send it upstream
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("PurgeInventoryDescendents");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("InventoryData");
- msg->addUUID("FolderID", id);
- gAgent.sendReliableMessage();
-
- // unceremoniously remove anything we have locally stored.
- cat_array_t categories;
- item_array_t items;
- collectDescendents(id,
- categories,
- items,
- INCLUDE_TRASH);
- S32 count = items.count();
-
- item_map_t::iterator item_map_end = mItemMap.end();
- cat_map_t::iterator cat_map_end = mCategoryMap.end();
- LLUUID uu_id;
-
- for(S32 i = 0; i < count; ++i)
- {
- uu_id = items.get(i)->getUUID();
-
- // This check prevents the deletion of a previously deleted item.
- // This is necessary because deletion is not done in a hierarchical
- // order. The current item may have been already deleted as a child
- // of its deleted parent.
- if (mItemMap.find(uu_id) != item_map_end)
- {
- deleteObject(uu_id);
- }
- }
-
- count = categories.count();
- for(S32 i = 0; i < count; ++i)
- {
- uu_id = categories.get(i)->getUUID();
- if (mCategoryMap.find(uu_id) != cat_map_end)
- {
- deleteObject(uu_id);
- }
- }
- }
- }
-}
-
// Add/remove an observer. If the observer is destroyed, be sure to
// remove it.
void LLInventoryModel::addObserver(LLInventoryObserver* observer)
@@ -3114,8 +3061,7 @@ bool LLInventoryModel::callbackEmptyFolderType(const LLSD& notification, const L
if (option == 0) // YES
{
const LLUUID folder_id = findCategoryUUIDForType(preferred_type);
- purgeDescendentsOf(folder_id);
- notifyObservers();
+ purge_descendents_of(folder_id, NULL);
}
return false;
}
@@ -3130,8 +3076,7 @@ void LLInventoryModel::emptyFolderType(const std::string notification, LLFolderT
else
{
const LLUUID folder_id = findCategoryUUIDForType(preferred_type);
- purgeDescendentsOf(folder_id);
- notifyObservers();
+ purge_descendents_of(folder_id, NULL);
}
}
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 50b57ea08d..b7e1888f20 100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -325,6 +325,14 @@ public:
// Delete
//--------------------------------------------------------------------
public:
+
+ // Update model after an item is confirmed as removed from
+ // server. Works for categories or items.
+ void onObjectDeletedFromServer(const LLUUID& item_id);
+
+ // Update model after all descendents removed from server.
+ void onDescendentsPurgedFromServer(const LLUUID& object_id);
+
// Delete a particular inventory object by ID. Will purge one
// object from the internal data structures, maintaining a
// consistent internal state. No cache accounting, observer
@@ -337,17 +345,6 @@ public:
/// removeItem() or removeCategory(), whichever is appropriate
void removeObject(const LLUUID& object_id);
- // Delete a particular inventory object by ID, and delete it from
- // the server. Also updates linked items.
- void purgeObject(const LLUUID& id);
-
- // Collects and purges the descendants of the id
- // provided. If the category is not found, no action is
- // taken. This method goes through the long winded process of
- // removing server representation of folders and items while doing
- // cache accounting in a fairly efficient manner. This method does
- // not notify observers (though maybe it should...)
- void purgeDescendentsOf(const LLUUID& id);
protected:
void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id);
diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp
index 04934b13f1..452efad291 100644
--- a/indra/newview/llpreview.cpp
+++ b/indra/newview/llpreview.cpp
@@ -401,13 +401,6 @@ void LLPreview::onDiscardBtn(void* data)
self->mForceClose = TRUE;
self->closeFloater();
- // Delete the item entirely
- /*
- item->removeFromServer();
- gInventory.deleteObject(item->getUUID());
- gInventory.notifyObservers();
- */
-
// Move the item to the trash
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
if (item->getParentUUID() != trash_id)
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 06efeb86d9..fbd6b292bd 100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -65,6 +65,7 @@
#include "llavataractions.h"
#include "lllogininstance.h"
#include "llfavoritesbar.h"
+#include "llclipboard.h"
// Two do-nothing ops for use in callbacks.
void no_op_inventory_func(const LLUUID&) {}
@@ -345,24 +346,6 @@ void LLViewerInventoryItem::cloneViewerItem(LLPointer<LLViewerInventoryItem>& ne
}
}
-void LLViewerInventoryItem::removeFromServer()
-{
- lldebugs << "Removing inventory item " << mUUID << " from server."
- << llendl;
-
- LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);
- gInventory.accountForUpdate(up);
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RemoveInventoryItem);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_InventoryData);
- msg->addUUIDFast(_PREHASH_ItemID, mUUID);
- gAgent.sendReliableMessage();
-}
-
void LLViewerInventoryItem::updateServer(BOOL is_new) const
{
if(!mIsComplete)
@@ -637,30 +620,6 @@ void LLViewerInventoryCategory::updateServer(BOOL is_new) const
gAgent.sendReliableMessage();
}
-void LLViewerInventoryCategory::removeFromServer( void )
-{
- llinfos << "Removing inventory category " << mUUID << " from server."
- << llendl;
- // communicate that change with the server.
- if(LLFolderType::lookupIsProtectedType(mPreferredType))
- {
- LLNotificationsUtil::add("CannotRemoveProtectedCategories");
- return;
- }
-
- LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);
- gInventory.accountForUpdate(up);
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RemoveInventoryFolder);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_FolderData);
- msg->addUUIDFast(_PREHASH_FolderID, mUUID);
- gAgent.sendReliableMessage();
-}
-
S32 LLViewerInventoryCategory::getVersion() const
{
return mVersion;
@@ -1179,25 +1138,10 @@ void move_inventory_item(
gAgent.sendReliableMessage();
}
-void handle_item_deletion(const LLUUID& item_id)
-{
- LLPointer<LLViewerInventoryItem> obj = gInventory.getItem(item_id);
- if(obj)
- {
- // From item removeFromServer()
- LLInventoryModel::LLCategoryUpdate up(obj->getParentUUID(), -1);
- gInventory.accountForUpdate(up);
-
- // From purgeObject()
- LLPreview::hide(item_id);
- gInventory.deleteObject(item_id);
- }
-}
-
-class RemoveItemResponder: public LLHTTPClient::Responder
+class RemoveObjectResponder: public LLHTTPClient::Responder
{
public:
- RemoveItemResponder(const LLUUID& item_id, LLPointer<LLInventoryCallback> callback):
+ RemoveObjectResponder(const LLUUID& item_id, LLPointer<LLInventoryCallback> callback):
mItemUUID(item_id),
mCallback(callback)
{
@@ -1212,7 +1156,7 @@ public:
}
llinfos << "succeeded: " << ll_pretty_print_sd(content) << llendl;
- handle_item_deletion(mItemUUID);
+ gInventory.onObjectDeletedFromServer(mItemUUID);
if (mCallback)
{
@@ -1251,7 +1195,7 @@ void remove_inventory_item(
{
std::string url = cap + std::string("/item/") + item_id.asString();
llinfos << "url: " << url << llendl;
- LLCurl::ResponderPtr responder_ptr = new RemoveItemResponder(item_id,cb);
+ LLCurl::ResponderPtr responder_ptr = new RemoveObjectResponder(item_id,cb);
LLHTTPClient::del(url,responder_ptr);
}
else // no cap
@@ -1267,7 +1211,7 @@ void remove_inventory_item(
// Update inventory and call callback immediately since
// message-based system has no callback mechanism (!)
- handle_item_deletion(item_id);
+ gInventory.onObjectDeletedFromServer(item_id);
if (cb)
{
cb->fire(item_id);
@@ -1280,6 +1224,224 @@ void remove_inventory_item(
}
}
+class LLRemoveObjectOnDestroy: public LLInventoryCallback
+{
+public:
+ LLRemoveObjectOnDestroy(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb):
+ mID(item_id),
+ mCB(cb)
+ {
+ }
+ /* virtual */ void fire(const LLUUID& item_id) {}
+ ~LLRemoveObjectOnDestroy()
+ {
+ remove_inventory_object(mID, mCB);
+ }
+private:
+ LLUUID mID;
+ LLPointer<LLInventoryCallback> mCB;
+};
+
+void remove_inventory_category(
+ const LLUUID& cat_id,
+ LLPointer<LLInventoryCallback> cb)
+{
+ llinfos << "cat_id: [" << cat_id << "] " << llendl;
+ LLPointer<LLViewerInventoryCategory> obj = gInventory.getCategory(cat_id);
+ if(obj)
+ {
+ if(LLFolderType::lookupIsProtectedType(obj->getPreferredType()))
+ {
+ LLNotificationsUtil::add("CannotRemoveProtectedCategories");
+ return;
+ }
+ LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(cat_id);
+ if(children != LLInventoryModel::CHILDREN_NO)
+ {
+ llinfos << "Will purge descendents first before deleting category " << cat_id << llendl;
+ LLPointer<LLInventoryCallback> wrap_cb = new LLRemoveObjectOnDestroy(cat_id,cb);
+ purge_descendents_of(cat_id, wrap_cb);
+ return;
+ }
+
+ std::string cap;
+ if (gAgent.getRegion())
+ {
+ cap = gAgent.getRegion()->getCapability("InventoryAPIv3");
+ }
+ if (!cap.empty())
+ {
+ std::string url = cap + std::string("/category/") + cat_id.asString();
+ llinfos << "url: " << url << llendl;
+ LLCurl::ResponderPtr responder_ptr = new RemoveObjectResponder(cat_id,cb);
+ LLHTTPClient::del(url,responder_ptr);
+ }
+ else // no cap
+ {
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_RemoveInventoryFolder);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_FolderData);
+ msg->addUUIDFast(_PREHASH_FolderID, cat_id);
+ gAgent.sendReliableMessage();
+
+ // Update inventory and call callback immediately since
+ // message-based system has no callback mechanism (!)
+ gInventory.onObjectDeletedFromServer(cat_id);
+ if (cb)
+ {
+ cb->fire(cat_id);
+ }
+ }
+ }
+ else
+ {
+ llwarns << "remove_inventory_category called for invalid or nonexistent item " << cat_id << llendl;
+ }
+}
+
+void remove_inventory_object(
+ const LLUUID& object_id,
+ LLPointer<LLInventoryCallback> cb)
+{
+ if (gInventory.getCategory(object_id))
+ {
+ remove_inventory_category(object_id, cb);
+ }
+ else
+ {
+ remove_inventory_item(object_id, cb);
+ }
+}
+
+class PurgeDescendentsResponder: public LLHTTPClient::Responder
+{
+public:
+ PurgeDescendentsResponder(const LLUUID& item_id, LLPointer<LLInventoryCallback> callback):
+ mItemUUID(item_id),
+ mCallback(callback)
+ {
+ }
+ /* virtual */ void httpSuccess()
+ {
+ const LLSD& content = getContent();
+ if (!content.isMap())
+ {
+ failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+ return;
+ }
+ llinfos << "succeeded: " << ll_pretty_print_sd(content) << llendl;
+
+ gInventory.onDescendentsPurgedFromServer(mItemUUID);
+
+ if (mCallback)
+ {
+ mCallback->fire(mItemUUID);
+ }
+ }
+ /*virtual*/ void httpFailure()
+ {
+ const LLSD& content = getContent();
+ if (!content.isMap())
+ {
+ failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+ return;
+ }
+ llwarns << "failed for " << mItemUUID << " content: " << ll_pretty_print_sd(content) << llendl;
+ }
+private:
+ LLPointer<LLInventoryCallback> mCallback;
+ const LLUUID mItemUUID;
+};
+
+// This is a method which collects the descendents of the id
+// provided. If the category is not found, no action is
+// taken. This method goes through the long winded process of
+// cancelling any calling cards, removing server representation of
+// folders, items, etc in a fairly efficient manner.
+void purge_descendents_of(const LLUUID& id, LLPointer<LLInventoryCallback> cb)
+{
+ LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(id);
+ if(children == LLInventoryModel::CHILDREN_NO)
+ {
+ llinfos << "No descendents to purge for " << id << llendl;
+ return;
+ }
+ LLPointer<LLViewerInventoryCategory> cat = gInventory.getCategory(id);
+ if (cat.notNull())
+ {
+ if (LLClipboard::instance().hasContents() && LLClipboard::instance().isCutMode())
+ {
+ // Something on the clipboard is in "cut mode" and needs to be preserved
+ llinfos << "purge_descendents_of clipboard case " << cat->getName()
+ << " iterate and purge non hidden items" << llendl;
+ LLInventoryModel::cat_array_t* categories;
+ LLInventoryModel::item_array_t* items;
+ // Get the list of direct descendants in tha categoy passed as argument
+ gInventory.getDirectDescendentsOf(id, categories, items);
+ std::vector<LLUUID> list_uuids;
+ // Make a unique list with all the UUIDs of the direct descendants (items and categories are not treated differently)
+ // Note: we need to do that shallow copy as purging things will invalidate the categories or items lists
+ for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it)
+ {
+ list_uuids.push_back((*it)->getUUID());
+ }
+ for (LLInventoryModel::item_array_t::const_iterator it = items->begin(); it != items->end(); ++it)
+ {
+ list_uuids.push_back((*it)->getUUID());
+ }
+ // Iterate through the list and only purge the UUIDs that are not on the clipboard
+ for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
+ {
+ if (!LLClipboard::instance().isOnClipboard(*it))
+ {
+ remove_inventory_object(*it, NULL);
+ }
+ }
+ }
+ else
+ {
+ std::string cap;
+ if (gAgent.getRegion())
+ {
+ cap = gAgent.getRegion()->getCapability("InventoryAPIv3");
+ }
+ if (!cap.empty())
+ {
+ std::string url = cap + std::string("/category/") + id.asString() + "/children";
+ llinfos << "url: " << url << llendl;
+ LLCurl::ResponderPtr responder_ptr = new PurgeDescendentsResponder(id,cb);
+ LLHTTPClient::del(url,responder_ptr);
+ }
+ else // no cap
+ {
+ // Fast purge
+ llinfos << "purge_descendents_of fast case " << cat->getName() << llendl;
+
+ // send it upstream
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("PurgeInventoryDescendents");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("InventoryData");
+ msg->addUUID("FolderID", id);
+ gAgent.sendReliableMessage();
+
+ // Update model immediately because there is no callback mechanism.
+ gInventory.onDescendentsPurgedFromServer(id);
+ if (cb)
+ {
+ cb->fire(id);
+ }
+ }
+ }
+ }
+}
+
const LLUUID get_folder_by_itemtype(const LLInventoryItem *src)
{
LLUUID retval = LLUUID::null;
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 6b0e8ed4ef..4e24dc87d1 100755
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -118,7 +118,6 @@ public:
void cloneViewerItem(LLPointer<LLViewerInventoryItem>& newitem) const;
// virtual methods
- virtual void removeFromServer( void );
virtual void updateParentOnServer(BOOL restamp) const;
virtual void updateServer(BOOL is_new) const;
void fetchFromServer(void) const;
@@ -198,7 +197,6 @@ public:
LLViewerInventoryCategory(const LLViewerInventoryCategory* other);
void copyViewerCategory(const LLViewerInventoryCategory* other);
- virtual void removeFromServer();
virtual void updateParentOnServer(BOOL restamp_children) const;
virtual void updateServer(BOOL is_new) const;
@@ -369,6 +367,18 @@ void remove_inventory_item(
const LLUUID& item_id,
LLPointer<LLInventoryCallback> cb);
+void remove_inventory_category(
+ const LLUUID& cat_id,
+ LLPointer<LLInventoryCallback> cb);
+
+void remove_inventory_object(
+ const LLUUID& object_id,
+ LLPointer<LLInventoryCallback> cb);
+
+void purge_descendents_of(
+ const LLUUID& cat_id,
+ LLPointer<LLInventoryCallback> cb);
+
const LLUUID get_folder_by_itemtype(const LLInventoryItem *src);
void copy_inventory_from_notecard(const LLUUID& destination_id,