From ced937cc460a6e0c0a80344ffea07c62d702de73 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 11 Jan 2012 00:55:03 -0600 Subject: [PATCH] Implemented CreateInventoryCategory sim caps support. (https://bitbucket.org/lindenlab/viewer-development/changeset/d327dcc8ae51) --- indra/newview/llfloateropenobject.cpp | 47 +++++++++++---- indra/newview/llfloateropenobject.h | 13 ++++- indra/newview/llinventorybridge.cpp | 8 +-- indra/newview/llinventorymodel.cpp | 83 ++++++++++++++++++++++++++- indra/newview/llinventorymodel.h | 4 +- indra/newview/llviewerregion.cpp | 1 + 6 files changed, 138 insertions(+), 18 deletions(-) diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 6a762d00a..7465eb94d 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -157,26 +157,51 @@ void LLFloaterOpenObject::moveToInventory(bool wear) { parent_category_id = gInventory.getRootFolderID(); } - LLUUID category_id = gInventory.createNewCategory(parent_category_id, - LLFolderType::FT_NONE, - name); - LLCatAndWear* data = new LLCatAndWear; - data->mCatID = category_id; - data->mWear = wear; + LLCategoryCreate* cat_data = new LLCategoryCreate(object_id, wear); + + LLUUID category_id = gInventory.createNewCategory(parent_category_id, + 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() ) + { + LLSD result; + result["folder_id"] = category_id; + //Reduce redundant code by just calling the callback. Dur. + callbackCreateInventoryCategory(result,cat_data); + } +} + +// 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 27653a5c9..8c00cc7f7 100644 --- a/indra/newview/llfloateropenobject.h +++ b/indra/newview/llfloateropenobject.h @@ -49,11 +49,21 @@ class LLFloaterOpenObject public: static void show(); static 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: @@ -67,6 +77,7 @@ protected: static void onClickMoveToInventory(void* data); static void onClickMoveAndWear(void* data); + static void callbackCreateInventoryCategory(const LLSD& result, void* data); static void callbackMoveInventory(S32 result, void* data); static void* createPanelInventory(void* data); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a773a196a..9d4edc275 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2097,15 +2097,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; }; @@ -2923,7 +2923,7 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response 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 ecafb56b9..68a52b1f2 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -492,13 +492,65 @@ LLUUID LLInventoryModel::findCategoryByName(std::string name) return LLUUID::null; } +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 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*)/*=NULL*/, + void* user_data/*=NULL*/) { LLUUID id; if(!isInventoryUsable()) @@ -524,6 +576,35 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, else name.assign(NEW_CATEGORY_NAMES[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 cat = new LLViewerInventoryCategory(id, parent_id, preferred_type, name, gAgent.getID()); diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index c5b94a0f4..b3608a536 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -393,7 +393,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& namevoid, + void (*callback)(const LLSD&, void*) = NULL, + void* user_data = NULL); // 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 9bbd9ca2a..57b53031e 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1493,6 +1493,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) //capabilityNames.append("AvatarPickerSearch"); //Display name/SLID lookup (llfloateravatarpicker.cpp) capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); + capabilityNames.append("CreateInventoryCategory"); capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet");