summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAura Linden <aura@lindenlab.com>2012-01-06 07:46:53 -0500
committerAura Linden <aura@lindenlab.com>2012-01-06 07:46:53 -0500
commitbd3a652eabf09a5843a6a0b8a9f60c4b402ecce5 (patch)
treef87e12efe45a6408fd49f436e82195e8e44242da /indra
parent570d562f5871f40bd7f8c683db5316ffd0133335 (diff)
Add capability-based create folder routine for more reliable inventory, with fix for copy and wear
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llfloateropenobject.cpp60
-rw-r--r--indra/newview/llfloateropenobject.h11
-rw-r--r--indra/newview/llinventorybridge.cpp13
-rw-r--r--indra/newview/llinventorymodel.cpp87
-rw-r--r--indra/newview/llinventorymodel.h4
-rw-r--r--indra/newview/llviewerregion.cpp1
6 files changed, 155 insertions, 21 deletions
diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index 8b6619def2..4bfef8b45f 100644
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -162,26 +162,66 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
{
parent_category_id = gInventory.getRootFolderID();
}
+
+ LLCategoryCreate* cat_data = new LLCategoryCreate(object_id, wear);
+
LLUUID category_id = gInventory.createNewCategory(parent_category_id,
- LLFolderType::FT_NONE,
- name);
+ LLFolderType::FT_NONE,
+ name,
+ callbackCreateInventoryCategory,
+ (void*)cat_data);
+
+ //If we get a null category ID, we are using a capability in createNewCategory and we will
+ //handle the following in the callbackCreateInventoryCategory routine.
+ if ( category_id.notNull() )
+ {
+ delete cat_data;
+
+ LLCatAndWear* data = new LLCatAndWear;
+ data->mCatID = category_id;
+ data->mWear = wear;
+ data->mFolderResponded = false;
+
+ // Copy and/or move the items into the newly created folder.
+ // Ignore any "you're going to break this item" messages.
+ BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE,
+ callbackMoveInventory,
+ (void*)data);
+ if (!success)
+ {
+ delete data;
+ data = NULL;
- LLCatAndWear* data = new LLCatAndWear;
- data->mCatID = category_id;
- data->mWear = wear;
+ LLNotificationsUtil::add("OpenObjectCannotCopy");
+ }
+ }
+}
+// static
+void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, void* data)
+{
+ LLCategoryCreate* cat_data = (LLCategoryCreate*)data;
+
+ LLUUID category_id = result["folder_id"].asUUID();
+ LLCatAndWear* wear_data = new LLCatAndWear;
+
+ wear_data->mCatID = category_id;
+ wear_data->mWear = cat_data->mWear;
+ wear_data->mFolderResponded = true;
+
// Copy and/or move the items into the newly created folder.
// Ignore any "you're going to break this item" messages.
- BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE,
+ BOOL success = move_inv_category_world_to_agent(cat_data->mObjectID, category_id, TRUE,
callbackMoveInventory,
- (void*)data);
+ (void*)wear_data);
if (!success)
{
- delete data;
- data = NULL;
-
+ delete wear_data;
+ wear_data = NULL;
+
LLNotificationsUtil::add("OpenObjectCannotCopy");
}
+ delete cat_data;
}
// static
diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h
index 0706e99f16..bf7fe69c65 100644
--- a/indra/newview/llfloateropenobject.h
+++ b/indra/newview/llfloateropenobject.h
@@ -45,10 +45,20 @@ public:
void dirty();
+ class LLCategoryCreate
+ {
+ public:
+ LLCategoryCreate(LLUUID object_id, bool wear) : mObjectID(object_id), mWear(wear) {}
+ public:
+ LLUUID mObjectID;
+ bool mWear;
+ };
+
struct LLCatAndWear
{
LLUUID mCatID;
bool mWear;
+ bool mFolderResponded;
};
protected:
@@ -62,6 +72,7 @@ protected:
void onClickMoveToInventory();
void onClickMoveAndWear();
+ static void callbackCreateInventoryCategory(const LLSD& result, void* data);
static void callbackMoveInventory(S32 result, void* data);
private:
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 0c092e9a56..eaf9b53eb9 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2305,15 +2305,15 @@ void LLRightClickInventoryFetchDescendentsObserver::done()
class LLInventoryCopyAndWearObserver : public LLInventoryObserver
{
public:
- LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count) :
- mCatID(cat_id), mContentsCount(count), mFolderAdded(FALSE) {}
+ LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count, bool folder_added=false) :
+ mCatID(cat_id), mContentsCount(count), mFolderAdded(folder_added) {}
virtual ~LLInventoryCopyAndWearObserver() {}
virtual void changed(U32 mask);
protected:
LLUUID mCatID;
int mContentsCount;
- BOOL mFolderAdded;
+ bool mFolderAdded;
};
@@ -2341,7 +2341,6 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask)
if (mFolderAdded)
{
LLViewerInventoryCategory* category = gInventory.getCategory(mCatID);
-
if (NULL == category)
{
llwarns << "gInventory.getCategory(" << mCatID
@@ -3188,13 +3187,13 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
if(option == 0 && object)
{
- if (cat_and_wear && cat_and_wear->mWear)
+ if (cat_and_wear && cat_and_wear->mWear) // && !cat_and_wear->mFolderResponded)
{
LLInventoryObject::object_list_t inventory_objects;
object->getInventoryContents(inventory_objects);
int contents_count = inventory_objects.size()-1; //subtract one for containing folder
-
- LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count);
+ LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count, cat_and_wear->mFolderResponded);
+
gInventory.addObserver(inventoryObserver);
}
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index dc25689fa3..568ec4c5e2 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -377,14 +377,67 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
return rv;
}
+class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
+{
+public:
+ LLCreateInventoryCategoryResponder(LLInventoryModel* model,
+ void (*callback)(const LLSD&, void*),
+ void* user_data) :
+ mModel(model),
+ mCallback(callback),
+ mData(user_data)
+ {
+ }
+
+ virtual void error(U32 status, const std::string& reason)
+ {
+ LL_WARNS("InvAPI") << "CreateInventoryCategory failed. status = " << status << ", reasion = \"" << reason << "\"" << LL_ENDL;
+ }
+
+ virtual void result(const LLSD& content)
+ {
+ //Server has created folder.
+
+ LLUUID category_id = content["folder_id"].asUUID();
+
+
+ // Add the category to the internal representation
+ LLPointer<LLViewerInventoryCategory> cat =
+ new LLViewerInventoryCategory( category_id,
+ content["parent_id"].asUUID(),
+ (LLFolderType::EType)content["type"].asInteger(),
+ content["name"].asString(),
+ gAgent.getID() );
+ cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
+ cat->setDescendentCount(0);
+ LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+ mModel->accountForUpdate(update);
+ mModel->updateCategory(cat);
+
+ if (mCallback && mData)
+ {
+ mCallback(content, mData);
+ }
+
+ }
+
+private:
+ void (*mCallback)(const LLSD&, void*);
+ void* mData;
+ LLInventoryModel* mModel;
+};
+
// Convenience function to create a new category. You could call
// updateCategory() with a newly generated UUID category, but this
// version will take care of details like what the name should be
// based on preferred type. Returns the UUID of the new category.
LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
LLFolderType::EType preferred_type,
- const std::string& pname)
+ const std::string& pname,
+ void (*callback)(const LLSD&, void*), //Default to NULL
+ void* user_data) //Default to NULL
{
+
LLUUID id;
if(!isInventoryUsable())
{
@@ -408,6 +461,35 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
{
name.assign(LLViewerFolderType::lookupNewCategoryName(preferred_type));
}
+
+ if ( callback && user_data ) //callback required for acked message.
+ {
+ LLViewerRegion* viewer_region = gAgent.getRegion();
+ std::string url;
+ if ( viewer_region )
+ url = viewer_region->getCapability("CreateInventoryCategory");
+
+ if (!url.empty())
+ {
+ //Let's use the new capability.
+
+ LLSD request, body;
+ body["folder_id"] = id;
+ body["parent_id"] = parent_id;
+ body["type"] = (LLSD::Integer) preferred_type;
+ body["name"] = name;
+
+ request["message"] = "CreateInventoryCategory";
+ request["payload"] = body;
+
+ // viewer_region->getCapAPI().post(request);
+ LLHTTPClient::post(
+ url,
+ body,
+ new LLCreateInventoryCategoryResponder(this, callback, user_data) );
+ return LLUUID::null;
+ }
+ }
// Add the category to the internal representation
LLPointer<LLViewerInventoryCategory> cat =
@@ -1087,7 +1169,6 @@ void LLInventoryModel::notifyObservers()
iter != mObservers.end(); )
{
LLInventoryObserver* observer = *iter;
-
observer->changed(mModifyMask);
// safe way to increment since changed may delete entries! (@!##%@!@&*!)
@@ -2574,7 +2655,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
<< titem->getParentUUID() << llendl;
U32 callback_id;
msg->getU32Fast(_PREHASH_ItemData, _PREHASH_CallbackID, callback_id);
- if(titem->getUUID().notNull())
+ if(titem->getUUID().notNull() ) // && callback_id.notNull() )
{
items.push_back(titem);
cblist.push_back(InventoryCallbackInfo(callback_id, titem->getUUID()));
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 340c1b0c22..0a564d353a 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -360,7 +360,9 @@ public:
// name based on type, pass in a NULL to the 'name' parameter.
LLUUID createNewCategory(const LLUUID& parent_id,
LLFolderType::EType preferred_type,
- const std::string& name);
+ const std::string& name,
+ void (*callback)(const LLSD&, void*) = NULL,
+ void* user_data = NULL );
protected:
// Internal methods that add inventory and make sure that all of
// the internal data structures are consistent. These methods
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index ed943964f9..e3cb985ddb 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1493,6 +1493,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("AvatarPickerSearch");
capabilityNames.append("ChatSessionRequest");
capabilityNames.append("CopyInventoryFromNotecard");
+ capabilityNames.append("CreateInventoryCategory");
capabilityNames.append("DispatchRegionInfo");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");