diff options
author | Aura Linden <aura@lindenlab.com> | 2012-01-06 07:46:53 -0500 |
---|---|---|
committer | Aura Linden <aura@lindenlab.com> | 2012-01-06 07:46:53 -0500 |
commit | bd3a652eabf09a5843a6a0b8a9f60c4b402ecce5 (patch) | |
tree | f87e12efe45a6408fd49f436e82195e8e44242da | |
parent | 570d562f5871f40bd7f8c683db5316ffd0133335 (diff) |
Add capability-based create folder routine for more reliable inventory, with fix for copy and wear
-rw-r--r-- | indra/newview/llfloateropenobject.cpp | 60 | ||||
-rw-r--r-- | indra/newview/llfloateropenobject.h | 11 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 13 | ||||
-rw-r--r-- | indra/newview/llinventorymodel.cpp | 87 | ||||
-rw-r--r-- | indra/newview/llinventorymodel.h | 4 | ||||
-rw-r--r-- | indra/newview/llviewerregion.cpp | 1 |
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"); |