From 56a7ba61f631924e36c779f7efcabfd755c4beb2 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax Date: Tue, 10 Jan 2012 22:39:31 +0100 Subject: New inventory categrory capability code - needs testing. * Original code from: https://bitbucket.org/lindenlab/viewer-development/changeset/d327dcc8ae51 * Port by Henri Beauchamp: https://lists.secondlife.com/pipermail/opensource-dev/2012-January/008544.html * 3 Lines of debug by /me (find the Hippos -remove after testing) --- linden/indra/newview/llfloateropenobject.cpp | 76 +++++++++++++++----- linden/indra/newview/llfloateropenobject.h | 15 ++++ linden/indra/newview/llinventorybridge.cpp | 18 +++-- linden/indra/newview/llinventorymodel.cpp | 103 ++++++++++++++++++++++++++- linden/indra/newview/llinventorymodel.h | 8 ++- linden/indra/newview/llviewerregion.cpp | 1 + 6 files changed, 192 insertions(+), 29 deletions(-) diff --git a/linden/indra/newview/llfloateropenobject.cpp b/linden/indra/newview/llfloateropenobject.cpp index fc483dd..4190c3e 100644 --- a/linden/indra/newview/llfloateropenobject.cpp +++ b/linden/indra/newview/llfloateropenobject.cpp @@ -155,29 +155,71 @@ void LLFloaterOpenObject::moveToInventory(bool wear) { parent_category_id = gAgent.getInventoryRootID(); } + + LLCategoryCreate* cat_data = new LLCategoryCreate(object_id, wear); LLUUID category_id = gInventory.createNewCategory(parent_category_id, - LLAssetType::AT_NONE, - name); - - LLCatAndWear* data = new LLCatAndWear; - data->mCatID = category_id; - data->mWear = wear; - - // 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; + LLAssetType::AT_NONE, + name, + callbackCreateInventoryCategory, + (void*)cat_data); + - LLNotifications::instance().add("OpenObjectCannotCopy"); + // 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; + + LLNotifications::instance().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(cat_data->mObjectID, category_id, TRUE, + callbackMoveInventory, + (void*)wear_data); + if (!success) + { + delete wear_data; + wear_data = NULL; + + LLNotifications::instance().add("OpenObjectCannotCopy"); + } + delete cat_data; + } + +// static void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data) { LLCatAndWear* cat = (LLCatAndWear*)data; diff --git a/linden/indra/newview/llfloateropenobject.h b/linden/indra/newview/llfloateropenobject.h index 27653a5..4b89158 100644 --- a/linden/indra/newview/llfloateropenobject.h +++ b/linden/indra/newview/llfloateropenobject.h @@ -50,10 +50,24 @@ 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 +81,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/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp index f71df2d..bd08773 100644 --- a/linden/indra/newview/llinventorybridge.cpp +++ b/linden/indra/newview/llinventorybridge.cpp @@ -1610,18 +1610,21 @@ 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(FALSE) {} virtual ~LLInventoryCopyAndWearObserver() {} virtual void changed(U32 mask); protected: LLUUID mCatID; int mContentsCount; - BOOL mFolderAdded; + bool mFolderAdded; }; - - void LLInventoryCopyAndWearObserver::changed(U32 mask) { if((mask & (LLInventoryObserver::ADD)) != 0) @@ -2331,13 +2334,16 @@ 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) { InventoryObjectList 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; + inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, + contents_count, + cat_and_wear->mFolderResponded); gInventory.addObserver(inventoryObserver); } diff --git a/linden/indra/newview/llinventorymodel.cpp b/linden/indra/newview/llinventorymodel.cpp index 58a2bdc..0200ed0 100644 --- a/linden/indra/newview/llinventorymodel.cpp +++ b/linden/indra/newview/llinventorymodel.cpp @@ -396,13 +396,63 @@ 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) + { + llwarns << "CreateInventoryCategory failed. status = " << status + << ", reason = \"" << reason << "\"" << llendl; + } + + 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; + cat = new LLViewerInventoryCategory(category_id, + content["parent_id"].asUUID(), + (LLAssetType::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, - LLAssetType::EType preferred_type, - const std::string& pname) + LLAssetType::EType preferred_type, const std::string& pname, + void (*callback)(const LLSD&, void*), + void* user_data) { LLUUID id; if(!isInventoryUsable()) @@ -433,6 +483,53 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, name.assign(NEW_CATEGORY_NAME); } + if (callback && user_data) // callback required for acked message. + { + + + LLViewerRegion* viewer_region = gAgent.getRegion(); + if (!viewer_region->capabilitiesReceived())//awfixme + { + LL_DEBUGS("Inventory") << "HIPPOS! not capabilitiesReceived()" << LL_ENDL; + } + std::string url; + if (viewer_region) + { + url = viewer_region->getCapability("CreateInventoryCategory"); + } + + if (!url.empty()) + { + LL_DEBUGS("Inventory") << "Using the CreateInventoryCategory capability." << LL_ENDL; + // 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; + + LLHTTPClient::post(url, body, + new LLCreateInventoryCategoryResponder(this, + callback, + user_data)); + return LLUUID::null; + } + else//awfixme + { + LL_DEBUGS("Inventory") << "HIPPOS! cap url empty" << LL_ENDL; + } + } + else//awfixme + { + LL_DEBUGS("Inventory") << "HIPPOS! callback: " + << (callback ? "true" : "false") + << "user_data" << ((NULL!= user_data) ? "!NULL" : "NULL") + << LL_ENDL; + } + // Add the category to the internal representation LLPointer cat = new LLViewerInventoryCategory(id, parent_id, preferred_type, name, gAgent.getID()); @@ -3173,7 +3270,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/linden/indra/newview/llinventorymodel.h b/linden/indra/newview/llinventorymodel.h index 7222c60..7788c34 100644 --- a/linden/indra/newview/llinventorymodel.h +++ b/linden/indra/newview/llinventorymodel.h @@ -308,9 +308,11 @@ public: // based on preferred type. Returns the UUID of the new // category. If you want to use the default name based on type, // pass in a NULL to the 'name parameter. - LLUUID createNewCategory(const LLUUID& parent_id, - LLAssetType::EType preferred_type, - const std::string& name); + LLUUID createNewCategory(const LLUUID& parent_id, + LLAssetType::EType preferred_type, + const std::string& name, + void (*callback)(const LLSD&, void*) = NULL, + void* user_data = NULL); LLUUID findCategoryByName(std::string name); diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp index a43e0c0..2fafe30 100644 --- a/linden/indra/newview/llviewerregion.cpp +++ b/linden/indra/newview/llviewerregion.cpp @@ -1428,6 +1428,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) LLSD capabilityNames = LLSD::emptyArray(); capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); + capabilityNames.append("CreateInventoryCategory"); // Aurora settings -- MC capabilityNames.append("DispatchOpenRegionSettings"); capabilityNames.append("DispatchRegionInfo"); -- cgit v1.1