diff options
Diffstat (limited to 'indra/newview')
| -rwxr-xr-x | indra/newview/llagentwearables.cpp | 8 | ||||
| -rwxr-xr-x | indra/newview/llagentwearablesfetch.cpp | 15 | ||||
| -rwxr-xr-x | indra/newview/llaisapi.cpp | 37 | ||||
| -rwxr-xr-x | indra/newview/llaisapi.h | 9 | ||||
| -rwxr-xr-x | indra/newview/llappearancemgr.cpp | 103 | ||||
| -rwxr-xr-x | indra/newview/llappearancemgr.h | 13 | ||||
| -rwxr-xr-x | indra/newview/llinventorybridge.cpp | 32 | ||||
| -rwxr-xr-x | indra/newview/llpaneleditwearable.cpp | 15 | ||||
| -rwxr-xr-x | indra/newview/llviewerinventory.cpp | 231 | ||||
| -rwxr-xr-x | indra/newview/llviewerinventory.h | 27 | 
10 files changed, 265 insertions, 225 deletions
| diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 8c33a778e3..f3c9998a7d 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -952,15 +952,15 @@ public:  	/* virtual */ void fire(const LLUUID& inv_item)  	{  		llinfos << "One item created " << inv_item.asString() << llendl; -		LLViewerInventoryItem *item = gInventory.getItem(inv_item); -		mItemsToLink.put(item); +		LLConstPointer<LLInventoryObject> item = gInventory.getItem(inv_item); +		mItemsToLink.push_back(item);  		updatePendingWearable(inv_item);  	}  	~OnWearableItemCreatedCB()  	{  		llinfos << "All items created" << llendl;  		LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; -		LLAppearanceMgr::instance().linkAll(LLAppearanceMgr::instance().getCOF(), +		link_inventory_array(LLAppearanceMgr::instance().getCOF(),  											mItemsToLink,  											link_waiter);  	} @@ -1011,7 +1011,7 @@ public:  	}  private: -	LLInventoryModel::item_array_t mItemsToLink; +	LLInventoryObject::const_object_list_t mItemsToLink;  	std::vector<LLViewerWearable*> mWearablesAwaitingItems;  }; diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index 014c610a5c..a2a667e660 100755 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -117,26 +117,21 @@ public:  		// Link to all fetched items in COF.  		LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; +		LLInventoryObject::const_object_list_t item_array;  		for (uuid_vec_t::iterator it = mIDs.begin();  			 it != mIDs.end();  			 ++it)  		{  			LLUUID id = *it; -			LLViewerInventoryItem *item = gInventory.getItem(*it); +			LLConstPointer<LLInventoryObject> item = gInventory.getItem(*it);  			if (!item)  			{ -				llwarns << "fetch failed!" << llendl; +				llwarns << "fetch failed for item " << (*it) << "!" << llendl;  				continue;  			} - -			link_inventory_item(gAgent.getID(), -								item->getLinkedUUID(), -								LLAppearanceMgr::instance().getCOF(), -								item->getName(), -								item->getDescription(), -								LLAssetType::AT_LINK, -								link_waiter); +			item_array.push_back(item);  		} +		link_inventory_array(LLAppearanceMgr::instance().getCOF(), item_array, link_waiter);  	}  }; diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index f8c9447b17..73aaebc050 100755 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -100,20 +100,9 @@ void AISCommand::httpSuccess()  /*virtual*/  void AISCommand::httpFailure()  { -	const LLSD& content = getContent(); +	LL_WARNS("Inventory") << dumpResponse() << LL_ENDL;  	S32 status = getStatus(); -	const std::string& reason = getReason();  	const LLSD& headers = getResponseHeaders(); -	if (!content.isMap()) -	{ -		LL_DEBUGS("Inventory") << "Malformed response contents " << content -							   << " status " << status << " reason " << reason << LL_ENDL; -	} -	else -	{ -		LL_DEBUGS("Inventory") << "failed with content: " << ll_pretty_print_sd(content) -							   << " status " << status << " reason " << reason << LL_ENDL; -	}  	mRetryPolicy->onFailure(status, headers);  	F32 seconds_to_wait;  	if (mRetryPolicy->shouldRetry(seconds_to_wait)) @@ -276,6 +265,30 @@ UpdateCategoryCommand::UpdateCategoryCommand(const LLUUID& item_id,  	setCommandFunc(cmd);  } +CreateInventoryCommand::CreateInventoryCommand(const LLUUID& parent_id, +							 				   const LLSD& new_inventory, +							 				   LLPointer<LLInventoryCallback> callback): +	mNewInventory(new_inventory), +	AISCommand(callback) +{ +	std::string cap; +	if (!getInvCap(cap)) +	{ +		llwarns << "No cap found" << llendl; +		return; +	} +	LLUUID tid; +	tid.generate(); +	std::string url = cap + std::string("/category/") + parent_id.asString() + "?tid=" + tid.asString(); +	LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; +	LLCurl::ResponderPtr responder = this; +	LLSD headers; +	headers["Content-Type"] = "application/llsd+xml"; +	F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +	command_func_type cmd = boost::bind(&LLHTTPClient::post, url, mNewInventory, responder, headers, timeout); +	setCommandFunc(cmd); +} +  SlamFolderCommand::SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback):  	mContents(contents),  	AISCommand(callback) diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index f4e219e9e6..5d31129a16 100755 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -130,6 +130,15 @@ protected:  	/* virtual */ bool getResponseUUID(const LLSD& content, LLUUID& id);  }; +class CreateInventoryCommand: public AISCommand +{ +public: +	CreateInventoryCommand(const LLUUID& parent_id, const LLSD& new_inventory, LLPointer<LLInventoryCallback> callback); + +private: +	LLSD mNewInventory; +}; +  class AISUpdate  {  public: diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 3818bd8aec..c4bc6f648f 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -909,20 +909,15 @@ void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLView  	}  	LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL; -	LLViewerInventoryItem *itemp = gInventory.getItem(item_id); +	LLConstPointer<LLInventoryObject> itemp = gInventory.getItem(item_id);  	wearable->setItemID(item_id); -	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));  	holder->eraseTypeToRecover(type);  	llassert(itemp);  	if (itemp)  	{ -		link_inventory_item( gAgent.getID(), -							 item_id, -							 LLAppearanceMgr::instance().getCOF(), -							 itemp->getName(), -							 itemp->getDescription(), -							 LLAssetType::AT_LINK, -							 cb); +		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder)); + +		link_inventory_object(LLAppearanceMgr::instance().getCOF(), itemp, cb);  	}  } @@ -1551,6 +1546,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL  	LLInventoryModel::item_array_t* items;  	gInventory.getDirectDescendentsOf(src_id, cats, items);  	llinfos << "copying " << items->count() << " items" << llendl; +	LLInventoryObject::const_object_list_t link_array;  	for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();  		 iter != items->end();  		 ++iter) @@ -1561,14 +1557,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL  			case LLAssetType::AT_LINK:  			{  				LL_DEBUGS("Avatar") << "linking inventory item " << item->getName() << llendl; -				//getActualDescription() is used for a new description  -				//to propagate ordering information saved in descriptions of links -				link_inventory_item(gAgent.getID(), -									item->getLinkedUUID(), -									dst_id, -									item->getName(), -									item->getActualDescription(), -									LLAssetType::AT_LINK, cb); +				link_array.push_back(LLConstPointer<LLInventoryObject>(item));  				break;  			}  			case LLAssetType::AT_LINK_FOLDER: @@ -1578,12 +1567,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL  				if (catp && catp->getPreferredType() != LLFolderType::FT_OUTFIT)  				{  					LL_DEBUGS("Avatar") << "linking inventory folder " << item->getName() << llendl; -					link_inventory_item(gAgent.getID(), -										item->getLinkedUUID(), -										dst_id, -										item->getName(), -										item->getDescription(), -										LLAssetType::AT_LINK_FOLDER, cb); +					link_array.push_back(LLConstPointer<LLInventoryObject>(item));  				}  				break;  			} @@ -1606,6 +1590,11 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL  				break;  		}  	} +	if (!link_array.empty()) +	{ +		const bool resolve_links = true; +		link_inventory_array(dst_id, link_array, cb, resolve_links); +	}  }  BOOL LLAppearanceMgr::getCanMakeFolderIntoOutfit(const LLUUID& folder_id) @@ -1753,42 +1742,6 @@ void LLAppearanceMgr::filterWearableItems(  	}  } -// Create links to all listed items. -void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid, -							  LLInventoryModel::item_array_t& items, -							  LLPointer<LLInventoryCallback> cb) -{ -	for (S32 i=0; i<items.count(); i++) -	{ -		const LLInventoryItem* item = items.get(i).get(); -		link_inventory_item(gAgent.getID(), -							item->getLinkedUUID(), -							cat_uuid, -							item->getName(), -							item->getActualDescription(), -							LLAssetType::AT_LINK, -							cb); - -		const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid); -		const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND"; -#ifndef LL_RELEASE_FOR_DOWNLOAD -		LL_DEBUGS("Avatar") << self_av_string() << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << LL_ENDL; -#endif -	} -} - -void LLAppearanceMgr::removeAll(LLInventoryModel::item_array_t& items_to_kill, -							   LLPointer<LLInventoryCallback> cb) -{ -	for (LLInventoryModel::item_array_t::iterator it = items_to_kill.begin(); -		 it != items_to_kill.end(); -		 ++it) -	{ -		LLViewerInventoryItem *item = *it; -		remove_inventory_item(item->getUUID(), cb); -	} -} -  void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)  {  	LLViewerInventoryCategory *pcat = gInventory.getCategory(category); @@ -1934,8 +1887,7 @@ void LLAppearanceMgr::createBaseOutfitLink(const LLUUID& category, LLPointer<LLI  	if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)  	{ -		link_inventory_item(gAgent.getID(), category, cof, catp->getName(), "", -							LLAssetType::AT_LINK_FOLDER, link_waiter); +		link_inventory_object(cof, catp, link_waiter);  		new_outfit_name = catp->getName();  	} @@ -2027,7 +1979,7 @@ void item_array_diff(LLInventoryModel::item_array_t& full_list,  S32 LLAppearanceMgr::findExcessOrDuplicateItems(const LLUUID& cat_id,  												 LLAssetType::EType type,  												 S32 max_items, -												 LLInventoryModel::item_array_t& items_to_kill) +												 LLInventoryObject::object_list_t& items_to_kill)  {  	S32 to_kill_count = 0; @@ -2045,7 +1997,7 @@ S32 LLAppearanceMgr::findExcessOrDuplicateItems(const LLUUID& cat_id,  		 it != kill_items.end();  		 ++it)  	{ -		items_to_kill.push_back(*it); +		items_to_kill.push_back(LLPointer<LLInventoryObject>(*it));  		to_kill_count++;  	}  	return to_kill_count; @@ -2053,7 +2005,7 @@ S32 LLAppearanceMgr::findExcessOrDuplicateItems(const LLUUID& cat_id,  void LLAppearanceMgr::findAllExcessOrDuplicateItems(const LLUUID& cat_id, -													LLInventoryModel::item_array_t& items_to_kill) +													LLInventoryObject::object_list_t& items_to_kill)  {  	findExcessOrDuplicateItems(cat_id,LLAssetType::AT_BODYPART,  							   1, items_to_kill); @@ -2065,14 +2017,13 @@ void LLAppearanceMgr::findAllExcessOrDuplicateItems(const LLUUID& cat_id,  void LLAppearanceMgr::enforceCOFItemRestrictions(LLPointer<LLInventoryCallback> cb)  { -	LLInventoryModel::item_array_t items_to_kill; +	LLInventoryObject::object_list_t items_to_kill;  	findAllExcessOrDuplicateItems(getCOF(), items_to_kill);  	if (items_to_kill.size()>0)  	{  		// Remove duplicate or excess wearables. Should normally be enforced at the UI level, but  		// this should catch anything that gets through. -		removeAll(items_to_kill, cb); -		return; +		remove_inventory_items(items_to_kill, cb);  	}  } @@ -2525,7 +2476,7 @@ void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id,  void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item,  									 LLPointer<LLInventoryCallback> cb,  									 const std::string description) -{		 +{  	const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item);  	if (!vitem)  	{ @@ -2577,18 +2528,10 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item,  	if (!linked_already)  	{ -		std::string link_description = description; -		if (vitem->getIsLinkType()) -		{ -			link_description = vitem->getActualDescription(); -		} -		link_inventory_item( gAgent.getID(), -							 vitem->getLinkedUUID(), -							 getCOF(), -							 vitem->getName(), -							 link_description, -							 LLAssetType::AT_LINK, -							 cb); +		LLInventoryObject::const_object_list_t obj_array; +		obj_array.push_back(LLConstPointer<LLInventoryObject>(vitem)); +		const bool resolve_links = true; +		link_inventory_array(getCOF(), obj_array, cb, resolve_links);  	}  } diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 8c8b5e2489..346577ab9a 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -67,9 +67,9 @@ public:  	S32 findExcessOrDuplicateItems(const LLUUID& cat_id,  								   LLAssetType::EType type,  								   S32 max_items, -								   LLInventoryModel::item_array_t& items_to_kill); +								   LLInventoryObject::object_list_t& items_to_kill);  	void findAllExcessOrDuplicateItems(const LLUUID& cat_id, -									  LLInventoryModel::item_array_t& items_to_kill); +									  LLInventoryObject::object_list_t& items_to_kill);  	void enforceCOFItemRestrictions(LLPointer<LLInventoryCallback> cb);  	S32 getActiveCopyOperations() const; @@ -139,15 +139,6 @@ public:  	void registerAttachment(const LLUUID& item_id);  	void setAttachmentInvLinkEnable(bool val); -	// utility function for bulk linking. -	void linkAll(const LLUUID& category, -				 LLInventoryModel::item_array_t& items, -				 LLPointer<LLInventoryCallback> cb); - -	// And bulk removal. -	void removeAll(LLInventoryModel::item_array_t& items, -				   LLPointer<LLInventoryCallback> cb); -  	// Add COF link to individual item.  	void addCOFItemLink(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");  	void addCOFItemLink(const LLInventoryItem *item, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = ""); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index cb3f40a5bb..0481bf5f45 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3223,28 +3223,9 @@ void LLFolderBridge::pasteLinkFromClipboard()  					dropToOutfit(item, move_is_into_current_outfit);  				}  			} -			else if (LLInventoryCategory *cat = model->getCategory(object_id)) +			else if (LLConstPointer<LLInventoryObject> obj = model->getObject(object_id))  			{ -				const std::string empty_description = ""; -				link_inventory_item( -					gAgent.getID(), -					cat->getUUID(), -					parent_id, -					cat->getName(), -					empty_description, -					LLAssetType::AT_LINK_FOLDER, -					LLPointer<LLInventoryCallback>(NULL)); -			} -			else if (LLInventoryItem *item = model->getItem(object_id)) -			{ -				link_inventory_item( -					gAgent.getID(), -					item->getLinkedUUID(), -					parent_id, -					item->getName(), -					item->getDescription(), -					LLAssetType::AT_LINK, -					LLPointer<LLInventoryCallback>(NULL)); +				link_inventory_object(parent_id, obj, LLPointer<LLInventoryCallback>(NULL));  			}  		}  		// Change mode to paste for next paste @@ -3830,14 +3811,7 @@ void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_c  	else  	{  		LLPointer<LLInventoryCallback> cb = NULL; -		link_inventory_item( -			gAgent.getID(), -			inv_item->getLinkedUUID(), -			mUUID, -			inv_item->getName(), -			inv_item->getDescription(), -			LLAssetType::AT_LINK, -			cb); +		link_inventory_object(mUUID, LLConstPointer<LLInventoryObject>(inv_item), cb);  	}  } diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index a1222424ee..0532370ff2 100755 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -1095,13 +1095,14 @@ void LLPanelEditWearable::saveChanges(bool force_save_as)  				LL_DEBUGS("Avatar") << "link refresh, creating new link to " << link_item->getLinkedUUID()  									<< " removing old link at " << link_item->getUUID()  									<< " wearable item id " << mWearablePtr->getItemID() << llendl; -				link_inventory_item( gAgent.getID(), -									 link_item->getLinkedUUID(), -									 LLAppearanceMgr::instance().getCOF(), -									 link_item->getName(), -									 description, -									 LLAssetType::AT_LINK, -									 gAgentAvatarp->mEndCustomizeCallback); + +				LLInventoryObject::const_object_list_t obj_array; +				obj_array.push_back(LLConstPointer<LLInventoryObject>(link_item)); +				const bool resolve_links = true; +				link_inventory_array(LLAppearanceMgr::instance().getCOF(), +									 obj_array,  +									 gAgentAvatarp->mEndCustomizeCallback, +									 resolve_links);  				// Remove old link  				remove_inventory_item(link_item->getUUID(), gAgentAvatarp->mEndCustomizeCallback);  			} diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index bff6767617..dc17da9009 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1074,77 +1074,158 @@ void copy_inventory_item(  	gAgent.sendReliableMessage();  } -void link_inventory_item( -	const LLUUID& agent_id, -	const LLUUID& item_id, -	const LLUUID& parent_id, -	const std::string& new_name, -	const std::string& new_description, -	const LLAssetType::EType asset_type, -	LLPointer<LLInventoryCallback> cb) +// Create link to single inventory object. +void link_inventory_object(const LLUUID& category, +			 LLConstPointer<LLInventoryObject> baseobj, +			 LLPointer<LLInventoryCallback> cb)  { -	const LLInventoryObject *baseobj = gInventory.getObject(item_id);  	if (!baseobj)  	{ -		llwarns << "attempt to link to unknown item, linked-to-item's itemID " << item_id << llendl; -		return; -	} -	if (baseobj && baseobj->getIsLinkType()) -	{ -		llwarns << "attempt to create a link to a link, linked-to-item's itemID " << item_id << llendl; +		llwarns << "Attempt to link to non-existent object" << llendl;  		return;  	} -	if (baseobj && !LLAssetType::lookupCanLink(baseobj->getType())) -	{ -		// Fail if item can be found but is of a type that can't be linked. -		// Arguably should fail if the item can't be found too, but that could -		// be a larger behavioral change. -		llwarns << "attempt to link an unlinkable item, type = " << baseobj->getActualType() << llendl; -		return; -	} -	 -	LLUUID transaction_id; -	LLInventoryType::EType inv_type = LLInventoryType::IT_NONE; -	if (dynamic_cast<const LLInventoryCategory *>(baseobj)) -	{ -		inv_type = LLInventoryType::IT_CATEGORY; -	} -	else +	LLInventoryObject::const_object_list_t obj_array; +	obj_array.push_back(baseobj); +	link_inventory_array(category, obj_array, cb); +} + +void link_inventory_object(const LLUUID& category, +			 const LLUUID& id, +			 LLPointer<LLInventoryCallback> cb) +{ +	LLConstPointer<LLInventoryObject> baseobj = gInventory.getObject(id); +	link_inventory_object(category, baseobj, cb); +} + +// Create links to all listed inventory objects. +void link_inventory_array(const LLUUID& category, +			 LLInventoryObject::const_object_list_t& baseobj_array, +			 LLPointer<LLInventoryCallback> cb, +			 bool resolve_links /* = false */) +{ +#ifndef LL_RELEASE_FOR_DOWNLOAD +	const LLViewerInventoryCategory *cat = gInventory.getCategory(category); +	const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND"; +#endif +	LLInventoryObject::const_object_list_t::const_iterator it = baseobj_array.begin(); +	LLInventoryObject::const_object_list_t::const_iterator end = baseobj_array.end(); +	LLSD links = LLSD::emptyArray(); +	for (; it != end; ++it)  	{ -		const LLViewerInventoryItem *baseitem = dynamic_cast<const LLViewerInventoryItem *>(baseobj); -		if (baseitem) +		const LLInventoryObject* baseobj = *it; +		if (!baseobj)  		{ -			inv_type = baseitem->getInventoryType(); +			llwarns << "attempt to link to unknown object" << llendl; +			continue; +		} +		if (!resolve_links && baseobj->getIsLinkType()) +		{ +			llwarns << "attempt to create a link to a link, linked-to-object's ID " << baseobj->getUUID() << llendl; +			continue;  		} -	} -#if 1 // debugging stuff -	LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id); -	lldebugs << "cat: " << cat << llendl; -	 +		if (!LLAssetType::lookupCanLink(baseobj->getType())) +		{ +			// Fail if item can be found but is of a type that can't be linked. +			// Arguably should fail if the item can't be found too, but that could +			// be a larger behavioral change. +			llwarns << "attempt to link an unlinkable object, type = " << baseobj->getActualType() << llendl; +			continue; +		} +		 +		LLInventoryType::EType inv_type = LLInventoryType::IT_NONE; +		LLAssetType::EType asset_type = LLAssetType::AT_NONE; +		std::string new_desc; +		LLUUID linkee_id; +		if (dynamic_cast<const LLInventoryCategory *>(baseobj)) +		{ +			inv_type = LLInventoryType::IT_CATEGORY; +			asset_type = LLAssetType::AT_LINK_FOLDER; +			linkee_id = baseobj->getUUID(); +		} +		else +		{ +			const LLViewerInventoryItem *baseitem = dynamic_cast<const LLViewerInventoryItem *>(baseobj); +			if (baseitem) +			{ +				inv_type = baseitem->getInventoryType(); +				new_desc = baseitem->getActualDescription(); +				switch (baseitem->getActualType()) +				{ +					case LLAssetType::AT_LINK: +					case LLAssetType::AT_LINK_FOLDER: +						linkee_id = baseobj->getLinkedUUID(); +						asset_type = baseitem->getActualType(); +						break; +					default: +						linkee_id = baseobj->getUUID(); +						asset_type = LLAssetType::AT_LINK; +						break; +				} +			} +			else +			{ +				llwarns << "could not convert object into an item or category: " << baseobj->getUUID() << llendl; +				continue; +			} +		} + +		LLSD link = LLSD::emptyMap(); +		link["linked_id"] = linkee_id; +		link["type"] = (S8)asset_type; +		link["inv_type"] = (S8)inv_type; +		link["name"] = baseobj->getName(); +		link["desc"] = new_desc; +		links.append(link); + +#ifndef LL_RELEASE_FOR_DOWNLOAD +		LL_DEBUGS("Inventory") << "Linking Object [ name:" << baseobj->getName()  +							   << " UUID:" << baseobj->getUUID()  +							   << " ] into Category [ name:" << cat_name  +							   << " UUID:" << category << " ] " << LL_ENDL;  #endif -	LLMessageSystem* msg = gMessageSystem; -	msg->newMessageFast(_PREHASH_LinkInventoryItem); -	msg->nextBlock(_PREHASH_AgentData); +	} + +	bool ais_ran = false; +	if (AISCommand::isAPIAvailable())  	{ -		msg->addUUIDFast(_PREHASH_AgentID, agent_id); -		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +		LLSD new_inventory = LLSD::emptyMap(); +		new_inventory["links"] = links; +		LLPointer<AISCommand> cmd_ptr = new CreateInventoryCommand(category, new_inventory, cb); +		ais_ran = cmd_ptr->run_command();  	} -	msg->nextBlock(_PREHASH_InventoryBlock); + +	if (!ais_ran)  	{ -		msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb)); -		msg->addUUIDFast(_PREHASH_FolderID, parent_id); -		msg->addUUIDFast(_PREHASH_TransactionID, transaction_id); -		msg->addUUIDFast(_PREHASH_OldItemID, item_id); -		msg->addS8Fast(_PREHASH_Type, (S8)asset_type); -		msg->addS8Fast(_PREHASH_InvType, (S8)inv_type); -		msg->addStringFast(_PREHASH_Name, new_name); -		msg->addStringFast(_PREHASH_Description, new_description); +		LLMessageSystem* msg = gMessageSystem; +		for (LLSD::array_iterator iter = links.beginArray(); iter != links.endArray(); ++iter ) +		{ +			msg->newMessageFast(_PREHASH_LinkInventoryItem); +			msg->nextBlock(_PREHASH_AgentData); +			{ +				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +			} +			msg->nextBlock(_PREHASH_InventoryBlock); +			{ +				LLSD link = (*iter); +				msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb)); +				msg->addUUIDFast(_PREHASH_FolderID, category); +				msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); +				msg->addUUIDFast(_PREHASH_OldItemID, link["linked_id"].asUUID()); +				msg->addS8Fast(_PREHASH_Type, link["type"].asInteger()); +				msg->addS8Fast(_PREHASH_InvType, link["inv_type"].asInteger()); +				msg->addStringFast(_PREHASH_Name, link["name"].asString()); +				msg->addStringFast(_PREHASH_Description, link["desc"].asString()); +			} +			gAgent.sendReliableMessage(); +		}  	} -	gAgent.sendReliableMessage();  } + +  void move_inventory_item(  	const LLUUID& agent_id,  	const LLUUID& session_id, @@ -1301,14 +1382,41 @@ void update_inventory_category(  	}  } +void remove_inventory_items( +	LLInventoryObject::object_list_t& items_to_kill, +	LLPointer<LLInventoryCallback> cb) +{ +	for (LLInventoryObject::object_list_t::iterator it = items_to_kill.begin(); +		 it != items_to_kill.end(); +		 ++it) +	{ +		remove_inventory_item(*it, cb); +	} +} +  void remove_inventory_item(  	const LLUUID& item_id,  	LLPointer<LLInventoryCallback> cb)  { -	LLPointer<LLViewerInventoryItem> obj = gInventory.getItem(item_id); -	LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << llendl; +	LLPointer<LLInventoryObject> obj = gInventory.getItem(item_id); +	if (obj) +	{ +		remove_inventory_item(obj, cb); +	} +	else +	{ +		LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << "(NOT FOUND)" << llendl; +	} +} + +void remove_inventory_item( +	LLPointer<LLInventoryObject> obj, +	LLPointer<LLInventoryCallback> cb) +{  	if(obj)  	{ +		const LLUUID item_id(obj->getUUID()); +		LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << obj->getName() << llendl;  		if (AISCommand::isAPIAvailable())  		{  			LLPointer<AISCommand> cmd_ptr = new RemoveItemCommand(item_id, cb); @@ -1336,7 +1444,8 @@ void remove_inventory_item(  	}  	else  	{ -		llwarns << "remove_inventory_item called for invalid or nonexistent item " << item_id << llendl; +		// *TODO: Clean up callback? +		llwarns << "remove_inventory_item called for invalid or nonexistent item." << llendl;  	}  } @@ -1632,13 +1741,7 @@ void slam_inventory_folder(const LLUUID& folder_id,  			 ++it)  		{  			const LLSD& item_contents = *it; -			link_inventory_item(gAgent.getID(), -								item_contents["linked_id"].asUUID(), -								folder_id, -								item_contents["name"].asString(), -								item_contents["desc"].asString(), -								LLAssetType::EType(item_contents["type"].asInteger()), -								cb); +			link_inventory_object(folder_id, item_contents["linked_id"].asUUID(), cb);  		}  		remove_folder_contents(folder_id,false,cb);  	} diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 6bc6343f3f..cc715ae21d 100755 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -351,14 +351,17 @@ void copy_inventory_item(  	const std::string& new_name,  	LLPointer<LLInventoryCallback> cb); -void link_inventory_item( -	const LLUUID& agent_id, -	const LLUUID& item_id, -	const LLUUID& parent_id, -	const std::string& new_name, -	const std::string& new_description, -	const LLAssetType::EType asset_type, -	LLPointer<LLInventoryCallback> cb); +// utility functions for inventory linking. +void link_inventory_object(const LLUUID& category, +			 LLConstPointer<LLInventoryObject> baseobj, +			 LLPointer<LLInventoryCallback> cb); +void link_inventory_object(const LLUUID& category, +			 const LLUUID& id, +			 LLPointer<LLInventoryCallback> cb); +void link_inventory_array(const LLUUID& category, +			 LLInventoryObject::const_object_list_t& baseobj_array, +			 LLPointer<LLInventoryCallback> cb, +			 bool resolve_links = false);  void move_inventory_item(  	const LLUUID& agent_id, @@ -382,6 +385,14 @@ void update_inventory_category(  	const LLSD& updates,  	LLPointer<LLInventoryCallback> cb); +void remove_inventory_items( +	LLInventoryObject::object_list_t& items, +	LLPointer<LLInventoryCallback> cb); + +void remove_inventory_item( +	LLPointer<LLInventoryObject> obj, +	LLPointer<LLInventoryCallback> cb); +  void remove_inventory_item(  	const LLUUID& item_id,  	LLPointer<LLInventoryCallback> cb); | 
