diff options
| author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2013-04-25 17:09:05 -0400 | 
|---|---|---|
| committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2013-04-25 17:09:05 -0400 | 
| commit | d843a0d8bef5d36d3a4ef838b1b0335b4532147b (patch) | |
| tree | 8861ebcde11e00cc7b900de7bd4cef8869730357 /indra | |
| parent | e60cb90b632d175690f48b783ece272deff524cd (diff) | |
SH-4137 WIP - added callback-based support for purge descendents, remove category
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llinventory/llinventory.cpp | 7 | ||||
| -rw-r--r-- | indra/llinventory/llinventory.h | 1 | ||||
| -rw-r--r-- | indra/newview/llinventorybridge.cpp | 9 | ||||
| -rwxr-xr-x | indra/newview/llinventorymodel.cpp | 207 | ||||
| -rwxr-xr-x | indra/newview/llinventorymodel.h | 19 | ||||
| -rw-r--r-- | indra/newview/llpreview.cpp | 7 | ||||
| -rwxr-xr-x | indra/newview/llviewerinventory.cpp | 286 | ||||
| -rwxr-xr-x | indra/newview/llviewerinventory.h | 14 | 
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, | 
