SH-4137 WIP - added callback-based support for purge descendents, remove category
parent
e60cb90b63
commit
d843a0d8be
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue